From cbe2f86165f77cabdd732a7a7b7c9d0850390f1c Mon Sep 17 00:00:00 2001 From: Michal Marcinkowski Date: Wed, 25 Feb 2015 10:50:35 -0500 Subject: [PATCH 01/45] update data --- openspace-data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openspace-data b/openspace-data index 978c7563c5..953506d4af 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 978c7563c542cf9a2c85c04ec6e38540172ef569 +Subproject commit 953506d4afc5ebb9cea3ac481c5cc392bce7267e From cae39f2788e8fd24f9085c302de3961b1590e996 Mon Sep 17 00:00:00 2001 From: Michal Marcinkowski Date: Tue, 24 Mar 2015 12:31:03 -0400 Subject: [PATCH 02/45] updates to the imagesequencing & renderableplanet projection classes mainly --- .gitignore | 4 + .../rendering/model/renderablemodel.h | 9 +- .../planets/renderableplanetprojection.h | 8 +- include/openspace/util/imagesequencer.h | 94 ++++- openspace.cfg | 2 +- scripts/bind_keys.lua | 11 + scripts/default_startup.lua | 6 +- shaders/nh_fs.glsl | 108 ++++++ shaders/nh_vs.glsl | 57 +++ src/engine/openspaceengine.cpp | 3 +- src/rendering/model/renderablemodel.cpp | 98 +++++- src/rendering/model/wavefrontgeometry.cpp | 40 ++- src/rendering/planets/renderableplanet.cpp | 18 +- .../planets/renderableplanetprojection.cpp | 107 ++++-- src/rendering/renderablefov.cpp | 2 +- src/rendering/renderableplane.cpp | 2 +- src/rendering/renderengine.cpp | 7 +- src/scenegraph/scenegraph.cpp | 13 +- src/util/imagesequencer.cpp | 328 ++++++++++++++---- 19 files changed, 748 insertions(+), 169 deletions(-) create mode 100644 shaders/nh_fs.glsl create mode 100644 shaders/nh_vs.glsl diff --git a/.gitignore b/.gitignore index f7e802b045..51a59b30d1 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,7 @@ 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 diff --git a/include/openspace/rendering/model/renderablemodel.h b/include/openspace/rendering/model/renderablemodel.h index 4dd721cc16..2329c609ea 100644 --- a/include/openspace/rendering/model/renderablemodel.h +++ b/include/openspace/rendering/model/renderablemodel.h @@ -57,8 +57,12 @@ protected: private: properties::StringProperty _colorTexturePath; + properties::StringProperty _bumpTexturePath; + ghoul::opengl::ProgramObject* _programObject; ghoul::opengl::Texture* _texture; + ghoul::opengl::Texture* _bumpMap; + modelgeometry::ModelGeometry* _geometry; @@ -67,10 +71,13 @@ private: std::string _source; std::string _destination; - psc _sunPosition; properties::BoolProperty _performShading; + properties::BoolProperty _performFade; + + properties::FloatProperty _fading; + }; } // namespace openspace diff --git a/include/openspace/rendering/planets/renderableplanetprojection.h b/include/openspace/rendering/planets/renderableplanetprojection.h index 4137e0f640..a6a2c57fa0 100644 --- a/include/openspace/rendering/planets/renderableplanetprojection.h +++ b/include/openspace/rendering/planets/renderableplanetprojection.h @@ -102,9 +102,15 @@ private: glm::dmat3 _instrumentMatrix; glm::vec3 _boresight; - double _time[2]; + double _time; + double _previousTime; + double _previousCapture; double lightTime; + std::vector> _imageTimes; + int _sequenceID; + + std::string _target; std::string _defaultProjImage; std::string _next; diff --git a/include/openspace/util/imagesequencer.h b/include/openspace/util/imagesequencer.h index d0595aa4eb..a557a45205 100644 --- a/include/openspace/util/imagesequencer.h +++ b/include/openspace/util/imagesequencer.h @@ -37,43 +37,103 @@ namespace openspace { class ImageSequencer { public: ImageSequencer(); - + /** + * Singelton instantiation + */ static ImageSequencer& ref(); - bool loadSequence(const std::string& dir); - - bool parsePlaybook(const std::string& dir, const std::string& type, std::string year = "2015"); - bool parsePlaybookFile(const std::string& fileName, std::string year = "2015"); - - void testStartTimeMap(); - static void initialize(); static void deinitialize(); - bool sequenceReset(); - bool getImagePath(double& _currentTime, std::string& path, bool closedInterval = false); + /** + * Updates current time and initializes the previous time member + */ + void update(double initTime); + + /** + * When the a projectable class loads its sequence it also has to request an ID + * which is set by reference and returned to the projectable. This ID is later + * used to access whatever data ImageSequencer loads. + */ + void setSequenceId(int& id); + + //bool sequenceReset(); + + /** + * Based on sequenceID and unique projectee name, the ImageSequencer determines which subset of data is to be filled to _imageTimes + * which can be used in a projecable class for projections. + */ + bool getImagePath(std::vector>& _imageTimes, int sequenceID, std::string projectee, bool withinFOV); + + /* + * Returns the time until next capture in seconds. + * + */ double getNextCaptureTime(); - double getIntervalLength(){ return _intervalLength; }; - std::string& getActiveInstrument(){ return _activeInstrument; }; - std::string findActiveInstrument(double time); + /* + * Returns the time until next capture in seconds. + */ + double getIntervalLength(){ return _intervalLength; }; + + /* + * Returns next active instrument + */ + std::string& getActiveInstrument(){ return _activeInstrument; }; + + /* + * Performs search to find next consective instrument thats active + */ + std::string findActiveInstrument(double time, int sequenceID); + + /* + * Performs search to find next consecutive projection image. + */ + double nextCaptureTime(double _time, int sequenceID); + + /* + * Load (from *.fit converted) jpg image sequence based on corresponding *.lbl header files + */ + bool loadSequence(const std::string& dir, int& sequenceID); + /* + * Load sequence file of either *.csv type (excel) or preparsed *.txt type + */ + bool parsePlaybook(const std::string& dir, const std::string& type, std::string year = "2015"); + bool parsePlaybookFile(const std::string& fileName, int& sequenceID, std::string year = "2015"); + + /* + * These three methods augment the playbook + */ + void augumentSequencesWithTargets(int sequenceID); + void addSequenceObserver(int sequenceID, std::string name, std::vector payload); + void registerTargets(std::vector& potential); static ImageSequencer* _sequencer; +protected: + + bool getMultipleImages(std::vector>& _imageTimes, int sequenceID, std::string projectee); + bool getSingleImage(std::vector>& _imageTimes, int sequenceID, std::string projectee); + private: + double getMissionElapsedTime(std::string timestr); - double nextCaptureTime(double _time); + std::map _projectableTargets; + std::map _observers; + std::map > _instruments; - void createImage(double t1, double t2, std::string instrument, std::string path = "dummypath"); - double _nextCapture; double _intervalLength; double _metRef = 299180517; - + double _currentTime; + int _sequenceIDs; std::string _defaultCaptureImage; std::string _activeInstrument; + + bool _targetsAdded; + }; } // namespace openspace diff --git a/openspace.cfg b/openspace.cfg index f00d192734..4291764e9c 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -45,5 +45,5 @@ return { SGCTConfig = "${SGCT}/single.xml", --SGCTConfig = "${SGCT}/single_fisheye.xml", --SGCTConfig = "${SGCT}/two_nodes.xml", - Scene = "${OPENSPACE_DATA}/scene/default.scene", + Scene = "${OPENSPACE_DATA}/scene/default_nh.scene", } \ No newline at end of file diff --git a/scripts/bind_keys.lua b/scripts/bind_keys.lua index 320207ace1..b328ced545 100644 --- a/scripts/bind_keys.lua +++ b/scripts/bind_keys.lua @@ -26,4 +26,15 @@ openspace.bindKey("7", "openspace.time.setTime('2015-07-14T15:02:46.00'); opensp openspace.bindKey("q", "local b = openspace.getPropertyValue('SunMarker.renderable.enabled'); openspace.setPropertyValue('SunMarker.renderable.enabled', not b)") openspace.bindKey("e", "local b = openspace.getPropertyValue('EarthMarker.renderable.enabled'); openspace.setPropertyValue('EarthMarker.renderable.enabled', not b)") +openspace.bindKey("k", "local b = openspace.getPropertyValue('HydraText.renderable.enabled'); openspace.setPropertyValue('HydraText.renderable.enabled', not b)") +openspace.bindKey("k", "local b = openspace.getPropertyValue('CharonText.renderable.enabled'); openspace.setPropertyValue('CharonText.renderable.enabled', not b)") +openspace.bindKey("k", "local b = openspace.getPropertyValue('NixText.renderable.enabled'); openspace.setPropertyValue('NixText.renderable.enabled', not b)") +openspace.bindKey("k", "local b = openspace.getPropertyValue('KerberosText.renderable.enabled'); openspace.setPropertyValue('KerberosText.renderable.enabled', not b)") +openspace.bindKey("k", "local b = openspace.getPropertyValue('StyxText.renderable.enabled'); openspace.setPropertyValue('StyxText.renderable.enabled', not b)") +openspace.bindKey("j", "local b = openspace.getPropertyValue('PlutoText.renderable.enabled'); openspace.setPropertyValue('PlutoText.renderable.enabled', not b)") + + +openspace.bindKey("l", "local b = openspace.getPropertyValue('Labels.renderable.performFading'); openspace.setPropertyValue('Labels.renderable.performFading', not b)") + + openspace.bindKey("PAUSE", "openspace.printInfo('F5: Toogle to Sun, F6: Toggle to Jupiter, F7: Toggle to Pluto'); openspace.printInfo('Bookmarks: 1: Jupter, 2-7: Pluto');") diff --git a/scripts/default_startup.lua b/scripts/default_startup.lua index 26a6c800db..19cd4413d1 100644 --- a/scripts/default_startup.lua +++ b/scripts/default_startup.lua @@ -5,16 +5,16 @@ openspace.setInvertRoll(true); --openspace.setInteractionSensitivity(10) -- This is the default value for the sensitivity (the higher, the more sensitive) -openspace.time.setTime("2007 FEB 27 16:40:00") -- This is the start time for a Jupiter run of New Horizons +--openspace.time.setTime("2007 FEB 27 16:30:00") -- This is the start time for a Jupiter run of New Horizons -openspace.time.setDeltaTime(10) -- How many seconds pass per second of realtime, changeable in the GUI +openspace.time.setDeltaTime(0) -- How many seconds pass per second of realtime, changeable in the GUI dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) -- Load the default keybindings -- openspace.time.setDeltaTime(50); ---openspace.time.setTime("2015-07-14T10:50:00.00") -- PLUTO +openspace.time.setTime("2015-07-14T10:10:00.00") -- PLUTO -- NH takes series of images from visible to dark side (across terminator) -- Sequence lasts ~10 mins, (recommended dt = 10) diff --git a/shaders/nh_fs.glsl b/shaders/nh_fs.glsl new file mode 100644 index 0000000000..d701b2e2c6 --- /dev/null +++ b/shaders/nh_fs.glsl @@ -0,0 +1,108 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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__ + +uniform vec4 campos; +uniform vec4 objpos; +uniform vec3 cam_dir; // add this for specular + +uniform vec3 sun_pos; + +uniform bool _performShading = true; + +uniform int shadows; + +uniform float fading; + +uniform float time; +uniform sampler2D texture1; +uniform sampler2D texture2; + +in vec2 vs_st; +in vec4 vs_normal; +in vec4 vs_position; + +#include "ABuffer/abufferStruct.hglsl" +#include "ABuffer/abufferAddToBuffer.hglsl" +#include "PowerScaling/powerScaling_fs.hglsl" + +//#include "PowerScaling/powerScaling_vs.hglsl" +void main() +{ + vec4 position = vs_position; + float depth = pscDepth(position); + vec4 diffuse = texture(texture1, vs_st); + + vec3 normal = normalize(texture2D(texture2, vs_st).rgb * 2.0 - 1.0); + + if (fading > 0 || fading < 1){ + diffuse.a = fading; + } + + if (_performShading) { + vec4 spec = vec4(0.0); + + vec3 n = normalize(vs_normal.xyz); + //vec3 n = normalize(normal.xyz); + vec3 l_pos = vec3(sun_pos); // sun. + vec3 l_dir = normalize(l_pos-objpos.xyz); + float intensity = min(max(1*dot(n,l_dir), 0.0), 1); + + float diff = max( dot(l_dir, n), 0.0 ); + + float shine = 100; + /*if(normal.x > 0 && normal.y > 0 && normal.z > 0){ + n = normalize(normal.xyz); + }*/ + + vec4 specular = vec4(1.0); + vec4 ambient = diffuse*0.4;//vec4(0.0,0.0,0.0,1); + + if(intensity > 0.0f){ + // halfway vector + vec3 h = normalize(l_dir + normalize(cam_dir)); + // specular factor + float intSpec = max(dot(n,h),0.0); + spec = specular * pow(intSpec, shine); + } + + diffuse = vec4(max(intensity * diffuse , ambient).xyz,1) +spec*1.5*diffuse ; + + if (fading > 0 || fading < 1){ + diffuse.a = fading; + } + + + //diffuse = vec4(1); + + ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); + addToBuffer(frag); + } + else { + ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); + addToBuffer(frag); + } + +} \ No newline at end of file diff --git a/shaders/nh_vs.glsl b/shaders/nh_vs.glsl new file mode 100644 index 0000000000..13f3025471 --- /dev/null +++ b/shaders/nh_vs.glsl @@ -0,0 +1,57 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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__ + +uniform mat4 ViewProjection; +uniform mat4 ModelTransform; + +layout(location = 0) in vec4 in_position; +//in vec3 in_position; +layout(location = 1) in vec2 in_st; +layout(location = 2) in vec3 in_normal; + +out vec2 vs_st; +out vec4 vs_normal; +out vec4 vs_position; +out float s; + +#include "PowerScaling/powerScaling_vs.hglsl" + +void main() +{ + // set variables + vs_st = in_st; + //vs_stp = in_position.xyz; + vs_position = in_position; + vec4 tmp = in_position; + + // this is wrong for the normal. The normal transform is the transposed inverse of the model transform + vs_normal = normalize(ModelTransform * vec4(in_normal,0)); + + vec4 position = pscTransform(tmp, ModelTransform); + vs_position = tmp; + position = ViewProjection * position; + gl_Position = z_normalization(position); +} \ No newline at end of file diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index d0943d82bc..ee00946979 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -100,6 +100,7 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName) { SpiceManager::initialize(); Time::initialize(); + ImageSequencer::initialize(); FactoryManager::initialize(); ghoul::systemcapabilities::SystemCapabilities::initialize(); } @@ -206,8 +207,6 @@ bool OpenSpaceEngine::create( } } - ImageSequencer::initialize(); - // Create the cachemanager FileSys.createCacheManager(absPath("${" + constants::configurationmanager::keyCache + "}")); _engine->_console->initialize(); diff --git a/src/rendering/model/renderablemodel.cpp b/src/rendering/model/renderablemodel.cpp index fa1b7dabba..258a85f0d8 100644 --- a/src/rendering/model/renderablemodel.cpp +++ b/src/rendering/model/renderablemodel.cpp @@ -45,17 +45,24 @@ namespace { const std::string _loggerCat = "RenderableModel"; const std::string keySource = "Rotation.Source"; const std::string keyDestination = "Rotation.Destination"; + const std::string keyShading = "Shading.PerformShading"; + const std::string keyFading = "Shading.Fadeable"; + } namespace openspace { -RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) - : Renderable(dictionary) - , _colorTexturePath("colorTexture", "Color Texture") - , _programObject(nullptr) - , _texture(nullptr) - , _geometry(nullptr) - , _performShading("performShading", "Perform Shading", true) + RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) + : Renderable(dictionary) + , _colorTexturePath("colorTexture", "Color Texture") + , _bumpTexturePath("bumpTexture", "Bump Texture") + , _programObject(nullptr) + , _texture(nullptr) + , _bumpMap(nullptr) + , _geometry(nullptr) + , _performShading("performShading", "Perform Shading", true) + , _fading("fading", "Fade", 0) + , _performFade("performFading", "Perform Fading", false) { std::string name; bool success = dictionary.getValue(constants::scenegraphnode::keyName, name); @@ -73,26 +80,53 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) _geometry = modelgeometry::ModelGeometry::createFromDictionary(geometryDictionary); } + addPropertySubOwner(_geometry); + + std::string texturePath = ""; success = dictionary.getValue("Textures.Color", texturePath); if (success) _colorTexturePath = path + "/" + texturePath; - addPropertySubOwner(_geometry); - addProperty(_colorTexturePath); _colorTexturePath.onChange(std::bind(&RenderableModel::loadTexture, this)); + std::string bumpPath = ""; + success = dictionary.getValue("Textures.BumpMap", bumpPath); + if (success) + _bumpTexturePath = path + "/" + bumpPath; + + addProperty(_bumpTexturePath); + _colorTexturePath.onChange(std::bind(&RenderableModel::loadTexture, this)); + dictionary.getValue(keySource, _source); dictionary.getValue(keyDestination, _destination); setBoundingSphere(pss(1.f, 9.f)); + + if (dictionary.hasKeyAndValue(keyShading)) { + bool shading; + dictionary.getValue(keyShading, shading); + _performShading = shading; + } + + addProperty(_performShading); + + if (dictionary.hasKeyAndValue(keyFading)) { + bool fading; + dictionary.getValue(keyShading, fading); + _performFade = fading; + } + + addProperty(_performFade); } bool RenderableModel::isReady() const { bool ready = true; ready &= (_programObject != nullptr); ready &= (_texture != nullptr); + ready &= (_bumpMap != nullptr); + return ready; } @@ -100,11 +134,12 @@ bool RenderableModel::initialize() { bool completeSuccess = true; if (_programObject == nullptr) completeSuccess - &= OsEng.ref().configurationManager()->getValue("pscShader", _programObject); + &= OsEng.ref().configurationManager()->getValue("NewHorizonsShader", _programObject); loadTexture(); completeSuccess &= (_texture != nullptr); + completeSuccess &= (_bumpMap != nullptr); completeSuccess &= _geometry->initialize(this); completeSuccess &= !_source.empty(); completeSuccess &= !_destination.empty(); @@ -119,9 +154,11 @@ bool RenderableModel::deinitialize() { } if (_texture) delete _texture; - + if (_bumpMap) + delete _bumpMap; _geometry = nullptr; _texture = nullptr; + _bumpMap = nullptr; return true; } @@ -138,13 +175,35 @@ void RenderableModel::render(const RenderData& data) { } transform *= tmp; + double lt; + psc tmppos; + SpiceManager::ref().getTargetPosition(_source, "SUN", "GALACTIC", "NONE", Time::ref().currentTime(), tmppos, lt); + + glm::vec3 cam_dir = glm::normalize(data.camera.position().vec3() - tmppos.vec3()); + + //std::cout << cam_dir << std::endl; _programObject->setUniform("sun_pos", _sunPosition.vec3()); + _programObject->setUniform("cam_dir", cam_dir); _programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); _programObject->setUniform("ModelTransform", transform); setPscUniforms(_programObject, &data.camera, data.position); - _programObject->setUniform("_performShading", true); + _programObject->setUniform("_performShading", _performShading); + + + if (_performFade && _fading > 0.f){ + _fading = _fading - 0.01f; + + } + else if (!_performFade && _fading < 1.f){ + _fading = _fading + 0.01f; + + } + + _programObject->setUniform("fading", _fading); + + // Bind texture ghoul::opengl::TextureUnit unit; @@ -152,6 +211,11 @@ void RenderableModel::render(const RenderData& data) { _texture->bind(); _programObject->setUniform("texture1", unit); + ghoul::opengl::TextureUnit unitBump; + unitBump.activate(); + _bumpMap->bind(); + //_programObject->setUniform("texture2", unitBump); + _geometry->render(); // disable shader @@ -177,6 +241,16 @@ void RenderableModel::loadTexture() { _texture->uploadTexture(); } } + + delete _bumpMap; + _bumpMap = nullptr; + if (_bumpTexturePath.value() != "") { + _bumpMap = ghoul::io::TextureReader::ref().loadTexture(absPath(_bumpTexturePath)); + if (_bumpMap) { + LDEBUG("Loaded texture from '" << absPath(_bumpTexturePath) << "'"); + _bumpMap->uploadTexture(); + } + } } } // namespace openspace diff --git a/src/rendering/model/wavefrontgeometry.cpp b/src/rendering/model/wavefrontgeometry.cpp index 0ff1605507..aa88ba01a9 100644 --- a/src/rendering/model/wavefrontgeometry.cpp +++ b/src/rendering/model/wavefrontgeometry.cpp @@ -35,6 +35,7 @@ namespace { const std::string _loggerCat = "WavefrontGeometry"; + const std::string keyEnabled = "StartsEnabled"; const std::string keyObjFile = "ObjFile"; @@ -69,6 +70,7 @@ WavefrontGeometry::WavefrontGeometry(const ghoul::Dictionary& dictionary) bool WavefrontGeometry::loadObj(const std::string& filename){ std::string cachedFile = ""; + FileSys.cacheManager()->getCachedFile(filename, cachedFile, true); bool hasCachedFile = FileSys.fileExists(cachedFile); @@ -86,6 +88,7 @@ bool WavefrontGeometry::loadObj(const std::string& filename){ else { LINFO("Cache for Model'" << filename << "' not found"); } + LINFO("Loading OBJ file '" << filename << "'"); bool success = loadModel(filename); if (!success) @@ -186,7 +189,7 @@ bool WavefrontGeometry::loadModel(const std::string& filename) { _vertices[j + currentPosition].location[1] = shapes[i].mesh.positions[3 * j + 1]; _vertices[j + currentPosition].location[2] = shapes[i].mesh.positions[3 * j + 2]; _vertices[j + currentPosition].location[3] = 5; - + _vertices[j + currentPosition].normal[0] = shapes[i].mesh.normals[3 * j + 0]; _vertices[j + currentPosition].normal[1] = shapes[i].mesh.normals[3 * j + 1]; _vertices[j + currentPosition].normal[2] = shapes[i].mesh.normals[3 * j + 2]; @@ -195,7 +198,7 @@ bool WavefrontGeometry::loadModel(const std::string& filename) { _vertices[j + currentPosition].tex[0] = shapes[0].mesh.texcoords[2 * j + 0]; _vertices[j + currentPosition].tex[1] = shapes[0].mesh.texcoords[2 * j + 1]; } - + } currentPosition += shapes[i].mesh.positions.size() / 3; @@ -206,7 +209,40 @@ bool WavefrontGeometry::loadModel(const std::string& filename) { ); p += shapes[i].mesh.indices.size(); } + /* + std::cout << _vertices.size() << " " << shapes[0].mesh.texcoords.size() << std::endl; + + const size_t face_count = shapes[0].mesh.indices.size() / 3; + for (size_t f = 0; f < face_count; f++) + { + int vertex_index_list[3]; + vertex_index_list[0] = shapes[0].mesh.indices[f * 3 + 0]; + vertex_index_list[1] = shapes[0].mesh.indices[f * 3 + 1]; + vertex_index_list[2] = shapes[0].mesh.indices[f * 3 + 2]; + + const int face[] = { + vertex_index_list[0], + vertex_index_list[1], + vertex_index_list[2] + }; + + if (!shapes[0].mesh.texcoords.empty()) + { + for (int k = 0; k < 3; k++) + { + const int vi = face[k]; + if (vi*2+1 < shapes[0].mesh.texcoords.size()){ + + _vertices[vi].tex[0] = shapes[0].mesh.texcoords[2 * vi + 0]; + _vertices[vi].tex[1] = shapes[0].mesh.texcoords[2 * vi + 1]; + } + + } + } + } + */ + return true; } diff --git a/src/rendering/planets/renderableplanet.cpp b/src/rendering/planets/renderableplanet.cpp index 7f4ab720c7..d0be033cd1 100644 --- a/src/rendering/planets/renderableplanet.cpp +++ b/src/rendering/planets/renderableplanet.cpp @@ -66,10 +66,10 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) ghoul_assert(success, "RenderablePlanet need the '" <uploadTexture(); // Textures of planets looks much smoother with AnisotropicMipMap rather than linear diff --git a/src/rendering/planets/renderableplanetprojection.cpp b/src/rendering/planets/renderableplanetprojection.cpp index 6c221a9070..a990de1d95 100644 --- a/src/rendering/planets/renderableplanetprojection.cpp +++ b/src/rendering/planets/renderableplanetprojection.cpp @@ -84,6 +84,7 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& , _texture(nullptr) , _textureProj(nullptr) , _geometry(nullptr) + , _sequenceID(-1) { std::string name; bool success = dictionary.getValue(constants::scenegraphnode::keyName, name); @@ -106,13 +107,12 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& dictionary.getValue(keyFrame, _target); - - bool b1 = dictionary.getValue(keyInstrument, _instrumentID); - bool b2 = dictionary.getValue(keyProjObserver, _projectorID); - bool b3 = dictionary.getValue(keyProjTarget, _projecteeID); - bool b4 = dictionary.getValue(keyProjAberration, _aberration); - bool b5 = dictionary.getValue(keyInstrumentFovy, _fovy); - bool b6 = dictionary.getValue(keyInstrumentAspect, _aspectRatio); + bool b1 = dictionary.getValue(keyInstrument, _instrumentID); // NH_LORRRI + bool b2 = dictionary.getValue(keyProjObserver, _projectorID); // NH_SPACECRAFT + bool b3 = dictionary.getValue(keyProjTarget, _projecteeID); // PLUTO + bool b4 = dictionary.getValue(keyProjAberration, _aberration); // NONE + bool b5 = dictionary.getValue(keyInstrumentFovy, _fovy); // deg + bool b6 = dictionary.getValue(keyInstrumentAspect, _aspectRatio); // .... bool b7 = dictionary.getValue(keyInstrumentNear, _nearPlane); bool b8 = dictionary.getValue(keyInstrumentFar, _farPlane); @@ -137,6 +137,8 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& _potentialTargets[i] = target; } + ImageSequencer::ref().registerTargets(_potentialTargets); + // TODO: textures need to be replaced by a good system similar to the geometry as soon // as the requirements are fixed (ab) std::string texturePath = ""; @@ -169,16 +171,33 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& found = dictionary.getValue(keySequenceType, sequenceType); if (found) { if (sequenceType == sequenceTypeImage) { - openspace::ImageSequencer::ref().loadSequence(sequenceSource); + openspace::ImageSequencer::ref().loadSequence(sequenceSource, _sequenceID); } else if (sequenceType == sequenceTypePlaybook) { - openspace::ImageSequencer::ref().parsePlaybookFile(sequenceSource); + openspace::ImageSequencer::ref().parsePlaybookFile(sequenceSource, _sequenceID); } else { LERROR("RenderablePlanetProjection '" << name << "' had unknown sequence type '" << sequenceType << "'"); } } + ImageSequencer::ref().addSequenceObserver(_sequenceID, "NEW HORIZONS", { "NH_LORRI", + "NH_RALPH_LEISA", + "NH_RALPH_MVIC_PAN1", + "NH_RALPH_MVIC_PAN2", + "NH_RALPH_MVIC_RED", + "NH_RALPH_MVIC_BLUE", + "NH_RALPH_MVIC_FT" }); } + + //ImageSequencer::ref().augumentSequencesWithTargets(_sequenceID); + + //@TODO planet should broadcast _sequenceID to moons (get-scenegraphnode thing) + if (_projecteeID == "CHARON"){ + _sequenceID = 0; + } + if (_projecteeID == "IO" || _projecteeID == "EUROPA" || _projecteeID == "CALLISTO" || _projecteeID == "GANYMEDE"){ + _sequenceID = 1; + } } RenderablePlanetProjection::~RenderablePlanetProjection(){ @@ -378,21 +397,26 @@ void RenderablePlanetProjection::render(const RenderData& data){ if (!_programObject) return; if (!_textureProj) return; - _camScaling = data.camera.scaling(); _up = data.camera.lookUpVector(); #ifdef GPU_PROJ if (_capture){ - attitudeParameters(_time[0]); - imageProjectGPU(); + for (auto imgSubset : _imageTimes){ + attitudeParameters(imgSubset.first); + _projectionTexturePath = imgSubset.second; + imageProjectGPU(); //fbopass + } + _capture = false; } #endif - attitudeParameters(_time[1]); + attitudeParameters(_time); + _projectionTexturePath = _defaultProjImage; + _imageTimes.clear(); psc sun_pos; double lt; - openspace::SpiceManager::ref().getTargetPosition("SUN", _projecteeID, "GALACTIC", "NONE", _time[1], sun_pos, lt); + openspace::SpiceManager::ref().getTargetPosition("SUN", _projecteeID, "GALACTIC", "NONE", _time, sun_pos, lt); // Main renderpass _programObject->activate(); @@ -420,33 +444,40 @@ void RenderablePlanetProjection::render(const RenderData& data){ void RenderablePlanetProjection::update(const UpdateData& data){ // set spice-orientation in accordance to timestamp - _time[0] = data.time; - _time[1] = _time[0]; + _time = data.time; _capture = false; - bool _withinFOV; + //happens only once + //ImageSequencer::ref().augumentSequencesWithTargets(_sequenceID); - std::string _fovTarget = ""; - for (int i = 0; i < _potentialTargets.size(); i++){ - bool success = openspace::SpiceManager::ref().targetWithinFieldOfView( - _instrumentID, - _potentialTargets[i], - _projectorID, - "ELLIPSOID", - _aberration, - _time[0], - _withinFOV); - if (success && _withinFOV){ - _fovTarget = _potentialTargets[i]; - break; + openspace::ImageSequencer::ref().findActiveInstrument(_time, _sequenceID); + openspace::ImageSequencer::ref().nextCaptureTime(_time, _sequenceID); + + bool _withinFOV; + if (_sequenceID != -1){ + std::string _fovTarget = ""; + for (int i = 0; i < _potentialTargets.size(); i++){ + bool success = openspace::SpiceManager::ref().targetWithinFieldOfView( + _instrumentID, + _potentialTargets[i], + _projectorID, + "ELLIPSOID", + _aberration, + _time, + _withinFOV); + if (success && _withinFOV){ + _fovTarget = _potentialTargets[i]; + break; + } } - } - if (_projecteeID == _fovTarget){ - _next = _defaultProjImage; - if (_time[0] >= openspace::ImageSequencer::ref().getNextCaptureTime()){ - _capture = openspace::ImageSequencer::ref().getImagePath(_time[0], _next); - } - _projectionTexturePath = _next; + + //if (_projecteeID == _fovTarget){ + if (_time >= openspace::ImageSequencer::ref().getNextCaptureTime()){ + openspace::ImageSequencer::ref().getImagePath(_imageTimes, _sequenceID, _projecteeID, _withinFOV); + + _capture = true; + } + //} } } @@ -456,7 +487,7 @@ void RenderablePlanetProjection::loadProjectionTexture(){ if (_colorTexturePath.value() != "") { _textureProj = ghoul::io::TextureReader::ref().loadTexture(absPath(_projectionTexturePath)); if (_textureProj) { - _textureProj->uploadTexture(); + _textureProj->uploadTexture(); _textureProj->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); _textureProj->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder); } diff --git a/src/rendering/renderablefov.cpp b/src/rendering/renderablefov.cpp index e2392b1fad..28687231ea 100644 --- a/src/rendering/renderablefov.cpp +++ b/src/rendering/renderablefov.cpp @@ -423,7 +423,7 @@ void RenderableFov::render(const RenderData& data){ _programObject->setUniform("ModelTransform", transform); setPscUniforms(_programObject, &data.camera, data.position); - ImageSequencer::ref().findActiveInstrument(_time); + // ImageSequencer::ref().findActiveInstrument(_time); std::string instrument = ImageSequencer::ref().getActiveInstrument(); diff --git a/src/rendering/renderableplane.cpp b/src/rendering/renderableplane.cpp index d57d83f915..d230660557 100644 --- a/src/rendering/renderableplane.cpp +++ b/src/rendering/renderableplane.cpp @@ -196,7 +196,7 @@ void RenderablePlane::loadTexture() { texture->uploadTexture(); // Textures of planets looks much smoother with AnisotropicMipMap rather than linear - texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); + texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); if (_texture) delete _texture; diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 5f7dc3e434..f4d34ef607 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -430,8 +430,7 @@ namespace openspace { Time::ref().deltaTime(), _doPerformanceMeasurements }); - - + ImageSequencer::ref().update(Time::ref().currentTime()); _sceneGraph->evaluate(_mainCamera); // clear the abuffer before rendering the scene @@ -508,7 +507,7 @@ namespace openspace { int startY = ySize - 2 * font_size_mono; double currentTime = Time::ref().currentTime(); - ImageSequencer::ref().findActiveInstrument(currentTime); + ImageSequencer::ref().getActiveInstrument(); double remaining = openspace::ImageSequencer::ref().getNextCaptureTime() - currentTime; double t = 1.f - remaining / openspace::ImageSequencer::ref().getIntervalLength(); @@ -583,8 +582,6 @@ namespace openspace { // Next 2 lines neccesary for instrument switching to work. double currentTime = Time::ref().currentTime(); - ImageSequencer::ref().findActiveInstrument(currentTime); - // GUI PRINT // Using a macro to shorten line length and increase readability diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index ed5a6b7345..e05541d0a7 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -203,7 +203,17 @@ bool SceneGraph::initialize() _programs.push_back(tmpProgram); OsEng.ref().configurationManager()->setValue("pscShader", tmpProgram); - // pscstandard + // NH shader + tmpProgram = ProgramObject::Build("NHProgram", + "${SHADERS}/nh_vs.glsl", + "${SHADERS}/nh_fs.glsl"); + if (!tmpProgram) return false; + tmpProgram->setProgramObjectCallback(cb); + + _programs.push_back(tmpProgram); + OsEng.ref().configurationManager()->setValue("NewHorizonsShader", tmpProgram); + + // fovProgram tmpProgram = ProgramObject::Build("FovProgram", "${SHADERS}/fov_vs.glsl", "${SHADERS}/fov_fs.glsl"); @@ -399,6 +409,7 @@ bool SceneGraph::loadSceneInternal(const std::string& sceneDescriptionFilePath) for (SceneGraphNode* node : _nodes) node->update({ Time::ref().currentTime() }); + // Calculate the bounding sphere for the scenegraph _root->calculateBoundingSphere(); diff --git a/src/util/imagesequencer.cpp b/src/util/imagesequencer.cpp index c7a5dc8c90..831c460eea 100644 --- a/src/util/imagesequencer.cpp +++ b/src/util/imagesequencer.cpp @@ -46,21 +46,37 @@ ImageSequencer* ImageSequencer::_sequencer = nullptr; struct ImageParams{ double startTime; - double stopTime; std::string path; std::string activeInstrument; + std::string target; bool projected; }; -auto cmp = [](const ImageParams &a, const ImageParams &b)->bool{ - return a.startTime < b.startTime; +bool imageComparer (const ImageParams &a, const ImageParams &b){ + return a.startTime < b.startTime; }; -std::vector _timeStamps; +std::vector> _timeStamps; +void createImage(std::vector& vec, double t1, std::string instrument, std::string target, std::string path = "dummypath"); + +std::vector::iterator binary_find(std::vector::iterator begin, + std::vector::iterator end, + const ImageParams &val, + bool(*imageComparer)(const ImageParams &a, const ImageParams &b)){ + // Finds the lower bound in at most log(last - first) + 1 comparisons + std::vector::iterator it = std::lower_bound(begin, end, val, imageComparer); + if (it != begin){ + return it; + } + return end; +} ImageSequencer::ImageSequencer() - : _nextCapture(0.0) - , _defaultCaptureImage(absPath("${OPENSPACE_DATA}/scene/common/textures/placeholder.png")) + : _nextCapture(-1.0) + , _currentTime(-1.0) + , _sequenceIDs(0) + , _targetsAdded(false) + , _defaultCaptureImage(absPath("C:/Users/michal/openspace/openspace-data/scene/common/textures/placeholder_blank.png")) {} @@ -78,93 +94,258 @@ void ImageSequencer::deinitialize() { _sequencer = nullptr; } -void ImageSequencer::createImage(double t1, double t2, std::string instrument, std::string path) { +void ImageSequencer::setSequenceId(int& id){ + id = _sequenceIDs; + _sequenceIDs++; +} + +void ImageSequencer::addSequenceObserver(int sequenceID, std::string name, std::vector payload){ + if (sequenceID >= 0){ + _observers.insert(std::make_pair(sequenceID, name)); + _instruments.insert(std::make_pair(name, payload)); + } +} + +void ImageSequencer::registerTargets(std::vector& potential){ + for (auto p : potential){ + if (_projectableTargets.find(p) == _projectableTargets.end()){ + _projectableTargets[p] = _currentTime; + } + } +} + +void ImageSequencer::update(double time){ + _currentTime = time; + static bool time_initialized; + + if (!time_initialized){ + for (auto &it : _projectableTargets) { + it.second = _currentTime; + assert(it.second > 0.0); + } + time_initialized = true; + } +} + +void createImage(std::vector& vec, double t1, std::string instrument, std::string target, std::string path) { // insert ImageParams image; image.startTime = t1; - image.stopTime = t2; image.path = path; image.activeInstrument = instrument; + image.target = target; image.projected = false; - _timeStamps.push_back(image); + vec.push_back(image); // sort } double ImageSequencer::getNextCaptureTime(){ return _nextCapture; } -double ImageSequencer::nextCaptureTime(double _time){ - auto binary_find = [](std::vector::iterator begin, - std::vector::iterator end, - const ImageParams &val, - bool(*cmp)(const ImageParams &a, const ImageParams &b))->std::vector::iterator{ - // Finds the lower bound in at most log(last - first) + 1 comparisons - std::vector::iterator it = std::lower_bound(begin, end, val, cmp); - if (it != begin){ - return it; - } - return end; - }; - - auto it = binary_find(_timeStamps.begin(), _timeStamps.end(), { _time, 0, "", "", false }, cmp); - - if (it == _timeStamps.end() || _time < _nextCapture) return _nextCapture; +double ImageSequencer::nextCaptureTime(double time, int sequenceID){ + if (time < _nextCapture) return _nextCapture; + auto it = binary_find(_timeStamps[sequenceID].begin(), _timeStamps[sequenceID].end(), { time, "", "", "", false }, imageComparer); + if (it == _timeStamps[sequenceID].end()) return _nextCapture; return it->startTime; } -std::string ImageSequencer::findActiveInstrument(double time){ - auto binary_find = [](std::vector::iterator begin, - std::vector::iterator end, - const ImageParams &val, - bool(*cmp)(const ImageParams &a, const ImageParams &b))->std::vector::iterator{ - // Finds the lower bound in at most log(last - first) + 1 comparisons - std::vector::iterator it = std::lower_bound(begin, end, val, cmp); - if (it != begin){ - return it; - } - return end; - }; - - auto it = binary_find(_timeStamps.begin(), _timeStamps.end(), { time, 0, "", "", false }, cmp); +std::string ImageSequencer::findActiveInstrument(double time, int sequenceID){ + auto it = binary_find(_timeStamps[sequenceID].begin(), _timeStamps[sequenceID].end(), { time, "", "", "",false }, imageComparer); - if ((it == _timeStamps.end())){ + if ((it == _timeStamps[sequenceID].end())){ _activeInstrument = "Not found, incufficient playbook-data"; }else{ _activeInstrument = std::prev(it)->activeInstrument; } - return _activeInstrument; } -bool ImageSequencer::getImagePath(double& currentTime, std::string& path, bool closedInterval){ - auto binary_find = [](std::vector::iterator begin, - std::vector::iterator end, - const ImageParams &val, - bool(*cmp)(const ImageParams &a, const ImageParams &b))->std::vector::iterator{ +void ImageSequencer::augumentSequencesWithTargets(int sequenceID){ + if (!_targetsAdded){ + // if there is an registered observer for this sequence + if (_observers.count(sequenceID) > 0) { + // find observer + std::string observer = _observers.at(sequenceID); + // find its instruments + std::map >::iterator it2 = _instruments.find(observer); + if (it2 != _instruments.end()){ + std::string _targetFOV; + bool _withinFOV; + // for each image taken + for (std::vector::iterator image = _timeStamps[sequenceID].begin(); image != _timeStamps[sequenceID].end(); ++image) { + // traverse potential targets... + for (auto t : _projectableTargets){ + // ... and potential instruments + for (auto i : it2->second){ + //register precisely which target is being projected to upon image-capture + bool success = openspace::SpiceManager::ref().targetWithinFieldOfView( + i, // Instrumnet + t.first, // projectables + observer, // new horizons + "ELLIPSOID", + "NONE", + image->startTime, + _withinFOV); + //if (!_withinFOV) image->target = "VOID"; + if (success && _withinFOV){ + image->target = t.first; + //once we find it abort search, break the loop. + break; + } + } + } + } + }else{ + LERROR("Spacecraft payload not provided, cannot write playbook"); + } + } + else{ + LERROR("Did not find observing spacecraft for sequence, cannot write playbook"); + } + _targetsAdded = true; + } +} + +bool ImageSequencer::getImagePath(std::vector>& _imageTimes, int sequenceID, std::string projectee, bool withinFOV){ + if (withinFOV && !Time::ref().timeJumped()){ + getSingleImage(_imageTimes, sequenceID, projectee); + }else{ + getMultipleImages(_imageTimes, sequenceID, projectee); + } + return true; +} + +bool ImageSequencer::getMultipleImages(std::vector>& _imageTimes, int sequenceID, std::string projectee){ + double previousTime; + std::map::iterator it = _projectableTargets.find(projectee); + if (it != _projectableTargets.end()){ + previousTime = it->second; + it->second = _currentTime; + } + auto it1 = binary_find(_timeStamps[sequenceID].begin(), _timeStamps[sequenceID].end(), { previousTime, "", "", "", false }, imageComparer); + auto it2 = binary_find(_timeStamps[sequenceID].begin(), _timeStamps[sequenceID].end(), { _currentTime, "", "", "", false }, imageComparer); + + if (it1 != _timeStamps[sequenceID].end() && it2 != _timeStamps[sequenceID].end() && it1 != it2){ + std::transform(it1, it2, std::back_inserter(_imageTimes), + [](const ImageParams& i) { + return std::make_pair(i.startTime, i.path); + }); + } + std::reverse(_imageTimes.begin(), _imageTimes.end()); + + double upcoming = nextCaptureTime(_currentTime, sequenceID); + if (_nextCapture != upcoming){ + _nextCapture = upcoming; + _intervalLength = upcoming - _currentTime; + } + + return true; +} + +bool ImageSequencer::getSingleImage(std::vector>& _imageTimes, int sequenceID, std::string projectee){ + + auto bfind = [](std::vector::iterator begin, + std::vector::iterator end, + const ImageParams &val, + bool(*imageComparer)(const ImageParams &a, const ImageParams &b))->std::vector::iterator{ // Finds the lower bound in at most log(last - first) + 1 comparisons - std::vector::iterator it = std::lower_bound(begin, end, val, cmp); + std::vector::iterator it = std::lower_bound(begin, end, val, imageComparer); if (it != begin){ return std::prev(it); } return end; }; - auto it = binary_find(_timeStamps.begin(), _timeStamps.end(), { currentTime, 0, "", "", false }, cmp); + auto it = bfind(_timeStamps[sequenceID].begin(), _timeStamps[sequenceID].end(), { _currentTime, "", "", "", false }, imageComparer); + + if (it != _timeStamps[sequenceID].end() && !it->projected){ + it->projected = true; + _imageTimes.push_back(std::make_pair(it->startTime, it->path)); + } + + double upcoming = nextCaptureTime(_currentTime, sequenceID); + if (_nextCapture != upcoming){ + _nextCapture = upcoming; + _intervalLength = upcoming - _currentTime; + } + + return true; +} +/* +bool ImageSequencer::getImagePath(std::vector>& _imageTimes, int sequenceID, std::string projectee, bool closedInterval){ + double t = _currentTime; + + double ptime; + std::map::iterator it = _previous.find(projectee); + if (it != _previous.end()){ + ptime = it->second; + it->second = _currentTime; + } + + while (t > ptime){ + auto binary_find = [](std::vector::iterator begin, + std::vector::iterator end, + const ImageParams &val, + bool(*imageComparer)(const ImageParams &a, const ImageParams &b))->std::vector::iterator{ + // Finds the lower bound in at most log(last - first) + 1 comparisons + std::vector::iterator it = std::lower_bound(begin, end, val, imageComparer); + if (it != begin){ + return std::prev(it); + } + return end; + }; + + auto it = binary_find(_timeStamps[sequenceID].begin(), _timeStamps[sequenceID].end(), { t, 0, "", "", false }, imageComparer); + + if (it == _timeStamps[sequenceID].end() || it->startTime < ptime) break; + + if (!it->projected || it != _timeStamps[sequenceID].end()){ + _imageTimes.push_back(std::make_pair(it->startTime, it->path)); + } + t = it->startTime - 1; + //it->projected = true; + } + std::reverse(_imageTimes.begin(), _imageTimes.end()); + + double upcoming = nextCaptureTime(_currentTime, sequenceID); + if (_nextCapture != upcoming){ + _nextCapture = upcoming; + _intervalLength = upcoming - _currentTime; + } + + return true; +}*/ +/* +bool ImageSequencer::getImagePath(double& currentTime, std::string& path, bool closedInterval){ + auto binary_find = [](std::vector::iterator begin, + std::vector::iterator end, + const ImageParams &val, + bool(*imageComparer)(const ImageParams &a, const ImageParams &b))->std::vector::iterator{ + // Finds the lower bound in at most log(last - first) + 1 comparisons + std::vector::iterator it = std::lower_bound(begin, end, val, imageComparer); + if (it != begin){ + return std::prev(it); + } + return end; + }; + + auto it = binary_find(_timeStamps.begin(), _timeStamps.end(), { currentTime, 0, "", "", false }, imageComparer); //check [start, stop] if (closedInterval && (it == _timeStamps.end() || it->stopTime < currentTime || it->projected)){ return false; }else if (!closedInterval && (it == _timeStamps.end() || it->projected)){ return false; } + double upcoming = nextCaptureTime(currentTime); if (_nextCapture != upcoming){ _nextCapture = upcoming; _intervalLength = upcoming - currentTime; } - + it->projected = true; path = it->path; currentTime = it->startTime; @@ -178,6 +359,9 @@ bool ImageSequencer::sequenceReset(){ } return true; } +*/ + +// ----------------- LOAD-DATA RELATED STUFF -------------------------------------- bool replace(std::string& str, const std::string& from, const std::string& to) { size_t start_pos = str.find(from); @@ -187,17 +371,6 @@ bool replace(std::string& str, const std::string& from, const std::string& to) { return true; } -bool ImageSequencer::parsePlaybook(const std::string& dir, const std::string& type, std::string year){ - ghoul::filesystem::Directory playbookDir(dir, true); - std::vector dirlist = playbookDir.read(true, false); - for (auto path : dirlist) { - bool success = parsePlaybookFile(path, year); - if (!success) - return false; - } - return true; // add check -} - double ImageSequencer::getMissionElapsedTime(std::string timestr){ std::string::size_type sz; // alias of size_t double met = std::stod(timestr, &sz); @@ -213,11 +386,13 @@ double ImageSequencer::getMissionElapsedTime(std::string timestr){ else if (met < _metRef){ et -= diff; } - return et; } -bool ImageSequencer::parsePlaybookFile(const std::string& fileName, std::string year) { +bool ImageSequencer::parsePlaybookFile(const std::string& fileName, int& sequenceID, std::string year) { + setSequenceId(sequenceID); + std::vector tmp; + if (size_t position = fileName.find_last_of(".") + 1){ if (position != std::string::npos){ std::string extension = ghoul::filesystem::File(fileName).fileExtension(); @@ -272,7 +447,7 @@ bool ImageSequencer::parsePlaybookFile(const std::string& fileName, std::string } } while (!file.eof()); - std::sort(_timeStamps.begin(), _timeStamps.end(), cmp); + std::sort(_timeStamps.begin(), _timeStamps.end(), imageComparer); std::ofstream cachedFileStream(cachedFile); cachedFileStream << std::setprecision(64); @@ -305,19 +480,23 @@ bool ImageSequencer::parsePlaybookFile(const std::string& fileName, std::string if (pos != std::string::npos){ timestr = timestr.substr(24, 9); et = getMissionElapsedTime(timestr); - createImage(et, et + shutter, id[i], _defaultCaptureImage); + createImage(tmp, et, id[i], "", _defaultCaptureImage); + std::sort(tmp.begin(), tmp.end(), imageComparer); } } } while (!file.eof()); - std::sort(_timeStamps.begin(), _timeStamps.end(), cmp); } } } + _timeStamps.push_back(tmp); return true; } -bool ImageSequencer::loadSequence(const std::string& dir) { +bool ImageSequencer::loadSequence(const std::string& dir, int& sequenceID) { + setSequenceId(sequenceID); + std::vector tmp; + ghoul::filesystem::Directory sequenceDir(dir, true); std::vector sequencePaths = sequenceDir.read(true, false); // check inputs for (auto path : sequencePaths){ @@ -333,27 +512,25 @@ bool ImageSequencer::loadSequence(const std::string& dir) { // open up label files std::string line = ""; - std::string specsOfInterest[2] = { "START_TIME", "STOP_TIME" }; - double timestamps[2] = { 0.0, 0.0 }; + std::string specsOfInterest = "START_TIME"; // can be extended + double timestamp= 0.0; bool found = false; do { std::getline(file, line); - for (int i = 0; i < 2; i++){ - auto pos = line.find(specsOfInterest[i]); + auto pos = line.find(specsOfInterest); if (pos != std::string::npos){ std::string time = line.substr(line.find("=") + 2); time.erase(std::remove(time.begin(), time.end(), ' '), time.end()); - openspace::SpiceManager::ref().getETfromDate(time, timestamps[i]); + openspace::SpiceManager::ref().getETfromDate(time, timestamp); } - } - if (timestamps[0] != 0.0 && timestamps[1] != 0.0){ + if (timestamp != 0.0){ found = true; std::string ext = "jpg"; path.replace(path.begin() + position, path.end(), ext); bool fileExists = FileSys.fileExists(path); if (fileExists) { - createImage(timestamps[0], timestamps[1], "NH_LORRI", path); /// fix active instrument! - std::sort(_timeStamps.begin(), _timeStamps.end(), cmp); + createImage(tmp, timestamp, "NH_LORRI", "", path); /// fix active instrument! + std::sort(tmp.begin(), tmp.end(), imageComparer); } } } while (!file.eof() && found == false); @@ -361,6 +538,7 @@ bool ImageSequencer::loadSequence(const std::string& dir) { } } } + _timeStamps.push_back(tmp); return !_timeStamps.empty(); } From d12420928177ea40474b1a637d2041c36b9620a2 Mon Sep 17 00:00:00 2001 From: Michal Marcinkowski Date: Thu, 9 Apr 2015 12:36:05 -0400 Subject: [PATCH 03/45] new imagesequencer class - WIP. Temporarily calling it "imagesequencer2" --- .../planets/renderableplanetprojection.h | 16 +- include/openspace/util/camerainstrument.h | 46 +++ include/openspace/util/hongkangparser.h | 85 +++++ include/openspace/util/imagesequencer.h | 3 +- include/openspace/util/imagesequencer2.h | 109 ++++++ include/openspace/util/payload.h | 47 +++ include/openspace/util/scannerinstrument.h | 46 +++ include/openspace/util/sequenceparser.h | 71 ++++ openspace-data | 2 +- scripts/default_startup.lua | 2 +- src/abuffer/abuffer.cpp | 4 +- src/engine/openspaceengine.cpp | 3 + .../planets/renderableplanetprojection.cpp | 170 +++++---- src/rendering/renderablefov.cpp | 116 +++--- src/rendering/renderengine.cpp | 70 +++- src/scenegraph/spiceephemeris.cpp | 1 + src/util/camerainstrument.cpp | 50 +++ src/util/factorymanager.cpp | 8 + src/util/hongkangparser.cpp | 276 +++++++++++++++ src/util/imagesequencer.cpp | 20 +- src/util/imagesequencer2.cpp | 335 ++++++++++++++++++ src/util/payload.cpp | 59 +++ src/util/scannerinstrument.cpp | 49 +++ 23 files changed, 1445 insertions(+), 143 deletions(-) create mode 100644 include/openspace/util/camerainstrument.h create mode 100644 include/openspace/util/hongkangparser.h create mode 100644 include/openspace/util/imagesequencer2.h create mode 100644 include/openspace/util/payload.h create mode 100644 include/openspace/util/scannerinstrument.h create mode 100644 include/openspace/util/sequenceparser.h create mode 100644 src/util/camerainstrument.cpp create mode 100644 src/util/hongkangparser.cpp create mode 100644 src/util/imagesequencer2.cpp create mode 100644 src/util/payload.cpp create mode 100644 src/util/scannerinstrument.cpp diff --git a/include/openspace/rendering/planets/renderableplanetprojection.h b/include/openspace/rendering/planets/renderableplanetprojection.h index a6a2c57fa0..016f6ee3cc 100644 --- a/include/openspace/rendering/planets/renderableplanetprojection.h +++ b/include/openspace/rendering/planets/renderableplanetprojection.h @@ -29,6 +29,12 @@ // open space includes #include #include +#include + +#include +#include +#include + #include #include @@ -71,6 +77,8 @@ protected: private: void imageProjectGPU(); + std::map _fileTranslation; + properties::StringProperty _colorTexturePath; properties::StringProperty _projectionTexturePath; properties::TriggerProperty _imageTrigger; @@ -87,12 +95,19 @@ private: glm::mat4 _transform; glm::mat4 _projectorMatrix; + //sequenceloading + std::string _sequenceSource; + std::string _sequenceType; + bool _foundSequence; + // spice std::string _instrumentID; std::string _projectorID; std::string _projecteeID; std::string _aberration; std::vector _potentialTargets; // @TODO copy-n-paste from renderablefov + + float _fovy; float _aspectRatio; float _nearPlane; @@ -110,7 +125,6 @@ private: std::vector> _imageTimes; int _sequenceID; - std::string _target; std::string _defaultProjImage; std::string _next; diff --git a/include/openspace/util/camerainstrument.h b/include/openspace/util/camerainstrument.h new file mode 100644 index 0000000000..6236f83896 --- /dev/null +++ b/include/openspace/util/camerainstrument.h @@ -0,0 +1,46 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 __CAMERAINSTRUMENT_H__ +#define __CAMERAINSTRUMENT_H__ + +#include + +#include + +namespace openspace { + +class CameraInstrument : public Payload { +public: + CameraInstrument(const ghoul::Dictionary& dictionary); + virtual std::string getType(); + virtual std::vector getSpiceIDs(); +private: + std::string _type; + std::vector _spiceIDs; +}; + +} // namespace openspace + +#endif // __CAMERAINSTRUMENT_H__ diff --git a/include/openspace/util/hongkangparser.h b/include/openspace/util/hongkangparser.h new file mode 100644 index 0000000000..63d52ae535 --- /dev/null +++ b/include/openspace/util/hongkangparser.h @@ -0,0 +1,85 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014-2015 * +* * +* 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 __HONGKANGPARSER_H__ +#define __HONGKANGPARSER_H__ +#include +#include + + +#include +#include +#include + +namespace openspace { + + class HongKangParser : public SequenceParser{ + public: + HongKangParser(); + HongKangParser(const std::string& fileName, + std::string spacecraft, + std::map acronymDictionary, + std::vector potentialTargets); + virtual void create(); + virtual std::map getSubsetMap(); + virtual std::vector> getIstrumentTimes(); + virtual std::vector> getTargetTimes(); + + // temporary need to figure this out + std::map getAcronymDictionary(){ return _fileTranslation; }; + + private: + double getMetFromET(double et); + double getETfromMet(std::string timestr); + double getETfromMet(double met); + + void createImage(Image& image, + double startTime, + double stopTime, + std::vector instr, + std::string targ, + std::string pot); + + bool augmentWithSpice(Image& image, + std::string spacecraft, + std::vector payload, + std::vector potentialTargets); + + + std::map _subsetMap; + std::vector> _instrumentTimes; + std::vector> _targetTimes; + + std::string _defaultCaptureImage; + double _metRef = 299180517; + + std::string _fileName; + std::string _spacecraft; + std::map _fileTranslation; + std::vector _potentialTargets; + }; + +} +#endif //__HONGKANGPARSER_H__ \ No newline at end of file diff --git a/include/openspace/util/imagesequencer.h b/include/openspace/util/imagesequencer.h index a557a45205..8dad22159c 100644 --- a/include/openspace/util/imagesequencer.h +++ b/include/openspace/util/imagesequencer.h @@ -99,11 +99,10 @@ public: */ bool parsePlaybook(const std::string& dir, const std::string& type, std::string year = "2015"); bool parsePlaybookFile(const std::string& fileName, int& sequenceID, std::string year = "2015"); - /* * These three methods augment the playbook */ - void augumentSequencesWithTargets(int sequenceID); + void augumentSequenceWithTargets(int sequenceID); void addSequenceObserver(int sequenceID, std::string name, std::vector payload); void registerTargets(std::vector& potential); diff --git a/include/openspace/util/imagesequencer2.h b/include/openspace/util/imagesequencer2.h new file mode 100644 index 0000000000..4a9982c744 --- /dev/null +++ b/include/openspace/util/imagesequencer2.h @@ -0,0 +1,109 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014 * +* * +* 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 __ImageSequencer2_H__ +#define __ImageSequencer2_H__ + +// open space includes +#include +#include +#include +#include +#include +#include + +#include + +namespace openspace { +class ImageSequencer2 { +public: + ImageSequencer2(); + /** + * Singelton instantiation + */ + static ImageSequencer2* _instance; + + static ImageSequencer2& ref(); + static void initialize(); + static void deinitialize(); + + //provides the sequencer with current time + void updateSequencer(double time); + + void runSequenceParser(SequenceParser* parser); + + //translates playbook ambiguous namesetting to spice calls, augments each observation with targets and + //stores all images in its own subset (see _subsetMap member) + bool parsePlaybookFile(const std::string& fileName, + std::string spacecraft, + std::map> acronymDictionary, + std::vector potentialTargets); + + // returns upcoming target + std::pair getNextTarget(); + // returns next target + std::pair getCurrentTarget(); + // returns current target and (in the list) adjacent targets, the number to retrieve is user set + std::pair> getIncidentTargetList(int range = 2); + + double getNextCaptureTime(); + + //a fov class can check whether or not its active + bool instumentActive(std::string instrumentID); + //get all currently active instruments + std::vector getActiveInstruments(); + + const Image* findLatestImageInSubset( ImageSubset& subset); +private: + //default comparison function + bool imageComparer(const Image &a, const Image &b); + + //binary find O(log n) always + std::vector::iterator binary_find(std::vector::iterator begin, + std::vector::iterator end, + const Image &val, + bool(*imageComparer)(const Image &a, const Image &b)); + + //var + double _currentTime; + double _previousTime; + + std::string _defaultCaptureImage; + std::vector _currentlyActiveInstruments; + + std::map _subsetMap; + std::vector> _targetTimes; + std::vector> _instrumentTimes; + //std::vector _activeInstruments + std::map> _acronymDictionary; + + static bool hasData(); + +}; + +} // namespace openspace + + +#endif // __ImageSequencer2_H__ + diff --git a/include/openspace/util/payload.h b/include/openspace/util/payload.h new file mode 100644 index 0000000000..5974e44680 --- /dev/null +++ b/include/openspace/util/payload.h @@ -0,0 +1,47 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 __PAYLOAD_H__ +#define __PAYLOAD_H__ + +#include +#include + +namespace openspace { + +class Payload { +public: + static Payload* createFromDictionary(const ghoul::Dictionary& dictionary, const std::string type); + + Payload(const ghoul::Dictionary& dictionary); + virtual ~Payload(); + virtual std::string getType() = 0; + virtual std::vector getSpiceIDs() = 0; +protected: + Payload(); +}; + +} // namespace openspace + +#endif // __PAYLOAD_H__ diff --git a/include/openspace/util/scannerinstrument.h b/include/openspace/util/scannerinstrument.h new file mode 100644 index 0000000000..16aa51b079 --- /dev/null +++ b/include/openspace/util/scannerinstrument.h @@ -0,0 +1,46 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 __SCANNERINSTRUMENT_H__ +#define __SCANNERINSTRUMENT_H__ + +#include + +#include + +namespace openspace { + +class ScannerInstrument : public Payload { +public: + ScannerInstrument(const ghoul::Dictionary& dictionary); + virtual std::string getType(); + virtual std::vector getSpiceIDs(); +private: + std::string _type; + std::vector _spiceIDs; +}; + +} // namespace openspace + +#endif // __SCANNERINSTRUMENT_H__ diff --git a/include/openspace/util/sequenceparser.h b/include/openspace/util/sequenceparser.h new file mode 100644 index 0000000000..96d4427c57 --- /dev/null +++ b/include/openspace/util/sequenceparser.h @@ -0,0 +1,71 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014-2015 * +* * +* 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 __SEQUENCEPARSER_H__ +#define __SEQUENCEPARSER_H__ +#include +#include +#include + +#include +#include +#include + +namespace openspace { + struct Image{ + double startTime; + double stopTime; + std::string path; + std::vector activeInstruments; + std::string target; + bool projected; + }; + struct TimeRange{ + TimeRange() : _min(-1), _max(-1){}; + void setRange(double val){ + if (_min > val || _min < 0) _min = val; + if (_max < val || _max < 0) _max = val; + }; + bool inRange(double min, double max){ + return (min >= _min && max <= _max); + } + double _min; + double _max; + }; + struct ImageSubset{ + TimeRange _range; + std::vector < Image > _subset; + }; + +class SequenceParser{ +public: + virtual void create() = 0; + virtual std::map getSubsetMap() = 0; + virtual std::vector> getIstrumentTimes() = 0; + virtual std::vector> getTargetTimes() = 0; + virtual std::map getAcronymDictionary() = 0; +}; +} +#endif //__SEQUENCEPARSER_H__ diff --git a/openspace-data b/openspace-data index 4fed5a4528..6f38f868b6 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 4fed5a45286c25d593f53920902b5bda0ca6d9c7 +Subproject commit 6f38f868b6ead66776c641095cdf9b9edbf77ec6 diff --git a/scripts/default_startup.lua b/scripts/default_startup.lua index 19cd4413d1..164eff55fc 100644 --- a/scripts/default_startup.lua +++ b/scripts/default_startup.lua @@ -14,7 +14,7 @@ dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) -- Load the default keyb -- openspace.time.setDeltaTime(50); -openspace.time.setTime("2015-07-14T10:10:00.00") -- PLUTO +openspace.time.setTime("2015-07-14T11:49:40.00") -- PLUTO -- NH takes series of images from visible to dark side (across terminator) -- Sequence lasts ~10 mins, (recommended dt = 10) diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index cba919f076..fbb12a3b3e 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -147,12 +147,12 @@ void ABuffer::resolve() { // Decrease stepsize in volumes if right click is pressed // TODO: Let the interactionhandler handle this - int val = sgct::Engine::getMouseButton(0, SGCT_MOUSE_BUTTON_RIGHT); + /*int val = sgct::Engine::getMouseButton(0, SGCT_MOUSE_BUTTON_RIGHT); float volumeStepFactor = (val) ? 0.2f: 1.0f; if(volumeStepFactor != _volumeStepFactor) { _volumeStepFactor = volumeStepFactor; _resolveShader->setUniform("volumeStepFactor", _volumeStepFactor); - } + }*/ glBindVertexArray(_screenQuad); glDrawArrays(GL_TRIANGLES, 0, 6); diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index ee00946979..132b43e705 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -45,6 +45,8 @@ #include #include #include +#include // testing + #include @@ -101,6 +103,7 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName) SpiceManager::initialize(); Time::initialize(); ImageSequencer::initialize(); + ImageSequencer2::initialize(); FactoryManager::initialize(); ghoul::systemcapabilities::SystemCapabilities::initialize(); } diff --git a/src/rendering/planets/renderableplanetprojection.cpp b/src/rendering/planets/renderableplanetprojection.cpp index a990de1d95..13ee2d3b3d 100644 --- a/src/rendering/planets/renderableplanetprojection.cpp +++ b/src/rendering/planets/renderableplanetprojection.cpp @@ -36,6 +36,8 @@ #include #include +#include + #include #include #include @@ -48,17 +50,21 @@ namespace { const std::string _loggerCat = "RenderablePlanetProjection"; - const std::string keyProjObserver = "Projection.Observer"; - const std::string keyProjTarget = "Projection.Target"; - const std::string keyProjAberration = "Projection.Aberration"; - 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 keySequenceDir = "Projection.Sequence"; - const std::string keySequenceType = "Projection.SequenceType"; + const std::string keyProjObserver = "Projection.Observer"; + const std::string keyProjTarget = "Projection.Target"; + const std::string keyProjAberration = "Projection.Aberration"; + 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 keySequenceDir = "Projection.Sequence"; + const std::string keySequenceType = "Projection.SequenceType"; const std::string keyPotentialTargets = "PotentialTargets"; + const std::string keyTranslation = "PlaybookTranslation"; + + + const std::string keyFrame = "Frame"; const std::string keyGeometry = "Geometry"; const std::string keyShading = "PerformShading"; @@ -73,6 +79,8 @@ namespace { namespace openspace { +//#define ORIGINAL_SEQUENCER + RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _colorTexturePath("planetTexture", "RGB Texture") @@ -107,12 +115,12 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& dictionary.getValue(keyFrame, _target); - bool b1 = dictionary.getValue(keyInstrument, _instrumentID); // NH_LORRRI - bool b2 = dictionary.getValue(keyProjObserver, _projectorID); // NH_SPACECRAFT - bool b3 = dictionary.getValue(keyProjTarget, _projecteeID); // PLUTO - bool b4 = dictionary.getValue(keyProjAberration, _aberration); // NONE - bool b5 = dictionary.getValue(keyInstrumentFovy, _fovy); // deg - bool b6 = dictionary.getValue(keyInstrumentAspect, _aspectRatio); // .... + bool b1 = dictionary.getValue(keyInstrument, _instrumentID); + bool b2 = dictionary.getValue(keyProjObserver, _projectorID); + bool b3 = dictionary.getValue(keyProjTarget, _projecteeID); + bool b4 = dictionary.getValue(keyProjAberration, _aberration); + bool b5 = dictionary.getValue(keyInstrumentFovy, _fovy); + bool b6 = dictionary.getValue(keyInstrumentAspect, _aspectRatio); bool b7 = dictionary.getValue(keyInstrumentNear, _nearPlane); bool b8 = dictionary.getValue(keyInstrumentFar, _farPlane); @@ -137,8 +145,6 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& _potentialTargets[i] = target; } - ImageSequencer::ref().registerTargets(_potentialTargets); - // TODO: textures need to be replaced by a good system similar to the geometry as soon // as the requirements are fixed (ab) std::string texturePath = ""; @@ -160,44 +166,58 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& addProperty(_projectionTexturePath); _projectionTexturePath.onChange(std::bind(&RenderablePlanetProjection::loadProjectionTexture, this)); - std::string sequenceSource; - bool found = dictionary.getValue(keySequenceDir, sequenceSource); - if (found) { - //LERROR("RenderablePlanetProjection '" << name << "' did not contain a sequence source"); - sequenceSource = absPath(sequenceSource); - //sequenceSource = path + ghoul::filesystem::FileSystem::PathSeparator + sequenceSource; + // std::string sequenceSource; + bool _foundSequence = dictionary.getValue(keySequenceDir, _sequenceSource); + if (_foundSequence) { + _sequenceSource = absPath(_sequenceSource); - std::string sequenceType; - found = dictionary.getValue(keySequenceType, sequenceType); - if (found) { - if (sequenceType == sequenceTypeImage) { - openspace::ImageSequencer::ref().loadSequence(sequenceSource, _sequenceID); - } - else if (sequenceType == sequenceTypePlaybook) { - openspace::ImageSequencer::ref().parsePlaybookFile(sequenceSource, _sequenceID); - } - else { - LERROR("RenderablePlanetProjection '" << name << "' had unknown sequence type '" << sequenceType << "'"); - } - } - ImageSequencer::ref().addSequenceObserver(_sequenceID, "NEW HORIZONS", { "NH_LORRI", - "NH_RALPH_LEISA", - "NH_RALPH_MVIC_PAN1", - "NH_RALPH_MVIC_PAN2", - "NH_RALPH_MVIC_RED", - "NH_RALPH_MVIC_BLUE", - "NH_RALPH_MVIC_FT" }); + _foundSequence = dictionary.getValue(keySequenceType, _sequenceType); + //Important: client must define translation-list in mod file IFF playbook + if (dictionary.hasKey(keyTranslation) && _sequenceType == sequenceTypePlaybook){ + ghoul::Dictionary translationDictionary; + //get translation dictionary + dictionary.getValue(keyTranslation, translationDictionary); + + //get the different instrument types + const std::vector& types = translationDictionary.keys(); + //for each instrument + for (int i = 0; i < types.size(); i++){ + std::string classtype = types[i]; + std::string currentType = keyTranslation + "." + classtype; + //create dictionary containing all {playbookKeys , spice IDs} + ghoul::Dictionary typeDictionary; + dictionary.getValue(keyTranslation + "." + classtype, typeDictionary); + //for each playbook call -> create a Payload object + const std::vector& keys = typeDictionary.keys(); + for (int j = 0; j < keys.size(); j++){ + std::string playbookKey = keys[j]; + std::string currentKey = currentType + "." + playbookKey; + //using dictionary as a way to extract the spiceIDs we need + ghoul::Dictionary spiceDictionary; + dictionary.getValue(currentKey, spiceDictionary); + //create payload + Payload *payload = Payload::createFromDictionary(spiceDictionary, classtype); + //insert payload to map - this will be used in the parser to determine + //behavioral characteristics of each instrument + _fileTranslation[playbookKey] = payload; + } + } + } + else{ + LWARNING("No playbook translation provided, please make sure all spice calls match playbook!"); + } + // Have to delay playbook load in order to augment with targets once current AND spacecraft kernels loaded + for (auto p : _fileTranslation){ + std::vector k = _fileTranslation[p.first]->getSpiceIDs(); + std::cout << "TYPE : " << _fileTranslation[p.first]->getType() << std::endl; + std::cout << "FILE-CALL : " << p.first << std::endl; + std::cout << "SPICE ID'S :" << std::endl; + for (auto r : k){ + std::cout << r << std::endl; + } + std::cout << std::endl; + } } - - //ImageSequencer::ref().augumentSequencesWithTargets(_sequenceID); - - //@TODO planet should broadcast _sequenceID to moons (get-scenegraphnode thing) - if (_projecteeID == "CHARON"){ - _sequenceID = 0; - } - if (_projecteeID == "IO" || _projecteeID == "EUROPA" || _projecteeID == "CALLISTO" || _projecteeID == "GANYMEDE"){ - _sequenceID = 1; - } } RenderablePlanetProjection::~RenderablePlanetProjection(){ @@ -401,14 +421,14 @@ void RenderablePlanetProjection::render(const RenderData& data){ _up = data.camera.lookUpVector(); #ifdef GPU_PROJ - if (_capture){ +/* if (_capture){ for (auto imgSubset : _imageTimes){ - attitudeParameters(imgSubset.first); - _projectionTexturePath = imgSubset.second; + attitudeParameters(imgSubset.first); // projector viewmatrix + _projectionTexturePath = imgSubset.second; // path to current images imageProjectGPU(); //fbopass } _capture = false; - } + }*/ #endif attitudeParameters(_time); _projectionTexturePath = _defaultProjImage; @@ -446,16 +466,36 @@ void RenderablePlanetProjection::update(const UpdateData& data){ // set spice-orientation in accordance to timestamp _time = data.time; _capture = false; - +#ifndef ORIGINAL_SEQUENCER + static bool once; + if (Time::ref().deltaTime() > 0 && !once){ + if (_foundSequence) { + if (_sequenceType == sequenceTypeImage) { + openspace::ImageSequencer::ref().loadSequence(_sequenceSource, _sequenceID); + } + else if (_sequenceType == sequenceTypePlaybook) { + SequenceParser* parser = new HongKangParser(_sequenceSource, + "NEW HORIZONS", + _fileTranslation, + _potentialTargets); + openspace::ImageSequencer2::ref().runSequenceParser(parser); + } + } + once = true; + } + if (Time::ref().deltaTime() > 10){ + openspace::ImageSequencer2::ref().updateSequencer(_time); + } +#else //happens only once //ImageSequencer::ref().augumentSequencesWithTargets(_sequenceID); - + openspace::ImageSequencer::ref().findActiveInstrument(_time, _sequenceID); openspace::ImageSequencer::ref().nextCaptureTime(_time, _sequenceID); - + bool _withinFOV; if (_sequenceID != -1){ - std::string _fovTarget = ""; + std::string _fovTarget = ""; for (int i = 0; i < _potentialTargets.size(); i++){ bool success = openspace::SpiceManager::ref().targetWithinFieldOfView( _instrumentID, @@ -470,15 +510,17 @@ void RenderablePlanetProjection::update(const UpdateData& data){ break; } } - + //if (_projecteeID == _fovTarget){ if (_time >= openspace::ImageSequencer::ref().getNextCaptureTime()){ openspace::ImageSequencer::ref().getImagePath(_imageTimes, _sequenceID, _projecteeID, _withinFOV); - _capture = true; } //} + } + +#endif } void RenderablePlanetProjection::loadProjectionTexture(){ diff --git a/src/rendering/renderablefov.cpp b/src/rendering/renderablefov.cpp index 28687231ea..31f266fed1 100644 --- a/src/rendering/renderablefov.cpp +++ b/src/rendering/renderablefov.cpp @@ -30,6 +30,9 @@ #include #include +#include // testing +#include + #include #include @@ -297,44 +300,46 @@ void RenderableFov::fovProjection(bool H[], std::vector bounds){ glm::dvec3 current; glm::dvec3 next; glm::vec4 tmp(1); - - for (int i = 0; i < 4; i++){ - int k = (i + 1 > 3) ? 0 : i + 1; - current = bounds[i]; - next = bounds[k]; - if (H[i] == false){ // If point is non-interceptive, project it. - insertPoint(_varray2, orthogonalProjection(current), tmp); - } - if (H[i] == true && H[i + 1] == false){ // current point is interceptive, next is not - // find outer most point for interpolation - mid = bisection(current, next, tolerance); - for (int j = 1; j <= _isteps; j++){ - t = ((double)j / _isteps); - // TODO: change the interpolate scheme to place points not on a straight line but instead - // using either slerp or some other viable method (goal: eliminate checkForIntercept -method) - interpolated = interpolate(current, mid, t); - _interceptVector = (j < _isteps) ? checkForIntercept(interpolated) : orthogonalProjection(interpolated); - insertPoint(_varray2, _interceptVector, col_sq); + if (bounds.size() > 1){ + for (int i = 0; i < 4; i++){ + int k = (i + 1 > 4 - 1) ? 0 : i + 1; + + current = bounds[i]; + next = bounds[k]; + if (H[i] == false){ // If point is non-interceptive, project it. + insertPoint(_varray2, orthogonalProjection(current), tmp); + } + if (H[i] == true && H[i + 1] == false){ // current point is interceptive, next is not + // find outer most point for interpolation + mid = bisection(current, next, tolerance); + for (int j = 1; j <= _isteps; j++){ + t = ((double)j / _isteps); + // TODO: change the interpolate scheme to place points not on a straight line but instead + // using either slerp or some other viable method (goal: eliminate checkForIntercept -method) + interpolated = interpolate(current, mid, t); + _interceptVector = (j < _isteps) ? checkForIntercept(interpolated) : orthogonalProjection(interpolated); + insertPoint(_varray2, _interceptVector, col_sq); + } + } + if (H[i] == false && H[i + 1] == true){ // current point is non-interceptive, next is + mid = bisection(next, current, tolerance); + for (int j = 1; j <= _isteps; j++){ + t = ((double)j / _isteps); + interpolated = interpolate(mid, next, t); + _interceptVector = (j > 1) ? checkForIntercept(interpolated) : orthogonalProjection(interpolated); + insertPoint(_varray2, _interceptVector, col_sq); + } + } + if (H[i] == true && H[i + 1] == true){ // both points intercept + for (int j = 0; j <= _isteps; j++){ + t = ((double)j / _isteps); + interpolated = interpolate(current, next, t); + _interceptVector = checkForIntercept(interpolated); + insertPoint(_varray2, _interceptVector, col_sq); + } } } - if (H[i] == false && H[i+1] == true){ // current point is non-interceptive, next is - mid = bisection(next, current, tolerance); - for (int j = 1; j <= _isteps; j++){ - t = ((double)j / _isteps); - interpolated = interpolate(mid, next, t); - _interceptVector = (j > 1) ? checkForIntercept(interpolated) : orthogonalProjection(interpolated); - insertPoint(_varray2, _interceptVector, col_sq); - } - } - if (H[i] == true && H[i + 1] == true){ // both points intercept - for (int j = 0; j <= _isteps; j++){ - t = ((double)j / _isteps); - interpolated = interpolate(current, next, t); - _interceptVector = checkForIntercept(interpolated); - insertPoint(_varray2, _interceptVector, col_sq); - } - } - } + } // only if new points are inserted are we interested in rebuilding the // vbo. Note that this can be optimized but is left as is for now. if (_nrInserted == 0){ @@ -349,7 +354,7 @@ void RenderableFov::fovProjection(bool H[], std::vector bounds){ for (int i = 0; i < _isize[1]; i++) _iarray1[1][i] = i; } - + } void RenderableFov::updateData(){ @@ -391,7 +396,7 @@ void RenderableFov::computeColors(){ col_gray = glm::vec4(0.3, 0.3, 0.3, 1); col_start = glm::vec4(1.00, 0.89, 0.00, 1); col_sq = glm::vec4(1.00, 0.29, 0.00, 1); - + /* col_end.x = c_project.x*t + col_end.x*(1 - t); col_end.y = c_project.y*t + col_end.y*(1 - t); col_end.z = c_project.z*t + col_end.z*(1 - t); @@ -403,6 +408,10 @@ void RenderableFov::computeColors(){ col_sq.x = c_project.x*t + col_sq.x*(1 - t); col_sq.y = c_project.y*t + col_sq.y*(1 - t); col_sq.z = c_project.z*t + col_sq.z*(1 - t); + */ + blue.w = 0.5; + c_project.w = 0.5; + col_end.w = 0.5; } void RenderableFov::render(const RenderData& data){ @@ -423,24 +432,13 @@ void RenderableFov::render(const RenderData& data){ _programObject->setUniform("ModelTransform", transform); setPscUniforms(_programObject, &data.camera, data.position); - // ImageSequencer::ref().findActiveInstrument(_time); - - std::string instrument = ImageSequencer::ref().getActiveInstrument(); - + bool drawFOV = false; - if (instrument == "MVIC"){ - if (_instrumentID == "NH_RALPH_MVIC_PAN1" || - _instrumentID == "NH_RALPH_MVIC_PAN2" || - _instrumentID == "NH_RALPH_MVIC_RED" || - _instrumentID == "NH_RALPH_MVIC_BLUE" || - _instrumentID == "NH_RALPH_MVIC_FT"){ - drawFOV = true; - } - } - else if (instrument == _instrumentID){ - drawFOV = true; + if (Time::ref().deltaTime() > 10){ + drawFOV = ImageSequencer2::ref().instumentActive(_instrumentID); } + if (drawFOV){ // update only when time progresses. if (_oldTime != _time){ @@ -477,12 +475,13 @@ void RenderableFov::render(const RenderData& data){ double targetEpoch; // for each FOV vector - for (int i = 0; i < 4; i++){ + for (int i = 0; i < bounds.size(); i++){ // compute surface intercept openspace::SpiceManager::ref().getSurfaceIntercept(_fovTarget, _spacecraft, _instrumentID, _frame, _method, _aberrationCorrection, _time, targetEpoch, bounds[i], ipoint, ivec, _interceptTag[i]); // if not found, use the orthogonal projected point + if (!_interceptTag[i]) _projectionBounds[i] = orthogonalProjection(bounds[i]); // VBO1 : draw vectors representing outer points of FOV. @@ -512,7 +511,7 @@ void RenderableFov::render(const RenderData& data){ indx += 4; } else{ - glm::vec4 corner(bounds[i][0], bounds[i][1], bounds[i][2], data.position[3] + 1); + glm::vec4 corner(bounds[i][0], bounds[i][1], bounds[i][2], data.position[3] + 2); corner = tmp*corner; // "INFINITE" FOV memcpy(&_varray1[indx], glm::value_ptr(glm::vec4(0)), size); @@ -533,7 +532,12 @@ void RenderableFov::render(const RenderData& data){ glLineWidth(_lineWidth); glBindVertexArray(_vaoID[0]); - glDrawArrays(_mode, 0, _vtotal[0]); + glDrawArrays(GL_TRIANGLE_STRIP, 0, _vtotal[0]); + glBindVertexArray(0); + + glLineWidth(_lineWidth); + glBindVertexArray(_vaoID[0]); + glDrawArrays(GL_LINES, 0, _vtotal[0]); glBindVertexArray(0); //render points diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index f4d34ef607..2842cb1e03 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -24,6 +24,10 @@ #include +#include +#include + + #include #include #include @@ -39,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -507,7 +510,6 @@ namespace openspace { int startY = ySize - 2 * font_size_mono; double currentTime = Time::ref().currentTime(); - ImageSequencer::ref().getActiveInstrument(); double remaining = openspace::ImageSequencer::ref().getNextCaptureTime() - currentTime; double t = 1.f - remaining / openspace::ImageSequencer::ref().getIntervalLength(); @@ -546,9 +548,14 @@ namespace openspace { ); } + std::vector instrVec = ImageSequencer2::ref().getActiveInstruments(); - std::string active = ImageSequencer::ref().getActiveInstrument(); - Freetype::print(font, + std::string active =""; + for (int i = 0; i < instrVec.size(); i++){ + active.append(instrVec[i]); + active.append(" "); + } + Freetype::print(font, _onScreenInformation._position.x * xSize, _onScreenInformation._position.y * ySize - font_size_mono * 3 * 2, glm::vec4(0.3, 0.6, 1, 1), @@ -597,6 +604,7 @@ namespace openspace { PrintText(i++, "Cam->origin: (% .15f, % .4f)", pssl[0], pssl[1]); PrintText(i++, "Scaling: (% .5f, % .5f)", scaling[0], scaling[1]); + double remaining = openspace::ImageSequencer::ref().getNextCaptureTime() - currentTime; double t = 1.f - remaining / openspace::ImageSequencer::ref().getIntervalLength(); std::string progress = "|"; @@ -616,10 +624,58 @@ namespace openspace { } glm::vec4 w(1); glm::vec4 b(0.3, 0.6, 1, 1); - PrintColorText(i++, "Ucoming : %s", 10, w, str.c_str()); + glm::vec4 b2(0.5, 1, 0.5, 1); + PrintColorText(i++, "Ucoming capture : %s", 10, w, str.c_str()); - std::string active = ImageSequencer::ref().getActiveInstrument(); - PrintColorText(i++, "Active Instrument : %s", 10, b, active.c_str()); + + if (Time::ref().deltaTime() > 10){ + std::pair nextTarget = ImageSequencer2::ref().getNextTarget(); + std::pair currentTarget = ImageSequencer2::ref().getCurrentTarget(); + + int timeleft = nextTarget.first - currentTime; + + int hour = timeleft / 3600; + int second = timeleft % 3600; + int minute = second / 60; + second = second % 60; + + std::string hh, mm, ss, coundtown; + + 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)); + + PrintColorText(i++, "Switching observation focus in : [%s:%s:%s]", 10, b2, hh.c_str(), mm.c_str(), ss.c_str()); + + std::pair> incidentTargets = ImageSequencer2::ref().getIncidentTargetList(2); + std::string space; + glm::vec4 color; + int isize = incidentTargets.second.size(); + for (int p = 0; p < isize; p++){ + double t = (double)(p + 1) / (double)(isize+1); + t = (p > isize / 2) ? 1-t : t; + t += 0.3; + color = (p == isize / 2) ? glm::vec4(0, 1, 0, 1) : glm::vec4(t, t, t, 1); + PrintColorText(i, "%s%s", 10, color, space.c_str(), incidentTargets.second[p].c_str()); + for (int k = 0; k < 10; k++){ space += " "; } + } + i++; + + + } + + std::vector instrVec = ImageSequencer2::ref().getActiveInstruments(); + + std::string active = ""; + for (int i = 0; i < instrVec.size(); i++){ + active.append(instrVec[i]); + active.append("\n"); + } + PrintColorText(i++, "Active Instrument : %5s", 10, b, active.c_str()); #undef PrintText } diff --git a/src/scenegraph/spiceephemeris.cpp b/src/scenegraph/spiceephemeris.cpp index 88395676d2..0e42a8f9da 100644 --- a/src/scenegraph/spiceephemeris.cpp +++ b/src/scenegraph/spiceephemeris.cpp @@ -73,6 +73,7 @@ void SpiceEphemeris::update(const UpdateData& data) { glm::dvec3 position(0,0,0); double lightTime = 0.0; + SpiceManager::ref().getTargetPosition(_targetName, _originName, "GALACTIC", "NONE", data.time, position, lightTime); diff --git a/src/util/camerainstrument.cpp b/src/util/camerainstrument.cpp new file mode 100644 index 0000000000..71d820d1ae --- /dev/null +++ b/src/util/camerainstrument.cpp @@ -0,0 +1,50 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +namespace { + const std::string _loggerCat = "CameraInstrument"; +} + +namespace openspace { + +CameraInstrument::CameraInstrument(const ghoul::Dictionary& dictionary) :_type("CAMERA") +{ + std::string value; + for (int k = 0; k < dictionary.size(); k++){ + dictionary.getValue(std::to_string(k + 1), value); + _spiceIDs.push_back(value); + } +} + +std::string CameraInstrument::getType(){ + return _type; +} + +std::vector CameraInstrument::getSpiceIDs(){ + return _spiceIDs; +} + +} // namespace openspace \ No newline at end of file diff --git a/src/util/factorymanager.cpp b/src/util/factorymanager.cpp index 4dac141501..8ddfc6e1d7 100644 --- a/src/util/factorymanager.cpp +++ b/src/util/factorymanager.cpp @@ -51,6 +51,10 @@ #include #include +#include +#include +#include + // std #include @@ -99,6 +103,10 @@ void FactoryManager::initialize() _manager->factory()->registerClass("Static"); _manager->factory()->registerClass("Spice"); + _manager->addFactory(new ghoul::TemplateFactory); + _manager->factory()->registerClass("Camera"); + _manager->factory()->registerClass("Scanner"); + // Add PlanetGeometry _manager->addFactory(new ghoul::TemplateFactory); _manager->factory() diff --git a/src/util/hongkangparser.cpp b/src/util/hongkangparser.cpp new file mode 100644 index 0000000000..0890192e2f --- /dev/null +++ b/src/util/hongkangparser.cpp @@ -0,0 +1,276 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014 * +* * +* Permission is hereby granted, free of charge, to any person obtaining a copy of this * +* software and associated documentation files (the "Software"), to deal in the Software * +* without restriction, including without limitation the rights to use, copy, modify, * +* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * +* permit persons to whom the Software is furnished to do so, subject to the following * +* conditions: * +* * +* The above copyright notice and this permission notice shall be included in all copies * +* or substantial portions of the Software. * +* * +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * +* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * +* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * +* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * +* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * +* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * +****************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace { + const std::string _loggerCat = "HongKangParser"; +} + +namespace openspace { +HongKangParser::HongKangParser(const std::string& fileName, + std::string spacecraft, + std::map fileTranslation, + std::vector potentialTargets) : + _defaultCaptureImage(absPath("C:/Users/michal/openspace/openspace-data/scene/common/textures/placeholder_blank.png")) +{ + _fileName = fileName; + _spacecraft = spacecraft; + _fileTranslation = fileTranslation; + _potentialTargets = potentialTargets; +} + +void HongKangParser::create(){ + if (size_t position = _fileName.find_last_of(".") + 1){ + if (position != std::string::npos){ + std::string extension = ghoul::filesystem::File(_fileName).fileExtension(); + + if (extension == "txt"){// Hong Kang. pre-parsed playbook + LINFO("Using Preparsed Playbook V9H"); + std::ifstream file(_fileName); + if (!file.good()) LERROR("Failed to open txt file '" << _fileName << "'"); + + std::string timestr = ""; + double shutter = 0.01; + double startTime, stopTime; + + // for augmentation we only need the keys in acronymDictionary as a vector + std::vector payload; + for (auto p : _acronymDictionary) + for (auto t : p.second) + payload.push_back(t); + payload.erase(std::unique(payload.begin(), payload.end()), payload.end()); + + std::string previousInstrument; + std::string previousTarget; + + double longExposureStart = 0; + double longExposureStop = 0; + std::string longExposureKeyword; + + do{ + std::getline(file, timestr); + //For each instrument in acronym dictionary + for (auto it : _acronymDictionary){ + // check if first col in line has keyword of interest + std::string keyword = timestr.substr(0, timestr.find_first_of(" ")); + auto pos = keyword.find(it.first); + if (pos != std::string::npos){ + // grab the time + std::string met = timestr.substr(24, 9); + //convert to ephemeris time + startTime = getETfromMet(met); + /* + std::string checkIfMVIC = "MVIC"; + int count = 0; + bool foundStopTime = false; + if (findExactMatch("MVIC", keyword)){ + std::string abortLine; + int len = file.tellg(); + while (!file.eof() && !findExactMatch("ABORT", abortLine)){ + + std::getline(file, abortLine); + std::string abortCommand = abortLine.substr(0, abortLine.find_first_of(" ")); + count++; + if (findExactMatch("ABORT", abortCommand)){ + met = abortLine.substr(24, 9); + stopTime = getETfromMet(met); + foundStopTime = true; + } + } + file.seekg(len, std::ios_base::beg); + }else{ + //assume regular shutter speed; + stopTime = startTime + shutter; + } + + if (foundStopTime){ + longExposureStart = startTime; + longExposureStop = stopTime; + longExposureKeyword = keyword; + }*/ + + // retrieve corresponding SPICE call + std::vector instrument = it.second; + + // create image + Image image; + //stoptime- quick setting for now + stopTime = startTime + 0.01; + createImage(image, startTime, stopTime, instrument, "", _defaultCaptureImage); + // add targets + augmentWithSpice(image, _spacecraft, payload, _potentialTargets); + + //SKA ERSATTAS MED NAGOT ANNAT - "instrument times" + if (previousInstrument != it.first){ + previousInstrument = it.first; + std::pair v_time = std::make_pair(image.startTime, keyword); + _instrumentTimes.push_back(v_time); + } + + if (previousTarget != image.target){ + previousTarget = image.target; + std::pair v_target = std::make_pair(image.startTime, image.target); + _targetTimes.push_back(v_target); + } + + //_subsetMap[image.target]._subset[keyword].push_back(image); + _subsetMap[image.target]._subset.push_back(image); + _subsetMap[image.target]._range.setRange(image.startTime); + } + } + } while (!file.eof()); + } + } + } + //PRINT TO FILE FUNCTION + std::ofstream myfile; + myfile.open("HongKangOutput.txt"); + + //print all + for (auto target : _subsetMap){ + std::string min, max; + SpiceManager::ref().getDateFromET(target.second._range._min, min); + SpiceManager::ref().getDateFromET(target.second._range._max, max); + + myfile << std::endl; + for (auto image : target.second._subset){ + std::string time; + SpiceManager::ref().getDateFromET(image.startTime, time); + myfile << std::fixed + << std::setw(10) << time + << std::setw(10) << (int)getMetFromET(image.startTime) + << std::setw(10) << image.target << std::setw(10); + for (auto instrument : image.activeInstruments){ + myfile << " " << instrument; + } + myfile << std::endl; + } + } + myfile.close(); +} + +bool HongKangParser::augmentWithSpice(Image& image, + std::string spacecraft, + std::vector payload, + std::vector potentialTargets){ + image.target = "VOID"; + // we have (?) to cast to int, unfortunately + int exposureTime = image.stopTime - image.startTime; + if (exposureTime == 0) exposureTime = 1; + double et; + for (int i = 0; i < potentialTargets.size(); i++){ + bool success = false; + bool _withinFOV = false; + for (int j = 0; j < image.activeInstruments.size(); j++){ + double time = image.startTime; + for (int k = 0; k < exposureTime; k++){ + time += k; + success = openspace::SpiceManager::ref().targetWithinFieldOfView( + image.activeInstruments[j], + potentialTargets[i], + spacecraft, + "ELLIPSOID", + "NONE", + time, + _withinFOV); + if (_withinFOV){ + image.target = potentialTargets[i]; + _withinFOV = false; + } + } + } + } + return false; +} + +void HongKangParser::createImage(Image& image, double startTime, double stopTime, std::vector instr, std::string targ, std::string pot) { + image.startTime = startTime; + image.stopTime = stopTime; + image.path = pot; + for (int i = 0; i < instr.size(); i++){ + image.activeInstruments.push_back(instr[i]); + } + image.target = targ; + image.projected = false; +} + +double HongKangParser::getETfromMet(std::string timestr){ + std::string::size_type sz; + return getETfromMet(std::stod(timestr, &sz)); +} + +double HongKangParser::getETfromMet(double met){ + double diff; + double referenceET; + double et; + openspace::SpiceManager::ref().getETfromDate("2015-07-14T11:50:00.00", referenceET); + double missionLaunch = referenceET - _metRef; + + diff = abs(met - _metRef); + if (met > _metRef){ + et = referenceET + diff; + }else if (met < _metRef){ + et = referenceET - diff; + } + return et; +} + + +double HongKangParser::getMetFromET(double et){ + double met; + double referenceET; + openspace::SpiceManager::ref().getETfromDate("2015-07-14T11:50:00.00", referenceET); + + if (et >= referenceET){ + met = _metRef + (et - referenceET); + } + else{ + met = _metRef - (referenceET - et); + } + + return met; +} + +std::map HongKangParser::getSubsetMap(){ + return _subsetMap; +} +std::vector> HongKangParser::getIstrumentTimes(){ + return _instrumentTimes; +} +std::vector> HongKangParser::getTargetTimes(){ + return _targetTimes; +} +} \ No newline at end of file diff --git a/src/util/imagesequencer.cpp b/src/util/imagesequencer.cpp index 831c460eea..cd16be7963 100644 --- a/src/util/imagesequencer.cpp +++ b/src/util/imagesequencer.cpp @@ -52,13 +52,16 @@ struct ImageParams{ bool projected; }; -bool imageComparer (const ImageParams &a, const ImageParams &b){ - return a.startTime < b.startTime; -}; + std::vector> _timeStamps; void createImage(std::vector& vec, double t1, std::string instrument, std::string target, std::string path = "dummypath"); +auto imageComparer = [](const ImageParams &a, const ImageParams &b)->bool{ + return a.startTime < b.startTime; +}; + + std::vector::iterator binary_find(std::vector::iterator begin, std::vector::iterator end, const ImageParams &val, @@ -153,7 +156,6 @@ double ImageSequencer::nextCaptureTime(double time, int sequenceID){ std::string ImageSequencer::findActiveInstrument(double time, int sequenceID){ auto it = binary_find(_timeStamps[sequenceID].begin(), _timeStamps[sequenceID].end(), { time, "", "", "",false }, imageComparer); - if ((it == _timeStamps[sequenceID].end())){ _activeInstrument = "Not found, incufficient playbook-data"; }else{ @@ -163,7 +165,7 @@ std::string ImageSequencer::findActiveInstrument(double time, int sequenceID){ return _activeInstrument; } -void ImageSequencer::augumentSequencesWithTargets(int sequenceID){ +void ImageSequencer::augumentSequenceWithTargets(int sequenceID){ if (!_targetsAdded){ // if there is an registered observer for this sequence if (_observers.count(sequenceID) > 0) { @@ -210,17 +212,17 @@ void ImageSequencer::augumentSequencesWithTargets(int sequenceID){ } bool ImageSequencer::getImagePath(std::vector>& _imageTimes, int sequenceID, std::string projectee, bool withinFOV){ - if (withinFOV && !Time::ref().timeJumped()){ + /*if (withinFOV && !Time::ref().timeJumped()){ getSingleImage(_imageTimes, sequenceID, projectee); - }else{ + }else{*/ getMultipleImages(_imageTimes, sequenceID, projectee); - } + //} return true; } bool ImageSequencer::getMultipleImages(std::vector>& _imageTimes, int sequenceID, std::string projectee){ double previousTime; - std::map::iterator it = _projectableTargets.find(projectee); + std::map::iterator it = _projectableTargets.find(projectee); if (it != _projectableTargets.end()){ previousTime = it->second; it->second = _currentTime; diff --git a/src/util/imagesequencer2.cpp b/src/util/imagesequencer2.cpp new file mode 100644 index 0000000000..9106319477 --- /dev/null +++ b/src/util/imagesequencer2.cpp @@ -0,0 +1,335 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014 * +* * +* 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. * +****************************************************************************************/ + +// open space includes +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace { +const std::string _loggerCat = "ImageSequencer2"; +} + +namespace openspace { + +ImageSequencer2* ImageSequencer2::_instance = nullptr; + +ImageSequencer2::ImageSequencer2() : +_defaultCaptureImage(absPath("C:/Users/michal/openspace/openspace-data/scene/common/textures/placeholder_blank.png")) +{} + + +ImageSequencer2& ImageSequencer2::ref() { + assert(_instance != nullptr); + return *_instance; +} +void ImageSequencer2::initialize() { + assert(_instance == nullptr); + _instance = new ImageSequencer2; +} + +void ImageSequencer2::deinitialize() { + delete _instance; + _instance = nullptr; +} +/* +auto cmp = [](const Image &a, const Image &b)->bool{ + return a.startTime < b.startTime; +};*/ + +bool ImageSequencer2::imageComparer(const Image &a, const Image &b){ + return a.startTime < b.startTime; +}; + +std::vector::iterator ImageSequencer2::binary_find(std::vector::iterator begin, + std::vector::iterator end, + const Image &val, + bool(*compareFunc)(const Image &a, const Image &b)){ + // Finds the lower bound in at most log(last - first) + 1 comparisons + std::vector::iterator it = std::lower_bound(begin, end, val, compareFunc); + if (it != begin){ + return it; + } + return end; +} + +void ImageSequencer2::updateSequencer(double time){ + if (_currentTime != time){ + _previousTime = _currentTime; + _currentTime = time; + } +} + +std::pair ImageSequencer2::getNextTarget(){ + // make into template func + auto compareTime = [](const std::pair &a, + const std::pair &b)->bool{ + return a.first < b.first; + }; + std::pair findEqualToThis; + findEqualToThis.first = _currentTime; + auto it = std::lower_bound(_targetTimes.begin(), _targetTimes.end(), findEqualToThis, compareTime); + + if (it != _targetTimes.end()){ + return (*it); + } +} + +std::pair ImageSequencer2::getCurrentTarget(){ + // make into template func + auto compareTime = [](const std::pair &a, + const std::pair &b)->bool{ + return a.first < b.first; + }; + std::pair findEqualToThis; + findEqualToThis.first = _currentTime; + auto it = std::lower_bound(_targetTimes.begin(), _targetTimes.end(), findEqualToThis, compareTime); + + if (it != _targetTimes.end()){ + return *std::prev(it); + } +} + +std::pair> ImageSequencer2::getIncidentTargetList(int range){ + std::pair> incidentTargets; + + auto compareTime = [](const std::pair &a, + const std::pair &b)->bool{ + return a.first < b.first; + }; + std::pair findEqualToThis; + findEqualToThis.first = _currentTime; + auto it = std::lower_bound(_targetTimes.begin(), _targetTimes.end(), findEqualToThis, compareTime); + + std::advance(it, -(range+1)); + + for (int i = 0; i < 2*range+1; i++){ + incidentTargets.first = it->first; + incidentTargets.second.push_back(it->second); + it++; + if (it == _targetTimes.end()) + break; + } + + return incidentTargets; +} + +std::vector ImageSequencer2::getActiveInstruments(){ + return _currentlyActiveInstruments; +} +bool ImageSequencer2::instumentActive(std::string instrumentID){ + // make into template func + auto compareTime = [](const std::pair &a, + const std::pair &b)->bool{ + return a.first < b.first; + }; + + std::pair findEqualToThis; + findEqualToThis.first = _currentTime; + auto it = std::lower_bound(_instrumentTimes.begin(), _instrumentTimes.end(), findEqualToThis, compareTime); + + it = std::prev(it); + if (it != _instrumentTimes.end()){ + std::string key = it->second; + std::vector instruments = _acronymDictionary[key]; + for (auto i : instruments){ + if (i == instrumentID){ + _currentlyActiveInstruments = instruments; + return true; + } + } + } + return false; +} + +double ImageSequencer2::getNextCaptureTime(){ + // to do this we need getCurrentTarget to ALWAYS work! + return 0.0; +} + +void ImageSequencer2::runSequenceParser(SequenceParser* parser){ + parser->create(); + + _subsetMap = parser->getSubsetMap(); + _instrumentTimes = parser->getIstrumentTimes(); + //_targetTimes = parser->getTargetTimes(); + _acronymDictionary = parser->getAcronymDictionary(); +} + +/* +bool ImageSequencer2::parsePlaybookFile(const std::string& fileName, + std::string spacecraft, + std::map> acronymDictionary, + std::vector potentialTargets) { + _acronymDictionary = acronymDictionary; + if (size_t position = fileName.find_last_of(".") + 1){ + if (position != std::string::npos){ + std::string extension = ghoul::filesystem::File(fileName).fileExtension(); + + if (extension == "txt"){// Hong Kang. pre-parsed playbook + LINFO("Using Preparsed Playbook V9H"); + std::ifstream file(fileName); + if (!file.good()) LERROR("Failed to open txt file '" << fileName << "'"); + + std::string timestr = ""; + double shutter = 0.01; + double startTime, stopTime; + + // for augmentation we only need the keys in acronymDictionary as a vector + std::vector payload; + for (auto p : acronymDictionary) + for (auto t : p.second) + payload.push_back(t); + payload.erase(std::unique(payload.begin(), payload.end()), payload.end()); + + std::string previousInstrument; + std::string previousTarget; + + double longExposureStart = 0; + double longExposureStop = 0; + std::string longExposureKeyword; + + do{ + std::getline(file, timestr); + //For each instrument in acronym dictionary + for (auto it : _acronymDictionary){ + // check if first col in line has keyword of interest + std::string keyword = timestr.substr(0, timestr.find_first_of(" ")); + auto pos = keyword.find(it.first); + if (pos != std::string::npos){ + // grab the time + std::string met = timestr.substr(24, 9); + //convert to ephemeris time + startTime = getETfromMet(met); + + //std::string checkIfMVIC = "MVIC"; + //int count = 0; + //bool foundStopTime = false; + //if (findExactMatch("MVIC", keyword)){ + // std::string abortLine; + // int len = file.tellg(); + // while (!file.eof() && !findExactMatch("ABORT", abortLine)){ + // + // std::getline(file, abortLine); + // std::string abortCommand = abortLine.substr(0, abortLine.find_first_of(" ")); + // count++; + // if (findExactMatch("ABORT", abortCommand)){ + // met = abortLine.substr(24, 9); + // stopTime = getETfromMet(met); + // foundStopTime = true; + // } + // } + // file.seekg(len, std::ios_base::beg); + //}else{ + // //assume regular shutter speed; + // stopTime = startTime + shutter; + //} + // + //if (foundStopTime){ + // longExposureStart = startTime; + // longExposureStop = stopTime; + // longExposureKeyword = keyword; + //} + + // retrieve corresponding SPICE call + std::vector instrument = it.second; + + // create image + Image image; + //stoptime- quick setting for now + stopTime = startTime + 0.01; + createImage(image, startTime, stopTime, instrument, "", _defaultCaptureImage); + // add targets + augmentWithSpice(image, spacecraft, payload, potentialTargets); + + //SKA ERSATTAS MED NAGOT ANNAT - "instrument times" + if (previousInstrument != it.first){ + previousInstrument = it.first; + std::pair v_time = std::make_pair(image.startTime, keyword); + _instrumentTimes.push_back(v_time); + } + + if (previousTarget != image.target ){ + previousTarget = image.target; + std::pair v_target = std::make_pair(image.startTime, image.target); + _targetTimes.push_back(v_target); + } + + //_subsetMap[image.target]._subset[keyword].push_back(image); + _subsetMap[image.target]._subset.push_back(image); + _subsetMap[image.target]._range.setRange(image.startTime); + } + } + } while (!file.eof()); + } + } + } + + //PRINT FUNCTION + std::string st1 = "2015-07-14T10:00:00.00"; + std::string st2 = "2015-07-14T12:00:00.00"; + double start, stop; + + SpiceManager::ref().getETfromDate(st1, start); + SpiceManager::ref().getETfromDate(st2, stop); + + std::ofstream myfile; + myfile.open("augmentedPef.txt"); + + //print all + for (auto target : _subsetMap){ + std::string min, max; + SpiceManager::ref().getDateFromET(target.second._range._min, min); + SpiceManager::ref().getDateFromET(target.second._range._max, max); + + myfile << std::endl; + for (auto image : target.second._subset){ + std::string time; + SpiceManager::ref().getDateFromET(image.startTime, time); + myfile << std::fixed + << std::setw(10) << time + << std::setw(10) << (int)getMetFromET(image.startTime) + << std::setw(10) << image.target << std::setw(10); + for (auto instrument : image.activeInstruments){ + myfile << " " << instrument; + } + myfile << std::endl; + } + } + + myfile.close(); + + return true; +} +*/ +} // namespace openspace diff --git a/src/util/payload.cpp b/src/util/payload.cpp new file mode 100644 index 0000000000..d7c23fdbbe --- /dev/null +++ b/src/util/payload.cpp @@ -0,0 +1,59 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 + +namespace { +const std::string _loggerCat = "Payload"; +} + +namespace openspace { + +Payload* Payload::createFromDictionary(const ghoul::Dictionary& dictionary, const std::string type) +{ + ghoul::TemplateFactory* factory + = FactoryManager::ref().factory(); + Payload* result = factory->create(type, dictionary); + + if (result == nullptr) { + LERROR("Failed creating Payload object of type '" << type << "'"); + return nullptr; + } + return result; +} + +Payload::Payload() +{ +} + +Payload::Payload(const ghoul::Dictionary& dictionary) +{ +} + +Payload::~Payload() +{ +} + +} // namespace openspace \ No newline at end of file diff --git a/src/util/scannerinstrument.cpp b/src/util/scannerinstrument.cpp new file mode 100644 index 0000000000..e93ec43efe --- /dev/null +++ b/src/util/scannerinstrument.cpp @@ -0,0 +1,49 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +namespace { + const std::string _loggerCat = "ScannerInstrument"; +} + +namespace openspace { + +ScannerInstrument::ScannerInstrument(const ghoul::Dictionary& dictionary) : _type("SCANNER") +{ + std::string value; + for (int k = 0; k < dictionary.size(); k++){ + dictionary.getValue(std::to_string(k + 1), value); + _spiceIDs.push_back(value); + } +} +std::string ScannerInstrument::getType(){ + return _type; +} + +std::vector ScannerInstrument::getSpiceIDs(){ + return _spiceIDs; +} + +} // namespace openspace \ No newline at end of file From de6fcf1583ffecb70ae8771cbe62f1b6a1c03949 Mon Sep 17 00:00:00 2001 From: Michal Marcinkowski Date: Thu, 16 Apr 2015 11:57:23 -0400 Subject: [PATCH 04/45] completely new imagesequencer class - WIP --- .../planets/renderableplanetprojection.h | 7 +- include/openspace/rendering/renderablefov.h | 56 ---- .../openspace/util/{payload.h => decoder.h} | 20 +- include/openspace/util/hongkangparser.h | 22 +- include/openspace/util/imagesequencer2.h | 23 +- ...cannerinstrument.h => instrumentdecoder.h} | 16 +- include/openspace/util/labelparser.h | 76 +++++ .../{camerainstrument.h => scannerdecoder.h} | 15 +- include/openspace/util/sequenceparser.h | 19 +- include/openspace/util/targetdecoder.h | 46 +++ openspace-data | 2 +- scripts/default_startup.lua | 2 +- .../planets/renderableplanetprojection.cpp | 125 +++----- src/rendering/renderablefov.cpp | 69 ++--- src/rendering/renderengine.cpp | 91 +++--- src/util/{payload.cpp => decoder.cpp} | 18 +- src/util/factorymanager.cpp | 13 +- src/util/hongkangparser.cpp | 232 ++++++++------ src/util/imagesequencer.cpp | 1 - src/util/imagesequencer2.cpp | 282 +++++++----------- src/util/instrumentdecoder.cpp | 63 ++++ src/util/labelparser.cpp | 185 ++++++++++++ ...amerainstrument.cpp => scannerdecoder.cpp} | 11 +- ...cannerinstrument.cpp => targetdecoder.cpp} | 24 +- 24 files changed, 834 insertions(+), 584 deletions(-) rename include/openspace/util/{payload.h => decoder.h} (86%) rename include/openspace/util/{scannerinstrument.h => instrumentdecoder.h} (87%) create mode 100644 include/openspace/util/labelparser.h rename include/openspace/util/{camerainstrument.h => scannerdecoder.h} (89%) create mode 100644 include/openspace/util/targetdecoder.h rename src/util/{payload.cpp => decoder.cpp} (86%) create mode 100644 src/util/instrumentdecoder.cpp create mode 100644 src/util/labelparser.cpp rename src/util/{camerainstrument.cpp => scannerdecoder.cpp} (89%) rename src/util/{scannerinstrument.cpp => targetdecoder.cpp} (82%) diff --git a/include/openspace/rendering/planets/renderableplanetprojection.h b/include/openspace/rendering/planets/renderableplanetprojection.h index 016f6ee3cc..8ad4369199 100644 --- a/include/openspace/rendering/planets/renderableplanetprojection.h +++ b/include/openspace/rendering/planets/renderableplanetprojection.h @@ -33,7 +33,8 @@ #include #include -#include +#include +#include #include @@ -77,7 +78,7 @@ protected: private: void imageProjectGPU(); - std::map _fileTranslation; + std::map _fileTranslation; properties::StringProperty _colorTexturePath; properties::StringProperty _projectionTexturePath; @@ -134,6 +135,8 @@ private: GLuint _fboID; GLuint _quad; GLuint _vertexPositionBuffer; + + bool _once; //fml }; } // namespace openspace diff --git a/include/openspace/rendering/renderablefov.h b/include/openspace/rendering/renderablefov.h index effadbfe6a..0fec4870c0 100644 --- a/include/openspace/rendering/renderablefov.h +++ b/include/openspace/rendering/renderablefov.h @@ -124,59 +124,3 @@ public: }; } #endif -// Scrap stuff i need to keep for now (michal) - - -/* // idk how we will compute the aberrated state. -double RenderableFov::computeTargetLocalTime(PowerScaledScalar d){ -double c = 299792456.075; // m/s -double dt = ( (d[0]*pow(10, d[1])) / c ); -double t_local = _time - dt*86400; - -std::string localTime; -std::string currentTime; - -openspace::SpiceManager::ref().getDateFromET(t_local, localTime); -openspace::SpiceManager::ref().getDateFromET(_time , currentTime); - -std::cout << "time at jupiter : " << localTime << "\time at NH" << currentTime << std::endl; -return t_local; -}*/ - -/* -psc RenderableFov::sphericalInterpolate(glm::dvec3 p0, glm::dvec3 p1, float t){ -double targetEt, lt; -glm::dvec3 ip, iv; -psc targetPos; -SpiceManager::ref().getTargetPosition("JUPITER", _spacecraft, _frame, _aberrationCorrection, _time, targetPos, lt); - -openspace::SpiceManager::ref().getSurfaceIntercept(_fovTarget, _spacecraft, _instrumentID, -_frame, _method, _aberrationCorrection, _time, targetEt, p0, ip, iv); -psc psc0 = PowerScaledCoordinate::CreatePowerScaledCoordinate(iv[0], iv[1], iv[2]); -openspace::SpiceManager::ref().getSurfaceIntercept(_fovTarget, _spacecraft, _instrumentID, -_frame, _method, _aberrationCorrection, _time, targetEt, p1, ip, iv); -psc psc1 = PowerScaledCoordinate::CreatePowerScaledCoordinate(iv[0], iv[1], iv[2]); -psc0[3] += 3; -psc1[3] += 3; - -psc0 -= targetPos; -psc1 -= targetPos; - -double angle = psc0.angle(psc1); - -std::cout << angle << std::endl; - -double sin_a = sin(angle); // opt -double l[2] = { sin((1.f - t)*angle) / sin_a, sin((t)*angle) / sin_a }; - -std::cout << l[0] << " " << l[1] << std::endl; - -float s = ((t-1)*psc0[3] + (t)*psc1[3]); -float x = (l[0]*psc0[0] + l[1]*psc1[0]); -float y = (l[0]*psc0[1] + l[1]*psc1[1]); -float z = (l[0]*psc0[2] + l[1]*psc1[2]); - -psc interpolated = PowerScaledCoordinate::PowerScaledCoordinate(x, y, z, 10); -return interpolated; -} -*/ diff --git a/include/openspace/util/payload.h b/include/openspace/util/decoder.h similarity index 86% rename from include/openspace/util/payload.h rename to include/openspace/util/decoder.h index 5974e44680..41340b1ce1 100644 --- a/include/openspace/util/payload.h +++ b/include/openspace/util/decoder.h @@ -22,26 +22,26 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __PAYLOAD_H__ -#define __PAYLOAD_H__ +#ifndef __DECODER_H__ +#define __DECODER_H__ #include #include namespace openspace { -class Payload { +class Decoder { public: - static Payload* createFromDictionary(const ghoul::Dictionary& dictionary, const std::string type); + static Decoder* createFromDictionary(const ghoul::Dictionary& dictionary, const std::string type); - Payload(const ghoul::Dictionary& dictionary); - virtual ~Payload(); - virtual std::string getType() = 0; - virtual std::vector getSpiceIDs() = 0; + Decoder(const ghoul::Dictionary& dictionary); + virtual ~Decoder(); + virtual std::string getDecoderType() = 0; + virtual std::vector getTranslation() = 0; protected: - Payload(); + Decoder(); }; } // namespace openspace -#endif // __PAYLOAD_H__ +#endif // __DECODER_H__ diff --git a/include/openspace/util/hongkangparser.h b/include/openspace/util/hongkangparser.h index 63d52ae535..f6e08c6160 100644 --- a/include/openspace/util/hongkangparser.h +++ b/include/openspace/util/hongkangparser.h @@ -28,27 +28,26 @@ #include #include - #include #include #include namespace openspace { - class HongKangParser : public SequenceParser{ public: HongKangParser(); HongKangParser(const std::string& fileName, std::string spacecraft, - std::map acronymDictionary, + ghoul::Dictionary dictionary, std::vector potentialTargets); virtual void create(); virtual std::map getSubsetMap(); - virtual std::vector> getIstrumentTimes(); + virtual std::vector> getIstrumentTimes(); virtual std::vector> getTargetTimes(); // temporary need to figure this out - std::map getAcronymDictionary(){ return _fileTranslation; }; + virtual std::map getTranslation(){ return _fileTranslation; }; + virtual std::vector getCaptureProgression(); private: double getMetFromET(double et); @@ -67,18 +66,19 @@ namespace openspace { std::vector payload, std::vector potentialTargets); - - std::map _subsetMap; - std::vector> _instrumentTimes; - std::vector> _targetTimes; - std::string _defaultCaptureImage; double _metRef = 299180517; std::string _fileName; std::string _spacecraft; - std::map _fileTranslation; + std::map _fileTranslation; std::vector _potentialTargets; + + //returnable + std::map _subsetMap; + std::vector> _instrumentTimes; + std::vector> _targetTimes; + std::vector _captureProgression; }; } diff --git a/include/openspace/util/imagesequencer2.h b/include/openspace/util/imagesequencer2.h index 4a9982c744..0e134dd49e 100644 --- a/include/openspace/util/imagesequencer2.h +++ b/include/openspace/util/imagesequencer2.h @@ -48,9 +48,10 @@ public: static void initialize(); static void deinitialize(); + bool isReady(); + //provides the sequencer with current time void updateSequencer(double time); - void runSequenceParser(SequenceParser* parser); //translates playbook ambiguous namesetting to spice calls, augments each observation with targets and @@ -68,11 +69,12 @@ public: std::pair> getIncidentTargetList(int range = 2); double getNextCaptureTime(); + double getIntervalLength(); + std::vector> getActiveInstruments(); + bool ImageSequencer2::getImagePaths(std::vector>& captures, std::string projectee, std::string instrumentID); + bool ImageSequencer2::getImagePaths(std::vector>& captures, std::string projectee); - //a fov class can check whether or not its active bool instumentActive(std::string instrumentID); - //get all currently active instruments - std::vector getActiveInstruments(); const Image* findLatestImageInSubset( ImageSubset& subset); private: @@ -88,18 +90,19 @@ private: //var double _currentTime; double _previousTime; + double _intervalLength; + double _nextCapture; std::string _defaultCaptureImage; - std::vector _currentlyActiveInstruments; + std::vector> _instrumentOnOff; std::map _subsetMap; std::vector> _targetTimes; - std::vector> _instrumentTimes; - //std::vector _activeInstruments - std::map> _acronymDictionary; - - static bool hasData(); + std::vector> _instrumentTimes; + std::vector _captureProgression; + std::map _fileTranslation; + bool _hasData; }; } // namespace openspace diff --git a/include/openspace/util/scannerinstrument.h b/include/openspace/util/instrumentdecoder.h similarity index 87% rename from include/openspace/util/scannerinstrument.h rename to include/openspace/util/instrumentdecoder.h index 16aa51b079..41d9b77f7d 100644 --- a/include/openspace/util/scannerinstrument.h +++ b/include/openspace/util/instrumentdecoder.h @@ -22,20 +22,20 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __SCANNERINSTRUMENT_H__ -#define __SCANNERINSTRUMENT_H__ +#ifndef __INSTRUMENTDECODER_H__ +#define __INSTRUMENTDECODER_H__ -#include +#include #include namespace openspace { -class ScannerInstrument : public Payload { +class InstrumentDecoder : public Decoder { public: - ScannerInstrument(const ghoul::Dictionary& dictionary); - virtual std::string getType(); - virtual std::vector getSpiceIDs(); + InstrumentDecoder(const ghoul::Dictionary& dictionary); + virtual std::string getDecoderType(); + virtual std::vector getTranslation(); private: std::string _type; std::vector _spiceIDs; @@ -43,4 +43,4 @@ private: } // namespace openspace -#endif // __SCANNERINSTRUMENT_H__ +#endif // __INSTRUMENTDECODER_H__ diff --git a/include/openspace/util/labelparser.h b/include/openspace/util/labelparser.h new file mode 100644 index 0000000000..220e7b4c3e --- /dev/null +++ b/include/openspace/util/labelparser.h @@ -0,0 +1,76 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014-2015 * +* * +* 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 __LABELPARSER_H__ +#define __LABELPARSER_H__ +#include +#include + +#include +#include +#include + +namespace openspace { + class LabelParser : public SequenceParser{ + public: + LabelParser(); + LabelParser(const std::string& fileName, + ghoul::Dictionary translationDictionary); + virtual void create(); + virtual std::map getSubsetMap(); + virtual std::vector> getIstrumentTimes(); + virtual std::vector> getTargetTimes(); + + // temporary need to figure this out + std::map getTranslation(){ return _fileTranslation; }; + virtual std::vector getCaptureProgression(){ return _captureProgression; }; + + private: + void createImage(Image& image, + double startTime, + double stopTime, + std::vector instr, + std::string targ, + std::string pot); + + bool augmentWithSpice(Image& image, + std::string spacecraft, + std::vector payload, + std::vector potentialTargets); + + std::string _fileName; + std::string _spacecraft; + std::map _fileTranslation; + std::vector _specsOfInterest; + + //returnable + std::map _subsetMap; + std::vector> _instrumentTimes; + std::vector> _targetTimes; + std::vector _captureProgression; + }; + +} +#endif //__LABELPARSER_H__ \ No newline at end of file diff --git a/include/openspace/util/camerainstrument.h b/include/openspace/util/scannerdecoder.h similarity index 89% rename from include/openspace/util/camerainstrument.h rename to include/openspace/util/scannerdecoder.h index 6236f83896..8eddf3aafb 100644 --- a/include/openspace/util/camerainstrument.h +++ b/include/openspace/util/scannerdecoder.h @@ -22,19 +22,18 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __CAMERAINSTRUMENT_H__ -#define __CAMERAINSTRUMENT_H__ - -#include +#ifndef __SCANNERDECODER_H__ +#define __SCANNERDECODER_H__ +#include #include namespace openspace { -class CameraInstrument : public Payload { +class ScannerDecoder : public Decoder { public: - CameraInstrument(const ghoul::Dictionary& dictionary); - virtual std::string getType(); + ScannerDecoder(const ghoul::Dictionary& dictionary); + virtual std::string getDecoderType(); virtual std::vector getSpiceIDs(); private: std::string _type; @@ -43,4 +42,4 @@ private: } // namespace openspace -#endif // __CAMERAINSTRUMENT_H__ +#endif // __SCANNERDECODER_H__ diff --git a/include/openspace/util/sequenceparser.h b/include/openspace/util/sequenceparser.h index 96d4427c57..90197884be 100644 --- a/include/openspace/util/sequenceparser.h +++ b/include/openspace/util/sequenceparser.h @@ -25,9 +25,8 @@ #ifndef __SEQUENCEPARSER_H__ #define __SEQUENCEPARSER_H__ -#include -#include -#include +#include + #include #include @@ -45,12 +44,15 @@ namespace openspace { struct TimeRange{ TimeRange() : _min(-1), _max(-1){}; void setRange(double val){ - if (_min > val || _min < 0) _min = val; - if (_max < val || _max < 0) _max = val; + if (_min > val) _min = val; + if (_max < val) _max = val; }; bool inRange(double min, double max){ return (min >= _min && max <= _max); } + bool inRange(double val){ + return (val >= _min && val <= _max); + } double _min; double _max; }; @@ -63,9 +65,10 @@ class SequenceParser{ public: virtual void create() = 0; virtual std::map getSubsetMap() = 0; - virtual std::vector> getIstrumentTimes() = 0; + virtual std::vector> getIstrumentTimes() = 0; virtual std::vector> getTargetTimes() = 0; - virtual std::map getAcronymDictionary() = 0; + virtual std::map getTranslation() = 0; + virtual std::vector getCaptureProgression() = 0; }; } -#endif //__SEQUENCEPARSER_H__ +#endif //__SEQUENCEPARSER_H__ \ No newline at end of file diff --git a/include/openspace/util/targetdecoder.h b/include/openspace/util/targetdecoder.h new file mode 100644 index 0000000000..244ba46f7f --- /dev/null +++ b/include/openspace/util/targetdecoder.h @@ -0,0 +1,46 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 __TARGETDECODER_H__ +#define __TARGETDECODER_H__ + +#include + +#include + +namespace openspace { + +class TargetDecoder : public Decoder { +public: + TargetDecoder(const ghoul::Dictionary& dictionary); + virtual std::string getDecoderType(); + virtual std::vector getTranslation(); +private: + std::string _type; + std::vector _names; +}; + +} // namespace openspace + +#endif // __TARGETDECODER_H__ diff --git a/openspace-data b/openspace-data index 6f38f868b6..6b34ef9849 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 6f38f868b6ead66776c641095cdf9b9edbf77ec6 +Subproject commit 6b34ef9849d58fa33a40c571eee6432bde83e343 diff --git a/scripts/default_startup.lua b/scripts/default_startup.lua index 164eff55fc..19cd4413d1 100644 --- a/scripts/default_startup.lua +++ b/scripts/default_startup.lua @@ -14,7 +14,7 @@ dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) -- Load the default keyb -- openspace.time.setDeltaTime(50); -openspace.time.setTime("2015-07-14T11:49:40.00") -- PLUTO +openspace.time.setTime("2015-07-14T10:10:00.00") -- PLUTO -- NH takes series of images from visible to dark side (across terminator) -- Sequence lasts ~10 mins, (recommended dt = 10) diff --git a/src/rendering/planets/renderableplanetprojection.cpp b/src/rendering/planets/renderableplanetprojection.cpp index 13ee2d3b3d..596ec9006e 100644 --- a/src/rendering/planets/renderableplanetprojection.cpp +++ b/src/rendering/planets/renderableplanetprojection.cpp @@ -61,7 +61,7 @@ namespace { const std::string keySequenceDir = "Projection.Sequence"; const std::string keySequenceType = "Projection.SequenceType"; const std::string keyPotentialTargets = "PotentialTargets"; - const std::string keyTranslation = "PlaybookTranslation"; + const std::string keyTranslation = "DataInputTranslation"; @@ -93,6 +93,7 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& , _textureProj(nullptr) , _geometry(nullptr) , _sequenceID(-1) + , _once(false) { std::string name; bool success = dictionary.getValue(constants::scenegraphnode::keyName, name); @@ -166,6 +167,8 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& addProperty(_projectionTexturePath); _projectionTexturePath.onChange(std::bind(&RenderablePlanetProjection::loadProjectionTexture, this)); + SequenceParser* parser; + // std::string sequenceSource; bool _foundSequence = dictionary.getValue(keySequenceDir, _sequenceSource); if (_foundSequence) { @@ -173,49 +176,38 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& _foundSequence = dictionary.getValue(keySequenceType, _sequenceType); //Important: client must define translation-list in mod file IFF playbook - if (dictionary.hasKey(keyTranslation) && _sequenceType == sequenceTypePlaybook){ + if (dictionary.hasKey(keyTranslation)){ ghoul::Dictionary translationDictionary; //get translation dictionary dictionary.getValue(keyTranslation, translationDictionary); - //get the different instrument types - const std::vector& types = translationDictionary.keys(); - //for each instrument - for (int i = 0; i < types.size(); i++){ - std::string classtype = types[i]; - std::string currentType = keyTranslation + "." + classtype; - //create dictionary containing all {playbookKeys , spice IDs} - ghoul::Dictionary typeDictionary; - dictionary.getValue(keyTranslation + "." + classtype, typeDictionary); - //for each playbook call -> create a Payload object - const std::vector& keys = typeDictionary.keys(); - for (int j = 0; j < keys.size(); j++){ - std::string playbookKey = keys[j]; - std::string currentKey = currentType + "." + playbookKey; - //using dictionary as a way to extract the spiceIDs we need - ghoul::Dictionary spiceDictionary; - dictionary.getValue(currentKey, spiceDictionary); - //create payload - Payload *payload = Payload::createFromDictionary(spiceDictionary, classtype); - //insert payload to map - this will be used in the parser to determine - //behavioral characteristics of each instrument - _fileTranslation[playbookKey] = payload; - } + + if (_sequenceType == sequenceTypePlaybook){ + // eeh to many inputs, bit ugly. beautify later. + parser = new HongKangParser(_sequenceSource, + "NEW HORIZONS", + translationDictionary, + _potentialTargets); } + /*else if (_sequenceType == sequenceTypeImage){ + parser = new LabelParser(_sequenceSource, translationDictionary); + }*/ } else{ LWARNING("No playbook translation provided, please make sure all spice calls match playbook!"); } - // Have to delay playbook load in order to augment with targets once current AND spacecraft kernels loaded - for (auto p : _fileTranslation){ - std::vector k = _fileTranslation[p.first]->getSpiceIDs(); - std::cout << "TYPE : " << _fileTranslation[p.first]->getType() << std::endl; - std::cout << "FILE-CALL : " << p.first << std::endl; - std::cout << "SPICE ID'S :" << std::endl; - for (auto r : k){ - std::cout << r << std::endl; - } - std::cout << std::endl; + + /*if (_sequenceType == sequenceTypeImage) { + LWARNING("LOADING STUFF FOR JUPITER!"); + //openspace::ImageSequencer::ref().loadSequence(_sequenceSource, _sequenceID); + // SequenceParser *parser = new LabelParser(_sequenceSource, + //"NEW HORIZONS", + //_fileTranslation, + //_potentialTargets); + //openspace::ImageSequencer2::ref().runSequenceParser(parser); + }*/ + /*else*/ if (_sequenceType == sequenceTypePlaybook) { + openspace::ImageSequencer2::ref().runSequenceParser(parser); } } } @@ -421,18 +413,17 @@ void RenderablePlanetProjection::render(const RenderData& data){ _up = data.camera.lookUpVector(); #ifdef GPU_PROJ -/* if (_capture){ + if (_capture){ for (auto imgSubset : _imageTimes){ attitudeParameters(imgSubset.first); // projector viewmatrix _projectionTexturePath = imgSubset.second; // path to current images imageProjectGPU(); //fbopass } _capture = false; - }*/ + } #endif attitudeParameters(_time); _projectionTexturePath = _defaultProjImage; - _imageTimes.clear(); psc sun_pos; double lt; @@ -466,61 +457,13 @@ void RenderablePlanetProjection::update(const UpdateData& data){ // set spice-orientation in accordance to timestamp _time = data.time; _capture = false; -#ifndef ORIGINAL_SEQUENCER - static bool once; - if (Time::ref().deltaTime() > 0 && !once){ - if (_foundSequence) { - if (_sequenceType == sequenceTypeImage) { - openspace::ImageSequencer::ref().loadSequence(_sequenceSource, _sequenceID); - } - else if (_sequenceType == sequenceTypePlaybook) { - SequenceParser* parser = new HongKangParser(_sequenceSource, - "NEW HORIZONS", - _fileTranslation, - _potentialTargets); - openspace::ImageSequencer2::ref().runSequenceParser(parser); - } - } - once = true; - } - if (Time::ref().deltaTime() > 10){ + + + if (openspace::ImageSequencer2::ref().isReady()){ openspace::ImageSequencer2::ref().updateSequencer(_time); + _capture = openspace::ImageSequencer2::ref().getImagePaths(_imageTimes, _projecteeID, _instrumentID); } -#else - //happens only once - //ImageSequencer::ref().augumentSequencesWithTargets(_sequenceID); - - openspace::ImageSequencer::ref().findActiveInstrument(_time, _sequenceID); - openspace::ImageSequencer::ref().nextCaptureTime(_time, _sequenceID); - - bool _withinFOV; - if (_sequenceID != -1){ - std::string _fovTarget = ""; - for (int i = 0; i < _potentialTargets.size(); i++){ - bool success = openspace::SpiceManager::ref().targetWithinFieldOfView( - _instrumentID, - _potentialTargets[i], - _projectorID, - "ELLIPSOID", - _aberration, - _time, - _withinFOV); - if (success && _withinFOV){ - _fovTarget = _potentialTargets[i]; - break; - } - } - - //if (_projecteeID == _fovTarget){ - if (_time >= openspace::ImageSequencer::ref().getNextCaptureTime()){ - openspace::ImageSequencer::ref().getImagePath(_imageTimes, _sequenceID, _projecteeID, _withinFOV); - _capture = true; - } - //} - - } - -#endif + } void RenderablePlanetProjection::loadProjectionTexture(){ diff --git a/src/rendering/renderablefov.cpp b/src/rendering/renderablefov.cpp index 31f266fed1..66233c48dd 100644 --- a/src/rendering/renderablefov.cpp +++ b/src/rendering/renderablefov.cpp @@ -104,9 +104,9 @@ namespace openspace{ } void RenderableFov::allocateData(){ - int points = 8; + int points = 10; _stride[0] = points; - _isize[0] = points; + _isize[0] = points; _iarray1[0] = new int[_isize[0]]; for (int i = 0; i < points; i++){ for (int j = 0; j < 4; j++){ @@ -123,7 +123,7 @@ void RenderableFov::allocateData(){ _vtotal[0] = static_cast(_vsize[0] / _stride[0]); // allocate second vbo data - int cornerPoints = 5; + int cornerPoints = 6; _isize[1] = cornerPoints; _iarray1[1] = new int[_isize[1]]; for (int i = 0; i < _isize[1]; i++){ @@ -213,14 +213,6 @@ void RenderableFov::insertPoint(std::vector& arr, psc p, glm::vec4 c){ _nrInserted++; } -psc RenderableFov::pscInterpolate(psc p0, psc p1, float t){ - assert(t >= 0 && t <= 1); - float t2 = (1.f - t); - return PowerScaledCoordinate(t2*p0[0] + t*p1[0], - t2*p0[1] + t*p1[1], - t2*p0[2] + t*p1[2], - t2*p0[3] + t*p1[3]); -} glm::dvec3 RenderableFov::interpolate(glm::dvec3 p0, glm::dvec3 p1, float t){ assert(t >= 0 && t <= 1); float t2 = (1.f - t); @@ -340,8 +332,6 @@ void RenderableFov::fovProjection(bool H[], std::vector bounds){ } } } - // only if new points are inserted are we interested in rebuilding the - // vbo. Note that this can be optimized but is left as is for now. if (_nrInserted == 0){ _rebuild = false; }else{ @@ -383,20 +373,20 @@ void RenderableFov::updateData(){ } } void RenderableFov::computeColors(){ - double t2 = openspace::ImageSequencer::ref().getNextCaptureTime(); + double t2 = openspace::ImageSequencer2::ref().getNextCaptureTime(); double diff = (t2 - _time); double t = 0.0; if (diff <= 7.0) t = 1.f - diff / 7.0; if (diff < 0) t = 0.0; - + // i need to add an *.h file with colortables.... c_project = glm::vec4(0.0, 1.0, 0.00,1); col_end = glm::vec4(1.00, 0.29, 0.00, 1); blue = glm::vec4(0, 0.5, 0.7, 1); - col_gray = glm::vec4(0.3, 0.3, 0.3, 1); + col_gray = glm::vec4(0.5, 0.5, 0.5, 0.5); col_start = glm::vec4(1.00, 0.89, 0.00, 1); col_sq = glm::vec4(1.00, 0.29, 0.00, 1); - /* + col_end.x = c_project.x*t + col_end.x*(1 - t); col_end.y = c_project.y*t + col_end.y*(1 - t); col_end.z = c_project.z*t + col_end.z*(1 - t); @@ -408,7 +398,7 @@ void RenderableFov::computeColors(){ col_sq.x = c_project.x*t + col_sq.x*(1 - t); col_sq.y = c_project.y*t + col_sq.y*(1 - t); col_sq.z = c_project.z*t + col_sq.z*(1 - t); - */ + blue.w = 0.5; c_project.w = 0.5; col_end.w = 0.5; @@ -420,10 +410,10 @@ void RenderableFov::render(const RenderData& data){ // fetch data glm::mat4 transform(1); - glm::mat4 tmp = glm::mat4(1); + glm::mat4 spacecraftRot = glm::mat4(1); for (int i = 0; i < 3; i++){ for (int j = 0; j < 3; j++){ - tmp[i][j] = _stateMatrix[i][j]; + spacecraftRot[i][j] = _stateMatrix[i][j]; } } @@ -431,11 +421,10 @@ void RenderableFov::render(const RenderData& data){ _programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); _programObject->setUniform("ModelTransform", transform); setPscUniforms(_programObject, &data.camera, data.position); - bool drawFOV = false; - if (Time::ref().deltaTime() > 10){ + if (openspace::ImageSequencer2::ref().isReady()){ drawFOV = ImageSequencer2::ref().instumentActive(_instrumentID); } @@ -475,20 +464,19 @@ void RenderableFov::render(const RenderData& data){ double targetEpoch; // for each FOV vector - for (int i = 0; i < bounds.size(); i++){ + for (int i = 0; i <= bounds.size(); i++){ // compute surface intercept + int r = (i == bounds.size()) ? 0 : i; openspace::SpiceManager::ref().getSurfaceIntercept(_fovTarget, _spacecraft, _instrumentID, _frame, _method, _aberrationCorrection, - _time, targetEpoch, bounds[i], ipoint, ivec, _interceptTag[i]); + _time, targetEpoch, bounds[r], ipoint, ivec, _interceptTag[r]); // if not found, use the orthogonal projected point - - if (!_interceptTag[i]) _projectionBounds[i] = orthogonalProjection(bounds[i]); + if (!_interceptTag[r]) _projectionBounds[r] = orthogonalProjection(bounds[r]); // VBO1 : draw vectors representing outer points of FOV. - if (_interceptTag[i]){ + if (_interceptTag[r]){ _interceptVector = PowerScaledCoordinate::CreatePowerScaledCoordinate(ivec[0], ivec[1], ivec[2]); _interceptVector[3] += 3; - //_interceptVector = pscInterpolate(_interceptVector, bsvec, t); // INTERCEPTIONS memcpy(&_varray1[indx], glm::value_ptr(glm::vec4(0)), size); indx += 4; @@ -505,14 +493,14 @@ void RenderableFov::render(const RenderData& data){ indx += 4; memcpy(&_varray1[indx], glm::value_ptr(glm::vec4(0, 0, 1, 1)), size); indx += 4; - memcpy(&_varray1[indx], glm::value_ptr(_projectionBounds[i].vec4()), size); + memcpy(&_varray1[indx], glm::value_ptr(_projectionBounds[r].vec4()), size); indx += 4; memcpy(&_varray1[indx], glm::value_ptr(blue), size); indx += 4; } else{ - glm::vec4 corner(bounds[i][0], bounds[i][1], bounds[i][2], data.position[3] + 2); - corner = tmp*corner; + glm::vec4 corner(bounds[r][0], bounds[r][1], bounds[r][2], data.position[3] + 2); + corner = spacecraftRot*corner; // "INFINITE" FOV memcpy(&_varray1[indx], glm::value_ptr(glm::vec4(0)), size); indx += 4; @@ -524,7 +512,8 @@ void RenderableFov::render(const RenderData& data){ indx += 4; } } - _interceptTag[4] = _interceptTag[0]; // 0 & 5 same point + + _interceptTag[4] = _interceptTag[0]; fovProjection(_interceptTag, bounds); updateData(); } @@ -532,7 +521,7 @@ void RenderableFov::render(const RenderData& data){ glLineWidth(_lineWidth); glBindVertexArray(_vaoID[0]); - glDrawArrays(GL_TRIANGLE_STRIP, 0, _vtotal[0]); + glDrawArrays(GL_LINES, 0, _vtotal[0]); glBindVertexArray(0); glLineWidth(_lineWidth); @@ -540,26 +529,14 @@ void RenderableFov::render(const RenderData& data){ glDrawArrays(GL_LINES, 0, _vtotal[0]); glBindVertexArray(0); - //render points - glPointSize(2.f); - glBindVertexArray(_vaoID[0]); - glDrawArrays(GL_POINTS, 0, _vtotal[0]); - glBindVertexArray(0); - //second vbo - if (_withinFOV){ + if (drawFOV){ glLineWidth(1.f); glBindVertexArray(_vaoID[1]); glDrawArrays(GL_LINE_LOOP, 0, _vtotal[1]); glBindVertexArray(0); } glLineWidth(1.f); - - /*glPointSize(5.f); - glBindVertexArray(_vaoID2); - glDrawArrays(GL_POINTS, 0, _vtotal2); - glBindVertexArray(0); - */ } _programObject->deactivate(); } diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 2842cb1e03..ae5ce38a4f 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -548,7 +548,7 @@ namespace openspace { ); } - std::vector instrVec = ImageSequencer2::ref().getActiveInstruments(); + /*std::vector instrVec = ImageSequencer2::ref().getActiveInstruments(); std::string active =""; for (int i = 0; i < instrVec.size(); i++){ @@ -561,7 +561,7 @@ namespace openspace { glm::vec4(0.3, 0.6, 1, 1), "Active Instrument : %s", active.c_str() - ); + );*/ } } @@ -595,6 +595,7 @@ namespace openspace { int i = 0; PrintText(i++, "Date: %s", Time::ref().currentTimeUTC().c_str()); + /* PrintText(i++, "Avg. Frametime: %.5f", sgct::Engine::instance()->getAvgDt()); PrintText(i++, "Drawtime: %.5f", sgct::Engine::instance()->getDrawTime()); PrintText(i++, "Frametime: %.5f", sgct::Engine::instance()->getDt()); @@ -603,32 +604,28 @@ namespace openspace { PrintText(i++, "View dir: (% .5f, % .5f, % .5f)", viewdirection[0], viewdirection[1], viewdirection[2]); PrintText(i++, "Cam->origin: (% .15f, % .4f)", pssl[0], pssl[1]); PrintText(i++, "Scaling: (% .5f, % .5f)", scaling[0], scaling[1]); + */ + if (openspace::ImageSequencer2::ref().isReady()){ + double remaining = openspace::ImageSequencer2::ref().getNextCaptureTime() - currentTime; + double t = 1.f - remaining / openspace::ImageSequencer2::ref().getIntervalLength(); + std::string progress = "|"; + int g = ((t)* 30) + 1; + for (int i = 0; i < g; i++) progress.append("-"); progress.append(">"); + for (int i = 0; i < 31 - g; i++) progress.append(" "); + std::string str = ""; + openspace::SpiceManager::ref().getDateFromET(openspace::ImageSequencer2::ref().getNextCaptureTime(), str); - double remaining = openspace::ImageSequencer::ref().getNextCaptureTime() - currentTime; - double t = 1.f - remaining / openspace::ImageSequencer::ref().getIntervalLength(); - std::string progress = "|"; - int g = ((t)* 20) + 1; - for (int i = 0; i < g; i++) progress.append("-"); progress.append(">"); - for (int i = 0; i < 21 - g; i++) progress.append(" "); + progress.append("|"); + if (remaining > 0){ + glm::vec4 g1(0, t, 0, 1); + glm::vec4 g2(1 - t); + PrintColorText(i++, "Next projection in:", 10, g1 + g2); + PrintColorText(i++, "%.0f sec %s %.1f %%", 10, g1 + g2, remaining, progress.c_str(), t * 100); + } + glm::vec4 w(1); + PrintColorText(i++, "Ucoming capture : %s", 10, w, str.c_str()); - std::string str = ""; - openspace::SpiceManager::ref().getDateFromET(openspace::ImageSequencer::ref().getNextCaptureTime(), str); - - progress.append("|"); - if (remaining > 0){ - glm::vec4 g1(0, t, 0, 1); - glm::vec4 g2(1 - t); - PrintColorText(i++, "Next projection in | %.0f seconds", 10, g1 + g2, remaining); - PrintColorText(i++, "%s %.1f %%", 10, g1 + g2, progress.c_str(), t * 100); - } - glm::vec4 w(1); - glm::vec4 b(0.3, 0.6, 1, 1); - glm::vec4 b2(0.5, 1, 0.5, 1); - PrintColorText(i++, "Ucoming capture : %s", 10, w, str.c_str()); - - - if (Time::ref().deltaTime() > 10){ std::pair nextTarget = ImageSequencer2::ref().getNextTarget(); std::pair currentTarget = ImageSequencer2::ref().getCurrentTarget(); @@ -648,7 +645,9 @@ namespace openspace { hh.append(std::to_string(hour)); mm.append(std::to_string(minute)); ss.append(std::to_string(second)); - + + + glm::vec4 b2(1.00, 0.51, 0.00, 1); PrintColorText(i++, "Switching observation focus in : [%s:%s:%s]", 10, b2, hh.c_str(), mm.c_str(), ss.c_str()); std::pair> incidentTargets = ImageSequencer2::ref().getIncidentTargetList(2); @@ -659,23 +658,43 @@ namespace openspace { double t = (double)(p + 1) / (double)(isize+1); t = (p > isize / 2) ? 1-t : t; t += 0.3; - color = (p == isize / 2) ? glm::vec4(0, 1, 0, 1) : glm::vec4(t, t, t, 1); + color = (p == isize / 2) ? glm::vec4(1.00, 0.51, 0.00, 1) : glm::vec4(t, t, t, 1); PrintColorText(i, "%s%s", 10, color, space.c_str(), incidentTargets.second[p].c_str()); for (int k = 0; k < 10; k++){ space += " "; } } i++; + + std::vector> instrVec = ImageSequencer2::ref().getActiveInstruments(); + + glm::vec4 active(0.58, 1, 0.00, 1); + glm::vec4 firing(0.58-t, 1-t, 1-t, 1); + glm::vec4 notFiring(0.5, 0.5, 0.5, 1); + + + double reduce = 0.01; + + PrintColorText(i++, "Active Instruments : ", 10, active); + for (int k = 0; k < instrVec.size(); k++){ + + if (instrVec[k].second == false){ + PrintColorText(i, "| |", 10, glm::vec4(0.3, 0.3, 0.3, 1)); + PrintColorText(i++, " %5s", 10, glm::vec4(0.3, 0.3, 0.3, 1), instrVec[k].first.c_str()); + } + else{ + PrintColorText(i, "|", 10, glm::vec4(0.3, 0.3, 0.3, 1)); + if (instrVec[k].first == "NH_LORRI"){ + PrintColorText(i, " + ", 10, firing); + } + PrintColorText(i, " |", 10, glm::vec4(0.3, 0.3, 0.3, 1)); + PrintColorText(i++, " %5s", 10, active, instrVec[k].first.c_str()); + + } + } + } - - std::vector instrVec = ImageSequencer2::ref().getActiveInstruments(); - - std::string active = ""; - for (int i = 0; i < instrVec.size(); i++){ - active.append(instrVec[i]); - active.append("\n"); - } - PrintColorText(i++, "Active Instrument : %5s", 10, b, active.c_str()); + #undef PrintText } diff --git a/src/util/payload.cpp b/src/util/decoder.cpp similarity index 86% rename from src/util/payload.cpp rename to src/util/decoder.cpp index d7c23fdbbe..6f9e77c742 100644 --- a/src/util/payload.cpp +++ b/src/util/decoder.cpp @@ -22,20 +22,20 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include +#include #include namespace { -const std::string _loggerCat = "Payload"; +const std::string _loggerCat = "Decoder"; } namespace openspace { -Payload* Payload::createFromDictionary(const ghoul::Dictionary& dictionary, const std::string type) +Decoder* Decoder::createFromDictionary(const ghoul::Dictionary& dictionary, const std::string type) { - ghoul::TemplateFactory* factory - = FactoryManager::ref().factory(); - Payload* result = factory->create(type, dictionary); + ghoul::TemplateFactory* factory + = FactoryManager::ref().factory(); + Decoder* result = factory->create(type, dictionary); if (result == nullptr) { LERROR("Failed creating Payload object of type '" << type << "'"); @@ -44,15 +44,15 @@ Payload* Payload::createFromDictionary(const ghoul::Dictionary& dictionary, cons return result; } -Payload::Payload() +Decoder::Decoder() { } -Payload::Payload(const ghoul::Dictionary& dictionary) +Decoder::Decoder(const ghoul::Dictionary& dictionary) { } -Payload::~Payload() +Decoder::~Decoder() { } diff --git a/src/util/factorymanager.cpp b/src/util/factorymanager.cpp index 8ddfc6e1d7..fbb5cbe807 100644 --- a/src/util/factorymanager.cpp +++ b/src/util/factorymanager.cpp @@ -51,9 +51,9 @@ #include #include -#include -#include -#include +#include +#include +#include // std @@ -103,9 +103,10 @@ void FactoryManager::initialize() _manager->factory()->registerClass("Static"); _manager->factory()->registerClass("Spice"); - _manager->addFactory(new ghoul::TemplateFactory); - _manager->factory()->registerClass("Camera"); - _manager->factory()->registerClass("Scanner"); + _manager->addFactory(new ghoul::TemplateFactory); + _manager->factory()->registerClass("Instrument"); + _manager->factory()->registerClass("Target"); + // Add PlanetGeometry _manager->addFactory(new ghoul::TemplateFactory); diff --git a/src/util/hongkangparser.cpp b/src/util/hongkangparser.cpp index 0890192e2f..8f700dce35 100644 --- a/src/util/hongkangparser.cpp +++ b/src/util/hongkangparser.cpp @@ -37,19 +37,61 @@ namespace { const std::string _loggerCat = "HongKangParser"; + const std::string keyTranslation = "DataInputTranslation"; } namespace openspace { -HongKangParser::HongKangParser(const std::string& fileName, - std::string spacecraft, - std::map fileTranslation, - std::vector potentialTargets) : - _defaultCaptureImage(absPath("C:/Users/michal/openspace/openspace-data/scene/common/textures/placeholder_blank.png")) + HongKangParser::HongKangParser(const std::string& fileName, + std::string spacecraft, + ghoul::Dictionary translationDictionary, + std::vector potentialTargets) : + _defaultCaptureImage(absPath("C:/Users/michal/openspace/openspace-data/scene/common/textures/placeholder_blank.png")) { _fileName = fileName; _spacecraft = spacecraft; - _fileTranslation = fileTranslation; _potentialTargets = potentialTargets; + + //get the different instrument types + const std::vector& decoders = translationDictionary.keys(); + //for each decoder (assuming might have more if hong makes changes) + for (int i = 0; i < decoders.size(); i++){ + //create dictionary containing all {playbookKeys , spice IDs} + if (decoders[i] == "Instrument"){ + ghoul::Dictionary typeDictionary; + translationDictionary.getValue(decoders[i], typeDictionary); + //for each playbook call -> create a Decoder object + const std::vector& keys = typeDictionary.keys(); + for (int j = 0; j < keys.size(); j++){ + std::string currentKey = decoders[i] + "." + keys[j]; + + ghoul::Dictionary decoderDictionary; + translationDictionary.getValue(currentKey, decoderDictionary); + + Decoder *decoder = Decoder::createFromDictionary(decoderDictionary, decoders[i]); + //insert decoder to map - this will be used in the parser to determine + //behavioral characteristics of each instrument + _fileTranslation[keys[j]] = decoder; + } + } + //Hong's playbook needs _only_ instrument translation though. + } +} + +void findPlaybookSpecifiedTarget(std::string line, std::string& target){ + //remembto add this lua later... + std::vector ptarg = { "PLUTO", "CHARON", "NIX", "HYDRA", "P5", "P4" }; + for (auto p : ptarg){ + // loop over all targets and determine from 4th col which target this instrument points to + std::transform(line.begin(), line.end(), line.begin(), toupper); + if (line.find(p) != std::string::npos){ + target = p; + break; + } + else{ + // not found - we set void until we have more info. + target = "VOID"; + } + } } void HongKangParser::create(){ @@ -62,100 +104,110 @@ void HongKangParser::create(){ std::ifstream file(_fileName); if (!file.good()) LERROR("Failed to open txt file '" << _fileName << "'"); - std::string timestr = ""; + std::string line = ""; double shutter = 0.01; double startTime, stopTime; - // for augmentation we only need the keys in acronymDictionary as a vector - std::vector payload; - for (auto p : _acronymDictionary) - for (auto t : p.second) - payload.push_back(t); - payload.erase(std::unique(payload.begin(), payload.end()), payload.end()); - - std::string previousInstrument; std::string previousTarget; - double longExposureStart = 0; - double longExposureStop = 0; - std::string longExposureKeyword; + std::string previousCamera; + std::string previousScanner; + TimeRange cameraRange; + TimeRange scanRange; + + std::vector scannerSpiceID; + std::vector cameraSpiceID; + + double capture_start = -1; + double capture_stop = -1; + double scan_start = -1; + double scan_stop = -1; + + std::string cameraTarget = "VOID"; + std::string scannerTarget = "VOID"; do{ - std::getline(file, timestr); - //For each instrument in acronym dictionary - for (auto it : _acronymDictionary){ - // check if first col in line has keyword of interest - std::string keyword = timestr.substr(0, timestr.find_first_of(" ")); - auto pos = keyword.find(it.first); - if (pos != std::string::npos){ - // grab the time - std::string met = timestr.substr(24, 9); - //convert to ephemeris time - startTime = getETfromMet(met); - /* - std::string checkIfMVIC = "MVIC"; - int count = 0; - bool foundStopTime = false; - if (findExactMatch("MVIC", keyword)){ - std::string abortLine; - int len = file.tellg(); - while (!file.eof() && !findExactMatch("ABORT", abortLine)){ + std::getline(file, line); + std::string event = line.substr(0, line.find_first_of(" ")); - std::getline(file, abortLine); - std::string abortCommand = abortLine.substr(0, abortLine.find_first_of(" ")); - count++; - if (findExactMatch("ABORT", abortCommand)){ - met = abortLine.substr(24, 9); - stopTime = getETfromMet(met); - foundStopTime = true; - } - } - file.seekg(len, std::ios_base::beg); - }else{ - //assume regular shutter speed; - stopTime = startTime + shutter; - } - - if (foundStopTime){ - longExposureStart = startTime; - longExposureStop = stopTime; - longExposureKeyword = keyword; - }*/ - - // retrieve corresponding SPICE call - std::vector instrument = it.second; - - // create image - Image image; - //stoptime- quick setting for now - stopTime = startTime + 0.01; - createImage(image, startTime, stopTime, instrument, "", _defaultCaptureImage); - // add targets - augmentWithSpice(image, _spacecraft, payload, _potentialTargets); - - //SKA ERSATTAS MED NAGOT ANNAT - "instrument times" - if (previousInstrument != it.first){ - previousInstrument = it.first; - std::pair v_time = std::make_pair(image.startTime, keyword); - _instrumentTimes.push_back(v_time); + auto it = _fileTranslation.find(event); + bool foundEvent = (it != _fileTranslation.end()); + + std::string met = line.substr(25, 9); + double time = getETfromMet(met); + + Image image; + + if (foundEvent){ + //store the time, this is used for getNextCaptureTime() + _captureProgression.push_back(time); + + if (it->second->getDecoderType() == "CAMERA"){ + if (capture_start == -1){ + //encountered new camera sequence- store start time + capture_start = time; + previousCamera = it->first; } + //always store individual image for camera + cameraSpiceID = it->second->getTranslation(); + //rely on playboook mdl column to determine target + findPlaybookSpecifiedTarget(line, cameraTarget); + //fill image + createImage(image, time, time + shutter, cameraSpiceID, cameraTarget, _defaultCaptureImage); + //IFF spaccraft has decided to switch target, store in target map (used for: 'next observation focus') if (previousTarget != image.target){ previousTarget = image.target; - std::pair v_target = std::make_pair(image.startTime, image.target); + std::pair v_target = std::make_pair(time, image.target); _targetTimes.push_back(v_target); } - //_subsetMap[image.target]._subset[keyword].push_back(image); + //store actual image in map. All targets get _only_ their corresp. subset. _subsetMap[image.target]._subset.push_back(image); - _subsetMap[image.target]._range.setRange(image.startTime); + //compute and store the range for each subset + _subsetMap[image.target]._range.setRange(time); + } + if (scan_start == -1 && it->second->getDecoderType() == "SCANNER"){ + //scanner works like state-machine -only store start time now + scan_start = time; + previousScanner = it->first; + //store scanning instrument - store image once stopTime is found! + findPlaybookSpecifiedTarget(line, scannerTarget); + scannerSpiceID = it->second->getTranslation(); + } + } + else{ // we have reached the end of a scan or consecutive capture sequence! + if (capture_start != -1){ + //end of capture sequence for camera, store end time of this sequence + capture_stop = time; + cameraRange._min = capture_start; + cameraRange._max = capture_stop; + _instrumentTimes.push_back(std::make_pair(previousCamera, cameraRange)); + + capture_start = -1; + } + if (line.find("END_NOM") != std::string::npos){ + assert(scan_start != -1, "SCAN end occured before SCAN call!"); + //end of scan, store end time of this scan + store the scan image + scan_stop = time; + scanRange._min = scan_start; + scanRange._max = scan_stop; + _instrumentTimes.push_back(std::make_pair(previousScanner, scanRange)); + + //store individual image + createImage(image, scan_start, scan_stop, scannerSpiceID, scannerTarget, _defaultCaptureImage); + + _subsetMap[image.target]._subset.push_back(image); + _subsetMap[image.target]._range.setRange(scan_start); + + scan_start = -1; } } } while (!file.eof()); } } } - //PRINT TO FILE FUNCTION + std::ofstream myfile; myfile.open("HongKangOutput.txt"); @@ -167,10 +219,14 @@ void HongKangParser::create(){ myfile << std::endl; for (auto image : target.second._subset){ - std::string time; - SpiceManager::ref().getDateFromET(image.startTime, time); + std::string time_beg; + std::string time_end; + SpiceManager::ref().getDateFromET(image.startTime, time_beg); + SpiceManager::ref().getDateFromET(image.stopTime, time_end); + myfile << std::fixed - << std::setw(10) << time + << std::setw(10) << time_beg + << std::setw(10) << time_end << std::setw(10) << (int)getMetFromET(image.startTime) << std::setw(10) << image.target << std::setw(10); for (auto instrument : image.activeInstruments){ @@ -180,6 +236,7 @@ void HongKangParser::create(){ } } myfile.close(); + } bool HongKangParser::augmentWithSpice(Image& image, @@ -227,9 +284,9 @@ void HongKangParser::createImage(Image& image, double startTime, double stopTime image.projected = false; } -double HongKangParser::getETfromMet(std::string timestr){ +double HongKangParser::getETfromMet(std::string line){ std::string::size_type sz; - return getETfromMet(std::stod(timestr, &sz)); + return getETfromMet(std::stod(line, &sz)); } double HongKangParser::getETfromMet(double met){ @@ -256,8 +313,7 @@ double HongKangParser::getMetFromET(double et){ if (et >= referenceET){ met = _metRef + (et - referenceET); - } - else{ + }else{ met = _metRef - (referenceET - et); } @@ -267,10 +323,14 @@ double HongKangParser::getMetFromET(double et){ std::map HongKangParser::getSubsetMap(){ return _subsetMap; } -std::vector> HongKangParser::getIstrumentTimes(){ +std::vector> HongKangParser::getIstrumentTimes(){ return _instrumentTimes; } std::vector> HongKangParser::getTargetTimes(){ return _targetTimes; } +std::vector HongKangParser::getCaptureProgression(){ + return _captureProgression; +}; + } \ No newline at end of file diff --git a/src/util/imagesequencer.cpp b/src/util/imagesequencer.cpp index cd16be7963..db2ee3c0b7 100644 --- a/src/util/imagesequencer.cpp +++ b/src/util/imagesequencer.cpp @@ -140,7 +140,6 @@ void createImage(std::vector& vec, double t1, std::string instrumen image.projected = false; vec.push_back(image); - // sort } double ImageSequencer::getNextCaptureTime(){ diff --git a/src/util/imagesequencer2.cpp b/src/util/imagesequencer2.cpp index 9106319477..a9e2e10567 100644 --- a/src/util/imagesequencer2.cpp +++ b/src/util/imagesequencer2.cpp @@ -45,6 +45,7 @@ namespace openspace { ImageSequencer2* ImageSequencer2::_instance = nullptr; ImageSequencer2::ImageSequencer2() : +_hasData(false), _defaultCaptureImage(absPath("C:/Users/michal/openspace/openspace-data/scene/common/textures/placeholder_blank.png")) {} @@ -62,10 +63,10 @@ void ImageSequencer2::deinitialize() { delete _instance; _instance = nullptr; } -/* -auto cmp = [](const Image &a, const Image &b)->bool{ - return a.startTime < b.startTime; -};*/ + +bool ImageSequencer2::isReady(){ + return _hasData; +} bool ImageSequencer2::imageComparer(const Image &a, const Image &b){ return a.startTime < b.startTime; @@ -77,7 +78,7 @@ std::vector::iterator ImageSequencer2::binary_find(std::vector::it bool(*compareFunc)(const Image &a, const Image &b)){ // Finds the lower bound in at most log(last - first) + 1 comparisons std::vector::iterator it = std::lower_bound(begin, end, val, compareFunc); - if (it != begin){ + if (it != begin && it != end){ return it; } return end; @@ -144,192 +145,119 @@ std::pair> ImageSequencer2::getIncidentTargetLi return incidentTargets; } -std::vector ImageSequencer2::getActiveInstruments(){ - return _currentlyActiveInstruments; +double ImageSequencer2::getIntervalLength(){ + double upcoming = getNextCaptureTime(); + if (_nextCapture != upcoming){ + _nextCapture = upcoming; + _intervalLength = upcoming - _currentTime; + } + return _intervalLength; +} + +double ImageSequencer2::getNextCaptureTime(){ + auto compareTime = [](const double &a, const double &b)->bool{ + return a < b; + }; + double nextCaptureTime = 0; + auto it = std::lower_bound(_captureProgression.begin(), _captureProgression.end(), _currentTime, compareTime); + if (it != _captureProgression.end()) + nextCaptureTime = *it; + + return nextCaptureTime; +} + +std::vector> ImageSequencer2::getActiveInstruments(){ + for (int i = 0; i < _instrumentOnOff.size(); i++){ + _instrumentOnOff[i].second = false; + } + for (auto key : _fileTranslation){ + for (auto instrumentID : key.second->getTranslation()){ + if (instumentActive(instrumentID)){ + for (int i = 0; i < _instrumentOnOff.size(); i++){ + if (instrumentID == _instrumentOnOff[i].first){ + _instrumentOnOff[i].second = true; + } + } + } + } + } + return _instrumentOnOff; } bool ImageSequencer2::instumentActive(std::string instrumentID){ - // make into template func - auto compareTime = [](const std::pair &a, - const std::pair &b)->bool{ - return a.first < b.first; - }; - - std::pair findEqualToThis; - findEqualToThis.first = _currentTime; - auto it = std::lower_bound(_instrumentTimes.begin(), _instrumentTimes.end(), findEqualToThis, compareTime); - - it = std::prev(it); - if (it != _instrumentTimes.end()){ - std::string key = it->second; - std::vector instruments = _acronymDictionary[key]; - for (auto i : instruments){ - if (i == instrumentID){ - _currentlyActiveInstruments = instruments; - return true; + for (auto i : _instrumentTimes){ + //check if this instrument is in range + if (i.second.inRange(_currentTime)){ + //if so, then get the corresponding spiceIDs + std::vector < std::string> spiceIDs = _fileTranslation[i.first]->getTranslation(); + //check which specific subinstrument is firing + for (auto s : spiceIDs){ + if (s == instrumentID){ + return true; + } } } } return false; } - -double ImageSequencer2::getNextCaptureTime(){ - // to do this we need getCurrentTarget to ALWAYS work! - return 0.0; +bool ImageSequencer2::getImagePaths(std::vector>& captures, std::string projectee, std::string instrumentID){ + if (!instumentActive(instrumentID) && !Time::ref().timeJumped()) return false; + return (instrumentID == "NH_LORRI") ? getImagePaths(captures, projectee) : false; } +bool ImageSequencer2::getImagePaths(std::vector>& captures, + std::string projectee){ + if (_subsetMap[projectee]._range.inRange(_currentTime) || + _subsetMap[projectee]._range.inRange(_previousTime)){ + auto compareTime = [](const Image &a, + const Image &b)->bool{ + return a.startTime < b.startTime; + }; + + auto begin = _subsetMap[projectee]._subset.begin(); + auto end = _subsetMap[projectee]._subset.end(); + + std::vector> captureTimes; + Image findPrevious; + findPrevious.startTime = _previousTime; + Image findCurrent; + findCurrent.startTime = _currentTime; + + auto curr = std::lower_bound(begin, end, findCurrent, compareTime); + auto prev = std::lower_bound(begin, end, findPrevious, compareTime); + + if (curr != begin && curr != end && prev != begin && prev != end){ + std::transform(prev, curr, std::back_inserter(captureTimes), + [](const Image& i) { + return std::make_pair(i.startTime, i.path); + }); + std::reverse(captureTimes.begin(), captureTimes.end()); + captures = captureTimes; + return true; + } + } + return false; +} + + void ImageSequencer2::runSequenceParser(SequenceParser* parser){ parser->create(); + _fileTranslation = parser->getTranslation(); // should perhaps be named 'instrumentTranslation' + _subsetMap = parser->getSubsetMap(); + _instrumentTimes = parser->getIstrumentTimes(); + _targetTimes = parser->getTargetTimes(); + _captureProgression = parser->getCaptureProgression(); - _subsetMap = parser->getSubsetMap(); - _instrumentTimes = parser->getIstrumentTimes(); - //_targetTimes = parser->getTargetTimes(); - _acronymDictionary = parser->getAcronymDictionary(); -} - -/* -bool ImageSequencer2::parsePlaybookFile(const std::string& fileName, - std::string spacecraft, - std::map> acronymDictionary, - std::vector potentialTargets) { - _acronymDictionary = acronymDictionary; - if (size_t position = fileName.find_last_of(".") + 1){ - if (position != std::string::npos){ - std::string extension = ghoul::filesystem::File(fileName).fileExtension(); - - if (extension == "txt"){// Hong Kang. pre-parsed playbook - LINFO("Using Preparsed Playbook V9H"); - std::ifstream file(fileName); - if (!file.good()) LERROR("Failed to open txt file '" << fileName << "'"); - - std::string timestr = ""; - double shutter = 0.01; - double startTime, stopTime; - - // for augmentation we only need the keys in acronymDictionary as a vector - std::vector payload; - for (auto p : acronymDictionary) - for (auto t : p.second) - payload.push_back(t); - payload.erase(std::unique(payload.begin(), payload.end()), payload.end()); - - std::string previousInstrument; - std::string previousTarget; - - double longExposureStart = 0; - double longExposureStop = 0; - std::string longExposureKeyword; - - do{ - std::getline(file, timestr); - //For each instrument in acronym dictionary - for (auto it : _acronymDictionary){ - // check if first col in line has keyword of interest - std::string keyword = timestr.substr(0, timestr.find_first_of(" ")); - auto pos = keyword.find(it.first); - if (pos != std::string::npos){ - // grab the time - std::string met = timestr.substr(24, 9); - //convert to ephemeris time - startTime = getETfromMet(met); - - //std::string checkIfMVIC = "MVIC"; - //int count = 0; - //bool foundStopTime = false; - //if (findExactMatch("MVIC", keyword)){ - // std::string abortLine; - // int len = file.tellg(); - // while (!file.eof() && !findExactMatch("ABORT", abortLine)){ - // - // std::getline(file, abortLine); - // std::string abortCommand = abortLine.substr(0, abortLine.find_first_of(" ")); - // count++; - // if (findExactMatch("ABORT", abortCommand)){ - // met = abortLine.substr(24, 9); - // stopTime = getETfromMet(met); - // foundStopTime = true; - // } - // } - // file.seekg(len, std::ios_base::beg); - //}else{ - // //assume regular shutter speed; - // stopTime = startTime + shutter; - //} - // - //if (foundStopTime){ - // longExposureStart = startTime; - // longExposureStop = stopTime; - // longExposureKeyword = keyword; - //} - - // retrieve corresponding SPICE call - std::vector instrument = it.second; - - // create image - Image image; - //stoptime- quick setting for now - stopTime = startTime + 0.01; - createImage(image, startTime, stopTime, instrument, "", _defaultCaptureImage); - // add targets - augmentWithSpice(image, spacecraft, payload, potentialTargets); - - //SKA ERSATTAS MED NAGOT ANNAT - "instrument times" - if (previousInstrument != it.first){ - previousInstrument = it.first; - std::pair v_time = std::make_pair(image.startTime, keyword); - _instrumentTimes.push_back(v_time); - } - - if (previousTarget != image.target ){ - previousTarget = image.target; - std::pair v_target = std::make_pair(image.startTime, image.target); - _targetTimes.push_back(v_target); - } - - //_subsetMap[image.target]._subset[keyword].push_back(image); - _subsetMap[image.target]._subset.push_back(image); - _subsetMap[image.target]._range.setRange(image.startTime); - } - } - } while (!file.eof()); - } + //copy payload from _fileTranslation + for (auto t : _fileTranslation){ + std::vector spiceIDs = t.second->getTranslation(); + for (auto id : spiceIDs){ + _instrumentOnOff.push_back(std::make_pair(id, false)); } } + _instrumentOnOff.erase(std::unique(_instrumentOnOff.begin(), + _instrumentOnOff.end()), + _instrumentOnOff.end()); + _hasData = true; - //PRINT FUNCTION - std::string st1 = "2015-07-14T10:00:00.00"; - std::string st2 = "2015-07-14T12:00:00.00"; - double start, stop; - - SpiceManager::ref().getETfromDate(st1, start); - SpiceManager::ref().getETfromDate(st2, stop); - - std::ofstream myfile; - myfile.open("augmentedPef.txt"); - - //print all - for (auto target : _subsetMap){ - std::string min, max; - SpiceManager::ref().getDateFromET(target.second._range._min, min); - SpiceManager::ref().getDateFromET(target.second._range._max, max); - - myfile << std::endl; - for (auto image : target.second._subset){ - std::string time; - SpiceManager::ref().getDateFromET(image.startTime, time); - myfile << std::fixed - << std::setw(10) << time - << std::setw(10) << (int)getMetFromET(image.startTime) - << std::setw(10) << image.target << std::setw(10); - for (auto instrument : image.activeInstruments){ - myfile << " " << instrument; - } - myfile << std::endl; - } - } - - myfile.close(); - - return true; } -*/ } // namespace openspace diff --git a/src/util/instrumentdecoder.cpp b/src/util/instrumentdecoder.cpp new file mode 100644 index 0000000000..e2370ed5e1 --- /dev/null +++ b/src/util/instrumentdecoder.cpp @@ -0,0 +1,63 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +namespace { + const std::string _loggerCat = "InstrumentDecoder"; + const std::string keyDetector = "DetectorType"; + const std::string keySpice = "Spice"; +} + +namespace openspace { + +InstrumentDecoder::InstrumentDecoder(const ghoul::Dictionary& dictionary) +{ + bool success = dictionary.getValue(keyDetector, _type); + ghoul_assert(success, "Instrument has not provided detector type"); + for_each(_type.begin(), _type.end(), [](char& in){ in = ::toupper(in); }); + + std::vector spice; + ghoul::Dictionary spiceDictionary; + success = dictionary.getValue(keySpice, spiceDictionary); + ghoul_assert(success, "Instrument did not provide spice ids"); + + + _spiceIDs.resize(spiceDictionary.size()); + for (int i = 0; i < _spiceIDs.size(); ++i) { + std::string id; + spiceDictionary.getValue(std::to_string(i + 1), id); + _spiceIDs[i] = id; + } +} + +std::string InstrumentDecoder::getDecoderType(){ + return _type; +} + +std::vector InstrumentDecoder::getTranslation(){ + return _spiceIDs; +} + +} // namespace openspace \ No newline at end of file diff --git a/src/util/labelparser.cpp b/src/util/labelparser.cpp new file mode 100644 index 0000000000..9ecf1293d9 --- /dev/null +++ b/src/util/labelparser.cpp @@ -0,0 +1,185 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014 * +* * +* Permission is hereby granted, free of charge, to any person obtaining a copy of this * +* software and associated documentation files (the "Software"), to deal in the Software * +* without restriction, including without limitation the rights to use, copy, modify, * +* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * +* permit persons to whom the Software is furnished to do so, subject to the following * +* conditions: * +* * +* The above copyright notice and this permission notice shall be included in all copies * +* or substantial portions of the Software. * +* * +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * +* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * +* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * +* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * +* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * +* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * +****************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace { + const std::string _loggerCat = "LabelParser"; + const std::string keySpecs = "Read"; + const std::string keyConvert = "Convert"; +} + +namespace openspace { +LabelParser::LabelParser(const std::string& fileName, + ghoul::Dictionary translationDictionary) +{ + _fileName = fileName; + //_fileTranslation = fileTranslation; + + //get the different instrument types + const std::vector& decoders = translationDictionary.keys(); + //for each decoder (assuming might have more if hong makes changes) + for (int i = 0; i < decoders.size(); i++){ + ghoul::Dictionary typeDictionary; + translationDictionary.getValue(decoders[i], typeDictionary); + + //create dictionary containing all {playbookKeys , spice IDs} + if (decoders[i] == "Instrument"){ + //for each playbook call -> create a Decoder object + const std::vector& keys = typeDictionary.keys(); + for (int j = 0; j < keys.size(); j++){ + std::string currentKey = decoders[i] + "." + keys[j]; + + ghoul::Dictionary decoderDictionary; + translationDictionary.getValue(currentKey, decoderDictionary); + + Decoder *decoder = Decoder::createFromDictionary(decoderDictionary, decoders[i]); + //insert decoder to map - this will be used in the parser to determine + //behavioral characteristics of each instrument + _fileTranslation[keys[j]] = decoder; + } + } + if (decoders[i] == "Target"){ + ghoul::Dictionary specsOfInterestDictionary; + typeDictionary.getValue(keySpecs, specsOfInterestDictionary); + + _specsOfInterest.resize(specsOfInterestDictionary.size()); + for (int i = 0; i < _specsOfInterest.size(); ++i) { + std::string readMe; + specsOfInterestDictionary.getValue(std::to_string(i + 1), readMe); + _specsOfInterest[i] = readMe; + } + ghoul::Dictionary convertDictionary; + typeDictionary.getValue(keyConvert, convertDictionary); + + const std::vector& keys = convertDictionary.keys(); + for (int j = 0; j < keys.size(); j++){ + ghoul::Dictionary itemDictionary; + convertDictionary.getValue(keys[j], itemDictionary); + Decoder *decoder = Decoder::createFromDictionary(itemDictionary, decoders[i]); + //insert decoder to map - this will be used in the parser to determine + //behavioral characteristics of each instrument + _fileTranslation[keys[j]] = decoder; + }; + } + } + for (auto t : _fileTranslation){ + std::cout << t.first << std::endl; + for (auto b : t.second->getTranslation()){ + std::cout << " " << b << std::endl; + } + } + +} +void LabelParser::create(){ + + std::vector tmp; + + + ghoul::filesystem::Directory sequenceDir(_fileName, true); + std::vector sequencePaths = sequenceDir.read(true, false); // check inputs + for (auto path : sequencePaths){ + if (size_t position = path.find_last_of(".") + 1){ + if (position != std::string::npos){ + ghoul::filesystem::File currentFile(path); + std::string extension = currentFile.fileExtension(); + + if (extension == "lbl"){ // discovered header file + std::ifstream file(currentFile.path()); + + if (!file.good()) LERROR("Failed to open label file '" << currentFile.path() << "'"); + + // open up label files + std::string line = ""; + double timestamp = 0.0; + bool found = false; + do { + std::getline(file, line); + for (auto spec : _specsOfInterest){ + auto pos = line.find(spec); + if (pos != std::string::npos){ + if (line.substr(0, line.find_first_of(" ")) == "TARGET_NAME"){ + /* std::string target = line.substr(line.find("=") + 2, line.find(" ")); + target.erase(std::remove(target.begin(), target.end(), '"'), target.end()); + for (auto t : _fileTranslation[target]->getTranslation()){ + std::cout << t << std::endl; + }*/ + + } + + + } + /*if (timestamp != 0.0){ + found = true; + std::string ext = "jpg"; + path.replace(path.begin() + position, path.end(), ext); + bool fileExists = FileSys.fileExists(path); + if (fileExists) { + // createImage(tmp, timestamp, "NH_LORRI", "", path); /// fix active instrument! + // std::sort(tmp.begin(), tmp.end(), imageComparer); + } + }*/ + } + } while (!file.eof() && found == false); + } + } + } + } + int pause; + std::cin >> pause; +} + +void LabelParser::createImage(Image& image, double startTime, double stopTime, std::vector instr, std::string targ, std::string pot) { + image.startTime = startTime; + image.stopTime = stopTime; + image.path = pot; + for (int i = 0; i < instr.size(); i++){ + image.activeInstruments.push_back(instr[i]); + } + image.target = targ; + image.projected = false; +} + + +std::map LabelParser::getSubsetMap(){ + return _subsetMap; +} +std::vector> LabelParser::getIstrumentTimes(){ + return _instrumentTimes; +} +std::vector> LabelParser::getTargetTimes(){ + return _targetTimes; +} +} \ No newline at end of file diff --git a/src/util/camerainstrument.cpp b/src/util/scannerdecoder.cpp similarity index 89% rename from src/util/camerainstrument.cpp rename to src/util/scannerdecoder.cpp index 71d820d1ae..e707bd8e99 100644 --- a/src/util/camerainstrument.cpp +++ b/src/util/scannerdecoder.cpp @@ -22,15 +22,15 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include +#include namespace { - const std::string _loggerCat = "CameraInstrument"; + const std::string _loggerCat = "ScannerDecoder"; } namespace openspace { -CameraInstrument::CameraInstrument(const ghoul::Dictionary& dictionary) :_type("CAMERA") +ScannerDecoder::ScannerDecoder(const ghoul::Dictionary& dictionary) : _type("SCANNER") { std::string value; for (int k = 0; k < dictionary.size(); k++){ @@ -38,12 +38,11 @@ CameraInstrument::CameraInstrument(const ghoul::Dictionary& dictionary) :_type(" _spiceIDs.push_back(value); } } - -std::string CameraInstrument::getType(){ +std::string ScannerDecoder::getDecoderType(){ return _type; } -std::vector CameraInstrument::getSpiceIDs(){ +std::vector ScannerDecoder::getSpiceIDs(){ return _spiceIDs; } diff --git a/src/util/scannerinstrument.cpp b/src/util/targetdecoder.cpp similarity index 82% rename from src/util/scannerinstrument.cpp rename to src/util/targetdecoder.cpp index e93ec43efe..e00ea938d7 100644 --- a/src/util/scannerinstrument.cpp +++ b/src/util/targetdecoder.cpp @@ -22,28 +22,30 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include +#include namespace { - const std::string _loggerCat = "ScannerInstrument"; + const std::string _loggerCat = "TargetDecoder"; } namespace openspace { - -ScannerInstrument::ScannerInstrument(const ghoul::Dictionary& dictionary) : _type("SCANNER") + +TargetDecoder::TargetDecoder(const ghoul::Dictionary& dictionary) :_type("TARGET") { - std::string value; - for (int k = 0; k < dictionary.size(); k++){ - dictionary.getValue(std::to_string(k + 1), value); - _spiceIDs.push_back(value); + _names.resize(dictionary.size()); + for (int i = 0; i < _names.size(); ++i) { + std::string readMe; + dictionary.getValue(std::to_string(i + 1), readMe); + _names[i] = readMe; } } -std::string ScannerInstrument::getType(){ + +std::string TargetDecoder::getDecoderType(){ return _type; } -std::vector ScannerInstrument::getSpiceIDs(){ - return _spiceIDs; +std::vector TargetDecoder::getTranslation(){ + return _names; } } // namespace openspace \ No newline at end of file From 8483c9b3211e1d20b59d23ac0286ee988dbfb931 Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Fri, 17 Apr 2015 21:23:16 -0400 Subject: [PATCH 05/45] added early return in frameConversion to avoid error --- src/util/spicemanager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index 304cee4447..a77fa8ea73 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -582,6 +582,8 @@ bool SpiceManager::getEstimatedPosition(const double time, const std::string tar // do NOT remove this method. bool SpiceManager::frameConversion(glm::dvec3& v, const std::string& from, const std::string& to, double ephemerisTime) const{ glm::dmat3 transform; + if (from == to) + return true; // get rotation matrix from frame A - frame B pxform_c(from.c_str(), to.c_str(), ephemerisTime, (double(*)[3])glm::value_ptr(transform)); bool success = !failed_c(); From 9893a6ee206660c3366ca280a32916a448d725ea Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Fri, 17 Apr 2015 21:25:33 -0400 Subject: [PATCH 06/45] Added temp method to get latest image in old imagesequencer --- include/openspace/util/imagesequencer.h | 3 ++- src/util/imagesequencer.cpp | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/openspace/util/imagesequencer.h b/include/openspace/util/imagesequencer.h index d0595aa4eb..599194ad0b 100644 --- a/include/openspace/util/imagesequencer.h +++ b/include/openspace/util/imagesequencer.h @@ -56,7 +56,7 @@ public: std::string& getActiveInstrument(){ return _activeInstrument; }; std::string findActiveInstrument(double time); - + std::string ImageSequencer::getLatestImage(); static ImageSequencer* _sequencer; @@ -74,6 +74,7 @@ private: std::string _defaultCaptureImage; std::string _activeInstrument; + std::string _latest; }; } // namespace openspace diff --git a/src/util/imagesequencer.cpp b/src/util/imagesequencer.cpp index c7a5dc8c90..7669de0959 100644 --- a/src/util/imagesequencer.cpp +++ b/src/util/imagesequencer.cpp @@ -139,6 +139,10 @@ std::string ImageSequencer::findActiveInstrument(double time){ return _activeInstrument; } +std::string ImageSequencer::getLatestImage(){ + return _latest; +} + bool ImageSequencer::getImagePath(double& currentTime, std::string& path, bool closedInterval){ auto binary_find = [](std::vector::iterator begin, std::vector::iterator end, @@ -168,6 +172,8 @@ bool ImageSequencer::getImagePath(double& currentTime, std::string& path, bool it->projected = true; path = it->path; currentTime = it->startTime; + + _latest = path; return true; } From 57800d12c7818d4ec30545c11cf1870900a3528d Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Fri, 17 Apr 2015 21:57:36 -0400 Subject: [PATCH 07/45] added the possibility to load a city light/night texture for planets --- .../rendering/planets/renderableplanet.h | 3 +- shaders/pscstandard_fs.glsl | 11 +++- src/rendering/planets/renderableplanet.cpp | 51 +++++++++++++++---- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/include/openspace/rendering/planets/renderableplanet.h b/include/openspace/rendering/planets/renderableplanet.h index f0cc725b87..2d3684552a 100644 --- a/include/openspace/rendering/planets/renderableplanet.h +++ b/include/openspace/rendering/planets/renderableplanet.h @@ -64,13 +64,14 @@ private: properties::StringProperty _colorTexturePath; ghoul::opengl::ProgramObject* _programObject; ghoul::opengl::Texture* _texture; + ghoul::opengl::Texture* _nightTexture; planetgeometry::PlanetGeometry* _geometry; properties::BoolProperty _performShading; properties::IntProperty _rotation; float _alpha; glm::dmat3 _stateMatrix; - + std::string _nightTexturePath; std::string _frame; std::string _target; double _time; diff --git a/shaders/pscstandard_fs.glsl b/shaders/pscstandard_fs.glsl index 8842f959a1..b4ae6a4131 100644 --- a/shaders/pscstandard_fs.glsl +++ b/shaders/pscstandard_fs.glsl @@ -36,8 +36,10 @@ uniform int shadows; uniform float time; uniform sampler2D texture1; +uniform sampler2D nightTex; in vec2 vs_st; +in vec2 vs_nightTex; in vec4 vs_normal; in vec4 vs_position; @@ -51,6 +53,7 @@ void main() vec4 position = vs_position; float depth = pscDepth(position); vec4 diffuse = texture(texture1, vs_st); + vec4 diffuse2 = texture(nightTex, vs_st); if (_performShading) { // directional lighting @@ -62,6 +65,7 @@ void main() vec3 l_pos = vec3(sun_pos); // sun. vec3 l_dir = normalize(l_pos-objpos.xyz); float intensity = min(max(5*dot(n,l_dir), 0.0), 1); + float darkSide = min(max(5*dot(n,-l_dir), 0.0), 1); float shine = 0.0001; @@ -76,9 +80,12 @@ void main() spec = specular * pow(intSpec, shine); } */ - diffuse = max(intensity * diffuse, ambient); + vec4 daytex = max(intensity * diffuse, ambient); + vec4 mixtex = mix(diffuse, diffuse2, (1+dot(n,-l_dir))/2); + + diffuse = (daytex*2 + mixtex)/3; + diffuse[3] = transparency; - ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); addToBuffer(frag); } diff --git a/src/rendering/planets/renderableplanet.cpp b/src/rendering/planets/renderableplanet.cpp index 958507d87d..817cf1acd4 100644 --- a/src/rendering/planets/renderableplanet.cpp +++ b/src/rendering/planets/renderableplanet.cpp @@ -56,8 +56,10 @@ namespace openspace { RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _colorTexturePath("colorTexture", "Color Texture") + , _nightTexturePath("") , _programObject(nullptr) , _texture(nullptr) + , _nightTexture(nullptr) , _geometry(nullptr) , _performShading("performShading", "Perform Shading", true) , _rotation("rotation", "Rotation", 0, 0, 360) @@ -68,8 +70,8 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) ghoul_assert(success, "RenderablePlanet need the '" <deinitialize(); delete _geometry; } - if(_texture) + if (_texture) delete _texture; + if (_nightTexture) + delete _nightTexture; _geometry = nullptr; _texture = nullptr; + _nightTexture = nullptr; return true; } @@ -181,10 +198,16 @@ void RenderablePlanet::render(const RenderData& data) _programObject->setUniform("_performShading", _performShading); // Bind texture - ghoul::opengl::TextureUnit unit; - unit.activate(); + ghoul::opengl::TextureUnit dayUnit; + dayUnit.activate(); _texture->bind(); - _programObject->setUniform("texture1", unit); + _programObject->setUniform("texture1", dayUnit); + + // Bind possible night texture + ghoul::opengl::TextureUnit nightUnit; + nightUnit.activate(); + _nightTexture->bind(); + _programObject->setUniform("nightTex", nightUnit); // render _geometry->render(); @@ -202,8 +225,18 @@ void RenderablePlanet::update(const UpdateData& data){ void RenderablePlanet::loadTexture() { delete _texture; _texture = nullptr; + delete _nightTexture; + _nightTexture = nullptr; + if (_nightTexturePath != "") { + _nightTexture = ghoul::io::TextureReader::ref().loadTexture(absPath(_nightTexturePath)); + if (_nightTexture) { + LDEBUG("Loaded texture from '" << _nightTexturePath << "'"); + _nightTexture->uploadTexture(); + _nightTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); + } + } if (_colorTexturePath.value() != "") { - _texture = ghoul::io::TextureReader::ref().loadTexture(_colorTexturePath); + _texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath)); if (_texture) { LDEBUG("Loaded texture from '" << _colorTexturePath << "'"); _texture->uploadTexture(); From 6cc21b3be78e667157a37def8e3b293179d81b88 Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Fri, 17 Apr 2015 22:09:35 -0400 Subject: [PATCH 08/45] Added image plane projection + shaders and dynamic ephemeris. The plane projection is now hard coded to target until it can be returned from imagesequencer. The dynamic ephemeris is not used for this at the moment but will come in handy later on. --- .../rendering/renderableplaneprojection.h | 96 +++++++ .../openspace/scenegraph/dynamicephemeris.h | 46 +++ include/openspace/util/constants.h | 13 + scripts/default_startup.lua | 3 +- shaders/modules/imageplane/imageplane_fs.glsl | 50 ++++ shaders/modules/imageplane/imageplane_vs.glsl | 49 ++++ src/rendering/renderablefov.cpp | 4 +- src/rendering/renderableplaneprojection.cpp | 267 ++++++++++++++++++ src/scenegraph/dynamicephemeris.cpp | 58 ++++ src/util/factorymanager.cpp | 5 + 10 files changed, 588 insertions(+), 3 deletions(-) create mode 100644 include/openspace/rendering/renderableplaneprojection.h create mode 100644 include/openspace/scenegraph/dynamicephemeris.h create mode 100644 shaders/modules/imageplane/imageplane_fs.glsl create mode 100644 shaders/modules/imageplane/imageplane_vs.glsl create mode 100644 src/rendering/renderableplaneprojection.cpp create mode 100644 src/scenegraph/dynamicephemeris.cpp diff --git a/include/openspace/rendering/renderableplaneprojection.h b/include/openspace/rendering/renderableplaneprojection.h new file mode 100644 index 0000000000..19d4390e9d --- /dev/null +++ b/include/openspace/rendering/renderableplaneprojection.h @@ -0,0 +1,96 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014-2015 * +* * +* 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 _RENDERABLEPLANEPROJECTION_H_ +#define _RENDERABLEPLANEPROJECTION_H_ + +#include + +#include +#include +#include + +namespace ghoul { + namespace filesystem { + class File; + } + namespace opengl { + class ProgramObject; + class Texture; + } +} + +namespace openspace { + struct LinePoint; + + struct target { + std::string body; + std::string frame; + std::string node; + }; + + class RenderablePlaneProjection : public Renderable { + + + public: + RenderablePlaneProjection(const ghoul::Dictionary& dictionary); + ~RenderablePlaneProjection(); + + bool initialize() override; + bool deinitialize() override; + + bool isReady() const override; + + void render(const RenderData& data) override; + void update(const UpdateData& data) override; + + private: + void loadTexture(); + void updatePlane(double time, std::string newPath); + void setTarget(std::string body); + + std::string _texturePath; + + bool _planeIsDirty; + + glm::dmat3 _stateMatrix; + std::string _frame; + + ghoul::opengl::ProgramObject* _shader; + bool _programIsDirty; + bool _textureIsDirty; + ghoul::opengl::Texture* _texture; + ghoul::filesystem::File* _textureFile; + GLuint _quad; + GLuint _vertexPositionBuffer; + std::string _spacecraft; + std::string _instrument; + + target _target; + std::string _name; + bool _moving; + }; + +} // namespace openspace +#endif diff --git a/include/openspace/scenegraph/dynamicephemeris.h b/include/openspace/scenegraph/dynamicephemeris.h new file mode 100644 index 0000000000..43b73e52db --- /dev/null +++ b/include/openspace/scenegraph/dynamicephemeris.h @@ -0,0 +1,46 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 __DYNAMICEPHEMERIS_H__ +#define __DYNAMICEPHEMERIS_H__ + +#include "ephemeris.h" + +namespace openspace { + +class DynamicEphemeris: public Ephemeris { +public: + DynamicEphemeris(const ghoul::Dictionary& dictionary + = ghoul::Dictionary()); + virtual ~DynamicEphemeris(); + virtual const psc& position() const; + virtual void update(const UpdateData& data) override; + void setPosition(psc pos); +private: + psc _position; +}; + +} // namespace openspace + +#endif // __DYNAMICEPHEMERIS_H__ diff --git a/include/openspace/util/constants.h b/include/openspace/util/constants.h index d82d62fb76..b779716d4e 100644 --- a/include/openspace/util/constants.h +++ b/include/openspace/util/constants.h @@ -88,6 +88,15 @@ namespace renderablemodel { const std::string keyGeometry = "Geometry"; } // namespace renderablemodel +namespace renderableplaneprojection { + const std::string keySpacecraft = "Spacecraft"; + const std::string keyInstrument = "Instrument"; + const std::string keyMoving = "Moving"; + const std::string keyTexture = "Texture"; + const std::string keyName = "Name"; + const std::string galacticFrame = "GALACTIC"; +} // namespace renderableplaneprojection + namespace renderablestars { const std::string keyFile = "File"; const std::string keyTexture = "Texture"; @@ -121,6 +130,10 @@ namespace staticephemeris { const std::string keyPosition = "Position"; } // namespace staticephemeris +namespace dynamicephemeris { + const std::string keyPosition = "Position"; +} // namespace dynamicephemeris + namespace spiceephemeris { const std::string keyBody = "Body"; const std::string keyOrigin = "Observer"; diff --git a/scripts/default_startup.lua b/scripts/default_startup.lua index 26a6c800db..9457af4b8a 100644 --- a/scripts/default_startup.lua +++ b/scripts/default_startup.lua @@ -5,8 +5,9 @@ openspace.setInvertRoll(true); --openspace.setInteractionSensitivity(10) -- This is the default value for the sensitivity (the higher, the more sensitive) -openspace.time.setTime("2007 FEB 27 16:40:00") -- This is the start time for a Jupiter run of New Horizons +openspace.time.setTime("2007 FEB 27 16:30:00") -- This is the start time for a Jupiter run of New Horizons +openspace.time.setTime("2007 FEB 28 03:45:00") -- Io Capture! openspace.time.setDeltaTime(10) -- How many seconds pass per second of realtime, changeable in the GUI diff --git a/shaders/modules/imageplane/imageplane_fs.glsl b/shaders/modules/imageplane/imageplane_fs.glsl new file mode 100644 index 0000000000..9f4447eabe --- /dev/null +++ b/shaders/modules/imageplane/imageplane_fs.glsl @@ -0,0 +1,50 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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__ + +uniform float time; +uniform sampler2D texture1; + +in vec2 vs_st; +in vec4 vs_position; + +#include "ABuffer/abufferStruct.hglsl" +#include "ABuffer/abufferAddToBuffer.hglsl" +#include "PowerScaling/powerScaling_fs.hglsl" + +void main() +{ + vec4 position = vs_position; + float depth = pscDepth(position); + vec4 diffuse; + if (gl_FrontFacing) + diffuse = texture(texture1, vs_st); + else { + diffuse = vec4(0.8); + } + + ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); + addToBuffer(frag); +} \ No newline at end of file diff --git a/shaders/modules/imageplane/imageplane_vs.glsl b/shaders/modules/imageplane/imageplane_vs.glsl new file mode 100644 index 0000000000..1d38eb6b77 --- /dev/null +++ b/shaders/modules/imageplane/imageplane_vs.glsl @@ -0,0 +1,49 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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__ + +uniform mat4 ViewProjection; +uniform mat4 ModelTransform; + +layout(location = 0) in vec4 in_position; +layout(location = 1) in vec2 in_st; + +out vec2 vs_st; +out vec4 vs_position; +out float s; + +#include "PowerScaling/powerScaling_vs.hglsl" + +void main() +{ + vec4 tmp = in_position; + vec4 position = pscTransform(tmp, ModelTransform); + + vs_position = tmp; + vs_st = in_st; + + position = ViewProjection * position; + gl_Position = z_normalization(position); +} \ No newline at end of file diff --git a/src/rendering/renderablefov.cpp b/src/rendering/renderablefov.cpp index e2392b1fad..243c723086 100644 --- a/src/rendering/renderablefov.cpp +++ b/src/rendering/renderablefov.cpp @@ -541,7 +541,7 @@ void RenderableFov::render(const RenderData& data){ glBindVertexArray(_vaoID[0]); glDrawArrays(GL_POINTS, 0, _vtotal[0]); glBindVertexArray(0); - + /* //second vbo if (_withinFOV){ glLineWidth(1.f); @@ -550,7 +550,7 @@ void RenderableFov::render(const RenderData& data){ glBindVertexArray(0); } glLineWidth(1.f); - +*/ /*glPointSize(5.f); glBindVertexArray(_vaoID2); glDrawArrays(GL_POINTS, 0, _vtotal2); diff --git a/src/rendering/renderableplaneprojection.cpp b/src/rendering/renderableplaneprojection.cpp new file mode 100644 index 0000000000..166399280c --- /dev/null +++ b/src/rendering/renderableplaneprojection.cpp @@ -0,0 +1,267 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014-2015 * +* * +* Permission is hereby granted, free of charge, to any person obtaining a copy of this * +* software and associated documentation files (the "Software"), to deal in the Software * +* without restriction, including without limitation the rights to use, copy, modify, * +* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * +* permit persons to whom the Software is furnished to do so, subject to the following * +* conditions: * +* * +* The above copyright notice and this permission notice shall be included in all copies * +* or substantial portions of the Software. * +* * +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * +* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * +* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * +* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * +* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * +* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * +****************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace { + const std::string _loggerCat = "RenderablePlaneProjection"; +} + +namespace openspace { + +using namespace constants::renderableplaneprojection; + +RenderablePlaneProjection::RenderablePlaneProjection(const ghoul::Dictionary& dictionary) + : Renderable(dictionary) + , _shader(nullptr) + , _programIsDirty(false) + , _texture(nullptr) + , _textureIsDirty(false) + , _quad(0) + , _vertexPositionBuffer(0) + , _name("ImagePlane") + , _texturePath("") + , _planeIsDirty(false) +{ + + dictionary.getValue(keySpacecraft, _spacecraft); + dictionary.getValue(keyInstrument, _instrument); + dictionary.getValue(keyMoving, _moving); + dictionary.getValue(keyName, _name); + + std::string texturePath = ""; + bool success = dictionary.getValue(keyTexture, _texturePath); + if (success) { + _texturePath = findPath(_texturePath); + _textureFile = new ghoul::filesystem::File(_texturePath); + } + + //_target.body = "JUPITER"; + //_target.frame = "IAU_JUPITER"; + //_target.node = "JupiterProjection"; + + _target.body = "IO"; + _target.frame = "IAU_IO"; + _target.node = "Io"; + + loadTexture(); +} + +RenderablePlaneProjection::~RenderablePlaneProjection() { + delete _textureFile; +} + +bool RenderablePlaneProjection::isReady() const { + bool ready = true; + if (!_shader) + ready &= false; + if (!_texture) + ready &= false; + return ready; +} + +bool RenderablePlaneProjection::initialize() { + glGenVertexArrays(1, &_quad); // generate array + glGenBuffers(1, &_vertexPositionBuffer); // generate buffer + + // Plane program + _shader = ghoul::opengl::ProgramObject::Build("imagePlane", + "${SHADERS}/modules/imageplane/imageplane_vs.glsl", + "${SHADERS}/modules/imageplane/imageplane_fs.glsl"); + if (!_shader) + return false; + _shader->setProgramObjectCallback([&](ghoul::opengl::ProgramObject*){ _programIsDirty = true; }); + + loadTexture(); + return isReady(); +} + +bool RenderablePlaneProjection::deinitialize() { + glDeleteVertexArrays(1, &_quad); + _quad = 0; + glDeleteBuffers(1, &_vertexPositionBuffer); + _vertexPositionBuffer = 0; + delete _texture; + delete _shader; + return true; +} + +void RenderablePlaneProjection::render(const RenderData& data) { + + glm::mat4 transform = glm::mat4(1.0); + + for (int i = 0; i < 3; i++){ + for (int j = 0; j < 3; j++){ + transform[i][j] = static_cast(_stateMatrix[i][j]); + } + } + + // Activate shader + _shader->activate(); + + _shader->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); + _shader->setUniform("ModelTransform", transform); + setPscUniforms(_shader, &data.camera, data.position); + + data.position; + ghoul::opengl::TextureUnit unit; + unit.activate(); + _texture->bind(); + _shader->setUniform("texture1", unit); + + glBindVertexArray(_quad); + glDrawArrays(GL_TRIANGLES, 0, 6); + + _shader->deactivate(); + +} + +void RenderablePlaneProjection::update(const UpdateData& data) { + + + double time = data.time; + openspace::SpiceManager::ref().getPositionTransformMatrix(_target.frame, galacticFrame, time, _stateMatrix); + + std::string str = openspace::ImageSequencer::ref().getLatestImage(); + std::string tex = _texturePath; + + if (str != tex || _moving || _planeIsDirty) { + updatePlane(time, str); + } + + if (_programIsDirty) { + _shader->rebuildFromFile(); + _programIsDirty = false; + } + + if (_textureIsDirty) { + loadTexture(); + _textureIsDirty = false; + } +} + +void RenderablePlaneProjection::loadTexture() { + if (_texturePath != "") { + ghoul::opengl::Texture* texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath)); + if (texture) { + texture->uploadTexture(); + texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); + if (_texture) + delete _texture; + _texture = texture; + + delete _textureFile; + _textureFile = new ghoul::filesystem::File(_texturePath); + _textureFile->setCallback([&](const ghoul::filesystem::File&) { _textureIsDirty = true; }); + } + } +} + +void RenderablePlaneProjection::updatePlane(double time, std::string newPath) { + + std::string shape, frame; + std::vector bounds; + glm::dvec3 boresight; + + bool found = openspace::SpiceManager::ref().getFieldOfView(_instrument, shape, frame, boresight, bounds); + if (!found) { + LERROR("Could not locate instrument"); + return; + } + + glm::dvec3 vecToTarget; + double lt; + psc projection[4]; + + SpiceManager::ref().getTargetPosition(_target.body, _spacecraft, galacticFrame, "CN+S", time, vecToTarget, lt); + // The apparent position, CN+S, makes image align best with target + + for (int j = 0; j < bounds.size(); ++j) { + openspace::SpiceManager::ref().frameConversion(bounds[j], frame, galacticFrame, time); + glm::dvec3 cornerPosition = openspace::SpiceManager::ref().orthogonalProjection(vecToTarget, bounds[j]); + + if (!_moving) { + cornerPosition -= vecToTarget; + } + openspace::SpiceManager::ref().frameConversion(cornerPosition, galacticFrame, _target.frame, time); + + projection[j] = PowerScaledCoordinate::CreatePowerScaledCoordinate(cornerPosition[0], cornerPosition[1], cornerPosition[2]); + projection[j][3] += 3; + } + + if (!_moving) { + SceneGraphNode* thisNode = OsEng.renderEngine()->sceneGraph()->sceneGraphNode(_target.body); + bool orphan = thisNode->parent()->abandonChild(thisNode); + if (orphan) { + SceneGraphNode* newParent = OsEng.renderEngine()->sceneGraph()->sceneGraphNode(_target.node); + if (newParent != nullptr) + newParent->addNode(thisNode); + } + } + + const GLfloat vertex_data[] = { // square of two triangles drawn within fov in target coordinates + // x y z w s t + projection[1][0], projection[1][1], projection[1][2], projection[1][3], 0, 1, // Lower left 1 + projection[3][0], projection[3][1], projection[3][2], projection[3][3], 1, 0, // Upper right 2 + projection[2][0], projection[2][1], projection[2][2], projection[2][3], 0, 0, // Upper left 3 + projection[1][0], projection[1][1], projection[1][2], projection[1][3], 0, 1, // Lower left 4 = 1 + projection[0][0], projection[0][1], projection[0][2], projection[0][3], 1, 1, // Lower right 5 + projection[3][0], projection[3][1], projection[3][2], projection[3][3], 1, 0, // Upper left 6 = 2 + }; + + glBindVertexArray(_quad); // bind array + glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); // bind buffer + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast(0)); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast(sizeof(GLfloat) * 4)); + + if (!_moving) { + _texturePath = newPath; + loadTexture(); + } +} + +void RenderablePlaneProjection::setTarget(std::string body) { + _target.body = body; + _target.frame = "IAU_" + body; + _target.node = "Io"; // TODO: search for a node containing the body string @AA +} + +} // namespace openspace diff --git a/src/scenegraph/dynamicephemeris.cpp b/src/scenegraph/dynamicephemeris.cpp new file mode 100644 index 0000000000..2a0557b620 --- /dev/null +++ b/src/scenegraph/dynamicephemeris.cpp @@ -0,0 +1,58 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 + +namespace openspace { + +using namespace constants::dynamicephemeris; + +DynamicEphemeris::DynamicEphemeris(const ghoul::Dictionary& dictionary) + : _position(0.f, 0.f, 0.f, 0.f) +{ + const bool hasPosition = dictionary.hasKeyAndValue(keyPosition); + if (hasPosition) { + glm::vec4 tmp; + dictionary.getValue(keyPosition, tmp); + _position = tmp; + } +} + +DynamicEphemeris::~DynamicEphemeris() {} + +const psc& DynamicEphemeris::position() const { + return _position; +} + +void DynamicEphemeris::setPosition(psc pos) { + _position = pos; +} + +void DynamicEphemeris::update(const UpdateData&) { + +} + +} // namespace openspace \ No newline at end of file diff --git a/src/util/factorymanager.cpp b/src/util/factorymanager.cpp index 4dac141501..55819b1fad 100644 --- a/src/util/factorymanager.cpp +++ b/src/util/factorymanager.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,7 @@ // positioninformation #include +#include #include // projection @@ -89,6 +91,8 @@ void FactoryManager::initialize() "RenderableModel"); _manager->factory()->registerClass( "RenderablePlane"); + _manager->factory()->registerClass( + "RenderablePlaneProjection"); _manager->factory()->registerClass( "RenderableVolumeGL"); _manager->factory()->registerClass( @@ -97,6 +101,7 @@ void FactoryManager::initialize() // Add Ephimerides _manager->addFactory(new ghoul::TemplateFactory); _manager->factory()->registerClass("Static"); + _manager->factory()->registerClass("Dynamic"); _manager->factory()->registerClass("Spice"); // Add PlanetGeometry From dd67c005a4ba0495f1fbb336c32a927d76242d3f Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Sat, 18 Apr 2015 15:57:35 -0400 Subject: [PATCH 09/45] bugfix --- src/rendering/renderableplaneprojection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rendering/renderableplaneprojection.cpp b/src/rendering/renderableplaneprojection.cpp index 166399280c..1d31a20a63 100644 --- a/src/rendering/renderableplaneprojection.cpp +++ b/src/rendering/renderableplaneprojection.cpp @@ -225,7 +225,7 @@ void RenderablePlaneProjection::updatePlane(double time, std::string newPath) { } if (!_moving) { - SceneGraphNode* thisNode = OsEng.renderEngine()->sceneGraph()->sceneGraphNode(_target.body); + SceneGraphNode* thisNode = OsEng.renderEngine()->sceneGraph()->sceneGraphNode(_name); bool orphan = thisNode->parent()->abandonChild(thisNode); if (orphan) { SceneGraphNode* newParent = OsEng.renderEngine()->sceneGraph()->sceneGraphNode(_target.node); From d977024a82ed9275e502bf148bc7d5ce6ac386d7 Mon Sep 17 00:00:00 2001 From: Joakim Kilby Date: Mon, 20 Apr 2015 10:40:01 +0200 Subject: [PATCH 10/45] Changed from absolute path into relative using ${OPENSPACE_DATA} --- src/util/imagesequencer2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/imagesequencer2.cpp b/src/util/imagesequencer2.cpp index a9e2e10567..573b648b4a 100644 --- a/src/util/imagesequencer2.cpp +++ b/src/util/imagesequencer2.cpp @@ -46,7 +46,7 @@ ImageSequencer2* ImageSequencer2::_instance = nullptr; ImageSequencer2::ImageSequencer2() : _hasData(false), -_defaultCaptureImage(absPath("C:/Users/michal/openspace/openspace-data/scene/common/textures/placeholder_blank.png")) +_defaultCaptureImage(absPath("${OPENSPACE_DATA}/scene/common/textures/placeholder_blank.png")) {} From b6da465301b6164872fd3e2698f1688915d38718 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 20 Apr 2015 13:43:10 +0200 Subject: [PATCH 11/45] More changes regarding the absolute/relative paths --- src/util/hongkangparser.cpp | 2 +- src/util/imagesequencer.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/hongkangparser.cpp b/src/util/hongkangparser.cpp index 8f700dce35..0628de37c3 100644 --- a/src/util/hongkangparser.cpp +++ b/src/util/hongkangparser.cpp @@ -45,7 +45,7 @@ namespace openspace { std::string spacecraft, ghoul::Dictionary translationDictionary, std::vector potentialTargets) : - _defaultCaptureImage(absPath("C:/Users/michal/openspace/openspace-data/scene/common/textures/placeholder_blank.png")) + _defaultCaptureImage(absPath("${OPENSPACE_DATA}/scene/common/textures/placeholder_blank.png")) { _fileName = fileName; _spacecraft = spacecraft; diff --git a/src/util/imagesequencer.cpp b/src/util/imagesequencer.cpp index db2ee3c0b7..a2541beb9a 100644 --- a/src/util/imagesequencer.cpp +++ b/src/util/imagesequencer.cpp @@ -79,7 +79,7 @@ ImageSequencer::ImageSequencer() , _currentTime(-1.0) , _sequenceIDs(0) , _targetsAdded(false) - , _defaultCaptureImage(absPath("C:/Users/michal/openspace/openspace-data/scene/common/textures/placeholder_blank.png")) + , _defaultCaptureImage(absPath("${OPENSPACE_DATA}/scene/common/textures/placeholder_blank.png")) {} From f95b746ee1360e046991643f285314fff723c806 Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Mon, 20 Apr 2015 11:34:19 -0400 Subject: [PATCH 12/45] Made position depend on parent --- .../rendering/planets/renderableplanetprojection.h | 2 ++ src/rendering/planets/renderableplanetprojection.cpp | 5 +++-- src/rendering/renderableplaneprojection.cpp | 10 +++++----- src/rendering/renderengine.cpp | 2 +- src/scene/dynamicephemeris.cpp | 2 +- src/scene/scenegraphnode.cpp | 2 +- 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/include/openspace/rendering/planets/renderableplanetprojection.h b/include/openspace/rendering/planets/renderableplanetprojection.h index a12c679378..0915177576 100644 --- a/include/openspace/rendering/planets/renderableplanetprojection.h +++ b/include/openspace/rendering/planets/renderableplanetprojection.h @@ -107,8 +107,10 @@ private: double lightTime; std::string _target; + std::string _frame; std::string _defaultProjImage; std::string _next; + bool _capture; // FBO stuff diff --git a/src/rendering/planets/renderableplanetprojection.cpp b/src/rendering/planets/renderableplanetprojection.cpp index 77d68a4853..9a59b4b612 100644 --- a/src/rendering/planets/renderableplanetprojection.cpp +++ b/src/rendering/planets/renderableplanetprojection.cpp @@ -105,7 +105,8 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& _geometry = planetgeometryprojection::PlanetGeometryProjection::createFromDictionary(geometryDictionary); } - dictionary.getValue(keyFrame, _target); + dictionary.getValue(keyBody, _target); + dictionary.getValue(keyFrame, _frame); bool b1 = dictionary.getValue(keyInstrument, _instrumentID); @@ -340,7 +341,7 @@ glm::mat4 RenderablePlanetProjection::computeProjectorMatrix(const glm::vec3 loc void RenderablePlanetProjection::attitudeParameters(double time){ // precomputations for shader - openspace::SpiceManager::ref().getPositionTransformMatrix(_target, _mainFrame, time, _stateMatrix); + openspace::SpiceManager::ref().getPositionTransformMatrix(_frame, _mainFrame, time, _stateMatrix); openspace::SpiceManager::ref().getPositionTransformMatrix(_instrumentID, _mainFrame, time, _instrumentMatrix); _transform = glm::mat4(1); diff --git a/src/rendering/renderableplaneprojection.cpp b/src/rendering/renderableplaneprojection.cpp index 1d31a20a63..43afe66ed1 100644 --- a/src/rendering/renderableplaneprojection.cpp +++ b/src/rendering/renderableplaneprojection.cpp @@ -26,11 +26,11 @@ #include #include #include -#include +#include #include #include -#include -#include +#include +#include #include #include @@ -225,10 +225,10 @@ void RenderablePlaneProjection::updatePlane(double time, std::string newPath) { } if (!_moving) { - SceneGraphNode* thisNode = OsEng.renderEngine()->sceneGraph()->sceneGraphNode(_name); + SceneGraphNode* thisNode = OsEng.renderEngine()->scene()->sceneGraphNode(_name); bool orphan = thisNode->parent()->abandonChild(thisNode); if (orphan) { - SceneGraphNode* newParent = OsEng.renderEngine()->sceneGraph()->sceneGraphNode(_target.node); + SceneGraphNode* newParent = OsEng.renderEngine()->scene()->sceneGraphNode(_target.node); if (newParent != nullptr) newParent->addNode(thisNode); } diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 0c7a5e5e8b..e6c1db8359 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -1059,7 +1059,7 @@ void RenderEngine::changeViewPoint(std::string origin) { { std::string("Type"), std::string("Spice") }, { std::string("Body"), std::string("NEW HORIZONS") }, { std::string("Reference"), std::string("GALACTIC") }, - { std::string("Observer"), std::string("JUPITER BARYCENTER") }, + { std::string("Observer"), std::string("SUN") }, { std::string("Kernels"), ghoul::Dictionary() } }; newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary)); diff --git a/src/scene/dynamicephemeris.cpp b/src/scene/dynamicephemeris.cpp index 2a0557b620..605be3aaef 100644 --- a/src/scene/dynamicephemeris.cpp +++ b/src/scene/dynamicephemeris.cpp @@ -22,7 +22,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include +#include #include diff --git a/src/scene/scenegraphnode.cpp b/src/scene/scenegraphnode.cpp index 84154f01ef..cc0a28a98d 100644 --- a/src/scene/scenegraphnode.cpp +++ b/src/scene/scenegraphnode.cpp @@ -252,7 +252,7 @@ void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition) { } void SceneGraphNode::render(const RenderData& data) { - const psc thisPosition = data.position + _ephemeris->position(); + const psc thisPosition = data.position + worldPosition(); RenderData newData = {data.camera, thisPosition, data.doPerformanceMeasurement}; From 411765ab4d77c1715fa967321971373172235957 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 21 Apr 2015 16:22:58 +0200 Subject: [PATCH 13/45] Added new files for GUI --- CMakeLists.txt | 3 +- gui/CMakeLists.txt | 3 +- gui/timelineview/CMakeLists.txt | 10 ++ gui/timelineview/configurationwidget.cpp | 43 ++++++++ gui/timelineview/configurationwidget.h | 45 ++++++++ gui/timelineview/informationwidget.cpp | 33 ++++++ gui/timelineview/informationwidget.h | 36 +++++++ gui/timelineview/main.cpp | 35 +++++++ gui/timelineview/mainwindow.cpp | 124 +++++++++++++++++++++++ gui/timelineview/mainwindow.h | 56 ++++++++++ gui/timelineview/timecontrolwidget.cpp | 62 ++++++++++++ gui/timelineview/timecontrolwidget.h | 51 ++++++++++ gui/timelineview/timelinewidget.cpp | 42 ++++++++ gui/timelineview/timelinewidget.h | 42 ++++++++ 14 files changed, 582 insertions(+), 3 deletions(-) create mode 100644 gui/timelineview/CMakeLists.txt create mode 100644 gui/timelineview/configurationwidget.cpp create mode 100644 gui/timelineview/configurationwidget.h create mode 100644 gui/timelineview/informationwidget.cpp create mode 100644 gui/timelineview/informationwidget.h create mode 100644 gui/timelineview/main.cpp create mode 100644 gui/timelineview/mainwindow.cpp create mode 100644 gui/timelineview/mainwindow.h create mode 100644 gui/timelineview/timecontrolwidget.cpp create mode 100644 gui/timelineview/timecontrolwidget.h create mode 100644 gui/timelineview/timelinewidget.cpp create mode 100644 gui/timelineview/timelinewidget.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9066fd76bc..85436e1070 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -145,8 +145,7 @@ endif () ######################################################################################### add_subdirectory(src) - -#add_subdirectory(gui) +add_subdirectory(gui) ######################################################################################### # File Fetch diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index e33b8eb266..1bb6b8c2c7 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -1,3 +1,4 @@ cmake_minimum_required(VERSION 2.8.11) -add_subdirectory(luascriptexternalcontrol) \ No newline at end of file +add_subdirectory(luascriptexternalcontrol) +add_subdirectory(timelineview) \ No newline at end of file diff --git a/gui/timelineview/CMakeLists.txt b/gui/timelineview/CMakeLists.txt new file mode 100644 index 0000000000..6fbd84d5bb --- /dev/null +++ b/gui/timelineview/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 2.8.11) + +project(TimelineView) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +find_package(Qt5Widgets) +find_package(Qt5Network) +add_executable(TimelineView WIN32 main.cpp mainwindow.cpp configurationwidget.cpp informationwidget.cpp timecontrolwidget.cpp timelinewidget.cpp) +target_link_libraries(TimelineView Qt5::Widgets Qt5::Network) \ No newline at end of file diff --git a/gui/timelineview/configurationwidget.cpp b/gui/timelineview/configurationwidget.cpp new file mode 100644 index 0000000000..a678a2a14f --- /dev/null +++ b/gui/timelineview/configurationwidget.cpp @@ -0,0 +1,43 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 "configurationwidget.h" + +#include + +ConfigurationWidget::ConfigurationWidget(QWidget* parent) + : QWidget(parent) + , _ipAddress(new QLineEdit) + , _connect(new QPushButton("Connect")) + , _playbook(new QLineEdit) + , _load(new QPushButton("Load")) +{ + QGridLayout* layout = new QGridLayout; + layout->addWidget(_ipAddress, 0, 0); + layout->addWidget(_connect, 0, 1); + layout->addWidget(_playbook, 1, 0); + layout->addWidget(_load, 1, 1); + + setLayout(layout); +} diff --git a/gui/timelineview/configurationwidget.h b/gui/timelineview/configurationwidget.h new file mode 100644 index 0000000000..82c32a89c8 --- /dev/null +++ b/gui/timelineview/configurationwidget.h @@ -0,0 +1,45 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 __CONFIGURATIONWIDGET_H__ +#define __CONFIGURATIONWIDGET_H__ + +#include +#include +#include + +class ConfigurationWidget : public QWidget { +Q_OBJECT +public: + ConfigurationWidget(QWidget* parent); + +private: + QLineEdit* _ipAddress; + QPushButton* _connect; + + QLineEdit* _playbook; + QPushButton* _load; +}; + +#endif // __CONFIGURATIONWIDGET_H__ diff --git a/gui/timelineview/informationwidget.cpp b/gui/timelineview/informationwidget.cpp new file mode 100644 index 0000000000..f53147b510 --- /dev/null +++ b/gui/timelineview/informationwidget.cpp @@ -0,0 +1,33 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 "informationwidget.h" + +#include +#include + +InformationWidget::InformationWidget(QWidget* parent) + : QTextEdit(parent) +{ +} diff --git a/gui/timelineview/informationwidget.h b/gui/timelineview/informationwidget.h new file mode 100644 index 0000000000..b0f4df3aed --- /dev/null +++ b/gui/timelineview/informationwidget.h @@ -0,0 +1,36 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 __INFORMATIONWIDGET_H__ +#define __INFORMATIONWIDGET_H__ + +#include + +class InformationWidget : public QTextEdit { +Q_OBJECT +public: + InformationWidget(QWidget* parent); +}; + +#endif // __INFORMATIONWIDGET_H__ diff --git a/gui/timelineview/main.cpp b/gui/timelineview/main.cpp new file mode 100644 index 0000000000..e349172d9a --- /dev/null +++ b/gui/timelineview/main.cpp @@ -0,0 +1,35 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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 "mainwindow.h" + +int main(int argc, char** argv) { + QApplication app(argc, argv); + + MainWindow window; + window.show(); + + return app.exec(); +} diff --git a/gui/timelineview/mainwindow.cpp b/gui/timelineview/mainwindow.cpp new file mode 100644 index 0000000000..4bb9ed8a53 --- /dev/null +++ b/gui/timelineview/mainwindow.cpp @@ -0,0 +1,124 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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 "mainwindow.h" + +#include "configurationwidget.h" +#include "timecontrolwidget.h" +#include "informationwidget.h" +#include "timelinewidget.h" + +#include +#include +#include + +MainWindow::MainWindow() + : QWidget(nullptr) + , _configurationWidget(nullptr) + , _timeControlWidget(nullptr) + , _informationWidget(nullptr) + , _timelineWidget(nullptr) + , _socket(nullptr) +{ + setWindowTitle("OpenSpace Timeline"); + + _configurationWidget = new ConfigurationWidget(this); + _timeControlWidget = new TimeControlWidget(this); + _informationWidget = new InformationWidget(this); + _timelineWidget = new TimelineWidget(this); + + QGridLayout* layout = new QGridLayout; + layout->addWidget(_configurationWidget, 0, 0); + layout->addWidget(_timeControlWidget, 1, 0); + layout->addWidget(_informationWidget, 2, 0); + layout->addWidget(_timelineWidget, 0, 1, 3, 1); + + + + + + //_ipAddress->setMinimumWidth(200); + //_ipAddress->setText("127.0.0.1"); + //layout->addWidget(_ipAddress, 0, 0); + + //QPushButton* connectButton = new QPushButton("Connect"); + //connect(connectButton, SIGNAL(clicked()), this, SLOT(onConnectButton())); + //connectButton->show(); + //layout->addWidget(connectButton, 0, 1); + + //_command->setMinimumWidth(200); + //layout->addWidget(_command, 1, 0); + + //QPushButton* sendButton = new QPushButton("Send"); + //sendButton->setDefault(true); + //connect(sendButton, SIGNAL(clicked()), this, SLOT(sendCommandButton())); + //layout->addWidget(sendButton, 1, 1); + + //layout->addWidget(_logWindow, 2, 0, 1, 2); + + setLayout(layout); +} + +MainWindow::~MainWindow() { + //delete _command; + //delete _socket; +} + +void MainWindow::readTcpData() { + // QByteArray data = _socket->readAll(); + + //if (_logWindow->toPlainText().isEmpty()) + // _logWindow->setText(data.data()); + //else + // _logWindow->setText(_logWindow->toPlainText() + "\n" + data.data()); +} + +void MainWindow::onConnectButton() { + //delete _socket; + // + //_socket = new QTcpSocket(this); + // connect( _socket, SIGNAL(readyRead()), SLOT(readTcpData()) ); + // _socket->connectToHost(_ipAddress->text(), 20500); + +} + +void MainWindow::sendCommandButton() { + //if (!_socket) { + // if (_logWindow->toPlainText().isEmpty()) + // _logWindow->setText("No connection found"); + // else + // _logWindow->setText(_logWindow->toPlainText() + "\n" + "No connection found"); + // return; + //} + + //QString command = _command->text(); + + //if (_logWindow->toPlainText().isEmpty()) + // _logWindow->setText(command); + //else + // _logWindow->setText(_logWindow->toPlainText() + "\n" + command); + + // + //_socket->write(("0" + command + "\r\n").toLatin1()); +} diff --git a/gui/timelineview/mainwindow.h b/gui/timelineview/mainwindow.h new file mode 100644 index 0000000000..e5c1984f72 --- /dev/null +++ b/gui/timelineview/mainwindow.h @@ -0,0 +1,56 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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 __MAINWINDOW_H__ +#define __MAINWINDOW_H__ + +#include +#include + +class ConfigurationWidget; +class TimeControlWidget; +class InformationWidget; +class TimelineWidget; + +class MainWindow : public QWidget { +Q_OBJECT +public: + MainWindow(); + ~MainWindow(); + +private slots: + void onConnectButton(); + void sendCommandButton(); + void readTcpData(); + +private: + ConfigurationWidget* _configurationWidget; + TimeControlWidget* _timeControlWidget; + InformationWidget* _informationWidget; + TimelineWidget* _timelineWidget; + + QTcpSocket* _socket; +}; + +#endif // __MAINWINDOW_H__ diff --git a/gui/timelineview/timecontrolwidget.cpp b/gui/timelineview/timecontrolwidget.cpp new file mode 100644 index 0000000000..a838b1dcfd --- /dev/null +++ b/gui/timelineview/timecontrolwidget.cpp @@ -0,0 +1,62 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 "timecontrolwidget.h" + +#include +#include +#include +#include +#include +#include + +TimeControlWidget::TimeControlWidget(QWidget* parent) + : QWidget(parent) + , _currentTime(new QLabel("Current Time")) + , _setTime(new QComboBox) + , _currentDelta(new QLabel("Current Delta")) + , _setDelta(new QSlider(Qt::Horizontal)) + , _rewind(new QPushButton("<<")) + , _pause(new QPushButton("||")) + , _play(new QPushButton("|>")) + , _forward(new QPushButton(">>")) +{ + QGridLayout* layout = new QGridLayout; + + layout->addWidget(_currentTime, 0, 0); + layout->addWidget(_setTime, 0, 1); + layout->addWidget(_currentDelta, 1, 0); + layout->addWidget(_setDelta, 2, 0, 1, 2); + + QWidget* controlContainer = new QWidget; + QHBoxLayout* controlContainerLayout = new QHBoxLayout; + controlContainerLayout->addWidget(_rewind); + controlContainerLayout->addWidget(_pause); + controlContainerLayout->addWidget(_play); + controlContainerLayout->addWidget(_forward); + controlContainer->setLayout(controlContainerLayout); + layout->addWidget(controlContainer, 3, 0, 1, 2); + + setLayout(layout); +} diff --git a/gui/timelineview/timecontrolwidget.h b/gui/timelineview/timecontrolwidget.h new file mode 100644 index 0000000000..66edc5586b --- /dev/null +++ b/gui/timelineview/timecontrolwidget.h @@ -0,0 +1,51 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 __TIMECONTROLWIDGET_H__ +#define __TIMECONTROLWIDGET_H__ + +#include + +class QComboBox; +class QLabel; +class QPushButton; +class QSlider; + +class TimeControlWidget : public QWidget { +Q_OBJECT +public: + TimeControlWidget(QWidget* parent); + +private: + QLabel* _currentTime; + QComboBox* _setTime; + QLabel* _currentDelta; + QSlider* _setDelta; + QPushButton* _rewind; + QPushButton* _pause; + QPushButton* _play; + QPushButton* _forward; +}; + +#endif // __TIMECONTROLWIDGET_H__ diff --git a/gui/timelineview/timelinewidget.cpp b/gui/timelineview/timelinewidget.cpp new file mode 100644 index 0000000000..7028482f30 --- /dev/null +++ b/gui/timelineview/timelinewidget.cpp @@ -0,0 +1,42 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 "timelinewidget.h" + +#include +#include + +TimelineWidget::TimelineWidget(QWidget* parent) + : QWidget(parent) +{ + setMinimumWidth(300); + setMinimumHeight(500); +} + +void TimelineWidget::paintEvent(QPaintEvent* event) { + QPainter painter(this); + + painter.setBrush(QBrush(Qt::white)); + painter.drawRect(contentsRect()); +} diff --git a/gui/timelineview/timelinewidget.h b/gui/timelineview/timelinewidget.h new file mode 100644 index 0000000000..def40ffe6c --- /dev/null +++ b/gui/timelineview/timelinewidget.h @@ -0,0 +1,42 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 __TIMELINEWIDGET_H__ +#define __TIMELINEWIDGET_H__ + +#include + +class QPaintEvent; + +class TimelineWidget : public QWidget { +Q_OBJECT +public: + TimelineWidget(QWidget* parent); + +protected: + void paintEvent(QPaintEvent* event); + +}; + +#endif // __TIMELINEWIDGET_H__ From 163796cfdf06596fe40f84d1d63ddf4bf0c040b3 Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Tue, 21 Apr 2015 15:50:40 -0400 Subject: [PATCH 14/45] Simplified error suppressing in Spicemanager --- include/openspace/util/spicemanager.h | 2 ++ src/util/spicemanager.cpp | 47 ++++++++------------------- 2 files changed, 16 insertions(+), 33 deletions(-) diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index 7c73f4d3f4..314c0b00d1 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -673,6 +673,8 @@ private: std::map > > _spkIntervals; std::map > _ckCoverageTimes; std::map > _spkCoverageTimes; + + const static bool _showErrors = true; /// The last assigned kernel-id, used to determine the next free kernel id KernelIdentifier _lastAssignedKernel; diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index a77fa8ea73..db78b0dedb 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -586,12 +586,7 @@ bool SpiceManager::frameConversion(glm::dvec3& v, const std::string& from, const return true; // get rotation matrix from frame A - frame B pxform_c(from.c_str(), to.c_str(), ephemerisTime, (double(*)[3])glm::value_ptr(transform)); - bool success = !failed_c(); - if (!success){ - reset_c(); - return false; - } - + bool hasError = checkForError("Error converting from frame '" + from + "' to frame '" + to + "' at time " + std::to_string(ephemerisTime)); if (hasError) @@ -628,12 +623,6 @@ bool SpiceManager::targetWithinFieldOfView(const std::string& instrument, &visible); isVisible = (visible == SPICETRUE); - bool success = !failed_c(); - if (!success){ - reset_c(); - return false; - } - bool hasError = checkForError("Checking if target '" + target + "' is in view of instrument '" + instrument + "' failed"); @@ -664,12 +653,6 @@ bool SpiceManager::targetWithinFieldOfView(const std::string& instrument, &visible); isVisible = (visible == SPICETRUE); - bool success = !failed_c(); - if (!success){ - reset_c(); - return false; - } - bool hasError = checkForError("Checking if target '" + target + "' is in view of instrument '" + instrument + "' failed"); @@ -725,12 +708,6 @@ bool SpiceManager::getSurfaceIntercept(const std::string& target, isVisible = (found == SPICETRUE); - bool success = !failed_c(); - if (!success){ - reset_c(); - return false; - } - bool hasError = checkForError("Error retrieving surface intercept on target '" + target + "'" + "viewed from observer '" + observer + "' in " + "reference frame '" + bodyfixed + "' at time '" + @@ -830,15 +807,20 @@ bool SpiceManager::getPositionTransformMatrix(const std::string& fromFrame, double ephemerisTime, glm::dmat3& positionMatrix) const { - bool success, estimated = false; + bool success = false, estimated = false; pxform_c(fromFrame.c_str(), toFrame.c_str(), ephemerisTime, (double(*)[3])glm::value_ptr(positionMatrix)); success = !(failed_c()); - if (!success) { + if (!success && !_showErrors) { reset_c(); estimated = getEstimatedTransformMatrix(ephemerisTime, fromFrame, toFrame, positionMatrix); } + else { + bool hasError = checkForError("Error retrieving position transform matrix from " + "frame '" + fromFrame + "' to frame '" + toFrame + + "' at time '" + std::to_string(ephemerisTime)); + } positionMatrix = glm::transpose(positionMatrix); @@ -955,12 +937,6 @@ bool SpiceManager::getFieldOfView(int instrument, (double(*)[3])boundsArr // the bounds ); - bool success = !failed_c(); - if (!success){ - reset_c(); - return false; - } - bool hasError = checkForError("Error getting Field-of-View parameters for " "instrument '" + std::to_string(instrument) + "'"); if (hasError) @@ -982,7 +958,7 @@ bool SpiceManager::getFieldOfView(int instrument, bool SpiceManager::checkForError(std::string errorMessage) { int failed = failed_c(); - if (failed) { + if (failed && _showErrors) { static char msg[1024]; if (!errorMessage.empty()) { getmsg_c("LONG", 1024, msg); @@ -992,6 +968,11 @@ bool SpiceManager::checkForError(std::string errorMessage) { reset_c(); return true; } + else if (failed) { + reset_c(); + return false; + } + else return false; } From 813cc4acdb130fc8e781481a4659ef3aacb6c78e Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Tue, 21 Apr 2015 20:17:31 -0400 Subject: [PATCH 15/45] Added possible error message for estimated positions --- src/util/spicemanager.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index db78b0dedb..ed30de2b3f 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -575,7 +575,9 @@ bool SpiceManager::getEstimatedPosition(const double time, const std::string tar targetPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(pos[0], pos[1], pos[2]); - + std::cout << "estimating position for: " << target << ", w observer: " << observer << std::endl; + checkForError("Error estimating positin for target: " + target + ", or observer: " + observer); + return targetFound && observerFound; } @@ -894,8 +896,11 @@ bool SpiceManager::getEstimatedTransformMatrix(const double time, const std::str } } } + std::cout << "estimating from frame: " << fromFrame << ", to frame: " << toFrame << std::endl; + bool hasError = checkForError("Error estimating transform matrix from frame: " + + fromFrame + ", to frame: " + toFrame); - return true; + return !hasError; } From 641107a106fd11c4f8d68e0e5aede11c36a95519 Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Tue, 21 Apr 2015 20:22:58 -0400 Subject: [PATCH 16/45] Commented currently unused functions in new parenting system --- include/openspace/scene/scenegraphnode.h | 4 +-- src/scene/scenegraphnode.cpp | 37 ++++++++++++------------ 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/include/openspace/scene/scenegraphnode.h b/include/openspace/scene/scenegraphnode.h index c06b4b0c3c..a27228a3e2 100644 --- a/include/openspace/scene/scenegraphnode.h +++ b/include/openspace/scene/scenegraphnode.h @@ -65,10 +65,10 @@ public: void render(const RenderData& data); void updateCamera(Camera* camera) const; - void addNode(SceneGraphNode* child); + //void addNode(SceneGraphNode* child); void setParent(SceneGraphNode* parent); - bool abandonChild(SceneGraphNode* child); + //bool abandonChild(SceneGraphNode* child); const psc& position() const; psc worldPosition() const; diff --git a/src/scene/scenegraphnode.cpp b/src/scene/scenegraphnode.cpp index cc0a28a98d..d57109125e 100644 --- a/src/scene/scenegraphnode.cpp +++ b/src/scene/scenegraphnode.cpp @@ -252,7 +252,7 @@ void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition) { } void SceneGraphNode::render(const RenderData& data) { - const psc thisPosition = data.position + worldPosition(); + const psc thisPosition = worldPosition(); RenderData newData = {data.camera, thisPosition, data.doPerformanceMeasurement}; @@ -278,29 +278,30 @@ void SceneGraphNode::render(const RenderData& data) { // child->render(newData); } -// set & get -void SceneGraphNode::addNode(SceneGraphNode* child) -{ - // add a child node and set this node to be the parent - child->setParent(this); - _children.push_back(child); -} +// not used anymore @AA +//void SceneGraphNode::addNode(SceneGraphNode* child) +//{ +// // add a child node and set this node to be the parent +// child->setParent(this); +// _children.push_back(child); +//} void SceneGraphNode::setParent(SceneGraphNode* parent) { _parent = parent; } -bool SceneGraphNode::abandonChild(SceneGraphNode* child) { - std::vector < SceneGraphNode* >::iterator it = std::find(_children.begin(), _children.end(), child); - - if (it != _children.end()){ - _children.erase(it); - return true; - } - - return false; -} +//not used anymore @AA +//bool SceneGraphNode::abandonChild(SceneGraphNode* child) { +// std::vector < SceneGraphNode* >::iterator it = std::find(_children.begin(), _children.end(), child); +// +// if (it != _children.end()){ +// _children.erase(it); +// return true; +// } +// +// return false; +//} const psc& SceneGraphNode::position() const { From 97cbf977c551f8b2d6aa7ecbfb1a65773f3b882b Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Tue, 21 Apr 2015 20:31:33 -0400 Subject: [PATCH 17/45] Added body string to renderable to be able to search for target in scenegraph --- include/openspace/rendering/renderable.h | 7 +++++++ src/rendering/planets/renderableplanet.cpp | 4 ++-- .../planets/renderableplanetprojection.cpp | 5 +++-- src/rendering/renderable.cpp | 21 ++++++++++++++++++- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/include/openspace/rendering/renderable.h b/include/openspace/rendering/renderable.h index 99d9fed3d8..1149c247a8 100644 --- a/include/openspace/rendering/renderable.h +++ b/include/openspace/rendering/renderable.h @@ -69,8 +69,13 @@ public: virtual void update(const UpdateData& data); bool isVisible() const; + bool hasTimeInterval(); bool getInterval(double& start, double& end); + + bool hasBody(); + bool getBody(std::string& body); + void setBody(std::string& body); protected: std::string findPath(const std::string& path); @@ -83,6 +88,8 @@ private: std::string _relativePath; std::string _startTime; std::string _endTime; + std::string _targetBody; + bool _hasBody; bool _hasTimeInterval; }; diff --git a/src/rendering/planets/renderableplanet.cpp b/src/rendering/planets/renderableplanet.cpp index 817cf1acd4..a9e8bc2fb5 100644 --- a/src/rendering/planets/renderableplanet.cpp +++ b/src/rendering/planets/renderableplanet.cpp @@ -84,9 +84,9 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) } dictionary.getValue(keyFrame, _frame); - dictionary.getValue(keyBody, _target); - //assert(b1 == true); + if (_target != "") + setBody(_target); // TODO: textures need to be replaced by a good system similar to the geometry as soon // as the requirements are fixed (ab) diff --git a/src/rendering/planets/renderableplanetprojection.cpp b/src/rendering/planets/renderableplanetprojection.cpp index 9a59b4b612..f9fddf98c6 100644 --- a/src/rendering/planets/renderableplanetprojection.cpp +++ b/src/rendering/planets/renderableplanetprojection.cpp @@ -105,9 +105,10 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& _geometry = planetgeometryprojection::PlanetGeometryProjection::createFromDictionary(geometryDictionary); } - dictionary.getValue(keyBody, _target); dictionary.getValue(keyFrame, _frame); - + dictionary.getValue(keyBody, _target); + if (_target != "") + setBody(_target); bool b1 = dictionary.getValue(keyInstrument, _instrumentID); bool b2 = dictionary.getValue(keyProjObserver, _projectorID); diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp index 3ed7ed06f0..e11ed1052c 100644 --- a/src/rendering/renderable.cpp +++ b/src/rendering/renderable.cpp @@ -74,7 +74,8 @@ Renderable::Renderable(const ghoul::Dictionary& dictionary) : _enabled("enabled", "Is Enabled", true), _hasTimeInterval(false), _startTime(""), - _endTime("") + _endTime(""), + _targetBody("") { setName("renderable"); #ifndef NDEBUG @@ -152,6 +153,10 @@ bool Renderable::hasTimeInterval() { return _hasTimeInterval; } +bool Renderable::hasBody() { + return _hasBody; +} + bool Renderable::getInterval(double& start, double& end) { if (_startTime != "" && _endTime != "") { bool successStart = openspace::SpiceManager::ref().getETfromDate(_startTime, start); @@ -162,6 +167,20 @@ bool Renderable::getInterval(double& start, double& end) { return false; } +bool Renderable::getBody(std::string& body) { + if (_hasBody) { + body = _targetBody; + return true; + } + else + return false; +} + +void Renderable::setBody(std::string& body) { + _targetBody = body; + _hasBody = true; +} + bool Renderable::isReady() const { return true; } From 5cf614f03dfbef49385eb553610a0eaddee45c45 Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Tue, 21 Apr 2015 20:37:24 -0400 Subject: [PATCH 18/45] Modified changeViewPoint in order to work with new parenting system --- src/rendering/renderengine.cpp | 106 +++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 45 deletions(-) diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index e6c1db8359..78b4beb9c7 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -979,27 +979,29 @@ void RenderEngine::changeViewPoint(std::string origin) { } if (origin == "Pluto") { - ghoul::Dictionary solarDictionary = - { - { std::string("Type"), std::string("Spice") }, - { std::string("Body") , std::string("SUN") }, - { std::string("Reference"), std::string("ECLIPJ2000") }, - { std::string("Observer") , std::string("PLUTO BARYCENTER") }, - { std::string("Kernels") , ghoul::Dictionary() } - }; + plutoBarycenterNode->setParent(scene()->sceneGraphNode("SolarSystem")); + plutoBarycenterNode->setEphemeris(new StaticEphemeris); + + solarSystemBarycenterNode->setParent(plutoBarycenterNode); + newHorizonsNode->setParent(plutoBarycenterNode); + ghoul::Dictionary solarDictionary = + { + { std::string("Type"), std::string("Spice") }, + { std::string("Body"), std::string("SUN") }, + { std::string("Reference"), std::string("GALACTIC") }, + { std::string("Observer"), std::string("PLUTO BARYCENTER") }, + { std::string("Kernels"), ghoul::Dictionary() } + }; + ghoul::Dictionary jupiterDictionary = { { std::string("Type"), std::string("Spice") }, { std::string("Body"), std::string("JUPITER BARYCENTER") }, - { std::string("Reference"), std::string("ECLIPJ2000") }, - { std::string("Observer"), std::string("SUN") }, + { std::string("Reference"), std::string("GALACTIC") }, + { std::string("Observer"), std::string("PLUTO BARYCENTER") }, { std::string("Kernels"), ghoul::Dictionary() } }; - solarSystemBarycenterNode->setEphemeris(new SpiceEphemeris(solarDictionary)); - jupiterBarycenterNode->setEphemeris(new SpiceEphemeris(jupiterDictionary)); - plutoBarycenterNode->setEphemeris(new StaticEphemeris); - ghoul::Dictionary newHorizonsDictionary = { { std::string("Type"), std::string("Spice") }, @@ -1008,6 +1010,8 @@ void RenderEngine::changeViewPoint(std::string origin) { { std::string("Observer"), std::string("PLUTO BARYCENTER") }, { std::string("Kernels"), ghoul::Dictionary() } }; + solarSystemBarycenterNode->setEphemeris(new SpiceEphemeris(solarDictionary)); + jupiterBarycenterNode->setEphemeris(new SpiceEphemeris(jupiterDictionary)); newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary)); //ghoul::Dictionary dawnDictionary = @@ -1033,11 +1037,17 @@ void RenderEngine::changeViewPoint(std::string origin) { return; } if (origin == "Sun") { + solarSystemBarycenterNode->setParent(scene()->sceneGraphNode("SolarSystem")); + + plutoBarycenterNode->setParent(solarSystemBarycenterNode); + jupiterBarycenterNode->setParent(solarSystemBarycenterNode); + newHorizonsNode->setParent(solarSystemBarycenterNode); + ghoul::Dictionary plutoDictionary = { { std::string("Type"), std::string("Spice") }, { std::string("Body"), std::string("PLUTO BARYCENTER") }, - { std::string("Reference"), std::string("ECLIPJ2000") }, + { std::string("Reference"), std::string("GALACTIC") }, { std::string("Observer"), std::string("SUN") }, { std::string("Kernels"), ghoul::Dictionary() } }; @@ -1045,7 +1055,7 @@ void RenderEngine::changeViewPoint(std::string origin) { { { std::string("Type"), std::string("Spice") }, { std::string("Body"), std::string("JUPITER BARYCENTER") }, - { std::string("Reference"), std::string("ECLIPJ2000") }, + { std::string("Reference"), std::string("GALACTIC") }, { std::string("Observer"), std::string("SUN") }, { std::string("Kernels"), ghoul::Dictionary() } }; @@ -1087,36 +1097,42 @@ void RenderEngine::changeViewPoint(std::string origin) { return; } if (origin == "Jupiter") { - ghoul::Dictionary plutoDictionary = - { - { std::string("Type"), std::string("Spice") }, - { std::string("Body"), std::string("PLUTO BARYCENTER") }, - { std::string("Reference"), std::string("ECLIPJ2000") }, - { std::string("Observer"), std::string("JUPITER BARYCENTER") }, - { std::string("Kernels"), ghoul::Dictionary() } - }; - ghoul::Dictionary solarDictionary = - { - { std::string("Type"), std::string("Spice") }, - { std::string("Body"), std::string("SUN") }, - { std::string("Reference"), std::string("ECLIPJ2000") }, - { std::string("Observer"), std::string("JUPITER BARYCENTER") }, - { std::string("Kernels"), ghoul::Dictionary() } - }; - - solarSystemBarycenterNode->setEphemeris(new SpiceEphemeris(solarDictionary)); - plutoBarycenterNode->setEphemeris(new SpiceEphemeris(plutoDictionary)); - jupiterBarycenterNode->setEphemeris(new StaticEphemeris); + jupiterBarycenterNode->setParent(scene()->sceneGraphNode("SolarSystem")); + jupiterBarycenterNode->setEphemeris(new StaticEphemeris); + + solarSystemBarycenterNode->setParent(jupiterBarycenterNode); + newHorizonsNode->setParent(jupiterBarycenterNode); + + ghoul::Dictionary solarDictionary = + { + { std::string("Type"), std::string("Spice") }, + { std::string("Body"), std::string("SUN") }, + { std::string("Reference"), std::string("GALACTIC") }, + { std::string("Observer"), std::string("JUPITER BARYCENTER") }, + { std::string("Kernels"), ghoul::Dictionary() } + }; + + ghoul::Dictionary plutoDictionary = + { + { std::string("Type"), std::string("Spice") }, + { std::string("Body"), std::string("PlUTO BARYCENTER") }, + { std::string("Reference"), std::string("ECLIPJ2000") }, + { std::string("Observer"), std::string("JUPITER BARYCENTER") }, + { std::string("Kernels"), ghoul::Dictionary() } + }; + + ghoul::Dictionary newHorizonsDictionary = + { + { std::string("Type"), std::string("Spice") }, + { std::string("Body"), std::string("NEW HORIZONS") }, + { std::string("Reference"), std::string("GALACTIC") }, + { std::string("Observer"), std::string("JUPITER BARYCENTER") }, + { std::string("Kernels"), ghoul::Dictionary() } + }; + solarSystemBarycenterNode->setEphemeris(new SpiceEphemeris(solarDictionary)); + plutoBarycenterNode->setEphemeris(new SpiceEphemeris(plutoDictionary)); + newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary)); - ghoul::Dictionary newHorizonsDictionary = - { - { std::string("Type"), std::string("Spice") }, - { std::string("Body"), std::string("NEW HORIZONS") }, - { std::string("Reference"), std::string("GALACTIC") }, - { std::string("Observer"), std::string("JUPITER BARYCENTER") }, - { std::string("Kernels"), ghoul::Dictionary() } - }; - newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary)); //ghoul::Dictionary dawnDictionary = //{ From fd99115b6b56008a8c9c354ac3a81ba9b114ad92 Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Tue, 21 Apr 2015 20:53:31 -0400 Subject: [PATCH 19/45] Proof of concept for changing target on with only body name present. Also removed some calculations in fov replaced by a imageplane instance --- src/rendering/renderablefov.cpp | 4 +- src/rendering/renderableplaneprojection.cpp | 50 ++++++++++++++------- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/rendering/renderablefov.cpp b/src/rendering/renderablefov.cpp index 243c723086..c9ef9ebacf 100644 --- a/src/rendering/renderablefov.cpp +++ b/src/rendering/renderablefov.cpp @@ -526,7 +526,9 @@ void RenderableFov::render(const RenderData& data){ } } _interceptTag[4] = _interceptTag[0]; // 0 & 5 same point - fovProjection(_interceptTag, bounds); + //because other instruments arent implemented as projectable instruments yet + if (_instrumentID != "NH_LORRI") + fovProjection(_interceptTag, bounds); updateData(); } _oldTime = _time; diff --git a/src/rendering/renderableplaneprojection.cpp b/src/rendering/renderableplaneprojection.cpp index 43afe66ed1..a5f06615d2 100644 --- a/src/rendering/renderableplaneprojection.cpp +++ b/src/rendering/renderableplaneprojection.cpp @@ -71,14 +71,6 @@ RenderablePlaneProjection::RenderablePlaneProjection(const ghoul::Dictionary& di _textureFile = new ghoul::filesystem::File(_texturePath); } - //_target.body = "JUPITER"; - //_target.frame = "IAU_JUPITER"; - //_target.node = "JupiterProjection"; - - _target.body = "IO"; - _target.frame = "IAU_IO"; - _target.node = "Io"; - loadTexture(); } @@ -107,6 +99,7 @@ bool RenderablePlaneProjection::initialize() { return false; _shader->setProgramObjectCallback([&](ghoul::opengl::ProgramObject*){ _programIsDirty = true; }); + setTarget("JUPITER"); loadTexture(); return isReady(); } @@ -198,6 +191,13 @@ void RenderablePlaneProjection::updatePlane(double time, std::string newPath) { std::vector bounds; glm::dvec3 boresight; + int iTime = static_cast(time); + if (iTime % 2 && !_moving) + setTarget("JUPITER"); + else if (!_moving) + setTarget("IO"); + + bool found = openspace::SpiceManager::ref().getFieldOfView(_instrument, shape, frame, boresight, bounds); if (!found) { LERROR("Could not locate instrument"); @@ -226,12 +226,9 @@ void RenderablePlaneProjection::updatePlane(double time, std::string newPath) { if (!_moving) { SceneGraphNode* thisNode = OsEng.renderEngine()->scene()->sceneGraphNode(_name); - bool orphan = thisNode->parent()->abandonChild(thisNode); - if (orphan) { - SceneGraphNode* newParent = OsEng.renderEngine()->scene()->sceneGraphNode(_target.node); - if (newParent != nullptr) - newParent->addNode(thisNode); - } + SceneGraphNode* newParent = OsEng.renderEngine()->scene()->sceneGraphNode(_target.node); + if (thisNode != nullptr && newParent != nullptr) + thisNode->setParent(newParent); } const GLfloat vertex_data[] = { // square of two triangles drawn within fov in target coordinates @@ -259,9 +256,28 @@ void RenderablePlaneProjection::updatePlane(double time, std::string newPath) { } void RenderablePlaneProjection::setTarget(std::string body) { - _target.body = body; - _target.frame = "IAU_" + body; - _target.node = "Io"; // TODO: search for a node containing the body string @AA + + std::vector nodes = OsEng.renderEngine()->scene()->allSceneGraphNodes(); + Renderable* possibleTarget; + bool hasBody, found = false; + std::string targetBody; + + for (auto node : nodes) + { + possibleTarget = node->renderable(); + if (possibleTarget != nullptr) { + hasBody = possibleTarget->hasBody(); + if (hasBody && possibleTarget->getBody(targetBody) && (targetBody == body)) { + _target.node = node->name(); // get name from propertyOwner + found = true; + break; + } + } + } + if (found) { + _target.body = body; + _target.frame = "IAU_" + body; + } } } // namespace openspace From 19417d87c891146bcc1445f80527516a42ef64c5 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 22 Apr 2015 18:22:19 +0200 Subject: [PATCH 20/45] Moved networking functions into their own engine class --- include/openspace/engine/openspaceengine.h | 2 + include/openspace/network/networkengine.h | 43 ++++++++++ include/openspace/util/time.h | 2 +- src/CMakeLists.txt | 6 ++ src/engine/openspaceengine.cpp | 17 ++-- src/network/networkengine.cpp | 97 ++++++++++++++++++++++ 6 files changed, 154 insertions(+), 13 deletions(-) create mode 100644 include/openspace/network/networkengine.h create mode 100644 src/network/networkengine.cpp diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index e6ce8570a7..2beeafa486 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -40,6 +40,7 @@ namespace openspace { class ConfigurationManager; class LuaConsole; +class NetworkEngine; class GUI; class RenderEngine; class SyncBuffer; @@ -111,6 +112,7 @@ private: interaction::InteractionHandler* _interactionHandler; RenderEngine* _renderEngine; scripting::ScriptEngine* _scriptEngine; + NetworkEngine* _networkEngine; ghoul::cmdparser::CommandlineParser* _commandlineParser; LuaConsole* _console; gui::GUI* _gui; diff --git a/include/openspace/network/networkengine.h b/include/openspace/network/networkengine.h new file mode 100644 index 0000000000..1d0c03481a --- /dev/null +++ b/include/openspace/network/networkengine.h @@ -0,0 +1,43 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 __NETWORKENGINE_H__ +#define __NETWORKENGINE_H__ + +#include + +namespace openspace { + +class NetworkEngine { +public: + NetworkEngine() = default; + + bool handleMessage(const std::string& message); + + void sendStatusMessage(); +}; + +} // namespace openspace + +#endif // __NETWORKENGINE_H__ \ No newline at end of file diff --git a/include/openspace/util/time.h b/include/openspace/util/time.h index b02763709d..1814dee2db 100644 --- a/include/openspace/util/time.h +++ b/include/openspace/util/time.h @@ -51,7 +51,7 @@ namespace openspace { * equal to the frame time. */ - class SyncBuffer; +class SyncBuffer; class Time { public: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6976e276c2..5bfeb38af5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,6 +48,12 @@ file(GLOB ENGINE_HEADER ${HEADER_ROOT_DIR}/openspace/engine/*.h) set(OPENSPACE_HEADER ${OPENSPACE_HEADER} ${ENGINE_HEADER}) source_group(Engine FILES ${ENGINE_SOURCE} ${ENGINE_HEADER}) +file(GLOB NETWORK_SOURCE ${SOURCE_ROOT_DIR}/network/*.cpp) +set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${NETWORK_SOURCE}) +file(GLOB NETWORK_HEADER ${HEADER_ROOT_DIR}/openspace/network/*.h) +set(OPENSPACE_HEADER ${OPENSPACE_HEADER} ${NETWORK_HEADER}) +source_group(Network FILES ${NETWORK_SOURCE} ${NETWORK_HEADER}) + file(GLOB GUI_SOURCE ${SOURCE_ROOT_DIR}/gui/*.cpp) set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${GUI_SOURCE}) file(GLOB GUI_HEADER ${HEADER_ROOT_DIR}/openspace/gui/*.h) diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 132b43e705..4e169dc328 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -94,6 +95,7 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName) , _interactionHandler(new interaction::InteractionHandler) , _renderEngine(new RenderEngine) , _scriptEngine(new scripting::ScriptEngine) + , _networkEngine(new NetworkEngine) , _commandlineParser(new ghoul::cmdparser::CommandlineParser(programName, true)) , _console(new LuaConsole) , _gui(new gui::GUI) @@ -115,6 +117,7 @@ OpenSpaceEngine::~OpenSpaceEngine() { delete _interactionHandler; delete _renderEngine; delete _scriptEngine; + delete _networkEngine; delete _commandlineParser; delete _console; delete _gui; @@ -700,6 +703,7 @@ void OpenSpaceEngine::encode() { _syncBuffer->write(); } + _networkEngine->sendStatusMessage(); } void OpenSpaceEngine::decode() { @@ -709,7 +713,6 @@ void OpenSpaceEngine::decode() { Time::ref().deserialize(_syncBuffer); _scriptEngine->deserialize(_syncBuffer); _renderEngine->deserialize(_syncBuffer); - } } @@ -719,17 +722,7 @@ void OpenSpaceEngine::externalControlCallback(const char* receivedChars, if (size == 0) return; - // The first byte determines the type of message - const char type = receivedChars[0]; - switch (type) { - case '0': // LuaScript - { - std::string script = std::string(receivedChars + 1); - LINFO("Received Lua Script: '" << script << "'"); - //_scriptEngine->runScript(script); - _scriptEngine->queueScript(script); - } - } + _networkEngine->handleMessage(std::string(receivedChars)); } void OpenSpaceEngine::enableBarrier() { diff --git a/src/network/networkengine.cpp b/src/network/networkengine.cpp new file mode 100644 index 0000000000..1b0c0a2599 --- /dev/null +++ b/src/network/networkengine.cpp @@ -0,0 +1,97 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 "sgct.h" + +namespace { + const std::string _loggerCat = "NetworkEngine"; + + const uint8_t MessageTypeStatus = 0; +} + +namespace openspace { + +bool NetworkEngine::handleMessage(const std::string& message) { + // The first byte determines the type of message + const char type = message[0]; + switch (type) { + case '0': // LuaScript + { + std::string script = message.substr(1); + //LINFO("Received Lua Script: '" << script << "'"); + OsEng.scriptEngine()->queueScript(script); + return true; + } + default: + LERROR("Unknown type '" << type << "'"); + return false; + } + +} + +void NetworkEngine::sendStatusMessage() { + if (!sgct::Engine::instance()->isExternalControlConnected()) + return; + // Protocols: + // 1 byte: type of message + // 8 bytes: time as a ET double + // 24 bytes: time as a UTC string + // 8 bytes: delta time as double + // Total: 41 + + uint16_t messageSize = 0; + + double time = Time::ref().currentTime(); + std::string timeString = Time::ref().currentTimeUTC(); + double delta = Time::ref().deltaTime(); + + messageSize += sizeof(uint8_t); + messageSize += sizeof(time); + messageSize += timeString.length(); + messageSize += sizeof(delta); + + //LINFO(delta); + + ghoul_assert(messageSize == 41, "Message size is not correct"); + + unsigned int currentLocation = 0; + std::vector buffer(messageSize); + + std::memcpy(buffer.data(), &MessageTypeStatus, sizeof(MessageTypeStatus)); + currentLocation += sizeof(MessageTypeStatus); + std::memmove(buffer.data() + currentLocation, &time, sizeof(time)); + currentLocation += sizeof(time); + std::memmove(buffer.data() + currentLocation, timeString.c_str(), timeString.length()); + currentLocation += timeString.length(); + std::memmove(buffer.data() + currentLocation, &delta, sizeof(delta)); + + sgct::Engine::instance()->sendMessageToExternalControl(buffer.data(), messageSize); +} + +} // namespace openspace From 07eaf6d7be570da22ba2c50cef850258e4e32244 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 22 Apr 2015 18:22:40 +0200 Subject: [PATCH 21/45] More work on Timelineview GUI application --- gui/timelineview/CMakeLists.txt | 2 +- gui/timelineview/configurationwidget.cpp | 17 +++- gui/timelineview/configurationwidget.h | 7 ++ gui/timelineview/mainwindow.cpp | 107 ++++++++++++----------- gui/timelineview/mainwindow.h | 10 ++- gui/timelineview/timecontrolwidget.cpp | 69 +++++++++++++++ gui/timelineview/timecontrolwidget.h | 14 +++ 7 files changed, 169 insertions(+), 57 deletions(-) diff --git a/gui/timelineview/CMakeLists.txt b/gui/timelineview/CMakeLists.txt index 6fbd84d5bb..86dd6b9a9c 100644 --- a/gui/timelineview/CMakeLists.txt +++ b/gui/timelineview/CMakeLists.txt @@ -6,5 +6,5 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) find_package(Qt5Widgets) find_package(Qt5Network) -add_executable(TimelineView WIN32 main.cpp mainwindow.cpp configurationwidget.cpp informationwidget.cpp timecontrolwidget.cpp timelinewidget.cpp) +add_executable(TimelineView main.cpp mainwindow.cpp configurationwidget.cpp informationwidget.cpp timecontrolwidget.cpp timelinewidget.cpp) target_link_libraries(TimelineView Qt5::Widgets Qt5::Network) \ No newline at end of file diff --git a/gui/timelineview/configurationwidget.cpp b/gui/timelineview/configurationwidget.cpp index a678a2a14f..900a02d5c1 100644 --- a/gui/timelineview/configurationwidget.cpp +++ b/gui/timelineview/configurationwidget.cpp @@ -28,16 +28,25 @@ ConfigurationWidget::ConfigurationWidget(QWidget* parent) : QWidget(parent) - , _ipAddress(new QLineEdit) + , _ipAddress(new QLineEdit("localhost")) + , _port(new QLineEdit("20500")) , _connect(new QPushButton("Connect")) , _playbook(new QLineEdit) , _load(new QPushButton("Load")) { QGridLayout* layout = new QGridLayout; layout->addWidget(_ipAddress, 0, 0); - layout->addWidget(_connect, 0, 1); - layout->addWidget(_playbook, 1, 0); - layout->addWidget(_load, 1, 1); + layout->addWidget(_port, 0, 1); + layout->addWidget(_connect, 0, 2); + layout->addWidget(_playbook, 1, 0, 1, 2); + layout->addWidget(_load, 1, 2); setLayout(layout); + + QObject::connect(_connect, SIGNAL(clicked()), this, SLOT(onConnectButton())); + +} + +void ConfigurationWidget::onConnectButton() { + emit connect(_ipAddress->text(), _port->text()); } diff --git a/gui/timelineview/configurationwidget.h b/gui/timelineview/configurationwidget.h index 82c32a89c8..dfc305005b 100644 --- a/gui/timelineview/configurationwidget.h +++ b/gui/timelineview/configurationwidget.h @@ -34,8 +34,15 @@ Q_OBJECT public: ConfigurationWidget(QWidget* parent); +signals: + void connect(QString host, QString port); + +private slots: + void onConnectButton(); + private: QLineEdit* _ipAddress; + QLineEdit* _port; QPushButton* _connect; QLineEdit* _playbook; diff --git a/gui/timelineview/mainwindow.cpp b/gui/timelineview/mainwindow.cpp index 4bb9ed8a53..a6b2bb9b24 100644 --- a/gui/timelineview/mainwindow.cpp +++ b/gui/timelineview/mainwindow.cpp @@ -33,6 +33,9 @@ #include #include +#include +#include + MainWindow::MainWindow() : QWidget(nullptr) , _configurationWidget(nullptr) @@ -55,70 +58,74 @@ MainWindow::MainWindow() layout->addWidget(_timelineWidget, 0, 1, 3, 1); + QObject::connect( + _configurationWidget, SIGNAL(connect(QString, QString)), + this, SLOT(onConnect(QString, QString)) + ); + QObject::connect( + _timeControlWidget, SIGNAL(scriptActivity(QString)), + this, SLOT(sendScript(QString)) + ); - //_ipAddress->setMinimumWidth(200); - //_ipAddress->setText("127.0.0.1"); - //layout->addWidget(_ipAddress, 0, 0); - - //QPushButton* connectButton = new QPushButton("Connect"); - //connect(connectButton, SIGNAL(clicked()), this, SLOT(onConnectButton())); - //connectButton->show(); - //layout->addWidget(connectButton, 0, 1); - - //_command->setMinimumWidth(200); - //layout->addWidget(_command, 1, 0); - - //QPushButton* sendButton = new QPushButton("Send"); - //sendButton->setDefault(true); - //connect(sendButton, SIGNAL(clicked()), this, SLOT(sendCommandButton())); - //layout->addWidget(sendButton, 1, 1); - - //layout->addWidget(_logWindow, 2, 0, 1, 2); - setLayout(layout); } MainWindow::~MainWindow() { - //delete _command; - //delete _socket; + delete _socket; } +void MainWindow::onConnect(QString host, QString port) { + delete _socket; + + _socket = new QTcpSocket(this); + connect(_socket, SIGNAL(readyRead()), SLOT(readTcpData())); + _socket->connectToHost(host, port.toUInt()); +} + + void MainWindow::readTcpData() { - // QByteArray data = _socket->readAll(); + static const uint8_t MessageTypeStatus = 0; - //if (_logWindow->toPlainText().isEmpty()) - // _logWindow->setText(data.data()); - //else - // _logWindow->setText(_logWindow->toPlainText() + "\n" + data.data()); + QByteArray data = _socket->readAll(); + + if (QString(data) == "Connected to SGCT!\r\n") + return; + if (QString(data) == "OK\r\n") + return; + + uint8_t messageType = data[0]; + + if (messageType == MessageTypeStatus) + handleStatusMessage(data.mid(1)); + handleStatusMessage(data.right(data.length() - 1)); } -void MainWindow::onConnectButton() { - //delete _socket; - // - //_socket = new QTcpSocket(this); - // connect( _socket, SIGNAL(readyRead()), SLOT(readTcpData()) ); - // _socket->connectToHost(_ipAddress->text(), 20500); +void MainWindow::handleStatusMessage(QByteArray data) { + const char* buffer = data.data(); + union { + double value; + std::array buffer; + } et; + std::memmove(et.buffer.data(), buffer, sizeof(double)); + + std::vector timeString(24); + std::memmove(timeString.data(), buffer + sizeof(double), 24); + + union { + double value; + std::array buffer; + } delta; + std::memmove(delta.buffer.data(), buffer + sizeof(double) + 24, sizeof(double)); + + _timeControlWidget->update( + QString::fromStdString(std::string(timeString.begin(), timeString.end())), + QString::number(delta.value) + ); } -void MainWindow::sendCommandButton() { - //if (!_socket) { - // if (_logWindow->toPlainText().isEmpty()) - // _logWindow->setText("No connection found"); - // else - // _logWindow->setText(_logWindow->toPlainText() + "\n" + "No connection found"); - // return; - //} - - //QString command = _command->text(); - - //if (_logWindow->toPlainText().isEmpty()) - // _logWindow->setText(command); - //else - // _logWindow->setText(_logWindow->toPlainText() + "\n" + command); - - // - //_socket->write(("0" + command + "\r\n").toLatin1()); +void MainWindow::sendScript(QString script) { + _socket->write(("0" + script + "\r\n").toLatin1()); } diff --git a/gui/timelineview/mainwindow.h b/gui/timelineview/mainwindow.h index e5c1984f72..9fdd10b1d3 100644 --- a/gui/timelineview/mainwindow.h +++ b/gui/timelineview/mainwindow.h @@ -39,10 +39,16 @@ public: MainWindow(); ~MainWindow(); +public slots: + void sendScript(QString script); + private slots: - void onConnectButton(); - void sendCommandButton(); + void onConnect(QString host, QString port); + + //void onConnectButton(); + //void sendCommandButton(); void readTcpData(); + void handleStatusMessage(QByteArray data); private: ConfigurationWidget* _configurationWidget; diff --git a/gui/timelineview/timecontrolwidget.cpp b/gui/timelineview/timecontrolwidget.cpp index a838b1dcfd..c2693c7aae 100644 --- a/gui/timelineview/timecontrolwidget.cpp +++ b/gui/timelineview/timecontrolwidget.cpp @@ -42,6 +42,44 @@ TimeControlWidget::TimeControlWidget(QWidget* parent) , _play(new QPushButton("|>")) , _forward(new QPushButton(">>")) { + _setDelta->setMinimum(-100); + _setDelta->setMaximum(100); + _setDelta->setValue(0); + QObject::connect( + _setDelta, + SIGNAL(valueChanged(int)), + this, + SLOT(onValueChange()) + ); + + QObject::connect( + _rewind, + SIGNAL(clicked()), + this, + SLOT(onRewindButton()) + ); + + QObject::connect( + _pause, + SIGNAL(clicked()), + this, + SLOT(onPauseButton()) + ); + + QObject::connect( + _play, + SIGNAL(clicked()), + this, + SLOT(onPlayButton()) + ); + + QObject::connect( + _forward, + SIGNAL(clicked()), + this, + SLOT(onForwardButton()) + ); + QGridLayout* layout = new QGridLayout; layout->addWidget(_currentTime, 0, 0); @@ -60,3 +98,34 @@ TimeControlWidget::TimeControlWidget(QWidget* parent) setLayout(layout); } + +void TimeControlWidget::update(QString currentTime, QString currentDelta) { + _currentTime->setText(currentTime); + _currentDelta->setText(currentDelta); +} + +void TimeControlWidget::onValueChange() { + QString script = "openspace.time.setDeltaTime(" + QString::number(_setDelta->value()) + ");"; + emit scriptActivity(script); +} + +void TimeControlWidget::onRewindButton() { + QString script = "openspace.time.setDeltaTime(-openspace.time.deltaTime());"; + emit scriptActivity(script); +} + +void TimeControlWidget::onPauseButton() { + QString script = "openspace.time.setPause(true);"; + emit scriptActivity(script); +} + +void TimeControlWidget::onPlayButton() { + QString script = "openspace.time.setPause(false);"; + emit scriptActivity(script); +} + +void TimeControlWidget::onForwardButton() { + QString script = "openspace.time.setDeltaTime(-openspace.time.deltaTime());"; + emit scriptActivity(script); + +} diff --git a/gui/timelineview/timecontrolwidget.h b/gui/timelineview/timecontrolwidget.h index 66edc5586b..8265184cf3 100644 --- a/gui/timelineview/timecontrolwidget.h +++ b/gui/timelineview/timecontrolwidget.h @@ -37,6 +37,18 @@ Q_OBJECT public: TimeControlWidget(QWidget* parent); + void update(QString currentTime, QString currentDelta); + +signals: + void scriptActivity(QString script); + +private slots: + void onValueChange(); + void onRewindButton(); + void onPauseButton(); + void onPlayButton(); + void onForwardButton(); + private: QLabel* _currentTime; QComboBox* _setTime; @@ -46,6 +58,8 @@ private: QPushButton* _pause; QPushButton* _play; QPushButton* _forward; + + bool _stateNoNotification = false; }; #endif // __TIMECONTROLWIDGET_H__ From bc591b2bdbfba6ef38261a214d0c63ce18b2411c Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Wed, 22 Apr 2015 15:41:55 -0400 Subject: [PATCH 22/45] Made night texture only be loaded if one exists, added new shader for planets with a night texture. Also added plane & image plane shader programs to the general shader declaration in scene.cpp --- .../rendering/planets/renderableplanet.h | 1 + shaders/nighttexture_fs.glsl | 87 +++++++++++++++++++ shaders/nighttexture_vs.glsl | 57 ++++++++++++ shaders/pscstandard_fs.glsl | 8 +- src/rendering/planets/renderableplanet.cpp | 53 +++++------ src/rendering/renderableplane.cpp | 14 ++- src/rendering/renderableplaneprojection.cpp | 10 +-- src/scene/scene.cpp | 31 ++++++- 8 files changed, 212 insertions(+), 49 deletions(-) create mode 100644 shaders/nighttexture_fs.glsl create mode 100644 shaders/nighttexture_vs.glsl diff --git a/include/openspace/rendering/planets/renderableplanet.h b/include/openspace/rendering/planets/renderableplanet.h index 2d3684552a..9ce978fe72 100644 --- a/include/openspace/rendering/planets/renderableplanet.h +++ b/include/openspace/rendering/planets/renderableplanet.h @@ -74,6 +74,7 @@ private: std::string _nightTexturePath; std::string _frame; std::string _target; + bool _hasNightTexture; double _time; }; diff --git a/shaders/nighttexture_fs.glsl b/shaders/nighttexture_fs.glsl new file mode 100644 index 0000000000..5c6278838d --- /dev/null +++ b/shaders/nighttexture_fs.glsl @@ -0,0 +1,87 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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__ + +uniform vec4 campos; +uniform vec4 objpos; + +uniform vec3 sun_pos; + +uniform bool _performShading = true; +uniform float transparency; +uniform int shadows; + +uniform float time; +uniform sampler2D texture1; +uniform sampler2D nightTex; + +in vec2 vs_st; +in vec2 vs_nightTex; +in vec4 vs_normal; +in vec4 vs_position; + +#include "ABuffer/abufferStruct.hglsl" +#include "ABuffer/abufferAddToBuffer.hglsl" +#include "PowerScaling/powerScaling_fs.hglsl" + +void main() +{ + vec4 position = vs_position; + float depth = pscDepth(position); + vec4 diffuse = texture(texture1, vs_st); + vec4 diffuse2 = texture(nightTex, vs_st); + + if (_performShading) { + // directional lighting + vec3 origin = vec3(0.0); + vec4 spec = vec4(0.0); + + vec3 n = normalize(vs_normal.xyz); + //vec3 e = normalize(camdir); + vec3 l_pos = vec3(sun_pos); // sun. + vec3 l_dir = normalize(l_pos-objpos.xyz); + float intensity = min(max(5*dot(n,l_dir), 0.0), 1); + float darkSide = min(max(5*dot(n,-l_dir), 0.0), 1); + + float shine = 0.0001; + + vec4 specular = vec4(0.5); + vec4 ambient = vec4(0.0,0.0,0.0,transparency); + + vec4 daytex = max(intensity * diffuse, ambient); + vec4 mixtex = mix(diffuse, diffuse2, (1+dot(n,-l_dir))/2); + + diffuse = (daytex*2 + mixtex)/3; + + diffuse[3] = transparency; + ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); + addToBuffer(frag); + } + else { + diffuse[3] = transparency; + ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); + addToBuffer(frag); + } +} \ No newline at end of file diff --git a/shaders/nighttexture_vs.glsl b/shaders/nighttexture_vs.glsl new file mode 100644 index 0000000000..cb945fa133 --- /dev/null +++ b/shaders/nighttexture_vs.glsl @@ -0,0 +1,57 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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__ + +uniform mat4 ViewProjection; +uniform mat4 ModelTransform; + +layout(location = 0) in vec4 in_position; +layout(location = 1) in vec2 in_st; +layout(location = 2) in vec3 in_normal; +//layout(location = 3) in vec2 in_nightTex; + + +out vec2 vs_st; +out vec4 vs_normal; +out vec4 vs_position; +out float s; + +#include "PowerScaling/powerScaling_vs.hglsl" + +void main() +{ + // set variables + vs_st = in_st; + vs_position = in_position; + vec4 tmp = in_position; + + // this is wrong for the normal. The normal transform is the transposed inverse of the model transform + vs_normal = normalize(ModelTransform * vec4(in_normal,0)); + + vec4 position = pscTransform(tmp, ModelTransform); + vs_position = tmp; + position = ViewProjection * position; + gl_Position = z_normalization(position); +} \ No newline at end of file diff --git a/shaders/pscstandard_fs.glsl b/shaders/pscstandard_fs.glsl index b4ae6a4131..98fd4871fa 100644 --- a/shaders/pscstandard_fs.glsl +++ b/shaders/pscstandard_fs.glsl @@ -36,7 +36,6 @@ uniform int shadows; uniform float time; uniform sampler2D texture1; -uniform sampler2D nightTex; in vec2 vs_st; in vec2 vs_nightTex; @@ -53,7 +52,6 @@ void main() vec4 position = vs_position; float depth = pscDepth(position); vec4 diffuse = texture(texture1, vs_st); - vec4 diffuse2 = texture(nightTex, vs_st); if (_performShading) { // directional lighting @@ -65,7 +63,6 @@ void main() vec3 l_pos = vec3(sun_pos); // sun. vec3 l_dir = normalize(l_pos-objpos.xyz); float intensity = min(max(5*dot(n,l_dir), 0.0), 1); - float darkSide = min(max(5*dot(n,-l_dir), 0.0), 1); float shine = 0.0001; @@ -80,10 +77,7 @@ void main() spec = specular * pow(intSpec, shine); } */ - vec4 daytex = max(intensity * diffuse, ambient); - vec4 mixtex = mix(diffuse, diffuse2, (1+dot(n,-l_dir))/2); - - diffuse = (daytex*2 + mixtex)/3; + diffuse = max(intensity * diffuse, ambient); diffuse[3] = transparency; ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); diff --git a/src/rendering/planets/renderableplanet.cpp b/src/rendering/planets/renderableplanet.cpp index a9e8bc2fb5..76fcf69dc9 100644 --- a/src/rendering/planets/renderableplanet.cpp +++ b/src/rendering/planets/renderableplanet.cpp @@ -63,6 +63,7 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) , _geometry(nullptr) , _performShading("performShading", "Perform Shading", true) , _rotation("rotation", "Rotation", 0, 0, 360) + , _hasNightTexture(false) , _alpha(1.f) { std::string name; @@ -97,16 +98,13 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) _colorTexturePath = path + "/" + texturePath; std::string nightTexturePath = ""; - success = dictionary.getValue("Textures.Night", nightTexturePath); - if (success){ + dictionary.getValue("Textures.Night", nightTexturePath); + + if (nightTexturePath != ""){ + _hasNightTexture = true; _nightTexturePath = absPath(nightTexturePath); _nightTexturePath = path + "/" + nightTexturePath; } - else - { - _nightTexturePath = absPath(texturePath); - _nightTexturePath = path + "/" + texturePath; - } addPropertySubOwner(_geometry); @@ -128,8 +126,10 @@ RenderablePlanet::~RenderablePlanet() { } bool RenderablePlanet::initialize() { - if (_programObject == nullptr) - OsEng.ref().configurationManager()->getValue("pscShader", _programObject); + if (_programObject == nullptr && _hasNightTexture) + OsEng.ref().configurationManager()->getValue("nightTextureProgram", _programObject); + else if (_programObject == nullptr) + OsEng.ref().configurationManager()->getValue("pscShader", _programObject); loadTexture(); _geometry->initialize(this); @@ -204,11 +204,12 @@ void RenderablePlanet::render(const RenderData& data) _programObject->setUniform("texture1", dayUnit); // Bind possible night texture - ghoul::opengl::TextureUnit nightUnit; - nightUnit.activate(); - _nightTexture->bind(); - _programObject->setUniform("nightTex", nightUnit); - + if (_hasNightTexture) { + ghoul::opengl::TextureUnit nightUnit; + nightUnit.activate(); + _nightTexture->bind(); + _programObject->setUniform("nightTex", nightUnit); + } // render _geometry->render(); @@ -225,17 +226,7 @@ void RenderablePlanet::update(const UpdateData& data){ void RenderablePlanet::loadTexture() { delete _texture; _texture = nullptr; - delete _nightTexture; - _nightTexture = nullptr; - if (_nightTexturePath != "") { - _nightTexture = ghoul::io::TextureReader::ref().loadTexture(absPath(_nightTexturePath)); - if (_nightTexture) { - LDEBUG("Loaded texture from '" << _nightTexturePath << "'"); - _nightTexture->uploadTexture(); - _nightTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); - } - } - if (_colorTexturePath.value() != "") { + if (_colorTexturePath.value() != "") { _texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath)); if (_texture) { LDEBUG("Loaded texture from '" << _colorTexturePath << "'"); @@ -245,6 +236,18 @@ void RenderablePlanet::loadTexture() { _texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); } } + if (_hasNightTexture) { + delete _nightTexture; + _nightTexture = nullptr; + if (_nightTexturePath != "") { + _nightTexture = ghoul::io::TextureReader::ref().loadTexture(absPath(_nightTexturePath)); + if (_nightTexture) { + LDEBUG("Loaded texture from '" << _nightTexturePath << "'"); + _nightTexture->uploadTexture(); + _nightTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); + } + } + } } } // namespace openspace diff --git a/src/rendering/renderableplane.cpp b/src/rendering/renderableplane.cpp index d57d83f915..f8dba7e68a 100644 --- a/src/rendering/renderableplane.cpp +++ b/src/rendering/renderableplane.cpp @@ -22,6 +22,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#include #include #include #include @@ -125,14 +126,10 @@ bool RenderablePlane::initialize() { glGenBuffers(1, &_vertexPositionBuffer); // generate buffer createPlane(); - // Plane program - _shader = ghoul::opengl::ProgramObject::Build("Plane", - "${SHADERS}/modules/plane/plane_vs.glsl", - "${SHADERS}/modules/plane/plane_fs.glsl"); - if (!_shader) - return false; - _shader->setProgramObjectCallback([&](ghoul::opengl::ProgramObject*){ _programIsDirty = true; }); - + if (_shader == nullptr) + OsEng.ref().configurationManager()->getValue("planeProgram", _shader); + + _shader->setProgramObjectCallback([&](ghoul::opengl::ProgramObject*){ _programIsDirty = true; }); loadTexture(); return isReady(); @@ -144,7 +141,6 @@ bool RenderablePlane::deinitialize() { glDeleteBuffers(1, &_vertexPositionBuffer); _vertexPositionBuffer = 0; delete _texture; - delete _shader; return true; } diff --git a/src/rendering/renderableplaneprojection.cpp b/src/rendering/renderableplaneprojection.cpp index a5f06615d2..964c985448 100644 --- a/src/rendering/renderableplaneprojection.cpp +++ b/src/rendering/renderableplaneprojection.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -92,12 +93,8 @@ bool RenderablePlaneProjection::initialize() { glGenBuffers(1, &_vertexPositionBuffer); // generate buffer // Plane program - _shader = ghoul::opengl::ProgramObject::Build("imagePlane", - "${SHADERS}/modules/imageplane/imageplane_vs.glsl", - "${SHADERS}/modules/imageplane/imageplane_fs.glsl"); - if (!_shader) - return false; - _shader->setProgramObjectCallback([&](ghoul::opengl::ProgramObject*){ _programIsDirty = true; }); + if (_shader == nullptr) + OsEng.ref().configurationManager()->getValue("planeProgram", _shader); setTarget("JUPITER"); loadTexture(); @@ -110,7 +107,6 @@ bool RenderablePlaneProjection::deinitialize() { glDeleteBuffers(1, &_vertexPositionBuffer); _vertexPositionBuffer = 0; delete _texture; - delete _shader; return true; } diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index ef4c1c9913..68c25ff71d 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -183,6 +183,7 @@ bool Scene::initialize() { tmpProgram->setProgramObjectCallback(cb); _programs.push_back(tmpProgram); OsEng.ref().configurationManager()->setValue("fboPassProgram", tmpProgram); + // projection program tmpProgram = ProgramObject::Build("projectiveProgram", "${SHADERS}/projectiveTexture_vs.glsl", @@ -202,7 +203,17 @@ bool Scene::initialize() { _programs.push_back(tmpProgram); OsEng.ref().configurationManager()->setValue("pscShader", tmpProgram); - // pscstandard + // Night texture program + tmpProgram = ProgramObject::Build("nightTextureProgram", + "${SHADERS}/nighttexture_vs.glsl", + "${SHADERS}/nighttexture_fs.glsl"); + if (!tmpProgram) return false; + tmpProgram->setProgramObjectCallback(cb); + + _programs.push_back(tmpProgram); + OsEng.ref().configurationManager()->setValue("nightTextureProgram", tmpProgram); + + // Fov Program tmpProgram = ProgramObject::Build("FovProgram", "${SHADERS}/fov_vs.glsl", "${SHADERS}/fov_fs.glsl"); @@ -211,6 +222,24 @@ bool Scene::initialize() { _programs.push_back(tmpProgram); OsEng.ref().configurationManager()->setValue("FovProgram", tmpProgram); + // Plane Program + tmpProgram = ProgramObject::Build("planeProgram", + "${SHADERS}/modules/plane/plane_vs.glsl", + "${SHADERS}/modules/plane/plane_fs.glsl"); + if (!tmpProgram) return false; + tmpProgram->setProgramObjectCallback(cb); + _programs.push_back(tmpProgram); + OsEng.ref().configurationManager()->setValue("planeProgram", tmpProgram); + + // Image Plane Program + tmpProgram = ProgramObject::Build("imagePlaneProgram", + "${SHADERS}/modules/imageplane/imageplane_vs.glsl", + "${SHADERS}/modules/imageplane/imageplane_fs.glsl"); + if (!tmpProgram) return false; + tmpProgram->setProgramObjectCallback(cb); + _programs.push_back(tmpProgram); + OsEng.ref().configurationManager()->setValue("imagePlaneProgram", tmpProgram); + // RaycastProgram tmpProgram = ProgramObject::Build("RaycastProgram", "${SHADERS}/exitpoints.vert", From 7913c74760546dab5caf1e7b0d59afad9dbe999e Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Wed, 22 Apr 2015 18:36:09 -0400 Subject: [PATCH 23/45] Changed shader for RenderablePlaneProjection --- src/rendering/renderableplaneprojection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rendering/renderableplaneprojection.cpp b/src/rendering/renderableplaneprojection.cpp index 964c985448..80848e56ea 100644 --- a/src/rendering/renderableplaneprojection.cpp +++ b/src/rendering/renderableplaneprojection.cpp @@ -94,7 +94,7 @@ bool RenderablePlaneProjection::initialize() { // Plane program if (_shader == nullptr) - OsEng.ref().configurationManager()->getValue("planeProgram", _shader); + OsEng.ref().configurationManager()->getValue("imagePlaneProgram", _shader); setTarget("JUPITER"); loadTexture(); From 9226dd2d6bc3c69fefdc82246d70f80f5cd9cdb3 Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Wed, 22 Apr 2015 21:43:54 -0400 Subject: [PATCH 24/45] Setting show errors to false by default in Spicemanager Removed debugging printouts --- include/openspace/util/spicemanager.h | 2 +- src/util/spicemanager.cpp | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index 314c0b00d1..852e4cf386 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -674,7 +674,7 @@ private: std::map > _ckCoverageTimes; std::map > _spkCoverageTimes; - const static bool _showErrors = true; + const static bool _showErrors = false; /// The last assigned kernel-id, used to determine the next free kernel id KernelIdentifier _lastAssignedKernel; diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index ed30de2b3f..2c1289e659 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -575,7 +575,6 @@ bool SpiceManager::getEstimatedPosition(const double time, const std::string tar targetPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(pos[0], pos[1], pos[2]); - std::cout << "estimating position for: " << target << ", w observer: " << observer << std::endl; checkForError("Error estimating positin for target: " + target + ", or observer: " + observer); return targetFound && observerFound; @@ -896,7 +895,6 @@ bool SpiceManager::getEstimatedTransformMatrix(const double time, const std::str } } } - std::cout << "estimating from frame: " << fromFrame << ", to frame: " << toFrame << std::endl; bool hasError = checkForError("Error estimating transform matrix from frame: " + fromFrame + ", to frame: " + toFrame); From 8becbbde41cd365abef884c30184935a90d78f7d Mon Sep 17 00:00:00 2001 From: Michal Marcinkowski Date: Wed, 22 Apr 2015 21:53:28 -0400 Subject: [PATCH 25/45] Imagesequencer update: - label/image data works - fixed issues with instrument firing - read handled in more uniform way - adding ALICE scanner - distance fading in renderabletrail (WIP) - essential fixes to renderableFOV - and additional changes to other classes reliant on imagesequenser. --- .../openspace/rendering/model/modelgeometry.h | 2 + .../rendering/model/renderablemodel.h | 4 +- .../rendering/model/wavefrontgeometry.h | 2 + .../planets/renderableplanetprojection.h | 3 +- include/openspace/rendering/renderablefov.h | 4 +- include/openspace/rendering/renderabletrail.h | 2 + include/openspace/util/imagesequencer2.h | 168 ++++++++++++---- include/openspace/util/instrumentdecoder.h | 2 + include/openspace/util/labelparser.h | 76 +++---- include/openspace/util/scannerdecoder.h | 3 + include/openspace/util/sequenceparser.h | 2 +- openspace-data | 2 +- scripts/default_startup.lua | 4 +- shaders/fboPass_fs.glsl | 7 +- shaders/modules/trails/ephemeris_fs.glsl | 3 +- src/engine/openspaceengine.cpp | 2 - src/rendering/model/renderablemodel.cpp | 75 ++++--- src/rendering/model/wavefrontgeometry.cpp | 7 +- .../planets/renderableplanetprojection.cpp | 52 ++--- src/rendering/renderablefov.cpp | 17 +- src/rendering/renderabletrail.cpp | 23 +++ src/rendering/renderengine.cpp | 122 +++++------- src/scenegraph/spiceephemeris.cpp | 13 +- src/util/hongkangparser.cpp | 71 +++++-- src/util/imagesequencer.cpp | 1 - src/util/imagesequencer2.cpp | 187 +++++++++++------- src/util/instrumentdecoder.cpp | 11 ++ src/util/labelparser.cpp | 155 ++++++++++++--- src/util/scannerdecoder.cpp | 4 + 29 files changed, 673 insertions(+), 351 deletions(-) diff --git a/include/openspace/rendering/model/modelgeometry.h b/include/openspace/rendering/model/modelgeometry.h index 75d13d8e20..d5ecd64b2d 100644 --- a/include/openspace/rendering/model/modelgeometry.h +++ b/include/openspace/rendering/model/modelgeometry.h @@ -42,6 +42,8 @@ public: virtual bool initialize(RenderableModel* parent); virtual void deinitialize(); virtual void render() = 0; + virtual void changeRenderMode(const GLenum mode) = 0; + protected: RenderableModel* _parent; diff --git a/include/openspace/rendering/model/renderablemodel.h b/include/openspace/rendering/model/renderablemodel.h index 2329c609ea..35784c2a3b 100644 --- a/include/openspace/rendering/model/renderablemodel.h +++ b/include/openspace/rendering/model/renderablemodel.h @@ -63,7 +63,6 @@ private: ghoul::opengl::Texture* _texture; ghoul::opengl::Texture* _bumpMap; - modelgeometry::ModelGeometry* _geometry; glm::dmat3 _stateMatrix; @@ -75,8 +74,9 @@ private: properties::BoolProperty _performShading; properties::BoolProperty _performFade; - properties::FloatProperty _fading; + bool _isGhost; + double _time; }; diff --git a/include/openspace/rendering/model/wavefrontgeometry.h b/include/openspace/rendering/model/wavefrontgeometry.h index be9e467205..75d04e8d43 100644 --- a/include/openspace/rendering/model/wavefrontgeometry.h +++ b/include/openspace/rendering/model/wavefrontgeometry.h @@ -40,6 +40,7 @@ public: bool initialize(RenderableModel* parent) override; void deinitialize() override; void render() override; + void changeRenderMode(const GLenum mode); private: struct Vertex { @@ -56,6 +57,7 @@ private: GLuint _vaoID; GLuint _vbo; GLuint _ibo; + GLenum _mode; std::vector _vertices; std::vector _indices; diff --git a/include/openspace/rendering/planets/renderableplanetprojection.h b/include/openspace/rendering/planets/renderableplanetprojection.h index 8ad4369199..e4e96ac17e 100644 --- a/include/openspace/rendering/planets/renderableplanetprojection.h +++ b/include/openspace/rendering/planets/renderableplanetprojection.h @@ -28,7 +28,6 @@ // open space includes #include -#include #include #include @@ -83,11 +82,13 @@ private: properties::StringProperty _colorTexturePath; properties::StringProperty _projectionTexturePath; properties::TriggerProperty _imageTrigger; + properties::FloatProperty _fadeProjection; ghoul::opengl::ProgramObject* _programObject; ghoul::opengl::ProgramObject* _fboProgramObject; ghoul::opengl::Texture* _texture; + ghoul::opengl::Texture* _textureOriginal; ghoul::opengl::Texture* _textureProj; planetgeometryprojection::PlanetGeometryProjection* _geometry; diff --git a/include/openspace/rendering/renderablefov.h b/include/openspace/rendering/renderablefov.h index 0fec4870c0..929156e9c5 100644 --- a/include/openspace/rendering/renderablefov.h +++ b/include/openspace/rendering/renderablefov.h @@ -76,9 +76,9 @@ public: int _nrInserted = 0; int _isteps; bool _rebuild = false; - bool _interceptTag[5]; + bool _interceptTag[9]; bool _withinFOV; - psc _projectionBounds[4]; + psc _projectionBounds[8]; psc _interceptVector; // spice diff --git a/include/openspace/rendering/renderabletrail.h b/include/openspace/rendering/renderabletrail.h index 29f0161359..b5c0bb93ad 100644 --- a/include/openspace/rendering/renderabletrail.h +++ b/include/openspace/rendering/renderabletrail.h @@ -86,6 +86,8 @@ private: float _increment; float _oldTime = 0; + float _time; + float _distanceFade; }; } // namespace openspace diff --git a/include/openspace/util/imagesequencer2.h b/include/openspace/util/imagesequencer2.h index 0e134dd49e..c016e168a8 100644 --- a/include/openspace/util/imagesequencer2.h +++ b/include/openspace/util/imagesequencer2.h @@ -36,6 +36,19 @@ #include namespace openspace { + /** + * The ImageSequencer singleton main function is to manage the timekeeping and + * distribution of large image data-sets across all openspace renderable instances, + * both for past and future unmanned-spacecraft missions. To load the instance with + * data the client must provide a parser inherited from the abstract base class + * SequenceParser. Hence, there is no restriction imposed on data input, whether its + * data in the form of existing images or in the form of a planned observation schedule. + * Notably, in order for the sequencer to function the client must provide or write a + * parser that fills the ImageSequencers private members. + * \see SequenceParser + * \see ImageSequencer2::runSequenceParser(SequenceParser* parser) + * std::map + */ class ImageSequencer2 { public: ImageSequencer2(); @@ -43,65 +56,140 @@ public: * Singelton instantiation */ static ImageSequencer2* _instance; - + /** + * Returns the reference to the singleton ImageSequencer object that must have been + * initialized by a call to the initialize method earlier. + * \return The ImageSequencer singleton + */ static ImageSequencer2& ref(); + /** + * Initializer that initializes the static member. + */ static void initialize(); + /** + * Deinitializes that deinitializes the static member. + */ static void deinitialize(); - + /** + * Returns true if sequencer has been loaded with data. + */ bool isReady(); - //provides the sequencer with current time + /** + * Updates sequencer with current time. This is used internally for keeping + * track of both current simulation time and the time of the previously rendered frame. + */ void updateSequencer(double time); + /** + * Runs parser and recieves the datastructures filled by it. + * \see SequenceParser + */ void runSequenceParser(SequenceParser* parser); - //translates playbook ambiguous namesetting to spice calls, augments each observation with targets and - //stores all images in its own subset (see _subsetMap member) - bool parsePlaybookFile(const std::string& fileName, - std::string spacecraft, - std::map> acronymDictionary, - std::vector potentialTargets); - - // returns upcoming target + /** + * Retrieves the next upcoming target in time. + */ std::pair getNextTarget(); - // returns next target + + /** + * Retrieves the most current target in time. + */ std::pair getCurrentTarget(); - // returns current target and (in the list) adjacent targets, the number to retrieve is user set + + /** + * Retrieves current target and (in the list) adjacent targets, the number to retrieve is user set + */ std::pair> getIncidentTargetList(int range = 2); + /** + * Retrieves the next upcoming time of image capture. + */ double getNextCaptureTime(); + + /** + * Retrieves the time interval length between the current time and an upcoming capture. + */ double getIntervalLength(); - std::vector> getActiveInstruments(); - bool ImageSequencer2::getImagePaths(std::vector>& captures, std::string projectee, std::string instrumentID); - bool ImageSequencer2::getImagePaths(std::vector>& captures, std::string projectee); + /* + * Returns a map with key instrument names whose value indicate whether + * an instrument is active or not. + */ + std::map getActiveInstruments(); + + /* + * Retrieves the relevant data from a specific subset based on the what instance + * makes the request. If an instance is not registered in the class then the singleton + * returns false and no projections will occur. + */ + bool ImageSequencer2::getImagePaths(std::vector>& captures, + std::string projectee, + std::string instrumentID); + + bool ImageSequencer2::getImagePaths(std::vector>& captures, + std::string projectee); + + /* + * returns true if instrumentID is within a capture range. + */ bool instumentActive(std::string instrumentID); - - const Image* findLatestImageInSubset( ImageSubset& subset); + //const Image* findLatestImageInSubset( ImageSubset& subset); private: - //default comparison function - bool imageComparer(const Image &a, const Image &b); - - //binary find O(log n) always - std::vector::iterator binary_find(std::vector::iterator begin, - std::vector::iterator end, - const Image &val, - bool(*imageComparer)(const Image &a, const Image &b)); - - //var - double _currentTime; - double _previousTime; - double _intervalLength; - double _nextCapture; - - std::string _defaultCaptureImage; - std::vector> _instrumentOnOff; - - std::map _subsetMap; - std::vector> _targetTimes; - std::vector> _instrumentTimes; - std::vector _captureProgression; + void sortData(); + + /* + * _fileTranslation handles any types of ambiguities between the data and + * spice/openspace -calls. This map is composed of a key that is a string in + * the data to be translated and a Decoder that holds the corresponding + * translation provided through a modfile. + * \see Decoder + * \see (projection mod files) + */ std::map _fileTranslation; + /* + * This is the main container of image data. The key is the target name, + * the value is a subset of images. + * \see SequenceParser + */ + std::map _subsetMap; + + /* + * In order for the simulation to know when to turn on/off any instrument within + * all instruments in the spacecraft payload, the key is the data-file given + * instrument name. + */ + std::map _switchingMap; + + /* + * This datastructure holds the specific times when the spacecraft switches from + * observing one inertial body to the next. This happens a lot in such missions + * and the coupling of target with specific time is usually therefore not 1:1. + */ + std::vector> _targetTimes; + + /* + * Holds the time ranges of each instruments on and off periods. An instrument + * rendering class may ask the ImageSequencer whether or not it + */ + std::vector> _instrumentTimes; + + /* + * Each consecutive images capture time, for easier traversal. + */ + std::vector _captureProgression; + + // current simulation time + double _currentTime; + // simulation time of previous frame + double _previousTime; + // time between current simulation time and an upcoming capture + double _intervalLength; + // next consecutive capture in time + double _nextCapture; + // default capture image + std::string _defaultCaptureImage; + // if no data, no run bool _hasData; }; diff --git a/include/openspace/util/instrumentdecoder.h b/include/openspace/util/instrumentdecoder.h index 41d9b77f7d..d464c3d6ef 100644 --- a/include/openspace/util/instrumentdecoder.h +++ b/include/openspace/util/instrumentdecoder.h @@ -36,8 +36,10 @@ public: InstrumentDecoder(const ghoul::Dictionary& dictionary); virtual std::string getDecoderType(); virtual std::vector getTranslation(); + std::string getStopCommand(); private: std::string _type; + std::string _stopCommand; std::vector _spiceIDs; }; diff --git a/include/openspace/util/labelparser.h b/include/openspace/util/labelparser.h index 220e7b4c3e..738de59552 100644 --- a/include/openspace/util/labelparser.h +++ b/include/openspace/util/labelparser.h @@ -33,44 +33,54 @@ #include namespace openspace { - class LabelParser : public SequenceParser{ - public: - LabelParser(); - LabelParser(const std::string& fileName, - ghoul::Dictionary translationDictionary); - virtual void create(); - virtual std::map getSubsetMap(); - virtual std::vector> getIstrumentTimes(); - virtual std::vector> getTargetTimes(); +class LabelParser : public SequenceParser{ +public: + LabelParser(); + LabelParser(const std::string& fileName, + ghoul::Dictionary translationDictionary); + virtual void create(); + virtual std::map getSubsetMap(); + virtual std::vector> getIstrumentTimes(); + virtual std::vector> getTargetTimes(); - // temporary need to figure this out - std::map getTranslation(){ return _fileTranslation; }; - virtual std::vector getCaptureProgression(){ return _captureProgression; }; + // temporary need to figure this out + std::map getTranslation(){ return _fileTranslation; }; + virtual std::vector getCaptureProgression(){ return _captureProgression; }; - private: - void createImage(Image& image, - double startTime, - double stopTime, - std::vector instr, - std::string targ, - std::string pot); +private: + void createImage(Image& image, + double startTime, + double stopTime, + std::vector instr, + std::string targ, + std::string path); - bool augmentWithSpice(Image& image, - std::string spacecraft, - std::vector payload, - std::vector potentialTargets); + std::string decode(std::string line); + + bool augmentWithSpice(Image& image, + std::string spacecraft, + std::vector payload, + std::vector potentialTargets); - std::string _fileName; - std::string _spacecraft; - std::map _fileTranslation; - std::vector _specsOfInterest; + std::string _fileName; + std::string _spacecraft; + std::map _fileTranslation; + std::vector _specsOfInterest; - //returnable - std::map _subsetMap; - std::vector> _instrumentTimes; - std::vector> _targetTimes; - std::vector _captureProgression; - }; + //returnable + std::map _subsetMap; + std::vector> _instrumentTimes; + std::vector> _targetTimes; + std::vector _captureProgression; + + std::string _target; + std::string _instrumentID; + std::string _instrumentHostID; + std::string _detectorType; + std::string _sequenceID; + double _startTime; + double _stopTime; +}; } #endif //__LABELPARSER_H__ \ No newline at end of file diff --git a/include/openspace/util/scannerdecoder.h b/include/openspace/util/scannerdecoder.h index 8eddf3aafb..4ddff2a935 100644 --- a/include/openspace/util/scannerdecoder.h +++ b/include/openspace/util/scannerdecoder.h @@ -35,8 +35,11 @@ public: ScannerDecoder(const ghoul::Dictionary& dictionary); virtual std::string getDecoderType(); virtual std::vector getSpiceIDs(); + std::string getStopCommand(); + void setStopCommand(std::string stopCommand); private: std::string _type; + std::string _abort; std::vector _spiceIDs; }; diff --git a/include/openspace/util/sequenceparser.h b/include/openspace/util/sequenceparser.h index 90197884be..b8b54336b8 100644 --- a/include/openspace/util/sequenceparser.h +++ b/include/openspace/util/sequenceparser.h @@ -37,7 +37,7 @@ namespace openspace { double startTime; double stopTime; std::string path; - std::vector activeInstruments; + std::vector activeInstruments; std::string target; bool projected; }; diff --git a/openspace-data b/openspace-data index 6b34ef9849..de36eeeb00 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 6b34ef9849d58fa33a40c571eee6432bde83e343 +Subproject commit de36eeeb000a6345bd6d63f21bf9c705e01ddfc0 diff --git a/scripts/default_startup.lua b/scripts/default_startup.lua index 19cd4413d1..27e520b7c4 100644 --- a/scripts/default_startup.lua +++ b/scripts/default_startup.lua @@ -14,11 +14,11 @@ dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) -- Load the default keyb -- openspace.time.setDeltaTime(50); -openspace.time.setTime("2015-07-14T10:10:00.00") -- PLUTO +--openspace.time.setTime("2015-07-14T10:10:00.00") -- PLUTO -- NH takes series of images from visible to dark side (across terminator) -- Sequence lasts ~10 mins, (recommended dt = 10) ---openspace.time.setTime("2015-07-14T11:22:00.00") -- PLUTO +openspace.time.setTime("2015-07-14T11:00:00.00") -- PLUTO --BEAUTIFUL SEQUENCE -- NH takes series of images (same as previous) -- Sequence ends at 2015 JUL 14T11:24:00:000, (recommended dt = 1) diff --git a/shaders/fboPass_fs.glsl b/shaders/fboPass_fs.glsl index b89dc7f7cf..b339ec85c7 100644 --- a/shaders/fboPass_fs.glsl +++ b/shaders/fboPass_fs.glsl @@ -25,12 +25,15 @@ #version 430 uniform sampler2D texture1; +uniform sampler2D texture2; uniform mat4 ProjectorMatrix; uniform mat4 ModelTransform; uniform vec2 _scaling; uniform vec2 radius; flat in uint vs_segments; +uniform float projectionFading; + in vec4 vs_position; uniform vec3 boresight; @@ -78,7 +81,9 @@ void main() { dot(v_b, normal) < 0 ) { color = texture(texture1, projected.xy); }else{ - color = vec4(1,1,1,0); + color = texture(texture2, uv); + color.a = projectionFading; } + // color.a = 0.1f;//1.f - abs(uv.x - 0.55) / (0.6 - 0.5); // blending } \ No newline at end of file diff --git a/shaders/modules/trails/ephemeris_fs.glsl b/shaders/modules/trails/ephemeris_fs.glsl index a5a72ae47f..c9a8c5f111 100644 --- a/shaders/modules/trails/ephemeris_fs.glsl +++ b/shaders/modules/trails/ephemeris_fs.glsl @@ -27,6 +27,7 @@ in vec4 vs_point_position; in vec4 vs_point_velocity; in float fade; +uniform float forceFade; uniform vec3 color; @@ -38,7 +39,7 @@ void main() { vec4 position = vs_point_position; float depth = pscDepth(position); - vec4 c = vec4(color, fade); + vec4 c = vec4(color, fade*forceFade); ABufferStruct_t frag = createGeometryFragment(c, position, depth); addToBuffer(frag); } \ No newline at end of file diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 132b43e705..ae3fa64834 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -44,7 +44,6 @@ #include #include #include -#include #include // testing @@ -102,7 +101,6 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName) { SpiceManager::initialize(); Time::initialize(); - ImageSequencer::initialize(); ImageSequencer2::initialize(); FactoryManager::initialize(); ghoul::systemcapabilities::SystemCapabilities::initialize(); diff --git a/src/rendering/model/renderablemodel.cpp b/src/rendering/model/renderablemodel.cpp index 258a85f0d8..c567ed67d5 100644 --- a/src/rendering/model/renderablemodel.cpp +++ b/src/rendering/model/renderablemodel.cpp @@ -37,6 +37,8 @@ #include #include +#include + #include #include @@ -47,6 +49,7 @@ const std::string _loggerCat = "RenderableModel"; const std::string keyDestination = "Rotation.Destination"; const std::string keyShading = "Shading.PerformShading"; const std::string keyFading = "Shading.Fadeable"; + const std::string keyGhosting = "Shading.Ghosting"; } @@ -60,6 +63,7 @@ namespace openspace { , _texture(nullptr) , _bumpMap(nullptr) , _geometry(nullptr) + , _isGhost(false) , _performShading("performShading", "Perform Shading", true) , _fading("fading", "Fade", 0) , _performFade("performFading", "Perform Fading", false) @@ -114,11 +118,17 @@ namespace openspace { if (dictionary.hasKeyAndValue(keyFading)) { bool fading; - dictionary.getValue(keyShading, fading); + dictionary.getValue(keyFading, fading); _performFade = fading; } addProperty(_performFade); + + if (dictionary.hasKeyAndValue(keyGhosting)) { + bool ghosting; + dictionary.getValue(keyGhosting, ghosting); + _isGhost = ghosting; + } } bool RenderableModel::isReady() const { @@ -163,26 +173,21 @@ bool RenderableModel::deinitialize() { } void RenderableModel::render(const RenderData& data) { - _programObject->activate(); + double lt; - glm::mat4 transform = glm::mat4(1); + _programObject->activate(); + glm::mat4 transform = glm::mat4(1); glm::mat4 tmp = glm::mat4(1); for (int i = 0; i < 3; i++){ for (int j = 0; j < 3; j++){ tmp[i][j] = static_cast(_stateMatrix[i][j]); } } - transform *= tmp; - double lt; psc tmppos; - - SpiceManager::ref().getTargetPosition(_source, "SUN", "GALACTIC", "NONE", Time::ref().currentTime(), tmppos, lt); - + SpiceManager::ref().getTargetPosition(_source, "SUN", "GALACTIC", "NONE", _time, tmppos, lt); glm::vec3 cam_dir = glm::normalize(data.camera.position().vec3() - tmppos.vec3()); - - //std::cout << cam_dir << std::endl; _programObject->setUniform("sun_pos", _sunPosition.vec3()); _programObject->setUniform("cam_dir", cam_dir); _programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); @@ -191,44 +196,58 @@ void RenderableModel::render(const RenderData& data) { _programObject->setUniform("_performShading", _performShading); - if (_performFade && _fading > 0.f){ _fading = _fading - 0.01f; - - } - else if (!_performFade && _fading < 1.f){ + }else if (!_performFade && _fading < 1.f){ _fading = _fading + 0.01f; } - _programObject->setUniform("fading", _fading); - - - // Bind texture - ghoul::opengl::TextureUnit unit; - unit.activate(); - _texture->bind(); - _programObject->setUniform("texture1", unit); + // Bind texture + ghoul::opengl::TextureUnit unit; + unit.activate(); + _texture->bind(); + _programObject->setUniform("texture1", unit); ghoul::opengl::TextureUnit unitBump; unitBump.activate(); _bumpMap->bind(); - //_programObject->setUniform("texture2", unitBump); _geometry->render(); - // disable shader - _programObject->deactivate(); + // disable shader + _programObject->deactivate(); } void RenderableModel::update(const UpdateData& data) { + _time = data.time; + + double futureTime; + if (_isGhost){ + futureTime = openspace::ImageSequencer2::ref().getNextCaptureTime(); + double remaining = openspace::ImageSequencer2::ref().getNextCaptureTime() - data.time; + double interval = openspace::ImageSequencer2::ref().getIntervalLength(); + double t = 1.f - remaining / openspace::ImageSequencer2::ref().getIntervalLength(); + if (interval > 60){ + if (t < 0.8){ + _fading = t; + } + else if (t >= 0.95f){ + _fading = _fading - 0.5f; + } + } + else{ + _fading = 0.0f; + } + _time = futureTime; + } + // set spice-orientation in accordance to timestamp if (!_source.empty()) - openspace::SpiceManager::ref().getPositionTransformMatrix(_source, _destination, data.time, _stateMatrix); - + openspace::SpiceManager::ref().getPositionTransformMatrix(_source, _destination, _time, _stateMatrix); double lt; - openspace::SpiceManager::ref().getTargetPosition("SUN", _source, "GALACTIC", "NONE", data.time, _sunPosition, lt); + openspace::SpiceManager::ref().getTargetPosition("SUN", _source, "GALACTIC", "NONE", _time, _sunPosition, lt); } void RenderableModel::loadTexture() { diff --git a/src/rendering/model/wavefrontgeometry.cpp b/src/rendering/model/wavefrontgeometry.cpp index aa88ba01a9..a31276a112 100644 --- a/src/rendering/model/wavefrontgeometry.cpp +++ b/src/rendering/model/wavefrontgeometry.cpp @@ -47,6 +47,7 @@ namespace modelgeometry { WavefrontGeometry::WavefrontGeometry(const ghoul::Dictionary& dictionary) : ModelGeometry() + ,_mode(GL_TRIANGLES) { using constants::scenegraphnode::keyName; @@ -139,10 +140,14 @@ void WavefrontGeometry::deinitialize() { glDeleteBuffers(1, &_ibo); } +void WavefrontGeometry::changeRenderMode(const GLenum mode){ + _mode = mode; +} + void WavefrontGeometry::render() { glBindVertexArray(_vaoID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo); - glDrawElements(GL_TRIANGLES, _indices.size(), GL_UNSIGNED_INT, 0); + glDrawElements(_mode, _indices.size(), GL_UNSIGNED_INT, 0); glBindVertexArray(0); } diff --git a/src/rendering/planets/renderableplanetprojection.cpp b/src/rendering/planets/renderableplanetprojection.cpp index 596ec9006e..24b4baf913 100644 --- a/src/rendering/planets/renderableplanetprojection.cpp +++ b/src/rendering/planets/renderableplanetprojection.cpp @@ -86,11 +86,12 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& , _colorTexturePath("planetTexture", "RGB Texture") , _projectionTexturePath("projectionTexture", "RGB Texture") , _imageTrigger("clearProjections", "Clear Projections") - //, _sequencer(nullptr) + , _fadeProjection("fadeProjections", "Image Fading Factor", 0.f, 0.f, 1.f) , _programObject(nullptr) , _fboProgramObject(nullptr) , _texture(nullptr) , _textureProj(nullptr) + , _textureOriginal(nullptr) , _geometry(nullptr) , _sequenceID(-1) , _once(false) @@ -158,9 +159,8 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& _projectionTexturePath = path + "/" + texturePath; } addPropertySubOwner(_geometry); - - addProperty(_imageTrigger); - _imageTrigger.onChange(std::bind(&RenderablePlanetProjection::loadTexture, this)); + + addProperty(_fadeProjection); addProperty(_colorTexturePath); _colorTexturePath.onChange(std::bind(&RenderablePlanetProjection::loadTexture, this)); @@ -181,34 +181,22 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& //get translation dictionary dictionary.getValue(keyTranslation, translationDictionary); - if (_sequenceType == sequenceTypePlaybook){ - // eeh to many inputs, bit ugly. beautify later. parser = new HongKangParser(_sequenceSource, "NEW HORIZONS", translationDictionary, _potentialTargets); + openspace::ImageSequencer2::ref().runSequenceParser(parser); } - /*else if (_sequenceType == sequenceTypeImage){ + else if (_sequenceType == sequenceTypeImage){ parser = new LabelParser(_sequenceSource, translationDictionary); - }*/ + openspace::ImageSequencer2::ref().runSequenceParser(parser); + + } } else{ LWARNING("No playbook translation provided, please make sure all spice calls match playbook!"); } - - /*if (_sequenceType == sequenceTypeImage) { - LWARNING("LOADING STUFF FOR JUPITER!"); - //openspace::ImageSequencer::ref().loadSequence(_sequenceSource, _sequenceID); - // SequenceParser *parser = new LabelParser(_sequenceSource, - //"NEW HORIZONS", - //_fileTranslation, - //_potentialTargets); - //openspace::ImageSequencer2::ref().runSequenceParser(parser); - }*/ - /*else*/ if (_sequenceType == sequenceTypePlaybook) { - openspace::ImageSequencer2::ref().runSequenceParser(parser); - } } } @@ -311,6 +299,13 @@ void RenderablePlanetProjection::imageProjectGPU(){ unitFbo.activate(); _textureProj->bind(); _fboProgramObject->setUniform("texture1" , unitFbo); + + ghoul::opengl::TextureUnit unitFbo2; + unitFbo2.activate(); + _textureOriginal->bind(); + _fboProgramObject->setUniform("texture2", unitFbo2); + _fboProgramObject->setUniform("projectionFading", _fadeProjection); + _fboProgramObject->setUniform("ProjectorMatrix", _projectorMatrix); _fboProgramObject->setUniform("ModelTransform" , _transform); _fboProgramObject->setUniform("_scaling" , _camScaling); @@ -395,7 +390,6 @@ void RenderablePlanetProjection::attitudeParameters(double time){ psc position; //observer target found = SpiceManager::ref().getTargetPosition(_projectorID, _projecteeID, _mainFrame, _aberration, time, position, lightTime); - //if (!found) LERROR("Could not locate target position"); //change to KM and add psc camera scaling. position[3] += (3 + _camScaling[1]); @@ -457,13 +451,13 @@ void RenderablePlanetProjection::update(const UpdateData& data){ // set spice-orientation in accordance to timestamp _time = data.time; _capture = false; - if (openspace::ImageSequencer2::ref().isReady()){ openspace::ImageSequencer2::ref().updateSequencer(_time); _capture = openspace::ImageSequencer2::ref().getImagePaths(_imageTimes, _projecteeID, _instrumentID); } - + //floor fading to decimal + _fadeProjection = floorf(_fadeProjection * 10) / 10; } void RenderablePlanetProjection::loadProjectionTexture(){ @@ -477,7 +471,6 @@ void RenderablePlanetProjection::loadProjectionTexture(){ _textureProj->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder); } } - //_sequencer->sequenceReset(); } void RenderablePlanetProjection::loadTexture(){ @@ -490,5 +483,14 @@ void RenderablePlanetProjection::loadTexture(){ _texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); } } + delete _textureOriginal; + _textureOriginal = nullptr; + if (_colorTexturePath.value() != "") { + _textureOriginal = ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath)); + if (_textureOriginal) { + _textureOriginal->uploadTexture(); + _textureOriginal->setFilter(ghoul::opengl::Texture::FilterMode::Linear); + } + } } } // namespace openspace diff --git a/src/rendering/renderablefov.cpp b/src/rendering/renderablefov.cpp index 66233c48dd..33cb8d82f8 100644 --- a/src/rendering/renderablefov.cpp +++ b/src/rendering/renderablefov.cpp @@ -29,7 +29,6 @@ #include #include -#include #include // testing #include @@ -104,7 +103,7 @@ namespace openspace{ } void RenderableFov::allocateData(){ - int points = 10; + int points = 20; _stride[0] = points; _isize[0] = points; _iarray1[0] = new int[_isize[0]]; @@ -123,7 +122,7 @@ void RenderableFov::allocateData(){ _vtotal[0] = static_cast(_vsize[0] / _stride[0]); // allocate second vbo data - int cornerPoints = 6; + int cornerPoints = 12; _isize[1] = cornerPoints; _iarray1[1] = new int[_isize[1]]; for (int i = 0; i < _isize[1]; i++){ @@ -293,8 +292,8 @@ void RenderableFov::fovProjection(bool H[], std::vector bounds){ glm::dvec3 next; glm::vec4 tmp(1); if (bounds.size() > 1){ - for (int i = 0; i < 4; i++){ - int k = (i + 1 > 4 - 1) ? 0 : i + 1; + for (int i = 0; i < bounds.size(); i++){ + int k = (i + 1 > bounds.size() - 1) ? 0 : i + 1; current = bounds[i]; next = bounds[k]; @@ -383,7 +382,7 @@ void RenderableFov::computeColors(){ c_project = glm::vec4(0.0, 1.0, 0.00,1); col_end = glm::vec4(1.00, 0.29, 0.00, 1); blue = glm::vec4(0, 0.5, 0.7, 1); - col_gray = glm::vec4(0.5, 0.5, 0.5, 0.5); + col_gray = glm::vec4(0.7); col_start = glm::vec4(1.00, 0.89, 0.00, 1); col_sq = glm::vec4(1.00, 0.29, 0.00, 1); @@ -416,14 +415,13 @@ void RenderableFov::render(const RenderData& data){ spacecraftRot[i][j] = _stateMatrix[i][j]; } } + bool drawFOV = false; // setup the data to the shader _programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); _programObject->setUniform("ModelTransform", transform); setPscUniforms(_programObject, &data.camera, data.position); - bool drawFOV = false; - if (openspace::ImageSequencer2::ref().isReady()){ drawFOV = ImageSequencer2::ref().instumentActive(_instrumentID); } @@ -513,7 +511,7 @@ void RenderableFov::render(const RenderData& data){ } } - _interceptTag[4] = _interceptTag[0]; + _interceptTag[bounds.size()] = _interceptTag[0]; fovProjection(_interceptTag, bounds); updateData(); } @@ -529,6 +527,7 @@ void RenderableFov::render(const RenderData& data){ glDrawArrays(GL_LINES, 0, _vtotal[0]); glBindVertexArray(0); + //second vbo if (drawFOV){ glLineWidth(1.f); diff --git a/src/rendering/renderabletrail.cpp b/src/rendering/renderabletrail.cpp index 044932897c..e9a0553ec6 100644 --- a/src/rendering/renderabletrail.cpp +++ b/src/rendering/renderabletrail.cpp @@ -30,6 +30,9 @@ #include #include #include +#include +#include + /* TODO for this class: * In order to add geometry shader (for pretty-draw), @@ -40,6 +43,7 @@ namespace { const std::string _loggerCat = "RenderableTrail"; //constants + const std::string keyName = "Name"; const std::string keyBody = "Body"; const std::string keyObserver = "Observer"; const std::string keyFrame = "Frame"; @@ -86,6 +90,7 @@ RenderableTrail::RenderableTrail(const ghoul::Dictionary& dictionary) addProperty(_lineFade); addProperty(_lineWidth); + _distanceFade = 1.0; } bool RenderableTrail::initialize() { @@ -139,6 +144,23 @@ void RenderableTrail::render(const RenderData& data) { _programObject->setUniform("nVertices", static_cast(_vertexArray.size())); _programObject->setUniform("lineFade", _lineFade); + const psc& position = data.camera.position(); + const psc& origin = openspace::OpenSpaceEngine::ref().interactionHandler()->focusNode()->worldPosition(); + const PowerScaledScalar& pssl = (position - origin).length(); + + + //std::cout << openspace::OpenSpaceEngine::ref().interactionHandler()->focusNode()->name()<< std::endl; + //std::cout << this->owner()->name() << std::endl; + + if (pssl[0] < 0.00001){ + if (_distanceFade > 0.0f) _distanceFade -= 0.05f; + _programObject->setUniform("forceFade", _distanceFade); + } + else{ + if (_distanceFade < 1.0f) _distanceFade += 0.05f; + _programObject->setUniform("forceFade", _distanceFade); + } + glLineWidth(_lineWidth); glBindVertexArray(_vaoID); @@ -151,6 +173,7 @@ void RenderableTrail::render(const RenderData& data) { } void RenderableTrail::update(const UpdateData& data) { + _time = data.time; if (data.isTimeJump) _needsSweep = true; diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index ae5ce38a4f..fce275c30a 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -24,7 +24,6 @@ #include -#include #include @@ -433,7 +432,6 @@ namespace openspace { Time::ref().deltaTime(), _doPerformanceMeasurements }); - ImageSequencer::ref().update(Time::ref().currentTime()); _sceneGraph->evaluate(_mainCamera); // clear the abuffer before rendering the scene @@ -509,60 +507,6 @@ namespace openspace { sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); int startY = ySize - 2 * font_size_mono; - double currentTime = Time::ref().currentTime(); - - double remaining = openspace::ImageSequencer::ref().getNextCaptureTime() - currentTime; - double t = 1.f - remaining / openspace::ImageSequencer::ref().getIntervalLength(); - std::string progress = "|"; - int g = ((t)* 20) + 1; - for (int i = 0; i < g; i++) progress.append("-"); progress.append(">"); - for (int i = 0; i < 21 - g; i++) progress.append(" "); - - std::string str = ""; - openspace::SpiceManager::ref().getDateFromET(openspace::ImageSequencer::ref().getNextCaptureTime(), str); - - Freetype::print(font, - _onScreenInformation._position.x * xSize, - _onScreenInformation._position.y * ySize, - "Date: %s", - Time::ref().currentTimeUTC().c_str() - ); - - progress.append("|"); - if (remaining > 0){ - glm::vec4 g1(0, t, 0, 1); - glm::vec4 g2(1 - t); - Freetype::print(font, - _onScreenInformation._position.x * xSize, - _onScreenInformation._position.y * ySize - font_size_mono * 2, - g1 + g2, - "Next projection in | %.0f seconds", - remaining - ); - Freetype::print(font, - _onScreenInformation._position.x * xSize, - _onScreenInformation._position.y * ySize - font_size_mono * 2 * 2, - g1 + g2, - "%s %.1f %%", - progress.c_str(), t * 100 - ); - - } - /*std::vector instrVec = ImageSequencer2::ref().getActiveInstruments(); - - std::string active =""; - for (int i = 0; i < instrVec.size(); i++){ - active.append(instrVec[i]); - active.append(" "); - } - Freetype::print(font, - _onScreenInformation._position.x * xSize, - _onScreenInformation._position.y * ySize - font_size_mono * 3 * 2, - glm::vec4(0.3, 0.6, 1, 1), - "Active Instrument : %s", - active.c_str() - );*/ - } } @@ -593,9 +537,9 @@ namespace openspace { // Using a macro to shorten line length and increase readability int i = 0; - - PrintText(i++, "Date: %s", Time::ref().currentTimeUTC().c_str()); /* + PrintText(i++, "Date: %s", Time::ref().currentTimeUTC().c_str()); + PrintText(i++, "Avg. Frametime: %.5f", sgct::Engine::instance()->getAvgDt()); PrintText(i++, "Drawtime: %.5f", sgct::Engine::instance()->getDrawTime()); PrintText(i++, "Frametime: %.5f", sgct::Engine::instance()->getDt()); @@ -605,6 +549,7 @@ namespace openspace { PrintText(i++, "Cam->origin: (% .15f, % .4f)", pssl[0], pssl[1]); PrintText(i++, "Scaling: (% .5f, % .5f)", scaling[0], scaling[1]); */ + if (openspace::ImageSequencer2::ref().isReady()){ double remaining = openspace::ImageSequencer2::ref().getNextCaptureTime() - currentTime; double t = 1.f - remaining / openspace::ImageSequencer2::ref().getIntervalLength(); @@ -625,9 +570,9 @@ namespace openspace { } glm::vec4 w(1); PrintColorText(i++, "Ucoming capture : %s", 10, w, str.c_str()); - + std::pair nextTarget = ImageSequencer2::ref().getNextTarget(); - std::pair currentTarget = ImageSequencer2::ref().getCurrentTarget(); + std::pair currentTarget = ImageSequencer2::ref().getCurrentTarget(); int timeleft = nextTarget.first - currentTime; @@ -649,7 +594,7 @@ namespace openspace { glm::vec4 b2(1.00, 0.51, 0.00, 1); PrintColorText(i++, "Switching observation focus in : [%s:%s:%s]", 10, b2, hh.c_str(), mm.c_str(), ss.c_str()); - + std::pair> incidentTargets = ImageSequencer2::ref().getIncidentTargetList(2); std::string space; glm::vec4 color; @@ -664,35 +609,26 @@ namespace openspace { } i++; - std::vector> instrVec = ImageSequencer2::ref().getActiveInstruments(); - + + std::map activeMap = ImageSequencer2::ref().getActiveInstruments(); glm::vec4 active(0.58, 1, 0.00, 1); - - glm::vec4 firing(0.58-t, 1-t, 1-t, 1); glm::vec4 notFiring(0.5, 0.5, 0.5, 1); - - - double reduce = 0.01; - PrintColorText(i++, "Active Instruments : ", 10, active); - for (int k = 0; k < instrVec.size(); k++){ - - if (instrVec[k].second == false){ + for (auto t : activeMap){ + if (t.second == false){ PrintColorText(i, "| |", 10, glm::vec4(0.3, 0.3, 0.3, 1)); - PrintColorText(i++, " %5s", 10, glm::vec4(0.3, 0.3, 0.3, 1), instrVec[k].first.c_str()); + PrintColorText(i++, " %5s", 10, glm::vec4(0.3, 0.3, 0.3, 1), t.first.c_str()); } else{ PrintColorText(i, "|", 10, glm::vec4(0.3, 0.3, 0.3, 1)); - if (instrVec[k].first == "NH_LORRI"){ + if (t.first == "NH_LORRI"){ PrintColorText(i, " + ", 10, firing); } PrintColorText(i, " |", 10, glm::vec4(0.3, 0.3, 0.3, 1)); - PrintColorText(i++, " %5s", 10, active, instrVec[k].first.c_str()); - + PrintColorText(i++, " %5s", 10, active, t.first.c_str()); } } - } #undef PrintText @@ -1037,6 +973,7 @@ void RenderEngine::changeViewPoint(std::string origin) { SceneGraphNode* solarSystemBarycenterNode = sceneGraph()->sceneGraphNode("SolarSystemBarycenter"); SceneGraphNode* plutoBarycenterNode = sceneGraph()->sceneGraphNode("PlutoBarycenter"); SceneGraphNode* newHorizonsNode = sceneGraph()->sceneGraphNode("NewHorizons"); + SceneGraphNode* newHorizonsGhostNode = sceneGraph()->sceneGraphNode("NewHorizonsGhost"); SceneGraphNode* jupiterBarycenterNode = sceneGraph()->sceneGraphNode("JupiterBarycenter"); if (solarSystemBarycenterNode == nullptr || plutoBarycenterNode == nullptr || newHorizonsNode == nullptr || jupiterBarycenterNode == nullptr) { @@ -1076,6 +1013,16 @@ void RenderEngine::changeViewPoint(std::string origin) { }; newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary)); + ghoul::Dictionary newHorizonsGhostDictionary = + { + { std::string("Type"), std::string("Spice") }, + { std::string("Body"), std::string("NEW HORIZONS GHOST") }, + { std::string("Reference"), std::string("GALACTIC") }, + { std::string("Observer"), std::string("PLUTO BARYCENTER") }, + { std::string("Kernels"), ghoul::Dictionary() } + }; + newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary)); + return; } if (origin == "Sun") { @@ -1109,6 +1056,17 @@ void RenderEngine::changeViewPoint(std::string origin) { { std::string("Kernels"), ghoul::Dictionary() } }; newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary)); + + ghoul::Dictionary newHorizonsGhostDictionary = + { + { std::string("Type"), std::string("Spice") }, + { std::string("Body"), std::string("NEW HORIZONS GHOST") }, + { std::string("Reference"), std::string("GALACTIC") }, + { std::string("Observer"), std::string("JUPITER BARYCENTER") }, + { std::string("Kernels"), ghoul::Dictionary() } + }; + newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary)); + return; } if (origin == "Jupiter") { @@ -1142,6 +1100,16 @@ void RenderEngine::changeViewPoint(std::string origin) { { std::string("Kernels"), ghoul::Dictionary() } }; newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary)); + + ghoul::Dictionary newHorizonsGhostDictionary = + { + { std::string("Type"), std::string("Spice") }, + { std::string("Body"), std::string("NEW HORIZONS GHOST") }, + { std::string("Reference"), std::string("GALACTIC") }, + { std::string("Observer"), std::string("JUPITER BARYCENTER") }, + { std::string("Kernels"), ghoul::Dictionary() } + }; + newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary)); return; } diff --git a/src/scenegraph/spiceephemeris.cpp b/src/scenegraph/spiceephemeris.cpp index 0e42a8f9da..cb7776611b 100644 --- a/src/scenegraph/spiceephemeris.cpp +++ b/src/scenegraph/spiceephemeris.cpp @@ -27,6 +27,7 @@ #include #include #include +#include namespace { const std::string _loggerCat = "SpiceEphemeris"; @@ -73,15 +74,15 @@ void SpiceEphemeris::update(const UpdateData& data) { glm::dvec3 position(0,0,0); double lightTime = 0.0; - + if (_targetName != "NEW HORIZONS GHOST") SpiceManager::ref().getTargetPosition(_targetName, _originName, "GALACTIC", "NONE", data.time, position, lightTime); - if (_targetName == "NEW HORIZONS"){ - // In order to properly draw the viewfrustrum, the craft might have to be - // positioned using the X-variations of aberration methods (ongoing investigation). - SpiceManager::ref().getTargetPosition(_targetName, _originName, - "GALACTIC", "NONE", data.time, position, lightTime); + double interval = openspace::ImageSequencer2::ref().getIntervalLength(); + if (_targetName == "NEW HORIZONS GHOST" && interval > 60){ + double _time = openspace::ImageSequencer2::ref().getNextCaptureTime(); + SpiceManager::ref().getTargetPosition("NEW HORIZONS", _originName, + "GALACTIC", "NONE", _time, position, lightTime); } _position = psc::CreatePowerScaledCoordinate(position.x, position.y, position.z); diff --git a/src/util/hongkangparser.cpp b/src/util/hongkangparser.cpp index 8f700dce35..2817818fd0 100644 --- a/src/util/hongkangparser.cpp +++ b/src/util/hongkangparser.cpp @@ -32,8 +32,9 @@ #include #include #include - #include +#include + namespace { const std::string _loggerCat = "HongKangParser"; @@ -61,9 +62,10 @@ namespace openspace { translationDictionary.getValue(decoders[i], typeDictionary); //for each playbook call -> create a Decoder object const std::vector& keys = typeDictionary.keys(); + //std::string abort = decoders[i] + "." + keyStopCommand; for (int j = 0; j < keys.size(); j++){ std::string currentKey = decoders[i] + "." + keys[j]; - + ghoul::Dictionary decoderDictionary; translationDictionary.getValue(currentKey, decoderDictionary); @@ -101,7 +103,7 @@ void HongKangParser::create(){ if (extension == "txt"){// Hong Kang. pre-parsed playbook LINFO("Using Preparsed Playbook V9H"); - std::ifstream file(_fileName); + std::ifstream file(_fileName , std::ios::binary); if (!file.good()) LERROR("Failed to open txt file '" << _fileName << "'"); std::string line = ""; @@ -126,18 +128,22 @@ void HongKangParser::create(){ std::string cameraTarget = "VOID"; std::string scannerTarget = "VOID"; - do{ - std::getline(file, line); + int counter = 0; + + + while (!file.eof()){//only while inte do, FIX + std::getline(file, line); + std::string event = line.substr(0, line.find_first_of(" ")); auto it = _fileTranslation.find(event); bool foundEvent = (it != _fileTranslation.end()); - + std::string met = line.substr(25, 9); double time = getETfromMet(met); Image image; - + if (foundEvent){ //store the time, this is used for getNextCaptureTime() _captureProgression.push_back(time); @@ -167,13 +173,48 @@ void HongKangParser::create(){ //compute and store the range for each subset _subsetMap[image.target]._range.setRange(time); } - if (scan_start == -1 && it->second->getDecoderType() == "SCANNER"){ - //scanner works like state-machine -only store start time now + if (it->second->getDecoderType() == "SCANNER"){ // SCANNER START + scan_start = time; + + InstrumentDecoder* scanner = static_cast(it->second); + std::string endNominal = scanner->getStopCommand(); + + // store current position in file + int len = file.tellg(); + std::string linePeek; + bool foundstop = false; + while (!file.eof() && !foundstop){ + //continue grabbing next line until we find what we need + getline(file, linePeek); + if (linePeek.find(endNominal) != std::string::npos){ + foundstop = true; + + met = linePeek.substr(25, 9); + scan_stop = getETfromMet(met); + findPlaybookSpecifiedTarget(line, scannerTarget); + scannerSpiceID = it->second->getTranslation(); + + scanRange._min = scan_start; + scanRange._max = scan_stop; + _instrumentTimes.push_back(std::make_pair(it->first, scanRange)); + + + //store individual image + createImage(image, scan_start, scan_stop, scannerSpiceID, scannerTarget, _defaultCaptureImage); + + _subsetMap[image.target]._subset.push_back(image); + _subsetMap[image.target]._range.setRange(scan_start); + } + } + //go back to stored position in file + file.seekg(len, std::ios_base::beg); + + /*//scanner works like state-machine -only store start time now scan_start = time; previousScanner = it->first; //store scanning instrument - store image once stopTime is found! findPlaybookSpecifiedTarget(line, scannerTarget); - scannerSpiceID = it->second->getTranslation(); + scannerSpiceID = it->second->getTranslation();*/ } } else{ // we have reached the end of a scan or consecutive capture sequence! @@ -186,7 +227,7 @@ void HongKangParser::create(){ capture_start = -1; } - if (line.find("END_NOM") != std::string::npos){ + /*if (line.find("END_NOM") != std::string::npos){ assert(scan_start != -1, "SCAN end occured before SCAN call!"); //end of scan, store end time of this scan + store the scan image scan_stop = time; @@ -201,9 +242,9 @@ void HongKangParser::create(){ _subsetMap[image.target]._range.setRange(scan_start); scan_start = -1; - } + }*/ } - } while (!file.eof()); + } } } } @@ -273,10 +314,10 @@ bool HongKangParser::augmentWithSpice(Image& image, return false; } -void HongKangParser::createImage(Image& image, double startTime, double stopTime, std::vector instr, std::string targ, std::string pot) { +void HongKangParser::createImage(Image& image, double startTime, double stopTime, std::vector instr, std::string targ, std::string path) { image.startTime = startTime; image.stopTime = stopTime; - image.path = pot; + image.path = path; for (int i = 0; i < instr.size(); i++){ image.activeInstruments.push_back(instr[i]); } diff --git a/src/util/imagesequencer.cpp b/src/util/imagesequencer.cpp index db2ee3c0b7..6ccbbb56ef 100644 --- a/src/util/imagesequencer.cpp +++ b/src/util/imagesequencer.cpp @@ -23,7 +23,6 @@ ****************************************************************************************/ // open space includes -#include #include #include #include diff --git a/src/util/imagesequencer2.cpp b/src/util/imagesequencer2.cpp index a9e2e10567..ccf3dfa4f7 100644 --- a/src/util/imagesequencer2.cpp +++ b/src/util/imagesequencer2.cpp @@ -49,7 +49,6 @@ _hasData(false), _defaultCaptureImage(absPath("C:/Users/michal/openspace/openspace-data/scene/common/textures/placeholder_blank.png")) {} - ImageSequencer2& ImageSequencer2::ref() { assert(_instance != nullptr); return *_instance; @@ -68,22 +67,6 @@ bool ImageSequencer2::isReady(){ return _hasData; } -bool ImageSequencer2::imageComparer(const Image &a, const Image &b){ - return a.startTime < b.startTime; -}; - -std::vector::iterator ImageSequencer2::binary_find(std::vector::iterator begin, - std::vector::iterator end, - const Image &val, - bool(*compareFunc)(const Image &a, const Image &b)){ - // Finds the lower bound in at most log(last - first) + 1 comparisons - std::vector::iterator it = std::lower_bound(begin, end, val, compareFunc); - if (it != begin && it != end){ - return it; - } - return end; -} - void ImageSequencer2::updateSequencer(double time){ if (_currentTime != time){ _previousTime = _currentTime; @@ -92,7 +75,6 @@ void ImageSequencer2::updateSequencer(double time){ } std::pair ImageSequencer2::getNextTarget(){ - // make into template func auto compareTime = [](const std::pair &a, const std::pair &b)->bool{ return a.first < b.first; @@ -101,22 +83,21 @@ std::pair ImageSequencer2::getNextTarget(){ findEqualToThis.first = _currentTime; auto it = std::lower_bound(_targetTimes.begin(), _targetTimes.end(), findEqualToThis, compareTime); - if (it != _targetTimes.end()){ + if (it != _targetTimes.end() && it != _targetTimes.begin()){ return (*it); } } std::pair ImageSequencer2::getCurrentTarget(){ - // make into template func auto compareTime = [](const std::pair &a, - const std::pair &b)->bool{ + const std::pair &b)->bool{ return a.first < b.first; }; std::pair findEqualToThis; findEqualToThis.first = _currentTime; auto it = std::lower_bound(_targetTimes.begin(), _targetTimes.end(), findEqualToThis, compareTime); - if (it != _targetTimes.end()){ + if (it != _targetTimes.end() && it != _targetTimes.begin() ){ return *std::prev(it); } } @@ -125,21 +106,26 @@ std::pair> ImageSequencer2::getIncidentTargetLi std::pair> incidentTargets; auto compareTime = [](const std::pair &a, - const std::pair &b)->bool{ - return a.first < b.first; + const std::pair &b)->bool{ + return a.first < b.first; }; + // what to look for std::pair findEqualToThis; findEqualToThis.first = _currentTime; auto it = std::lower_bound(_targetTimes.begin(), _targetTimes.end(), findEqualToThis, compareTime); - std::advance(it, -(range+1)); + if (it != _targetTimes.end() && it != _targetTimes.begin()){ + // move the iterator to the first element of the range + std::advance(it, -(range + 1)); - for (int i = 0; i < 2*range+1; i++){ - incidentTargets.first = it->first; - incidentTargets.second.push_back(it->second); - it++; - if (it == _targetTimes.end()) - break; + // now extract incident range + for (int i = 0; i < 2 * range + 1; i++){ + incidentTargets.first = it->first; + incidentTargets.second.push_back(it->second); + it++; + if (it == _targetTimes.end()) + break; + } } return incidentTargets; @@ -166,29 +152,36 @@ double ImageSequencer2::getNextCaptureTime(){ return nextCaptureTime; } -std::vector> ImageSequencer2::getActiveInstruments(){ - for (int i = 0; i < _instrumentOnOff.size(); i++){ - _instrumentOnOff[i].second = false; - } +std::map ImageSequencer2::getActiveInstruments(){ + // first set all instruments to off + for (auto i : _switchingMap) + _switchingMap[i.first] = false; + // go over the filetranslation map for (auto key : _fileTranslation){ + // for each spice-instrument for (auto instrumentID : key.second->getTranslation()){ + // check if the spice-instrument is active if (instumentActive(instrumentID)){ - for (int i = 0; i < _instrumentOnOff.size(); i++){ - if (instrumentID == _instrumentOnOff[i].first){ - _instrumentOnOff[i].second = true; + // go over switching map + for (auto instrument : _switchingMap){ + // if instrument is present in switching map + if (instrumentID == instrument.first){ + // set as active + _switchingMap[instrumentID] = true; } } } } } - return _instrumentOnOff; + // return entire map, seen in GUI. + return _switchingMap; } -bool ImageSequencer2::instumentActive(std::string instrumentID){ +bool ImageSequencer2::instumentActive(std::string instrumentID){ for (auto i : _instrumentTimes){ //check if this instrument is in range - if (i.second.inRange(_currentTime)){ - //if so, then get the corresponding spiceIDs - std::vector < std::string> spiceIDs = _fileTranslation[i.first]->getTranslation(); + if (i.second.inRange(_currentTime)){ + //if so, then get the corresponding spiceID + std::vector spiceIDs = _fileTranslation[i.first]->getTranslation(); //check which specific subinstrument is firing for (auto s : spiceIDs){ if (s == instrumentID){ @@ -199,65 +192,115 @@ bool ImageSequencer2::instumentActive(std::string instrumentID){ } return false; } -bool ImageSequencer2::getImagePaths(std::vector>& captures, std::string projectee, std::string instrumentID){ +bool ImageSequencer2::getImagePaths(std::vector>& captures, + std::string projectee, + std::string instrumentID){ + if (!instumentActive(instrumentID) && !Time::ref().timeJumped()) return false; + // developer note: this is only due to LORRI being the only instrument implemented so far. return (instrumentID == "NH_LORRI") ? getImagePaths(captures, projectee) : false; } bool ImageSequencer2::getImagePaths(std::vector>& captures, std::string projectee){ + + // check if this instance is either in range or + // a valid candidate to recieve data + + if (!Time::ref().timeJumped() && projectee == getCurrentTarget().second) if (_subsetMap[projectee]._range.inRange(_currentTime) || _subsetMap[projectee]._range.inRange(_previousTime)){ auto compareTime = [](const Image &a, - const Image &b)->bool{ + const Image &b)->bool{ return a.startTime < b.startTime; }; - - auto begin = _subsetMap[projectee]._subset.begin(); - auto end = _subsetMap[projectee]._subset.end(); - + + // for readability we store the iterators + auto begin = _subsetMap[projectee]._subset.begin(); + auto end = _subsetMap[projectee]._subset.end(); + + // create temporary storage std::vector> captureTimes; - Image findPrevious; + // what to look for + Image findPrevious, findCurrent; findPrevious.startTime = _previousTime; - Image findCurrent; - findCurrent.startTime = _currentTime; + findCurrent.startTime = _currentTime; + // find the two iterators that correspond to the latest time jump auto curr = std::lower_bound(begin, end, findCurrent, compareTime); auto prev = std::lower_bound(begin, end, findPrevious, compareTime); if (curr != begin && curr != end && prev != begin && prev != end){ - std::transform(prev, curr, std::back_inserter(captureTimes), - [](const Image& i) { - return std::make_pair(i.startTime, i.path); - }); - std::reverse(captureTimes.begin(), captureTimes.end()); - captures = captureTimes; - return true; + if (curr->startTime >= prev->startTime){ + // insert + std::transform(prev, curr, std::back_inserter(captureTimes), + [](const Image& i) { + return std::make_pair(i.startTime, i.path); + }); + std::reverse(captureTimes.begin(), captureTimes.end()); + + captures = captureTimes; + return true; + } } } return false; } +void ImageSequencer2::sortData(){ + auto targetComparer = [](const std::pair &a, + const std::pair &b)->bool{ + return a.first < b.first; + }; + auto imageComparer = [](const Image &a, const Image &b)->bool{ + return a.startTime < b.startTime; + }; + std::sort(_targetTimes.begin(), _targetTimes.end(), targetComparer); + std::stable_sort(_captureProgression.begin(), _captureProgression.end()); + + for (auto sub : _subsetMap){ + std::sort(_subsetMap[sub.first]._subset.begin(), + _subsetMap[sub.first]._subset.end(), imageComparer); + } +} void ImageSequencer2::runSequenceParser(SequenceParser* parser){ parser->create(); - _fileTranslation = parser->getTranslation(); // should perhaps be named 'instrumentTranslation' - _subsetMap = parser->getSubsetMap(); - _instrumentTimes = parser->getIstrumentTimes(); - _targetTimes = parser->getTargetTimes(); - _captureProgression = parser->getCaptureProgression(); + // get new data + std::map in1 = parser->getTranslation(); + std::map in2 = parser->getSubsetMap(); + std::vector> in3 = parser->getIstrumentTimes(); + std::vector> in4 = parser->getTargetTimes(); + std::vector in5 = parser->getCaptureProgression(); + + // check for sanity + assert(in1.size() > 0, "Sequencer failed to load Translation" ); + assert(in2.size() > 0, "Sequencer failed to load Image data" ); + assert(in3.size() > 0, "Sequencer failed to load Instrument Switching schedule"); + assert(in4.size() > 0, "Sequencer failed to load Target Switching schedule" ); + assert(in5.size() > 0, "Sequencer failed to load Capture progression" ); - //copy payload from _fileTranslation + + // append data + _fileTranslation.insert ( in1.begin(), in1.end()); + _subsetMap.insert ( in2.begin(), in2.end()); + _instrumentTimes.insert ( _instrumentTimes.end(), in3.begin(), in3.end()); + _targetTimes.insert ( _targetTimes.end(), in4.begin(), in4.end()); + _captureProgression.insert(_captureProgression.end(), in5.begin(), in5.end()); + + // sorting of data _not_ optional + sortData(); + + // extract payload from _fileTranslation for (auto t : _fileTranslation){ - std::vector spiceIDs = t.second->getTranslation(); - for (auto id : spiceIDs){ - _instrumentOnOff.push_back(std::make_pair(id, false)); + if (t.second->getDecoderType() == "CAMERA" || + t.second->getDecoderType() == "SCANNER" ){ + std::vector spiceIDs = t.second->getTranslation(); + for (auto id : spiceIDs){ + _switchingMap[id] = false; + } } } - _instrumentOnOff.erase(std::unique(_instrumentOnOff.begin(), - _instrumentOnOff.end()), - _instrumentOnOff.end()); _hasData = true; - } } // namespace openspace diff --git a/src/util/instrumentdecoder.cpp b/src/util/instrumentdecoder.cpp index e2370ed5e1..c062ce0df0 100644 --- a/src/util/instrumentdecoder.cpp +++ b/src/util/instrumentdecoder.cpp @@ -28,6 +28,7 @@ namespace { const std::string _loggerCat = "InstrumentDecoder"; const std::string keyDetector = "DetectorType"; const std::string keySpice = "Spice"; + const std::string keyStopCommand = "StopCommand"; } namespace openspace { @@ -38,6 +39,12 @@ InstrumentDecoder::InstrumentDecoder(const ghoul::Dictionary& dictionary) ghoul_assert(success, "Instrument has not provided detector type"); for_each(_type.begin(), _type.end(), [](char& in){ in = ::toupper(in); }); + if (!dictionary.hasKeyAndValue(keyStopCommand) && _type == "SCANNER"){ + LWARNING("Scanner must provide stop command, please check mod file."); + }else{ + dictionary.getValue(keyStopCommand, _stopCommand); + } + std::vector spice; ghoul::Dictionary spiceDictionary; success = dictionary.getValue(keySpice, spiceDictionary); @@ -52,6 +59,10 @@ InstrumentDecoder::InstrumentDecoder(const ghoul::Dictionary& dictionary) } } +std::string InstrumentDecoder::getStopCommand(){ + return _stopCommand; +} + std::string InstrumentDecoder::getDecoderType(){ return _type; } diff --git a/src/util/labelparser.cpp b/src/util/labelparser.cpp index 9ecf1293d9..9a0f7a39a2 100644 --- a/src/util/labelparser.cpp +++ b/src/util/labelparser.cpp @@ -45,9 +45,7 @@ namespace openspace { LabelParser::LabelParser(const std::string& fileName, ghoul::Dictionary translationDictionary) { - _fileName = fileName; - //_fileTranslation = fileTranslation; - + _fileName = fileName; //get the different instrument types const std::vector& decoders = translationDictionary.keys(); //for each decoder (assuming might have more if hong makes changes) @@ -95,18 +93,27 @@ LabelParser::LabelParser(const std::string& fileName, }; } } - for (auto t : _fileTranslation){ - std::cout << t.first << std::endl; - for (auto b : t.second->getTranslation()){ - std::cout << " " << b << std::endl; +} + +std::string LabelParser::decode(std::string line){ + for (auto key : _fileTranslation){ + std::size_t value = line.find(key.first); + if (value != std::string::npos){ + std::string toTranslate = line.substr(value); + return _fileTranslation[toTranslate]->getTranslation()[0]; //lbls always 1:1 -> single value return. } } - } + void LabelParser::create(){ - - std::vector tmp; - + auto imageComparer = [](const Image &a, const Image &b)->bool{ + return a.startTime < b.startTime; + }; + auto targetComparer = [](const std::pair &a, + const std::pair &b)->bool{ + return a.first < b.first; + }; + std::string previousTarget; ghoul::filesystem::Directory sequenceDir(_fileName, true); std::vector sequencePaths = sequenceDir.read(true, false); // check inputs @@ -121,44 +128,130 @@ void LabelParser::create(){ if (!file.good()) LERROR("Failed to open label file '" << currentFile.path() << "'"); + int count = 0; + // open up label files std::string line = ""; - double timestamp = 0.0; - bool found = false; + std::string previousSequence; + TimeRange instrumentRange; + do { std::getline(file, line); - for (auto spec : _specsOfInterest){ - auto pos = line.find(spec); - if (pos != std::string::npos){ - if (line.substr(0, line.find_first_of(" ")) == "TARGET_NAME"){ - /* std::string target = line.substr(line.find("=") + 2, line.find(" ")); - target.erase(std::remove(target.begin(), target.end(), '"'), target.end()); - for (auto t : _fileTranslation[target]->getTranslation()){ - std::cout << t << std::endl; - }*/ - } + std::string read = line.substr(0, line.find_first_of(" ")); + line.erase(std::remove(line.begin(), line.end(), '"'), line.end()); + line.erase(std::remove(line.begin(), line.end(), ' '), line.end()); + /* Add more */ + if (read == "TARGET_NAME"){ + _target = decode(line); + count++; + } + if (read == "INSTRUMENT_HOST_NAME"){ + _instrumentHostID = decode(line); + count++; + } + if (read == "INSTRUMENT_ID"){ + _instrumentID = decode(line); + count++; + } + if (read == "DETECTOR_TYPE"){ + _detectorType = decode(line); + count++; + } + if (read == "START_TIME"){ + std::string start = line.substr(line.find("=") + 2); + start.erase(std::remove(start.begin(), start.end(), ' '), start.end()); + openspace::SpiceManager::ref().getETfromDate(start, _startTime); + count++; + + getline(file, line); + read = line.substr(0, line.find_first_of(" ")); + if (read == "STOP_TIME"){ + std::string stop = line.substr(line.find("=") + 2); + stop.erase(std::remove(stop.begin(), stop.end(), ' '), stop.end()); + openspace::SpiceManager::ref().getETfromDate(stop, _stopTime); + count++; } - /*if (timestamp != 0.0){ - found = true; + else{ + LERROR("Label file " + _fileName + " deviates from generic standard!"); + LINFO("Please make sure input data adheres to format https://pds.jpl.nasa.gov/documents/qs/labels.html"); + } + } + if (count == _specsOfInterest.size()){ + count = 0; std::string ext = "jpg"; path.replace(path.begin() + position, path.end(), ext); bool fileExists = FileSys.fileExists(path); if (fileExists) { - // createImage(tmp, timestamp, "NH_LORRI", "", path); /// fix active instrument! - // std::sort(tmp.begin(), tmp.end(), imageComparer); + Image image; + std::vector spiceInstrument; + spiceInstrument.push_back(_instrumentID); + createImage(image, _startTime, _startTime, spiceInstrument, _target, path); + + _subsetMap[image.target]._subset.push_back(image); + _subsetMap[image.target]._range.setRange(_startTime); + + _captureProgression.push_back(_startTime); + std::stable_sort(_captureProgression.begin(), _captureProgression.end()); } - }*/ + } - } while (!file.eof() && found == false); + } while (!file.eof()); } } } } - int pause; - std::cin >> pause; + + std::vector tmp; + for (auto key : _subsetMap){ + for (auto image : key.second._subset){ + tmp.push_back(image); + } + } + std::sort(tmp.begin(), tmp.end(), imageComparer); + + for (auto image : tmp){ + if (previousTarget != image.target){ + previousTarget = image.target; + std::pair v_target = std::make_pair(image.startTime, image.target); + _targetTimes.push_back(v_target); + std::sort(_targetTimes.begin(), _targetTimes.end(), targetComparer); + } + } + + std::ofstream myfile; + myfile.open("LabelFileOutput.txt"); + + //print all + for (auto target : _subsetMap){ + _instrumentTimes.push_back(std::make_pair("LORRI", _subsetMap[target.first]._range)); + std::string min, max; + SpiceManager::ref().getDateFromET(target.second._range._min, min); + SpiceManager::ref().getDateFromET(target.second._range._max, max); + + myfile << std::endl; + for (auto image : target.second._subset){ + std::string time_beg; + std::string time_end; + SpiceManager::ref().getDateFromET(image.startTime, time_beg); + SpiceManager::ref().getDateFromET(image.stopTime, time_end); + + myfile << std::fixed + << " " << time_beg + << "-->" << time_end + << " [ " << image.startTime + << " ] " << image.target << std::setw(10); + for (auto instrument : image.activeInstruments){ + myfile << " " << instrument; + } + myfile << std::endl; + } + } + myfile.close(); + + } void LabelParser::createImage(Image& image, double startTime, double stopTime, std::vector instr, std::string targ, std::string pot) { diff --git a/src/util/scannerdecoder.cpp b/src/util/scannerdecoder.cpp index e707bd8e99..953e183e8f 100644 --- a/src/util/scannerdecoder.cpp +++ b/src/util/scannerdecoder.cpp @@ -46,4 +46,8 @@ std::vector ScannerDecoder::getSpiceIDs(){ return _spiceIDs; } +void ScannerDecoder::setStopCommand(std::string stopCommand){ + _abort = stopCommand; +} + } // namespace openspace \ No newline at end of file From 2ad3b58898a35c5a5ab2e432fc74787cb1a139ce Mon Sep 17 00:00:00 2001 From: Michal Marcinkowski Date: Wed, 22 Apr 2015 22:01:50 -0400 Subject: [PATCH 26/45] Imagesequencer update: - label/image data works - fixed issues with instrument firing - read handled in more uniform way - adding ALICE scanner - distance fading in renderabletrail (WIP) - essential fixes to renderableFOV - and additional changes to other classes reliant on imagesequenser. --- src/util/imagesequencer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/imagesequencer.cpp b/src/util/imagesequencer.cpp index 0eca0205f1..a2541beb9a 100644 --- a/src/util/imagesequencer.cpp +++ b/src/util/imagesequencer.cpp @@ -23,6 +23,7 @@ ****************************************************************************************/ // open space includes +#include #include #include #include From 59ab26848988e2427fcdcd00d80fc5feac28eb38 Mon Sep 17 00:00:00 2001 From: Michal Marcinkowski Date: Thu, 23 Apr 2015 00:13:11 -0400 Subject: [PATCH 27/45] restore back some previous code --- openspace-data | 2 +- src/rendering/renderengine.cpp | 13 +++++++------ src/scenegraph/spiceephemeris.cpp | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/openspace-data b/openspace-data index de36eeeb00..f39bdf433e 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit de36eeeb000a6345bd6d63f21bf9c705e01ddfc0 +Subproject commit f39bdf433e9f8e85ded9be7375c2c2e7d0050923 diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index fce275c30a..74ad614e83 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -973,7 +973,7 @@ void RenderEngine::changeViewPoint(std::string origin) { SceneGraphNode* solarSystemBarycenterNode = sceneGraph()->sceneGraphNode("SolarSystemBarycenter"); SceneGraphNode* plutoBarycenterNode = sceneGraph()->sceneGraphNode("PlutoBarycenter"); SceneGraphNode* newHorizonsNode = sceneGraph()->sceneGraphNode("NewHorizons"); - SceneGraphNode* newHorizonsGhostNode = sceneGraph()->sceneGraphNode("NewHorizonsGhost"); + //SceneGraphNode* newHorizonsGhostNode = sceneGraph()->sceneGraphNode("NewHorizonsGhost"); SceneGraphNode* jupiterBarycenterNode = sceneGraph()->sceneGraphNode("JupiterBarycenter"); if (solarSystemBarycenterNode == nullptr || plutoBarycenterNode == nullptr || newHorizonsNode == nullptr || jupiterBarycenterNode == nullptr) { @@ -1012,7 +1012,7 @@ void RenderEngine::changeViewPoint(std::string origin) { { std::string("Kernels"), ghoul::Dictionary() } }; newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary)); - + /* ghoul::Dictionary newHorizonsGhostDictionary = { { std::string("Type"), std::string("Spice") }, @@ -1022,7 +1022,7 @@ void RenderEngine::changeViewPoint(std::string origin) { { std::string("Kernels"), ghoul::Dictionary() } }; newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary)); - + */ return; } if (origin == "Sun") { @@ -1056,7 +1056,7 @@ void RenderEngine::changeViewPoint(std::string origin) { { std::string("Kernels"), ghoul::Dictionary() } }; newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary)); - + /* ghoul::Dictionary newHorizonsGhostDictionary = { { std::string("Type"), std::string("Spice") }, @@ -1066,7 +1066,7 @@ void RenderEngine::changeViewPoint(std::string origin) { { std::string("Kernels"), ghoul::Dictionary() } }; newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary)); - + */ return; } if (origin == "Jupiter") { @@ -1100,7 +1100,7 @@ void RenderEngine::changeViewPoint(std::string origin) { { std::string("Kernels"), ghoul::Dictionary() } }; newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary)); - + /* ghoul::Dictionary newHorizonsGhostDictionary = { { std::string("Type"), std::string("Spice") }, @@ -1110,6 +1110,7 @@ void RenderEngine::changeViewPoint(std::string origin) { { std::string("Kernels"), ghoul::Dictionary() } }; newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary)); + */ return; } diff --git a/src/scenegraph/spiceephemeris.cpp b/src/scenegraph/spiceephemeris.cpp index cb7776611b..577c716e1f 100644 --- a/src/scenegraph/spiceephemeris.cpp +++ b/src/scenegraph/spiceephemeris.cpp @@ -74,17 +74,17 @@ void SpiceEphemeris::update(const UpdateData& data) { glm::dvec3 position(0,0,0); double lightTime = 0.0; - if (_targetName != "NEW HORIZONS GHOST") + //if (_targetName != "NEW HORIZONS GHOST") SpiceManager::ref().getTargetPosition(_targetName, _originName, "GALACTIC", "NONE", data.time, position, lightTime); - + /* double interval = openspace::ImageSequencer2::ref().getIntervalLength(); if (_targetName == "NEW HORIZONS GHOST" && interval > 60){ double _time = openspace::ImageSequencer2::ref().getNextCaptureTime(); SpiceManager::ref().getTargetPosition("NEW HORIZONS", _originName, "GALACTIC", "NONE", _time, position, lightTime); } - + */ _position = psc::CreatePowerScaledCoordinate(position.x, position.y, position.z); _position[3] += 3; } From 632025c2a0f092998ca07d85d3aa9b0fe74bd8d5 Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Fri, 24 Apr 2015 17:55:48 -0400 Subject: [PATCH 28/45] Miinor bugfix, get position of body instead of frame --- src/rendering/model/renderablemodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rendering/model/renderablemodel.cpp b/src/rendering/model/renderablemodel.cpp index 5f5c97c5b7..79dbc20762 100644 --- a/src/rendering/model/renderablemodel.cpp +++ b/src/rendering/model/renderablemodel.cpp @@ -169,7 +169,7 @@ void RenderableModel::render(const RenderData& data) { _alpha = 1.0f; psc tmppos; - SpiceManager::ref().getTargetPosition(_source, "SUN", "GALACTIC", "NONE", time, tmppos, lt); + SpiceManager::ref().getTargetPosition(_target, "SUN", "GALACTIC", "NONE", time, tmppos, lt); glm::vec3 cam_dir = glm::normalize(data.camera.position().vec3() - tmppos.vec3()); _programObject->setUniform("cam_dir", cam_dir); _programObject->setUniform("transparency", _alpha); From 4f8c1e4a146cd7260c3b1911f45a558478ea06ed Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 2 May 2015 22:24:03 +0200 Subject: [PATCH 29/45] Added methods to Hongkang parser that publish the results More changes to the TImeline GUI --- gui/timelineview/common.h | 35 +++++ gui/timelineview/mainwindow.cpp | 115 ++++++++++++++- gui/timelineview/mainwindow.h | 3 + gui/timelineview/timelinewidget.cpp | 155 ++++++++++++++++++++- gui/timelineview/timelinewidget.h | 24 ++++ include/openspace/engine/openspaceengine.h | 1 + include/openspace/network/networkengine.h | 37 ++++- include/openspace/util/hongkangparser.h | 1 + src/engine/openspaceengine.cpp | 7 +- src/main.cpp | 1 - src/network/networkengine.cpp | 128 +++++++++++++++-- src/util/hongkangparser.cpp | 121 ++++++++++++++++ 12 files changed, 602 insertions(+), 26 deletions(-) create mode 100644 gui/timelineview/common.h diff --git a/gui/timelineview/common.h b/gui/timelineview/common.h new file mode 100644 index 0000000000..2588afda3a --- /dev/null +++ b/gui/timelineview/common.h @@ -0,0 +1,35 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 __COMMON_H__ +#define __COMMON_H__ + +struct Image { + double beginning; + double ending; + std::string target; + std::vector instruments; +}; + +#endif // __COMMON_H__ diff --git a/gui/timelineview/mainwindow.cpp b/gui/timelineview/mainwindow.cpp index a6b2bb9b24..845a719e89 100644 --- a/gui/timelineview/mainwindow.cpp +++ b/gui/timelineview/mainwindow.cpp @@ -36,6 +36,28 @@ #include #include +template +T readFromBuffer(char* buffer, size_t& currentReadLocation) { + union { + T value; + std::array data; + } b; + std::memmove(b.data.data(), buffer + currentReadLocation, sizeof(T)); + currentReadLocation += sizeof(T); + return b.value; +} + +template <> +std::string readFromBuffer(char* buffer, size_t& currentReadLocation) { + uint8_t size = readFromBuffer(buffer, currentReadLocation); + + std::string result(buffer + currentReadLocation, buffer + currentReadLocation + size); + currentReadLocation += size; + return result; +} + + + MainWindow::MainWindow() : QWidget(nullptr) , _configurationWidget(nullptr) @@ -82,24 +104,52 @@ void MainWindow::onConnect(QString host, QString port) { _socket = new QTcpSocket(this); connect(_socket, SIGNAL(readyRead()), SLOT(readTcpData())); _socket->connectToHost(host, port.toUInt()); + + _socket->write(QString("1\r\n").toLatin1()); } void MainWindow::readTcpData() { - static const uint8_t MessageTypeStatus = 0; + static const uint16_t MessageTypeStatus = 0; + static const uint16_t MessageTypePlayBook = 2; QByteArray data = _socket->readAll(); + //QString debug(data); + //qDebug() << debug; + if (QString(data) == "Connected to SGCT!\r\n") return; if (QString(data) == "OK\r\n") return; - uint8_t messageType = data[0]; + QByteArray messageTypeData = data.left(2); + union { + uint16_t value; + std::array data; + } messageType; + std::memcpy(messageType.data.data(), messageTypeData.data(), sizeof(uint16_t)); - if (messageType == MessageTypeStatus) - handleStatusMessage(data.mid(1)); - handleStatusMessage(data.right(data.length() - 1)); + switch (messageType.value) { + case MessageTypeStatus: + handleStatusMessage(data.mid(2)); + break; + case MessageTypePlayBook: + { + const char* payloadDebug = data.mid(2).data(); + + size_t beginning = 0; + uint32_t size = readFromBuffer(data.mid(2).data(), beginning); + + while (_socket->waitForReadyRead() && data.size() < size) { + data = data.append(_socket->readAll()); + } + handlePlaybook(data.mid(2)); + break; + } + default: + qDebug() << "Unknown message of type '" << messageType.value << "'"; + } } void MainWindow::handleStatusMessage(QByteArray data) { @@ -124,8 +174,63 @@ void MainWindow::handleStatusMessage(QByteArray data) { QString::fromStdString(std::string(timeString.begin(), timeString.end())), QString::number(delta.value) ); + _timelineWidget->setCurrentTime(std::string(timeString.begin(), timeString.end())); } +std::vector instrumentsFromId(uint16_t instrumentId, std::map instrumentMap) { + std::vector results; + for (int i = 0; i < 16; ++i) { + uint16_t testValue = 1 << i; + if ((testValue & instrumentId) == 1) + results.push_back(instrumentMap[testValue]); + } + return results; +} + +void MainWindow::handlePlaybook(QByteArray data) { + char* buffer = data.data(); + size_t currentReadLocation = 0; + + uint32_t totalData = readFromBuffer(buffer, currentReadLocation); + + uint8_t nTargets = readFromBuffer(buffer, currentReadLocation); + std::map targetMap; + for (uint8_t i = 0; i < nTargets; ++i) { + uint8_t id = readFromBuffer(buffer, currentReadLocation); + std::string value = readFromBuffer(buffer, currentReadLocation); + targetMap[id] = value; + } + + uint8_t nInstruments = readFromBuffer(buffer, currentReadLocation); + std::map instrumentMap; + for (uint8_t i = 0; i < nInstruments; ++i) { + uint8_t id = readFromBuffer(buffer, currentReadLocation); + std::string value = readFromBuffer(buffer, currentReadLocation); + instrumentMap[id] = value; + } + + uint32_t nImages = readFromBuffer(buffer, currentReadLocation); + std::vector images; + for (uint32_t i = 0; i < nImages; ++i) { + Image image; + image.beginning = readFromBuffer(buffer, currentReadLocation); + image.ending = readFromBuffer(buffer, currentReadLocation); + + image.beginningString = readFromBuffer(buffer, currentReadLocation); + image.endingString = readFromBuffer(buffer, currentReadLocation); + + uint8_t targetId = readFromBuffer(buffer, currentReadLocation); + uint16_t instrumentId = readFromBuffer(buffer, currentReadLocation); + image.target = targetMap[targetId]; + image.instruments = instrumentsFromId(instrumentId, instrumentMap); + images.push_back(image); + } + + _timelineWidget->setData(std::move(images), std::move(targetMap), std::move(instrumentMap)); +} + + void MainWindow::sendScript(QString script) { _socket->write(("0" + script + "\r\n").toLatin1()); } + diff --git a/gui/timelineview/mainwindow.h b/gui/timelineview/mainwindow.h index 9fdd10b1d3..cb9ada8a8b 100644 --- a/gui/timelineview/mainwindow.h +++ b/gui/timelineview/mainwindow.h @@ -28,6 +28,8 @@ #include #include +#include "common.h" + class ConfigurationWidget; class TimeControlWidget; class InformationWidget; @@ -49,6 +51,7 @@ private slots: //void sendCommandButton(); void readTcpData(); void handleStatusMessage(QByteArray data); + void handlePlaybook(QByteArray data); private: ConfigurationWidget* _configurationWidget; diff --git a/gui/timelineview/timelinewidget.cpp b/gui/timelineview/timelinewidget.cpp index 7028482f30..5f064a0619 100644 --- a/gui/timelineview/timelinewidget.cpp +++ b/gui/timelineview/timelinewidget.cpp @@ -24,19 +24,166 @@ #include "timelinewidget.h" +#include #include #include +#include + +namespace { + static const int LegendHeight = 105; + static const int TimeWidth = 150; + + const QColor targetColors[] = { + QColor(251, 180, 174), + QColor(179, 205, 227), + QColor(204, 235, 197), + QColor(222, 203, 228), + QColor(254, 217, 166), + QColor(255, 255, 204) + }; + + const QColor instrumentColors[] = { + QColor(228, 26, 28), + QColor(55, 126, 184), + QColor(77, 175, 74), + QColor(152, 78, 163), + QColor(255, 127, 0), + QColor(255, 255, 51), + QColor(166, 86, 40), + QColor(247, 129, 191), + QColor(153, 153, 153), + }; + + const double etSpread = 100.0; +} + TimelineWidget::TimelineWidget(QWidget* parent) : QWidget(parent) { - setMinimumWidth(300); - setMinimumHeight(500); + setMinimumWidth(600); + setMinimumHeight(600); } void TimelineWidget::paintEvent(QPaintEvent* event) { QPainter painter(this); - painter.setBrush(QBrush(Qt::white)); - painter.drawRect(contentsRect()); + QRectF fullRect = contentsRect(); + QRectF contentRect(0, 0, fullRect.width() - 1, fullRect.height() - LegendHeight); + QRectF legendRect(0, fullRect.bottom() - LegendHeight, fullRect.right(), fullRect.bottom()); + + painter.save(); + drawContent(painter, contentRect); + painter.restore(); + + painter.save(); + painter.translate(0, fullRect.height() - LegendHeight); + drawLegend(painter, QRectF(legendRect)); + painter.restore(); } + +void TimelineWidget::setData(std::vector images, std::map targetMap, std::map instrumentMap) { + _images = std::move(images); + + std::sort(_images.begin(), _images.end(), [](const Image& a, const Image& b) { return a.beginning < b.beginning; }); + + _targetMap = std::move(targetMap); + _instrumentMap = std::move(instrumentMap); + + _instruments.clear(); + std::set instruments; + for (auto p : _instrumentMap) + instruments.insert(p.second); + std::copy(instruments.begin(), instruments.end(), std::back_inserter(_instruments)); + + _targets.clear(); + std::set targets; + for (auto p : _targetMap) + targets.insert(p.second); + std::copy(targets.begin(), targets.end(), std::back_inserter(_targets)); + + repaint(); +} + +void TimelineWidget::drawContent(QPainter& painter, QRectF rect) { + QRectF timelineRect(0, 0, rect.width() - TimeWidth, rect.height()); + QRectF dateRect(rect.width() - TimeWidth, 0, TimeWidth, rect.height()); + + // Draw background + painter.setBrush(QBrush(Qt::white)); painter.drawRect(timelineRect); + painter.setBrush(QBrush(Qt::gray)); painter.drawRect(dateRect); + + // Draw current time + painter.setBrush(QBrush(Qt::black)); + painter.drawLine(QPointF(0, timelineRect.height() / 2), QPointF(timelineRect.width(), timelineRect.height() / 2)); + painter.drawText(timelineRect.width(), timelineRect.height() / 2, QString::fromStdString(_currentTime.time)); + + + const double lowerTime = _currentTime.et - etSpread; + const double upperTime = _currentTime.et + etSpread; + + std::vector::const_iterator start = _images.end(); + std::vector::const_iterator end = _images.end(); + for (std::vector::const_iterator it = _images.begin(); it != _image.end(); ++it) { + if (it->beginning > lowerTime + } + + //std::vector::const_iterator lower = std::lower_bound(_images.begin(), _images.end(), lowerTime, [lowerTime](const Image& i) { return i.beginning < lowerTime; }); + ////std::vector::const_iterator upper = std::lower_bound(_images.begin(), _iamges.end(), upperTime) + + + +} + +void TimelineWidget::drawLegend(QPainter& painter, QRectF rect) { + static const int HalfHeight = LegendHeight / 2; + static const int Padding = 5; + static const int BoxSize = 20; + + // Draw Targets + int currentHorizontalPosition = Padding; + int currentVerticalPosition = Padding; + for (int i = 0; i < _targets.size(); ++i) { + + const std::string& target = _targets[i]; + + painter.setBrush(QBrush(targetColors[i])); + painter.drawRect(currentHorizontalPosition, currentVerticalPosition, BoxSize, BoxSize); + currentHorizontalPosition += BoxSize + Padding; + + painter.drawText(currentHorizontalPosition, currentVerticalPosition + BoxSize / 2, QString::fromStdString(target)); + int textWidth = painter.boundingRect(QRect(), QString::fromStdString(target)).width(); + currentHorizontalPosition += std::max(textWidth, 25) + Padding; + } + + // Draw Instruments + currentHorizontalPosition = Padding; + currentVerticalPosition = Padding + BoxSize + Padding; + for (int i = 0; i < _instruments.size(); ++i) { + if (i == _instruments.size() / 3 || i == _instruments.size() * 2 / 3) { + currentVerticalPosition += BoxSize + Padding; + currentHorizontalPosition = Padding; + } + + const std::string& instrument = _instruments[i]; + + //painter.setBrush(QBrush(instrumentColors[i])); + painter.setBrush(Qt::NoBrush); + painter.setPen(QPen(instrumentColors[i])); + painter.drawRect(currentHorizontalPosition, currentVerticalPosition, BoxSize, BoxSize); + currentHorizontalPosition += BoxSize + Padding; + + painter.setPen(QPen(Qt::black)); + painter.drawText(currentHorizontalPosition, currentVerticalPosition + BoxSize / 2, QString::fromStdString(instrument)); + int textWidth = painter.boundingRect(QRect(), QString::fromStdString(instrument)).width(); + currentHorizontalPosition += std::max(textWidth, 25) + Padding; + } +} + +void TimelineWidget::setCurrentTime(std::string currentTime, double et) { + _currentTime.time = std::move(currentTime); + _currentTime.et = std::move(et); + repaint(); + +} + diff --git a/gui/timelineview/timelinewidget.h b/gui/timelineview/timelinewidget.h index def40ffe6c..33c455b3eb 100644 --- a/gui/timelineview/timelinewidget.h +++ b/gui/timelineview/timelinewidget.h @@ -27,6 +27,12 @@ #include +#include "common.h" + +#include +#include +#include + class QPaintEvent; class TimelineWidget : public QWidget { @@ -34,9 +40,27 @@ Q_OBJECT public: TimelineWidget(QWidget* parent); + void setData(std::vector images, std::map targetMap, std::map instrumentMap); + void setCurrentTime(std::string currentTime, double et); + protected: void paintEvent(QPaintEvent* event); + void drawContent(QPainter& painter, QRectF rect); + void drawLegend(QPainter& painter, QRectF rect); + +private: + std::vector _images; + std::map _targetMap; + std::map _instrumentMap; + + std::vector _targets; + std::vector _instruments; + + struct { + std::string time; + double et; + } _currentTime; }; #endif // __TIMELINEWIDGET_H__ diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 2beeafa486..155a9f9e33 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -69,6 +69,7 @@ public: interaction::InteractionHandler* interactionHandler(); RenderEngine* renderEngine(); scripting::ScriptEngine* scriptEngine(); + NetworkEngine* networkEngine(); LuaConsole* console(); gui::GUI* gui(); diff --git a/include/openspace/network/networkengine.h b/include/openspace/network/networkengine.h index 1d0c03481a..90558f9717 100644 --- a/include/openspace/network/networkengine.h +++ b/include/openspace/network/networkengine.h @@ -25,17 +25,50 @@ #ifndef __NETWORKENGINE_H__ #define __NETWORKENGINE_H__ +#include +#include #include +#include namespace openspace { class NetworkEngine { public: - NetworkEngine() = default; + typedef uint16_t MessageIdentifier; + NetworkEngine(); + + // Receiving messages bool handleMessage(const std::string& message); - void sendStatusMessage(); + // Sending messages + void publishStatusMessage(); + void publishIdentifierMappingMessage(); + void publishMessage(MessageIdentifier identifier, std::vector message); + void sendMessages(); + + // Initial Connection Messages + void setInitialConnectionMessage(MessageIdentifier identifier, std::vector message); + void sendInitialInformation(); + + // Background + MessageIdentifier identifier(std::string name); +private: + std::map _identifiers; + MessageIdentifier _lastAssignedIdentifier; + + struct Message { + MessageIdentifier identifer; + std::vector body; + }; + std::vector _messagesToSend; + + std::vector _initialConnectionMessages; + + + + MessageIdentifier _statusMessageIdentifier; + MessageIdentifier _identifierMappingIdentifier; }; } // namespace openspace diff --git a/include/openspace/util/hongkangparser.h b/include/openspace/util/hongkangparser.h index f6e08c6160..ca1eccf68d 100644 --- a/include/openspace/util/hongkangparser.h +++ b/include/openspace/util/hongkangparser.h @@ -65,6 +65,7 @@ namespace openspace { std::string spacecraft, std::vector payload, std::vector potentialTargets); + void sendPlaybookInformation(); std::string _defaultCaptureImage; double _metRef = 299180517; diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 4e169dc328..7499cab4ec 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -703,7 +703,8 @@ void OpenSpaceEngine::encode() { _syncBuffer->write(); } - _networkEngine->sendStatusMessage(); + _networkEngine->publishStatusMessage(); + _networkEngine->sendMessages(); } void OpenSpaceEngine::decode() { @@ -733,4 +734,8 @@ void OpenSpaceEngine::disableBarrier() { sgct::SGCTWindow::setBarrier(false); } +NetworkEngine* OpenSpaceEngine::networkEngine() { + return _networkEngine; +} + } // namespace openspace diff --git a/src/main.cpp b/src/main.cpp index 86a3dfdf2a..d7a851db0f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -79,7 +79,6 @@ int main(int argc, char** argv) { sgct::MessageHandler::instance()->setLogToCallback(true); sgct::MessageHandler::instance()->setLogCallback(mainLogCallback); - LDEBUG("Creating SGCT Engine"); _sgctEngine = new sgct::Engine(newArgc, newArgv); diff --git a/src/network/networkengine.cpp b/src/network/networkengine.cpp index 1b0c0a2599..c89ce924b3 100644 --- a/src/network/networkengine.cpp +++ b/src/network/networkengine.cpp @@ -27,27 +27,49 @@ #include #include +#include + #include "sgct.h" namespace { const std::string _loggerCat = "NetworkEngine"; - const uint8_t MessageTypeStatus = 0; + const std::string StatusMessageIdentifierName = "StatusMessage"; + const std::string MappingIdentifierIdentifierName = "IdentifierMapping"; + + const char MessageTypeLuaScript = '0'; + const char MessageTypeExternalControlConnected = '1'; } namespace openspace { +NetworkEngine::NetworkEngine() + : _lastAssignedIdentifier(-1) // -1 is okay as we assign one identifier in this ctor +{ + static_assert( + sizeof(MessageIdentifier) == 2, + "MessageIdentifier has to be 2 bytes or dependent applications will break" + ); + _statusMessageIdentifier = identifier(StatusMessageIdentifierName); + _identifierMappingIdentifier = identifier(MappingIdentifierIdentifierName); +} + bool NetworkEngine::handleMessage(const std::string& message) { // The first byte determines the type of message const char type = message[0]; switch (type) { - case '0': // LuaScript + case MessageTypeLuaScript: // LuaScript { std::string script = message.substr(1); //LINFO("Received Lua Script: '" << script << "'"); OsEng.scriptEngine()->queueScript(script); return true; } + case MessageTypeExternalControlConnected: + { + sendInitialInformation(); + return true; + } default: LERROR("Unknown type '" << type << "'"); return false; @@ -55,15 +77,14 @@ bool NetworkEngine::handleMessage(const std::string& message) { } -void NetworkEngine::sendStatusMessage() { +void NetworkEngine::publishStatusMessage() { if (!sgct::Engine::instance()->isExternalControlConnected()) return; - // Protocols: - // 1 byte: type of message + // Protocol: // 8 bytes: time as a ET double // 24 bytes: time as a UTC string // 8 bytes: delta time as double - // Total: 41 + // Total: 40 uint16_t messageSize = 0; @@ -71,27 +92,108 @@ void NetworkEngine::sendStatusMessage() { std::string timeString = Time::ref().currentTimeUTC(); double delta = Time::ref().deltaTime(); - messageSize += sizeof(uint8_t); messageSize += sizeof(time); messageSize += timeString.length(); messageSize += sizeof(delta); - //LINFO(delta); - - ghoul_assert(messageSize == 41, "Message size is not correct"); + ghoul_assert(messageSize == 40, "Message size is not correct"); unsigned int currentLocation = 0; std::vector buffer(messageSize); - std::memcpy(buffer.data(), &MessageTypeStatus, sizeof(MessageTypeStatus)); - currentLocation += sizeof(MessageTypeStatus); std::memmove(buffer.data() + currentLocation, &time, sizeof(time)); currentLocation += sizeof(time); std::memmove(buffer.data() + currentLocation, timeString.c_str(), timeString.length()); currentLocation += timeString.length(); std::memmove(buffer.data() + currentLocation, &delta, sizeof(delta)); - sgct::Engine::instance()->sendMessageToExternalControl(buffer.data(), messageSize); + publishMessage(_statusMessageIdentifier, std::move(buffer)); +} + +void NetworkEngine::publishIdentifierMappingMessage() { + size_t bufferSize = 0; + for (const std::pair& i : _identifiers) { + bufferSize += sizeof(MessageIdentifier); + bufferSize += i.second.size() + 1; // +1 for \0 terminating character + } + + std::vector buffer(bufferSize); + size_t currentWritingPosition = 0; + for (const std::pair& i : _identifiers) { + std::memcpy(buffer.data() + currentWritingPosition, &(i.first), sizeof(MessageIdentifier)); + currentWritingPosition += sizeof(MessageIdentifier); + std::memcpy(buffer.data() + currentWritingPosition, i.second.data(), i.second.size()); + currentWritingPosition += i.second.size(); + buffer[currentWritingPosition] = '\0'; + currentWritingPosition += 1; + } + + publishMessage(_identifierMappingIdentifier, std::move(buffer)); +} + + +NetworkEngine::MessageIdentifier NetworkEngine::identifier(std::string name) { +#ifdef DEBUG + // Check if name has been assigned already + for (const std::pair& p : _identifiers) { + if (p.second == name) { + LERROR("Name '" << name << "' for identifier has been registered before"); + return -1; + } + } +#endif + _lastAssignedIdentifier++; + + MessageIdentifier result = _lastAssignedIdentifier; + + _identifiers[result] = std::move(name); + return result; +} + +void NetworkEngine::publishMessage(MessageIdentifier identifier, std::vector message) { + _messagesToSend.push_back({ std::move(identifier), std::move(message) }); +} + +void NetworkEngine::sendMessages() { + if (!sgct::Engine::instance()->isExternalControlConnected()) + return; + + for (Message& m : _messagesToSend) { + // Protocol: + // 2 bytes: type of message as uint16_t + // Rest of payload depending on the message type + + union { + MessageIdentifier value; + std::array data; + } identifier; + identifier.value = m.identifer; + + // Prepending the message identifier to the front + m.body.insert(m.body.begin(), identifier.data.begin(), identifier.data.end()); + sgct::Engine::instance()->sendMessageToExternalControl(m.body.data(), m.body.size()); + } + + _messagesToSend.clear(); +} + +void NetworkEngine::sendInitialInformation() { + for (const Message& m : _initialConnectionMessages) { + union { + MessageIdentifier value; + std::array data; + } identifier; + identifier.value = m.identifer; + + std::vector payload = m.body; + payload.insert(payload.begin(), identifier.data.begin(), identifier.data.end()); + sgct::Engine::instance()->sendMessageToExternalControl(payload.data(), payload.size()); + } +} + +void NetworkEngine::setInitialConnectionMessage(MessageIdentifier identifier, std::vector message) { + // Add check if a MessageIdentifier already exists ---abock + _initialConnectionMessages.push_back({std::move(identifier), std::move(message)}); } } // namespace openspace diff --git a/src/util/hongkangparser.cpp b/src/util/hongkangparser.cpp index 0628de37c3..55802a7249 100644 --- a/src/util/hongkangparser.cpp +++ b/src/util/hongkangparser.cpp @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include @@ -38,6 +40,8 @@ namespace { const std::string _loggerCat = "HongKangParser"; const std::string keyTranslation = "DataInputTranslation"; + + const std::string PlaybookIdentifierName = "Playbook"; } namespace openspace { @@ -207,6 +211,8 @@ void HongKangParser::create(){ } } } + + sendPlaybookInformation(); std::ofstream myfile; myfile.open("HongKangOutput.txt"); @@ -333,4 +339,119 @@ std::vector HongKangParser::getCaptureProgression(){ return _captureProgression; }; + +template +void writeToBuffer(std::vector& buffer, size_t& currentWriteLocation, T value) { + if ((currentWriteLocation + sizeof(T)) > buffer.size()) + buffer.resize(2 * buffer.size()); + + std::memmove(buffer.data() + currentWriteLocation, reinterpret_cast(&value), sizeof(T)); + currentWriteLocation += sizeof(T); +} + +template <> + +void writeToBuffer(std::vector& buffer, size_t& currentWriteLocation, std::string value) { + if ((currentWriteLocation + sizeof(uint8_t) + value.size()) > buffer.size()) + buffer.resize(2 * buffer.size()); + + uint8_t length = value.size(); + std::memcpy(buffer.data() + currentWriteLocation, &length, sizeof(uint8_t)); + currentWriteLocation += sizeof(uint8_t); + + std::memmove(buffer.data() + currentWriteLocation, value.data(), length); + currentWriteLocation += length; +} + + +void HongKangParser::sendPlaybookInformation() { + static const NetworkEngine::MessageIdentifier PlaybookIdentifier = OsEng.networkEngine()->identifier(PlaybookIdentifierName); + + std::vector buffer(1024); + size_t currentWriteLocation = 0; + + // Protocol: + // 4 bytes: Total number of bytes sent + // 1 byte : Number of Targets (i) + // i times: 1 byte (id), 1 byte (length j of name), j bytes (name) + // 1 byte : Number of Instruments (i) + // i times: 1 byte (id), 1 byte (length j of name), j bytes (name) + // 4 byte: Number (n) of images + // n times: 8 byte (beginning time), 8 byte (ending time), 1 byte (target id), 2 byte (instrument id) + + std::map targetMap; + uint8_t currentTargetId = 0; + for (auto target : _subsetMap) { + if (targetMap.find(target.first) == targetMap.end()) + targetMap[target.first] = currentTargetId++; + } + + std::map instrumentMap; + uint16_t currentInstrumentId = 1; + for (auto target : _subsetMap) { + for (auto image : target.second._subset) { + for (auto instrument : image.activeInstruments) { + if (instrumentMap.find(instrument) == instrumentMap.end()) { + instrumentMap[instrument] = currentInstrumentId; + currentInstrumentId = currentInstrumentId << 1; + } + } + } + } + + writeToBuffer(buffer, currentWriteLocation, uint8_t(targetMap.size())); + for (const std::pair& p : targetMap) { + writeToBuffer(buffer, currentWriteLocation, p.second); + writeToBuffer(buffer, currentWriteLocation, p.first); + } + + writeToBuffer(buffer, currentWriteLocation, uint8_t(instrumentMap.size())); + for (const std::pair& p : instrumentMap) { + writeToBuffer(buffer, currentWriteLocation, p.second); + writeToBuffer(buffer, currentWriteLocation, p.first); + } + + uint32_t allImages = 0; + for (auto target : _subsetMap) + allImages += target.second._subset.size(); + writeToBuffer(buffer, currentWriteLocation, allImages); + + for (auto target : _subsetMap){ + for (auto image : target.second._subset){ + writeToBuffer(buffer, currentWriteLocation, image.startTime); + writeToBuffer(buffer, currentWriteLocation, image.stopTime); + + std::string timeBegin; + std::string timeEnd; + SpiceManager::ref().getDateFromET(image.startTime, timeBegin); + SpiceManager::ref().getDateFromET(image.stopTime, timeEnd); + + writeToBuffer(buffer, currentWriteLocation, timeBegin); + writeToBuffer(buffer, currentWriteLocation, timeEnd); + + uint8_t targetId = targetMap[target.first]; + writeToBuffer(buffer, currentWriteLocation, targetId); + uint16_t totalInstrumentId = 0; + for (auto instrument : image.activeInstruments) { + uint16_t thisInstrumentId = instrumentMap[instrument]; + totalInstrumentId |= thisInstrumentId; + } + writeToBuffer(buffer, currentWriteLocation, totalInstrumentId); + } + } + + union { + uint32_t value; + std::array data; + } sizeBuffer; + sizeBuffer.value = currentWriteLocation; + buffer.insert(buffer.begin(), sizeBuffer.data.begin(), sizeBuffer.data.end()); + currentWriteLocation += sizeof(uint32_t); + + buffer.resize(currentWriteLocation); + + //OsEng.networkEngine()->publishMessage(PlaybookIdentifier, buffer); + OsEng.networkEngine()->setInitialConnectionMessage(PlaybookIdentifier, buffer); +} + } \ No newline at end of file From 8b9165fbfbe76576c50ae59432a4781bb7a7896d Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 2 May 2015 22:24:27 +0200 Subject: [PATCH 30/45] Added missing files --- gui/timelineview/configurationwidget.cpp | 4 ---- gui/timelineview/configurationwidget.h | 3 --- 2 files changed, 7 deletions(-) diff --git a/gui/timelineview/configurationwidget.cpp b/gui/timelineview/configurationwidget.cpp index 900a02d5c1..38b4526546 100644 --- a/gui/timelineview/configurationwidget.cpp +++ b/gui/timelineview/configurationwidget.cpp @@ -31,15 +31,11 @@ ConfigurationWidget::ConfigurationWidget(QWidget* parent) , _ipAddress(new QLineEdit("localhost")) , _port(new QLineEdit("20500")) , _connect(new QPushButton("Connect")) - , _playbook(new QLineEdit) - , _load(new QPushButton("Load")) { QGridLayout* layout = new QGridLayout; layout->addWidget(_ipAddress, 0, 0); layout->addWidget(_port, 0, 1); layout->addWidget(_connect, 0, 2); - layout->addWidget(_playbook, 1, 0, 1, 2); - layout->addWidget(_load, 1, 2); setLayout(layout); diff --git a/gui/timelineview/configurationwidget.h b/gui/timelineview/configurationwidget.h index dfc305005b..2c6291a13c 100644 --- a/gui/timelineview/configurationwidget.h +++ b/gui/timelineview/configurationwidget.h @@ -44,9 +44,6 @@ private: QLineEdit* _ipAddress; QLineEdit* _port; QPushButton* _connect; - - QLineEdit* _playbook; - QPushButton* _load; }; #endif // __CONFIGURATIONWIDGET_H__ From 9a76f3757374677bef122b532e21b33a12e675e2 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 3 May 2015 00:14:01 +0200 Subject: [PATCH 31/45] Fix crashes with focus node change when view and camera vectors were almost the same but not equal Fix crash when moving to time without any images --- src/interaction/interactionhandler.cpp | 7 +- src/rendering/renderengine.cpp | 100 +++++++++++++------------ src/util/imagesequencer2.cpp | 6 +- 3 files changed, 61 insertions(+), 52 deletions(-) diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index 9ac16253d6..6017ebb36e 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -556,7 +556,12 @@ void InteractionHandler::setFocusNode(SceneGraphNode* node) { glm::vec3 cameraView = glm::normalize(_camera->viewDirection()); //set new focus position _camera->setFocusPosition(node->worldPosition()); - if (viewDir != cameraView) { + float dot = glm::dot(viewDir, cameraView); + + //static const float Epsilon = 0.001f; + if (dot < 1.f && dot > -1.f) { + //if (glm::length(viewDir - cameraView) < 0.001) { + //if (viewDir != cameraView) { glm::vec3 rotAxis = glm::normalize(glm::cross(viewDir, cameraView)); float angle = glm::angle(viewDir, cameraView); glm::quat q = glm::angleAxis(angle, rotAxis); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index ae5ce38a4f..f05d615695 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -629,70 +629,72 @@ namespace openspace { std::pair nextTarget = ImageSequencer2::ref().getNextTarget(); std::pair currentTarget = ImageSequencer2::ref().getCurrentTarget(); - int timeleft = nextTarget.first - currentTime; + if (currentTarget.first > 0.0) { - int hour = timeleft / 3600; - int second = timeleft % 3600; - int minute = second / 60; - second = second % 60; + int timeleft = nextTarget.first - currentTime; - std::string hh, mm, ss, coundtown; + int hour = timeleft / 3600; + int second = timeleft % 3600; + int minute = second / 60; + second = second % 60; - if (hour < 10) hh.append("0"); - if (minute < 10) mm.append("0"); - if (second < 10) ss.append("0"); + std::string hh, mm, ss, coundtown; - hh.append(std::to_string(hour)); - mm.append(std::to_string(minute)); - ss.append(std::to_string(second)); + 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)); - glm::vec4 b2(1.00, 0.51, 0.00, 1); - PrintColorText(i++, "Switching observation focus in : [%s:%s:%s]", 10, b2, hh.c_str(), mm.c_str(), ss.c_str()); + glm::vec4 b2(1.00, 0.51, 0.00, 1); + PrintColorText(i++, "Switching observation focus in : [%s:%s:%s]", 10, b2, hh.c_str(), mm.c_str(), ss.c_str()); - std::pair> incidentTargets = ImageSequencer2::ref().getIncidentTargetList(2); - std::string space; - glm::vec4 color; - int isize = incidentTargets.second.size(); - for (int p = 0; p < isize; p++){ - double t = (double)(p + 1) / (double)(isize+1); - t = (p > isize / 2) ? 1-t : t; - t += 0.3; - color = (p == isize / 2) ? glm::vec4(1.00, 0.51, 0.00, 1) : glm::vec4(t, t, t, 1); - PrintColorText(i, "%s%s", 10, color, space.c_str(), incidentTargets.second[p].c_str()); - for (int k = 0; k < 10; k++){ space += " "; } - } - i++; - - std::vector> instrVec = ImageSequencer2::ref().getActiveInstruments(); + std::pair> incidentTargets = ImageSequencer2::ref().getIncidentTargetList(2); + std::string space; + glm::vec4 color; + int isize = incidentTargets.second.size(); + for (int p = 0; p < isize; p++){ + double t = (double)(p + 1) / (double)(isize + 1); + t = (p > isize / 2) ? 1 - t : t; + t += 0.3; + color = (p == isize / 2) ? glm::vec4(1.00, 0.51, 0.00, 1) : glm::vec4(t, t, t, 1); + PrintColorText(i, "%s%s", 10, color, space.c_str(), incidentTargets.second[p].c_str()); + for (int k = 0; k < 10; k++){ space += " "; } + } + i++; - glm::vec4 active(0.58, 1, 0.00, 1); + std::vector> instrVec = ImageSequencer2::ref().getActiveInstruments(); + + glm::vec4 active(0.58, 1, 0.00, 1); - glm::vec4 firing(0.58-t, 1-t, 1-t, 1); - glm::vec4 notFiring(0.5, 0.5, 0.5, 1); + glm::vec4 firing(0.58 - t, 1 - t, 1 - t, 1); + glm::vec4 notFiring(0.5, 0.5, 0.5, 1); - double reduce = 0.01; + double reduce = 0.01; - PrintColorText(i++, "Active Instruments : ", 10, active); - for (int k = 0; k < instrVec.size(); k++){ + PrintColorText(i++, "Active Instruments : ", 10, active); + for (int k = 0; k < instrVec.size(); k++){ - if (instrVec[k].second == false){ - PrintColorText(i, "| |", 10, glm::vec4(0.3, 0.3, 0.3, 1)); - PrintColorText(i++, " %5s", 10, glm::vec4(0.3, 0.3, 0.3, 1), instrVec[k].first.c_str()); - } - else{ - PrintColorText(i, "|", 10, glm::vec4(0.3, 0.3, 0.3, 1)); - if (instrVec[k].first == "NH_LORRI"){ - PrintColorText(i, " + ", 10, firing); - } - PrintColorText(i, " |", 10, glm::vec4(0.3, 0.3, 0.3, 1)); - PrintColorText(i++, " %5s", 10, active, instrVec[k].first.c_str()); + if (instrVec[k].second == false){ + PrintColorText(i, "| |", 10, glm::vec4(0.3, 0.3, 0.3, 1)); + PrintColorText(i++, " %5s", 10, glm::vec4(0.3, 0.3, 0.3, 1), instrVec[k].first.c_str()); + } + else{ + PrintColorText(i, "|", 10, glm::vec4(0.3, 0.3, 0.3, 1)); + if (instrVec[k].first == "NH_LORRI"){ + PrintColorText(i, " + ", 10, firing); + } + PrintColorText(i, " |", 10, glm::vec4(0.3, 0.3, 0.3, 1)); + PrintColorText(i++, " %5s", 10, active, instrVec[k].first.c_str()); - } - } - + } + } + } } #undef PrintText diff --git a/src/util/imagesequencer2.cpp b/src/util/imagesequencer2.cpp index 573b648b4a..e5d66c7a5b 100644 --- a/src/util/imagesequencer2.cpp +++ b/src/util/imagesequencer2.cpp @@ -116,9 +116,11 @@ std::pair ImageSequencer2::getCurrentTarget(){ findEqualToThis.first = _currentTime; auto it = std::lower_bound(_targetTimes.begin(), _targetTimes.end(), findEqualToThis, compareTime); - if (it != _targetTimes.end()){ + if (it != _targetTimes.end() && it != _targetTimes.begin()){ return *std::prev(it); } + else + return std::make_pair(0.0, "No Target"); } std::pair> ImageSequencer2::getIncidentTargetList(int range){ @@ -225,7 +227,7 @@ bool ImageSequencer2::getImagePaths(std::vector>& auto curr = std::lower_bound(begin, end, findCurrent, compareTime); auto prev = std::lower_bound(begin, end, findPrevious, compareTime); - if (curr != begin && curr != end && prev != begin && prev != end){ + if (curr != begin && curr != end && prev != begin && prev != end && prev < curr){ std::transform(prev, curr, std::back_inserter(captureTimes), [](const Image& i) { return std::make_pair(i.startTime, i.path); From d89760c9e96585441badd8e3d2fc929a8373c0c0 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 3 May 2015 00:14:17 +0200 Subject: [PATCH 32/45] More changes on TimelineView --- gui/timelineview/CMakeLists.txt | 2 +- gui/timelineview/common.h | 2 + ...imecontrolwidget.cpp => controlwidget.cpp} | 58 ++++++++++++++++--- .../{timecontrolwidget.h => controlwidget.h} | 12 ++-- gui/timelineview/mainwindow.cpp | 6 +- gui/timelineview/mainwindow.h | 4 +- gui/timelineview/timelinewidget.cpp | 6 +- 7 files changed, 68 insertions(+), 22 deletions(-) rename gui/timelineview/{timecontrolwidget.cpp => controlwidget.cpp} (72%) rename gui/timelineview/{timecontrolwidget.h => controlwidget.h} (93%) diff --git a/gui/timelineview/CMakeLists.txt b/gui/timelineview/CMakeLists.txt index 86dd6b9a9c..da453d23bd 100644 --- a/gui/timelineview/CMakeLists.txt +++ b/gui/timelineview/CMakeLists.txt @@ -6,5 +6,5 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) find_package(Qt5Widgets) find_package(Qt5Network) -add_executable(TimelineView main.cpp mainwindow.cpp configurationwidget.cpp informationwidget.cpp timecontrolwidget.cpp timelinewidget.cpp) +add_executable(TimelineView main.cpp mainwindow.cpp configurationwidget.cpp informationwidget.cpp controlwidget.cpp timelinewidget.cpp) target_link_libraries(TimelineView Qt5::Widgets Qt5::Network) \ No newline at end of file diff --git a/gui/timelineview/common.h b/gui/timelineview/common.h index 2588afda3a..ddc0bad206 100644 --- a/gui/timelineview/common.h +++ b/gui/timelineview/common.h @@ -28,6 +28,8 @@ struct Image { double beginning; double ending; + std::string beginningString; + std::string endingString; std::string target; std::vector instruments; }; diff --git a/gui/timelineview/timecontrolwidget.cpp b/gui/timelineview/controlwidget.cpp similarity index 72% rename from gui/timelineview/timecontrolwidget.cpp rename to gui/timelineview/controlwidget.cpp index c2693c7aae..8074092a36 100644 --- a/gui/timelineview/timecontrolwidget.cpp +++ b/gui/timelineview/controlwidget.cpp @@ -22,7 +22,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include "timecontrolwidget.h" +#include "controlwidget.h" #include #include @@ -31,7 +31,25 @@ #include #include -TimeControlWidget::TimeControlWidget(QWidget* parent) +namespace { + struct ImportantDate { + QString date; + QString focus; + QString coordinateSystem; + }; + + const ImportantDate ImportantDates[] = { + { "2007-02-27T16:40:00.00", "JupiterProjection", "Jupiter" }, + { "2015-07-14T10:50:00.00", "PlutoProjection", "Pluto" }, + { "2015-07-14T11:22:00.00", "PlutoProjection", "Pluto" }, + { "2015-07-14T11:36:40.00", "PlutoProjection", "Pluto" }, + { "2015-07-14T11:48:43.00", "PlutoProjection", "Pluto" }, + { "2015-07-14T12:04:35.00", "PlutoProjection", "Pluto" }, + { "2015-07-14T15:02:46.00", "PlutoProjection", "Pluto" } + }; +} + +ControlWidget::ControlWidget(QWidget* parent) : QWidget(parent) , _currentTime(new QLabel("Current Time")) , _setTime(new QComboBox) @@ -42,6 +60,16 @@ TimeControlWidget::TimeControlWidget(QWidget* parent) , _play(new QPushButton("|>")) , _forward(new QPushButton(">>")) { + for (const ImportantDate& d : ImportantDates) + _setTime->addItem(d.date); + QObject::connect( + _setTime, + SIGNAL(currentIndexChanged(int)), + this, + SLOT(onDateChange()) + ); + + _setDelta->setMinimum(-100); _setDelta->setMaximum(100); _setDelta->setValue(0); @@ -99,33 +127,47 @@ TimeControlWidget::TimeControlWidget(QWidget* parent) setLayout(layout); } -void TimeControlWidget::update(QString currentTime, QString currentDelta) { +void ControlWidget::update(QString currentTime, QString currentDelta) { _currentTime->setText(currentTime); _currentDelta->setText(currentDelta); } -void TimeControlWidget::onValueChange() { +void ControlWidget::onValueChange() { QString script = "openspace.time.setDeltaTime(" + QString::number(_setDelta->value()) + ");"; emit scriptActivity(script); } -void TimeControlWidget::onRewindButton() { +void ControlWidget::onRewindButton() { QString script = "openspace.time.setDeltaTime(-openspace.time.deltaTime());"; emit scriptActivity(script); } -void TimeControlWidget::onPauseButton() { +void ControlWidget::onPauseButton() { QString script = "openspace.time.setPause(true);"; emit scriptActivity(script); } -void TimeControlWidget::onPlayButton() { +void ControlWidget::onPlayButton() { QString script = "openspace.time.setPause(false);"; emit scriptActivity(script); } -void TimeControlWidget::onForwardButton() { +void ControlWidget::onForwardButton() { QString script = "openspace.time.setDeltaTime(-openspace.time.deltaTime());"; emit scriptActivity(script); } + +void ControlWidget::onDateChange() { + int index = _setTime->currentIndex(); + QString date = ImportantDates[index].date; + QString focus = ImportantDates[index].focus; + QString coordinateSystem = ImportantDates[index].coordinateSystem; + //QString script = + // "openspace.time.setTime('" + date + "');\ + // openspace.setOrigin('" + focus + "');\ + // openspace.changeCoordinateSystem('" + coordinateSystem + "');"; + QString script = + "openspace.setOrigin('" + focus + "');"; + emit scriptActivity(script); +} diff --git a/gui/timelineview/timecontrolwidget.h b/gui/timelineview/controlwidget.h similarity index 93% rename from gui/timelineview/timecontrolwidget.h rename to gui/timelineview/controlwidget.h index 8265184cf3..c60783d3fb 100644 --- a/gui/timelineview/timecontrolwidget.h +++ b/gui/timelineview/controlwidget.h @@ -22,8 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __TIMECONTROLWIDGET_H__ -#define __TIMECONTROLWIDGET_H__ +#ifndef __CONTROLWIDGET_H__ +#define __CONTROLWIDGET_H__ #include @@ -32,10 +32,10 @@ class QLabel; class QPushButton; class QSlider; -class TimeControlWidget : public QWidget { +class ControlWidget : public QWidget { Q_OBJECT public: - TimeControlWidget(QWidget* parent); + ControlWidget(QWidget* parent); void update(QString currentTime, QString currentDelta); @@ -44,11 +44,13 @@ signals: private slots: void onValueChange(); + void onDateChange(); void onRewindButton(); void onPauseButton(); void onPlayButton(); void onForwardButton(); + private: QLabel* _currentTime; QComboBox* _setTime; @@ -62,4 +64,4 @@ private: bool _stateNoNotification = false; }; -#endif // __TIMECONTROLWIDGET_H__ +#endif // __CONTROLWIDGET_H__ diff --git a/gui/timelineview/mainwindow.cpp b/gui/timelineview/mainwindow.cpp index 845a719e89..86e0a1517f 100644 --- a/gui/timelineview/mainwindow.cpp +++ b/gui/timelineview/mainwindow.cpp @@ -25,7 +25,7 @@ #include "mainwindow.h" #include "configurationwidget.h" -#include "timecontrolwidget.h" +#include "controlwidget.h" #include "informationwidget.h" #include "timelinewidget.h" @@ -69,7 +69,7 @@ MainWindow::MainWindow() setWindowTitle("OpenSpace Timeline"); _configurationWidget = new ConfigurationWidget(this); - _timeControlWidget = new TimeControlWidget(this); + _timeControlWidget = new ControlWidget(this); _informationWidget = new InformationWidget(this); _timelineWidget = new TimelineWidget(this); @@ -174,7 +174,7 @@ void MainWindow::handleStatusMessage(QByteArray data) { QString::fromStdString(std::string(timeString.begin(), timeString.end())), QString::number(delta.value) ); - _timelineWidget->setCurrentTime(std::string(timeString.begin(), timeString.end())); + _timelineWidget->setCurrentTime(std::string(timeString.begin(), timeString.end()), et.value); } std::vector instrumentsFromId(uint16_t instrumentId, std::map instrumentMap) { diff --git a/gui/timelineview/mainwindow.h b/gui/timelineview/mainwindow.h index cb9ada8a8b..cf30e8bfa2 100644 --- a/gui/timelineview/mainwindow.h +++ b/gui/timelineview/mainwindow.h @@ -31,7 +31,7 @@ #include "common.h" class ConfigurationWidget; -class TimeControlWidget; +class ControlWidget; class InformationWidget; class TimelineWidget; @@ -55,7 +55,7 @@ private slots: private: ConfigurationWidget* _configurationWidget; - TimeControlWidget* _timeControlWidget; + ControlWidget* _timeControlWidget; InformationWidget* _informationWidget; TimelineWidget* _timelineWidget; diff --git a/gui/timelineview/timelinewidget.cpp b/gui/timelineview/timelinewidget.cpp index 5f064a0619..30d2b018ec 100644 --- a/gui/timelineview/timelinewidget.cpp +++ b/gui/timelineview/timelinewidget.cpp @@ -124,9 +124,9 @@ void TimelineWidget::drawContent(QPainter& painter, QRectF rect) { std::vector::const_iterator start = _images.end(); std::vector::const_iterator end = _images.end(); - for (std::vector::const_iterator it = _images.begin(); it != _image.end(); ++it) { - if (it->beginning > lowerTime - } + //for (std::vector::const_iterator it = _images.begin(); it != _images.end(); ++it) { + // if (it->beginning > lowerTime + //} //std::vector::const_iterator lower = std::lower_bound(_images.begin(), _images.end(), lowerTime, [lowerTime](const Image& i) { return i.beginning < lowerTime; }); ////std::vector::const_iterator upper = std::lower_bound(_images.begin(), _iamges.end(), upperTime) From 14270b316e370b16768b2717f7fbaf2e031ea780 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 3 May 2015 13:52:55 +0200 Subject: [PATCH 33/45] Bugfix fixing a crash with rendering Started rendering of image data --- gui/timelineview/controlwidget.cpp | 10 +++---- gui/timelineview/mainwindow.cpp | 3 ++- gui/timelineview/timelinewidget.cpp | 41 ++++++++++++++++++++--------- gui/timelineview/timelinewidget.h | 2 +- 4 files changed, 37 insertions(+), 19 deletions(-) diff --git a/gui/timelineview/controlwidget.cpp b/gui/timelineview/controlwidget.cpp index 8074092a36..d54f97ac3d 100644 --- a/gui/timelineview/controlwidget.cpp +++ b/gui/timelineview/controlwidget.cpp @@ -163,11 +163,11 @@ void ControlWidget::onDateChange() { QString date = ImportantDates[index].date; QString focus = ImportantDates[index].focus; QString coordinateSystem = ImportantDates[index].coordinateSystem; - //QString script = - // "openspace.time.setTime('" + date + "');\ - // openspace.setOrigin('" + focus + "');\ - // openspace.changeCoordinateSystem('" + coordinateSystem + "');"; QString script = - "openspace.setOrigin('" + focus + "');"; + "openspace.time.setTime('" + date + "');\ + openspace.setOrigin('" + focus + "');\ + openspace.changeCoordinateSystem('" + coordinateSystem + "');"; + //QString script = + // "openspace.setOrigin('" + focus + "');"; emit scriptActivity(script); } diff --git a/gui/timelineview/mainwindow.cpp b/gui/timelineview/mainwindow.cpp index 86e0a1517f..503bcf1e6b 100644 --- a/gui/timelineview/mainwindow.cpp +++ b/gui/timelineview/mainwindow.cpp @@ -231,6 +231,7 @@ void MainWindow::handlePlaybook(QByteArray data) { void MainWindow::sendScript(QString script) { - _socket->write(("0" + script + "\r\n").toLatin1()); + if (_socket) + _socket->write(("0" + script + "\r\n").toLatin1()); } diff --git a/gui/timelineview/timelinewidget.cpp b/gui/timelineview/timelinewidget.cpp index 30d2b018ec..0fd032b40b 100644 --- a/gui/timelineview/timelinewidget.cpp +++ b/gui/timelineview/timelinewidget.cpp @@ -121,18 +121,10 @@ void TimelineWidget::drawContent(QPainter& painter, QRectF rect) { const double lowerTime = _currentTime.et - etSpread; const double upperTime = _currentTime.et + etSpread; - - std::vector::const_iterator start = _images.end(); - std::vector::const_iterator end = _images.end(); - //for (std::vector::const_iterator it = _images.begin(); it != _images.end(); ++it) { - // if (it->beginning > lowerTime - //} - - //std::vector::const_iterator lower = std::lower_bound(_images.begin(), _images.end(), lowerTime, [lowerTime](const Image& i) { return i.beginning < lowerTime; }); - ////std::vector::const_iterator upper = std::lower_bound(_images.begin(), _iamges.end(), upperTime) - - - + std::vector::const_iterator lower = std::lower_bound(_images.begin(), _images.end(), lowerTime, [](const Image& i, double time) { return i.beginning < time; }); + std::vector::const_iterator upper = std::lower_bound(_images.begin(), _images.end(), upperTime, [](const Image& i, double time) { return i.ending < time; }); + if (lower != _images.end() && upper != _images.end()) + drawImages(painter, timelineRect, lower, upper, lowerTime, upperTime); } void TimelineWidget::drawLegend(QPainter& painter, QRectF rect) { @@ -187,3 +179,28 @@ void TimelineWidget::setCurrentTime(std::string currentTime, double et) { } +void TimelineWidget::drawImages( + QPainter& painter, + QRectF rect, + std::vector::const_iterator beginning, + std::vector::const_iterator ending, + double minimumTime, double maximumTime) +{ + int width = rect.width(); + + for (std::vector::const_iterator cur = beginning; cur != ending; ++cur) { + //double tBeg = (cur->beginning - minimumTime) / (maximumTime - minimumTime); + //double tEnd = (cur->ending - minimumTime) / (maximumTime - minimumTime); + double t = (cur->beginning - minimumTime) / (maximumTime - minimumTime); + + int loc = rect.top() + rect.height() * t; + + //int begin = rect.top() + rect.height() * tBeg; + //int end = rect.top() + rect.height() * tEnd; + + //painter.drawRect(begin, 0, width, end); + painter.drawLine(QPointF(0, loc), QPointF(rect.width(), loc)); + + } +} + diff --git a/gui/timelineview/timelinewidget.h b/gui/timelineview/timelinewidget.h index 33c455b3eb..8ed55e44af 100644 --- a/gui/timelineview/timelinewidget.h +++ b/gui/timelineview/timelinewidget.h @@ -47,7 +47,7 @@ protected: void paintEvent(QPaintEvent* event); void drawContent(QPainter& painter, QRectF rect); void drawLegend(QPainter& painter, QRectF rect); - + void drawImages(QPainter& painter, QRectF rect, std::vector::const_iterator beginning, std::vector::const_iterator ending, double minimumTime, double maximumTime); private: std::vector _images; From 810480d5d859149357077c74dd3b9c09e6ae5cb5 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 4 May 2015 10:02:47 +0200 Subject: [PATCH 34/45] Enable focus node change Show instruments --- gui/timelineview/controlwidget.cpp | 45 +++++++++++++++++++++++++++-- gui/timelineview/controlwidget.h | 4 +-- gui/timelineview/timelinewidget.cpp | 27 ++++++++++++----- openspace-data | 2 +- 4 files changed, 66 insertions(+), 12 deletions(-) diff --git a/gui/timelineview/controlwidget.cpp b/gui/timelineview/controlwidget.cpp index d54f97ac3d..964c34ce55 100644 --- a/gui/timelineview/controlwidget.cpp +++ b/gui/timelineview/controlwidget.cpp @@ -47,6 +47,20 @@ namespace { { "2015-07-14T12:04:35.00", "PlutoProjection", "Pluto" }, { "2015-07-14T15:02:46.00", "PlutoProjection", "Pluto" } }; + + struct FocusNode { + QString guiName; + QString name; + QString coordinateSystem; + }; + const FocusNode FocusNodes[] = { + { "Earth", "Earth", "Sun" }, + { "Sun", "Sun", "Sun" }, + { "Pluto", "PlutoProjection", "Pluto" }, + { "Charon", "Charon", "Pluto" }, + { "Jupiter", "JupiterProjection", "Jupiter" }, + { "New Horizons", "NewHorizons", ""} + }; } ControlWidget::ControlWidget(QWidget* parent) @@ -59,6 +73,7 @@ ControlWidget::ControlWidget(QWidget* parent) , _pause(new QPushButton("||")) , _play(new QPushButton("|>")) , _forward(new QPushButton(">>")) + , _focusNode(new QComboBox) { for (const ImportantDate& d : ImportantDates) _setTime->addItem(d.date); @@ -69,6 +84,14 @@ ControlWidget::ControlWidget(QWidget* parent) SLOT(onDateChange()) ); + for (const FocusNode& f : FocusNodes) + _focusNode->addItem(f.guiName); + QObject::connect( + _focusNode, + SIGNAL(currentIndexChanged(int)), + this, + SLOT(onFocusChange()) + ); _setDelta->setMinimum(-100); _setDelta->setMaximum(100); @@ -124,6 +147,8 @@ ControlWidget::ControlWidget(QWidget* parent) controlContainer->setLayout(controlContainerLayout); layout->addWidget(controlContainer, 3, 0, 1, 2); + layout->addWidget(_focusNode, 4, 0, 1, 2); + setLayout(layout); } @@ -167,7 +192,23 @@ void ControlWidget::onDateChange() { "openspace.time.setTime('" + date + "');\ openspace.setOrigin('" + focus + "');\ openspace.changeCoordinateSystem('" + coordinateSystem + "');"; - //QString script = - // "openspace.setOrigin('" + focus + "');"; + emit scriptActivity(script); +} + +void ControlWidget::onFocusChange() { + int index = _focusNode->currentIndex(); + QString name = FocusNodes[index].name; + QString coordinateSystem = FocusNodes[index].coordinateSystem; + if (coordinateSystem.isEmpty()) { + int date = _currentTime->text().left(4).toInt(); + if (date < 2008) + coordinateSystem = "Jupiter"; + else if (date < 2014) + coordinateSystem = "Sun"; + else + coordinateSystem = "Pluto"; + + } + QString script = "openspace.setOrigin('" + name + "');openspace.changeCoordinateSystem('" + coordinateSystem + "');"; emit scriptActivity(script); } diff --git a/gui/timelineview/controlwidget.h b/gui/timelineview/controlwidget.h index c60783d3fb..f4d78ae676 100644 --- a/gui/timelineview/controlwidget.h +++ b/gui/timelineview/controlwidget.h @@ -45,6 +45,7 @@ signals: private slots: void onValueChange(); void onDateChange(); + void onFocusChange(); void onRewindButton(); void onPauseButton(); void onPlayButton(); @@ -60,8 +61,7 @@ private: QPushButton* _pause; QPushButton* _play; QPushButton* _forward; - - bool _stateNoNotification = false; + QComboBox* _focusNode; }; #endif // __CONTROLWIDGET_H__ diff --git a/gui/timelineview/timelinewidget.cpp b/gui/timelineview/timelinewidget.cpp index 0fd032b40b..beda0e0490 100644 --- a/gui/timelineview/timelinewidget.cpp +++ b/gui/timelineview/timelinewidget.cpp @@ -188,19 +188,32 @@ void TimelineWidget::drawImages( { int width = rect.width(); - for (std::vector::const_iterator cur = beginning; cur != ending; ++cur) { + for (std::vector::const_iterator cur = beginning; cur <= ending; ++cur) { //double tBeg = (cur->beginning - minimumTime) / (maximumTime - minimumTime); //double tEnd = (cur->ending - minimumTime) / (maximumTime - minimumTime); double t = (cur->beginning - minimumTime) / (maximumTime - minimumTime); int loc = rect.top() + rect.height() * t; + int height = 25; - //int begin = rect.top() + rect.height() * tBeg; - //int end = rect.top() + rect.height() * tEnd; + std::string target = cur->target; + auto it = std::find(_targets.begin(), _targets.end(), target); + int iTarget = std::distance(_targets.begin(), it); + QColor targetColor = targetColors[iTarget]; - //painter.drawRect(begin, 0, width, end); - painter.drawLine(QPointF(0, loc), QPointF(rect.width(), loc)); - + std::vector instruments = cur->instruments; + std::vector colors; + for (std::string instrument : instruments) { + auto it = std::find(_instruments.begin(), _instruments.end(), instrument); + int i = std::distance(_instruments.begin(), it); + colors.push_back(instrumentColors[i]); + } + + painter.setBrush(QBrush(targetColor)); + if (colors.empty())) + painter.setPen(QPen(Qt::black)); + else + painter.setPen(QPen(colors[0])); + painter.drawRect(0, loc, rect.width(), height); } } - diff --git a/openspace-data b/openspace-data index 6b34ef9849..16dbd84e5c 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 6b34ef9849d58fa33a40c571eee6432bde83e343 +Subproject commit 16dbd84e5c11116339d2071a49f4a473577a0dad From 314ce645f6820693f6fdd7dd93f6ea1e3331f600 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 4 May 2015 11:55:53 +0200 Subject: [PATCH 35/45] Fix a bug where OpenSpace would crash when too many field of views are generated --- src/rendering/renderablefov.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rendering/renderablefov.cpp b/src/rendering/renderablefov.cpp index 66233c48dd..64234ac171 100644 --- a/src/rendering/renderablefov.cpp +++ b/src/rendering/renderablefov.cpp @@ -104,7 +104,7 @@ namespace openspace{ } void RenderableFov::allocateData(){ - int points = 10; + int points = 20; _stride[0] = points; _isize[0] = points; _iarray1[0] = new int[_isize[0]]; From 5704c8dcf687b33de3cbc7b42e7838bf630f6203 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 4 May 2015 11:56:21 +0200 Subject: [PATCH 36/45] Show the target of an instrument in the timeline view --- gui/timelineview/mainwindow.cpp | 1 + gui/timelineview/timelinewidget.cpp | 86 +++++++++++++++++------------ gui/timelineview/timelinewidget.h | 2 +- 3 files changed, 52 insertions(+), 37 deletions(-) diff --git a/gui/timelineview/mainwindow.cpp b/gui/timelineview/mainwindow.cpp index 503bcf1e6b..16342cf91f 100644 --- a/gui/timelineview/mainwindow.cpp +++ b/gui/timelineview/mainwindow.cpp @@ -142,6 +142,7 @@ void MainWindow::readTcpData() { uint32_t size = readFromBuffer(data.mid(2).data(), beginning); while (_socket->waitForReadyRead() && data.size() < size) { + //while (data.size() < size) { data = data.append(_socket->readAll()); } handlePlaybook(data.mid(2)); diff --git a/gui/timelineview/timelinewidget.cpp b/gui/timelineview/timelinewidget.cpp index beda0e0490..aea1d27e05 100644 --- a/gui/timelineview/timelinewidget.cpp +++ b/gui/timelineview/timelinewidget.cpp @@ -32,16 +32,18 @@ namespace { static const int LegendHeight = 105; - static const int TimeWidth = 150; + static const int TimeWidth = 200; + + static const int TextOffset = 5; - const QColor targetColors[] = { - QColor(251, 180, 174), - QColor(179, 205, 227), - QColor(204, 235, 197), - QColor(222, 203, 228), - QColor(254, 217, 166), - QColor(255, 255, 204) - }; + //const QColor targetColors[] = { + // QColor(251, 180, 174), + // QColor(179, 205, 227), + // QColor(204, 235, 197), + // QColor(222, 203, 228), + // QColor(254, 217, 166), + // QColor(255, 255, 204) + //}; const QColor instrumentColors[] = { QColor(228, 26, 28), @@ -116,8 +118,7 @@ void TimelineWidget::drawContent(QPainter& painter, QRectF rect) { // Draw current time painter.setBrush(QBrush(Qt::black)); painter.drawLine(QPointF(0, timelineRect.height() / 2), QPointF(timelineRect.width(), timelineRect.height() / 2)); - painter.drawText(timelineRect.width(), timelineRect.height() / 2, QString::fromStdString(_currentTime.time)); - + painter.drawText(timelineRect.width(), timelineRect.height() / 2 + TextOffset, QString::fromStdString(_currentTime.time)); const double lowerTime = _currentTime.et - etSpread; const double upperTime = _currentTime.et + etSpread; @@ -135,18 +136,18 @@ void TimelineWidget::drawLegend(QPainter& painter, QRectF rect) { // Draw Targets int currentHorizontalPosition = Padding; int currentVerticalPosition = Padding; - for (int i = 0; i < _targets.size(); ++i) { + //for (int i = 0; i < _targets.size(); ++i) { - const std::string& target = _targets[i]; - - painter.setBrush(QBrush(targetColors[i])); - painter.drawRect(currentHorizontalPosition, currentVerticalPosition, BoxSize, BoxSize); - currentHorizontalPosition += BoxSize + Padding; + // const std::string& target = _targets[i]; + // + // painter.setBrush(QBrush(targetColors[i])); + // painter.drawRect(currentHorizontalPosition, currentVerticalPosition, BoxSize, BoxSize); + // currentHorizontalPosition += BoxSize + Padding; - painter.drawText(currentHorizontalPosition, currentVerticalPosition + BoxSize / 2, QString::fromStdString(target)); - int textWidth = painter.boundingRect(QRect(), QString::fromStdString(target)).width(); - currentHorizontalPosition += std::max(textWidth, 25) + Padding; - } + // painter.drawText(currentHorizontalPosition, currentVerticalPosition + BoxSize / 2 + TextOffset, QString::fromStdString(target)); + // int textWidth = painter.boundingRect(QRect(), QString::fromStdString(target)).width(); + // currentHorizontalPosition += std::max(textWidth, 25) + Padding; + //} // Draw Instruments currentHorizontalPosition = Padding; @@ -160,13 +161,13 @@ void TimelineWidget::drawLegend(QPainter& painter, QRectF rect) { const std::string& instrument = _instruments[i]; //painter.setBrush(QBrush(instrumentColors[i])); - painter.setBrush(Qt::NoBrush); + painter.setBrush(QBrush(instrumentColors[i])); painter.setPen(QPen(instrumentColors[i])); painter.drawRect(currentHorizontalPosition, currentVerticalPosition, BoxSize, BoxSize); currentHorizontalPosition += BoxSize + Padding; painter.setPen(QPen(Qt::black)); - painter.drawText(currentHorizontalPosition, currentVerticalPosition + BoxSize / 2, QString::fromStdString(instrument)); + painter.drawText(currentHorizontalPosition, currentVerticalPosition + BoxSize / 2 + TextOffset, QString::fromStdString(instrument)); int textWidth = painter.boundingRect(QRect(), QString::fromStdString(instrument)).width(); currentHorizontalPosition += std::max(textWidth, 25) + Padding; } @@ -181,25 +182,26 @@ void TimelineWidget::setCurrentTime(std::string currentTime, double et) { void TimelineWidget::drawImages( QPainter& painter, - QRectF rect, + QRectF timelineRect, std::vector::const_iterator beginning, std::vector::const_iterator ending, double minimumTime, double maximumTime) { - int width = rect.width(); + int width = timelineRect.width(); for (std::vector::const_iterator cur = beginning; cur <= ending; ++cur) { - //double tBeg = (cur->beginning - minimumTime) / (maximumTime - minimumTime); - //double tEnd = (cur->ending - minimumTime) / (maximumTime - minimumTime); - double t = (cur->beginning - minimumTime) / (maximumTime - minimumTime); + double tBeg = (cur->beginning - minimumTime) / (maximumTime - minimumTime); + double tEnd = (cur->ending - minimumTime) / (maximumTime - minimumTime); + //double t = (cur->ending - minimumTime) / (maximumTime - minimumTime); - int loc = rect.top() + rect.height() * t; - int height = 25; + int loc = timelineRect.top() + timelineRect.height() * tBeg; + int height = (timelineRect.top() + timelineRect.height() * tEnd) - loc; + height = std::max(height, 5); std::string target = cur->target; auto it = std::find(_targets.begin(), _targets.end(), target); int iTarget = std::distance(_targets.begin(), it); - QColor targetColor = targetColors[iTarget]; + //QColor targetColor = targetColors[iTarget]; std::vector instruments = cur->instruments; std::vector colors; @@ -209,11 +211,23 @@ void TimelineWidget::drawImages( colors.push_back(instrumentColors[i]); } - painter.setBrush(QBrush(targetColor)); - if (colors.empty())) - painter.setPen(QPen(Qt::black)); + //painter.setBrush(QBrush(targetColor)); + if (colors.empty()) + painter.setBrush(QBrush(Qt::black)); else - painter.setPen(QPen(colors[0])); - painter.drawRect(0, loc, rect.width(), height); + painter.setBrush(QBrush(colors[0])); + painter.drawRect(0, loc, timelineRect.width(), height); + + painter.setBrush(QBrush(Qt::black)); + painter.setPen(QPen(Qt::black)); + //QString firstLine = QString::fromStdString(cur->beginningString); + //QString secondLine = QString::fromStdString(cur->target); + QString line = QString::fromStdString(cur->beginningString) + QString("(") + QString::fromStdString(cur->target) + QString(")"); + + painter.drawText(timelineRect.width(), loc + height / 2 + TextOffset, line); + + //painter.drawText(timelineRect.width(), loc + height / 2 - 1.5 * TextOffset, firstLine); + //painter.drawText(timelineRect.width(), loc + height / 2 + 1.5 * TextOffset, secondLine); + } } diff --git a/gui/timelineview/timelinewidget.h b/gui/timelineview/timelinewidget.h index 8ed55e44af..e8dbd02b8b 100644 --- a/gui/timelineview/timelinewidget.h +++ b/gui/timelineview/timelinewidget.h @@ -47,7 +47,7 @@ protected: void paintEvent(QPaintEvent* event); void drawContent(QPainter& painter, QRectF rect); void drawLegend(QPainter& painter, QRectF rect); - void drawImages(QPainter& painter, QRectF rect, std::vector::const_iterator beginning, std::vector::const_iterator ending, double minimumTime, double maximumTime); + void drawImages(QPainter& painter, QRectF timelineRect, std::vector::const_iterator beginning, std::vector::const_iterator ending, double minimumTime, double maximumTime); private: std::vector _images; From 4451bbe920aab5a49cbf37e0b11546cf09671184 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 4 May 2015 17:29:18 +0200 Subject: [PATCH 37/45] More work on timeline application Only showing the images that are inside of the timeline Disabling all widgets when no connection is established --- gui/timelineview/configurationwidget.cpp | 6 +++++ gui/timelineview/configurationwidget.h | 3 +++ gui/timelineview/controlwidget.cpp | 8 +++++++ gui/timelineview/controlwidget.h | 4 +++- gui/timelineview/informationwidget.cpp | 8 +++++++ gui/timelineview/informationwidget.h | 2 ++ gui/timelineview/mainwindow.cpp | 30 ++++++++++++++++++++---- gui/timelineview/mainwindow.h | 3 +++ gui/timelineview/timelinewidget.cpp | 20 +++++++++++++++- gui/timelineview/timelinewidget.h | 2 ++ 10 files changed, 79 insertions(+), 7 deletions(-) diff --git a/gui/timelineview/configurationwidget.cpp b/gui/timelineview/configurationwidget.cpp index 38b4526546..8f2043fed5 100644 --- a/gui/timelineview/configurationwidget.cpp +++ b/gui/timelineview/configurationwidget.cpp @@ -46,3 +46,9 @@ ConfigurationWidget::ConfigurationWidget(QWidget* parent) void ConfigurationWidget::onConnectButton() { emit connect(_ipAddress->text(), _port->text()); } + +void ConfigurationWidget::socketConnected() { +} + +void ConfigurationWidget::socketDisconnected() { +} diff --git a/gui/timelineview/configurationwidget.h b/gui/timelineview/configurationwidget.h index 2c6291a13c..ae6fd8b654 100644 --- a/gui/timelineview/configurationwidget.h +++ b/gui/timelineview/configurationwidget.h @@ -34,6 +34,9 @@ Q_OBJECT public: ConfigurationWidget(QWidget* parent); + void socketConnected(); + void socketDisconnected(); + signals: void connect(QString host, QString port); diff --git a/gui/timelineview/controlwidget.cpp b/gui/timelineview/controlwidget.cpp index 964c34ce55..1bd65f0c7c 100644 --- a/gui/timelineview/controlwidget.cpp +++ b/gui/timelineview/controlwidget.cpp @@ -212,3 +212,11 @@ void ControlWidget::onFocusChange() { QString script = "openspace.setOrigin('" + name + "');openspace.changeCoordinateSystem('" + coordinateSystem + "');"; emit scriptActivity(script); } + +void ControlWidget::socketConnected() { + setDisabled(false); +} + +void ControlWidget::socketDisconnected() { + setDisabled(true); +} diff --git a/gui/timelineview/controlwidget.h b/gui/timelineview/controlwidget.h index f4d78ae676..970040cfb7 100644 --- a/gui/timelineview/controlwidget.h +++ b/gui/timelineview/controlwidget.h @@ -39,6 +39,9 @@ public: void update(QString currentTime, QString currentDelta); + void socketConnected(); + void socketDisconnected(); + signals: void scriptActivity(QString script); @@ -51,7 +54,6 @@ private slots: void onPlayButton(); void onForwardButton(); - private: QLabel* _currentTime; QComboBox* _setTime; diff --git a/gui/timelineview/informationwidget.cpp b/gui/timelineview/informationwidget.cpp index f53147b510..0647f9fb32 100644 --- a/gui/timelineview/informationwidget.cpp +++ b/gui/timelineview/informationwidget.cpp @@ -31,3 +31,11 @@ InformationWidget::InformationWidget(QWidget* parent) : QTextEdit(parent) { } + +void InformationWidget::socketConnected() { + setDisabled(false); +} + +void InformationWidget::socketDisconnected() { + setDisabled(true); +} diff --git a/gui/timelineview/informationwidget.h b/gui/timelineview/informationwidget.h index b0f4df3aed..abf56897a9 100644 --- a/gui/timelineview/informationwidget.h +++ b/gui/timelineview/informationwidget.h @@ -31,6 +31,8 @@ class InformationWidget : public QTextEdit { Q_OBJECT public: InformationWidget(QWidget* parent); + void socketConnected(); + void socketDisconnected(); }; #endif // __INFORMATIONWIDGET_H__ diff --git a/gui/timelineview/mainwindow.cpp b/gui/timelineview/mainwindow.cpp index 16342cf91f..2de8575a57 100644 --- a/gui/timelineview/mainwindow.cpp +++ b/gui/timelineview/mainwindow.cpp @@ -90,8 +90,12 @@ MainWindow::MainWindow() this, SLOT(sendScript(QString)) ); - setLayout(layout); + + _configurationWidget->socketDisconnected(); + _timeControlWidget->socketDisconnected(); + _informationWidget->socketDisconnected(); + _timelineWidget->socketDisconnected(); } MainWindow::~MainWindow() { @@ -102,10 +106,11 @@ void MainWindow::onConnect(QString host, QString port) { delete _socket; _socket = new QTcpSocket(this); - connect(_socket, SIGNAL(readyRead()), SLOT(readTcpData())); - _socket->connectToHost(host, port.toUInt()); + QObject::connect(_socket, SIGNAL(readyRead()), SLOT(readTcpData())); + QObject::connect(_socket, SIGNAL(connected()), SLOT(onSocketConnected())); + QObject::connect(_socket, SIGNAL(disconnected()), SLOT(onSocketDisconnected())); - _socket->write(QString("1\r\n").toLatin1()); + _socket->connectToHost(host, port.toUInt()); } @@ -228,11 +233,26 @@ void MainWindow::handlePlaybook(QByteArray data) { } _timelineWidget->setData(std::move(images), std::move(targetMap), std::move(instrumentMap)); -} + _configurationWidget->socketConnected(); + _timeControlWidget->socketConnected(); + _informationWidget->socketConnected(); + _timelineWidget->socketConnected(); +} void MainWindow::sendScript(QString script) { if (_socket) _socket->write(("0" + script + "\r\n").toLatin1()); } +void MainWindow::onSocketConnected() { + _socket->write(QString("1\r\n").toLatin1()); +} + +void MainWindow::onSocketDisconnected() { + _configurationWidget->socketDisconnected(); + _timeControlWidget->socketDisconnected(); + _informationWidget->socketDisconnected(); + _timelineWidget->socketDisconnected(); +} + diff --git a/gui/timelineview/mainwindow.h b/gui/timelineview/mainwindow.h index cf30e8bfa2..594e400583 100644 --- a/gui/timelineview/mainwindow.h +++ b/gui/timelineview/mainwindow.h @@ -47,6 +47,9 @@ public slots: private slots: void onConnect(QString host, QString port); + void onSocketConnected(); + void onSocketDisconnected(); + //void onConnectButton(); //void sendCommandButton(); void readTcpData(); diff --git a/gui/timelineview/timelinewidget.cpp b/gui/timelineview/timelinewidget.cpp index aea1d27e05..cb6bbb2e6d 100644 --- a/gui/timelineview/timelinewidget.cpp +++ b/gui/timelineview/timelinewidget.cpp @@ -28,6 +28,7 @@ #include #include +#include #include namespace { @@ -189,9 +190,11 @@ void TimelineWidget::drawImages( { int width = timelineRect.width(); - for (std::vector::const_iterator cur = beginning; cur <= ending; ++cur) { + for (std::vector::const_iterator cur = beginning; cur < ending; ++cur) { double tBeg = (cur->beginning - minimumTime) / (maximumTime - minimumTime); + tBeg = std::max(tBeg, 0.0); double tEnd = (cur->ending - minimumTime) / (maximumTime - minimumTime); + tEnd = std::min(tEnd, 1.0); //double t = (cur->ending - minimumTime) / (maximumTime - minimumTime); int loc = timelineRect.top() + timelineRect.height() * tBeg; @@ -230,4 +233,19 @@ void TimelineWidget::drawImages( //painter.drawText(timelineRect.width(), loc + height / 2 + 1.5 * TextOffset, secondLine); } + + painter.setPen(QPen(Qt::green)); + int _tmp = timelineRect.top() + timelineRect.height() * 1.0; + painter.drawLine(QPointF(0, _tmp), QPointF(timelineRect.width(), _tmp)); +} + +void TimelineWidget::socketConnected() { + setDisabled(false); +} + +void TimelineWidget::socketDisconnected() { + setDisabled(true); + _images.clear(); + _instruments.clear(); + _targets.clear(); } diff --git a/gui/timelineview/timelinewidget.h b/gui/timelineview/timelinewidget.h index e8dbd02b8b..f658d4f3a3 100644 --- a/gui/timelineview/timelinewidget.h +++ b/gui/timelineview/timelinewidget.h @@ -42,6 +42,8 @@ public: void setData(std::vector images, std::map targetMap, std::map instrumentMap); void setCurrentTime(std::string currentTime, double et); + void socketConnected(); + void socketDisconnected(); protected: void paintEvent(QPaintEvent* event); From fde0d10199c57b7d7c2540ac40a1a96e6e45c959 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 4 May 2015 18:31:17 +0200 Subject: [PATCH 38/45] Fix error with instrument transmission over the network --- gui/timelineview/mainwindow.cpp | 16 +++++-- gui/timelineview/timelinewidget.cpp | 73 +++++++++++++++-------------- gui/timelineview/timelinewidget.h | 2 +- src/util/hongkangparser.cpp | 6 ++- 4 files changed, 56 insertions(+), 41 deletions(-) diff --git a/gui/timelineview/mainwindow.cpp b/gui/timelineview/mainwindow.cpp index 2de8575a57..3574f4dbfe 100644 --- a/gui/timelineview/mainwindow.cpp +++ b/gui/timelineview/mainwindow.cpp @@ -187,8 +187,12 @@ std::vector instrumentsFromId(uint16_t instrumentId, std::map results; for (int i = 0; i < 16; ++i) { uint16_t testValue = 1 << i; - if ((testValue & instrumentId) == 1) - results.push_back(instrumentMap[testValue]); + if ((testValue & instrumentId) != 0) { + std::string t = instrumentMap.at(testValue); + if (t.empty()) + qDebug() << "Empty instrument"; + results.push_back(t); + } } return results; } @@ -200,18 +204,22 @@ void MainWindow::handlePlaybook(QByteArray data) { uint32_t totalData = readFromBuffer(buffer, currentReadLocation); uint8_t nTargets = readFromBuffer(buffer, currentReadLocation); + qDebug() << "Targets: " << nTargets; std::map targetMap; for (uint8_t i = 0; i < nTargets; ++i) { uint8_t id = readFromBuffer(buffer, currentReadLocation); std::string value = readFromBuffer(buffer, currentReadLocation); + qDebug() << QString::fromStdString(value); targetMap[id] = value; } uint8_t nInstruments = readFromBuffer(buffer, currentReadLocation); + qDebug() << "Instruments: " << nInstruments; std::map instrumentMap; for (uint8_t i = 0; i < nInstruments; ++i) { - uint8_t id = readFromBuffer(buffer, currentReadLocation); + uint16_t id = readFromBuffer(buffer, currentReadLocation); std::string value = readFromBuffer(buffer, currentReadLocation); + qDebug() << QString::fromStdString(value); instrumentMap[id] = value; } @@ -229,6 +237,8 @@ void MainWindow::handlePlaybook(QByteArray data) { uint16_t instrumentId = readFromBuffer(buffer, currentReadLocation); image.target = targetMap[targetId]; image.instruments = instrumentsFromId(instrumentId, instrumentMap); + if (image.instruments.empty()) + qDebug() << "Instruments were empty"; images.push_back(image); } diff --git a/gui/timelineview/timelinewidget.cpp b/gui/timelineview/timelinewidget.cpp index cb6bbb2e6d..92360afb22 100644 --- a/gui/timelineview/timelinewidget.cpp +++ b/gui/timelineview/timelinewidget.cpp @@ -116,17 +116,21 @@ void TimelineWidget::drawContent(QPainter& painter, QRectF rect) { painter.setBrush(QBrush(Qt::white)); painter.drawRect(timelineRect); painter.setBrush(QBrush(Qt::gray)); painter.drawRect(dateRect); - // Draw current time - painter.setBrush(QBrush(Qt::black)); - painter.drawLine(QPointF(0, timelineRect.height() / 2), QPointF(timelineRect.width(), timelineRect.height() / 2)); - painter.drawText(timelineRect.width(), timelineRect.height() / 2 + TextOffset, QString::fromStdString(_currentTime.time)); - const double lowerTime = _currentTime.et - etSpread; const double upperTime = _currentTime.et + etSpread; std::vector::const_iterator lower = std::lower_bound(_images.begin(), _images.end(), lowerTime, [](const Image& i, double time) { return i.beginning < time; }); std::vector::const_iterator upper = std::lower_bound(_images.begin(), _images.end(), upperTime, [](const Image& i, double time) { return i.ending < time; }); if (lower != _images.end() && upper != _images.end()) - drawImages(painter, timelineRect, lower, upper, lowerTime, upperTime); + drawImages(painter, timelineRect, std::vector(lower, upper), lowerTime, upperTime); + + //drawImages(painter, timelineRect, _images, lowerTime, upperTime); + + + // Draw current time + painter.setBrush(QBrush(Qt::black)); + painter.setPen(QPen(Qt::black)); + painter.drawLine(QPointF(0, timelineRect.height() / 2), QPointF(timelineRect.width(), timelineRect.height() / 2)); + painter.drawText(timelineRect.width(), timelineRect.height() / 2 + TextOffset, QString::fromStdString(_currentTime.time)); } void TimelineWidget::drawLegend(QPainter& painter, QRectF rect) { @@ -184,59 +188,56 @@ void TimelineWidget::setCurrentTime(std::string currentTime, double et) { void TimelineWidget::drawImages( QPainter& painter, QRectF timelineRect, - std::vector::const_iterator beginning, - std::vector::const_iterator ending, + std::vector images, double minimumTime, double maximumTime) { int width = timelineRect.width(); - for (std::vector::const_iterator cur = beginning; cur < ending; ++cur) { - double tBeg = (cur->beginning - minimumTime) / (maximumTime - minimumTime); + int nInstruments = 0; + std::set instrumentSet; + for (const Image& i : images) { + for (std::string instrument : i.instruments) + instrumentSet.insert(instrument); + } + std::map instruments; + for (std::set::const_iterator it = instrumentSet.begin(); it != instrumentSet.end(); ++it) + instruments[*it] = std::distance(instrumentSet.begin(), it); + + for (const Image& i : images) { + double tBeg = (i.beginning - minimumTime) / (maximumTime - minimumTime); tBeg = std::max(tBeg, 0.0); - double tEnd = (cur->ending - minimumTime) / (maximumTime - minimumTime); + double tEnd = (i.ending - minimumTime) / (maximumTime - minimumTime); tEnd = std::min(tEnd, 1.0); - //double t = (cur->ending - minimumTime) / (maximumTime - minimumTime); int loc = timelineRect.top() + timelineRect.height() * tBeg; int height = (timelineRect.top() + timelineRect.height() * tEnd) - loc; height = std::max(height, 5); - std::string target = cur->target; + std::string target = i.target; auto it = std::find(_targets.begin(), _targets.end(), target); int iTarget = std::distance(_targets.begin(), it); - //QColor targetColor = targetColors[iTarget]; - std::vector instruments = cur->instruments; - std::vector colors; - for (std::string instrument : instruments) { + //std::vector colors; + for (std::string instrument : i.instruments) { auto it = std::find(_instruments.begin(), _instruments.end(), instrument); + if (it == _instruments.end()) + qDebug() << "Instrument not found"; int i = std::distance(_instruments.begin(), it); - colors.push_back(instrumentColors[i]); - } - //painter.setBrush(QBrush(targetColor)); - if (colors.empty()) - painter.setBrush(QBrush(Qt::black)); - else - painter.setBrush(QBrush(colors[0])); - painter.drawRect(0, loc, timelineRect.width(), height); + painter.setBrush(QBrush(instrumentColors[i])); + + double width = timelineRect.width() / instruments.size(); + double pos = instruments[instrument] * width; + + painter.drawRect(pos, loc, width, height); + } painter.setBrush(QBrush(Qt::black)); painter.setPen(QPen(Qt::black)); - //QString firstLine = QString::fromStdString(cur->beginningString); - //QString secondLine = QString::fromStdString(cur->target); - QString line = QString::fromStdString(cur->beginningString) + QString("(") + QString::fromStdString(cur->target) + QString(")"); + QString line = QString::fromStdString(i.beginningString) + QString(" (") + QString::fromStdString(i.target) + QString(")"); painter.drawText(timelineRect.width(), loc + height / 2 + TextOffset, line); - - //painter.drawText(timelineRect.width(), loc + height / 2 - 1.5 * TextOffset, firstLine); - //painter.drawText(timelineRect.width(), loc + height / 2 + 1.5 * TextOffset, secondLine); - } - - painter.setPen(QPen(Qt::green)); - int _tmp = timelineRect.top() + timelineRect.height() * 1.0; - painter.drawLine(QPointF(0, _tmp), QPointF(timelineRect.width(), _tmp)); } void TimelineWidget::socketConnected() { diff --git a/gui/timelineview/timelinewidget.h b/gui/timelineview/timelinewidget.h index f658d4f3a3..6dcb437c7a 100644 --- a/gui/timelineview/timelinewidget.h +++ b/gui/timelineview/timelinewidget.h @@ -49,7 +49,7 @@ protected: void paintEvent(QPaintEvent* event); void drawContent(QPainter& painter, QRectF rect); void drawLegend(QPainter& painter, QRectF rect); - void drawImages(QPainter& painter, QRectF timelineRect, std::vector::const_iterator beginning, std::vector::const_iterator ending, double minimumTime, double maximumTime); + void drawImages(QPainter& painter, QRectF timelineRect, std::vector images, double minimumTime, double maximumTime); private: std::vector _images; diff --git a/src/util/hongkangparser.cpp b/src/util/hongkangparser.cpp index 55802a7249..ae19165dc8 100644 --- a/src/util/hongkangparser.cpp +++ b/src/util/hongkangparser.cpp @@ -393,7 +393,7 @@ void HongKangParser::sendPlaybookInformation() { for (auto instrument : image.activeInstruments) { if (instrumentMap.find(instrument) == instrumentMap.end()) { instrumentMap[instrument] = currentInstrumentId; - currentInstrumentId = currentInstrumentId << 1; + currentInstrumentId = currentInstrumentId << 1; } } } @@ -432,6 +432,10 @@ void HongKangParser::sendPlaybookInformation() { uint8_t targetId = targetMap[target.first]; writeToBuffer(buffer, currentWriteLocation, targetId); uint16_t totalInstrumentId = 0; + if (image.activeInstruments.empty()) { + LERROR("Image had no active instruments"); + } + for (auto instrument : image.activeInstruments) { uint16_t thisInstrumentId = instrumentMap[instrument]; totalInstrumentId |= thisInstrumentId; From a993dfb42fa78ff908aecd5b2386351005860486 Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Mon, 4 May 2015 19:20:14 -0400 Subject: [PATCH 39/45] Storing frame-to-body relationship Store frames for bodies in SpiceManager, still adding "IAU_" if no frame is added for the body. Adding frames in renderableModel for 67p to get proper inertial frame. --- include/openspace/util/spicemanager.h | 18 +++++++++ src/rendering/model/renderablemodel.cpp | 2 + src/rendering/renderableplaneprojection.cpp | 2 +- src/util/spicemanager.cpp | 43 +++++++++++++++++---- 4 files changed, 56 insertions(+), 9 deletions(-) diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index 852e4cf386..f05f6cb329 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -630,6 +630,22 @@ public: */ bool getFieldOfView(int instrument, std::string& fovShape, std::string& frameName, glm::dvec3& boresightVector, std::vector& bounds) const; + + /** + * This function adds a frame to a body + * \param body - the name of the body + * \param frame - the name of the frame + * \return false if the arguments are empty + */ + bool addFrame(const std::string body, const std::string frame); + + /** + * This function returns the frame of a body if defined, otherwise it returns + * IAU_ + body (most frames are known by the International Astronomical Union) + * \param body - the name of the body + * \return the frame of the body + */ + std::string frameFromBody(const std::string body) const; /** * This method checks if one of the previous SPICE methods has failed. If it has, the @@ -673,6 +689,8 @@ private: std::map > > _spkIntervals; std::map > _ckCoverageTimes; std::map > _spkCoverageTimes; + // Vector of pairs: Body, Frame + std::vector< std::pair > _frameByBody; const static bool _showErrors = false; diff --git a/src/rendering/model/renderablemodel.cpp b/src/rendering/model/renderablemodel.cpp index 79dbc20762..76838fd328 100644 --- a/src/rendering/model/renderablemodel.cpp +++ b/src/rendering/model/renderablemodel.cpp @@ -96,6 +96,8 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) dictionary.getValue(keyDestination, _destination); dictionary.getValue(keyBody, _target); + openspace::SpiceManager::ref().addFrame(_target, _source); + setBoundingSphere(pss(1.f, 9.f)); addProperty(_performShading); diff --git a/src/rendering/renderableplaneprojection.cpp b/src/rendering/renderableplaneprojection.cpp index 206a37fe8f..67885de7a5 100644 --- a/src/rendering/renderableplaneprojection.cpp +++ b/src/rendering/renderableplaneprojection.cpp @@ -281,7 +281,7 @@ void RenderablePlaneProjection::setTarget(std::string body) { } if (found) { _target.body = body; - _target.frame = "IAU_" + body; + _target.frame = openspace::SpiceManager::ref().frameFromBody(body); } } diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index 2c1289e659..3f9b24d5d5 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -641,13 +641,12 @@ bool SpiceManager::targetWithinFieldOfView(const std::string& instrument, int visible; - std::string bodyfixed = "IAU_"; - bodyfixed += target; + std::string frame = frameFromBody(target); fovtrg_c(instrument.c_str(), target.c_str(), method.c_str(), - bodyfixed.c_str(), + frame.c_str(), aberrationCorrection.c_str(), observer.c_str(), &targetEpoch, @@ -688,9 +687,9 @@ bool SpiceManager::getSurfaceIntercept(const std::string& target, // allow client specify non-inertial frame. std::string bodyfixed = "IAU_"; convert = (referenceFrame.find(bodyfixed) == std::string::npos); - if (convert){ - bodyfixed += target; - }else{ + if (convert) { + bodyfixed = frameFromBody(target); + } else { bodyfixed = referenceFrame; } @@ -813,11 +812,11 @@ bool SpiceManager::getPositionTransformMatrix(const std::string& fromFrame, ephemerisTime, (double(*)[3])glm::value_ptr(positionMatrix)); success = !(failed_c()); - if (!success && !_showErrors) { + if (!success) { reset_c(); estimated = getEstimatedTransformMatrix(ephemerisTime, fromFrame, toFrame, positionMatrix); } - else { + if (_showErrors) { bool hasError = checkForError("Error retrieving position transform matrix from " "frame '" + fromFrame + "' to frame '" + toFrame + "' at time '" + std::to_string(ephemerisTime)); @@ -958,6 +957,34 @@ bool SpiceManager::getFieldOfView(int instrument, return true; } +std::string SpiceManager::frameFromBody(const std::string body) const { + + for (auto pair : _frameByBody) { + if (pair.first == body) { + return pair.second; + } + } + + std::string unionPrefix = "IAU_"; + std::string frame = ""; + + if (body.find(unionPrefix) == std::string::npos) + frame = unionPrefix + body; + else + frame = body; + + return frame; +} + +bool SpiceManager::addFrame(const std::string body, const std::string frame) { + if (body == "" || frame == "") + return false; + else { + _frameByBody.push_back(std::make_pair(body, frame)); + return true; + } +} + bool SpiceManager::checkForError(std::string errorMessage) { int failed = failed_c(); From d495778d4a65a2d3d9520dd0d14564170b832602 Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Mon, 4 May 2015 19:30:57 -0400 Subject: [PATCH 40/45] Restored some changes lost in merge + "timedots" Added impact on trails from start/stoptime definitions in modfile. Added dots of equal time in trails, no progress on printing the time string. --- include/openspace/rendering/renderabletrail.h | 1 + src/rendering/renderabletrail.cpp | 64 +++++++++++++++---- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/include/openspace/rendering/renderabletrail.h b/include/openspace/rendering/renderabletrail.h index b5c0bb93ad..4aecd34b16 100644 --- a/include/openspace/rendering/renderabletrail.h +++ b/include/openspace/rendering/renderabletrail.h @@ -63,6 +63,7 @@ private: properties::Vec3Property _lineColor; properties::FloatProperty _lineFade; properties::FloatProperty _lineWidth; + properties::BoolProperty _showTimestamps; ghoul::opengl::ProgramObject* _programObject; bool _programIsDirty; diff --git a/src/rendering/renderabletrail.cpp b/src/rendering/renderabletrail.cpp index 689d9eb55a..5d2c8f4b1e 100644 --- a/src/rendering/renderabletrail.cpp +++ b/src/rendering/renderabletrail.cpp @@ -52,6 +52,7 @@ namespace { const std::string keyTropicalOrbitPeriod = "TropicalOrbitPeriod"; const std::string keyEarthOrbitRatio = "EarthOrbitRatio"; const std::string keyDayLength = "DayLength"; + const std::string keyStamps = "Timestamps"; } namespace openspace { @@ -68,6 +69,7 @@ RenderableTrail::RenderableTrail(const ghoul::Dictionary& dictionary) , _oldTime(std::numeric_limits::max()) , _successfullDictionaryFetch(true) , _needsSweep(true) + , _showTimestamps("timestamps", "Show Timestamps", false) { _successfullDictionaryFetch &= dictionary.getValue(keyBody, _target); _successfullDictionaryFetch &= dictionary.getValue(keyObserver, _observer); @@ -84,6 +86,10 @@ RenderableTrail::RenderableTrail(const ghoul::Dictionary& dictionary) dictionary.getValue(keyColor, color); _lineColor = color; + if (dictionary.hasKeyAndValue(keyStamps)) + dictionary.getValue(keyStamps, _showTimestamps); + addProperty(_showTimestamps); + _lineColor.setViewOption(properties::Property::ViewOptions::Color); addProperty(_lineColor); @@ -165,12 +171,18 @@ void RenderableTrail::render(const RenderData& data) { glLineWidth(1.f); + if (_showTimestamps){ + glPointSize(5.f); + glBindVertexArray(_vaoID); + glDrawArrays(GL_POINTS, 0, _vertexArray.size()); + glBindVertexArray(0); + } + _programObject->deactivate(); } void RenderableTrail::update(const UpdateData& data) { - _time = data.time; - if (data.isTimeJump) + if (data.isTimeJump) _needsSweep = true; if (_needsSweep) { @@ -185,7 +197,14 @@ void RenderableTrail::update(const UpdateData& data) { _programIsDirty = false; } double lightTime = 0.0; - psc pscPos, pscVel; + psc pscPos; + + bool intervalSet = hasTimeInterval(); + double start = DBL_MIN; + double end = DBL_MAX; + if (intervalSet) { + getInterval(start, end); + } // Points in the vertex array should always have a fixed distance. For this reason we // keep the first entry in the array floating and always pointing to the current date @@ -195,9 +214,13 @@ void RenderableTrail::update(const UpdateData& data) { int nValues = floor(deltaTime / _increment); // Update the floating current time - // Is 'CN+S' correct? It has to be chosen to be the same as in SpiceEphemeris, but - // unsure if it is correct ---abock - SpiceManager::ref().getTargetState(_target, _observer, _frame, "NONE", data.time, pscPos, pscVel, lightTime); + if (start > data.time) + SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", start, pscPos, lightTime); + else if (end < data.time) + SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", end, pscPos, lightTime); + else + SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", data.time, pscPos, lightTime); + pscPos[3] += 3; // KM to M _vertexArray[0] = { pscPos[0], pscPos[1], pscPos[2], pscPos[3] }; @@ -212,8 +235,12 @@ void RenderableTrail::update(const UpdateData& data) { for (int i = nValues; i > 0; --i) { double et = _oldTime + i * _increment; - SpiceManager::ref().getTargetState(_target, _observer, _frame, "CN+S", et, pscPos, pscVel, lightTime); - pscPos[3] += 3; + if (start > et) + et = start; + else if (end < et) + et = end; + SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", et, pscPos, lightTime); + pscPos[3] += 3; _vertexArray[i] = { pscPos[0], pscPos[1], pscPos[2], pscPos[3] }; } @@ -241,15 +268,28 @@ void RenderableTrail::fullYearSweep(double time) { float planetYear = SecondsPerEarthYear * _ratio; int segments = static_cast(_tropic); + bool intervalSet = hasTimeInterval(); + double start = DBL_MIN; + double end = DBL_MAX; + if (intervalSet) { + getInterval(start, end); + } + _increment = planetYear / _tropic; _oldTime = time; - psc pscPos, pscVel; + psc pscPos; + bool validPosition = true; _vertexArray.resize(segments+2); - for (int i = 0; i < segments+2; i++){ - SpiceManager::ref().getTargetState(_target, _observer, _frame, "CN+S", time, pscPos, pscVel, lightTime); - pscPos[3] += 3; + for (int i = 0; i < segments+2; i++) { + if (start > time) + time = start; + else if (end < time) + time = end; + + SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", time, pscPos, lightTime); + pscPos[3] += 3; _vertexArray[i] = {pscPos[0], pscPos[1], pscPos[2], pscPos[3]}; time -= _increment; From 17064a92d5e18e50c314496dbb98ac6c50be92d2 Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Mon, 4 May 2015 19:40:08 -0400 Subject: [PATCH 41/45] Modifying labelparser and imagesequencer2 For extension to handling other instruments than lorri --- include/openspace/util/labelparser.h | 1 + src/rendering/renderablefov.cpp | 3 ++- src/util/imagesequencer2.cpp | 2 +- src/util/labelparser.cpp | 30 +++++++++++++++++++++++----- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/include/openspace/util/labelparser.h b/include/openspace/util/labelparser.h index 738de59552..cea2dce8aa 100644 --- a/include/openspace/util/labelparser.h +++ b/include/openspace/util/labelparser.h @@ -56,6 +56,7 @@ private: std::string path); std::string decode(std::string line); + std::string encode(std::string line); bool augmentWithSpice(Image& image, std::string spacecraft, diff --git a/src/rendering/renderablefov.cpp b/src/rendering/renderablefov.cpp index cb57a15379..71e425c1c1 100644 --- a/src/rendering/renderablefov.cpp +++ b/src/rendering/renderablefov.cpp @@ -333,7 +333,8 @@ void RenderableFov::fovProjection(bool H[], std::vector bounds){ } if (_nrInserted == 0){ _rebuild = false; - }else{ + } + else { _rebuild = true; //update size etc; _vtotal[1] = _nrInserted; diff --git a/src/util/imagesequencer2.cpp b/src/util/imagesequencer2.cpp index bf5d64ac1a..1ef6cc6baf 100644 --- a/src/util/imagesequencer2.cpp +++ b/src/util/imagesequencer2.cpp @@ -203,7 +203,7 @@ bool ImageSequencer2::getImagePaths(std::vector& captures, if (!instumentActive(instrumentID) && !Time::ref().timeJumped()) return false; // dev. note: this is only due to LORRI being the only instrument implemented so far. - return (instrumentID == "NH_LORRI") ? getImagePaths(captures, projectee) : false; + return getImagePaths(captures, projectee); } bool ImageSequencer2::getImagePaths(std::vector& captures, diff --git a/src/util/labelparser.cpp b/src/util/labelparser.cpp index 9a0f7a39a2..7ea41621d8 100644 --- a/src/util/labelparser.cpp +++ b/src/util/labelparser.cpp @@ -74,10 +74,10 @@ LabelParser::LabelParser(const std::string& fileName, typeDictionary.getValue(keySpecs, specsOfInterestDictionary); _specsOfInterest.resize(specsOfInterestDictionary.size()); - for (int i = 0; i < _specsOfInterest.size(); ++i) { + for (int n = 0; n < _specsOfInterest.size(); ++n) { std::string readMe; - specsOfInterestDictionary.getValue(std::to_string(i + 1), readMe); - _specsOfInterest[i] = readMe; + specsOfInterestDictionary.getValue(std::to_string(n + 1), readMe); + _specsOfInterest[n] = readMe; } ghoul::Dictionary convertDictionary; typeDictionary.getValue(keyConvert, convertDictionary); @@ -103,6 +103,18 @@ std::string LabelParser::decode(std::string line){ return _fileTranslation[toTranslate]->getTranslation()[0]; //lbls always 1:1 -> single value return. } } + return ""; +} + +std::string LabelParser::encode(std::string line) { + for (auto key : _fileTranslation) { + std::size_t value = line.find(key.first); + if (value != std::string::npos) { + //std::cout << line.substr(value) << std::endl; + return line.substr(value); + } + } + return ""; } void LabelParser::create(){ @@ -114,16 +126,18 @@ void LabelParser::create(){ return a.first < b.first; }; std::string previousTarget; + std::string lblName = ""; ghoul::filesystem::Directory sequenceDir(_fileName, true); std::vector sequencePaths = sequenceDir.read(true, false); // check inputs for (auto path : sequencePaths){ + //std::cout << path << std::endl; if (size_t position = path.find_last_of(".") + 1){ if (position != std::string::npos){ ghoul::filesystem::File currentFile(path); std::string extension = currentFile.fileExtension(); - if (extension == "lbl"){ // discovered header file + if (extension == "lbl" || extension == "LBL"){ // discovered header file std::ifstream file(currentFile.path()); if (!file.good()) LERROR("Failed to open label file '" << currentFile.path() << "'"); @@ -154,6 +168,7 @@ void LabelParser::create(){ } if (read == "INSTRUMENT_ID"){ _instrumentID = decode(line); + lblName = encode(line); count++; } if (read == "DETECTOR_TYPE"){ @@ -184,6 +199,11 @@ void LabelParser::create(){ std::string ext = "jpg"; path.replace(path.begin() + position, path.end(), ext); bool fileExists = FileSys.fileExists(path); + if (!fileExists) { + ext = "JPG"; + path.replace(path.begin() + position, path.end(), ext); + fileExists = FileSys.fileExists(path); + } if (fileExists) { Image image; std::vector spiceInstrument; @@ -226,7 +246,7 @@ void LabelParser::create(){ //print all for (auto target : _subsetMap){ - _instrumentTimes.push_back(std::make_pair("LORRI", _subsetMap[target.first]._range)); + _instrumentTimes.push_back(std::make_pair(lblName, _subsetMap[target.first]._range)); std::string min, max; SpiceManager::ref().getDateFromET(target.second._range._min, min); SpiceManager::ref().getDateFromET(target.second._range._max, max); From f8d6f42f441e8a55c8b1dbf7317c7866f20d6a64 Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Mon, 4 May 2015 19:52:56 -0400 Subject: [PATCH 42/45] Default startup + renderengine fixes Added interesting times for Dawn and Rosetta in default startup script. Fixed coordinate system switch to Vesta, commented for demo but needed for development. --- scripts/default_startup.lua | 4 ++++ src/rendering/renderengine.cpp | 37 ++++++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/scripts/default_startup.lua b/scripts/default_startup.lua index 6ef57e5c0e..9d7089981b 100644 --- a/scripts/default_startup.lua +++ b/scripts/default_startup.lua @@ -9,6 +9,10 @@ openspace.setInvertRoll(true); --openspace.time.setTime("2007 FEB 28 03:45:00") -- Io Capture! + +--openspace.time.setTime("2011 AUG 6 07:15:00") -- Dawn @ Vestaprojection +--openspace.time.setTime("2014 AUG 28 03:45:00") -- Rosetta Travels 67p in triangular shape + openspace.time.setDeltaTime(10) -- How many seconds pass per second of realtime, changeable in the GUI dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) -- Load the default keybindings diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 02b9cb4881..1594700989 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -539,18 +539,18 @@ namespace openspace { int i = 0; PrintText(i++, "Date: %s", Time::ref().currentTimeUTC().c_str()); - /* PrintText(i++, "Avg. Frametime: %.5f", sgct::Engine::instance()->getAvgDt()); PrintText(i++, "Drawtime: %.5f", sgct::Engine::instance()->getDrawTime()); PrintText(i++, "Frametime: %.5f", sgct::Engine::instance()->getDt()); + /* PrintText(i++, "Origin: (% .5f, % .5f, % .5f, % .5f)", origin[0], origin[1], origin[2], origin[3]); PrintText(i++, "Cam pos: (% .5f, % .5f, % .5f, % .5f)", position[0], position[1], position[2], position[3]); PrintText(i++, "View dir: (% .5f, % .5f, % .5f)", viewdirection[0], viewdirection[1], viewdirection[2]); PrintText(i++, "Cam->origin: (% .15f, % .4f)", pssl[0], pssl[1]); PrintText(i++, "Scaling: (% .5f, % .5f)", scaling[0], scaling[1]); */ - - if (openspace::ImageSequencer2::ref().isReady()){ + + if (openspace::ImageSequencer2::ref().isReady()) { double remaining = openspace::ImageSequencer2::ref().getNextCaptureTime() - currentTime; double t = 1.f - remaining / openspace::ImageSequencer2::ref().getIntervalLength(); std::string progress = "|"; @@ -983,7 +983,7 @@ void RenderEngine::changeViewPoint(std::string origin) { if (solarSystemBarycenterNode == nullptr || plutoBarycenterNode == nullptr || newHorizonsNode == nullptr || jupiterBarycenterNode == nullptr //|| dawnNode == nullptr - //|| vestaNode == nullptr + //|| vestaNode == nullptr ) { LERROR("Necessary nodes does not exist"); return; @@ -995,6 +995,10 @@ void RenderEngine::changeViewPoint(std::string origin) { solarSystemBarycenterNode->setParent(plutoBarycenterNode); newHorizonsNode->setParent(plutoBarycenterNode); + + //dawnNode->setParent(plutoBarycenterNode); + //vestaNode->setParent(plutoBarycenterNode); + //newHorizonsTrailNode->setParent(plutoBarycenterNode); ghoul::Dictionary solarDictionary = { @@ -1069,6 +1073,8 @@ void RenderEngine::changeViewPoint(std::string origin) { jupiterBarycenterNode->setParent(solarSystemBarycenterNode); newHorizonsNode->setParent(solarSystemBarycenterNode); //newHorizonsTrailNode->setParent(solarSystemBarycenterNode); + //dawnNode->setParent(solarSystemBarycenterNode); + //vestaNode->setParent(solarSystemBarycenterNode); ghoul::Dictionary plutoDictionary = { @@ -1144,6 +1150,10 @@ void RenderEngine::changeViewPoint(std::string origin) { newHorizonsNode->setParent(jupiterBarycenterNode); //newHorizonsTrailNode->setParent(jupiterBarycenterNode); + //dawnNode->setParent(jupiterBarycenterNode); + //vestaNode->setParent(jupiterBarycenterNode); + + ghoul::Dictionary solarDictionary = { { std::string("Type"), std::string("Spice") }, @@ -1157,7 +1167,7 @@ void RenderEngine::changeViewPoint(std::string origin) { { { std::string("Type"), std::string("Spice") }, { std::string("Body"), std::string("PlUTO BARYCENTER") }, - { std::string("Reference"), std::string("ECLIPJ2000") }, + { std::string("Reference"), std::string("GALACTIC") }, { std::string("Observer"), std::string("JUPITER BARYCENTER") }, { std::string("Kernels"), ghoul::Dictionary() } }; @@ -1211,11 +1221,22 @@ void RenderEngine::changeViewPoint(std::string origin) { return; } //if (origin == "Vesta") { + // + // vestaNode->setParent(scene()->sceneGraphNode("SolarSystem")); + // vestaNode->setEphemeris(new StaticEphemeris); + // + // solarSystemBarycenterNode->setParent(vestaNode); + // newHorizonsNode->setParent(vestaNode); + // + // dawnNode->setParent(vestaNode); + // plutoBarycenterNode->setParent(vestaNode); + // + // // ghoul::Dictionary plutoDictionary = // { // { std::string("Type"), std::string("Spice") }, // { std::string("Body"), std::string("PLUTO BARYCENTER") }, - // { std::string("Reference"), std::string("ECLIPJ2000") }, + // { std::string("Reference"), std::string("GALACTIC") }, // { std::string("Observer"), std::string("VESTA") }, // { std::string("Kernels"), ghoul::Dictionary() } // }; @@ -1223,7 +1244,7 @@ void RenderEngine::changeViewPoint(std::string origin) { // { // { std::string("Type"), std::string("Spice") }, // { std::string("Body"), std::string("SUN") }, - // { std::string("Reference"), std::string("ECLIPJ2000") }, + // { std::string("Reference"), std::string("GALACTIC") }, // { std::string("Observer"), std::string("VESTA") }, // { std::string("Kernels"), ghoul::Dictionary() } // }; @@ -1232,7 +1253,7 @@ void RenderEngine::changeViewPoint(std::string origin) { // { // { std::string("Type"), std::string("Spice") }, // { std::string("Body"), std::string("JUPITER BARYCENTER") }, - // { std::string("Reference"), std::string("ECLIPJ2000") }, + // { std::string("Reference"), std::string("GALACTIC") }, // { std::string("Observer"), std::string("VESTA") }, // { std::string("Kernels"), ghoul::Dictionary() } // }; From 0a1c0164ef7b28e9b47c27a9b96d4c4cc21fd2da Mon Sep 17 00:00:00 2001 From: Michal Marcinkowski Date: Mon, 4 May 2015 20:15:34 -0400 Subject: [PATCH 43/45] Fixes to trails, fov and adding some keybindings --- config/sgct/single.xml | 2 +- .../rendering/model/renderablemodel.h | 1 + include/openspace/rendering/renderablefov.h | 1 + include/openspace/scene/spiceephemeris.h | 2 + openspace-data | 2 +- scripts/bind_keys.lua | 14 ++++++ shaders/model_fs.glsl | 6 +-- shaders/projectiveTexture_fs.glsl | 2 +- src/rendering/model/renderablemodel.cpp | 47 +++++++++++++++---- .../planets/renderableplanetprojection.cpp | 7 +-- src/rendering/renderablefov.cpp | 34 +++++++++++--- src/rendering/renderableplaneprojection.cpp | 5 +- src/rendering/renderabletrail.cpp | 4 +- src/rendering/renderengine.cpp | 32 ++++++++----- src/scene/spiceephemeris.cpp | 13 ++--- 15 files changed, 127 insertions(+), 45 deletions(-) diff --git a/config/sgct/single.xml b/config/sgct/single.xml index 24f762d6a4..8086791404 100644 --- a/config/sgct/single.xml +++ b/config/sgct/single.xml @@ -31,6 +31,6 @@ - + \ No newline at end of file diff --git a/include/openspace/rendering/model/renderablemodel.h b/include/openspace/rendering/model/renderablemodel.h index eac92234b5..2522d136df 100644 --- a/include/openspace/rendering/model/renderablemodel.h +++ b/include/openspace/rendering/model/renderablemodel.h @@ -71,6 +71,7 @@ private: std::string _destination; std::string _target; + bool _isGhost; psc _sunPosition; diff --git a/include/openspace/rendering/renderablefov.h b/include/openspace/rendering/renderablefov.h index 929156e9c5..79516b8083 100644 --- a/include/openspace/rendering/renderablefov.h +++ b/include/openspace/rendering/renderablefov.h @@ -53,6 +53,7 @@ public: private: properties::FloatProperty _lineWidth; + properties::BoolProperty _drawSolid; ghoul::opengl::ProgramObject* _programObject; ghoul::opengl::Texture* _texture; openspace::SceneGraphNode* _targetNode; diff --git a/include/openspace/scene/spiceephemeris.h b/include/openspace/scene/spiceephemeris.h index c01ea527f7..a5381223cf 100644 --- a/include/openspace/scene/spiceephemeris.h +++ b/include/openspace/scene/spiceephemeris.h @@ -42,6 +42,8 @@ private: std::string _originName; psc _position; bool _kernelsLoadedSuccessfully; + std::string _ghosting; + std::string _name; }; } // namespace openspace diff --git a/openspace-data b/openspace-data index f39bdf433e..d03aa05d72 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit f39bdf433e9f8e85ded9be7375c2c2e7d0050923 +Subproject commit d03aa05d729b564a2ac1dfafbcaac24da4cba614 diff --git a/scripts/bind_keys.lua b/scripts/bind_keys.lua index b328ced545..dd48663a61 100644 --- a/scripts/bind_keys.lua +++ b/scripts/bind_keys.lua @@ -36,5 +36,19 @@ openspace.bindKey("j", "local b = openspace.getPropertyValue('PlutoText.renderab openspace.bindKey("l", "local b = openspace.getPropertyValue('Labels.renderable.performFading'); openspace.setPropertyValue('Labels.renderable.performFading', not b)") +openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_LORRI.renderable.solidDraw'); openspace.setPropertyValue('NH_LORRI.renderable.solidDraw', not b)") +openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_LEISA.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_LEISA.renderable.solidDraw', not b)") +openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_PAN1.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_PAN1.renderable.solidDraw', not b)") +openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_PAN2.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_PAN2.renderable.solidDraw', not b)") +openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_RED.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_RED.renderable.solidDraw', not b)") +openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_BLUE.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_BLUE.renderable.solidDraw', not b)") +openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_FT.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_FT.renderable.solidDraw', not b)") +openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_METHANE.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_METHANE.renderable.solidDraw', not b)") +openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_NIR.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_NIR.renderable.solidDraw', not b)") +openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_ALICE_AIRGLOW.renderable.solidDraw'); openspace.setPropertyValue('NH_ALICE_AIRGLOW.renderable.solidDraw', not b)") + + + + openspace.bindKey("PAUSE", "openspace.printInfo('F5: Toogle to Sun, F6: Toggle to Jupiter, F7: Toggle to Pluto'); openspace.printInfo('Bookmarks: 1: Jupter, 2-7: Pluto');") diff --git a/shaders/model_fs.glsl b/shaders/model_fs.glsl index cb0e75cdb2..f9e799c2ec 100644 --- a/shaders/model_fs.glsl +++ b/shaders/model_fs.glsl @@ -68,9 +68,9 @@ void main() float shine = 100; vec4 specular = vec4(1.0); - vec4 ambient = vec4(0.0,0.0,0.0,transparency);//diffuse*0.4; - - if(intensity > 0.0f){ + vec4 ambient =diffuse*0.4; + ambient[3] = transparency; + if(intensity > 0.0f){ // halfway vector vec3 h = normalize(l_dir + normalize(cam_dir)); // specular factor diff --git a/shaders/projectiveTexture_fs.glsl b/shaders/projectiveTexture_fs.glsl index d62a5ccffa..f222cceeb1 100644 --- a/shaders/projectiveTexture_fs.glsl +++ b/shaders/projectiveTexture_fs.glsl @@ -60,7 +60,7 @@ void main() //vec3 e = normalize(camdir); vec3 l_pos = sun_pos; // sun. vec3 l_dir = normalize(l_pos-objpos.xyz); - float terminatorBright = 0.4; + float terminatorBright = 0.1; float intensity = min(max(5*dot(n,l_dir), terminatorBright), 1); float shine = 0.0001; diff --git a/src/rendering/model/renderablemodel.cpp b/src/rendering/model/renderablemodel.cpp index 5f5c97c5b7..0f0ed1d697 100644 --- a/src/rendering/model/renderablemodel.cpp +++ b/src/rendering/model/renderablemodel.cpp @@ -37,19 +37,21 @@ #include #include +#include #include #include #include "imgui.h" -namespace { - const std::string _loggerCat = "RenderableModel"; +namespace { + const std::string _loggerCat = "RenderableModel"; const std::string keySource = "Rotation.Source"; const std::string keyDestination = "Rotation.Destination"; - const std::string keyBody = "Body"; - const std::string keyStart = "StartTime"; - const std::string keyEnd = "EndTime"; - const std::string keyFading = "Shading.Fadeable"; + const std::string keyBody = "Body"; + const std::string keyStart = "StartTime"; + const std::string keyEnd = "EndTime"; + const std::string keyFading = "Shading.Fadeable"; + const std::string keyGhosting = "Shading.Ghosting"; } @@ -61,6 +63,7 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) , _programObject(nullptr) , _texture(nullptr) , _geometry(nullptr) + , _isGhost(false) , _performShading("performShading", "Perform Shading", true) , _alpha(1.f) , _fading("fading", "Fade", 0) @@ -105,6 +108,12 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) _performFade = fading; } addProperty(_performFade); + + if (dictionary.hasKeyAndValue(keyGhosting)) { + bool ghosting; + dictionary.getValue(keyGhosting, ghosting); + _isGhost = ghosting; + } } bool RenderableModel::isReady() const { @@ -203,12 +212,34 @@ void RenderableModel::render(const RenderData& data) { } void RenderableModel::update(const UpdateData& data) { + double _time = data.time; + + double futureTime; + if (_isGhost){ + futureTime = openspace::ImageSequencer2::ref().getNextCaptureTime(); + double remaining = openspace::ImageSequencer2::ref().getNextCaptureTime() - data.time; + double interval = openspace::ImageSequencer2::ref().getIntervalLength(); + double t = 1.f - remaining / openspace::ImageSequencer2::ref().getIntervalLength(); + if (interval > 60){ + if (t < 0.8){ + _fading = t; + } + else if (t >= 0.95f){ + _fading = _fading - 0.5f; + } + } + else{ + _fading = 0.0f; + } + _time = futureTime; + } + // set spice-orientation in accordance to timestamp if (!_source.empty()) - openspace::SpiceManager::ref().getPositionTransformMatrix(_source, _destination, data.time, _stateMatrix); + openspace::SpiceManager::ref().getPositionTransformMatrix(_source, _destination, _time, _stateMatrix); double lt; - openspace::SpiceManager::ref().getTargetPosition("SUN", _target, "GALACTIC", "NONE", data.time, _sunPosition, lt); + openspace::SpiceManager::ref().getTargetPosition("SUN", _target, "GALACTIC", "NONE", _time, _sunPosition, lt); } void RenderableModel::loadTexture() { diff --git a/src/rendering/planets/renderableplanetprojection.cpp b/src/rendering/planets/renderableplanetprojection.cpp index 71a3490e63..c171217504 100644 --- a/src/rendering/planets/renderableplanetprojection.cpp +++ b/src/rendering/planets/renderableplanetprojection.cpp @@ -341,7 +341,7 @@ void RenderablePlanetProjection::imageProjectGPU(){ m_viewport[2], m_viewport[3]); } -#include + glm::mat4 RenderablePlanetProjection::computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up){ //rotate boresight into correct alignment _boresight = _instrumentMatrix*aim; @@ -435,7 +435,7 @@ void RenderablePlanetProjection::render(const RenderData& data){ _programObject->setUniform("ModelTransform" , _transform); _programObject->setUniform("boresight" , _boresight); setPscUniforms(_programObject, &data.camera, data.position); - + // Bind texture ghoul::opengl::TextureUnit unit[2]; unit[0].activate(); @@ -444,6 +444,7 @@ void RenderablePlanetProjection::render(const RenderData& data){ unit[1].activate(); _textureProj->bind(); _programObject->setUniform("texture2", unit[1]); + // render geometry _geometry->render(); // disable shader @@ -460,7 +461,7 @@ void RenderablePlanetProjection::update(const UpdateData& data){ _capture = openspace::ImageSequencer2::ref().getImagePaths(_imageTimes, _projecteeID, _instrumentID); } //floor fading to decimal - _fadeProjection = floorf(_fadeProjection * 10) / 10; + //_fadeProjection = floorf(_fadeProjection * 10) / 10; } void RenderablePlanetProjection::loadProjectionTexture(){ diff --git a/src/rendering/renderablefov.cpp b/src/rendering/renderablefov.cpp index cb57a15379..82d9def720 100644 --- a/src/rendering/renderablefov.cpp +++ b/src/rendering/renderablefov.cpp @@ -71,6 +71,7 @@ namespace openspace{ , _lineWidth("lineWidth", "Line Width", 1.f, 1.f, 20.f) , _programObject(nullptr) , _texture(nullptr) + , _drawSolid("solidDraw", "Draw as Quads", false) , _mode(GL_LINES){ bool success = dictionary.getValue(keyBody, _spacecraft); @@ -100,6 +101,7 @@ namespace openspace{ } addProperty(_lineWidth); + addProperty(_drawSolid); } void RenderableFov::allocateData(){ @@ -305,8 +307,6 @@ void RenderableFov::fovProjection(bool H[], std::vector bounds){ mid = bisection(current, next, tolerance); for (int j = 1; j <= _isteps; j++){ t = ((double)j / _isteps); - // TODO: change the interpolate scheme to place points not on a straight line but instead - // using either slerp or some other viable method (goal: eliminate checkForIntercept -method) interpolated = interpolate(current, mid, t); _interceptVector = (j < _isteps) ? checkForIntercept(interpolated) : orthogonalProjection(interpolated); insertPoint(_varray2, _interceptVector, col_sq); @@ -426,6 +426,7 @@ void RenderableFov::render(const RenderData& data){ drawFOV = ImageSequencer2::ref().instumentActive(_instrumentID); } + if (drawFOV){ // update only when time progresses. if (_oldTime != _time){ @@ -463,8 +464,9 @@ void RenderableFov::render(const RenderData& data){ double targetEpoch; // for each FOV vector for (int i = 0; i <= bounds.size(); i++){ - // compute surface intercept int r = (i == bounds.size()) ? 0 : i; + + // compute surface intercept openspace::SpiceManager::ref().getSurfaceIntercept(_fovTarget, _spacecraft, _instrumentID, _frame, _method, _aberrationCorrection, _time, targetEpoch, bounds[r], ipoint, ivec, _interceptTag[r]); @@ -512,17 +514,37 @@ void RenderableFov::render(const RenderData& data){ } _interceptTag[bounds.size()] = _interceptTag[0]; - + + if (!(_instrumentID == "NH_LORRI")) // image plane replaces fov square fovProjection(_interceptTag, bounds); updateData(); + glm::vec3 aim = (spacecraftRot * glm::vec4(boresight, 1)).xyz; + psc position; + double lt; + SpiceManager::ref().getTargetPosition(_fovTarget, + _spacecraft, + _frame, + _aberrationCorrection, + _time, + position, + lt); + + //if aimed 80 deg away from target, dont draw white square + if (glm::dot(glm::normalize(aim), glm::normalize(position.vec3())) < 0.2){ + drawFOV = false; + } + } _oldTime = _time; + if (!_drawSolid) _mode = GL_LINES; + else _mode = GL_TRIANGLE_STRIP; + glLineWidth(_lineWidth); glBindVertexArray(_vaoID[0]); - glDrawArrays(GL_LINES, 0, _vtotal[0]); + glDrawArrays(_mode, 0, _vtotal[0]); glBindVertexArray(0); glLineWidth(_lineWidth); @@ -530,8 +552,6 @@ void RenderableFov::render(const RenderData& data){ glDrawArrays(GL_LINES, 0, _vtotal[0]); glBindVertexArray(0); - - //second vbo if (drawFOV){ glLineWidth(1.f); glBindVertexArray(_vaoID[1]); diff --git a/src/rendering/renderableplaneprojection.cpp b/src/rendering/renderableplaneprojection.cpp index 206a37fe8f..822d067fa4 100644 --- a/src/rendering/renderableplaneprojection.cpp +++ b/src/rendering/renderableplaneprojection.cpp @@ -194,9 +194,10 @@ void RenderablePlaneProjection::updatePlane(const Image* img, double currentTime std::string target = "JUPITER"; //default if (!_moving) { - target = findClosestTarget(currentTime); + // target = findClosestTarget(currentTime); } - + if (img != nullptr) + target = img->target; setTarget(target); diff --git a/src/rendering/renderabletrail.cpp b/src/rendering/renderabletrail.cpp index 689d9eb55a..0356437f02 100644 --- a/src/rendering/renderabletrail.cpp +++ b/src/rendering/renderabletrail.cpp @@ -60,7 +60,7 @@ RenderableTrail::RenderableTrail(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _lineColor("lineColor", "Line Color") , _lineFade("lineFade", "Line Fade", 0.75f, 0.f, 5.f) - , _lineWidth("lineWidth", "Line Width", 1.f, 1.f, 20.f) + , _lineWidth("lineWidth", "Line Width", 2.f, 1.f, 20.f) , _programObject(nullptr) , _programIsDirty(true) , _vaoID(0) @@ -148,7 +148,7 @@ void RenderableTrail::render(const RenderData& data) { const psc& origin = openspace::OpenSpaceEngine::ref().interactionHandler()->focusNode()->worldPosition(); const PowerScaledScalar& pssl = (position - origin).length(); - if (pssl[0] < 0.00001){ + if (pssl[0] < 0.000001){ if (_distanceFade > 0.0f) _distanceFade -= 0.05f; _programObject->setUniform("forceFade", _distanceFade); } diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 02b9cb4881..34b984ef5a 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -976,7 +976,7 @@ void RenderEngine::changeViewPoint(std::string origin) { SceneGraphNode* jupiterBarycenterNode = scene()->sceneGraphNode("JupiterBarycenter"); - //SceneGraphNode* newHorizonsGhostNode = sceneGraph()->sceneGraphNode("NewHorizonsGhost"); + SceneGraphNode* newHorizonsGhostNode = scene()->sceneGraphNode("NewHorizonsGhost"); //SceneGraphNode* dawnNode = scene()->sceneGraphNode("Dawn"); //SceneGraphNode* vestaNode = scene()->sceneGraphNode("Vesta"); @@ -995,6 +995,8 @@ void RenderEngine::changeViewPoint(std::string origin) { solarSystemBarycenterNode->setParent(plutoBarycenterNode); newHorizonsNode->setParent(plutoBarycenterNode); + newHorizonsGhostNode->setParent(plutoBarycenterNode); + //newHorizonsTrailNode->setParent(plutoBarycenterNode); ghoul::Dictionary solarDictionary = { @@ -1049,17 +1051,18 @@ void RenderEngine::changeViewPoint(std::string origin) { //}; //vestaNode->setEphemeris(new SpiceEphemeris(vestaDictionary)); - /* + ghoul::Dictionary newHorizonsGhostDictionary = { { std::string("Type"), std::string("Spice") }, - { std::string("Body"), std::string("NEW HORIZONS GHOST") }, + { std::string("Body"), std::string("NEW HORIZONS") }, + { std::string("EphmerisGhosting"), std::string("TRUE") }, { std::string("Reference"), std::string("GALACTIC") }, { std::string("Observer"), std::string("PLUTO BARYCENTER") }, { std::string("Kernels"), ghoul::Dictionary() } }; newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary)); - */ + return; } if (origin == "Sun") { @@ -1068,6 +1071,8 @@ void RenderEngine::changeViewPoint(std::string origin) { plutoBarycenterNode->setParent(solarSystemBarycenterNode); jupiterBarycenterNode->setParent(solarSystemBarycenterNode); newHorizonsNode->setParent(solarSystemBarycenterNode); + newHorizonsGhostNode->setParent(solarSystemBarycenterNode); + //newHorizonsTrailNode->setParent(solarSystemBarycenterNode); ghoul::Dictionary plutoDictionary = @@ -1123,17 +1128,18 @@ void RenderEngine::changeViewPoint(std::string origin) { //}; //vestaNode->setEphemeris(new SpiceEphemeris(vestaDictionary)); - /* + ghoul::Dictionary newHorizonsGhostDictionary = { { std::string("Type"), std::string("Spice") }, - { std::string("Body"), std::string("NEW HORIZONS GHOST") }, + { std::string("Body"), std::string("NEW HORIZONS") }, + { std::string("EphmerisGhosting"), std::string("TRUE") }, { std::string("Reference"), std::string("GALACTIC") }, { std::string("Observer"), std::string("JUPITER BARYCENTER") }, { std::string("Kernels"), ghoul::Dictionary() } }; newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary)); - */ + return; } if (origin == "Jupiter") { @@ -1172,7 +1178,8 @@ void RenderEngine::changeViewPoint(std::string origin) { }; solarSystemBarycenterNode->setEphemeris(new SpiceEphemeris(solarDictionary)); plutoBarycenterNode->setEphemeris(new SpiceEphemeris(plutoDictionary)); - //newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary)); + newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary)); + newHorizonsGhostNode->setParent(jupiterBarycenterNode); //newHorizonsTrailNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary)); @@ -1197,17 +1204,20 @@ void RenderEngine::changeViewPoint(std::string origin) { //vestaNode->setEphemeris(new SpiceEphemeris(vestaDictionary)); - /* + ghoul::Dictionary newHorizonsGhostDictionary = { { std::string("Type"), std::string("Spice") }, - { std::string("Body"), std::string("NEW HORIZONS GHOST") }, + { std::string("Body"), std::string("NEW HORIZONS") }, + { std::string("EphmerisGhosting"), std::string("TRUE") }, { std::string("Reference"), std::string("GALACTIC") }, { std::string("Observer"), std::string("JUPITER BARYCENTER") }, { std::string("Kernels"), ghoul::Dictionary() } }; newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary)); - */ + newHorizonsGhostNode->setParent(jupiterBarycenterNode); + + return; } //if (origin == "Vesta") { diff --git a/src/scene/spiceephemeris.cpp b/src/scene/spiceephemeris.cpp index e8055700d1..f31c4489e3 100644 --- a/src/scene/spiceephemeris.cpp +++ b/src/scene/spiceephemeris.cpp @@ -31,6 +31,7 @@ namespace { const std::string _loggerCat = "SpiceEphemeris"; + const std::string keyGhosting = "EphmerisGhosting"; } namespace openspace { @@ -51,6 +52,8 @@ SpiceEphemeris::SpiceEphemeris(const ghoul::Dictionary& dictionary) if (!hasObserver) LERROR("SpiceEphemeris does not contain the key '" << keyOrigin << "'"); + dictionary.getValue(keyGhosting, _ghosting); + ghoul::Dictionary kernels; dictionary.getValue(keyKernels, kernels); for (size_t i = 1; i <= kernels.size(); ++i) { @@ -74,18 +77,16 @@ void SpiceEphemeris::update(const UpdateData& data) { glm::dvec3 position(0,0,0); double lightTime = 0.0; - //if (_targetName != "NEW HORIZONS GHOST") SpiceManager::ref().getTargetPosition(_targetName, _originName, "GALACTIC", "NONE", data.time, position, lightTime); - - /* + double interval = openspace::ImageSequencer2::ref().getIntervalLength(); - if (_targetName == "NEW HORIZONS GHOST" && interval > 60){ + if (_ghosting == "TRUE" && interval > 60){ double _time = openspace::ImageSequencer2::ref().getNextCaptureTime(); - SpiceManager::ref().getTargetPosition("NEW HORIZONS", _originName, + SpiceManager::ref().getTargetPosition(_targetName, _originName, "GALACTIC", "NONE", _time, position, lightTime); } - */ + _position = psc::CreatePowerScaledCoordinate(position.x, position.y, position.z); _position[3] += 3; } From 2f5114fe2dc16d9ffae0cfcbfd8eadc32191d949 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 5 May 2015 10:58:10 +0200 Subject: [PATCH 44/45] More changes in timelinegui; show images even if start time and end time are outside the viewing frame --- gui/timelineview/timelinewidget.cpp | 36 ++++++++++++++++++----------- gui/timelineview/timelinewidget.h | 2 +- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/gui/timelineview/timelinewidget.cpp b/gui/timelineview/timelinewidget.cpp index 92360afb22..d8f2b0c3e6 100644 --- a/gui/timelineview/timelinewidget.cpp +++ b/gui/timelineview/timelinewidget.cpp @@ -118,12 +118,20 @@ void TimelineWidget::drawContent(QPainter& painter, QRectF rect) { const double lowerTime = _currentTime.et - etSpread; const double upperTime = _currentTime.et + etSpread; - std::vector::const_iterator lower = std::lower_bound(_images.begin(), _images.end(), lowerTime, [](const Image& i, double time) { return i.beginning < time; }); - std::vector::const_iterator upper = std::lower_bound(_images.begin(), _images.end(), upperTime, [](const Image& i, double time) { return i.ending < time; }); - if (lower != _images.end() && upper != _images.end()) - drawImages(painter, timelineRect, std::vector(lower, upper), lowerTime, upperTime); + + std::vector images; + for (Image& i : _images) { + if (i.beginning <= upperTime && i.ending >= lowerTime) + images.push_back(&i); + } + + + //std::vector::const_iterator lower = std::lower_bound(_images.begin(), _images.end(), lowerTime, [](const Image& i, double time) { return i.beginning < time; }); + //std::vector::const_iterator upper = std::lower_bound(_images.begin(), _images.end(), upperTime, [](const Image& i, double time) { return i.ending < time; }); + //if (lower != _images.end() && upper != _images.end()) + // drawImages(painter, timelineRect, std::vector(lower, upper), lowerTime, upperTime); - //drawImages(painter, timelineRect, _images, lowerTime, upperTime); + drawImages(painter, timelineRect, images, lowerTime, upperTime); // Draw current time @@ -188,37 +196,37 @@ void TimelineWidget::setCurrentTime(std::string currentTime, double et) { void TimelineWidget::drawImages( QPainter& painter, QRectF timelineRect, - std::vector images, + std::vector images, double minimumTime, double maximumTime) { int width = timelineRect.width(); int nInstruments = 0; std::set instrumentSet; - for (const Image& i : images) { - for (std::string instrument : i.instruments) + for (Image* i : images) { + for (std::string instrument : i->instruments) instrumentSet.insert(instrument); } std::map instruments; for (std::set::const_iterator it = instrumentSet.begin(); it != instrumentSet.end(); ++it) instruments[*it] = std::distance(instrumentSet.begin(), it); - for (const Image& i : images) { - double tBeg = (i.beginning - minimumTime) / (maximumTime - minimumTime); + for (Image* i : images) { + double tBeg = (i->beginning - minimumTime) / (maximumTime - minimumTime); tBeg = std::max(tBeg, 0.0); - double tEnd = (i.ending - minimumTime) / (maximumTime - minimumTime); + double tEnd = (i->ending - minimumTime) / (maximumTime - minimumTime); tEnd = std::min(tEnd, 1.0); int loc = timelineRect.top() + timelineRect.height() * tBeg; int height = (timelineRect.top() + timelineRect.height() * tEnd) - loc; height = std::max(height, 5); - std::string target = i.target; + std::string target = i->target; auto it = std::find(_targets.begin(), _targets.end(), target); int iTarget = std::distance(_targets.begin(), it); //std::vector colors; - for (std::string instrument : i.instruments) { + for (std::string instrument : i->instruments) { auto it = std::find(_instruments.begin(), _instruments.end(), instrument); if (it == _instruments.end()) qDebug() << "Instrument not found"; @@ -234,7 +242,7 @@ void TimelineWidget::drawImages( painter.setBrush(QBrush(Qt::black)); painter.setPen(QPen(Qt::black)); - QString line = QString::fromStdString(i.beginningString) + QString(" (") + QString::fromStdString(i.target) + QString(")"); + QString line = QString::fromStdString(i->beginningString) + QString(" (") + QString::fromStdString(i->target) + QString(")"); painter.drawText(timelineRect.width(), loc + height / 2 + TextOffset, line); } diff --git a/gui/timelineview/timelinewidget.h b/gui/timelineview/timelinewidget.h index 6dcb437c7a..86ec18779d 100644 --- a/gui/timelineview/timelinewidget.h +++ b/gui/timelineview/timelinewidget.h @@ -49,7 +49,7 @@ protected: void paintEvent(QPaintEvent* event); void drawContent(QPainter& painter, QRectF rect); void drawLegend(QPainter& painter, QRectF rect); - void drawImages(QPainter& painter, QRectF timelineRect, std::vector images, double minimumTime, double maximumTime); + void drawImages(QPainter& painter, QRectF timelineRect, std::vector images, double minimumTime, double maximumTime); private: std::vector _images; From 5b1ab8b69260728984d12ef17bf03e9710476d62 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 5 May 2015 14:10:37 +0200 Subject: [PATCH 45/45] Fix crash when changing coordinate system origin to Pluto --- src/rendering/renderengine.cpp | 70 +++++++++++++++++----------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 931abeecfb..2a8bd2a963 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -979,7 +979,7 @@ void RenderEngine::changeViewPoint(std::string origin) { SceneGraphNode* jupiterBarycenterNode = scene()->sceneGraphNode("JupiterBarycenter"); - SceneGraphNode* newHorizonsGhostNode = scene()->sceneGraphNode("NewHorizonsGhost"); + //SceneGraphNode* newHorizonsGhostNode = scene()->sceneGraphNode("NewHorizonsGhost"); //SceneGraphNode* dawnNode = scene()->sceneGraphNode("Dawn"); //SceneGraphNode* vestaNode = scene()->sceneGraphNode("Vesta"); @@ -998,7 +998,7 @@ void RenderEngine::changeViewPoint(std::string origin) { solarSystemBarycenterNode->setParent(plutoBarycenterNode); newHorizonsNode->setParent(plutoBarycenterNode); - newHorizonsGhostNode->setParent(plutoBarycenterNode); + //newHorizonsGhostNode->setParent(plutoBarycenterNode); //dawnNode->setParent(plutoBarycenterNode); //vestaNode->setParent(plutoBarycenterNode); @@ -1058,16 +1058,16 @@ void RenderEngine::changeViewPoint(std::string origin) { //vestaNode->setEphemeris(new SpiceEphemeris(vestaDictionary)); - ghoul::Dictionary newHorizonsGhostDictionary = - { - { std::string("Type"), std::string("Spice") }, - { std::string("Body"), std::string("NEW HORIZONS") }, - { std::string("EphmerisGhosting"), std::string("TRUE") }, - { std::string("Reference"), std::string("GALACTIC") }, - { std::string("Observer"), std::string("PLUTO BARYCENTER") }, - { std::string("Kernels"), ghoul::Dictionary() } - }; - newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary)); + //ghoul::Dictionary newHorizonsGhostDictionary = + //{ + // { std::string("Type"), std::string("Spice") }, + // { std::string("Body"), std::string("NEW HORIZONS") }, + // { std::string("EphmerisGhosting"), std::string("TRUE") }, + // { std::string("Reference"), std::string("GALACTIC") }, + // { std::string("Observer"), std::string("PLUTO BARYCENTER") }, + // { std::string("Kernels"), ghoul::Dictionary() } + //}; + //newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary)); return; } @@ -1077,7 +1077,7 @@ void RenderEngine::changeViewPoint(std::string origin) { plutoBarycenterNode->setParent(solarSystemBarycenterNode); jupiterBarycenterNode->setParent(solarSystemBarycenterNode); newHorizonsNode->setParent(solarSystemBarycenterNode); - newHorizonsGhostNode->setParent(solarSystemBarycenterNode); + //newHorizonsGhostNode->setParent(solarSystemBarycenterNode); //newHorizonsTrailNode->setParent(solarSystemBarycenterNode); //dawnNode->setParent(solarSystemBarycenterNode); @@ -1137,16 +1137,16 @@ void RenderEngine::changeViewPoint(std::string origin) { //vestaNode->setEphemeris(new SpiceEphemeris(vestaDictionary)); - ghoul::Dictionary newHorizonsGhostDictionary = - { - { std::string("Type"), std::string("Spice") }, - { std::string("Body"), std::string("NEW HORIZONS") }, - { std::string("EphmerisGhosting"), std::string("TRUE") }, - { std::string("Reference"), std::string("GALACTIC") }, - { std::string("Observer"), std::string("JUPITER BARYCENTER") }, - { std::string("Kernels"), ghoul::Dictionary() } - }; - newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary)); + //ghoul::Dictionary newHorizonsGhostDictionary = + //{ + // { std::string("Type"), std::string("Spice") }, + // { std::string("Body"), std::string("NEW HORIZONS") }, + // { std::string("EphmerisGhosting"), std::string("TRUE") }, + // { std::string("Reference"), std::string("GALACTIC") }, + // { std::string("Observer"), std::string("JUPITER BARYCENTER") }, + // { std::string("Kernels"), ghoul::Dictionary() } + //}; + //newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary)); return; } @@ -1191,7 +1191,7 @@ void RenderEngine::changeViewPoint(std::string origin) { solarSystemBarycenterNode->setEphemeris(new SpiceEphemeris(solarDictionary)); plutoBarycenterNode->setEphemeris(new SpiceEphemeris(plutoDictionary)); newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary)); - newHorizonsGhostNode->setParent(jupiterBarycenterNode); + //newHorizonsGhostNode->setParent(jupiterBarycenterNode); //newHorizonsTrailNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary)); @@ -1217,17 +1217,17 @@ void RenderEngine::changeViewPoint(std::string origin) { - ghoul::Dictionary newHorizonsGhostDictionary = - { - { std::string("Type"), std::string("Spice") }, - { std::string("Body"), std::string("NEW HORIZONS") }, - { std::string("EphmerisGhosting"), std::string("TRUE") }, - { std::string("Reference"), std::string("GALACTIC") }, - { std::string("Observer"), std::string("JUPITER BARYCENTER") }, - { std::string("Kernels"), ghoul::Dictionary() } - }; - newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary)); - newHorizonsGhostNode->setParent(jupiterBarycenterNode); + //ghoul::Dictionary newHorizonsGhostDictionary = + //{ + // { std::string("Type"), std::string("Spice") }, + // { std::string("Body"), std::string("NEW HORIZONS") }, + // { std::string("EphmerisGhosting"), std::string("TRUE") }, + // { std::string("Reference"), std::string("GALACTIC") }, + // { std::string("Observer"), std::string("JUPITER BARYCENTER") }, + // { std::string("Kernels"), ghoul::Dictionary() } + //}; + //newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary)); + //newHorizonsGhostNode->setParent(jupiterBarycenterNode); return;