Merge branch 'timeadjustments' into NewHorizonsMerge

Conflicts:
	CMakeLists.txt
	include/openspace/rendering/model/modelgeometry.h
	include/openspace/rendering/model/wavefrontgeometry.h
	include/openspace/rendering/planets/renderableplanetprojection.h
	include/openspace/util/imagesequencer.h
	scripts/default_startup.lua
	src/abuffer/abuffer.cpp
	src/rendering/model/renderablemodel.cpp
	src/rendering/model/wavefrontgeometry.cpp
	src/rendering/planets/renderableplanet.cpp
	src/rendering/planets/renderableplanetprojection.cpp
	src/rendering/renderablefov.cpp
	src/rendering/renderabletrail.cpp
	src/rendering/renderengine.cpp
	src/scene/scene.cpp
	src/scene/spiceephemeris.cpp
	src/util/imagesequencer.cpp
This commit is contained in:
Anton Arbring
2015-04-23 22:51:55 -04:00
66 changed files with 3704 additions and 505 deletions
+4
View File
@@ -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
+1 -2
View File
@@ -145,8 +145,7 @@ endif ()
#########################################################################################
add_subdirectory(src)
#add_subdirectory(tests)
#add_subdirectory(gui)
add_subdirectory(gui)
#########################################################################################
# File Fetch
+2 -1
View File
@@ -1,3 +1,4 @@
cmake_minimum_required(VERSION 2.8.11)
add_subdirectory(luascriptexternalcontrol)
add_subdirectory(luascriptexternalcontrol)
add_subdirectory(timelineview)
+10
View File
@@ -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 main.cpp mainwindow.cpp configurationwidget.cpp informationwidget.cpp timecontrolwidget.cpp timelinewidget.cpp)
target_link_libraries(TimelineView Qt5::Widgets Qt5::Network)
+52
View File
@@ -0,0 +1,52 @@
/*****************************************************************************************
* *
* 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 <QGridLayout>
ConfigurationWidget::ConfigurationWidget(QWidget* parent)
: 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);
QObject::connect(_connect, SIGNAL(clicked()), this, SLOT(onConnectButton()));
}
void ConfigurationWidget::onConnectButton() {
emit connect(_ipAddress->text(), _port->text());
}
+52
View File
@@ -0,0 +1,52 @@
/*****************************************************************************************
* *
* 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 <QWidget>
#include <QLineEdit>
#include <QPushButton>
class ConfigurationWidget : public QWidget {
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;
QPushButton* _load;
};
#endif // __CONFIGURATIONWIDGET_H__
+33
View File
@@ -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 <QLayout>
#include <QTextEdit>
InformationWidget::InformationWidget(QWidget* parent)
: QTextEdit(parent)
{
}
+36
View File
@@ -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 <QTextEdit>
class InformationWidget : public QTextEdit {
Q_OBJECT
public:
InformationWidget(QWidget* parent);
};
#endif // __INFORMATIONWIDGET_H__
+35
View File
@@ -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 <QApplication>
#include "mainwindow.h"
int main(int argc, char** argv) {
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
+131
View File
@@ -0,0 +1,131 @@
/*****************************************************************************************
* *
* 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 <QGridLayout>
#include <QPushButton>
#include <QTextEdit>
#include <array>
#include <cstdint>
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);
QObject::connect(
_configurationWidget, SIGNAL(connect(QString, QString)),
this, SLOT(onConnect(QString, QString))
);
QObject::connect(
_timeControlWidget, SIGNAL(scriptActivity(QString)),
this, SLOT(sendScript(QString))
);
setLayout(layout);
}
MainWindow::~MainWindow() {
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() {
static const uint8_t MessageTypeStatus = 0;
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::handleStatusMessage(QByteArray data) {
const char* buffer = data.data();
union {
double value;
std::array<char, 8> buffer;
} et;
std::memmove(et.buffer.data(), buffer, sizeof(double));
std::vector<char> timeString(24);
std::memmove(timeString.data(), buffer + sizeof(double), 24);
union {
double value;
std::array<char, 8> 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::sendScript(QString script) {
_socket->write(("0" + script + "\r\n").toLatin1());
}
+62
View File
@@ -0,0 +1,62 @@
/*****************************************************************************************
* *
* 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 <QWidget>
#include <QTcpSocket>
class ConfigurationWidget;
class TimeControlWidget;
class InformationWidget;
class TimelineWidget;
class MainWindow : public QWidget {
Q_OBJECT
public:
MainWindow();
~MainWindow();
public slots:
void sendScript(QString script);
private slots:
void onConnect(QString host, QString port);
//void onConnectButton();
//void sendCommandButton();
void readTcpData();
void handleStatusMessage(QByteArray data);
private:
ConfigurationWidget* _configurationWidget;
TimeControlWidget* _timeControlWidget;
InformationWidget* _informationWidget;
TimelineWidget* _timelineWidget;
QTcpSocket* _socket;
};
#endif // __MAINWINDOW_H__
+131
View File
@@ -0,0 +1,131 @@
/*****************************************************************************************
* *
* 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 <QComboBox>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QSlider>
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(">>"))
{
_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);
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);
}
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);
}
+65
View File
@@ -0,0 +1,65 @@
/*****************************************************************************************
* *
* 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 <QWidget>
class QComboBox;
class QLabel;
class QPushButton;
class QSlider;
class TimeControlWidget : public QWidget {
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;
QLabel* _currentDelta;
QSlider* _setDelta;
QPushButton* _rewind;
QPushButton* _pause;
QPushButton* _play;
QPushButton* _forward;
bool _stateNoNotification = false;
};
#endif // __TIMECONTROLWIDGET_H__
+42
View File
@@ -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 <QPainter>
#include <QPaintEvent>
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());
}
+42
View File
@@ -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 <QWidget>
class QPaintEvent;
class TimelineWidget : public QWidget {
Q_OBJECT
public:
TimelineWidget(QWidget* parent);
protected:
void paintEvent(QPaintEvent* event);
};
#endif // __TIMELINEWIDGET_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;
+43
View File
@@ -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 <string>
namespace openspace {
class NetworkEngine {
public:
NetworkEngine() = default;
bool handleMessage(const std::string& message);
void sendStatusMessage();
};
} // namespace openspace
#endif // __NETWORKENGINE_H__
@@ -43,6 +43,7 @@ public:
virtual void deinitialize();
void render();
virtual bool loadModel(const std::string& filename) = 0;
void changeRenderMode(const GLenum mode);
protected:
RenderableModel* _parent;
@@ -59,6 +60,7 @@ protected:
GLuint _vaoID;
GLuint _vbo;
GLuint _ibo;
GLenum _mode;
std::vector<Vertex> _vertices;
std::vector<int> _indices;
@@ -57,6 +57,8 @@ protected:
private:
properties::StringProperty _colorTexturePath;
properties::BoolProperty _performFade;
properties::FloatProperty _fading;
ghoul::opengl::ProgramObject* _programObject;
ghoul::opengl::Texture* _texture;
@@ -28,7 +28,13 @@
// open space includes
#include <openspace/rendering/renderable.h>
#include <openspace/util/imagesequencer.h>
#include <openspace/util/imagesequencer2.h>
#include <openspace/util/sequenceparser.h>
#include <openspace/util/hongkangparser.h>
#include <openspace/util/labelparser.h>
#include <openspace/util/decoder.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/triggerproperty.h>
@@ -71,15 +77,18 @@ protected:
private:
void imageProjectGPU();
std::map<std::string, Decoder*> _fileTranslation;
properties::StringProperty _colorTexturePath;
properties::StringProperty _projectionTexturePath;
properties::TriggerProperty _imageTrigger;
properties::IntProperty _rotation;
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;
@@ -88,12 +97,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<std::string> _potentialTargets; // @TODO copy-n-paste from renderablefov
float _fovy;
float _aspectRatio;
float _nearPlane;
@@ -103,9 +119,14 @@ private:
glm::dmat3 _instrumentMatrix;
glm::vec3 _boresight;
double _time[2];
double _time;
double _previousTime;
double _previousCapture;
double lightTime;
std::vector<Image> _imageTimes;
int _sequenceID;
std::string _target;
std::string _frame;
std::string _defaultProjImage;
@@ -117,6 +138,8 @@ private:
GLuint _fboID;
GLuint _quad;
GLuint _vertexPositionBuffer;
bool _once; //fml
};
} // namespace openspace
+2 -58
View File
@@ -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
@@ -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;
}
*/
@@ -28,6 +28,7 @@
#include <openspace/rendering/renderable.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/util/imagesequencer2.h>
#include <openspace/properties/vectorproperty.h>
#include <openspace/util/updatestructures.h>
@@ -67,7 +68,8 @@ namespace openspace {
private:
void loadTexture();
void updatePlane(double time, std::string newPath);
void updatePlane(const Image* img, double currentTime);
std::string findClosestTarget(double currentTime);
void setTarget(std::string body);
std::string _texturePath;
@@ -86,6 +86,8 @@ private:
float _increment;
float _oldTime = 0;
float _time;
float _distanceFade;
};
} // namespace openspace
+47
View File
@@ -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 __DECODER_H__
#define __DECODER_H__
#include <ghoul/misc/dictionary.h>
#include <openspace/util/updatestructures.h>
namespace openspace {
class Decoder {
public:
static Decoder* createFromDictionary(const ghoul::Dictionary& dictionary, const std::string type);
Decoder(const ghoul::Dictionary& dictionary);
virtual ~Decoder();
virtual std::string getDecoderType() = 0;
virtual std::vector<std::string> getTranslation() = 0;
protected:
Decoder();
};
} // namespace openspace
#endif // __DECODER_H__
+85
View File
@@ -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 <openspace/util/ImageSequencer2.h>
#include <openspace/util/sequenceparser.h>
#include <map>
#include <string>
#include <vector>
namespace openspace {
class HongKangParser : public SequenceParser{
public:
HongKangParser();
HongKangParser(const std::string& fileName,
std::string spacecraft,
ghoul::Dictionary dictionary,
std::vector<std::string> potentialTargets);
virtual void create();
virtual std::map<std::string, ImageSubset> getSubsetMap();
virtual std::vector<std::pair<std::string, TimeRange>> getIstrumentTimes();
virtual std::vector<std::pair<double, std::string>> getTargetTimes();
// temporary need to figure this out
virtual std::map<std::string, Decoder*> getTranslation(){ return _fileTranslation; };
virtual std::vector<double> getCaptureProgression();
private:
double getMetFromET(double et);
double getETfromMet(std::string timestr);
double getETfromMet(double met);
void createImage(Image& image,
double startTime,
double stopTime,
std::vector<std::string> instr,
std::string targ,
std::string pot);
bool augmentWithSpice(Image& image,
std::string spacecraft,
std::vector<std::string> payload,
std::vector<std::string> potentialTargets);
std::string _defaultCaptureImage;
double _metRef = 299180517;
std::string _fileName;
std::string _spacecraft;
std::map<std::string, Decoder*> _fileTranslation;
std::vector<std::string> _potentialTargets;
//returnable
std::map<std::string, ImageSubset> _subsetMap;
std::vector<std::pair<std::string, TimeRange>> _instrumentTimes;
std::vector<std::pair<double, std::string>> _targetTimes;
std::vector<double> _captureProgression;
};
}
#endif //__HONGKANGPARSER_H__
+77 -19
View File
@@ -37,44 +37,102 @@ 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<std::pair<double, std::string>>& _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);
std::string ImageSequencer::getLatestImage();
/*
* 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 augumentSequenceWithTargets(int sequenceID);
void addSequenceObserver(int sequenceID, std::string name, std::vector<std::string> payload);
void registerTargets(std::vector<std::string>& potential);
static ImageSequencer* _sequencer;
protected:
bool getMultipleImages(std::vector<std::pair<double, std::string>>& _imageTimes, int sequenceID, std::string projectee);
bool getSingleImage(std::vector<std::pair<double, std::string>>& _imageTimes, int sequenceID, std::string projectee);
private:
double getMissionElapsedTime(std::string timestr);
double nextCaptureTime(double _time);
std::map<std::string, double> _projectableTargets;
std::map <int, std::string> _observers;
std::map <std::string, std::vector<std::string>> _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;
std::string _latest;
bool _targetsAdded;
};
} // namespace openspace
+205
View File
@@ -0,0 +1,205 @@
/*****************************************************************************************
* *
* 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 <ghoul/opengl/ghoul_gl.h>
#include <openspace/util/powerscaledcoordinate.h>
#include <openspace/util/powerscaledscalar.h>
#include <unordered_map>
#include <map>
#include <vector>
#include <openspace/util/sequenceparser.h>
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<std::string, bool>
*/
class ImageSequencer2 {
public:
ImageSequencer2();
/**
* 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();
/**
* Updates sequencer with current <code>time</code>. 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);
/**
* Retrieves the next upcoming target in time.
*/
std::pair<double, std::string> getNextTarget();
/**
* Retrieves the most current target in time.
*/
std::pair<double, std::string> getCurrentTarget();
/**
* Retrieves current target and (in the list) adjacent targets, the number to retrieve is user set
*/
std::pair<double, std::vector<std::string>> 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();
/*
* Returns a map with key instrument names whose value indicate whether
* an instrument is active or not.
*/
std::map<std::string, bool> 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<Image>& captures,
std::string projectee,
std::string instrumentID);
bool ImageSequencer2::getImagePaths(std::vector<Image>& captures,
std::string projectee);
/*
* returns true if instrumentID is within a capture range.
*/
bool instumentActive(std::string instrumentID);
/*
* returns latest captured image
*/
const Image* getLatestImageForInstrument(const std::string _instrumentID);
private:
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<std::string, Decoder*> _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<std::string, ImageSubset> _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<std::string, bool> _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<std::pair<double, std::string>> _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<std::pair<std::string, TimeRange>> _instrumentTimes;
/*
* Each consecutive images capture time, for easier traversal.
*/
std::vector<double> _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;
Image* _latestImage;
// if no data, no run
bool _hasData;
};
} // namespace openspace
#endif // __ImageSequencer2_H__
@@ -0,0 +1,48 @@
/*****************************************************************************************
* *
* 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 __INSTRUMENTDECODER_H__
#define __INSTRUMENTDECODER_H__
#include <openspace/util/decoder.h>
#include <openspace/util/powerscaledcoordinate.h>
namespace openspace {
class InstrumentDecoder : public Decoder {
public:
InstrumentDecoder(const ghoul::Dictionary& dictionary);
virtual std::string getDecoderType();
virtual std::vector<std::string> getTranslation();
std::string getStopCommand();
private:
std::string _type;
std::string _stopCommand;
std::vector<std::string> _spiceIDs;
};
} // namespace openspace
#endif // __INSTRUMENTDECODER_H__
+86
View File
@@ -0,0 +1,86 @@
/*****************************************************************************************
* *
* 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 <openspace/util/ImageSequencer2.h>
#include <openspace/util/sequenceparser.h>
#include <map>
#include <string>
#include <vector>
namespace openspace {
class LabelParser : public SequenceParser{
public:
LabelParser();
LabelParser(const std::string& fileName,
ghoul::Dictionary translationDictionary);
virtual void create();
virtual std::map<std::string, ImageSubset> getSubsetMap();
virtual std::vector<std::pair<std::string, TimeRange>> getIstrumentTimes();
virtual std::vector<std::pair<double, std::string>> getTargetTimes();
// temporary need to figure this out
std::map<std::string, Decoder*> getTranslation(){ return _fileTranslation; };
virtual std::vector<double> getCaptureProgression(){ return _captureProgression; };
private:
void createImage(Image& image,
double startTime,
double stopTime,
std::vector<std::string> instr,
std::string targ,
std::string path);
std::string decode(std::string line);
bool augmentWithSpice(Image& image,
std::string spacecraft,
std::vector<std::string> payload,
std::vector<std::string> potentialTargets);
std::string _fileName;
std::string _spacecraft;
std::map<std::string, Decoder*> _fileTranslation;
std::vector<std::string> _specsOfInterest;
//returnable
std::map<std::string, ImageSubset> _subsetMap;
std::vector<std::pair<std::string, TimeRange>> _instrumentTimes;
std::vector<std::pair<double, std::string>> _targetTimes;
std::vector<double> _captureProgression;
std::string _target;
std::string _instrumentID;
std::string _instrumentHostID;
std::string _detectorType;
std::string _sequenceID;
double _startTime;
double _stopTime;
};
}
#endif //__LABELPARSER_H__
+48
View File
@@ -0,0 +1,48 @@
/*****************************************************************************************
* *
* 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 __SCANNERDECODER_H__
#define __SCANNERDECODER_H__
#include <openspace/util/decoder.h>
#include <openspace/util/powerscaledcoordinate.h>
namespace openspace {
class ScannerDecoder : public Decoder {
public:
ScannerDecoder(const ghoul::Dictionary& dictionary);
virtual std::string getDecoderType();
virtual std::vector<std::string> getSpiceIDs();
std::string getStopCommand();
void setStopCommand(std::string stopCommand);
private:
std::string _type;
std::string _abort;
std::vector<std::string> _spiceIDs;
};
} // namespace openspace
#endif // __SCANNERDECODER_H__
+74
View File
@@ -0,0 +1,74 @@
/*****************************************************************************************
* *
* 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 <openspace/util/decoder.h>
#include <map>
#include <string>
#include <vector>
namespace openspace {
struct Image{
double startTime;
double stopTime;
std::string path;
std::vector<std::string> activeInstruments;
std::string target;
bool projected;
};
struct TimeRange{
TimeRange() : _min(-1), _max(-1){};
void setRange(double 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;
};
struct ImageSubset{
TimeRange _range;
std::vector < Image > _subset;
};
class SequenceParser{
public:
virtual void create() = 0;
virtual std::map<std::string, ImageSubset> getSubsetMap() = 0;
virtual std::vector<std::pair<std::string, TimeRange>> getIstrumentTimes() = 0;
virtual std::vector<std::pair<double, std::string>> getTargetTimes() = 0;
virtual std::map<std::string, Decoder*> getTranslation() = 0;
virtual std::vector<double> getCaptureProgression() = 0;
};
}
#endif //__SEQUENCEPARSER_H__
+46
View File
@@ -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 <openspace/util/decoder.h>
#include <openspace/util/powerscaledcoordinate.h>
namespace openspace {
class TargetDecoder : public Decoder {
public:
TargetDecoder(const ghoul::Dictionary& dictionary);
virtual std::string getDecoderType();
virtual std::vector<std::string> getTranslation();
private:
std::string _type;
std::vector<std::string> _names;
};
} // namespace openspace
#endif // __TARGETDECODER_H__
+1 -1
View File
@@ -51,7 +51,7 @@ namespace openspace {
* equal to the frame time.
*/
class SyncBuffer;
class SyncBuffer;
class Time {
public:
+1 -1
View File
@@ -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",
}
+11
View File
@@ -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');")
+3 -3
View File
@@ -5,9 +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:30: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.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
@@ -15,7 +15,7 @@ dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) -- Load the default keyb
-- openspace.time.setDeltaTime(50);
--openspace.time.setTime("2015-07-14T10:50:00.00") -- PLUTO
openspace.time.setTime("2015-07-14T10:50:00.00") -- PLUTO
-- NH takes series of images from visible to dark side (across terminator)
-- Sequence lasts ~10 mins, (recommended dt = 10)
+6 -1
View File
@@ -25,12 +25,15 @@
#version __CONTEXT__
uniform sampler2D texture1;
uniform sampler2D texture2;
uniform mat4 ProjectorMatrix;
uniform mat4 ModelTransform;
uniform vec2 _scaling;
uniform vec4 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
}
+93
View File
@@ -0,0 +1,93 @@
/*****************************************************************************************
* *
* 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 float transparency;
uniform int shadows;
uniform float fading;
uniform float time;
uniform sampler2D texture1;
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);
diffuse[3] = fading;
if (_performShading) {
vec4 spec = vec4(0.0);
vec3 n = normalize(vs_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 shine = 100;
vec4 specular = vec4(1.0);
vec4 ambient = vec4(0.0,0.0,0.0,transparency);//diffuse*0.4;
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 ;
diffuse[3] = fading*transparency;
ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth);
addToBuffer(frag);
}
else {
diffuse[3] = fading*transparency;
ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth);
addToBuffer(frag);
}
}
+57
View File
@@ -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);
}
+2 -1
View File
@@ -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);
}
-1
View File
@@ -38,7 +38,6 @@ uniform float time;
uniform sampler2D texture1;
in vec2 vs_st;
in vec2 vs_nightTex;
in vec4 vs_normal;
in vec4 vs_position;
+6
View File
@@ -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)
+8 -15
View File
@@ -35,6 +35,7 @@
#include <openspace/interaction/keyboardcontroller.h>
#include <openspace/interaction/luaconsole.h>
#include <openspace/interaction/mousecontroller.h>
#include <openspace/network/networkengine.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/scripting/scriptengine.h>
#include <openspace/scene/scene.h>
@@ -44,7 +45,8 @@
#include <openspace/util/constants.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/syncbuffer.h>
#include <openspace/util/imagesequencer.h>
#include <openspace/util/imagesequencer2.h> // testing
#include <ghoul/cmdparser/commandlineparser.h>
@@ -92,6 +94,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)
@@ -100,6 +103,7 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName)
{
SpiceManager::initialize();
Time::initialize();
ImageSequencer2::initialize();
FactoryManager::initialize();
ghoul::systemcapabilities::SystemCapabilities::initialize();
}
@@ -111,6 +115,7 @@ OpenSpaceEngine::~OpenSpaceEngine() {
delete _interactionHandler;
delete _renderEngine;
delete _scriptEngine;
delete _networkEngine;
delete _commandlineParser;
delete _console;
delete _gui;
@@ -206,8 +211,6 @@ bool OpenSpaceEngine::create(
}
}
ImageSequencer::initialize();
// Create the cachemanager
FileSys.createCacheManager(absPath("${" + constants::configurationmanager::keyCache + "}"));
_engine->_console->initialize();
@@ -698,6 +701,7 @@ void OpenSpaceEngine::encode() {
_syncBuffer->write();
}
_networkEngine->sendStatusMessage();
}
void OpenSpaceEngine::decode() {
@@ -707,7 +711,6 @@ void OpenSpaceEngine::decode() {
Time::ref().deserialize(_syncBuffer);
_scriptEngine->deserialize(_syncBuffer);
_renderEngine->deserialize(_syncBuffer);
}
}
@@ -717,17 +720,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() {
+97
View File
@@ -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 <openspace/network/networkengine.h>
#include <openspace/util/time.h>
#include <openspace/engine/openspaceengine.h>
#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<char> 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
+7 -2
View File
@@ -64,6 +64,7 @@ ModelGeometry* ModelGeometry::createFromDictionary(const ghoul::Dictionary& dict
ModelGeometry::ModelGeometry(const ghoul::Dictionary& dictionary)
: _parent(nullptr)
, _mode(GL_TRIANGLES)
{
setName("ModelGeometry");
using constants::scenegraphnode::keyName;
@@ -90,10 +91,14 @@ ModelGeometry::~ModelGeometry() {
void ModelGeometry::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);
}
void ModelGeometry::changeRenderMode(const GLenum mode){
_mode = mode;
}
bool ModelGeometry::initialize(RenderableModel* parent) {
_parent = parent;
PowerScaledScalar ps = PowerScaledScalar(1.0, 0.0); // will set proper bounding soon.
@@ -152,7 +157,7 @@ bool ModelGeometry::loadObj(const std::string& filename){
else {
LINFO("Cache for Model'" << filename << "' not found");
}
LINFO("Loading OBJ file '" << filename << "'");
LINFO("Loading Model file '" << filename << "'");
bool success = loadModel(filename);
if (!success)
//return false;
+28 -1
View File
@@ -49,6 +49,8 @@ namespace {
const std::string keyBody = "Body";
const std::string keyStart = "StartTime";
const std::string keyEnd = "EndTime";
const std::string keyFading = "Shading.Fadeable";
}
namespace openspace {
@@ -61,6 +63,8 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
, _geometry(nullptr)
, _performShading("performShading", "Perform Shading", true)
, _alpha(1.f)
, _fading("fading", "Fade", 0)
, _performFade("performFading", "Perform Fading", false)
{
std::string name;
bool success = dictionary.getValue(constants::scenegraphnode::keyName, name);
@@ -94,6 +98,13 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
setBoundingSphere(pss(1.f, 9.f));
addProperty(_performShading);
if (dictionary.hasKeyAndValue<bool>(keyFading)) {
bool fading;
dictionary.getValue(keyFading, fading);
_performFade = fading;
}
addProperty(_performFade);
}
bool RenderableModel::isReady() const {
@@ -107,7 +118,7 @@ bool RenderableModel::initialize() {
bool completeSuccess = true;
if (_programObject == nullptr)
completeSuccess
&= OsEng.ref().configurationManager()->getValue("pscShader", _programObject);
&= OsEng.ref().configurationManager()->getValue("GenericModelShader", _programObject);
loadTexture();
@@ -135,6 +146,7 @@ bool RenderableModel::deinitialize() {
void RenderableModel::render(const RenderData& data) {
_programObject->activate();
double lt;
glm::mat4 transform = glm::mat4(1);
glm::mat4 tmp = glm::mat4(1);
@@ -155,6 +167,11 @@ void RenderableModel::render(const RenderData& data) {
}
else
_alpha = 1.0f;
psc tmppos;
SpiceManager::ref().getTargetPosition(_source, "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);
_programObject->setUniform("sun_pos", _sunPosition.vec3());
_programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
@@ -163,6 +180,16 @@ 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){
_fading = _fading + 0.01f;
}
_programObject->setUniform("fading", _fading);
// Bind texture
ghoul::opengl::TextureUnit unit;
unit.activate();
+2 -2
View File
@@ -105,7 +105,7 @@ bool WavefrontGeometry::loadModel(const std::string& filename) {
_vertices[j + currentPosition].tex[0] = shapes[i].mesh.texcoords[2 * j + 0];
_vertices[j + currentPosition].tex[1] = shapes[i].mesh.texcoords[2 * j + 1];
}
}
currentPosition += shapes[i].mesh.positions.size() / 3;
@@ -117,7 +117,7 @@ bool WavefrontGeometry::loadModel(const std::string& filename) {
p += shapes[i].mesh.indices.size();
}
return true;
return true;
}
@@ -36,6 +36,8 @@
#include <openspace/util/time.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/factorymanager.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/engine/configurationmanager.h>
#include <sgct.h>
@@ -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 = "DataInputTranslation";
const std::string keyFrame = "Frame";
const std::string keyGeometry = "Geometry";
const std::string keyShading = "PerformShading";
@@ -73,18 +79,21 @@ namespace {
namespace openspace {
//#define ORIGINAL_SEQUENCER
RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& dictionary)
: Renderable(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)
, _rotation("rotation", "Rotation", 0, 0, 360)
, _once(false)
{
std::string name;
bool success = dictionary.getValue(constants::scenegraphnode::keyName, name);
@@ -114,8 +123,8 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary&
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 b5 = dictionary.getValue(keyInstrumentFovy, _fovy);
bool b6 = dictionary.getValue(keyInstrumentAspect, _aspectRatio);
bool b7 = dictionary.getValue(keyInstrumentNear, _nearPlane);
bool b8 = dictionary.getValue(keyInstrumentFar, _farPlane);
@@ -153,34 +162,43 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary&
}
addPropertySubOwner(_geometry);
addProperty(_rotation);
addProperty(_imageTrigger);
_imageTrigger.onChange(std::bind(&RenderablePlanetProjection::loadTexture, this));
addProperty(_fadeProjection);
addProperty(_colorTexturePath);
_colorTexturePath.onChange(std::bind(&RenderablePlanetProjection::loadTexture, this));
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;
SequenceParser* parser;
std::string sequenceType;
found = dictionary.getValue(keySequenceType, sequenceType);
if (found) {
if (sequenceType == sequenceTypeImage) {
openspace::ImageSequencer::ref().loadSequence(sequenceSource);
}
else if (sequenceType == sequenceTypePlaybook) {
openspace::ImageSequencer::ref().parsePlaybookFile(sequenceSource);
}
else {
LERROR("RenderablePlanetProjection '" << name << "' had unknown sequence type '" << sequenceType << "'");
}
}
// std::string sequenceSource;
bool _foundSequence = dictionary.getValue(keySequenceDir, _sequenceSource);
if (_foundSequence) {
_sequenceSource = absPath(_sequenceSource);
_foundSequence = dictionary.getValue(keySequenceType, _sequenceType);
//Important: client must define translation-list in mod file IFF playbook
if (dictionary.hasKey(keyTranslation)){
ghoul::Dictionary translationDictionary;
//get translation dictionary
dictionary.getValue(keyTranslation, translationDictionary);
if (_sequenceType == sequenceTypePlaybook){
parser = new HongKangParser(_sequenceSource,
"NEW HORIZONS",
translationDictionary,
_potentialTargets);
openspace::ImageSequencer2::ref().runSequenceParser(parser);
}
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!");
}
}
}
@@ -283,6 +301,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);
@@ -368,7 +393,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]);
@@ -382,21 +406,25 @@ 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 img : _imageTimes){
attitudeParameters(img.startTime); // compute projector viewmatrix
_projectionTexturePath = img.path; // path to current images
imageProjectGPU(); //fbopass
}
_capture = false;
}
#endif
attitudeParameters(_time[1]);
attitudeParameters(_time);
_projectionTexturePath = _defaultProjImage;
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();
@@ -424,34 +452,15 @@ 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;
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;
}
}
if (_projecteeID == _fovTarget){
_next = _defaultProjImage;
if (_time[0] >= openspace::ImageSequencer::ref().getNextCaptureTime()){
_capture = openspace::ImageSequencer::ref().getImagePath(_time[0], _next);
}
_projectionTexturePath = _next;
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(){
@@ -460,12 +469,11 @@ 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);
}
}
//_sequencer->sequenceReset();
}
void RenderablePlanetProjection::loadTexture(){
@@ -478,5 +486,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
+2 -1
View File
@@ -75,7 +75,8 @@ Renderable::Renderable(const ghoul::Dictionary& dictionary)
_hasTimeInterval(false),
_startTime(""),
_endTime(""),
_targetBody("")
_targetBody(""),
_hasBody(false)
{
setName("renderable");
#ifndef NDEBUG
+78 -97
View File
@@ -29,7 +29,9 @@
#include <openspace/util/constants.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/imagesequencer.h>
#include <openspace/util/imagesequencer2.h> // testing
#include <openspace/util/time.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/opengl/textureunit.h>
@@ -101,9 +103,9 @@ namespace openspace{
}
void RenderableFov::allocateData(){
int points = 8;
int points = 20;
_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++){
@@ -120,7 +122,7 @@ void RenderableFov::allocateData(){
_vtotal[0] = static_cast<int>(_vsize[0] / _stride[0]);
// allocate second vbo data
int cornerPoints = 5;
int cornerPoints = 12;
_isize[1] = cornerPoints;
_iarray1[1] = new int[_isize[1]];
for (int i = 0; i < _isize[1]; i++){
@@ -210,14 +212,6 @@ void RenderableFov::insertPoint(std::vector<float>& 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);
@@ -297,46 +291,46 @@ void RenderableFov::fovProjection(bool H[], std::vector<glm::dvec3> 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 < bounds.size(); i++){
int k = (i + 1 > bounds.size() - 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){
_rebuild = false;
}else{
@@ -349,7 +343,7 @@ void RenderableFov::fovProjection(bool H[], std::vector<glm::dvec3> bounds){
for (int i = 0; i < _isize[1]; i++)
_iarray1[1][i] = i;
}
}
void RenderableFov::updateData(){
@@ -378,17 +372,17 @@ 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.7);
col_start = glm::vec4(1.00, 0.89, 0.00, 1);
col_sq = glm::vec4(1.00, 0.29, 0.00, 1);
@@ -403,6 +397,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){
@@ -411,36 +409,23 @@ 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];
}
}
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);
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 (openspace::ImageSequencer2::ref().isReady()){
drawFOV = ImageSequencer2::ref().instumentActive(_instrumentID);
}
if (drawFOV){
// update only when time progresses.
if (_oldTime != _time){
@@ -477,19 +462,19 @@ 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
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;
@@ -506,14 +491,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] + 1);
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;
@@ -525,39 +510,35 @@ void RenderableFov::render(const RenderData& data){
indx += 4;
}
}
_interceptTag[4] = _interceptTag[0]; // 0 & 5 same point
//because other instruments arent implemented as projectable instruments yet
if (_instrumentID != "NH_LORRI")
_interceptTag[bounds.size()] = _interceptTag[0];
if (!(_instrumentID == "NH_LORRI")) // image plane replaces fov square
fovProjection(_interceptTag, bounds);
updateData();
}
_oldTime = _time;
glLineWidth(_lineWidth);
glBindVertexArray(_vaoID[0]);
glDrawArrays(_mode, 0, _vtotal[0]);
glDrawArrays(GL_LINES, 0, _vtotal[0]);
glBindVertexArray(0);
//render points
glPointSize(2.f);
glLineWidth(_lineWidth);
glBindVertexArray(_vaoID[0]);
glDrawArrays(GL_POINTS, 0, _vtotal[0]);
glDrawArrays(GL_LINES, 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();
}
+1 -1
View File
@@ -192,7 +192,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;
+64 -16
View File
@@ -26,7 +26,6 @@
#include <openspace/engine/openspaceengine.h>
#include <openspace/engine/configurationmanager.h>
#include <openspace/util/constants.h>
#include <openspace/util/imagesequencer.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/util/spicemanager.h>
#include <openspace/rendering/renderengine.h>
@@ -38,6 +37,7 @@
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
#include <openspace/util/time.h>
namespace {
const std::string _loggerCat = "RenderablePlaneProjection";
@@ -144,13 +144,18 @@ void RenderablePlaneProjection::update(const UpdateData& data) {
double time = data.time;
const Image* img = openspace::ImageSequencer2::ref().getLatestImageForInstrument(_instrument);
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 (_moving || _planeIsDirty)
updatePlane(img, time);
else if (img != nullptr && img->path != tex) {
time = img->startTime;
updatePlane(img, time);
}
if (_programIsDirty) {
@@ -181,18 +186,19 @@ void RenderablePlaneProjection::loadTexture() {
}
}
void RenderablePlaneProjection::updatePlane(double time, std::string newPath) {
void RenderablePlaneProjection::updatePlane(const Image* img, double currentTime) {
std::string shape, frame;
std::vector<glm::dvec3> bounds;
glm::dvec3 boresight;
std::string target = "JUPITER"; //default
if (!_moving) {
target = findClosestTarget(currentTime);
}
int iTime = static_cast<int>(time);
if (iTime % 2 && !_moving)
setTarget("JUPITER");
else if (!_moving)
setTarget("IO");
setTarget(target);
bool found = openspace::SpiceManager::ref().getFieldOfView(_instrument, shape, frame, boresight, bounds);
if (!found) {
@@ -204,17 +210,17 @@ void RenderablePlaneProjection::updatePlane(double time, std::string newPath) {
double lt;
psc projection[4];
SpiceManager::ref().getTargetPosition(_target.body, _spacecraft, galacticFrame, "CN+S", time, vecToTarget, lt);
SpiceManager::ref().getTargetPosition(_target.body, _spacecraft, galacticFrame, "CN+S", currentTime, 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);
openspace::SpiceManager::ref().frameConversion(bounds[j], frame, galacticFrame, currentTime);
glm::dvec3 cornerPosition = openspace::SpiceManager::ref().orthogonalProjection(vecToTarget, bounds[j]);
if (!_moving) {
cornerPosition -= vecToTarget;
}
openspace::SpiceManager::ref().frameConversion(cornerPosition, galacticFrame, _target.frame, time);
openspace::SpiceManager::ref().frameConversion(cornerPosition, galacticFrame, _target.frame, currentTime);
projection[j] = PowerScaledCoordinate::CreatePowerScaledCoordinate(cornerPosition[0], cornerPosition[1], cornerPosition[2]);
projection[j][3] += 3;
@@ -245,14 +251,17 @@ void RenderablePlaneProjection::updatePlane(double time, std::string newPath) {
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast<void*>(sizeof(GLfloat) * 4));
if (!_moving) {
_texturePath = newPath;
if (!_moving && img != nullptr) {
_texturePath = img->path;
loadTexture();
}
}
void RenderablePlaneProjection::setTarget(std::string body) {
if (body == "")
return;
std::vector<SceneGraphNode*> nodes = OsEng.renderEngine()->scene()->allSceneGraphNodes();
Renderable* possibleTarget;
bool hasBody, found = false;
@@ -276,4 +285,43 @@ void RenderablePlaneProjection::setTarget(std::string body) {
}
}
std::string RenderablePlaneProjection::findClosestTarget(double currentTime) {
std::vector<std::string> targets;
std::vector<SceneGraphNode*> nodes = OsEng.renderEngine()->scene()->allSceneGraphNodes();
Renderable* possibleTarget;
std::string targetBody;
bool hasBody, found = false;
PowerScaledScalar min = PowerScaledScalar::CreatePSS(9999999999999);
PowerScaledScalar distance = PowerScaledScalar::CreatePSS(0.0);
std::string closestTarget = "";
psc spacecraftPos;
double lt;
SpiceManager::ref().getTargetPosition(_spacecraft, "SSB", galacticFrame, "NONE", currentTime, spacecraftPos, lt);
for (auto node : nodes)
{
possibleTarget = node->renderable();
if (possibleTarget != nullptr) {
hasBody = possibleTarget->hasBody();
if (hasBody && possibleTarget->getBody(targetBody)) {
openspace::SpiceManager::ref().targetWithinFieldOfView(_instrument, targetBody, _spacecraft, "ELLIPSOID", "NONE", currentTime, found);
if (found){
targets.push_back(node->name()); // get name from propertyOwner
distance = (node->worldPosition() - spacecraftPos).length();
if (distance < min)
closestTarget = targetBody;
}
}
}
}
return closestTarget;
}
} // namespace openspace
+33 -41
View File
@@ -30,6 +30,9 @@
#include <openspace/util/updatestructures.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/misc/highresclock.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/interaction/interactionhandler.h>
/* 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";
@@ -78,13 +82,15 @@ RenderableTrail::RenderableTrail(const ghoul::Dictionary& dictionary)
glm::vec3 color(0.f);
if (dictionary.hasKeyAndValue<glm::vec3>(keyColor))
dictionary.getValue(keyColor, color);
_lineColor = color;
_lineColor.setViewOption(properties::Property::ViewOptions::Color);
_lineColor = color;
_lineColor.setViewOption(properties::Property::ViewOptions::Color);
addProperty(_lineColor);
addProperty(_lineFade);
addProperty(_lineWidth);
_distanceFade = 1.0;
}
bool RenderableTrail::initialize() {
@@ -138,6 +144,19 @@ void RenderableTrail::render(const RenderData& data) {
_programObject->setUniform("nVertices", static_cast<unsigned int>(_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();
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);
@@ -150,7 +169,8 @@ void RenderableTrail::render(const RenderData& data) {
}
void RenderableTrail::update(const UpdateData& data) {
if (data.isTimeJump)
_time = data.time;
if (data.isTimeJump)
_needsSweep = true;
if (_needsSweep) {
@@ -165,14 +185,7 @@ void RenderableTrail::update(const UpdateData& data) {
_programIsDirty = false;
}
double lightTime = 0.0;
psc pscPos;
bool intervalSet = hasTimeInterval();
double start = DBL_MIN;
double end = DBL_MAX;
if (intervalSet) {
getInterval(start, end);
}
psc pscPos, pscVel;
// 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
@@ -182,13 +195,9 @@ void RenderableTrail::update(const UpdateData& data) {
int nValues = floor(deltaTime / _increment);
// Update the floating current time
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);
// 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);
pscPos[3] += 3; // KM to M
_vertexArray[0] = { pscPos[0], pscPos[1], pscPos[2], pscPos[3] };
@@ -203,12 +212,8 @@ void RenderableTrail::update(const UpdateData& data) {
for (int i = nValues; i > 0; --i) {
double et = _oldTime + i * _increment;
if (start > et)
et = start;
else if (end < et)
et = end;
SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", et, pscPos, lightTime);
pscPos[3] += 3;
SpiceManager::ref().getTargetState(_target, _observer, _frame, "CN+S", et, pscPos, pscVel, lightTime);
pscPos[3] += 3;
_vertexArray[i] = { pscPos[0], pscPos[1], pscPos[2], pscPos[3] };
}
@@ -236,28 +241,15 @@ void RenderableTrail::fullYearSweep(double time) {
float planetYear = SecondsPerEarthYear * _ratio;
int segments = static_cast<int>(_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;
bool validPosition = true;
_vertexArray.resize(segments+2);
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;
for (int i = 0; i < segments+2; i++){
SpiceManager::ref().getTargetState(_target, _observer, _frame, "CN+S", time, pscPos, pscVel, lightTime);
pscPos[3] += 3;
_vertexArray[i] = {pscPos[0], pscPos[1], pscPos[2], pscPos[3]};
time -= _increment;
+132 -78
View File
@@ -24,6 +24,9 @@
#include <openspace/rendering/renderengine.h>
#include <openspace/util/imagesequencer2.h>
#include <openspace/abuffer/abuffervisualizer.h>
#include <openspace/abuffer/abuffer.h>
#include <openspace/abuffer/abufferframebuffer.h>
@@ -39,7 +42,6 @@
#include <openspace/util/screenlog.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/syncbuffer.h>
#include <openspace/util/imagesequencer.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/lua/lua_helper.h>
#include <ghoul/misc/sharedmemory.h>
@@ -430,8 +432,6 @@ namespace openspace {
Time::ref().deltaTime(),
_doPerformanceMeasurements
});
_sceneGraph->evaluate(_mainCamera);
// clear the abuffer before rendering the scene
@@ -507,56 +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();
ImageSequencer::ref().findActiveInstrument(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::string active = ImageSequencer::ref().getActiveInstrument();
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()
);
}
}
@@ -583,14 +533,13 @@ 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
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());
@@ -599,30 +548,88 @@ 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(" ");
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::ImageSequencer2::ref().getNextCaptureTime(), 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:", 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::pair<double, std::string> nextTarget = ImageSequencer2::ref().getNextTarget();
std::pair<double, std::string> currentTarget = ImageSequencer2::ref().getCurrentTarget();
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);
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));
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<double, std::vector<std::string>> 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::map<std::string, bool> 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);
PrintColorText(i++, "Active Instruments : ", 10, active);
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), t.first.c_str());
}
else{
PrintColorText(i, "|", 10, glm::vec4(0.3, 0.3, 0.3, 1));
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, t.first.c_str());
}
}
}
glm::vec4 w(1);
glm::vec4 b(0.3, 0.6, 1, 1);
PrintColorText(i++, "Ucoming : %s", 10, w, str.c_str());
std::string active = ImageSequencer::ref().getActiveInstrument();
PrintColorText(i++, "Active Instrument : %s", 10, b, active.c_str());
#undef PrintText
}
@@ -965,7 +972,11 @@ void RenderEngine::changeViewPoint(std::string origin) {
SceneGraphNode* solarSystemBarycenterNode = scene()->sceneGraphNode("SolarSystemBarycenter");
SceneGraphNode* plutoBarycenterNode = scene()->sceneGraphNode("PlutoBarycenter");
SceneGraphNode* newHorizonsNode = scene()->sceneGraphNode("NewHorizons");
SceneGraphNode* newHorizonsTrailNode = scene()->sceneGraphNode("NewHorizonsTrail");
SceneGraphNode* jupiterBarycenterNode = scene()->sceneGraphNode("JupiterBarycenter");
//SceneGraphNode* newHorizonsGhostNode = sceneGraph()->sceneGraphNode("NewHorizonsGhost");
//SceneGraphNode* dawnNode = scene()->sceneGraphNode("Dawn");
//SceneGraphNode* vestaNode = scene()->sceneGraphNode("Vesta");
@@ -984,6 +995,7 @@ void RenderEngine::changeViewPoint(std::string origin) {
solarSystemBarycenterNode->setParent(plutoBarycenterNode);
newHorizonsNode->setParent(plutoBarycenterNode);
//newHorizonsTrailNode->setParent(plutoBarycenterNode);
ghoul::Dictionary solarDictionary =
{
{ std::string("Type"), std::string("Spice") },
@@ -1010,9 +1022,12 @@ 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));
//newHorizonsTrailNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary));
//ghoul::Dictionary dawnDictionary =
//{
@@ -1034,6 +1049,17 @@ 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("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") {
@@ -1042,6 +1068,7 @@ void RenderEngine::changeViewPoint(std::string origin) {
plutoBarycenterNode->setParent(solarSystemBarycenterNode);
jupiterBarycenterNode->setParent(solarSystemBarycenterNode);
newHorizonsNode->setParent(solarSystemBarycenterNode);
//newHorizonsTrailNode->setParent(solarSystemBarycenterNode);
ghoul::Dictionary plutoDictionary =
{
@@ -1073,6 +1100,8 @@ void RenderEngine::changeViewPoint(std::string origin) {
{ std::string("Kernels"), ghoul::Dictionary() }
};
newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary));
//newHorizonsTrailNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary));
//ghoul::Dictionary dawnDictionary =
//{
@@ -1094,7 +1123,18 @@ void RenderEngine::changeViewPoint(std::string origin) {
//};
//vestaNode->setEphemeris(new SpiceEphemeris(vestaDictionary));
return;
/*
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") {
jupiterBarycenterNode->setParent(scene()->sceneGraphNode("SolarSystem"));
@@ -1102,6 +1142,7 @@ void RenderEngine::changeViewPoint(std::string origin) {
solarSystemBarycenterNode->setParent(jupiterBarycenterNode);
newHorizonsNode->setParent(jupiterBarycenterNode);
//newHorizonsTrailNode->setParent(jupiterBarycenterNode);
ghoul::Dictionary solarDictionary =
{
@@ -1131,7 +1172,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));
//newHorizonsTrailNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary));
//ghoul::Dictionary dawnDictionary =
@@ -1154,6 +1196,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("Reference"), std::string("GALACTIC") },
{ std::string("Observer"), std::string("JUPITER BARYCENTER") },
{ std::string("Kernels"), ghoul::Dictionary() }
};
newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary));
*/
return;
}
//if (origin == "Vesta") {
+10 -2
View File
@@ -199,17 +199,25 @@ bool Scene::initialize() {
"${SHADERS}/pscstandard_fs.glsl");
if( ! tmpProgram) return false;
tmpProgram->setProgramObjectCallback(cb);
_programs.push_back(tmpProgram);
OsEng.ref().configurationManager()->setValue("pscShader", tmpProgram);
// NH shader
tmpProgram = ProgramObject::Build("ModelProgram",
"${SHADERS}/model_vs.glsl",
"${SHADERS}/model_fs.glsl");
if (!tmpProgram) return false;
tmpProgram->setProgramObjectCallback(cb);
_programs.push_back(tmpProgram);
OsEng.ref().configurationManager()->setValue("GenericModelShader", tmpProgram);
// 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);
+10 -7
View File
@@ -27,6 +27,7 @@
#include <openspace/util/constants.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/time.h>
#include <openspace/util/imagesequencer2.h>
namespace {
const std::string _loggerCat = "SpiceEphemeris";
@@ -73,16 +74,18 @@ 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);
_position[3] += 3;
}
+59
View File
@@ -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 <openspace/util/decoder.h>
#include <openspace/util/factorymanager.h>
namespace {
const std::string _loggerCat = "Decoder";
}
namespace openspace {
Decoder* Decoder::createFromDictionary(const ghoul::Dictionary& dictionary, const std::string type)
{
ghoul::TemplateFactory<Decoder>* factory
= FactoryManager::ref().factory<Decoder>();
Decoder* result = factory->create(type, dictionary);
if (result == nullptr) {
LERROR("Failed creating Payload object of type '" << type << "'");
return nullptr;
}
return result;
}
Decoder::Decoder()
{
}
Decoder::Decoder(const ghoul::Dictionary& dictionary)
{
}
Decoder::~Decoder()
{
}
} // namespace openspace
+9
View File
@@ -53,6 +53,10 @@
#include <openspace/rendering/planets/simplespheregeometryprojection.h>
#include <openspace/rendering/planets/planetgeometryprojection.h>
#include <openspace/util/decoder.h>
#include <openspace/util/instrumentdecoder.h>
#include <openspace/util/targetdecoder.h>
// std
#include <cassert>
@@ -104,6 +108,11 @@ void FactoryManager::initialize()
_manager->factory<Ephemeris>()->registerClass<StaticEphemeris>("Dynamic");
_manager->factory<Ephemeris>()->registerClass<SpiceEphemeris>("Spice");
_manager->addFactory(new ghoul::TemplateFactory<Decoder>);
_manager->factory<Decoder>()->registerClass<InstrumentDecoder>("Instrument");
_manager->factory<Decoder>()->registerClass<TargetDecoder>("Target");
// Add PlanetGeometry
_manager->addFactory(new ghoul::TemplateFactory<planetgeometry::PlanetGeometry>);
_manager->factory<planetgeometry::PlanetGeometry>()
+377
View File
@@ -0,0 +1,377 @@
/*****************************************************************************************
* *
* 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 <openspace/util/ImageSequencer2.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/filesystem/directory.h>
#include <openspace/util/time.h>
#include <openspace/util/spicemanager.h>
#include <fstream>
#include <iterator>
#include <iomanip>
#include <limits>
#include <openspace/util/hongkangparser.h>
#include <openspace/util/instrumentdecoder.h>
namespace {
const std::string _loggerCat = "HongKangParser";
const std::string keyTranslation = "DataInputTranslation";
}
namespace openspace {
HongKangParser::HongKangParser(const std::string& fileName,
std::string spacecraft,
ghoul::Dictionary translationDictionary,
std::vector<std::string> potentialTargets) :
_defaultCaptureImage(absPath("${OPENSPACE_DATA}/scene/common/textures/placeholder_blank.png"))
{
_fileName = fileName;
_spacecraft = spacecraft;
_potentialTargets = potentialTargets;
//get the different instrument types
const std::vector<std::string>& 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<std::string>& 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);
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<std::string> 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(){
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 , std::ios::binary);
if (!file.good()) LERROR("Failed to open txt file '" << _fileName << "'");
std::string line = "";
double shutter = 0.01;
double startTime, stopTime;
std::string previousTarget;
std::string previousCamera;
std::string previousScanner;
TimeRange cameraRange;
TimeRange scanRange;
std::vector<std::string> scannerSpiceID;
std::vector<std::string> 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";
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);
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<double, std::string> v_target = std::make_pair(time, image.target);
_targetTimes.push_back(v_target);
}
//store actual image in map. All targets get _only_ their corresp. subset.
_subsetMap[image.target]._subset.push_back(image);
//compute and store the range for each subset
_subsetMap[image.target]._range.setRange(time);
}
if (it->second->getDecoderType() == "SCANNER"){ // SCANNER START
scan_start = time;
InstrumentDecoder* scanner = static_cast<InstrumentDecoder*>(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();*/
}
}
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;
}*/
}
}
}
}
}
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_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_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){
myfile << " " << instrument;
}
myfile << std::endl;
}
}
myfile.close();
}
bool HongKangParser::augmentWithSpice(Image& image,
std::string spacecraft,
std::vector<std::string> payload,
std::vector<std::string> 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<std::string> instr, std::string targ, std::string path) {
image.startTime = startTime;
image.stopTime = stopTime;
image.path = path;
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 line){
std::string::size_type sz;
return getETfromMet(std::stod(line, &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<std::string, ImageSubset> HongKangParser::getSubsetMap(){
return _subsetMap;
}
std::vector<std::pair<std::string, TimeRange>> HongKangParser::getIstrumentTimes(){
return _instrumentTimes;
}
std::vector<std::pair<double, std::string>> HongKangParser::getTargetTimes(){
return _targetTimes;
}
std::vector<double> HongKangParser::getCaptureProgression(){
return _captureProgression;
};
}
+253 -80
View File
@@ -46,21 +46,40 @@ 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{
std::vector<std::vector<ImageParams>> _timeStamps;
void createImage(std::vector<ImageParams>& 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<ImageParams> _timeStamps;
std::vector<ImageParams>::iterator binary_find(std::vector<ImageParams>::iterator begin,
std::vector<ImageParams>::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<ImageParams>::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("${OPENSPACE_DATA}/scene/common/textures/placeholder_blank.png"))
{}
@@ -78,102 +97,259 @@ 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<std::string> payload){
if (sequenceID >= 0){
_observers.insert(std::make_pair(sequenceID, name));
_instruments.insert(std::make_pair(name, payload));
}
}
void ImageSequencer::registerTargets(std::vector<std::string>& 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<ImageParams>& 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);
// sort
vec.push_back(image);
}
double ImageSequencer::getNextCaptureTime(){
return _nextCapture;
}
double ImageSequencer::nextCaptureTime(double _time){
auto binary_find = [](std::vector<ImageParams>::iterator begin,
std::vector<ImageParams>::iterator end,
const ImageParams &val,
bool(*cmp)(const ImageParams &a, const ImageParams &b))->std::vector<ImageParams>::iterator{
// Finds the lower bound in at most log(last - first) + 1 comparisons
std::vector<ImageParams>::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<ImageParams>::iterator begin,
std::vector<ImageParams>::iterator end,
const ImageParams &val,
bool(*cmp)(const ImageParams &a, const ImageParams &b))->std::vector<ImageParams>::iterator{
// Finds the lower bound in at most log(last - first) + 1 comparisons
std::vector<ImageParams>::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())){
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{
_activeInstrument = std::prev(it)->activeInstrument;
}
return _activeInstrument;
}
std::string ImageSequencer::getLatestImage(){
return _latest;
void ImageSequencer::augumentSequenceWithTargets(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 <std::string, std::vector<std::string>>::iterator it2 = _instruments.find(observer);
if (it2 != _instruments.end()){
std::string _targetFOV;
bool _withinFOV;
// for each image taken
for (std::vector<ImageParams>::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(double& currentTime, std::string& path, bool closedInterval){
auto binary_find = [](std::vector<ImageParams>::iterator begin,
std::vector<ImageParams>::iterator end,
const ImageParams &val,
bool(*cmp)(const ImageParams &a, const ImageParams &b))->std::vector<ImageParams>::iterator{
bool ImageSequencer::getImagePath(std::vector<std::pair<double, std::string>>& _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<std::pair<double, std::string>>& _imageTimes, int sequenceID, std::string projectee){
double previousTime;
std::map<std::string, double>::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<std::pair<double, std::string>>& _imageTimes, int sequenceID, std::string projectee){
auto bfind = [](std::vector<ImageParams>::iterator begin,
std::vector<ImageParams>::iterator end,
const ImageParams &val,
bool(*imageComparer)(const ImageParams &a, const ImageParams &b))->std::vector<ImageParams>::iterator{
// Finds the lower bound in at most log(last - first) + 1 comparisons
std::vector<ImageParams>::iterator it = std::lower_bound(begin, end, val, cmp);
std::vector<ImageParams>::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<std::pair<double, std::string>>& _imageTimes, int sequenceID, std::string projectee, bool closedInterval){
double t = _currentTime;
double ptime;
std::map<std::string, double>::iterator it = _previous.find(projectee);
if (it != _previous.end()){
ptime = it->second;
it->second = _currentTime;
}
while (t > ptime){
auto binary_find = [](std::vector<ImageParams>::iterator begin,
std::vector<ImageParams>::iterator end,
const ImageParams &val,
bool(*imageComparer)(const ImageParams &a, const ImageParams &b))->std::vector<ImageParams>::iterator{
// Finds the lower bound in at most log(last - first) + 1 comparisons
std::vector<ImageParams>::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<ImageParams>::iterator begin,
std::vector<ImageParams>::iterator end,
const ImageParams &val,
bool(*imageComparer)(const ImageParams &a, const ImageParams &b))->std::vector<ImageParams>::iterator{
// Finds the lower bound in at most log(last - first) + 1 comparisons
std::vector<ImageParams>::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;
_latest = path;
return true;
}
@@ -184,6 +360,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);
@@ -193,17 +372,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<std::string> 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);
@@ -219,11 +387,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<ImageParams> tmp;
if (size_t position = fileName.find_last_of(".") + 1){
if (position != std::string::npos){
std::string extension = ghoul::filesystem::File(fileName).fileExtension();
@@ -278,7 +448,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);
@@ -311,19 +481,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<ImageParams> tmp;
ghoul::filesystem::Directory sequenceDir(dir, true);
std::vector<std::string> sequencePaths = sequenceDir.read(true, false); // check inputs
for (auto path : sequencePaths){
@@ -339,27 +513,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);
@@ -367,6 +539,7 @@ bool ImageSequencer::loadSequence(const std::string& dir) {
}
}
}
_timeStamps.push_back(tmp);
return !_timeStamps.empty();
}
+315
View File
@@ -0,0 +1,315 @@
/*****************************************************************************************
* *
* 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 <openspace/util/ImageSequencer2.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/filesystem/directory.h>
#include <openspace/util/time.h>
#include <ghoul/filesystem/cachemanager.h>
#include <openspace/util/spicemanager.h>
#include <fstream>
#include <iterator>
#include <iomanip>
#include <limits>
namespace {
const std::string _loggerCat = "ImageSequencer2";
}
namespace openspace {
ImageSequencer2* ImageSequencer2::_instance = nullptr;
ImageSequencer2::ImageSequencer2() :
_hasData(false),
_latestImage(nullptr),
_defaultCaptureImage(absPath("${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;
}
bool ImageSequencer2::isReady(){
return _hasData;
}
void ImageSequencer2::updateSequencer(double time){
if (_currentTime != time){
_previousTime = _currentTime;
_currentTime = time;
}
}
std::pair<double, std::string> ImageSequencer2::getNextTarget(){
auto compareTime = [](const std::pair<double, std::string> &a,
const std::pair<double, std::string> &b)->bool{
return a.first < b.first;
};
std::pair<double, std::string> findEqualToThis;
findEqualToThis.first = _currentTime;
auto it = std::lower_bound(_targetTimes.begin(), _targetTimes.end(), findEqualToThis, compareTime);
if (it != _targetTimes.end() && it != _targetTimes.begin()){
return (*it);
}
}
std::pair<double, std::string> ImageSequencer2::getCurrentTarget(){
auto compareTime = [](const std::pair<double, std::string> &a,
const std::pair<double, std::string> &b)->bool{
return a.first < b.first;
};
std::pair<double, std::string> findEqualToThis;
findEqualToThis.first = _currentTime;
auto it = std::lower_bound(_targetTimes.begin(), _targetTimes.end(), findEqualToThis, compareTime);
if (it != _targetTimes.end() && it != _targetTimes.begin() ){
return *std::prev(it);
}
}
std::pair<double, std::vector<std::string>> ImageSequencer2::getIncidentTargetList(int range){
std::pair<double, std::vector<std::string>> incidentTargets;
auto compareTime = [](const std::pair<double, std::string> &a,
const std::pair<double, std::string> &b)->bool{
return a.first < b.first;
};
// what to look for
std::pair<double, std::string> findEqualToThis;
findEqualToThis.first = _currentTime;
auto it = std::lower_bound(_targetTimes.begin(), _targetTimes.end(), findEqualToThis, compareTime);
if (it != _targetTimes.end() && it != _targetTimes.begin()){
// move the iterator to the first element of the range
std::advance(it, -(range + 1));
// 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;
}
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;
}
const Image* ImageSequencer2::getLatestImageForInstrument(const std::string _instrumentID){
return _latestImage;
}
std::map<std::string, bool> 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)){
// 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 entire map, seen in GUI.
return _switchingMap;
}
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 spiceID
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;
}
bool ImageSequencer2::getImagePaths(std::vector<Image>& captures,
std::string projectee,
std::string instrumentID){
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;
}
bool ImageSequencer2::getImagePaths(std::vector<Image>& 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{
return a.startTime < b.startTime;
};
// for readability we store the iterators
auto begin = _subsetMap[projectee]._subset.begin();
auto end = _subsetMap[projectee]._subset.end();
// create temporary storage
std::vector<Image> captureTimes;
// what to look for
Image findPrevious, findCurrent;
findPrevious.startTime = _previousTime;
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){
if (curr->startTime >= prev->startTime){
// insert
std::transform(prev, curr, std::back_inserter(captureTimes),
[](const Image& image) {
return image;
});
std::reverse(captureTimes.begin(), captureTimes.end());
captures = captureTimes;
if (!captures.empty())
_latestImage = &captures.back();
return true;
}
}
}
return false;
}
void ImageSequencer2::sortData(){
auto targetComparer = [](const std::pair<double, std::string> &a,
const std::pair<double, std::string> &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();
// get new data
std::map<std::string, Decoder*> in1 = parser->getTranslation();
std::map<std::string, ImageSubset> in2 = parser->getSubsetMap();
std::vector<std::pair<std::string, TimeRange>> in3 = parser->getIstrumentTimes();
std::vector<std::pair<double, std::string>> in4 = parser->getTargetTimes();
std::vector<double> 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" );
// 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){
if (t.second->getDecoderType() == "CAMERA" ||
t.second->getDecoderType() == "SCANNER" ){
std::vector<std::string> spiceIDs = t.second->getTranslation();
for (auto id : spiceIDs){
_switchingMap[id] = false;
}
}
}
_hasData = true;
}
} // namespace openspace
+74
View File
@@ -0,0 +1,74 @@
/*****************************************************************************************
* *
* 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 <openspace/util/instrumentdecoder.h>
namespace {
const std::string _loggerCat = "InstrumentDecoder";
const std::string keyDetector = "DetectorType";
const std::string keySpice = "Spice";
const std::string keyStopCommand = "StopCommand";
}
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); });
if (!dictionary.hasKeyAndValue<std::string>(keyStopCommand) && _type == "SCANNER"){
LWARNING("Scanner must provide stop command, please check mod file.");
}else{
dictionary.getValue(keyStopCommand, _stopCommand);
}
std::vector<std::string> 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::getStopCommand(){
return _stopCommand;
}
std::string InstrumentDecoder::getDecoderType(){
return _type;
}
std::vector<std::string> InstrumentDecoder::getTranslation(){
return _spiceIDs;
}
} // namespace openspace
+278
View File
@@ -0,0 +1,278 @@
/*****************************************************************************************
* *
* 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 <openspace/util/ImageSequencer2.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/filesystem/directory.h>
#include <openspace/util/time.h>
#include <openspace/util/spicemanager.h>
#include <fstream>
#include <iterator>
#include <iomanip>
#include <limits>
#include <openspace/util/labelparser.h>
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;
//get the different instrument types
const std::vector<std::string>& 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<std::string>& 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<std::string>& 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;
};
}
}
}
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(){
auto imageComparer = [](const Image &a, const Image &b)->bool{
return a.startTime < b.startTime;
};
auto targetComparer = [](const std::pair<double, std::string> &a,
const std::pair<double, std::string> &b)->bool{
return a.first < b.first;
};
std::string previousTarget;
ghoul::filesystem::Directory sequenceDir(_fileName, true);
std::vector<std::string> 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() << "'");
int count = 0;
// open up label files
std::string line = "";
std::string previousSequence;
TimeRange instrumentRange;
do {
std::getline(file, line);
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++;
}
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) {
Image image;
std::vector<std::string> 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());
}
}
}
}
std::vector<Image> 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<double, std::string> 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<std::string> 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<std::string, ImageSubset> LabelParser::getSubsetMap(){
return _subsetMap;
}
std::vector<std::pair<std::string, TimeRange>> LabelParser::getIstrumentTimes(){
return _instrumentTimes;
}
std::vector<std::pair<double, std::string>> LabelParser::getTargetTimes(){
return _targetTimes;
}
}
+53
View File
@@ -0,0 +1,53 @@
/*****************************************************************************************
* *
* 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 <openspace/util/scannerdecoder.h>
namespace {
const std::string _loggerCat = "ScannerDecoder";
}
namespace openspace {
ScannerDecoder::ScannerDecoder(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 ScannerDecoder::getDecoderType(){
return _type;
}
std::vector<std::string> ScannerDecoder::getSpiceIDs(){
return _spiceIDs;
}
void ScannerDecoder::setStopCommand(std::string stopCommand){
_abort = stopCommand;
}
} // namespace openspace
+51
View File
@@ -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. *
****************************************************************************************/
#include <openspace/util/targetdecoder.h>
namespace {
const std::string _loggerCat = "TargetDecoder";
}
namespace openspace {
TargetDecoder::TargetDecoder(const ghoul::Dictionary& dictionary) :_type("TARGET")
{
_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 TargetDecoder::getDecoderType(){
return _type;
}
std::vector<std::string> TargetDecoder::getTranslation(){
return _names;
}
} // namespace openspace