Merge branch 'develop' into NewHorizonsMerge

This commit is contained in:
Michal Marcinkowski
2015-05-05 20:33:52 -04:00
31 changed files with 1025 additions and 193 deletions

View File

@@ -92,7 +92,7 @@ include_directories(${GHOUL_ROOT_DIR}/ext/boost)
find_package(SGCT REQUIRED)
include_directories(${SGCT_INCLUDE_DIRECTORIES})
set(DEPENDENT_LIBS ${DEPENDENT_LIBS} ${SGCT_LIBRARIES})
if (UNIX)
if (UNIX AND (NOT APPLE))
set(DEPENDENT_LIBS ${DEPENDENT_LIBS} Xcursor Xinerama)
endif ()
@@ -145,7 +145,11 @@ endif ()
#########################################################################################
add_subdirectory(src)
add_subdirectory(gui)
option(BUILD_GUI_APPLICATIONS "Build GUI Applications" OFF)
if (BUILD_GUI_APPLICATIONS)
add_subdirectory(gui)
endif ()
#########################################################################################
# File Fetch

View File

@@ -6,5 +6,5 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
find_package(Qt5Widgets)
find_package(Qt5Network)
add_executable(TimelineView main.cpp mainwindow.cpp configurationwidget.cpp informationwidget.cpp timecontrolwidget.cpp timelinewidget.cpp)
add_executable(TimelineView main.cpp mainwindow.cpp configurationwidget.cpp informationwidget.cpp controlwidget.cpp timelinewidget.cpp)
target_link_libraries(TimelineView Qt5::Widgets Qt5::Network)

37
gui/timelineview/common.h Normal file
View File

@@ -0,0 +1,37 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2015 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __COMMON_H__
#define __COMMON_H__
struct Image {
double beginning;
double ending;
std::string beginningString;
std::string endingString;
std::string target;
std::vector<std::string> instruments;
};
#endif // __COMMON_H__

View File

@@ -31,15 +31,11 @@ ConfigurationWidget::ConfigurationWidget(QWidget* parent)
, _ipAddress(new QLineEdit("localhost"))
, _port(new QLineEdit("20500"))
, _connect(new QPushButton("Connect"))
, _playbook(new QLineEdit)
, _load(new QPushButton("Load"))
{
QGridLayout* layout = new QGridLayout;
layout->addWidget(_ipAddress, 0, 0);
layout->addWidget(_port, 0, 1);
layout->addWidget(_connect, 0, 2);
layout->addWidget(_playbook, 1, 0, 1, 2);
layout->addWidget(_load, 1, 2);
setLayout(layout);
@@ -50,3 +46,9 @@ ConfigurationWidget::ConfigurationWidget(QWidget* parent)
void ConfigurationWidget::onConnectButton() {
emit connect(_ipAddress->text(), _port->text());
}
void ConfigurationWidget::socketConnected() {
}
void ConfigurationWidget::socketDisconnected() {
}

View File

@@ -34,6 +34,9 @@ Q_OBJECT
public:
ConfigurationWidget(QWidget* parent);
void socketConnected();
void socketDisconnected();
signals:
void connect(QString host, QString port);
@@ -44,9 +47,6 @@ private:
QLineEdit* _ipAddress;
QLineEdit* _port;
QPushButton* _connect;
QLineEdit* _playbook;
QPushButton* _load;
};
#endif // __CONFIGURATIONWIDGET_H__

View File

@@ -22,7 +22,7 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include "timecontrolwidget.h"
#include "controlwidget.h"
#include <QComboBox>
#include <QGridLayout>
@@ -31,7 +31,43 @@
#include <QPushButton>
#include <QSlider>
TimeControlWidget::TimeControlWidget(QWidget* parent)
namespace {
struct ImportantDate {
QString date;
QString focus;
QString coordinateSystem;
};
const ImportantDate ImportantDates[] = {
{ "2007-02-27T16:40:00.00", "JupiterProjection", "Jupiter" },
{ "2015-07-14T10:10:00.00", "PlutoProjection", "Pluto" },
{ "2015-07-14T10:50:00.00", "PlutoProjection", "Pluto" },
{ "2015-07-14T11:22:00.00", "PlutoProjection", "Pluto" },
{ "2015-07-14T11:36:40.00", "PlutoProjection", "Pluto" },
{ "2015-07-14T11:48:43.00", "PlutoProjection", "Pluto" },
{ "2015-07-14T12:04:35.00", "PlutoProjection", "Pluto" },
{ "2015-07-14T15:02:46.00", "PlutoProjection", "Pluto" }
};
struct FocusNode {
QString guiName;
QString name;
QString coordinateSystem;
};
const FocusNode FocusNodes[] = {
{ "Earth", "Earth", "Sun" },
{ "Sun", "Sun", "Sun" },
{ "Pluto", "PlutoProjection", "Pluto" },
{ "Charon", "Charon", "Pluto" },
{ "Jupiter", "JupiterProjection", "Jupiter" },
{ "New Horizons", "NewHorizons", "" },
{ "Nix", "Nix", "Pluto" },
{ "Kerberos", "Kerberos", "Pluto" },
{ "Hydra", "Hydra", "Pluto" },
};
}
ControlWidget::ControlWidget(QWidget* parent)
: QWidget(parent)
, _currentTime(new QLabel("Current Time"))
, _setTime(new QComboBox)
@@ -41,7 +77,26 @@ TimeControlWidget::TimeControlWidget(QWidget* parent)
, _pause(new QPushButton("||"))
, _play(new QPushButton("|>"))
, _forward(new QPushButton(">>"))
, _focusNode(new QComboBox)
{
for (const ImportantDate& d : ImportantDates)
_setTime->addItem(d.date);
QObject::connect(
_setTime,
SIGNAL(currentIndexChanged(int)),
this,
SLOT(onDateChange())
);
for (const FocusNode& f : FocusNodes)
_focusNode->addItem(f.guiName);
QObject::connect(
_focusNode,
SIGNAL(currentIndexChanged(int)),
this,
SLOT(onFocusChange())
);
_setDelta->setMinimum(-100);
_setDelta->setMaximum(100);
_setDelta->setValue(0);
@@ -96,36 +151,89 @@ TimeControlWidget::TimeControlWidget(QWidget* parent)
controlContainer->setLayout(controlContainerLayout);
layout->addWidget(controlContainer, 3, 0, 1, 2);
layout->addWidget(_focusNode, 4, 0, 1, 2);
setLayout(layout);
}
void TimeControlWidget::update(QString currentTime, QString currentDelta) {
void ControlWidget::update(QString currentTime, QString currentDelta) {
_currentTime->setText(currentTime);
_currentDelta->setText(currentDelta);
}
void TimeControlWidget::onValueChange() {
QString script = "openspace.time.setDeltaTime(" + QString::number(_setDelta->value()) + ");";
void ControlWidget::onValueChange() {
float value = static_cast<float>(_setDelta->value());
int delta;
if (value < 0.f) {
value = -value;
float d = std::pow(2, value / 10);
delta = static_cast<int>(-d);
}
else {
float d = std::pow(2, value / 10);
delta = static_cast<int>(d);
}
QString script = "openspace.time.setDeltaTime(" + QString::number(delta) + ");";
emit scriptActivity(script);
}
void TimeControlWidget::onRewindButton() {
void ControlWidget::onRewindButton() {
QString script = "openspace.time.setDeltaTime(-openspace.time.deltaTime());";
emit scriptActivity(script);
}
void TimeControlWidget::onPauseButton() {
void ControlWidget::onPauseButton() {
QString script = "openspace.time.setPause(true);";
emit scriptActivity(script);
}
void TimeControlWidget::onPlayButton() {
void ControlWidget::onPlayButton() {
QString script = "openspace.time.setPause(false);";
emit scriptActivity(script);
}
void TimeControlWidget::onForwardButton() {
void ControlWidget::onForwardButton() {
QString script = "openspace.time.setDeltaTime(-openspace.time.deltaTime());";
emit scriptActivity(script);
}
void ControlWidget::onDateChange() {
int index = _setTime->currentIndex();
QString date = ImportantDates[index].date;
QString focus = ImportantDates[index].focus;
QString coordinateSystem = ImportantDates[index].coordinateSystem;
QString script =
"openspace.time.setTime('" + date + "');\
openspace.setOrigin('" + focus + "');\
openspace.changeCoordinateSystem('" + coordinateSystem + "');";
emit scriptActivity(script);
}
void ControlWidget::onFocusChange() {
int index = _focusNode->currentIndex();
QString name = FocusNodes[index].name;
QString coordinateSystem = FocusNodes[index].coordinateSystem;
if (coordinateSystem.isEmpty()) {
int date = _currentTime->text().left(4).toInt();
if (date < 2008)
coordinateSystem = "Jupiter";
else if (date < 2014)
coordinateSystem = "Sun";
else
coordinateSystem = "Pluto";
}
QString script = "openspace.setOrigin('" + name + "');openspace.changeCoordinateSystem('" + coordinateSystem + "');";
emit scriptActivity(script);
}
void ControlWidget::socketConnected() {
setDisabled(false);
}
void ControlWidget::socketDisconnected() {
setDisabled(true);
}

View File

@@ -22,8 +22,8 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __TIMECONTROLWIDGET_H__
#define __TIMECONTROLWIDGET_H__
#ifndef __CONTROLWIDGET_H__
#define __CONTROLWIDGET_H__
#include <QWidget>
@@ -32,18 +32,23 @@ class QLabel;
class QPushButton;
class QSlider;
class TimeControlWidget : public QWidget {
class ControlWidget : public QWidget {
Q_OBJECT
public:
TimeControlWidget(QWidget* parent);
ControlWidget(QWidget* parent);
void update(QString currentTime, QString currentDelta);
void socketConnected();
void socketDisconnected();
signals:
void scriptActivity(QString script);
private slots:
void onValueChange();
void onDateChange();
void onFocusChange();
void onRewindButton();
void onPauseButton();
void onPlayButton();
@@ -58,8 +63,7 @@ private:
QPushButton* _pause;
QPushButton* _play;
QPushButton* _forward;
bool _stateNoNotification = false;
QComboBox* _focusNode;
};
#endif // __TIMECONTROLWIDGET_H__
#endif // __CONTROLWIDGET_H__

View File

@@ -31,3 +31,11 @@ InformationWidget::InformationWidget(QWidget* parent)
: QTextEdit(parent)
{
}
void InformationWidget::socketConnected() {
setDisabled(false);
}
void InformationWidget::socketDisconnected() {
setDisabled(true);
}

View File

@@ -31,6 +31,8 @@ class InformationWidget : public QTextEdit {
Q_OBJECT
public:
InformationWidget(QWidget* parent);
void socketConnected();
void socketDisconnected();
};
#endif // __INFORMATIONWIDGET_H__

View File

@@ -25,7 +25,7 @@
#include "mainwindow.h"
#include "configurationwidget.h"
#include "timecontrolwidget.h"
#include "controlwidget.h"
#include "informationwidget.h"
#include "timelinewidget.h"
@@ -36,6 +36,28 @@
#include <array>
#include <cstdint>
template <typename T>
T readFromBuffer(char* buffer, size_t& currentReadLocation) {
union {
T value;
std::array<char, sizeof(T)> data;
} b;
std::memmove(b.data.data(), buffer + currentReadLocation, sizeof(T));
currentReadLocation += sizeof(T);
return b.value;
}
template <>
std::string readFromBuffer(char* buffer, size_t& currentReadLocation) {
uint8_t size = readFromBuffer<uint8_t>(buffer, currentReadLocation);
std::string result(buffer + currentReadLocation, buffer + currentReadLocation + size);
currentReadLocation += size;
return result;
}
MainWindow::MainWindow()
: QWidget(nullptr)
, _configurationWidget(nullptr)
@@ -47,7 +69,7 @@ MainWindow::MainWindow()
setWindowTitle("OpenSpace Timeline");
_configurationWidget = new ConfigurationWidget(this);
_timeControlWidget = new TimeControlWidget(this);
_timeControlWidget = new ControlWidget(this);
_informationWidget = new InformationWidget(this);
_timelineWidget = new TimelineWidget(this);
@@ -68,8 +90,12 @@ MainWindow::MainWindow()
this, SLOT(sendScript(QString))
);
setLayout(layout);
_configurationWidget->socketDisconnected();
_timeControlWidget->socketDisconnected();
_informationWidget->socketDisconnected();
_timelineWidget->socketDisconnected();
}
MainWindow::~MainWindow() {
@@ -80,26 +106,56 @@ void MainWindow::onConnect(QString host, QString port) {
delete _socket;
_socket = new QTcpSocket(this);
connect(_socket, SIGNAL(readyRead()), SLOT(readTcpData()));
QObject::connect(_socket, SIGNAL(readyRead()), SLOT(readTcpData()));
QObject::connect(_socket, SIGNAL(connected()), SLOT(onSocketConnected()));
QObject::connect(_socket, SIGNAL(disconnected()), SLOT(onSocketDisconnected()));
_socket->connectToHost(host, port.toUInt());
}
void MainWindow::readTcpData() {
static const uint8_t MessageTypeStatus = 0;
static const uint16_t MessageTypeStatus = 0;
static const uint16_t MessageTypePlayBook = 2;
QByteArray data = _socket->readAll();
//QString debug(data);
//qDebug() << debug;
if (QString(data) == "Connected to SGCT!\r\n")
return;
if (QString(data) == "OK\r\n")
return;
uint8_t messageType = data[0];
QByteArray messageTypeData = data.left(2);
union {
uint16_t value;
std::array<char, 2> data;
} messageType;
std::memcpy(messageType.data.data(), messageTypeData.data(), sizeof(uint16_t));
if (messageType == MessageTypeStatus)
handleStatusMessage(data.mid(1));
handleStatusMessage(data.right(data.length() - 1));
switch (messageType.value) {
case MessageTypeStatus:
handleStatusMessage(data.mid(2));
break;
case MessageTypePlayBook:
{
const char* payloadDebug = data.mid(2).data();
size_t beginning = 0;
uint32_t size = readFromBuffer<uint32_t>(data.mid(2).data(), beginning);
while (_socket->waitForReadyRead() && data.size() < size) {
//while (data.size() < size) {
data = data.append(_socket->readAll());
}
handlePlaybook(data.mid(2));
break;
}
default:
qDebug() << "Unknown message of type '" << messageType.value << "'";
}
}
void MainWindow::handleStatusMessage(QByteArray data) {
@@ -124,8 +180,89 @@ void MainWindow::handleStatusMessage(QByteArray data) {
QString::fromStdString(std::string(timeString.begin(), timeString.end())),
QString::number(delta.value)
);
_timelineWidget->setCurrentTime(std::string(timeString.begin(), timeString.end()), et.value);
}
std::vector<std::string> instrumentsFromId(uint16_t instrumentId, std::map<uint16_t, std::string> instrumentMap) {
std::vector<std::string> results;
for (int i = 0; i < 16; ++i) {
uint16_t testValue = 1 << i;
if ((testValue & instrumentId) != 0) {
std::string t = instrumentMap.at(testValue);
if (t.empty())
qDebug() << "Empty instrument";
results.push_back(t);
}
}
return results;
}
void MainWindow::handlePlaybook(QByteArray data) {
char* buffer = data.data();
size_t currentReadLocation = 0;
uint32_t totalData = readFromBuffer<uint32_t>(buffer, currentReadLocation);
uint8_t nTargets = readFromBuffer<uint8_t>(buffer, currentReadLocation);
qDebug() << "Targets: " << nTargets;
std::map<uint8_t, std::string> targetMap;
for (uint8_t i = 0; i < nTargets; ++i) {
uint8_t id = readFromBuffer<uint8_t>(buffer, currentReadLocation);
std::string value = readFromBuffer<std::string>(buffer, currentReadLocation);
qDebug() << QString::fromStdString(value);
targetMap[id] = value;
}
uint8_t nInstruments = readFromBuffer<uint8_t>(buffer, currentReadLocation);
qDebug() << "Instruments: " << nInstruments;
std::map<uint16_t, std::string> instrumentMap;
for (uint8_t i = 0; i < nInstruments; ++i) {
uint16_t id = readFromBuffer<uint16_t>(buffer, currentReadLocation);
std::string value = readFromBuffer<std::string>(buffer, currentReadLocation);
qDebug() << QString::fromStdString(value);
instrumentMap[id] = value;
}
uint32_t nImages = readFromBuffer<uint32_t>(buffer, currentReadLocation);
std::vector<Image> images;
for (uint32_t i = 0; i < nImages; ++i) {
Image image;
image.beginning = readFromBuffer<double>(buffer, currentReadLocation);
image.ending = readFromBuffer<double>(buffer, currentReadLocation);
image.beginningString = readFromBuffer<std::string>(buffer, currentReadLocation);
image.endingString = readFromBuffer<std::string>(buffer, currentReadLocation);
uint8_t targetId = readFromBuffer<uint8_t>(buffer, currentReadLocation);
uint16_t instrumentId = readFromBuffer<uint16_t>(buffer, currentReadLocation);
image.target = targetMap[targetId];
image.instruments = instrumentsFromId(instrumentId, instrumentMap);
if (image.instruments.empty())
qDebug() << "Instruments were empty";
images.push_back(image);
}
_timelineWidget->setData(std::move(images), std::move(targetMap), std::move(instrumentMap));
_configurationWidget->socketConnected();
_timeControlWidget->socketConnected();
_informationWidget->socketConnected();
_timelineWidget->socketConnected();
}
void MainWindow::sendScript(QString script) {
_socket->write(("0" + script + "\r\n").toLatin1());
if (_socket)
_socket->write(("0" + script + "\r\n").toLatin1());
}
void MainWindow::onSocketConnected() {
_socket->write(QString("1\r\n").toLatin1());
}
void MainWindow::onSocketDisconnected() {
_configurationWidget->socketDisconnected();
_timeControlWidget->socketDisconnected();
_informationWidget->socketDisconnected();
_timelineWidget->socketDisconnected();
}

View File

@@ -28,8 +28,10 @@
#include <QWidget>
#include <QTcpSocket>
#include "common.h"
class ConfigurationWidget;
class TimeControlWidget;
class ControlWidget;
class InformationWidget;
class TimelineWidget;
@@ -45,14 +47,18 @@ public slots:
private slots:
void onConnect(QString host, QString port);
void onSocketConnected();
void onSocketDisconnected();
//void onConnectButton();
//void sendCommandButton();
void readTcpData();
void handleStatusMessage(QByteArray data);
void handlePlaybook(QByteArray data);
private:
ConfigurationWidget* _configurationWidget;
TimeControlWidget* _timeControlWidget;
ControlWidget* _timeControlWidget;
InformationWidget* _informationWidget;
TimelineWidget* _timelineWidget;

View File

@@ -24,19 +24,237 @@
#include "timelinewidget.h"
#include <QDebug>
#include <QPainter>
#include <QPaintEvent>
#include <iostream>
#include <set>
namespace {
static const int LegendHeight = 105;
static const int TimeWidth = 200;
static const int TextOffset = 5;
//const QColor targetColors[] = {
// QColor(251, 180, 174),
// QColor(179, 205, 227),
// QColor(204, 235, 197),
// QColor(222, 203, 228),
// QColor(254, 217, 166),
// QColor(255, 255, 204)
//};
const QColor instrumentColors[] = {
QColor(228, 26, 28),
QColor(55, 126, 184),
QColor(77, 175, 74),
QColor(152, 78, 163),
QColor(255, 127, 0),
QColor(255, 255, 51),
QColor(166, 86, 40),
QColor(247, 129, 191),
QColor(153, 153, 153),
};
const double etSpread = 100.0;
}
TimelineWidget::TimelineWidget(QWidget* parent)
: QWidget(parent)
{
setMinimumWidth(300);
setMinimumHeight(500);
setMinimumWidth(600);
setMinimumHeight(600);
}
void TimelineWidget::paintEvent(QPaintEvent* event) {
QPainter painter(this);
painter.setBrush(QBrush(Qt::white));
painter.drawRect(contentsRect());
QRectF fullRect = contentsRect();
QRectF contentRect(0, 0, fullRect.width() - 1, fullRect.height() - LegendHeight);
QRectF legendRect(0, fullRect.bottom() - LegendHeight, fullRect.right(), fullRect.bottom());
painter.save();
drawContent(painter, contentRect);
painter.restore();
painter.save();
painter.translate(0, fullRect.height() - LegendHeight);
drawLegend(painter, QRectF(legendRect));
painter.restore();
}
void TimelineWidget::setData(std::vector<Image> images, std::map<uint8_t, std::string> targetMap, std::map<uint16_t, std::string> instrumentMap) {
_images = std::move(images);
std::sort(_images.begin(), _images.end(), [](const Image& a, const Image& b) { return a.beginning < b.beginning; });
_targetMap = std::move(targetMap);
_instrumentMap = std::move(instrumentMap);
_instruments.clear();
std::set<std::string> instruments;
for (auto p : _instrumentMap)
instruments.insert(p.second);
std::copy(instruments.begin(), instruments.end(), std::back_inserter(_instruments));
_targets.clear();
std::set<std::string> targets;
for (auto p : _targetMap)
targets.insert(p.second);
std::copy(targets.begin(), targets.end(), std::back_inserter(_targets));
repaint();
}
void TimelineWidget::drawContent(QPainter& painter, QRectF rect) {
QRectF timelineRect(0, 0, rect.width() - TimeWidth, rect.height());
QRectF dateRect(rect.width() - TimeWidth, 0, TimeWidth, rect.height());
// Draw background
painter.setBrush(QBrush(Qt::white)); painter.drawRect(timelineRect);
painter.setBrush(QBrush(Qt::gray)); painter.drawRect(dateRect);
const double lowerTime = _currentTime.et - etSpread;
const double upperTime = _currentTime.et + etSpread;
std::vector<Image*> images;
for (Image& i : _images) {
if (i.beginning <= upperTime && i.ending >= lowerTime)
images.push_back(&i);
}
//std::vector<Image>::const_iterator lower = std::lower_bound(_images.begin(), _images.end(), lowerTime, [](const Image& i, double time) { return i.beginning < time; });
//std::vector<Image>::const_iterator upper = std::lower_bound(_images.begin(), _images.end(), upperTime, [](const Image& i, double time) { return i.ending < time; });
//if (lower != _images.end() && upper != _images.end())
// drawImages(painter, timelineRect, std::vector<Image>(lower, upper), lowerTime, upperTime);
drawImages(painter, timelineRect, images, lowerTime, upperTime);
// Draw current time
painter.setBrush(QBrush(Qt::black));
painter.setPen(QPen(Qt::black));
painter.drawLine(QPointF(0, timelineRect.height() / 2), QPointF(timelineRect.width(), timelineRect.height() / 2));
painter.drawText(timelineRect.width(), timelineRect.height() / 2 + TextOffset, QString::fromStdString(_currentTime.time));
}
void TimelineWidget::drawLegend(QPainter& painter, QRectF rect) {
static const int HalfHeight = LegendHeight / 2;
static const int Padding = 5;
static const int BoxSize = 20;
// Draw Targets
int currentHorizontalPosition = Padding;
int currentVerticalPosition = Padding;
//for (int i = 0; i < _targets.size(); ++i) {
// const std::string& target = _targets[i];
//
// painter.setBrush(QBrush(targetColors[i]));
// painter.drawRect(currentHorizontalPosition, currentVerticalPosition, BoxSize, BoxSize);
// currentHorizontalPosition += BoxSize + Padding;
// painter.drawText(currentHorizontalPosition, currentVerticalPosition + BoxSize / 2 + TextOffset, QString::fromStdString(target));
// int textWidth = painter.boundingRect(QRect(), QString::fromStdString(target)).width();
// currentHorizontalPosition += std::max(textWidth, 25) + Padding;
//}
// Draw Instruments
currentHorizontalPosition = Padding;
currentVerticalPosition = Padding + BoxSize + Padding;
for (int i = 0; i < _instruments.size(); ++i) {
if (i == _instruments.size() / 3 || i == _instruments.size() * 2 / 3) {
currentVerticalPosition += BoxSize + Padding;
currentHorizontalPosition = Padding;
}
const std::string& instrument = _instruments[i];
//painter.setBrush(QBrush(instrumentColors[i]));
painter.setBrush(QBrush(instrumentColors[i]));
painter.setPen(QPen(instrumentColors[i]));
painter.drawRect(currentHorizontalPosition, currentVerticalPosition, BoxSize, BoxSize);
currentHorizontalPosition += BoxSize + Padding;
painter.setPen(QPen(Qt::black));
painter.drawText(currentHorizontalPosition, currentVerticalPosition + BoxSize / 2 + TextOffset, QString::fromStdString(instrument));
int textWidth = painter.boundingRect(QRect(), QString::fromStdString(instrument)).width();
currentHorizontalPosition += std::max(textWidth, 25) + Padding;
}
}
void TimelineWidget::setCurrentTime(std::string currentTime, double et) {
_currentTime.time = std::move(currentTime);
_currentTime.et = std::move(et);
repaint();
}
void TimelineWidget::drawImages(
QPainter& painter,
QRectF timelineRect,
std::vector<Image*> images,
double minimumTime, double maximumTime)
{
int width = timelineRect.width();
int nInstruments = 0;
std::set<std::string> instrumentSet;
for (Image* i : images) {
for (std::string instrument : i->instruments)
instrumentSet.insert(instrument);
}
std::map<std::string, int> instruments;
for (std::set<std::string>::const_iterator it = instrumentSet.begin(); it != instrumentSet.end(); ++it)
instruments[*it] = std::distance(instrumentSet.begin(), it);
for (Image* i : images) {
double tBeg = (i->beginning - minimumTime) / (maximumTime - minimumTime);
tBeg = std::max(tBeg, 0.0);
double tEnd = (i->ending - minimumTime) / (maximumTime - minimumTime);
tEnd = std::min(tEnd, 1.0);
int loc = timelineRect.top() + timelineRect.height() * tBeg;
int height = (timelineRect.top() + timelineRect.height() * tEnd) - loc;
height = std::max(height, 5);
std::string target = i->target;
auto it = std::find(_targets.begin(), _targets.end(), target);
int iTarget = std::distance(_targets.begin(), it);
//std::vector<QColor> colors;
for (std::string instrument : i->instruments) {
auto it = std::find(_instruments.begin(), _instruments.end(), instrument);
if (it == _instruments.end())
qDebug() << "Instrument not found";
int i = std::distance(_instruments.begin(), it);
painter.setBrush(QBrush(instrumentColors[i]));
double width = timelineRect.width() / instruments.size();
double pos = instruments[instrument] * width;
painter.drawRect(pos, loc, width, height);
}
painter.setBrush(QBrush(Qt::black));
painter.setPen(QPen(Qt::black));
QString line = QString::fromStdString(i->beginningString) + QString(" (") + QString::fromStdString(i->target) + QString(")");
painter.drawText(timelineRect.width(), loc + height / 2 + TextOffset, line);
}
}
void TimelineWidget::socketConnected() {
setDisabled(false);
}
void TimelineWidget::socketDisconnected() {
setDisabled(true);
_images.clear();
_instruments.clear();
_targets.clear();
}

View File

@@ -27,6 +27,12 @@
#include <QWidget>
#include "common.h"
#include <stdint.h>
#include <map>
#include <vector>
class QPaintEvent;
class TimelineWidget : public QWidget {
@@ -34,9 +40,29 @@ Q_OBJECT
public:
TimelineWidget(QWidget* parent);
void setData(std::vector<Image> images, std::map<uint8_t, std::string> targetMap, std::map<uint16_t, std::string> instrumentMap);
void setCurrentTime(std::string currentTime, double et);
void socketConnected();
void socketDisconnected();
protected:
void paintEvent(QPaintEvent* event);
void drawContent(QPainter& painter, QRectF rect);
void drawLegend(QPainter& painter, QRectF rect);
void drawImages(QPainter& painter, QRectF timelineRect, std::vector<Image*> images, double minimumTime, double maximumTime);
private:
std::vector<Image> _images;
std::map<uint8_t, std::string> _targetMap;
std::map<uint16_t, std::string> _instrumentMap;
std::vector<std::string> _targets;
std::vector<std::string> _instruments;
struct {
std::string time;
double et;
} _currentTime;
};
#endif // __TIMELINEWIDGET_H__

View File

@@ -69,6 +69,7 @@ public:
interaction::InteractionHandler* interactionHandler();
RenderEngine* renderEngine();
scripting::ScriptEngine* scriptEngine();
NetworkEngine* networkEngine();
LuaConsole* console();
gui::GUI* gui();

View File

@@ -25,17 +25,50 @@
#ifndef __NETWORKENGINE_H__
#define __NETWORKENGINE_H__
#include <cstdint>
#include <map>
#include <string>
#include <vector>
namespace openspace {
class NetworkEngine {
public:
NetworkEngine() = default;
typedef uint16_t MessageIdentifier;
NetworkEngine();
// Receiving messages
bool handleMessage(const std::string& message);
void sendStatusMessage();
// Sending messages
void publishStatusMessage();
void publishIdentifierMappingMessage();
void publishMessage(MessageIdentifier identifier, std::vector<char> message);
void sendMessages();
// Initial Connection Messages
void setInitialConnectionMessage(MessageIdentifier identifier, std::vector<char> message);
void sendInitialInformation();
// Background
MessageIdentifier identifier(std::string name);
private:
std::map<MessageIdentifier, std::string> _identifiers;
MessageIdentifier _lastAssignedIdentifier;
struct Message {
MessageIdentifier identifer;
std::vector<char> body;
};
std::vector<Message> _messagesToSend;
std::vector<Message> _initialConnectionMessages;
MessageIdentifier _statusMessageIdentifier;
MessageIdentifier _identifierMappingIdentifier;
};
} // namespace openspace

View File

@@ -25,7 +25,7 @@
#ifndef __HONGKANGPARSER_H__
#define __HONGKANGPARSER_H__
#include <openspace/util/ImageSequencer2.h>
#include <openspace/util/imagesequencer2.h>
#include <openspace/util/sequenceparser.h>
#include <map>
@@ -65,6 +65,7 @@ namespace openspace {
std::string spacecraft,
std::vector<std::string> payload,
std::vector<std::string> potentialTargets);
void sendPlaybookInformation();
std::string _defaultCaptureImage;
double _metRef = 299180517;

View File

@@ -122,11 +122,11 @@ public:
* 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,
bool getImagePaths(std::vector<Image>& captures,
std::string projectee,
std::string instrumentID);
bool ImageSequencer2::getImagePaths(std::vector<Image>& captures,
bool getImagePaths(std::vector<Image>& captures,
std::string projectee);
/*

View File

@@ -22,10 +22,9 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __LABELPARSER_H__
#define __LABELPARSER_H__
#include <openspace/util/ImageSequencer2.h>
#include <openspace/util/imagesequencer2.h>
#include <openspace/util/sequenceparser.h>
#include <map>

View File

@@ -23,6 +23,6 @@
****************************************************************************************/
#define OPENSPACE_VERSION_MAJOR 0
#define OPENSPACE_VERSION_MINOR 0
#define OPENSPACE_VERSION_REVISION 3
#define OPENSPACE_VERSION_STRING "prerelease-3"
#define OPENSPACE_VERSION_MINOR 1
#define OPENSPACE_VERSION_REVISION 0
#define OPENSPACE_VERSION_STRING "prerelease-4"

View File

@@ -701,7 +701,8 @@ void OpenSpaceEngine::encode() {
_syncBuffer->write();
}
_networkEngine->sendStatusMessage();
_networkEngine->publishStatusMessage();
_networkEngine->sendMessages();
}
void OpenSpaceEngine::decode() {
@@ -731,4 +732,8 @@ void OpenSpaceEngine::disableBarrier() {
sgct::SGCTWindow::setBarrier(false);
}
NetworkEngine* OpenSpaceEngine::networkEngine() {
return _networkEngine;
}
} // namespace openspace

View File

@@ -556,7 +556,12 @@ void InteractionHandler::setFocusNode(SceneGraphNode* node) {
glm::vec3 cameraView = glm::normalize(_camera->viewDirection());
//set new focus position
_camera->setFocusPosition(node->worldPosition());
if (viewDir != cameraView) {
float dot = glm::dot(viewDir, cameraView);
//static const float Epsilon = 0.001f;
if (dot < 1.f && dot > -1.f) {
//if (glm::length(viewDir - cameraView) < 0.001) {
//if (viewDir != cameraView) {
glm::vec3 rotAxis = glm::normalize(glm::cross(viewDir, cameraView));
float angle = glm::angle(viewDir, cameraView);
glm::quat q = glm::angleAxis(angle, rotAxis);

View File

@@ -79,7 +79,6 @@ int main(int argc, char** argv) {
sgct::MessageHandler::instance()->setLogToCallback(true);
sgct::MessageHandler::instance()->setLogCallback(mainLogCallback);
LDEBUG("Creating SGCT Engine");
_sgctEngine = new sgct::Engine(newArgc, newArgv);

View File

@@ -27,27 +27,49 @@
#include <openspace/util/time.h>
#include <openspace/engine/openspaceengine.h>
#include <array>
#include "sgct.h"
namespace {
const std::string _loggerCat = "NetworkEngine";
const uint8_t MessageTypeStatus = 0;
const std::string StatusMessageIdentifierName = "StatusMessage";
const std::string MappingIdentifierIdentifierName = "IdentifierMapping";
const char MessageTypeLuaScript = '0';
const char MessageTypeExternalControlConnected = '1';
}
namespace openspace {
NetworkEngine::NetworkEngine()
: _lastAssignedIdentifier(-1) // -1 is okay as we assign one identifier in this ctor
{
static_assert(
sizeof(MessageIdentifier) == 2,
"MessageIdentifier has to be 2 bytes or dependent applications will break"
);
_statusMessageIdentifier = identifier(StatusMessageIdentifierName);
_identifierMappingIdentifier = identifier(MappingIdentifierIdentifierName);
}
bool NetworkEngine::handleMessage(const std::string& message) {
// The first byte determines the type of message
const char type = message[0];
switch (type) {
case '0': // LuaScript
case MessageTypeLuaScript: // LuaScript
{
std::string script = message.substr(1);
//LINFO("Received Lua Script: '" << script << "'");
OsEng.scriptEngine()->queueScript(script);
return true;
}
case MessageTypeExternalControlConnected:
{
sendInitialInformation();
return true;
}
default:
LERROR("Unknown type '" << type << "'");
return false;
@@ -55,15 +77,14 @@ bool NetworkEngine::handleMessage(const std::string& message) {
}
void NetworkEngine::sendStatusMessage() {
void NetworkEngine::publishStatusMessage() {
if (!sgct::Engine::instance()->isExternalControlConnected())
return;
// Protocols:
// 1 byte: type of message
// Protocol:
// 8 bytes: time as a ET double
// 24 bytes: time as a UTC string
// 8 bytes: delta time as double
// Total: 41
// Total: 40
uint16_t messageSize = 0;
@@ -71,27 +92,108 @@ void NetworkEngine::sendStatusMessage() {
std::string timeString = Time::ref().currentTimeUTC();
double delta = Time::ref().deltaTime();
messageSize += sizeof(uint8_t);
messageSize += sizeof(time);
messageSize += timeString.length();
messageSize += sizeof(delta);
//LINFO(delta);
ghoul_assert(messageSize == 41, "Message size is not correct");
ghoul_assert(messageSize == 40, "Message size is not correct");
unsigned int currentLocation = 0;
std::vector<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);
publishMessage(_statusMessageIdentifier, std::move(buffer));
}
void NetworkEngine::publishIdentifierMappingMessage() {
size_t bufferSize = 0;
for (const std::pair<MessageIdentifier, std::string>& i : _identifiers) {
bufferSize += sizeof(MessageIdentifier);
bufferSize += i.second.size() + 1; // +1 for \0 terminating character
}
std::vector<char> buffer(bufferSize);
size_t currentWritingPosition = 0;
for (const std::pair<MessageIdentifier, std::string>& i : _identifiers) {
std::memcpy(buffer.data() + currentWritingPosition, &(i.first), sizeof(MessageIdentifier));
currentWritingPosition += sizeof(MessageIdentifier);
std::memcpy(buffer.data() + currentWritingPosition, i.second.data(), i.second.size());
currentWritingPosition += i.second.size();
buffer[currentWritingPosition] = '\0';
currentWritingPosition += 1;
}
publishMessage(_identifierMappingIdentifier, std::move(buffer));
}
NetworkEngine::MessageIdentifier NetworkEngine::identifier(std::string name) {
#ifdef DEBUG
// Check if name has been assigned already
for (const std::pair<MessageIdentifier, std::string>& p : _identifiers) {
if (p.second == name) {
LERROR("Name '" << name << "' for identifier has been registered before");
return -1;
}
}
#endif
_lastAssignedIdentifier++;
MessageIdentifier result = _lastAssignedIdentifier;
_identifiers[result] = std::move(name);
return result;
}
void NetworkEngine::publishMessage(MessageIdentifier identifier, std::vector<char> message) {
_messagesToSend.push_back({ std::move(identifier), std::move(message) });
}
void NetworkEngine::sendMessages() {
if (!sgct::Engine::instance()->isExternalControlConnected())
return;
for (Message& m : _messagesToSend) {
// Protocol:
// 2 bytes: type of message as uint16_t
// Rest of payload depending on the message type
union {
MessageIdentifier value;
std::array<char, 2> data;
} identifier;
identifier.value = m.identifer;
// Prepending the message identifier to the front
m.body.insert(m.body.begin(), identifier.data.begin(), identifier.data.end());
sgct::Engine::instance()->sendMessageToExternalControl(m.body.data(), m.body.size());
}
_messagesToSend.clear();
}
void NetworkEngine::sendInitialInformation() {
for (const Message& m : _initialConnectionMessages) {
union {
MessageIdentifier value;
std::array<char, 2> data;
} identifier;
identifier.value = m.identifer;
std::vector<char> payload = m.body;
payload.insert(payload.begin(), identifier.data.begin(), identifier.data.end());
sgct::Engine::instance()->sendMessageToExternalControl(payload.data(), payload.size());
}
}
void NetworkEngine::setInitialConnectionMessage(MessageIdentifier identifier, std::vector<char> message) {
// Add check if a MessageIdentifier already exists ---abock
_initialConnectionMessages.push_back({std::move(identifier), std::move(message)});
}
} // namespace openspace

View File

@@ -206,6 +206,11 @@ bool ModelGeometry::loadCachedFile(const std::string& filename) {
fileStream.read(reinterpret_cast<char*>(&vSize), sizeof(int64_t));
fileStream.read(reinterpret_cast<char*>(&iSize), sizeof(int64_t));
if (vSize == 0 || iSize == 0) {
LERROR("Error opening file '" << filename << "' for loading cache file");
return false;
}
_vertices.resize(vSize);
_indices.resize(iSize);

View File

@@ -306,7 +306,7 @@ void RenderableFieldlines::update(const UpdateData&) {
void RenderableFieldlines::loadSeedPoints() {
_seedPoints.clear();
switch (_seedPointSource) {
switch (_seedPointSource.value()) {
case SeedPointSourceFile:
loadSeedPointsFromFile();
break;

View File

@@ -190,7 +190,7 @@ namespace openspace {
double t = luaL_checknumber(L, -1);
OsEng.renderEngine()->startFading(1, t);
OsEng.renderEngine()->startFading(1, static_cast<float>(t));
return 0;
}
/**
@@ -205,7 +205,7 @@ namespace openspace {
double t = luaL_checknumber(L, -1);
OsEng.renderEngine()->startFading(-1, t);
OsEng.renderEngine()->startFading(-1, static_cast<float>(t));
return 0;
}
@@ -494,8 +494,9 @@ namespace openspace {
}
#if 1
#define PrintText(i, format, ...) Freetype::print(font, 10.f, static_cast<float>(startY - font_size_mono * i * 2), format, __VA_ARGS__);
#define PrintColorText(i, format, size, color, ...) Freetype::print(font, size, static_cast<float>(startY - font_size_mono * i * 2), color, format, __VA_ARGS__);
#define PrintText(__i__, __format__, ...) Freetype::print(font, 10.f, static_cast<float>(startY - font_size_mono * __i__ * 2), __format__, __VA_ARGS__);
#define PrintColorTextArg(__i__, __format__, __size__, __color__, ...) Freetype::print(font, __size__, static_cast<float>(startY - font_size_mono * __i__ * 2), __color__, __format__, __VA_ARGS__);
#define PrintColorText(__i__, __format__, __size__, __color__) Freetype::print(font, __size__, static_cast<float>(startY - font_size_mono * __i__ * 2), __color__, __format__);
if (_onScreenInformation._node != -1) {
int thisId = sgct_core::ClusterManager::instance()->getThisNodeId();
@@ -536,13 +537,13 @@ namespace openspace {
// GUI PRINT
// Using a macro to shorten line length and increase readability
int i = 0;
int line = 0;
PrintText(i++, "Date: %s", Time::ref().currentTimeUTC().c_str());
PrintText(line++, "Date: %s", Time::ref().currentTimeUTC().c_str());
PrintText(i++, "Avg. Frametime: %.5f", sgct::Engine::instance()->getAvgDt());
PrintText(i++, "Drawtime: %.5f", sgct::Engine::instance()->getDrawTime());
PrintText(i++, "Frametime: %.5f", sgct::Engine::instance()->getDt());
PrintText(line++, "Avg. Frametime: %.5f", sgct::Engine::instance()->getAvgDt());
PrintText(line++, "Drawtime: %.5f", sgct::Engine::instance()->getDrawTime());
PrintText(line++, "Frametime: %.5f", sgct::Engine::instance()->getDt());
/*
PrintText(i++, "Origin: (% .5f, % .5f, % .5f, % .5f)", origin[0], origin[1], origin[2], origin[3]);
PrintText(i++, "Cam pos: (% .5f, % .5f, % .5f, % .5f)", position[0], position[1], position[2], position[3]);
@@ -556,8 +557,11 @@ namespace openspace {
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(" ");
for (int i = 0; i < g; i++)
progress.append("-");
progress.append(">");
for (int i = 0; i < 31 - g; i++)
progress.append(" ");
std::string str = "";
openspace::SpiceManager::ref().getDateFromET(openspace::ImageSequencer2::ref().getNextCaptureTime(), str);
@@ -566,69 +570,72 @@ namespace openspace {
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);
PrintColorText(line++, "Next projection in:", 10, g1 + g2);
PrintColorTextArg(line++, "%.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());
PrintColorTextArg(line++, "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();
int timeleft = nextTarget.first - currentTime;
if (currentTarget.first > 0.0) {
int timeleft = nextTarget.first - currentTime;
int hour = timeleft / 3600;
int second = timeleft % 3600;
int minute = second / 60;
second = second % 60;
int hour = timeleft / 3600;
int second = timeleft % 3600;
int minute = second / 60;
second = second % 60;
std::string hh, mm, ss, coundtown;
std::string hh, mm, ss, coundtown;
if (hour < 10) hh.append("0");
if (minute < 10) mm.append("0");
if (second < 10) ss.append("0");
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));
hh.append(std::to_string(hour));
mm.append(std::to_string(minute));
ss.append(std::to_string(second));
glm::vec4 b2(1.00, 0.51, 0.00, 1);
PrintColorText(i++, "Switching observation focus in : [%s:%s:%s]", 10, b2, hh.c_str(), mm.c_str(), ss.c_str());
glm::vec4 b2(1.00, 0.51, 0.00, 1);
PrintColorTextArg(line++, "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::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);
PrintColorTextArg(line, "%s%s", 10, color, space.c_str(), incidentTargets.second[p].c_str());
for (int k = 0; k < 10; k++)
space += " ";
}
line++;
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());
}
}
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(line++, "Active Instruments : ", 10, active);
for (auto t : activeMap){
if (t.second == false){
PrintColorText(line, "| |", 10, glm::vec4(0.3, 0.3, 0.3, 1));
PrintColorTextArg(line++, " %5s", 10, glm::vec4(0.3, 0.3, 0.3, 1), t.first.c_str());
}
else{
PrintColorText(line, "|", 10, glm::vec4(0.3, 0.3, 0.3, 1));
if (t.first == "NH_LORRI"){
PrintColorText(line, " + ", 10, firing);
}
PrintColorText(line, " |", 10, glm::vec4(0.3, 0.3, 0.3, 1));
PrintColorTextArg(line++, " %5s", 10, active, t.first.c_str());
}
}
}
}
#undef PrintText
@@ -977,7 +984,7 @@ void RenderEngine::changeViewPoint(std::string origin) {
SceneGraphNode* jupiterBarycenterNode = scene()->sceneGraphNode("JupiterBarycenter");
SceneGraphNode* newHorizonsGhostNode = scene()->sceneGraphNode("NewHorizonsGhost");
//SceneGraphNode* newHorizonsGhostNode = scene()->sceneGraphNode("NewHorizonsGhost");
//SceneGraphNode* dawnNode = scene()->sceneGraphNode("Dawn");
//SceneGraphNode* vestaNode = scene()->sceneGraphNode("Vesta");
@@ -996,7 +1003,7 @@ void RenderEngine::changeViewPoint(std::string origin) {
solarSystemBarycenterNode->setParent(plutoBarycenterNode);
newHorizonsNode->setParent(plutoBarycenterNode);
newHorizonsGhostNode->setParent(plutoBarycenterNode);
//newHorizonsGhostNode->setParent(plutoBarycenterNode);
//dawnNode->setParent(plutoBarycenterNode);
//vestaNode->setParent(plutoBarycenterNode);
@@ -1056,16 +1063,16 @@ void RenderEngine::changeViewPoint(std::string origin) {
//vestaNode->setEphemeris(new SpiceEphemeris(vestaDictionary));
ghoul::Dictionary newHorizonsGhostDictionary =
{
{ std::string("Type"), std::string("Spice") },
{ std::string("Body"), std::string("NEW HORIZONS") },
{ std::string("EphmerisGhosting"), std::string("TRUE") },
{ std::string("Reference"), std::string("GALACTIC") },
{ std::string("Observer"), std::string("PLUTO BARYCENTER") },
{ std::string("Kernels"), ghoul::Dictionary() }
};
newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary));
//ghoul::Dictionary newHorizonsGhostDictionary =
//{
// { std::string("Type"), std::string("Spice") },
// { std::string("Body"), std::string("NEW HORIZONS") },
// { std::string("EphmerisGhosting"), std::string("TRUE") },
// { std::string("Reference"), std::string("GALACTIC") },
// { std::string("Observer"), std::string("PLUTO BARYCENTER") },
// { std::string("Kernels"), ghoul::Dictionary() }
//};
//newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary));
return;
}
@@ -1075,7 +1082,7 @@ void RenderEngine::changeViewPoint(std::string origin) {
plutoBarycenterNode->setParent(solarSystemBarycenterNode);
jupiterBarycenterNode->setParent(solarSystemBarycenterNode);
newHorizonsNode->setParent(solarSystemBarycenterNode);
newHorizonsGhostNode->setParent(solarSystemBarycenterNode);
//newHorizonsGhostNode->setParent(solarSystemBarycenterNode);
//newHorizonsTrailNode->setParent(solarSystemBarycenterNode);
//dawnNode->setParent(solarSystemBarycenterNode);
@@ -1135,16 +1142,16 @@ void RenderEngine::changeViewPoint(std::string origin) {
//vestaNode->setEphemeris(new SpiceEphemeris(vestaDictionary));
ghoul::Dictionary newHorizonsGhostDictionary =
{
{ std::string("Type"), std::string("Spice") },
{ std::string("Body"), std::string("NEW HORIZONS") },
{ std::string("EphmerisGhosting"), std::string("TRUE") },
{ std::string("Reference"), std::string("GALACTIC") },
{ std::string("Observer"), std::string("JUPITER BARYCENTER") },
{ std::string("Kernels"), ghoul::Dictionary() }
};
newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary));
//ghoul::Dictionary newHorizonsGhostDictionary =
//{
// { std::string("Type"), std::string("Spice") },
// { std::string("Body"), std::string("NEW HORIZONS") },
// { std::string("EphmerisGhosting"), std::string("TRUE") },
// { std::string("Reference"), std::string("GALACTIC") },
// { std::string("Observer"), std::string("JUPITER BARYCENTER") },
// { std::string("Kernels"), ghoul::Dictionary() }
//};
//newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary));
return;
}
@@ -1189,7 +1196,7 @@ void RenderEngine::changeViewPoint(std::string origin) {
solarSystemBarycenterNode->setEphemeris(new SpiceEphemeris(solarDictionary));
plutoBarycenterNode->setEphemeris(new SpiceEphemeris(plutoDictionary));
newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary));
newHorizonsGhostNode->setParent(jupiterBarycenterNode);
//newHorizonsGhostNode->setParent(jupiterBarycenterNode);
//newHorizonsTrailNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary));
@@ -1215,17 +1222,17 @@ void RenderEngine::changeViewPoint(std::string origin) {
ghoul::Dictionary newHorizonsGhostDictionary =
{
{ std::string("Type"), std::string("Spice") },
{ std::string("Body"), std::string("NEW HORIZONS") },
{ std::string("EphmerisGhosting"), std::string("TRUE") },
{ std::string("Reference"), std::string("GALACTIC") },
{ std::string("Observer"), std::string("JUPITER BARYCENTER") },
{ std::string("Kernels"), ghoul::Dictionary() }
};
newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary));
newHorizonsGhostNode->setParent(jupiterBarycenterNode);
//ghoul::Dictionary newHorizonsGhostDictionary =
//{
// { std::string("Type"), std::string("Spice") },
// { std::string("Body"), std::string("NEW HORIZONS") },
// { std::string("EphmerisGhosting"), std::string("TRUE") },
// { std::string("Reference"), std::string("GALACTIC") },
// { std::string("Observer"), std::string("JUPITER BARYCENTER") },
// { std::string("Kernels"), ghoul::Dictionary() }
//};
//newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary));
//newHorizonsGhostNode->setParent(jupiterBarycenterNode);
return;

View File

@@ -22,12 +22,14 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include <openspace/util/ImageSequencer2.h>
#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 <openspace/engine/openspaceengine.h>
#include <openspace/network/networkengine.h>
#include <fstream>
#include <iterator>
#include <iomanip>
@@ -39,6 +41,8 @@
namespace {
const std::string _loggerCat = "HongKangParser";
const std::string keyTranslation = "DataInputTranslation";
const std::string PlaybookIdentifierName = "Playbook";
}
namespace openspace {
@@ -248,6 +252,8 @@ void HongKangParser::create(){
}
}
}
sendPlaybookInformation();
std::ofstream myfile;
myfile.open("HongKangOutput.txt");
@@ -374,4 +380,123 @@ std::vector<double> HongKangParser::getCaptureProgression(){
return _captureProgression;
};
template <typename T>
void writeToBuffer(std::vector<char>& buffer, size_t& currentWriteLocation, T value) {
if ((currentWriteLocation + sizeof(T)) > buffer.size())
buffer.resize(2 * buffer.size());
std::memmove(buffer.data() + currentWriteLocation, reinterpret_cast<const void*>(&value), sizeof(T));
currentWriteLocation += sizeof(T);
}
template <>
void writeToBuffer<std::string>(std::vector<char>& buffer, size_t& currentWriteLocation, std::string value) {
if ((currentWriteLocation + sizeof(uint8_t) + value.size()) > buffer.size())
buffer.resize(2 * buffer.size());
uint8_t length = value.size();
std::memcpy(buffer.data() + currentWriteLocation, &length, sizeof(uint8_t));
currentWriteLocation += sizeof(uint8_t);
std::memmove(buffer.data() + currentWriteLocation, value.data(), length);
currentWriteLocation += length;
}
void HongKangParser::sendPlaybookInformation() {
static const NetworkEngine::MessageIdentifier PlaybookIdentifier = OsEng.networkEngine()->identifier(PlaybookIdentifierName);
std::vector<char> buffer(1024);
size_t currentWriteLocation = 0;
// Protocol:
// 4 bytes: Total number of bytes sent
// 1 byte : Number of Targets (i)
// i times: 1 byte (id), 1 byte (length j of name), j bytes (name)
// 1 byte : Number of Instruments (i)
// i times: 1 byte (id), 1 byte (length j of name), j bytes (name)
// 4 byte: Number (n) of images
// n times: 8 byte (beginning time), 8 byte (ending time), 1 byte (target id), 2 byte (instrument id)
std::map<std::string, uint8_t> targetMap;
uint8_t currentTargetId = 0;
for (auto target : _subsetMap) {
if (targetMap.find(target.first) == targetMap.end())
targetMap[target.first] = currentTargetId++;
}
std::map<std::string, uint16_t> instrumentMap;
uint16_t currentInstrumentId = 1;
for (auto target : _subsetMap) {
for (auto image : target.second._subset) {
for (auto instrument : image.activeInstruments) {
if (instrumentMap.find(instrument) == instrumentMap.end()) {
instrumentMap[instrument] = currentInstrumentId;
currentInstrumentId = currentInstrumentId << 1;
}
}
}
}
writeToBuffer(buffer, currentWriteLocation, uint8_t(targetMap.size()));
for (const std::pair<std::string, uint8_t>& p : targetMap) {
writeToBuffer(buffer, currentWriteLocation, p.second);
writeToBuffer(buffer, currentWriteLocation, p.first);
}
writeToBuffer(buffer, currentWriteLocation, uint8_t(instrumentMap.size()));
for (const std::pair<std::string, uint16_t>& p : instrumentMap) {
writeToBuffer(buffer, currentWriteLocation, p.second);
writeToBuffer(buffer, currentWriteLocation, p.first);
}
uint32_t allImages = 0;
for (auto target : _subsetMap)
allImages += target.second._subset.size();
writeToBuffer(buffer, currentWriteLocation, allImages);
for (auto target : _subsetMap){
for (auto image : target.second._subset){
writeToBuffer(buffer, currentWriteLocation, image.startTime);
writeToBuffer(buffer, currentWriteLocation, image.stopTime);
std::string timeBegin;
std::string timeEnd;
SpiceManager::ref().getDateFromET(image.startTime, timeBegin);
SpiceManager::ref().getDateFromET(image.stopTime, timeEnd);
writeToBuffer(buffer, currentWriteLocation, timeBegin);
writeToBuffer(buffer, currentWriteLocation, timeEnd);
uint8_t targetId = targetMap[target.first];
writeToBuffer(buffer, currentWriteLocation, targetId);
uint16_t totalInstrumentId = 0;
if (image.activeInstruments.empty()) {
LERROR("Image had no active instruments");
}
for (auto instrument : image.activeInstruments) {
uint16_t thisInstrumentId = instrumentMap[instrument];
totalInstrumentId |= thisInstrumentId;
}
writeToBuffer(buffer, currentWriteLocation, totalInstrumentId);
}
}
union {
uint32_t value;
std::array<char, sizeof(uint32_t)> data;
} sizeBuffer;
sizeBuffer.value = currentWriteLocation;
buffer.insert(buffer.begin(), sizeBuffer.data.begin(), sizeBuffer.data.end());
currentWriteLocation += sizeof(uint32_t);
buffer.resize(currentWriteLocation);
//OsEng.networkEngine()->publishMessage(PlaybookIdentifier, buffer);
OsEng.networkEngine()->setInitialConnectionMessage(PlaybookIdentifier, buffer);
}
}

View File

@@ -23,7 +23,7 @@
****************************************************************************************/
// open space includes
#include <openspace/util/ImageSequencer2.h>
#include <openspace/util/imagesequencer2.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/filesystem/directory.h>
@@ -98,9 +98,11 @@ std::pair<double, std::string> ImageSequencer2::getCurrentTarget(){
findEqualToThis.first = _currentTime;
auto it = std::lower_bound(_targetTimes.begin(), _targetTimes.end(), findEqualToThis, compareTime);
if (it != _targetTimes.end() && it != _targetTimes.begin() ){
if (it != _targetTimes.end() && it != _targetTimes.begin()){
return *std::prev(it);
}
else
return std::make_pair(0.0, "No Target");
}
std::pair<double, std::vector<std::string>> ImageSequencer2::getIncidentTargetList(int range){
@@ -235,22 +237,19 @@ bool ImageSequencer2::getImagePaths(std::vector<Image>& captures,
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());
if (curr != begin && curr != end && prev != begin && prev != end && prev < curr){
if (curr->startTime >= prev->startTime){
std::transform(prev, curr, std::back_inserter(captureTimes),
[](const Image& i) {
return i;
});
std::reverse(captureTimes.begin(), captureTimes.end());
captures = captureTimes;
if (!captures.empty())
_latestImage = &captures.back();
captures = captureTimes;
if (!captures.empty())
_latestImage = &captures.back();
return true;
}
return true;
}
}
}
return false;
@@ -283,11 +282,11 @@ void ImageSequencer2::runSequenceParser(SequenceParser* parser){
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" );
ghoul_assert(in1.size() > 0, "Sequencer failed to load Translation" );
ghoul_assert(in2.size() > 0, "Sequencer failed to load Image data" );
ghoul_assert(in3.size() > 0, "Sequencer failed to load Instrument Switching schedule");
ghoul_assert(in4.size() > 0, "Sequencer failed to load Target Switching schedule" );
ghoul_assert(in5.size() > 0, "Sequencer failed to load Capture progression" );
// append data

View File

@@ -22,7 +22,6 @@
* 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>

View File

@@ -48,9 +48,9 @@ void SpiceManager::initialize() {
_manager->_lastAssignedKernel = 0;
// Set the SPICE library to not exit the program if an error occurs
erract_c("SET", 0, static_cast<char*>("REPORT"));
erract_c("SET", 0, const_cast<char*>("REPORT"));
// But we do not want SPICE to print the errors, we will fetch them ourselves
errprt_c("SET", 0, static_cast<char*>("NONE"));
errprt_c("SET", 0, const_cast<char*>("NONE"));
}
void SpiceManager::deinitialize() {
@@ -61,8 +61,8 @@ void SpiceManager::deinitialize() {
_manager = nullptr;
// Set values back to default
erract_c("SET", 0, static_cast<char*>("DEFAULT"));
errprt_c("SET", 0, static_cast<char*>("DEFAULT"));
erract_c("SET", 0, const_cast<char*>("DEFAULT"));
errprt_c("SET", 0, const_cast<char*>("DEFAULT"));
}
SpiceManager& SpiceManager::ref() {