Merge branch 'master' into project/b612-asteroid-uncertainty

This commit is contained in:
Roxeena
2025-04-14 13:08:44 +02:00
516 changed files with 6227 additions and 2656 deletions
+6
View File
@@ -27,6 +27,12 @@ cmake_policy(VERSION 3.25)
project(OpenSpace)
# CMake 4.0 will no longer allow minimum required version below 3.5 and some of our
# dependencies have not been updated to reflect this. To make things work, we blanked
# require to 3.10 here to remove those issues. Once CMake configures and generates
# successfully without this next line, it can be removed
set(CMAKE_POLICY_VERSION_MINIMUM 3.10)
set(OPENSPACE_RELEASE_BUILD OFF)
set(OPENSPACE_VERSION_MAJOR)
set(OPENSPACE_VERSION_MINOR)
@@ -48,6 +48,7 @@ set(HEADER_FILES
include/profile/timedialog.h
include/profile/profileedit.h
include/profile/propertiesdialog.h
include/profile/uipanelsdialog.h
include/sgctedit/displaywindowunion.h
include/sgctedit/monitorbox.h
include/sgctedit/sgctedit.h
@@ -78,6 +79,7 @@ set(SOURCE_FILES
src/profile/timedialog.cpp
src/profile/profileedit.cpp
src/profile/propertiesdialog.cpp
src/profile/uipanelsdialog.cpp
src/sgctedit/sgctedit.cpp
src/sgctedit/displaywindowunion.cpp
src/sgctedit/monitorbox.cpp
@@ -62,18 +62,16 @@ public:
bool wasLaunchSelected() const;
/**
* Returns the selected profile name when launcher window closed.
* Returns the selected profile name when the launcher window closed.
*
* \return The name of selected profile (this is only the name without file extension
* and without path)
* \return The path to the selected profile
*/
std::string selectedProfile() const;
/**
* Returns the selected sgct window configuration when launcher window closed.
* Returns the selected SGCT window configuration when the launcher window closed.
*
* \return The name of selected profile (this is only the name without file extension
* and without path)
* \return The path to the selected profile
*/
std::string selectedWindowConfig() const;
@@ -86,16 +86,17 @@ signals:
void raiseExitWindow();
private slots:
void openMeta();
void openProperties();
void openModules();
void openKeybindings();
void openAssets();
void openTime();
void openAddedScripts();
void openKeybindings();
void openMeta();
void openMarkNodes();
void openDeltaTimes();
void openCamera();
void openMarkNodes();
void openTime();
void openModules();
void openUiPanels();
void openAddedScripts();
void approved();
private:
@@ -112,18 +113,19 @@ private:
std::string _profileFilename;
QLineEdit* _profileEdit = nullptr;
QLabel* _modulesLabel = nullptr;
QLabel* _assetsLabel = nullptr;
QTextEdit* _assetsEdit = nullptr;
QLabel* _propertiesLabel = nullptr;
QTextEdit* _propertiesEdit = nullptr;
QLabel* _assetsLabel = nullptr;
QTextEdit* _assetsEdit = nullptr;
QLabel* _keybindingsLabel = nullptr;
QTextEdit* _keybindingsEdit = nullptr;
QLabel* _deltaTimesLabel = nullptr;
QLabel* _metaLabel = nullptr;
QLabel* _interestingNodesLabel = nullptr;
QLabel* _deltaTimesLabel = nullptr;
QLabel* _cameraLabel = nullptr;
QLabel* _timeLabel = nullptr;
QLabel* _metaLabel = nullptr;
QLabel* _modulesLabel = nullptr;
QLabel* _uiPanelVisibilityLabel = nullptr;
QLabel* _additionalScriptsLabel = nullptr;
};
@@ -30,10 +30,10 @@
#include <openspace/scene/profile.h>
class QCheckBox;
class QComboBox;
class QDateTimeEdit;
class QLabel;
class QLineEdit;
class QTabWidget;
class TimeDialog final : public QDialog {
Q_OBJECT
@@ -48,18 +48,15 @@ public:
TimeDialog(QWidget* parent, std::optional<openspace::Profile::Time>* time);
private slots:
void enableAccordingToType(int);
void approved();
private:
void createWidgets();
void enableFormatForAbsolute(bool enableAbs);
std::optional<openspace::Profile::Time>* _time = nullptr;
openspace::Profile::Time _timeData;
bool _initializedAsAbsolute = true;
QComboBox* _typeCombo = nullptr;
QTabWidget* _tabWidget = nullptr;
QLabel* _absoluteLabel = nullptr;
QDateTimeEdit* _absoluteEdit = nullptr;
QLabel* _relativeLabel = nullptr;
@@ -0,0 +1,51 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2025 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_UI_LAUNCHER___UIPANELSDIALOG___H__
#define __OPENSPACE_UI_LAUNCHER___UIPANELSDIALOG___H__
#include <QDialog>
class QCheckBox;
class UiPanelsDialog final : public QDialog {
Q_OBJECT
public:
/**
* Constructor for UiPanelsDialog class.
*
* \param parent Pointer to parent Qt widget
* \param uiPanels The list of ui panels and their visibility
*/
UiPanelsDialog(QWidget* parent, std::map<std::string, bool>* uiPanels);
private slots:
void parseSelections();
private:
std::map<std::string, bool>* _uiPanels;
std::map<QCheckBox*, std::string> _checkboxToId;
};
#endif // __OPENSPACE_UI_LAUNCHER___UIPANELSDIALOG___H__
@@ -127,9 +127,10 @@ public:
*
* \param quality The value for number of vertical lines of resolution. This will be
* compared against the QualityValues array in order to set the correct
* combobox index
* combobox index
* \tilt The tilt of the fisheye in degrees
*/
void setProjectionFisheye(int quality);
void setProjectionFisheye(int quality, float tilt);
/**
* Sets the window's projection type to spherical mirror, with the accompanying
@@ -162,6 +163,21 @@ public:
*/
void setProjectionEquirectangular(int quality);
/**
* Sets the window's projection type to blitting the contents of another window.
*
* \param windowBlitId The id of the window from which to blit
*/
void setProjectionBlit(int windowBlitId);
/**
* This function must be called by users of this class whenever the total number of
* windows has changed.
*
* \param newWindowCount the number of windows after the change
*/
void updateWindowCount(int newWindowCount);
signals:
void windowChanged(int monitorIndex, int windowIndex, const QRectF& newDimensions);
@@ -171,6 +187,7 @@ private:
QWidget* createSphericalMirrorWidget();
QWidget* createCylindricalWidget();
QWidget* createEquirectangularWidget();
QWidget* createBlitWidget();
void onSizeXChanged(int newValue);
void onSizeYChanged(int newValue);
@@ -209,44 +226,39 @@ private:
struct {
QWidget* widget = nullptr;
QLabel* labelInfo = nullptr;
QDoubleSpinBox* fovH = nullptr;
QDoubleSpinBox* fovV = nullptr;
QLabel* labelFovH = nullptr;
QLabel* labelFovV = nullptr;
QPushButton* buttonLockFov = nullptr;
} _planar;
struct {
QWidget* widget = nullptr;
QLabel* labelInfo = nullptr;
QComboBox* quality = nullptr;
QLabel* labelQuality = nullptr;
QDoubleSpinBox* tilt = nullptr;
} _fisheye;
struct {
QWidget* widget = nullptr;
QLabel* labelInfo = nullptr;
QComboBox* quality = nullptr;
QLabel* labelQuality = nullptr;
} _sphericalMirror;
struct {
QWidget* widget = nullptr;
QLabel* labelInfo = nullptr;
QComboBox* quality = nullptr;
QLabel* labelQuality = nullptr;
QDoubleSpinBox* heightOffset = nullptr;
QLabel* labelHeightOffset = nullptr;
} _cylindrical;
struct {
QWidget* widget = nullptr;
QLabel* labelInfo = nullptr;
QComboBox* quality = nullptr;
QLabel* labelQuality = nullptr;
} _equirectangular;
struct {
QWidget* widget = nullptr;
QComboBox* windowId = nullptr;
QLabel* unavailable = nullptr;
} _blit;
const QIcon _lockIcon;
const QIcon _unlockIcon;
};
@@ -35,6 +35,7 @@
#include "profile/modulesdialog.h"
#include "profile/propertiesdialog.h"
#include "profile/timedialog.h"
#include "profile/uipanelsdialog.h"
#include <openspace/scene/profile.h>
#include <ghoul/format.h>
#include <QDialogButtonBox>
@@ -305,6 +306,21 @@ void ProfileEdit::createWidgets() {
rightLayout->addLayout(container);
}
rightLayout->addWidget(new Line);
{
QBoxLayout* container = new QVBoxLayout;
_uiPanelVisibilityLabel = new QLabel("User Interface Panels");
_uiPanelVisibilityLabel->setObjectName("heading");
_uiPanelVisibilityLabel->setWordWrap(true);
container->addWidget(_uiPanelVisibilityLabel);
QPushButton* uiPanelEdit = new QPushButton("Edit");
connect(uiPanelEdit, &QPushButton::clicked, this, &ProfileEdit::openUiPanels);
uiPanelEdit->setLayoutDirection(Qt::RightToLeft);
uiPanelEdit->setAccessibleName("Edit user interface panels");
container->addWidget(uiPanelEdit);
rightLayout->addLayout(container);
}
rightLayout->addWidget(new Line);
{
QBoxLayout* container = new QVBoxLayout;
_additionalScriptsLabel = new QLabel("Additional Scripts");
@@ -375,6 +391,10 @@ void ProfileEdit::openModules() {
_modulesLabel->setText(labelText(_profile.modules.size(), "Modules"));
}
void ProfileEdit::openUiPanels() {
UiPanelsDialog(this, &_profile.uiPanelVisibility).exec();
}
void ProfileEdit::openProperties() {
PropertiesDialog(this, &_profile.properties).exec();
_propertiesLabel->setText(labelText(_profile.properties.size(), "Properties"));
@@ -32,6 +32,7 @@
#include <QKeyEvent>
#include <QLabel>
#include <QLineEdit>
#include <QTabWidget>
#include <QVBoxLayout>
#include <format>
#include <algorithm>
@@ -45,8 +46,6 @@ TimeDialog::TimeDialog(QWidget* parent, std::optional<openspace::Profile::Time>*
setWindowTitle("Time");
createWidgets();
const QStringList types = { "Absolute", "Relative" };
_typeCombo->addItems(types);
if (_time->has_value()) {
_timeData = **_time;
if (_timeData.type == Profile::Time::Type::Relative) {
@@ -66,44 +65,75 @@ TimeDialog::TimeDialog(QWidget* parent, std::optional<openspace::Profile::Time>*
}
_startPaused->setChecked(_timeData.startPaused);
_initializedAsAbsolute = (_timeData.type == Profile::Time::Type::Absolute);
enableAccordingToType(static_cast<int>(_timeData.type));
if (_timeData.type == Profile::Time::Type::Relative) {
_relativeEdit->setText(QString::fromStdString(_timeData.value));
_relativeEdit->setFocus(Qt::OtherFocusReason);
}
else {
const size_t tIdx = _timeData.value.find_first_of('T', 0);
const QString importDate = QString::fromStdString(
_timeData.value.substr(0, tIdx)
);
const QString importTime = QString::fromStdString(
_timeData.value.substr(tIdx + 1)
);
_absoluteEdit->setDate(QDate::fromString(importDate, Qt::DateFormat::ISODate));
_absoluteEdit->setTime(QTime::fromString(importTime));
_relativeEdit->clear();
_absoluteEdit->setFocus(Qt::OtherFocusReason);
}
_tabWidget->setCurrentIndex(static_cast<int>(_timeData.type));
}
void TimeDialog::createWidgets() {
QBoxLayout* layout = new QVBoxLayout(this);
_tabWidget = new QTabWidget;
{
layout->addWidget(new QLabel("Time Type"));
_typeCombo = new QComboBox;
_typeCombo->setAccessibleName("Time type");
_typeCombo->setToolTip("Types: Absolute defined time or Relative to actual time");
connect(
_typeCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &TimeDialog::enableAccordingToType
);
layout->addWidget(_typeCombo);
}
{
QWidget* container = new QWidget;
QBoxLayout* l = new QVBoxLayout(container);
_absoluteLabel = new QLabel("Absolute UTC:");
layout->addWidget(_absoluteLabel);
l->addWidget(_absoluteLabel);
_absoluteEdit = new QDateTimeEdit;
_absoluteEdit->setDisplayFormat("yyyy-MM-dd T hh:mm:ss");
_absoluteEdit->setDateTime(QDateTime::currentDateTime());
_absoluteEdit->setAccessibleName("Set absolute time");
layout->addWidget(_absoluteEdit);
l->addWidget(_absoluteEdit);
l->addStretch();
_tabWidget->addTab(container, "Absolute");
}
{
QWidget* container = new QWidget;
QBoxLayout* l = new QVBoxLayout(container);
_relativeLabel = new QLabel("Relative Time:");
layout->addWidget(_relativeLabel);
l->addWidget(_relativeLabel);
_relativeEdit = new QLineEdit;
_relativeEdit->setAccessibleName("Set relative time");
_relativeEdit->setToolTip(
"String for relative time to actual (e.g. \"-1d\" for back 1 day)"
);
layout->addWidget(_relativeEdit);
l->addWidget(_relativeEdit);
QLabel* desc = new QLabel(
"This field modifies the default start time. It has to be of the form "
"[-]XX(s,m,h,d,M,y). For example '-1d' will cause the profile to start at "
"yesterday's date."
);
desc->setObjectName("information");
desc->setWordWrap(true);
l->addWidget(desc);
_tabWidget->addTab(container, "Relative");
}
layout->addWidget(_tabWidget);
{
_startPaused = new QCheckBox("Start with time paused");
_startPaused->setChecked(false);
@@ -123,47 +153,9 @@ void TimeDialog::createWidgets() {
}
}
void TimeDialog::enableAccordingToType(int idx) {
const Profile::Time::Type comboIdx = static_cast<Profile::Time::Type>(idx);
const bool setFormatForAbsolute = (comboIdx == Profile::Time::Type::Absolute);
enableFormatForAbsolute(setFormatForAbsolute);
_typeCombo->setCurrentIndex(idx);
if (comboIdx == Profile::Time::Type::Relative) {
_relativeEdit->setText("<font color='black'>Relative Time:</font>");
if (_initializedAsAbsolute) {
_relativeEdit->setText("0d");
}
else {
_relativeEdit->setText(QString::fromStdString(_timeData.value));
}
_relativeEdit->setFocus(Qt::OtherFocusReason);
}
else {
_relativeEdit->setText("<font color='gray'>Relative Time:</font>");
const size_t tIdx = _timeData.value.find_first_of('T', 0);
const QString importDate = QString::fromStdString(
_timeData.value.substr(0, tIdx)
);
const QString importTime = QString::fromStdString(
_timeData.value.substr(tIdx + 1)
);
_absoluteEdit->setDate(QDate::fromString(importDate, Qt::DateFormat::ISODate));
_absoluteEdit->setTime(QTime::fromString(importTime));
_relativeEdit->clear();
_absoluteEdit->setFocus(Qt::OtherFocusReason);
}
}
void TimeDialog::enableFormatForAbsolute(bool enableAbs) {
_absoluteLabel->setEnabled(enableAbs);
_absoluteEdit->setEnabled(enableAbs);
_relativeLabel->setEnabled(!enableAbs);
_relativeEdit->setEnabled(!enableAbs);
}
void TimeDialog::approved() {
constexpr int Relative = static_cast<int>(Profile::Time::Type::Relative);
if (_typeCombo->currentIndex() == Relative) {
if (_tabWidget->currentIndex() == Relative) {
if (_relativeEdit->text().isEmpty()) {
*_time = std::nullopt;
}
@@ -0,0 +1,130 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2025 *
* *
* 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 "profile/uipanelsdialog.h"
#include "profile/line.h"
#include <openspace/json.h>
#include <ghoul/filesystem/filesystem.h>
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QLabel>
#include <QVBoxLayout>
#include <fstream>
#include <string_view>
namespace {
constexpr std::string_view DefaultPanelPath = "${DATA}/web/default_ui_panels.json";
struct Panel {
std::string id;
std::string name;
bool isVisible;
};
void from_json(const nlohmann::json& j, Panel& layout) {
j["id"].get_to(layout.id);
j["name"].get_to(layout.name);
j["visible"].get_to(layout.isVisible);
}
std::vector<Panel> loadPanels() {
std::ifstream panelFile = std::ifstream(absPath(DefaultPanelPath));
const std::string panelContent = std::string(
std::istreambuf_iterator<char>(panelFile),
std::istreambuf_iterator<char>()
);
const nlohmann::json panel = nlohmann::json::parse(panelContent);
std::map<std::string, Panel> panels = panel.get<std::map<std::string, Panel>>();
std::vector<Panel> result;
for (const auto& [key, value] : panels) {
result.push_back(value);
}
std::sort(
result.begin(),
result.end(),
[](const Panel& lhs, const Panel& rhs) { return lhs.name < rhs.name; }
);
return result;
}
} // namespace
UiPanelsDialog::UiPanelsDialog(QWidget* parent, std::map<std::string, bool>* uiPanels)
: QDialog(parent)
, _uiPanels(uiPanels)
{
setWindowTitle("User Interface Panels");
std::vector<Panel> panels = loadPanels();
QBoxLayout* layout = new QVBoxLayout(this);
QLabel* info = new QLabel(
"Select the user interface panels that should be visible by default in the "
"current profile."
);
info->setWordWrap(true);
layout->addWidget(info);
for (const Panel& panel : panels) {
QCheckBox* box = new QCheckBox(QString::fromStdString(panel.name));
// If the profile already has a desired value for the checkbox, use it. Otherwise
// use the default values
auto it = _uiPanels->find(panel.id);
if (it != _uiPanels->end()) {
box->setChecked(it->second);
}
else {
box->setChecked(panel.isVisible);
}
layout->addWidget(box);
_checkboxToId[box] = panel.id;
}
layout->addWidget(new Line);
{
QDialogButtonBox* buttons = new QDialogButtonBox;
buttons->setStandardButtons(QDialogButtonBox::Save | QDialogButtonBox::Cancel);
connect(
buttons, &QDialogButtonBox::accepted,
this, &UiPanelsDialog::parseSelections
);
connect(buttons, &QDialogButtonBox::rejected, this, &UiPanelsDialog::reject);
layout->addWidget(buttons);
}
}
void UiPanelsDialog::parseSelections() {
_uiPanels->clear();
for (const auto& [key, value] : _checkboxToId) {
_uiPanels->emplace(value, key->isChecked());
}
accept();
}
@@ -194,7 +194,7 @@ void DisplayWindowUnion::initialize(const std::vector<QRect>& monitorSizeList,
},
[&](const sgct::config::FisheyeProjection& p) {
if (p.quality.has_value()) {
wCtrl->setProjectionFisheye(*p.quality);
wCtrl->setProjectionFisheye(*p.quality, p.tilt.value_or(0.f));
}
},
[&](const sgct::config::PlanarProjection& p) {
@@ -208,7 +208,12 @@ void DisplayWindowUnion::initialize(const std::vector<QRect>& monitorSizeList,
wCtrl->setProjectionSphericalMirror(*p.quality);
}
},
[&](const sgct::config::NoProjection&) {},
[&](const sgct::config::NoProjection&) {
// We can only generate blitting when there is no projection selected.
if (w.blitWindowId.has_value()) {
wCtrl->setProjectionBlit(*w.blitWindowId);
}
},
[&](const sgct::config::ProjectionPlane&) {},
[&](const sgct::config::CubemapProjection&) {},
},
@@ -251,6 +256,7 @@ void DisplayWindowUnion::updateWindows() {
_addWindowButton->setEnabled(_nWindowsDisplayed != _windowControls.size());
for (WindowControl* w : _windowControls) {
w->showWindowLabel(_nWindowsDisplayed > 1);
w->updateWindowCount(_nWindowsDisplayed);
}
emit nWindowsChanged(_nWindowsDisplayed);
@@ -64,7 +64,8 @@ namespace {
Fisheye,
SphericalMirror,
Cylindrical,
Equirectangular
Equirectangular,
Blit
};
constexpr int LineEditWidthFixedWindowSize = 95;
@@ -378,7 +379,7 @@ WindowControl::WindowControl(int monitorIndex, int windowIndex,
_projectionType = new QComboBox;
_projectionType->addItems({
"Planar Projection", "Fisheye", "Spherical Mirror Projection",
"Cylindrical Projection", "Equirectangular Projection"
"Cylindrical Projection", "Equirectangular Projection", "Copy Window Contents"
});
_projectionType->setToolTip("Select from the supported window projection types");
_projectionType->setCurrentIndex(0);
@@ -403,6 +404,9 @@ WindowControl::WindowControl(int monitorIndex, int windowIndex,
_equirectangular.widget = createEquirectangularWidget();
projectionLayout->addWidget(_equirectangular.widget);
_blit.widget = createBlitWidget();
projectionLayout->addWidget(_blit.widget);
// We need to trigger this once to ensure that all of the defaults are correct
onProjectionChanged(0);
@@ -424,21 +428,21 @@ QWidget* WindowControl::createPlanarWidget() {
QGridLayout* layout = new QGridLayout(widget);
layout->setColumnStretch(1, 1);
_planar.labelInfo = new QLabel(
QLabel* labelInfo = new QLabel(
"This projection type is the 'regular' projection with a horizontal and a "
"vertical field of view, given in degrees. The wider the field of view, the "
"more content is shown at the same time, but everything becomes smaller. Very "
"large values will introduce distortions on the corners."
);
_planar.labelInfo->setObjectName("info");
_planar.labelInfo->setWordWrap(true);
layout->addWidget(_planar.labelInfo, 0, 0, 1, 3);
labelInfo->setObjectName("info");
labelInfo->setWordWrap(true);
layout->addWidget(labelInfo, 0, 0, 1, 3);
_planar.labelFovH = new QLabel("Horizontal FOV");
QLabel* labelFovH = new QLabel("Horizontal FOV");
const QString hfovTip =
"The total horizontal field of view of the viewport (degrees)";
_planar.labelFovH->setToolTip(hfovTip);
layout->addWidget(_planar.labelFovH, 1, 0);
labelFovH->setToolTip(hfovTip);
layout->addWidget(labelFovH, 1, 0);
_planar.fovH = new QDoubleSpinBox;
_planar.fovH->setMinimum(FovEpsilon);
@@ -452,11 +456,11 @@ QWidget* WindowControl::createPlanarWidget() {
);
layout->addWidget(_planar.fovH, 1, 1);
_planar.labelFovV = new QLabel("Vertical FOV");
QLabel* labelFovV = new QLabel("Vertical FOV");
const QString vfovTip = "The total vertical field of view of the viewport (degrees). "
"Internally,\nthe values for 'up' & 'down' will each be half this value";
_planar.labelFovV->setToolTip(vfovTip);
layout->addWidget(_planar.labelFovV, 2, 0);
labelFovV->setToolTip(vfovTip);
layout->addWidget(labelFovV, 2, 0);
_planar.fovV = new QDoubleSpinBox;
_planar.fovV->setMinimum(FovEpsilon);
@@ -493,29 +497,29 @@ QWidget* WindowControl::createFisheyeWidget() {
// *------------*-----------*
// | { Informational text } | Row 0
// | Quality * [DDDDD>] | Row 1
// | [] Spout Output | Row 2
// | Tilt * [oooooo] | Row 2
// *------------*-----------*
QWidget* widget = new QWidget;
QGridLayout* layout = new QGridLayout(widget);
layout->setColumnStretch(1, 1);
_fisheye.labelInfo = new QLabel(
QLabel* labelInfo = new QLabel(
"This projection provides a rendering in a format that is suitable for "
"planetariums and other immersive environments. A field-of-view of 180 degrees "
"is presented as a circular image in the center of the screen. For this "
"projection a square window is suggested, but not necessary."
);
_fisheye.labelInfo->setObjectName("info");
_fisheye.labelInfo->setWordWrap(true);
layout->addWidget(_fisheye.labelInfo, 0, 0, 1, 2);
labelInfo->setObjectName("info");
labelInfo->setWordWrap(true);
layout->addWidget(labelInfo, 0, 0, 1, 2);
_fisheye.labelQuality = new QLabel("Quality");
QLabel* labelQuality = new QLabel("Quality");
const QString qualityTip = "Determines the pixel resolution of the projection "
"rendering. The higher resolution,\nthe better the rendering quality, but at the "
"expense of increased rendering times";
_fisheye.labelQuality->setToolTip(qualityTip);
layout->addWidget(_fisheye.labelQuality, 1, 0);
"expense of increased rendering times.";
labelQuality->setToolTip(qualityTip);
layout->addWidget(labelQuality, 1, 0);
_fisheye.quality = new QComboBox;
_fisheye.quality->addItems(qualityList());
@@ -523,6 +527,19 @@ QWidget* WindowControl::createFisheyeWidget() {
_fisheye.quality->setCurrentIndex(2);
layout->addWidget(_fisheye.quality, 1, 1);
QLabel* labelTilt = new QLabel("Tilt");
const QString tiltTip = "Determines the tilt (in degrees) of the fisheye rendering. "
"Changing this value will cause the entire rendering to be tilted by the set "
"number of degrees.";
labelTilt->setToolTip(tiltTip);
layout->addWidget(labelTilt, 2, 0);
_fisheye.tilt = new QDoubleSpinBox;
_fisheye.tilt->setToolTip(tiltTip);
_fisheye.tilt->setMinimum(-180.0);
_fisheye.tilt->setMaximum(180.0);
layout->addWidget(_fisheye.tilt, 2, 1);
return widget;
}
@@ -536,22 +553,22 @@ QWidget* WindowControl::createSphericalMirrorWidget() {
QGridLayout* layout = new QGridLayout(widget);
layout->setColumnStretch(1, 1);
_sphericalMirror.labelInfo = new QLabel(
QLabel* labelInfo = new QLabel(
"This projection is rendering a image suite for use with a spherical mirror "
"projection as described by Paul Bourke (http://paulbourke.net/dome/mirrordome/) "
"and which is a low-cost yet effective way to provide content for a sphericalal "
"display surface using a regular projector."
);
_sphericalMirror.labelInfo->setObjectName("info");
_sphericalMirror.labelInfo->setWordWrap(true);
layout->addWidget(_sphericalMirror.labelInfo, 0, 0, 1, 2);
labelInfo->setObjectName("info");
labelInfo->setWordWrap(true);
layout->addWidget(labelInfo, 0, 0, 1, 2);
_sphericalMirror.labelQuality = new QLabel("Quality");
QLabel* labelQuality = new QLabel("Quality");
const QString qualityTip = "Determines the pixel resolution of the projection "
"rendering. The higher resolution,\nthe better the rendering quality, but at the "
"expense of increased rendering times";
_sphericalMirror.labelQuality->setToolTip(qualityTip);
layout->addWidget(_sphericalMirror.labelQuality, 1, 0);
labelQuality->setToolTip(qualityTip);
layout->addWidget(labelQuality, 1, 0);
_sphericalMirror.quality = new QComboBox;
_sphericalMirror.quality->addItems(qualityList());
@@ -573,22 +590,22 @@ QWidget* WindowControl::createCylindricalWidget() {
QGridLayout* layout = new QGridLayout(widget);
layout->setColumnStretch(1, 1);
_cylindrical.labelInfo = new QLabel(
QLabel* labelInfo = new QLabel(
"This projection type provides a cylindrical rendering that covers 360 degrees "
"around the camera, which can be useful in immersive environments that are not "
"spherical, but where, for example, all walls of a room are covered with "
"projectors."
);
_cylindrical.labelInfo->setObjectName("info");
_cylindrical.labelInfo->setWordWrap(true);
layout->addWidget(_cylindrical.labelInfo, 0, 0, 1, 2);
labelInfo->setObjectName("info");
labelInfo->setWordWrap(true);
layout->addWidget(labelInfo, 0, 0, 1, 2);
_cylindrical.labelQuality = new QLabel("Quality");
QLabel* labelQuality = new QLabel("Quality");
const QString qualityTip = "Determines the pixel resolution of the projection "
"rendering. The higher resolution,\nthe better the rendering quality, but at the "
"expense of increased rendering times";
_cylindrical.labelQuality->setToolTip(qualityTip);
layout->addWidget(_cylindrical.labelQuality, 1, 0);
labelQuality->setToolTip(qualityTip);
layout->addWidget(labelQuality, 1, 0);
_cylindrical.quality = new QComboBox;
_cylindrical.quality->addItems(qualityList());
@@ -596,13 +613,13 @@ QWidget* WindowControl::createCylindricalWidget() {
_cylindrical.quality->setCurrentIndex(2);
layout->addWidget(_cylindrical.quality, 1, 1);
_cylindrical.labelHeightOffset = new QLabel("Height Offset");
QLabel* labelHeightOffset = new QLabel("Height Offset");
const QString heightTip = "Offsets the height from which the cylindrical projection "
"is generated.\nThis is, in general, only necessary if the user position is "
"offset and\ncountering that offset is desired in order to continue producing\n"
"a 'standard' cylindrical projection";
_cylindrical.labelHeightOffset->setToolTip(heightTip);
layout->addWidget(_cylindrical.labelHeightOffset, 2, 0);
labelHeightOffset->setToolTip(heightTip);
layout->addWidget(labelHeightOffset, 2, 0);
_cylindrical.heightOffset = new QDoubleSpinBox;
_cylindrical.heightOffset->setMinimum(-1000000.0);
@@ -611,7 +628,6 @@ QWidget* WindowControl::createCylindricalWidget() {
_cylindrical.heightOffset->setToolTip(heightTip);
layout->addWidget(_cylindrical.heightOffset, 2, 1);
return widget;
}
@@ -620,28 +636,27 @@ QWidget* WindowControl::createEquirectangularWidget() {
// *------------*-----------*
// | { Informational text } | Row 0
// | Quality * [DDDDD>] | Row 1
// | [] Spout Output | Row 2
// *------------*-----------*
QWidget* widget = new QWidget;
QGridLayout* layout = new QGridLayout(widget);
layout->setColumnStretch(1, 1);
_equirectangular.labelInfo = new QLabel(
QLabel* labelInfo = new QLabel(
"This projection provides the rendering as an image in equirectangular "
"projection, which is a common display type for 360 surround video. When "
"uploading a video in equirectangular projection to YouTube, for example, it "
"will use it as a 360 video."
);
_equirectangular.labelInfo->setObjectName("info");
_equirectangular.labelInfo->setWordWrap(true);
layout->addWidget(_equirectangular.labelInfo, 0, 0, 1, 2);
labelInfo->setObjectName("info");
labelInfo->setWordWrap(true);
layout->addWidget(labelInfo, 0, 0, 1, 2);
_equirectangular.labelQuality = new QLabel("Quality");
QLabel* labelQuality = new QLabel("Quality");
const QString qualityTip = "Determines the pixel resolution of the projection "
"rendering. The higher resolution,\nthe better the rendering quality, but at the "
"expense of increased rendering times";
_equirectangular.labelQuality->setToolTip(qualityTip);
layout->addWidget(_equirectangular.labelQuality, 1, 0);
labelQuality->setToolTip(qualityTip);
layout->addWidget(labelQuality, 1, 0);
_equirectangular.quality = new QComboBox;
_equirectangular.quality->addItems(qualityList());
@@ -652,6 +667,49 @@ QWidget* WindowControl::createEquirectangularWidget() {
return widget;
}
QWidget* WindowControl::createBlitWidget() {
// Column 0 Column 1
// *------------*-----------*
// | { Informational text } | Row 0
// | Window ID * [DDDDD>] | Row 1
// | { Unavailability } | Row 2
// *------------*-----------*
QWidget* widget = new QWidget;
QGridLayout* layout = new QGridLayout(widget);
layout->setColumnStretch(1, 1);
QLabel* labelInfo = new QLabel(
"This projection type will reuse the contents of another window. This can be "
"useful for GUI windows that should show the 3D scene, but not incur the cost of "
"rendering the scene twice. Note that the contents of the rendering will be "
"copied in their entirety, which means that if the rendering windows have "
"different aspect ratios, the image in the receiving window will be stretched."
);
labelInfo->setObjectName("info");
labelInfo->setWordWrap(true);
layout->addWidget(labelInfo, 0, 0, 1, 2);
QLabel* labelBlitId = new QLabel("Window ID");
const QString blitTip = "Determines the window from which to copy the contents.";
labelBlitId->setToolTip(blitTip);
layout->addWidget(labelBlitId, 1, 0);
_blit.windowId = new QComboBox;
_blit.windowId->setToolTip(blitTip);
layout->addWidget(_blit.windowId, 1, 1);
_blit.unavailable = new QLabel(
"It is only possible to copy the contents of another window if at least two "
"windows have been created. Add a second window before selecting this projection "
"type."
);
_blit.unavailable->setWordWrap(true);
layout->addWidget(_blit.unavailable, 2, 0, 1, 2);
return widget;
}
void WindowControl::resetToDefaults() {
//
// Determine ideal window sizes
@@ -684,9 +742,11 @@ void WindowControl::resetToDefaults() {
_planar.fovV->setValue(DefaultFovShortEdge);
_cylindrical.heightOffset->setValue(DefaultHeightOffset);
_fisheye.quality->setCurrentIndex(2);
_fisheye.tilt->setValue(0.0);
_sphericalMirror.quality->setCurrentIndex(2);
_cylindrical.quality->setCurrentIndex(2);
_equirectangular.quality->setCurrentIndex(2);
_blit.windowId->setCurrentIndex(0);
emit windowChanged(_monitorIndexDefault, _windowIndex, _windowDimensions);
}
@@ -736,6 +796,7 @@ void WindowControl::generateWindowInformation(sgct::config::Window& window) cons
);
window.draw2D = _render2D->isChecked();
window.draw3D = _render3D->isChecked();
window.isDecorated = _windowDecoration->isChecked();
if (_spoutOutput->isChecked()) {
window.spout = sgct::config::Window::Spout{
@@ -746,6 +807,8 @@ void WindowControl::generateWindowInformation(sgct::config::Window& window) cons
window.name = _windowName->text().toStdString();
}
window.viewports.clear();
// The rest of this function is just specifying the rendering, which we can skip if we
// don't want to render 3D anyway
if (!window.draw3D) {
@@ -762,7 +825,7 @@ void WindowControl::generateWindowInformation(sgct::config::Window& window) cons
vp.projection = sgct::config::FisheyeProjection {
.fov = 180.f,
.quality = Quality[_fisheye.quality->currentIndex()].first,
.tilt = 0.f
.tilt = static_cast<float>(_fisheye.tilt->value())
};
break;
case ProjectionIndices::SphericalMirror:
@@ -781,6 +844,16 @@ void WindowControl::generateWindowInformation(sgct::config::Window& window) cons
.quality = Quality[_equirectangular.quality->currentIndex()].first
};
break;
case ProjectionIndices::Blit:
// We have to subtract here as SGCT uses 0-indexing, but we present it to the
// user as 1-indexing
window.blitWindowId = _blit.windowId->currentText().toInt() - 1;
window.draw3D = false;
// We are falling through the planar value on purpose as for a variety of
// reasons requires a projection to be defined even when we are blitting the
// contents of another window.
[[fallthrough]];
case ProjectionIndices::Planar:
{
double fovH = _planar.fovH->value();
@@ -799,8 +872,6 @@ void WindowControl::generateWindowInformation(sgct::config::Window& window) cons
break;
}
}
window.viewports.clear();
window.viewports.push_back(vp);
}
@@ -810,8 +881,9 @@ void WindowControl::setProjectionPlanar(float hfov, float vfov) {
_projectionType->setCurrentIndex(static_cast<int>(ProjectionIndices::Planar));
}
void WindowControl::setProjectionFisheye(int quality) {
void WindowControl::setProjectionFisheye(int quality, float tilt) {
_fisheye.quality->setCurrentIndex(indexForQuality(quality));
_fisheye.tilt->setValue(tilt);
_projectionType->setCurrentIndex(static_cast<int>(ProjectionIndices::Fisheye));
}
@@ -835,6 +907,32 @@ void WindowControl::setProjectionEquirectangular(int quality) {
);
}
void WindowControl::setProjectionBlit(int windowBlitId) {
// We add 1 here as SGCT uses a 0-indexing for the window idx, but we present it to
// the user as a 1-indexing
int idx = _blit.windowId->findText(QString::number(windowBlitId + 1));
ghoul_assert(idx != -1, "Could not find window blit id");
_blit.windowId->setCurrentIndex(idx);
_projectionType->setCurrentIndex(
static_cast<int>(ProjectionIndices::Blit)
);
}
void WindowControl::updateWindowCount(int newWindowCount) {
QString currentIdx = _blit.windowId->currentText();
_blit.windowId->clear();
for (int idx = 0; idx < newWindowCount; idx++) {
if (idx == _windowIndex) {
continue;
}
_blit.windowId->addItem(QString::number(idx + 1));
}
_blit.windowId->setCurrentText(currentIdx);
// Set the correct visibility
_blit.unavailable->setVisible(newWindowCount == 1);
}
void WindowControl::onSizeXChanged(int newValue) {
_windowDimensions.setWidth(newValue);
if (_aspectRatioLocked) {
@@ -896,6 +994,7 @@ void WindowControl::onProjectionChanged(int newSelection) const {
_sphericalMirror.widget->setVisible(selected == ProjectionIndices::SphericalMirror);
_cylindrical.widget->setVisible(selected == ProjectionIndices::Cylindrical);
_equirectangular.widget->setVisible(selected == ProjectionIndices::Equirectangular);
_blit.widget->setVisible(selected == ProjectionIndices::Blit);
}
void WindowControl::onAspectRatioLockClicked() {
+34 -3
View File
@@ -37,6 +37,7 @@
#include <ghoul/cmdparser/multiplecommand.h>
#include <ghoul/cmdparser/singlecommand.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/logging/visualstudiooutputlog.h>
#include <ghoul/misc/stacktrace.h>
#ifdef WIN32
@@ -1414,9 +1415,39 @@ int main(int argc, char* argv[]) {
openspace::Settings settings = loadSettings();
settings.hasStartedBefore = true;
const std::filesystem::path p = global::configuration->profile;
const std::filesystem::path reducedName = p.filename().replace_extension();
settings.profile = reducedName.string();
const std::filesystem::path profile = global::configuration->profile;
const bool isDefaultProfile = ghoul::filesystem::isSubdirectory(
profile,
absPath("${PROFILES}")
);
const bool isUserProfile = ghoul::filesystem::isSubdirectory(
profile,
absPath("${USER_PROFILES}")
);
if (isDefaultProfile) {
std::filesystem::path p = std::filesystem::relative(
profile,
absPath("${PROFILES}")
);
p.replace_extension();
settings.profile = p.string();
}
else if (isUserProfile) {
std::filesystem::path p = std::filesystem::relative(
profile,
absPath("${USER_PROFILES}")
);
p.replace_extension();
settings.profile = p.string();
}
else {
LWARNING(
"Cannot save remembered profile when starting a profile that is not in "
"the data/profiles or user/data/profiles folder."
);
}
settings.configuration =
isGeneratedWindowConfig ? "" : global::configuration->windowConfiguration;
+3 -1
View File
@@ -1,7 +1,9 @@
local Item = {
Type = "DashboardItemDistance",
Identifier = "Distance",
GuiName = "Distance"
GuiName = "Distance",
SourceType = "Camera",
DestinationType = "Focus"
}
@@ -0,0 +1,61 @@
-- Three nodes
-- This example adds three invisible scene graph nodes and then shows the angle between
-- those three nodes.
local Node1 = {
Identifier = "DashboardItemAngle_Example_ThreeNodes_Node1",
GUI = {
Name = "DashboardItemAngle - Three Nodes (Node 1)"
}
}
local Node2 = {
Identifier = "DashboardItemAngle_Example_ThreeNodes_Node2",
Transform = {
Translation = {
Type = "StaticTranslation",
Position = { 2.0, 1.0, 0.0 }
}
},
GUI = {
Name = "DashboardItemAngle - Three Nodes (Node 2)"
}
}
local Node3 = {
Identifier = "DashboardItemAngle_Example_ThreeNodes_Node3",
Transform = {
Translation = {
Type = "StaticTranslation",
Position = { -2.0, 1.0, 0.0 }
}
},
GUI = {
Name = "DashboardItemAngle - Three Nodes (Node 3)"
}
}
local Item = {
Identifier = "DashboardItemAngle_Example_ThreeNodes",
Type = "DashboardItemAngle",
SourceType = "Node",
SourceNodeIdentifier = Node1.Identifier,
ReferenceType = "Node",
ReferenceNodeIdentifier = Node2.Identifier,
DestinationType = "Node",
DestinationNodeIdentifier = Node3.Identifier
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Node1)
openspace.addSceneGraphNode(Node2)
openspace.addSceneGraphNode(Node3)
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
openspace.removeSceneGraphNode(Node3)
openspace.removeSceneGraphNode(Node2)
openspace.removeSceneGraphNode(Node1)
end)
@@ -0,0 +1,45 @@
-- Two nodes and camera
-- This example adds two invisible scene graph nodes and then shows the angle between the
-- camera and those two nodes.
local Node1 = {
Identifier = "DashboardItemAngle_Example_TwoNodesCamera_Node1",
GUI = {
Name = "DashboardItemAngle - Two Nodes & Camera (Node 1)"
}
}
local Node2 = {
Identifier = "DashboardItemAngle_Example_TwoNodesCamera_Node2",
Transform = {
Translation = {
Type = "StaticTranslation",
Position = { 20.0, 1.0, 0.0 }
}
},
GUI = {
Name = "DashboardItemAngle - Two Nodes & Camera (Node 2)"
}
}
local Item = {
Identifier = "DashboardItemAngle_Example_TwoNodesCamera",
Type = "DashboardItemAngle",
SourceType = "Camera",
ReferenceType = "Node",
ReferenceNodeIdentifier = Node1.Identifier,
DestinationType = "Node",
DestinationNodeIdentifier = Node2.Identifier
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Node1)
openspace.addSceneGraphNode(Node2)
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
openspace.removeSceneGraphNode(Node2)
openspace.removeSceneGraphNode(Node1)
end)
@@ -0,0 +1,45 @@
-- Two nodes and focus
-- This example adds two invisible scene graph nodes and then shows the angle between the
-- current focus node and those two nodes.
local Node1 = {
Identifier = "DashboardItemAngle_Example_TwoNodesFocus_Node1",
GUI = {
Name = "DashboardItemAngle - Two Nodes & Focus (Node 1)"
}
}
local Node2 = {
Identifier = "DashboardItemAngle_Example_TwoNodesFocus_Node2",
Transform = {
Translation = {
Type = "StaticTranslation",
Position = { 20.0, 1.0, 0.0 }
}
},
GUI = {
Name = "DashboardItemAngle - Two Nodes & Focus (Node 2)"
}
}
local Item = {
Identifier = "DashboardItemAngle_Example_TwoNodesFocus",
Type = "DashboardItemAngle",
SourceType = "Focus",
ReferenceType = "Node",
ReferenceNodeIdentifier = Node1.Identifier,
DestinationType = "Node",
DestinationNodeIdentifier = Node2.Identifier
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Node1)
openspace.addSceneGraphNode(Node2)
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
openspace.removeSceneGraphNode(Node2)
openspace.removeSceneGraphNode(Node1)
end)
@@ -0,0 +1,15 @@
-- Basic
-- This example adds a new DashboardItem that shows the current in-game simulation date.
local Item = {
Identifier = "DashboardItemDate_Example",
Type = "DashboardItemDate"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,17 @@
-- Day of Year
-- This example adds a new DashboardItem that shows the current in-game simulation date
-- showing the current year and the number of days that have passed in the year.
local Item = {
Identifier = "DashboardItemDate_Example_DayOfYear",
Type = "DashboardItemDate",
TimeFormat = "YYYY DOY"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,17 @@
-- No Decorations
-- This example adds a new DashboardItem that shows the current in-game simulation date
-- without any additional text surrounding the current date
local Item = {
Identifier = "DashboardItemDate_Example_NoDecoration",
Type = "DashboardItemDate",
FormatString = "{}"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,17 @@
-- Timezone
-- This example adds a new DashboardItem that shows the current in-game simulation date
-- with a timezone of UTC-7 (=PDT)
local Item = {
Identifier = "DashboardItemDate_Example_Timezone",
Type = "DashboardItemDate",
TimeFormat = "YYYY MON DD HR:MN:SC.### PDT ::UTC-7"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,17 @@
-- Year Month Day
-- This example adds a new DashboardItem that shows the current in-game simulation date
-- with a resolution of days.
local Item = {
Identifier = "DashboardItemDate_Example_YearMonthDay",
Type = "DashboardItemDate",
TimeFormat = "YYYY MON DD"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,28 @@
-- Node-Camera
-- This example adds an invisible node and a dashboard item that shows the distance
-- between this node and the current focus node.
local Node = {
Identifier = "DashboardItemDistance_Example_NodeCamera_Node",
GUI = {
Name = "DashboardItemDistance - Node-Camera"
}
}
local Item = {
Identifier = "DashboardItemDistance_Example_NodeCamera",
Type = "DashboardItemDistance",
SourceType = "Node",
SourceNodeIdentifier = Node.Identifier,
DestinationType = "Camera"
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Node)
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
openspace.removeSceneGraphNode(Node)
end)
@@ -0,0 +1,28 @@
-- Node-Focus
-- This example adds an invisible node and a dashboard item that shows the distance
-- between this node and the current focus node.
local Node = {
Identifier = "DashboardItemDistance_Example_NodeFocus_Node",
GUI = {
Name = "DashboardItemDistance - Node-Focus"
}
}
local Item = {
Identifier = "DashboardItemDistance_Example_NodeFocus",
Type = "DashboardItemDistance",
SourceType = "Node",
SourceNodeIdentifier = Node.Identifier,
DestinationType = "Focus"
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Node)
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
openspace.removeSceneGraphNode(Node1)
end)
@@ -0,0 +1,44 @@
-- Node-Node
-- This example adds two invisible nodes and a dashboard item that shows the distance
-- between those two nodes.
local Node1 = {
Identifier = "DashboardItemDistance_Example_NodeNode_Node1",
GUI = {
Name = "DashboardItemDistance - Node-Node (Node 1)"
}
}
local Node2 = {
Identifier = "DashboardItemDistance_Example_NodeNode_Node2",
Transform = {
Translation = {
Type = "StaticTranslation",
Position = { 2.0, 0.0, 0.0 }
}
},
GUI = {
Name = "DashboardItemDistance - Node-Node (Node 2)"
}
}
local Item = {
Identifier = "DashboardItemDistance_Example_NodeNode",
Type = "DashboardItemDistance",
SourceType = "Node",
SourceNodeIdentifier = Node1.Identifier,
DestinationType = "Node",
DestinationNodeIdentifier = Node2.Identifier
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Node1)
openspace.addSceneGraphNode(Node2)
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
openspace.removeSceneGraphNode(Node2)
openspace.removeSceneGraphNode(Node1)
end)
@@ -0,0 +1,29 @@
-- NodeSurface-Camera
-- This example adds two invisible nodes and a dashboard item that shows the distance
-- between those two nodes
local Node = {
Identifier = "DashboardItemDistance_Example_NodeSurfaceCamera_Node",
BoundingSphere = 200.0,
GUI = {
Name = "DashboardItemDistance - NodeSurface-Camera"
}
}
local Item = {
Identifier = "DashboardItemDistance_Example_NodeSurfaceCamera",
Type = "DashboardItemDistance",
SourceType = "Node Surface",
SourceNodeIdentifier = Node.Identifier,
DestinationType = "Camera"
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Node)
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
openspace.removeSceneGraphNode(Node)
end)
@@ -0,0 +1,17 @@
-- Basic
-- This example adds a dashboard item that shows the remaining time or the elapsed time
-- since midday 2000 JAN 01.
local Item = {
Identifier = "DashboardItemElapsedTime_Example",
Type = "DashboardItemElapsedTime",
ReferenceTime = "2000 JAN 01 12:00:00"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,18 @@
-- Fixed Time
-- This example adds a dashboard item that shows the remaining time or the elapsed time
-- since 2000 JAN 01 but ignoring any unit smaller than days.
local Item = {
Identifier = "DashboardItemElapsedTime_Example_FixedTime",
Type = "DashboardItemElapsedTime",
ReferenceTime = "2000 JAN 01 12:00:00",
LowestTimeUnit = "Day"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,19 @@
-- No Decorations
-- This example adds a dashboard item that shows the remaining time or the elapsed time
-- since midday 2000 JAN 01 without any additional text decoration and only printing the
-- remaining time.
local Item = {
Identifier = "DashboardItemElapsedTime_Example_NoDecorations",
Type = "DashboardItemElapsedTime",
ReferenceTime = "2000 JAN 01 12:00:00",
FormatString = "{}"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,16 @@
-- Basic
-- This example adds a dashboard item that shows the average number of frames per second,
-- which is the default value for the frame time type setting.
local Item = {
Identifier = "DashboardItemFramerate_Example",
Type = "DashboardItemFramerate"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,17 @@
-- Delta Time
-- This example adds a dashboard item that shows the frame rate of the last frame in
-- milliseconds.
local Item = {
Identifier = "DashboardItemFramerate_Example_DeltaTime",
Type = "DashboardItemFramerate",
FrametimeType = "Deltatime"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,16 @@
-- Basic
-- This example adds a dashboard item that shows the position of the camera relative to
-- the focus node, if that focus node is a globe.
local Item = {
Identifier = "DashboardItemGlobeLocation_Example",
Type = "DashboardItemGlobeLocation"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,18 @@
-- Degree/Minute/Seconds
-- This example adds a dashboard item that shows the position of the camera relative to
-- the focus node, if that focus node is a globe. The longitude and latitude of the camera
-- is provided in the sexagesimal system (degrees, minutes, seconds).
local Item = {
Identifier = "DashboardItemGlobeLocation_Example",
Type = "DashboardItemGlobeLocation",
DisplayFormat = "DegreeMinuteSeconds"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,16 @@
-- Basic
-- This example adds a dashboard item that shows the input state of the mouse, keyboard,
-- and joystick input devices.
local Item = {
Identifier = "DashboardItemInputState_Example",
Type = "DashboardItemInputState"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,17 @@
-- Mouse Only
-- This example adds a dashboard item that only shows the input state of the mouse inputs.
local Item = {
Identifier = "DashboardItemInputState_Example_MouseOnly",
Type = "DashboardItemInputState",
ShowKeyboard = false,
ShowJoystick = false
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,17 @@
-- Only disabled
-- This example adds a dashboard item that shows the input state of the mouse, keyboard,
-- and joystick input devices but only when they are disabled.
local Item = {
Identifier = "DashboardItemInputState_Example_OnlyDisabled",
Type = "DashboardItemInputState",
ShowWhenDisabled = true
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,16 @@
-- Basic
-- This example adds a dashboard item that shows the status of the currently active
-- mission.
local Item = {
Identifier = "DashboardItemMission_Example",
Type = "DashboardItemMission"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,15 @@
-- Basic
-- This example adds a dashboard item that shows the status of the parallel connection.
local Item = {
Identifier = "DashboardItemParallelConnection_Example",
Type = "DashboardItemParallelConnection"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,17 @@
-- Bool
-- This example adds a dashboard item that shows the state of a boolean property.
local Item = {
Identifier = "DashboardItemPropertyValue_Example_Bool",
Type = "DashboardItemPropertyValue",
URI = "NavigationHandler.OrbitalNavigator.Friction.RotationalFriction",
DisplayString = "Rotational Friction is: {}"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,18 @@
-- Float
-- This example adds a dashboard item that shows the state of a floating point value
-- property.
local Item = {
Identifier = "DashboardItemPropertyValue_Example_Float",
Type = "DashboardItemPropertyValue",
URI = "RenderEngine.Gamma",
DisplayString = "Gamma Correction: {}"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,18 @@
-- Int
-- This example adds a dashboard item that shows the state of a integer point value
-- property.
local Item = {
Identifier = "DashboardItemPropertyValue_Example_Int",
Type = "DashboardItemPropertyValue",
URI = "LuaConsole.HistoryLength",
DisplayString = "Lua Console History Length: {}"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,17 @@
-- Vec3
-- This example adds a dashboard item that shows the state of a 3-vector value property.
local Item = {
Identifier = "DashboardItemPropertyValue_Example_Vec3",
Type = "DashboardItemPropertyValue",
URI = "RenderEngine.GlobalRotation",
DisplayString = "Global Rotation: ({}, {}, {})"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,17 @@
-- Vec4
-- This example adds a dashboard item that shows the state of a 4-vector value property.
local Item = {
Identifier = "DashboardItemPropertyValue_Example_Vec4",
Type = "DashboardItemPropertyValue",
URI = "RenderEngine.EnabledFontColor",
DisplayString = "Font Color (enabled): ({}, {}, {}, {})"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,15 @@
-- Basic
-- This example adds a dashboard item that shows the current simulation increment.
local Item = {
Identifier = "DashboardItemSimulationIncrement_Example",
Type = "DashboardItemSimulationIncrement"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,17 @@
-- Nanoseconds
-- This example adds a dashboard item that shows the current simulation increment always
-- expressed in nanoseconds.
local Item = {
Identifier = "DashboardItemSimulationIncrement_Example_NoDecoration",
Type = "DashboardItemSimulationIncrement",
RequestedUnit = "Nanosecond"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,22 @@
-- No Decoration
-- This example adds a dashboard item that shows the current simulation increment without
-- any textual decorations. This example also shows how to ignore the first two parameters
-- the `TransitionFormat` format string. Both the `TransitionFormat` and the
-- `RegularFormat` string replacement markers allow the setting of numbers to determine
-- which argument should be placed in here. The `TransitionFormat` in this example omits
-- the numbers 0 and 1, thus ignoring the first two arguments to the string.
local Item = {
Identifier = "DashboardItemSimulationIncrement_Example_NoDecoration",
Type = "DashboardItemSimulationIncrement",
TransitionFormat = "{3:.1f} {4:s} / second{2:s}",
RegularFormat = "{:.1f} {:s} / second{:s}"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,16 @@
-- Basic
-- This example adds a dashboard item that adds a spacing to the dashboard. This example
-- will not show anything by itself.
local Item = {
Identifier = "DashboardItemSpacing_Example",
Type = "DashboardItemSpacing"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,15 @@
-- Basic
-- This example adds a dashboard item that shows the speed of the camera.
local Item = {
Identifier = "DashboardItemVelocity_Example",
Type = "DashboardItemVelocity"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
@@ -0,0 +1,17 @@
-- Nautical Miles
-- This example adds a dashboard item that shows the speed of the camera, but always
-- displayed in nautical miles per second (or knots).
local Item = {
Identifier = "DashboardItemVelocity_Example_NauticalMiles",
Type = "DashboardItemVelocity",
RequestedUnit = "Nautical Mile"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)
-201
View File
@@ -1,201 +0,0 @@
asset.require("scene/solarsystem/planets/earth/earth")
asset.require("scene/solarsystem/planets/earth/moon/moon")
local Angle = {
Type = "DashboardItemAngle",
Identifier = "Angle",
ReferenceType = "Node",
ReferenceNodeName = "Earth",
DestinationType = "Node",
DestinationNodeName = "Moon"
}
local Date = {
Type = "DashboardItemDate",
Identifier = "Date"
}
local SimulationIncrement = {
Type = "DashboardItemSimulationIncrement",
Identifier = "SimulationIncrement",
GuiName = "Simulation Increment"
}
local Distance = {
Type = "DashboardItemDistance",
Identifier = "Distance"
}
local Framerate = {
Type = "DashboardItemFramerate",
Identifier = "Framerate"
}
local ParallelConnection = {
Type = "DashboardItemParallelConnection",
Identifier = "ParallelConnection",
GuiName = "Parallel Connection"
}
local Mission = {
Type = "DashboardItemMission",
Identifier = "Mission"
}
local PropertyValue = {
Type = "DashboardItemPropertyValue",
Identifier = "DashbaordItemPropertyValue",
URI = "Scene.Earth.Renderable.Enabled",
DisplayString = "Earth is enabled: {}"
}
local PropertyValueFloat = {
Type = "DashboardItemPropertyValue",
Identifier = "DashbaordItemPropertyValue_Float",
URI = "Scene.Earth.Renderable.TargetLodScaleFactor",
DisplayString = "Earth LOD is {:.5f}"
}
local PropertyValueDouble = {
Type = "DashboardItemPropertyValue",
Identifier = "DashbaordItemPropertyValue_Double",
URI = "NavigationHandler.PathNavigator.ArrivalDistanceFactor",
DisplayString = "Arrival Distance Factor is {:.8f}"
}
local PropertyValueInt = {
Type = "DashboardItemPropertyValue",
Identifier = "DashbaordItemPropertyValue_Int",
URI = "LuaConsole.HistoryLength",
DisplayString = "History length is {}"
}
local PropertyValueUInt = {
Type = "DashboardItemPropertyValue",
Identifier = "DashboardItemPropertyValue_UInt",
URI = "Modules.Globebrowsing.TileCacheSize",
DisplayString = "Tile Cache Size is {}"
}
local PropertyValueDVec3 = {
Type = "DashboardItemPropertyValue",
Identifier = "DashboardItemPropertyValue_DVec3",
URI = "Scene.SolarSystemBarycenter.Transform.Transform",
DisplayString = "SSB Transform is: ({}, {}, {})"
}
local PropertyValueIVec2 = {
Type = "DashboardItemPropertyValue",
Identifier = "DashboardItemPropertyValue_IVec2",
URI = "Scene.SolarSystemBarycenter.Renderable.ScreenSpacePosition",
DisplayString = "Random ScreenSpace Position: ({}, {})"
}
local PropertyValueVec2 = {
Type = "DashboardItemPropertyValue",
Identifier = "DashboardItemPropertyValue_Vec2",
URI = "Scene.EarthAtmosphere.Renderable.AtmosphereDimmingSunsetAngle",
DisplayString = "Sunset Angle is ({}, {})"
}
local PropertyValueVec3 = {
Type = "DashboardItemPropertyValue",
Identifier = "DashboardItemPropertyValue_Vec3",
URI = "RenderEngine.GlobalRotation",
DisplayString = "Global Rotation is ({}, {}, {})"
}
local PropertyValueVec4 = {
Type = "DashboardItemPropertyValue",
Identifier = "DashboardItemPropertyValue_Vec4",
URI = "LuaConsole.BackgroundColor",
DisplayString = "Background Coolor is ({}, {}, {}, {})"
}
local ElapsedTime = {
Type = "DashboardItemElapsedTime",
Identifier = "ElapsedTime",
ReferenceTime = "2022-10-12 12:00:00"
}
local InputState = {
Type = "DashboardItemInputState",
Identifier = "InputState"
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Angle)
openspace.dashboard.addDashboardItem(Date)
openspace.dashboard.addDashboardItem(SimulationIncrement)
openspace.dashboard.addDashboardItem(Distance)
openspace.dashboard.addDashboardItem(Framerate)
openspace.dashboard.addDashboardItem(ParallelConnection)
openspace.dashboard.addDashboardItem(Mission)
openspace.dashboard.addDashboardItem(PropertyValue)
openspace.dashboard.addDashboardItem(PropertyValueFloat)
openspace.dashboard.addDashboardItem(PropertyValueDouble)
openspace.dashboard.addDashboardItem(PropertyValueInt)
openspace.dashboard.addDashboardItem(PropertyValueUInt)
openspace.dashboard.addDashboardItem(PropertyValueDVec3)
openspace.dashboard.addDashboardItem(PropertyValueIVec2)
openspace.dashboard.addDashboardItem(PropertyValueVec2)
openspace.dashboard.addDashboardItem(PropertyValueVec3)
openspace.dashboard.addDashboardItem(PropertyValueVec4)
openspace.dashboard.addDashboardItem(ElapsedTime)
openspace.dashboard.addDashboardItem(InputState)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(InputState)
openspace.dashboard.removeDashboardItem(ElapsedTime)
openspace.dashboard.removeDashboardItem(PropertyValueVec4)
openspace.dashboard.removeDashboardItem(PropertyValueVec3)
openspace.dashboard.removeDashboardItem(PropertyValueVec2)
openspace.dashboard.removeDashboardItem(PropertyValueIVec2)
openspace.dashboard.removeDashboardItem(PropertyValueDVec3)
openspace.dashboard.removeDashboardItem(PropertyValueUInt)
openspace.dashboard.removeDashboardItem(PropertyValueInt)
openspace.dashboard.removeDashboardItem(PropertyValueDouble)
openspace.dashboard.removeDashboardItem(PropertyValueFloat)
openspace.dashboard.removeDashboardItem(PropertyValue)
openspace.dashboard.removeDashboardItem(Mission)
openspace.dashboard.removeDashboardItem(ParallelConnection)
openspace.dashboard.removeDashboardItem(Framerate)
openspace.dashboard.removeDashboardItem(Distance)
openspace.dashboard.removeDashboardItem(SimulationIncrement)
openspace.dashboard.removeDashboardItem(Date)
openspace.dashboard.removeDashboardItem(Angle)
end)
asset.export(Angle)
asset.export(Date)
asset.export(SimulationIncrement)
asset.export(Distance)
asset.export(Framerate)
asset.export(ParallelConnection)
asset.export(Mission)
asset.export(PropertyValue)
asset.export(PropertyValueFloat)
asset.export(PropertyValueDouble)
asset.export(PropertyValueInt)
asset.export(PropertyValueUInt)
asset.export(PropertyValueDVec3)
asset.export(PropertyValueIVec2)
asset.export(PropertyValueVec2)
asset.export(PropertyValueVec3)
asset.export(PropertyValueVec4)
asset.export(ElapsedTime)
asset.export(InputState)
asset.meta = {
Name = "Dashboard Items Example",
Description = [[Examples of different types of dashboard items. These are dynamic
information texts that will be shown over the rendering (per default in the top
left corner, on flat screens).]],
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}
@@ -1,6 +1,6 @@
-- Basic
-- This example creates a SceneGraphNode that only displays coordinate axes. The
-- parent is not set which defaults to placing the axes at the center of the Sun.
-- This example creates a scene graph node that only displays coordinate axes. The parent
-- is not set which defaults to placing the axes at the center of the Sun.
local Node = {
Identifier = "RenderableCartesianAxes_Example",
@@ -1,6 +1,6 @@
-- With Parent
-- This example creates a SceneGraphNode that displays coordinate axes of the given parent
-- node, in this case Earth.
-- This example creates a scene graph node that displays coordinate axes of the given
-- parent node, in this case Earth.
local earth = asset.require("scene/solarsystem/planets/earth/earth")
@@ -0,0 +1,24 @@
-- Basic
-- This example shows how to create a textured plane in 3D space, where the texture is
-- loaded from a local file on disk.
local Node = {
Identifier = "RenderablePlaneImageLocal_Example",
Renderable = {
Type = "RenderablePlaneImageLocal",
Size = 3.0E11,
Texture = openspace.absPath("${DATA}/test2.jpg")
},
GUI = {
Name = "RenderablePlaneImageLocal - Basic",
Path = "/Examples"
}
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Node)
end)
asset.onDeinitialize(function()
openspace.removeSceneGraphNode(Node)
end)
@@ -0,0 +1,26 @@
-- Billboard Image
-- This example shows how to create a textured plane in 3D space, where the texture is
-- loaded from a local file on disk and the plane is billboarded to always face the
-- camera.
local Node = {
Identifier = "RenderablePlaneImageLocal_Example_Billboard",
Renderable = {
Type = "RenderablePlaneImageLocal",
Size = 3.0E11,
Texture = openspace.absPath("${DATA}/test2.jpg"),
Billboard = true
},
GUI = {
Name = "RenderablePlaneImageLocal - Billboard",
Path = "/Examples"
}
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Node)
end)
asset.onDeinitialize(function()
openspace.removeSceneGraphNode(Node)
end)
@@ -1,18 +1,18 @@
-- Billboarded Image
-- Billboard Image
-- This example shows how to create a textured plane in 3D space, where the texture is
-- loaded from the internet though a web URL and the plane is billboarded to always
-- face the camera.
local Node = {
Identifier = "RenderablePlaneImageOnline_Example_Billboarded",
Identifier = "RenderablePlaneImageOnline_Example_Billboard",
Renderable = {
Type = "RenderablePlaneImageOnline",
Size = 3.0E11,
URL = "http://data.openspaceproject.com/examples/renderableplaneimageonline.jpg",
Billboarded = true
Billboard = true
},
GUI = {
Name = "RenderablePlaneImageOnline - Billboarded",
Name = "RenderablePlaneImageOnline - Billboard",
Path = "/Examples"
}
}
@@ -0,0 +1,56 @@
-- Basic
-- This asset creates a rotation that places coordinate axes close to a sphere with the
-- z axis pointing towards the sphere. The coordinate axes are translated away from the
-- sphere to make that orientation more obvious.
--
-- Making the `YAxis` `{ 0.0, 1.0, 0.0 }` and actually using the orthogonal projection of
-- that direction means that the y axis of the new coordinate system will point in the
-- hemisphere in which the old y-axis was pointing, albeit being orthogonal to the other
-- specified axis. That axis is pointing towards the scene graph node holding the sphere.
local Sphere = {
Identifier = "FixedRotation_Example_Sphere",
Transform = {
Translation = {
Type = "StaticTranslation",
Position = { 2.0, 1.5, 1.0 }
}
},
Renderable = {
Type = "RenderableSphericalGrid"
},
GUI = {
Name = "FixedRotation - Basic (Sphere)",
Path = "/Examples"
}
}
local Node = {
Identifier = "FixedRotation_Example",
Transform = {
Rotation = {
Type = "FixedRotation",
Attached = "FixedRotation_Example",
YAxis = { 0.0, 1.0, 0.0 },
YAxisOrthogonal = true,
ZAxis = "FixedRotation_Example_Sphere"
}
},
Renderable = {
Type = "RenderableCartesianAxes"
},
GUI = {
Name = "FixedRotation - Basic",
Path = "/Examples"
}
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Sphere)
openspace.addSceneGraphNode(Node)
end)
asset.onDeinitialize(function()
openspace.removeSceneGraphNode(Node)
openspace.removeSceneGraphNode(Sphere)
end)
@@ -0,0 +1,33 @@
-- Axis Mapping
-- This asset creates a rotation that shows coordinate axes in which the x and the y axes
-- are flipped. While this could also be achieved with a
-- [ConstantRotation](#base_transform_rotation_constant) class, this serves as an example
-- for more elaborate coordinate system mappings, such as converting to a coordinate
-- system with a known coordinate axes.
local Node = {
Identifier = "FixedRotation_Example_Mapping",
Transform = {
Rotation = {
Type = "FixedRotation",
XAxis = { 0.0, 1.0, 0.0 },
YAxis = { 1.0, 0.0, 0.0 },
ZAxis = { 0.0, 0.0, 1.0 }
}
},
Renderable = {
Type = "RenderableCartesianAxes"
},
GUI = {
Name = "FixedRotation - Mapping",
Path = "/Examples"
}
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Node)
end)
asset.onDeinitialize(function()
openspace.removeSceneGraphNode(Node)
end)
@@ -0,0 +1,56 @@
-- Inverted Axis
-- This asset creates a rotation that places coordinate axes close to a sphere with the z
-- axis pointing away from the sphere. The coordinate axes are translated away from the
-- sphere to make that orientation more obvious.
--
-- Making the `YAxis` { 0.0, 1.0, 0.0 } and actually using the orthogonal projection of
-- that direction means that the y axis of the new coordinate system will point in the
-- hemisphere in which the old y-axis was pointing, albeit being orthogonal to the other
-- specified axis. That axis is pointing towards the scene graph node holding the sphere.
local Sphere = {
Identifier = "FixedRotation_Example_InvertedAxis_Sphere",
Transform = {
Translation = {
Type = "StaticTranslation",
Position = { 2.0, 1.5, 1.0 }
}
},
Renderable = {
Type = "RenderableSphericalGrid"
},
GUI = {
Name = "FixedRotation - Inverted Axis (Sphere)",
Path = "/Examples"
}
}
local Node = {
Identifier = "FixedRotation_Example_InvertedAxis",
Transform = {
Rotation = {
Type = "FixedRotation",
Attached = "FixedRotation_Example_InvertedAxis",
YAxis = { 0.0, 1.0, 0.0 },
YAxisOrthogonal = true,
ZAxis = Sphere.Identifier,
ZAxisInvert = true
}
},
Renderable = {
Type = "RenderableCartesianAxes"
},
GUI = {
Name = "FixedRotation - Inverted Axis",
Path = "/Examples"
}
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Sphere)
openspace.addSceneGraphNode(Node)
end)
asset.onDeinitialize(function()
openspace.removeSceneGraphNode(Node)
openspace.removeSceneGraphNode(Sphere)
end)
@@ -0,0 +1,87 @@
-- Rotation Following Two Moving Objects
-- This asset creates a rotation that places coordinate axes orbiting close to two spheres
-- with the y axis always pointing towards the first sphere and the z axis always pointing
-- towards the second sphere as the coordinate system moves around. The set of coordinate
-- axes are orbiting using a [KeplerTranslation](#space_transform_kepler) that provides a
-- configurable orbital motion. The use of the
-- [KeplerTranslation](#space_transform_kepler) in this example is arbitrary and the
-- FixedRotation does not depend on the use of that class. We use it in this example as we
-- want a moving object to show that the `FixedRotation` will always point at the object,
-- even as it is moving.
--
-- Note that in this example the coordinate system will be skewed as, in general, it is
-- not guaranteed that the direction from the node to the two spheres will be an
-- orthogonal vector.
local Sphere1 = {
Identifier = "FixedRotation_Example_Moving_TwoObjects_Sphere1",
Transform = {
Translation = {
Type = "StaticTranslation",
Position = { 3.0, -2.0, 0.0 }
}
},
Renderable = {
Type = "RenderableSphericalGrid"
},
GUI = {
Name = "FixedRotation - Moving Two Objects (Sphere 1)",
Path = "/Examples"
}
}
local Sphere2 = {
Identifier = "FixedRotation_Example_Moving_TwoObjects_Sphere2",
Transform = {
Translation = {
Type = "KeplerTranslation",
Eccentricity = 0.5,
SemiMajorAxis = 0.0025,
Inclination = 0.0,
AscendingNode = 0.0,
ArgumentOfPeriapsis = 0.0,
MeanAnomaly = 0.0,
Epoch = "2000 JAN 01 12:00:00",
Period = 10.0
}
},
Renderable = {
Type = "RenderableSphericalGrid"
},
GUI = {
Name = "FixedRotation - Moving Two Objects (Sphere 2)",
Path = "/Examples"
}
}
local Node = {
Identifier = "FixedRotation_Example_Moving_TwoObjects",
Transform = {
Rotation = {
Type = "FixedRotation",
Attached = "FixedRotation_Example_Moving_TwoObjects",
YAxis = Sphere1.Identifier,
YAxisOrthogonal = true,
ZAxis = Sphere2.Identifier
}
},
Renderable = {
Type = "RenderableCartesianAxes"
},
GUI = {
Name = "FixedRotation - Moving Two Objects",
Path = "/Examples"
}
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Sphere1)
openspace.addSceneGraphNode(Sphere2)
openspace.addSceneGraphNode(Node)
end)
asset.onDeinitialize(function()
openspace.removeSceneGraphNode(Node)
openspace.removeSceneGraphNode(Sphere2)
openspace.removeSceneGraphNode(Sphere1)
end)
@@ -0,0 +1,63 @@
-- Rotation Following One Moving Object
-- This asset creates a rotation that places coordinate axes orbiting close to a sphere
-- with the z axis always pointing towards the sphere as it orbits around the sphere. The
-- coordinate axes are translated away from the sphere to make that orientation more
-- obvious.
--
-- Making the `YAxis` { 0.0, 1.0, 0.0 } and actually using the orthogonal projection of
-- that direction means that the y axis of the new coordinate system will point in the
-- hemisphere in which the old y-axis was pointing, albeit being orthogonal to the other
-- specified axis. That axis is pointing towards the scene graph node holding the sphere.
local Sphere = {
Identifier = "FixedRotation_Example_Moving_Sphere",
Transform = {
Translation = {
Type = "KeplerTranslation",
Eccentricity = 0.5,
SemiMajorAxis = 0.0025,
Inclination = 0.0,
AscendingNode = 0.0,
ArgumentOfPeriapsis = 0.0,
MeanAnomaly = 0.0,
Epoch = "2000 JAN 01 12:00:00",
Period = 10.0
}
},
Renderable = {
Type = "RenderableSphericalGrid"
},
GUI = {
Name = "FixedRotation - Moving (Sphere)",
Path = "/Examples"
}
}
local Node = {
Identifier = "FixedRotation_Example_Moving",
Transform = {
Rotation = {
Type = "FixedRotation",
Attached = "FixedRotation_Example_Moving",
YAxis = { 0.0, 1.0, 0.0 },
YAxisOrthogonal = true,
ZAxis = Sphere.Identifier
}
},
Renderable = {
Type = "RenderableCartesianAxes"
},
GUI = {
Name = "FixedRotation - Moving",
Path = "/Examples"
}
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Sphere)
openspace.addSceneGraphNode(Node)
end)
asset.onDeinitialize(function()
openspace.removeSceneGraphNode(Node)
openspace.removeSceneGraphNode(Sphere)
end)
@@ -1,7 +1,7 @@
-- Basic
-- This asset creates a SceneGraphNode that only displays coordinate axes. The rotation of
-- coordinate axes are determined by executing a Lua file that returns the rotation matrix
-- to be used.
-- This asset creates a scene graph node that only displays coordinate axes. The rotation
-- of coordinate axes are determined by executing a Lua file that returns the rotation
-- matrix to be used.
--
-- ```{literalinclude} example.lua
-- :language: lua
@@ -1,6 +1,6 @@
-- Basic
-- This asset creates a SceneGraphNode that only displays coordinate axes. The rotation of
-- the coordinate axes are determined by a combination of individual rotations. The
-- This asset creates a scene graph node that only displays coordinate axes. The rotation
-- of the coordinate axes are determined by a combination of individual rotations. The
-- rotations are applied in the order in which they are specified
local Node = {
@@ -1,8 +1,8 @@
-- Basic
-- This asset creates a rotation provided by a SPICE kernel and applies it to a
-- SceneGraphNode that only displays coordinate axes. The rotation of the coordinate axes
-- are determined by SPICE, in this case pretending that the coordinate axes are rotating
-- at the same rate as Earth.
-- This asset creates a rotation provided by a SPICE kernel and applies it to a scene
-- graph node that only displays coordinate axes. The rotation of the coordinate axes are
-- determined by SPICE, in this case pretending that the coordinate axes are rotating at
-- the same rate as Earth.
-- For more information about SPICE see: https://naif.jpl.nasa.gov/naif/
-- Load the default SPICE kernels, which are the planetary constants and the DE430 kernel
@@ -1,9 +1,9 @@
-- Fixed Date
-- This asset creates a rotation provided by a SPICE kernel and applies it to a
-- SceneGraphNode that only displays coordinate axes. The rotation of the coordinate axes
-- are determined by SPICE, in this case pretending that the coordinate axes are rotating
-- at the same rate as Earth. In this specific example, the orientation is independent of
-- the actual in-game time in OpenSpace and only uses a fixed date of 2000 JAN 01 instead.
-- This asset creates a rotation provided by a SPICE kernel and applies it to a scene
-- graph node that only displays coordinate axes. The rotation of the coordinate axes are
-- determined by SPICE, in this case pretending that the coordinate axes are rotating at
-- the same rate as Earth. In this specific example, the orientation is independent of the
-- actual in-game time in OpenSpace and only uses a fixed date of 2000 JAN 01 instead.
-- Load the default SPICE kernels, which is the planetary constants and the DE430 kernel
asset.require("spice/core")
@@ -1,10 +1,10 @@
-- TimeFrame
-- This asset creates a rotation provided by a SPICE kernel and applies it to a
-- SceneGraphNode that only displays coordinate axes. The rotation of the coordinate axes
-- are determined by SPICE, in this case pretending that the coordinate axes are rotating
-- at the same rate as Earth. In this example, the rotation is only calculated between
-- 2000 JAN 01 and 2002 JAN 01 to exemplify a use-case in which the data from the SPICE
-- kernel is not available for the whole duration.
-- This asset creates a rotation provided by a SPICE kernel and applies it to a scene
-- graph node that only displays coordinate axes. The rotation of the coordinate axes are
-- determined by SPICE, in this case pretending that the coordinate axes are rotating at
-- the same rate as Earth. In this example, the rotation is only calculated between 2000
-- JAN 01 and 2002 JAN 01 to exemplify a use-case in which the data from the SPICE kernel
-- is not available for the whole duration.
-- Load the default SPICE kernels, which is the planetary constants and the DE430 kernel
asset.require("spice/core")
@@ -1,8 +1,8 @@
-- Time offset
-- This asset creates a rotation provided by a SPICE kernel and applies it to a
-- SceneGraphNode that only displays coordinate axes. The rotation of the coordinate axes
-- are determined by SPICE, in this case pretending that the coordinate axes are rotating
-- at the same rate as Earth. In this specific example, the orientation is offset 8h back
-- This asset creates a rotation provided by a SPICE kernel and applies it to a scene
-- graph node that only displays coordinate axes. The rotation of the coordinate axes are
-- determined by SPICE, in this case pretending that the coordinate axes are rotating at
-- the same rate as Earth. In this specific example, the orientation is offset 8h back
-- compared to the actual in-game time in OpenSpace.
-- Load the default SPICE kernels, which is the planetary constants and the DE430 kernel
@@ -1,7 +1,7 @@
-- Euler Angles
-- This asset creates a rotation provided by Euler angles and applies it to a
-- SceneGraphNode that only displays coordinate axes. The rotation of the coordinate axes
-- are determined by a constant and unchanging static rotation.
-- This asset creates a rotation provided by Euler angles and applies it to a scene graph
-- node that only displays coordinate axes. The rotation of the coordinate axes are
-- determined by a constant and unchanging static rotation.
local Node = {
Identifier = "StaticRotation_Example_Euler",
@@ -1,7 +1,7 @@
-- Matrix
-- This asset creates a SceneGraphNode that only displays coordinate axes. The rotation of
-- the coordinate axes are determined by a constant and unchanging static rotation that is
-- provided by a 3-by-3 rotation matrix in column-major order.
-- This asset creates a scene graph node that only displays coordinate axes. The rotation
-- of the coordinate axes are determined by a constant and unchanging static rotation that
-- is provided by a 3-by-3 rotation matrix in column-major order.
local Node = {
Identifier = "StaticRotation_Example_Matrix",
@@ -1,7 +1,7 @@
-- Quaternion
-- This asset creates a SceneGraphNode that only displays coordinate axes. The rotation of
-- the coordinate axes are determined by a constant and unchanging static rotation that is
-- provided by a four-dimensional quaternion.
-- This asset creates a scene graph node that only displays coordinate axes. The rotation
-- of the coordinate axes are determined by a constant and unchanging static rotation that
-- is provided by a four-dimensional quaternion.
local Node = {
Identifier = "StaticRotation_Example_Quaternion",
@@ -1,9 +1,9 @@
-- Basic
-- This asset creates a SceneGraphNode that only displays coordinate axes. The rotation of
-- the coordinate axes are determined by a timeline of individual rotations. These rotations
-- are keyframes that are used to seamlessly change between different orientations. This
-- example transitions between three rotations over a long time span. This example will
-- only work if the in-game time is set to January 1st, 2000.
-- This asset creates a scene graph node that only displays coordinate axes. The rotation
-- of the coordinate axes are determined by a timeline of individual rotations. These
-- rotations are keyframes that are used to seamlessly change between different
-- orientations. This example transitions between three rotations over a long time span.
-- This example will only work if the in-game time is set to January 1st, 2000.
local Node = {
Identifier = "TimelineRotation_Example",
@@ -1,13 +1,13 @@
-- No Interpolation
-- This asset creates a SceneGraphNode that only displays coordinate axes. The rotation of
-- the coordinate axes are determined by a timeline of individual rotations that are used
-- without interpolating between the timeline entries. These rotations are keyframes that
-- are used to change between different orientations. This example transitions between
-- three rotations. In this example, the interpolation between entries is disabled, which
-- will cause the coordinate axes to change their orientation abruptly when the rotation
-- changes. If the interpolation were enabled, the orientation of the coordinate axes
-- would transition seamlessly instead at the provided times. This example will only work
-- if the in-game time is set to January 1st, 2000.
-- This asset creates a scene graph node that only displays coordinate axes. The rotation
-- of the coordinate axes are determined by a timeline of individual rotations that are
-- used without interpolating between the timeline entries. These rotations are keyframes
-- that are used to change between different orientations. This example transitions
-- between three rotations. In this example, the interpolation between entries is
-- disabled, which will cause the coordinate axes to change their orientation abruptly
-- when the rotation changes. If the interpolation were enabled, the orientation of the
-- coordinate axes would transition seamlessly instead at the provided times. This example
-- will only work if the in-game time is set to January 1st, 2000.
local Node = {
Identifier = "TimelineRotation_Example_NoInterpolation",
@@ -1,5 +1,5 @@
-- Basic
-- This asset creates a SceneGraphNode that only displays coordinate axes. The sizes of
-- This asset creates a scene graph node that only displays coordinate axes. The sizes of
-- coordinate axes are determined by executing a Lua file that returns the scaling
-- parameters to be used as a table.
--
@@ -1,5 +1,5 @@
-- Basic
-- This asset creates a SceneGraphNode that only displays coordinate axes, with a set of
-- This asset creates a scene graph node that only displays coordinate axes, with a set of
-- multiple scales that are applied one after the other.
local Node = {
@@ -1,10 +1,10 @@
-- Basic
-- This asset creates a SceneGraphNode that only displays coordinate axes. The coordinate
-- axis normally have a length of 1 meter and are scaled in this example by different
-- values for each axis. The x axis is scaled by a factor of 149597870700, which means
-- they will be 149597870700 m (1 AU) long and thus reaching the same distance as Earth's
-- orbit around the Sun. The y-axis stays at its original size, and the z-axis will be
-- hidden entirely by setting the scale value close to 0.
-- This asset creates a scene graph node that only displays coordinate axes. The
-- coordinate axis normally have a length of 1 meter and are scaled in this example by
-- different values for each axis. The x axis is scaled by a factor of 149597870700, which
-- means they will be 149597870700 m (1 AU) long and thus reaching the same distance as
-- Earth's orbit around the Sun. The y-axis stays at its original size, and the z-axis
-- will be hidden entirely by setting the scale value close to 0.
local Node = {
Identifier = "NonUniformStaticScale_Example",
@@ -1,5 +1,5 @@
-- Ellipsoid
-- This asset creates a SceneGraphNode that is rendering a sphere which is adjust to an
-- This asset creates a scene graph node that is rendering a sphere which is adjust to an
-- ellipsoidal shape by using a non-uniform scaling. In particular, the second axis is
-- half as long as the first, and the third axis is a third as long.
@@ -1,8 +1,8 @@
-- Basic
-- This asset creates a SceneGraphNode that only displays coordinate axes. The coordinate
-- axis normally have a length of 1 meter and are scaled in this example by a factor of
-- 149597870700, which means they will be 149597870700 m (1 AU) long, thus reaching the
-- same distance as Earth's orbit around the Sun.
-- This asset creates a scene graph node that only displays coordinate axes. The
-- coordinate axis normally have a length of 1 meter and are scaled in this example by a
-- factor of 149597870700, which means they will be 149597870700 m (1 AU) long, thus
-- reaching the same distance as Earth's orbit around the Sun.
local Node = {
Identifier = "StaticScale_Example",
@@ -1,5 +1,5 @@
-- Basic
-- This asset creates a SceneGraphNode that only displays coordinate axes, which grow at
-- This asset creates a scene graph node that only displays coordinate axes, which grow at
-- a speed of 1 m/s starting on January 1st, 2000 00:00:00. This means that on
-- that date, the coordinate axes will disappear and, for example, on January 1st, 2000
-- 12:00:00, the coordinate axes will be 43200 meters long.
@@ -1,5 +1,5 @@
-- with Speed
-- This asset creates a SceneGraphNode that only displays coordinate axes, which grow at
-- This asset creates a scene graph node that only displays coordinate axes, which grow at
-- a speed of 12 km/s starting on August 8th, 1969 12:00:00. This means that on
-- that date, the coordinate axes will disappear and, for example, on August 8th, 1969
-- 23:00:00, the coordinate axes will be 475200 km long.
@@ -1,5 +1,5 @@
-- No Interpolation
-- This asset creates a SceneGraphNode that only displays coordinate axes. The scale of
-- This asset creates a scene graph node that only displays coordinate axes. The scale of
-- the coordinate axes are determined by a timeline of individual scales that are used
-- without interpolating between the timeline entries. These scales are keyframes that are
-- used to change between different sizes. This example transitions between three sizes.
@@ -1,5 +1,5 @@
-- Basic
-- This asset creates a SceneGraphNode that only displays coordinate axes. The scale of
-- This asset creates a scene graph node that only displays coordinate axes. The scale of
-- the coordinate axes are determined by a timeline of individual scales. These scales
-- are keyframes that are used to seamlessly change between different sizes. This example
-- transitions between three scales over a long time span. This example will only work if
@@ -0,0 +1,53 @@
-- No Interpolation
-- This asset creates a scene graph node that only displays coordinate axes whose scale is
-- determined by a timeline of individual scales that are used without interpolating
-- between the timeline entries. These scales are keyframes that are used to change
-- between different sizes.
--
-- This example transitions between three sizes, but as the interpolation between entries
-- is disabled, it will cause the coordinate axes to change their size abruptly when the
-- scale changes. If the interpolation were enabled, the orientation of the coordinate
-- axes would transition seamlessly instead at the provided times. This example will only
-- work if the in-game time is set to January 1st, 2000.
local Node = {
Identifier = "TimelineScale_Example_NoInterpolation",
Transform = {
Scale = {
Type = "TimelineScale",
Keyframes = {
-- The first timeline entry
["2000 JAN 01 00:00:00"] = {
Type = "StaticScale",
Scale = 10.0
},
-- The second timeline entry
["2000 JAN 01 12:00:00"] = {
Type = "StaticScale",
Scale = 0.0
},
-- The third timeline entry
["2000 JAN 01 23:59:59"] = {
Type = "StaticScale",
Scale = -10.0
}
},
ShouldInterpolate = false
}
},
Renderable = {
Type = "RenderableCartesianAxes"
},
GUI = {
Name = "TimelineScale - No Interpolation",
Path = "/Examples"
}
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Node)
end)
asset.onDeinitialize(function()
openspace.removeSceneGraphNode(Node)
end)
@@ -16,7 +16,7 @@ local Dashboard = {
FontSize = 40,
SourceType = "Camera",
DestinationType = "Node",
DestinationNodeName = earth.Earth.Identifier,
DestinationNodeIdentifier = earth.Earth.Identifier,
-- Specify to use a specific unit, by disabling the automatic simplification of
-- unit and instead use light-years
Simplification = false,
@@ -0,0 +1,22 @@
-- Basic
-- Creates a screenspace image that shows a spherical grid as an example for any
-- [Renderable](#renderable) that can be displayed.
local Object = {
Type = "ScreenSpaceRenderableRenderable",
Identifier = "ScreenSpaceRenderableRenderable_Example",
Renderable = {
Type = "RenderableSphericalGrid",
Opacity = 1.0,
Color = { 0.3, 0.84, 1.0 },
LineWidth = 2.0
}
}
asset.onInitialize(function()
openspace.addScreenSpaceRenderable(Object)
end)
asset.onDeinitialize(function()
openspace.removeScreenSpaceRenderable(Object)
end)
@@ -0,0 +1,24 @@
-- Axes
-- Creates a screenspace image that renders three Cartesian axes into the screen space
-- window. This example also modifies the original camera position to give an oblique view
-- onto the axes and increases the field of view of the camera to a wider degree. We also
-- set the background color to be fully opaque to make it easier to see the axes.
local Object = {
Type = "ScreenSpaceRenderableRenderable",
Identifier = "ScreenSpaceRenderableRenderable_Example_Axes",
Renderable = {
Type = "RenderableCartesianAxes"
},
BackgroundColor = { 0.0, 0.0, 0.0, 1.0 },
CameraPosition = { 1.0, 1.0, 1.0 },
CameraFov = 80.0
}
asset.onInitialize(function()
openspace.addScreenSpaceRenderable(Object)
end)
asset.onDeinitialize(function()
openspace.removeScreenSpaceRenderable(Object)
end)
@@ -0,0 +1,41 @@
-- Model Distance
-- Creates a screen space window into which 3D model of the Eiffel tower is rendered. As
-- the objects are rendered in meter scale, and the Eiffel tower is about 300m tall, we
-- place the camera at a great distance to be able to see the entire Eiffel tower at the
-- same time.
-- Download the model file for the Eiffel tower
local modelFolder = asset.resource({
Name = "Scale Eiffel Tower",
Type = "HttpSynchronization",
Identifier = "scale_model_eiffel_tower",
Version = 1
})
local Object = {
Type = "ScreenSpaceRenderableRenderable",
Identifier = "ScreenSpaceRenderableRenderable_Example_ModelDistance",
Renderable = {
Type = "RenderableModel",
GeometryFile = modelFolder .. "eiffeltower.osmodel",
RotationVector = { 0.0, 45.0, 0.0 },
LightSources = {
{
Identifier = "Camera",
Type = "CameraLightSource",
Intensity = 5.0
}
}
},
Scale = 1.25,
CameraPosition = { 0.0, 3500.0, 9000.0 },
CameraCenter = { 0.0, 2750.0, 0.0 }
}
asset.onInitialize(function()
openspace.addScreenSpaceRenderable(Object)
end)
asset.onDeinitialize(function()
openspace.removeScreenSpaceRenderable(Object)
end)
@@ -0,0 +1,47 @@
-- Model
-- Creates a screen space window into which 3D model of the Eiffel tower is rendered. As
-- the objects are rendered in meter scale, and the Eiffel tower is about 300m tall, we
-- both shrink the rendering to make the entire model fit into the view and also modify
-- the position of the camera.
-- Download the model file for the Eiffel tower
local modelFolder = asset.resource({
Name = "Scale Eiffel Tower",
Type = "HttpSynchronization",
Identifier = "scale_model_eiffel_tower",
Version = 1
})
local Object = {
Type = "ScreenSpaceRenderableRenderable",
Identifier = "ScreenSpaceRenderableRenderable_Example_Model",
Transform = {
Scale = {
Type = "StaticScale",
Scale = 0.0002
}
},
Renderable = {
Type = "RenderableModel",
GeometryFile = modelFolder .. "eiffeltower.osmodel",
RotationVector = { 0.0, 45.0, 0.0 },
LightSources = {
{
Identifier = "Camera",
Type = "CameraLightSource",
Intensity = 5.0
}
}
},
Scale = 1.25,
CameraPosition = { 0.0, 1.0, 2.0 },
CameraCenter = { 0.0, 0.5, 0.0 }
}
asset.onInitialize(function()
openspace.addScreenSpaceRenderable(Object)
end)
asset.onDeinitialize(function()
openspace.removeScreenSpaceRenderable(Object)
end)
@@ -0,0 +1,28 @@
-- Basic
-- This example creates time frame interval and uses it for a scene graph node displaying
-- a set of coordinate axes. The time frame interval causes the scene graph node to only
-- be valid between January 1st, 2000 and March 1st, 2002.
local Node = {
Identifier = "TimeFrameInterval_Example",
TimeFrame = {
Type = "TimeFrameInterval",
Start = "2000 JAN 01 00:00:00.000",
End = "2002 MAR 02 00:00:00.00"
},
Renderable = {
Type = "RenderableCartesianAxes"
},
GUI = {
Name = "TimeFrameInterval - Basic",
Path = "/Examples"
}
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Node)
end)
asset.onDeinitialize(function()
openspace.removeSceneGraphNode(Node)
end)
+2 -2
View File
@@ -13,13 +13,13 @@ local Node = {
{
Type = "TimeFrameInterval",
Start = "2000 JAN 01 00:00:00.000",
End = "2000 JAN 01 23:59:59.999"
End = "2000 JAN 02 00:00:00.000"
},
-- The second TimeFrameInterval for the second day
{
Type = "TimeFrameInterval",
Start = "2002 MAR 01 00:00:00.000",
End = "2002 MAR 01 23:59:59.999"
End = "2002 MAR 02 00:00:00.000"
}
}
},
@@ -1,8 +1,9 @@
-- Basic
-- This asset creates a SceneGraphNode that only displays coordinate axes. The coordinate
-- axes are translated by a value determined by executing a Lua file that returns the
-- translation parameters to be used as a table. In order to see the translation, we need
-- to also have a node that does not move so that we can see the relative movement.
-- This asset creates a scene graph node that only displays coordinate axes. The
-- coordinate axes are translated by a value determined by executing a Lua file that
-- returns the translation parameters to be used as a table. In order to see the
-- translation, we need to also have a node that does not move so that we can see the
-- relative movement.
--
-- ```{literalinclude} example.lua
-- :language: lua
@@ -1,7 +1,7 @@
-- Basic
-- This asset creates a time-varying translation with information from a SPICE kernel and
-- applies it to a SceneGraphNode that only displays coordinate axes. The position of the
-- coordinate axes are determined by SPICE, in this case pretending that the axes are
-- applies it to a scene graph node that only displays coordinate axes. The position of
-- the coordinate axes are determined by SPICE, in this case pretending that the axes are
-- orbiting the same way the Moon does around Earth.
-- For more information about SPICE see: https://naif.jpl.nasa.gov/naif/
@@ -1,7 +1,7 @@
-- Fixed Date
-- This asset creates a time-varying translation with information from a SPICE kernel and
-- applies it to a SceneGraphNode that only displays coordinate axes. The position of the
-- coordinate axes are determined by SPICE, in this case pretending that the axes are
-- applies it to a scene graph node that only displays coordinate axes. The position of
-- the coordinate axes are determined by SPICE, in this case pretending that the axes are
-- orbiting the same way the Moon does around Earth. In this specific example, the
-- position is independent of the actual in-game time in OpenSpace and only uses a fixed
-- date of 2000 JAN 01 instead.
@@ -1,7 +1,7 @@
-- Reference Frame
-- This asset creates a time-varying translation with information from a SPICE kernel and
-- applies it to a SceneGraphNode that only displays coordinate axes. The position of the
-- coordinate axes are determined by SPICE, in this case pretending that the axes are
-- applies it to a scene graph node that only displays coordinate axes. The position of
-- the coordinate axes are determined by SPICE, in this case pretending that the axes are
-- orbiting the same way the Moon does around Earth. The calculated position will be
-- provided in the rotating coordinate system of Earth itself.
-- For more information about SPICE see: https://naif.jpl.nasa.gov/naif/
@@ -1,7 +1,7 @@
-- Fixed Date
-- This asset creates a time-varying translation with information from a SPICE kernel and
-- applies it to a SceneGraphNode that only displays coordinate axes. The position of the
-- coordinate axes are determined by SPICE, in this case pretending that the axes are
-- applies it to a scene graph node that only displays coordinate axes. The position of
-- the coordinate axes are determined by SPICE, in this case pretending that the axes are
-- orbiting the same way the Moon does around Earth. In this specific example, the position
-- is offset 8h back compared to the actual in-game time in OpenSpace.
-- For more information about SPICE see: https://naif.jpl.nasa.gov/naif/
@@ -0,0 +1,48 @@
-- Basic
-- This asset creates a scene graph node that only displays coordinate axes whose
-- translation of the coordinate axes is determined by a timeline of individual
-- translations. These translations are provided as keyframes that interpolate seamlessly
-- between different positions.
--
-- This example will only work if the in-game time is set to January 1st, 2000.
local Node = {
Identifier = "TimelineTranslation_Example",
Transform = {
Translation = {
Type = "TimelineTranslation",
Keyframes = {
-- The first timeline entry
["2000 JAN 01 00:00:00"] = {
Type = "StaticTranslation",
Position = { -10.0, 0.0, 0.0 }
},
-- The second timeline entry
["2000 JAN 01 12:00:00"] = {
Type = "StaticTranslation",
Position = { 0.0, 0.0, 0.0 }
},
-- The third timeline entry
["2000 JAN 01 23:59:59"] = {
Type = "StaticTranslation",
Position = { 10.0, 0.0, 0.0 }
}
}
}
},
Renderable = {
Type = "RenderableCartesianAxes"
},
GUI = {
Name = "TimelineTranslation - Basic",
Path = "/Examples"
}
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Node)
end)
asset.onDeinitialize(function()
openspace.removeSceneGraphNode(Node)
end)
@@ -0,0 +1,55 @@
-- No Interpolation
-- This asset creates a scene graph node that only displays coordinate axes whose
-- translation of the coordinate axes is determined by a timeline of individual
-- translations that are used without interpolating between the timeline entries. These
-- translations are keyframes that are used to change between different positions.
--
-- This example transitions between three positions. In this example, the interpolation
-- between entries is disabled, which will cause the coordinate axes to change their
-- position abruptly when the translation changes. If the interpolation were enabled, the
-- orientation of the coordinate axes would transition seamlessly instead at the provided
-- times.
--
-- This example will only work if the in-game time is set to January 1st, 2000.
local Node = {
Identifier = "TimelineTranslation_Example_NoInterpolation",
Transform = {
Translation = {
Type = "TimelineTranslation",
Keyframes = {
-- The first timeline entry
["2000 JAN 01 00:00:00"] = {
Type = "StaticTranslation",
Position = { -10.0, 0.0, 0.0 }
},
-- The second timeline entry
["2000 JAN 01 12:00:00"] = {
Type = "StaticTranslation",
Position = { 0.0, 0.0, 0.0 }
},
-- The third timeline entry
["2000 JAN 01 23:59:59"] = {
Type = "StaticTranslation",
Position = { 10.0, 0.0, 0.0 }
}
},
ShouldInterpolate = false
}
},
Renderable = {
Type = "RenderableCartesianAxes"
},
GUI = {
Name = "TimelineTranslation - No Interpolation",
Path = "/Examples"
}
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Node)
end)
asset.onDeinitialize(function()
openspace.removeSceneGraphNode(Node)
end)
+1 -2
View File
@@ -42,8 +42,7 @@ local LightPollutionSphere = {
Orientation = "Inside",
MirrorTexture = true,
FadeOutThreshold = 1.00,
RenderBinMode = "PostDeferredTransparent",
Enabled = asset.enabled
RenderBinMode = "PostDeferredTransparent"
},
GUI = {
Name = "Light Pollution Sphere",
@@ -23,7 +23,9 @@ local Object = {
Texture = textures .. "mwHalpha-f.png",
Orientation = "Inside",
MirrorTexture = true,
FadeOutThreshold = 0.025
FadeOutThreshold = 0.025,
BlendingOption = "Additive",
DisableDepth = true
},
GUI = {
Name = "Hydrogen Alpha",

Some files were not shown because too many files have changed in this diff Show More