mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-04-30 15:59:37 -05:00
Merge branch 'master' into project/b612-asteroid-uncertainty
This commit is contained in:
+6
-1
@@ -41,7 +41,12 @@
|
||||
[submodule "support/doxygen/css"]
|
||||
path = support/doxygen/css
|
||||
url = https://github.com/jothepro/doxygen-awesome-css.git
|
||||
|
||||
[submodule "modules/audio/ext/soloud"]
|
||||
path = modules/audio/ext/soloud
|
||||
url = https://github.com/jarikomppa/soloud
|
||||
[submodule "modules/opensoundcontrol/ext/oscpack"]
|
||||
path = modules/opensoundcontrol/ext/oscpack
|
||||
url = https://github.com/OpenSpace/oscpack.git
|
||||
[submodule "ext/json"]
|
||||
path = ext/json
|
||||
url = https://github.com/nlohmann/json
|
||||
|
||||
+3
-3
@@ -157,15 +157,15 @@ add_custom_target(
|
||||
ALL DEPENDS
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/__codegen.h"
|
||||
)
|
||||
add_dependencies(run_codegen codegen)
|
||||
add_dependencies(run_codegen codegen-tool)
|
||||
add_custom_command(
|
||||
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/__codegen.h"
|
||||
COMMAND codegen ARGS "modules" "src"
|
||||
COMMAND codegen-tool ARGS "modules" "src"
|
||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||
VERBATIM
|
||||
)
|
||||
set_target_properties(codegen-lib PROPERTIES FOLDER "support")
|
||||
set_target_properties(codegen PROPERTIES FOLDER "support")
|
||||
set_target_properties(codegen-tool PROPERTIES FOLDER "support")
|
||||
set_target_properties(run_codegen PROPERTIES FOLDER "support")
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <ghoul/ghoul.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int main(int, char** argv) {
|
||||
using namespace openspace;
|
||||
|
||||
ghoul::logging::LogManager::initialize(
|
||||
|
||||
@@ -113,6 +113,7 @@ begin_header("Dependency: SGCT")
|
||||
set(SGCT_TEXT OFF CACHE BOOL "" FORCE)
|
||||
set(SGCT_DEP_INCLUDE_FREETYPE OFF CACHE BOOL "" FORCE)
|
||||
set(SGCT_DEP_INCLUDE_FMT OFF CACHE BOOL "" FORCE)
|
||||
set(SGCT_DEP_INCLUDE_JSON OFF CACHE BOOL "" FORCE)
|
||||
set(SGCT_DEP_INCLUDE_SCN OFF CACHE BOOL "" FORCE)
|
||||
set(SGCT_DEP_INCLUDE_CATCH2 OFF CACHE BOOL "" FORCE)
|
||||
|
||||
|
||||
@@ -28,8 +28,10 @@ set(HEADER_FILES
|
||||
include/backgroundimage.h
|
||||
include/filesystemaccess.h
|
||||
include/launcherwindow.h
|
||||
include/notificationwindow.h
|
||||
include/settingsdialog.h
|
||||
include/splitcombobox.h
|
||||
include/usericon.h
|
||||
include/windowcolors.h
|
||||
include/profile/actiondialog.h
|
||||
include/profile/additionalscriptsdialog.h
|
||||
@@ -59,8 +61,10 @@ set(SOURCE_FILES
|
||||
src/backgroundimage.cpp
|
||||
src/launcherwindow.cpp
|
||||
src/filesystemaccess.cpp
|
||||
src/notificationwindow.cpp
|
||||
src/settingsdialog.cpp
|
||||
src/splitcombobox.cpp
|
||||
src/usericon.cpp
|
||||
src/windowcolors.cpp
|
||||
src/profile/actiondialog.cpp
|
||||
src/profile/additionalscriptsdialog.cpp
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___NOTIFICATIONWINDOW___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___NOTIFICATIONWINDOW___H__
|
||||
|
||||
#include <QTextEdit>
|
||||
|
||||
#include <openspace/util/httprequest.h>
|
||||
#include <memory>
|
||||
|
||||
class NotificationWindow final : public QTextEdit {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit NotificationWindow(QWidget* parent);
|
||||
|
||||
private:
|
||||
std::unique_ptr<openspace::HttpMemoryDownload> _request;
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___NOTIFICATIONWINDOW___H__
|
||||
@@ -0,0 +1,28 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <QIcon>
|
||||
|
||||
// Creates an icon that is used to represent user-generated content
|
||||
QIcon userIcon();
|
||||
@@ -27,7 +27,7 @@ LauncherWindow QLabel {
|
||||
}
|
||||
|
||||
LauncherWindow QLabel#label_choose, QLabel#label_options {
|
||||
color: rgb(255, 255, 255);
|
||||
color: white;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
@@ -37,11 +37,11 @@ LauncherWindow QLabel#clear {
|
||||
|
||||
LauncherWindow QLabel#version-info {
|
||||
font-size: 10pt;
|
||||
color: #dfdfdf;
|
||||
color: rgb(225, 225, 225);
|
||||
}
|
||||
|
||||
LauncherWindow QComboBox#config {
|
||||
background: rgb(86, 86, 86);
|
||||
background: rgb(96, 96, 96);
|
||||
border: 1px solid rgb(225, 225, 225);
|
||||
border-radius: 2px;
|
||||
padding: 1px 18px 1px 3px;
|
||||
@@ -49,7 +49,7 @@ LauncherWindow QComboBox#config {
|
||||
font-size: 10pt;
|
||||
font-family: Segoe UI;
|
||||
font-weight: bold;
|
||||
color: rgb(255, 255, 255);
|
||||
color: white;
|
||||
}
|
||||
|
||||
LauncherWindow QComboBox#config:hover {
|
||||
@@ -61,6 +61,17 @@ LauncherWindow QComboBox#config:disabled {
|
||||
color: rgb(225, 225, 225);
|
||||
}
|
||||
|
||||
LauncherWindow QMenu#newprofile {
|
||||
background: rgb(60, 60, 60);
|
||||
min-width: 8em;
|
||||
max-width: 8em;
|
||||
color: white;
|
||||
}
|
||||
|
||||
LauncherWindow QMenu#newprofile::item:selected {
|
||||
background: rgb(110, 110, 110);
|
||||
}
|
||||
|
||||
LauncherWindow QPushButton#start {
|
||||
background: rgb(96, 96, 96);
|
||||
border: 2px solid rgb(225, 225, 225);
|
||||
@@ -69,34 +80,34 @@ LauncherWindow QPushButton#start {
|
||||
font-size: 16pt;
|
||||
font-weight: bold;
|
||||
letter-spacing: 1px;
|
||||
color: rgb(255, 255, 255);
|
||||
color: white;
|
||||
}
|
||||
LauncherWindow QPushButton#start:hover {
|
||||
background: rgb(120, 120, 120);
|
||||
background: rgb(110, 110, 110);
|
||||
}
|
||||
LauncherWindow QPushButton#start:disabled {
|
||||
background: rgb(175, 175, 175);
|
||||
color: rgb(225, 225, 225);
|
||||
background: rgb(60, 60, 60);
|
||||
border: 1px solid rgb(60, 60, 60);
|
||||
color: rgb(90, 90, 90);
|
||||
}
|
||||
|
||||
LauncherWindow QPushButton#small {
|
||||
background: rgb(86, 86, 86);
|
||||
background: rgb(90, 90, 90);
|
||||
border: 1px solid rgb(225, 225, 225);
|
||||
border-radius: 2px;
|
||||
border-style: outset;
|
||||
min-height: 1em;
|
||||
font-size: 10pt;
|
||||
font-weight: bold;
|
||||
color: rgb(255, 255, 255);
|
||||
color: white;
|
||||
}
|
||||
|
||||
LauncherWindow QPushButton#small:hover {
|
||||
background: rgb(110, 110, 110);
|
||||
}
|
||||
|
||||
LauncherWindow QPushButton#small:disabled {
|
||||
background: rgb(204, 204, 204);
|
||||
color: rgb(86, 86, 86);
|
||||
background: rgb(60, 60, 60);
|
||||
border: 1px solid rgb(60, 60, 60);
|
||||
color: rgb(90, 90, 90);
|
||||
}
|
||||
|
||||
LauncherWindow QPushButton#settings {
|
||||
@@ -119,6 +130,12 @@ LauncherWindow QComboBox#config:focus
|
||||
LauncherWindow QPushButton#settings:focus {
|
||||
outline: 2px solid rgb(61, 189, 238);
|
||||
}
|
||||
|
||||
LauncherWindow QTextEdit#notifications {
|
||||
background-color: #242424;
|
||||
color: #d7d7d7;
|
||||
}
|
||||
|
||||
/*
|
||||
* ProfileEdit
|
||||
*/
|
||||
@@ -195,6 +212,10 @@ ScriptlogDialog QListWidget {
|
||||
min-width: 60em;
|
||||
}
|
||||
|
||||
MarkNodesDialog QListWidget:focus {
|
||||
border: 2px solid rgb(61, 189, 238);
|
||||
}
|
||||
|
||||
/*
|
||||
* Horizons dialog
|
||||
*/
|
||||
@@ -211,7 +232,7 @@ HorizonsDialog QLabel#thin {
|
||||
}
|
||||
|
||||
HorizonsDialog QLabel#normal {
|
||||
color: rgb(0, 0, 0);
|
||||
color: black;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "profile/profileedit.h"
|
||||
#include "backgroundimage.h"
|
||||
#include "notificationwindow.h"
|
||||
#include "settingsdialog.h"
|
||||
#include "splitcombobox.h"
|
||||
#include <openspace/openspace.h>
|
||||
@@ -35,6 +36,7 @@
|
||||
#include <QFile>
|
||||
#include <QKeyEvent>
|
||||
#include <QLabel>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QStandardItemModel>
|
||||
@@ -45,8 +47,10 @@
|
||||
using namespace openspace;
|
||||
|
||||
namespace {
|
||||
constexpr int ScreenWidth = 480;
|
||||
constexpr int ScreenHeight = 640;
|
||||
constexpr int MainScreenWidth = 480;
|
||||
constexpr int MainScreenHeight = 640;
|
||||
constexpr int FullScreenWidth = MainScreenWidth;
|
||||
constexpr int FullScreenHeight = 706;
|
||||
|
||||
constexpr int LeftRuler = 40;
|
||||
constexpr int TopRuler = 80;
|
||||
@@ -55,10 +59,12 @@ namespace {
|
||||
constexpr int SmallItemWidth = 100;
|
||||
constexpr int SmallItemHeight = SmallItemWidth / 4;
|
||||
|
||||
constexpr int NotificationShelfHeight = FullScreenHeight - MainScreenHeight;
|
||||
|
||||
constexpr int SettingsIconSize = 35;
|
||||
|
||||
namespace geometry {
|
||||
constexpr QRect BackgroundImage(0, 0, ScreenWidth, ScreenHeight);
|
||||
constexpr QRect BackgroundImage(0, 0, MainScreenWidth, MainScreenHeight);
|
||||
constexpr QRect LogoImage(LeftRuler, TopRuler, ItemWidth, ItemHeight);
|
||||
constexpr QRect ChooseLabel(LeftRuler + 10, TopRuler + 80, 151, 24);
|
||||
constexpr QRect ProfileBox(LeftRuler, TopRuler + 110, ItemWidth, ItemHeight);
|
||||
@@ -80,14 +86,19 @@ namespace {
|
||||
LeftRuler, TopRuler + 400, ItemWidth, ItemHeight
|
||||
);
|
||||
constexpr QRect VersionString(
|
||||
5, ScreenHeight - SmallItemHeight, ItemWidth, SmallItemHeight
|
||||
5, MainScreenHeight - SmallItemHeight, ItemWidth, SmallItemHeight
|
||||
);
|
||||
constexpr QRect SettingsButton(
|
||||
ScreenWidth - SettingsIconSize - 5,
|
||||
ScreenHeight - SettingsIconSize - 5,
|
||||
MainScreenWidth - SettingsIconSize - 5,
|
||||
MainScreenHeight - SettingsIconSize - 5,
|
||||
SettingsIconSize,
|
||||
SettingsIconSize
|
||||
);
|
||||
constexpr QRect NotificationShelf(
|
||||
0,
|
||||
MainScreenHeight,
|
||||
MainScreenWidth,
|
||||
NotificationShelfHeight);
|
||||
} // namespace geometry
|
||||
|
||||
|
||||
@@ -132,7 +143,7 @@ LauncherWindow::LauncherWindow(bool profileEnabled, const Configuration& globalC
|
||||
);
|
||||
|
||||
setWindowTitle("OpenSpace Launcher");
|
||||
setFixedSize(ScreenWidth, ScreenHeight);
|
||||
setFixedSize(FullScreenWidth, FullScreenHeight);
|
||||
setAutoFillBackground(false);
|
||||
|
||||
{
|
||||
@@ -163,6 +174,12 @@ LauncherWindow::LauncherWindow(bool profileEnabled, const Configuration& globalC
|
||||
logoImage->setPixmap(QPixmap(":/images/openspace-horiz-logo-small.png"));
|
||||
}
|
||||
|
||||
{
|
||||
NotificationWindow* notificationWindow = new NotificationWindow(centralWidget);
|
||||
notificationWindow->setGeometry(geometry::NotificationShelf);
|
||||
notificationWindow->show();
|
||||
}
|
||||
|
||||
//
|
||||
// Profile chooser
|
||||
//
|
||||
@@ -173,30 +190,6 @@ LauncherWindow::LauncherWindow(bool profileEnabled, const Configuration& globalC
|
||||
labelChoose->setObjectName("label_choose");
|
||||
}
|
||||
|
||||
_editProfileButton = new QPushButton("Edit", centralWidget);
|
||||
_editProfileButton->setObjectName("small");
|
||||
_editProfileButton->setGeometry(geometry::EditProfileButton);
|
||||
_editProfileButton->setCursor(Qt::PointingHandCursor);
|
||||
_editProfileButton->setAutoDefault(true);
|
||||
_editProfileButton->setAccessibleName("Edit profile");
|
||||
connect(
|
||||
_editProfileButton, &QPushButton::released,
|
||||
this, &LauncherWindow::editProfile
|
||||
);
|
||||
|
||||
{
|
||||
QPushButton* newProfileButton = new QPushButton("New", centralWidget);
|
||||
newProfileButton->setObjectName("small");
|
||||
newProfileButton->setGeometry(geometry::NewProfileButton);
|
||||
newProfileButton->setCursor(Qt::PointingHandCursor);
|
||||
newProfileButton->setAutoDefault(true);
|
||||
newProfileButton->setAccessibleName("New profile");
|
||||
connect(
|
||||
newProfileButton, &QPushButton::released,
|
||||
this, &LauncherWindow::newProfile
|
||||
);
|
||||
}
|
||||
|
||||
// Creating the profile box _after_ the Edit and New buttons as the comboboxes
|
||||
// `selectionChanged` signal will trigger that will try to make changes to the edit
|
||||
// button
|
||||
@@ -222,8 +215,8 @@ LauncherWindow::LauncherWindow(bool profileEnabled, const Configuration& globalC
|
||||
_profileBox->setObjectName("config");
|
||||
_profileBox->setGeometry(geometry::ProfileBox);
|
||||
_profileBox->setAccessibleName("Choose profile");
|
||||
_profileBox->populateList(globalConfig.profile);
|
||||
_profileBox->setEnabled(profileEnabled);
|
||||
_profileBox->populateList(globalConfig.profile);
|
||||
connect(
|
||||
_profileBox, &SplitComboBox::selectionChanged,
|
||||
this, &LauncherWindow::selectProfile
|
||||
@@ -233,12 +226,58 @@ LauncherWindow::LauncherWindow(bool profileEnabled, const Configuration& globalC
|
||||
this, &LauncherWindow::updateStartButton
|
||||
);
|
||||
|
||||
|
||||
_editProfileButton = new QPushButton("Edit", centralWidget);
|
||||
_editProfileButton->setObjectName("small");
|
||||
_editProfileButton->setGeometry(geometry::EditProfileButton);
|
||||
_editProfileButton->setCursor(Qt::PointingHandCursor);
|
||||
_editProfileButton->setAutoDefault(true);
|
||||
_editProfileButton->setAccessibleName("Edit profile");
|
||||
connect(
|
||||
_editProfileButton, &QPushButton::released,
|
||||
this, &LauncherWindow::editProfile
|
||||
);
|
||||
{
|
||||
// Set up the default value for the edit button
|
||||
std::string selection = std::get<1>(_profileBox->currentSelection());
|
||||
_editProfileButton->setEnabled(std::filesystem::exists(selection));
|
||||
}
|
||||
|
||||
{
|
||||
QPushButton* newProfileButton = new QPushButton("New", centralWidget);
|
||||
newProfileButton->setObjectName("small");
|
||||
newProfileButton->setGeometry(geometry::NewProfileButton);
|
||||
newProfileButton->setCursor(Qt::PointingHandCursor);
|
||||
newProfileButton->setAutoDefault(true);
|
||||
newProfileButton->setAccessibleName("New profile");
|
||||
connect(
|
||||
newProfileButton, &QPushButton::released,
|
||||
this, &LauncherWindow::newProfile
|
||||
);
|
||||
|
||||
QMenu* menu = new QMenu(this);
|
||||
menu->setObjectName("newprofile");
|
||||
menu->setToolTipsVisible(true);
|
||||
QAction* newEmpty = new QAction("Empty profile", this);
|
||||
newEmpty->setToolTip("Creates a new empty profile without any existing content");
|
||||
connect(
|
||||
newEmpty, &QAction::triggered,
|
||||
this, &LauncherWindow::newProfile
|
||||
);
|
||||
QAction* newFromCurrent = new QAction("Duplicate profile", this);
|
||||
newFromCurrent->setToolTip(
|
||||
"Creates a duplicate of the currently selected profile. This duplicate can "
|
||||
"be edited and saved under a new name, or if it was a user profile be "
|
||||
"overwritten"
|
||||
);
|
||||
connect(
|
||||
newFromCurrent, &QAction::triggered,
|
||||
this, &LauncherWindow::editProfile
|
||||
);
|
||||
menu->addActions({ newEmpty, newFromCurrent });
|
||||
newProfileButton->setMenu(menu);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
@@ -250,31 +289,6 @@ LauncherWindow::LauncherWindow(bool profileEnabled, const Configuration& globalC
|
||||
optionsLabel->setObjectName("label_options");
|
||||
}
|
||||
|
||||
_editWindowButton = new QPushButton("Edit", centralWidget);
|
||||
_editWindowButton->setVisible(true);
|
||||
_editWindowButton->setObjectName("small");
|
||||
_editWindowButton->setGeometry(geometry::EditWindowButton);
|
||||
_editWindowButton->setCursor(Qt::PointingHandCursor);
|
||||
_editWindowButton->setAutoDefault(true);
|
||||
_editWindowButton->setAccessibleName("Edit window configuration");
|
||||
connect(
|
||||
_editWindowButton, &QPushButton::released,
|
||||
this, &LauncherWindow::editConfiguration
|
||||
);
|
||||
|
||||
{
|
||||
QPushButton* newWindowButton = new QPushButton("New", centralWidget);
|
||||
newWindowButton->setObjectName("small");
|
||||
newWindowButton->setGeometry(geometry::NewWindowButton);
|
||||
newWindowButton->setCursor(Qt::PointingHandCursor);
|
||||
newWindowButton->setAutoDefault(true);
|
||||
newWindowButton->setAccessibleName("New window configuration");
|
||||
connect(
|
||||
newWindowButton, &QPushButton::released,
|
||||
this, &LauncherWindow::newConfiguration
|
||||
);
|
||||
}
|
||||
|
||||
_windowConfigBox = new SplitComboBox(
|
||||
centralWidget,
|
||||
_userConfigPath,
|
||||
@@ -313,11 +327,36 @@ LauncherWindow::LauncherWindow(bool profileEnabled, const Configuration& globalC
|
||||
this, &LauncherWindow::updateStartButton
|
||||
);
|
||||
|
||||
|
||||
|
||||
_editWindowButton = new QPushButton("Edit", centralWidget);
|
||||
_editWindowButton->setVisible(true);
|
||||
_editWindowButton->setObjectName("small");
|
||||
_editWindowButton->setGeometry(geometry::EditWindowButton);
|
||||
_editWindowButton->setCursor(Qt::PointingHandCursor);
|
||||
_editWindowButton->setAutoDefault(true);
|
||||
_editWindowButton->setAccessibleName("Edit window configuration");
|
||||
connect(
|
||||
_editWindowButton, &QPushButton::released,
|
||||
this, &LauncherWindow::editConfiguration
|
||||
);
|
||||
{
|
||||
// Set up the default value for the edit button
|
||||
std::string selection = std::get<1>(_windowConfigBox->currentSelection());
|
||||
_editWindowButton->setEnabled(std::filesystem::exists(selection));
|
||||
}
|
||||
{
|
||||
QPushButton* newWindowButton = new QPushButton("New", centralWidget);
|
||||
newWindowButton->setObjectName("small");
|
||||
newWindowButton->setGeometry(geometry::NewWindowButton);
|
||||
newWindowButton->setCursor(Qt::PointingHandCursor);
|
||||
newWindowButton->setAutoDefault(true);
|
||||
newWindowButton->setAccessibleName("New window configuration");
|
||||
connect(
|
||||
newWindowButton, &QPushButton::released,
|
||||
this, &LauncherWindow::newConfiguration
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
@@ -391,7 +430,19 @@ void LauncherWindow::selectProfile(std::optional<std::string> selection) {
|
||||
ghoul_assert(selection.has_value(), "No special item in the profiles");
|
||||
if (selection.has_value()) {
|
||||
// Having the `if` statement here to satisfy the MSVC code analysis
|
||||
_editProfileButton->setEnabled(std::filesystem::exists(*selection));
|
||||
|
||||
// Enable the Edit button only for the user profiles
|
||||
const bool isUser = selection->starts_with(_userProfilePath.string());
|
||||
_editProfileButton->setEnabled(isUser);
|
||||
|
||||
if (isUser) {
|
||||
_editProfileButton->setToolTip("");
|
||||
}
|
||||
else {
|
||||
_editProfileButton->setToolTip(
|
||||
"Cannot edit the selected profile as it is one of the built-in profiles"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,8 +458,7 @@ void LauncherWindow::selectConfiguration(std::optional<std::string> selection) {
|
||||
// If the configuration is a default configuration, we don't allow editing
|
||||
_editWindowButton->setEnabled(false);
|
||||
_editWindowButton->setToolTip(
|
||||
"Cannot edit since the selected configuration is one of the files "
|
||||
"provided by OpenSpace"
|
||||
"Cannot edit the selected configuration as it is one of the built-in profiles"
|
||||
);
|
||||
}
|
||||
else {
|
||||
@@ -598,19 +648,21 @@ void LauncherWindow::openProfileEditor(const std::string& profile, bool isUserPr
|
||||
&ProfileEdit::raiseExitWindow,
|
||||
[&editor, &savePath, &p, &profile]() {
|
||||
const std::string origPath = std::format("{}{}.profile", savePath, profile);
|
||||
// If this is a new profile we want to prompt the user
|
||||
if (!std::filesystem::exists(origPath)) {
|
||||
// If this is a new profile we want to prompt the user, but only if the user
|
||||
// actually changed something. If it is still an empty profile, there is no
|
||||
// need to save it
|
||||
if (!std::filesystem::exists(origPath) && *p != Profile()) {
|
||||
editor.promptUserOfUnsavedChanges();
|
||||
return;
|
||||
}
|
||||
// Check if the profile is the same as current existing file
|
||||
if (std::filesystem::exists(origPath) && *p != Profile(origPath)) {
|
||||
editor.promptUserOfUnsavedChanges();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the profile is the same as current existing file
|
||||
if (*p != Profile(origPath)) {
|
||||
editor.promptUserOfUnsavedChanges();
|
||||
}
|
||||
else {
|
||||
editor.closeWithoutSaving();
|
||||
}
|
||||
// If we got this far, we can safely close the dialog without saving anything
|
||||
editor.closeWithoutSaving();
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 "notificationwindow.h"
|
||||
|
||||
#include <openspace/openspace.h>
|
||||
#include <openspace/engine/settings.h>
|
||||
#include <openspace/util/httprequest.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
#include <ghoul/misc/stringhelper.h>
|
||||
#include <QGuiApplication>
|
||||
#include <QStyleHints>
|
||||
#include <QTimer>
|
||||
#include <scn/scan.h>
|
||||
#include <date/date.h>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
using namespace openspace;
|
||||
|
||||
namespace {
|
||||
struct Entry {
|
||||
std::string date;
|
||||
std::string text;
|
||||
};
|
||||
|
||||
// Parses a single notification entry out of the list of lines
|
||||
Entry parseEntry(std::vector<std::string>::const_iterator& curr) {
|
||||
ghoul_assert(!curr->empty(), "First line must not be empty");
|
||||
|
||||
std::string date = *curr;
|
||||
std::string text;
|
||||
do {
|
||||
curr++;
|
||||
|
||||
text += *curr;
|
||||
} while (!curr->empty());
|
||||
curr++;
|
||||
|
||||
return { std::move(date), std::move(text) };
|
||||
}
|
||||
|
||||
std::vector<Entry> parseEntries(const std::string& data) {
|
||||
std::vector<Entry> entries;
|
||||
|
||||
std::vector<std::string> lines = ghoul::tokenizeString(data, '\n');
|
||||
if (lines.empty() || lines[0].empty()) {
|
||||
// The notification file is empty and we don't want to show anything
|
||||
return entries;
|
||||
}
|
||||
|
||||
std::vector<std::string>::const_iterator curr = lines.cbegin();
|
||||
while (curr != lines.end()) {
|
||||
Entry e = parseEntry(curr);
|
||||
entries.push_back(std::move(e));
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
std::string formatEntry(const Entry& e, date::year_month_day lastStartedDate) {
|
||||
auto r = scn::scan<int, int, int>(e.date, "{}-{}-{}");
|
||||
ghoul_assert(r, "Invalid date");
|
||||
auto& [year, month, day] = r->values();
|
||||
const date::year_month_day ymd = date::year_month_day(
|
||||
date::year(year),
|
||||
date::month(month),
|
||||
date::day(day)
|
||||
);
|
||||
|
||||
QColor text = QGuiApplication::palette().text().color();
|
||||
text = text.darker();
|
||||
|
||||
if (date::sys_days(ymd) < date::sys_days(lastStartedDate)) {
|
||||
const QColor textColor = QColor(120, 120, 120);
|
||||
return std::format(
|
||||
"<tr>"
|
||||
"<td width='15%'>"
|
||||
"<font color='#{2:x}{3:x}{4:x}'>{0}</font>"
|
||||
"</td>"
|
||||
"<td width='85%' align='left'>"
|
||||
"<font color='#{2:x}{3:x}{4:x}'>{1}</font>"
|
||||
"</td>"
|
||||
"</tr>",
|
||||
e.date, e.text, textColor.red(), textColor.green(), textColor.blue()
|
||||
);
|
||||
}
|
||||
else {
|
||||
return std::format(
|
||||
"<tr>"
|
||||
"<td width='15%'>"
|
||||
"{0}"
|
||||
"</td>"
|
||||
"<td width='85%' align='left'>"
|
||||
"{1}"
|
||||
"</td>"
|
||||
"</tr>",
|
||||
e.date, e.text
|
||||
);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
NotificationWindow::NotificationWindow(QWidget* parent)
|
||||
: QTextEdit(parent)
|
||||
{
|
||||
setAcceptRichText(true);
|
||||
setReadOnly(true);
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
setObjectName("notifications");
|
||||
|
||||
std::string URL = std::format(
|
||||
"https://raw.githubusercontent.com/OpenSpace/Notifications/refs/heads/master/"
|
||||
"{}.txt",
|
||||
OPENSPACE_IS_RELEASE_BUILD ? OPENSPACE_VERSION_NUMBER : "master"
|
||||
);
|
||||
|
||||
_request = std::make_unique<HttpMemoryDownload>(
|
||||
URL,
|
||||
ghoul::logging::LogLevel::NoLogging
|
||||
);
|
||||
_request->start(std::chrono::seconds(1));
|
||||
|
||||
// The download has a timeout of 1s, so after 1250ms we'll definitely have answer.
|
||||
constexpr int TimeOut = 1250;
|
||||
QTimer::singleShot(TimeOut, [this](){
|
||||
while (!_request->hasSucceeded() && !_request->hasFailed()) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
}
|
||||
if (_request->hasFailed()) {
|
||||
LWARNINGC("Notification", "Failed to retrieve notification file");
|
||||
// The download has failed for some reason
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. Get the downloaded data
|
||||
const std::vector<char>& data = _request->downloadedData();
|
||||
std::string notificationText = std::string(data.begin(), data.end());
|
||||
|
||||
// 2. Parse the retrieved data into entries
|
||||
std::vector<Entry> entries = parseEntries(notificationText);
|
||||
|
||||
// 3. Filter the entries to not show anything that is older than 6 months
|
||||
const date::year_month_day now = date::year_month_day(
|
||||
floor<date::days>(std::chrono::system_clock::now())
|
||||
);
|
||||
std::erase_if(
|
||||
entries,
|
||||
[now](const Entry& e) {
|
||||
auto r = scn::scan<int, int, int>(e.date, "{}-{}-{}");
|
||||
if (!r) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& [year, month, day] = r->values();
|
||||
|
||||
const date::year_month_day ymd = date::year_month_day(
|
||||
date::year(year),
|
||||
date::month(month),
|
||||
date::day(day)
|
||||
);
|
||||
|
||||
const std::chrono::days diff = date::sys_days(now) - date::sys_days(ymd);
|
||||
const bool older = diff.count() > (365 / 2);
|
||||
return older;
|
||||
}
|
||||
);
|
||||
|
||||
// 4. Format the entries into a table format
|
||||
Settings settings = loadSettings();
|
||||
// Picking a date as the default date that is far enough in the past
|
||||
date::year_month_day lastStart = date::year_month_day(
|
||||
date::year(2000),
|
||||
date::month(1),
|
||||
date::day(1)
|
||||
);
|
||||
if (settings.lastStartedDate.has_value()) {
|
||||
auto r = scn::scan<int, int, int>(*settings.lastStartedDate, "{}-{}-{}");
|
||||
if (r) {
|
||||
auto& [year, month, day] = r->values();
|
||||
|
||||
lastStart = date::year_month_day(
|
||||
date::year(year),
|
||||
date::month(month),
|
||||
date::day(day)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
std::string text = std::accumulate(
|
||||
entries.begin(),
|
||||
entries.end(),
|
||||
std::string(),
|
||||
[&lastStart](std::string t, const Entry& e) {
|
||||
return std::format(
|
||||
"{}{}",
|
||||
std::move(t), formatEntry(e, lastStart)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Add the HTML-like table attributes
|
||||
text = std::format("<table border='0'>{}</table>", std::move(text));
|
||||
|
||||
// 5. Set the text
|
||||
QString t = QString::fromStdString(text);
|
||||
setText(t);
|
||||
});
|
||||
}
|
||||
@@ -917,7 +917,7 @@ openspace::HorizonsFile HorizonsDialog::handleAnswer(nlohmann::json& answer) {
|
||||
}
|
||||
|
||||
// Return a new file with the result
|
||||
return openspace::HorizonsFile(filePath, *result);
|
||||
return openspace::HorizonsFile(filePath, result->get<std::string>());
|
||||
}
|
||||
|
||||
bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
|
||||
@@ -1084,6 +1084,23 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
|
||||
std::filesystem::remove(_horizonsFile.file());
|
||||
break;
|
||||
}
|
||||
case HorizonsResultCode::News: {
|
||||
std::string msg = std::format(
|
||||
"The target '{}' is too simlar to the Horizons command 'NEWS'",
|
||||
_targetName
|
||||
);
|
||||
appendLog(msg, HorizonsDialog::LogLevel::Error);
|
||||
|
||||
msg = std::format(
|
||||
"Try to use '@{}' as target to avoid false positive matches with the "
|
||||
"Horizons command 'NEWS'", _targetName
|
||||
);
|
||||
appendLog(msg, HorizonsDialog::LogLevel::Info);
|
||||
styleLabel(_targetLabel, IsDirty::Yes);
|
||||
|
||||
std::filesystem::remove(_horizonsFile.file());
|
||||
break;
|
||||
}
|
||||
case HorizonsResultCode::MultipleObserver: {
|
||||
std::string msg = std::format(
|
||||
"Multiple matches were found for observer '{}'", _observerName
|
||||
|
||||
@@ -55,8 +55,8 @@ void SettingsDialog::createWidgets() {
|
||||
// | Profile |
|
||||
// | Starting Profile: | [oooooooooooooooooooo] |
|
||||
// | [] Keep Last Profile |
|
||||
// | Configuration |
|
||||
// | Starting Configuration: | [oooooooooooooooooooo] |
|
||||
// | Window Options |
|
||||
// | Starting Window Option: | [oooooooooooooooooooo] |
|
||||
// | [] Keep Last Configuration |
|
||||
// | User Interface |
|
||||
// | Property Visibility | DDDDDDDDDDDDDDDDDDDDD> |
|
||||
@@ -108,9 +108,14 @@ void SettingsDialog::createWidgets() {
|
||||
"If this setting is checked, the application will remember the profile that "
|
||||
"was loaded into OpenSpace and will use it at the next startup as well"
|
||||
);
|
||||
|
||||
connect(
|
||||
_rememberLastProfile,
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
|
||||
&QCheckBox::checkStateChanged,
|
||||
#else // ^^^^ >=6.7.0 // !WIN32 <6.7.0
|
||||
&QCheckBox::stateChanged,
|
||||
#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
|
||||
[this]() {
|
||||
if (_rememberLastProfile->isChecked()) {
|
||||
_currentEdit.rememberLastProfile = true;
|
||||
@@ -129,11 +134,11 @@ void SettingsDialog::createWidgets() {
|
||||
layout->addWidget(new Line(), 3, 0, 1, 2);
|
||||
|
||||
{
|
||||
QLabel* label = new QLabel("Configuration");
|
||||
QLabel* label = new QLabel("Window Configuration");
|
||||
label->setObjectName("heading");
|
||||
layout->addWidget(label, 4, 0, 1, 2);
|
||||
|
||||
QLabel* conf = new QLabel("Starting Configuration");
|
||||
QLabel* conf = new QLabel("Starting Window Configuration");
|
||||
conf->setToolTip(
|
||||
"With this setting, you can choose a window configuration that will be "
|
||||
"loaded the next time you start the application"
|
||||
@@ -166,7 +171,11 @@ void SettingsDialog::createWidgets() {
|
||||
);
|
||||
connect(
|
||||
_rememberLastConfiguration,
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
|
||||
&QCheckBox::checkStateChanged,
|
||||
#else // ^^^^ >=6.7.0 // !WIN32 <6.7.0
|
||||
&QCheckBox::stateChanged,
|
||||
#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
|
||||
[this]() {
|
||||
if (_rememberLastConfiguration->isChecked()) {
|
||||
_currentEdit.rememberLastConfiguration = true;
|
||||
@@ -241,7 +250,11 @@ void SettingsDialog::createWidgets() {
|
||||
);
|
||||
connect(
|
||||
_bypassLauncher,
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
|
||||
&QCheckBox::checkStateChanged,
|
||||
#else // ^^^^ >=6.7.0 // !WIN32 <6.7.0
|
||||
&QCheckBox::stateChanged,
|
||||
#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
|
||||
[this]() {
|
||||
if (_bypassLauncher->isChecked()) {
|
||||
_currentEdit.bypassLauncher = _bypassLauncher->isChecked();
|
||||
@@ -313,7 +326,11 @@ void SettingsDialog::createWidgets() {
|
||||
);
|
||||
connect(
|
||||
_mrf.isEnabled,
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
|
||||
&QCheckBox::checkStateChanged,
|
||||
#else // ^^^^ >=6.7.0 // !WIN32 <6.7.0
|
||||
&QCheckBox::stateChanged,
|
||||
#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
|
||||
[this]() {
|
||||
if (_mrf.isEnabled->isChecked()) {
|
||||
_currentEdit.mrf.isEnabled = _mrf.isEnabled->isChecked();
|
||||
|
||||
@@ -32,7 +32,7 @@ MonitorBox::MonitorBox(QRect widgetSize, const std::vector<QRect>& monitorResolu
|
||||
QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
constexpr float MarginFractionWidgetSize = 0.05f;
|
||||
constexpr float MarginFractionWidgetSize = 0.02f;
|
||||
|
||||
//
|
||||
// Calculate the collective size of the monitors
|
||||
@@ -132,7 +132,7 @@ void MonitorBox::paintEvent(QPaintEvent*) {
|
||||
_monitorDimensionsScaled[i].top() + 24.0
|
||||
);
|
||||
QFont f = QFont("Arial");
|
||||
f.setPixelSize(24);
|
||||
f.setPixelSize(18);
|
||||
painter.setFont(f);
|
||||
painter.drawText(textPos, "Primary");
|
||||
}
|
||||
@@ -148,6 +148,9 @@ void MonitorBox::paintEvent(QPaintEvent*) {
|
||||
std::clamp(x, 0.0, static_cast<double>(size().width()) - 10.0),
|
||||
std::clamp(y, 20.0, static_cast<double>(size().height()))
|
||||
);
|
||||
QFont f = QFont("Arial");
|
||||
f.setPixelSize(18);
|
||||
painter.setFont(f);
|
||||
painter.drawText(p, QString::number(i + 1));
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ SgctEdit::SgctEdit(sgct::config::Cluster cluster, std::string configName,
|
||||
//
|
||||
// Monitor widget at the top of the window
|
||||
{
|
||||
constexpr QRect MonitorWidgetSize = QRect(0, 0, 500, 500);
|
||||
constexpr QRect MonitorWidgetSize = QRect(0, 0, 350, 350);
|
||||
|
||||
MonitorBox* monitorBox = new MonitorBox(MonitorWidgetSize, monitorSizes);
|
||||
layout->addWidget(monitorBox, 0, Qt::AlignCenter);
|
||||
@@ -131,6 +131,7 @@ SgctEdit::SgctEdit(sgct::config::Cluster cluster, std::string configName,
|
||||
layout->addWidget(settingsContainer);
|
||||
QBoxLayout* settingsLayout = new QVBoxLayout(settingsContainer);
|
||||
settingsLayout->setContentsMargins(0, 0, 0, 0);
|
||||
settingsLayout->setSpacing(0);
|
||||
|
||||
|
||||
//
|
||||
@@ -149,9 +150,6 @@ SgctEdit::SgctEdit(sgct::config::Cluster cluster, std::string configName,
|
||||
|
||||
//
|
||||
// Orientation specification
|
||||
QLabel* labelOrientation = new QLabel("Orientation");
|
||||
settingsLayout->addWidget(labelOrientation);
|
||||
|
||||
QWidget* orientationContainer = new QWidget;
|
||||
settingsLayout->addWidget(orientationContainer);
|
||||
QGridLayout* layoutWindow = new QGridLayout(orientationContainer);
|
||||
@@ -177,9 +175,6 @@ SgctEdit::SgctEdit(sgct::config::Cluster cluster, std::string configName,
|
||||
validatorPitch->setNotation(QDoubleValidator::StandardNotation);
|
||||
_linePitch->setValidator(validatorPitch);
|
||||
layoutWindow->addWidget(_linePitch, 0, 1);
|
||||
|
||||
QLabel* range = new QLabel("Range [-90, 90] in degrees");
|
||||
layoutWindow->addWidget(range, 0, 2);
|
||||
}
|
||||
{
|
||||
const QString rollTip = "Roll or bank: negative numbers rotate the camera "
|
||||
@@ -188,7 +183,7 @@ SgctEdit::SgctEdit(sgct::config::Cluster cluster, std::string configName,
|
||||
|
||||
QLabel* labelRoll = new QLabel("Roll");
|
||||
labelRoll->setToolTip(rollTip);
|
||||
layoutWindow->addWidget(labelRoll, 1, 0);
|
||||
layoutWindow->addWidget(labelRoll, 0, 2);
|
||||
|
||||
_lineRoll = new QLineEdit;
|
||||
_lineRoll->setText(QString::number(glm::degrees(glm::roll(q))));
|
||||
@@ -196,10 +191,7 @@ SgctEdit::SgctEdit(sgct::config::Cluster cluster, std::string configName,
|
||||
QDoubleValidator* validatorRoll = new QDoubleValidator(-360.0, 360.0, 15);
|
||||
validatorRoll->setNotation(QDoubleValidator::StandardNotation);
|
||||
_lineRoll->setValidator(validatorRoll);
|
||||
layoutWindow->addWidget(_lineRoll, 1, 1);
|
||||
|
||||
QLabel* range = new QLabel("Range [-360, 360] in degrees");
|
||||
layoutWindow->addWidget(range, 1, 2);
|
||||
layoutWindow->addWidget(_lineRoll, 0, 3);
|
||||
}
|
||||
{
|
||||
const QString yawTip = "Yaw, heading, or azimuth: negative numbers pan the "
|
||||
@@ -209,7 +201,7 @@ SgctEdit::SgctEdit(sgct::config::Cluster cluster, std::string configName,
|
||||
QLabel* labelYaw = new QLabel;
|
||||
labelYaw->setText("Yaw");
|
||||
labelYaw->setToolTip(yawTip);
|
||||
layoutWindow->addWidget(labelYaw, 2, 0);
|
||||
layoutWindow->addWidget(labelYaw, 0, 4);
|
||||
|
||||
_lineYaw = new QLineEdit;
|
||||
_lineYaw->setText(QString::number(glm::degrees(glm::yaw(q))));
|
||||
@@ -217,10 +209,15 @@ SgctEdit::SgctEdit(sgct::config::Cluster cluster, std::string configName,
|
||||
QDoubleValidator* validatorYaw = new QDoubleValidator(-180.0, 180.0, 15, this);
|
||||
validatorYaw->setNotation(QDoubleValidator::StandardNotation);
|
||||
_lineYaw->setValidator(validatorYaw);
|
||||
layoutWindow->addWidget(_lineYaw, 2, 1);
|
||||
layoutWindow->addWidget(_lineYaw, 0, 5);
|
||||
}
|
||||
|
||||
QLabel* range = new QLabel("Range [-180, 180] in degrees");
|
||||
layoutWindow->addWidget(range, 2, 2);
|
||||
{
|
||||
QLabel* info = new QLabel(
|
||||
"The allowed ranges for pitch is [-90, 90], for roll [-180, 180], and for "
|
||||
"yaw [-360, 360]."
|
||||
);
|
||||
layoutWindow->addWidget(info, 1, 0, 1, 6);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ WindowControl::WindowControl(int monitorIndex, int windowIndex,
|
||||
|
||||
_windowName = new QLineEdit;
|
||||
_windowName->setToolTip(tip);
|
||||
layout->addWidget(_windowName, 1, 1, 1, 7);
|
||||
layout->addWidget(_windowName, 1, 1, 1, 3);
|
||||
}
|
||||
const QString tip = "The monitor where this window is located";
|
||||
|
||||
@@ -188,9 +188,9 @@ WindowControl::WindowControl(int monitorIndex, int windowIndex,
|
||||
// potential nullpointer accesses elsewhere in the code
|
||||
QLabel* labelLocation = new QLabel("Monitor");
|
||||
labelLocation->setToolTip(tip);
|
||||
layout->addWidget(labelLocation, 2, 0);
|
||||
layout->addWidget(labelLocation, 1, 4);
|
||||
|
||||
layout->addWidget(_monitor, 2, 1, 1, 7);
|
||||
layout->addWidget(_monitor, 1, 5, 1, 4);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -24,8 +24,10 @@
|
||||
|
||||
#include "splitcombobox.h"
|
||||
|
||||
#include "usericon.h"
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
#include <QPainter>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
SplitComboBox::SplitComboBox(QWidget* parent, std::filesystem::path userPath,
|
||||
@@ -42,6 +44,8 @@ SplitComboBox::SplitComboBox(QWidget* parent, std::filesystem::path userPath,
|
||||
, _fileFilter(std::move(fileFilter))
|
||||
, _createTooltip(std::move(createTooltip))
|
||||
{
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
|
||||
connect(
|
||||
this,
|
||||
QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
@@ -66,14 +70,25 @@ void SplitComboBox::populateList(const std::string& preset) {
|
||||
// Clear the previously existing entries since we might call this function again
|
||||
clear();
|
||||
|
||||
// Create "icons" that we use to indicate whether an item is built-in or user content
|
||||
QIcon icon = userIcon();
|
||||
|
||||
//
|
||||
// Special item (if it was specified)
|
||||
if (!_specialFirst.empty()) {
|
||||
addItem(
|
||||
QString::fromStdString(_specialFirst),
|
||||
QString::fromStdString(_specialFirst)
|
||||
);
|
||||
if (_specialFirst.starts_with(_userPath.string())) {
|
||||
addItem(
|
||||
icon,
|
||||
QString::fromStdString(_specialFirst),
|
||||
QString::fromStdString(_specialFirst)
|
||||
);
|
||||
}
|
||||
else {
|
||||
addItem(
|
||||
QString::fromStdString(_specialFirst),
|
||||
QString::fromStdString(_specialFirst)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +109,7 @@ void SplitComboBox::populateList(const std::string& preset) {
|
||||
|
||||
// Display the relative path, but store the full path in the user data segment
|
||||
addItem(
|
||||
icon,
|
||||
QString::fromStdString(relPath.string()),
|
||||
QString::fromStdString(p.string())
|
||||
);
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 "usericon.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
QIcon userIcon() {
|
||||
QPixmap px = QPixmap(40, 50);
|
||||
px.fill(Qt::transparent);
|
||||
|
||||
QPainter painter = QPainter(&px);
|
||||
painter.setBrush(QColor(183, 211, 149, 255));
|
||||
painter.drawEllipse(0, 10, 38, 38);
|
||||
|
||||
QFont f = QFont("Arial");
|
||||
f.setPixelSize(28);
|
||||
f.setBold(true);
|
||||
painter.setFont(f);
|
||||
painter.drawText(0, 10, 40, 40, Qt::AlignCenter, "U");
|
||||
return QIcon(px);
|
||||
}
|
||||
+1
-1
Submodule apps/OpenSpace/ext/sgct updated: 7ac1bd4891...a332b1691d
+122
-32
@@ -29,6 +29,9 @@
|
||||
#include <openspace/engine/settings.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/interaction/joystickinputstate.h>
|
||||
#include <openspace/util/progressbar.h>
|
||||
#include <openspace/util/task.h>
|
||||
#include <openspace/util/taskloader.h>
|
||||
#include <openspace/openspace.h>
|
||||
#include <ghoul/format.h>
|
||||
#include <ghoul/ghoul.h>
|
||||
@@ -53,6 +56,7 @@
|
||||
#include <sgct/projection/nonlinearprojection.h>
|
||||
#include <sgct/user.h>
|
||||
#include <sgct/window.h>
|
||||
#include <date/date.h>
|
||||
#include <stb_image.h>
|
||||
#include <tracy/Tracy.hpp>
|
||||
#include <iostream>
|
||||
@@ -99,6 +103,11 @@ glm::ivec2 currentDrawResolution;
|
||||
Window* FirstOpenVRWindow = nullptr;
|
||||
#endif
|
||||
|
||||
// This value is specified from the commandline options and kept around to be run after
|
||||
// everything has been initialized. It's going to be std::nullopt unless a user wants to
|
||||
// run a task
|
||||
std::optional<std::string> taskToRun;
|
||||
|
||||
//
|
||||
// SPOUT-support
|
||||
//
|
||||
@@ -400,6 +409,40 @@ void mainInitFunc(GLFWwindow*) {
|
||||
// Query joystick status, those connected before start up
|
||||
checkJoystickStatus();
|
||||
|
||||
if (taskToRun.has_value()) {
|
||||
// If a task was specified on the commandline line, we are loading that file and
|
||||
// executing everything within
|
||||
|
||||
TaskLoader loader;
|
||||
std::vector<std::unique_ptr<Task>> tasks = loader.tasksFromFile(*taskToRun);
|
||||
|
||||
size_t nTasks = tasks.size();
|
||||
if (nTasks == 1) {
|
||||
LINFO("Task queue has 1 item");
|
||||
}
|
||||
else {
|
||||
LINFO(std::format("Task queue has {} items", tasks.size()));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < tasks.size(); i++) {
|
||||
Task& task = *tasks[i].get();
|
||||
LINFO(std::format(
|
||||
"Performing task {} out of {}: {}",
|
||||
i + 1, tasks.size(), task.description()
|
||||
));
|
||||
ProgressBar progressBar = ProgressBar(100);
|
||||
auto onProgress = [&progressBar](float progress) {
|
||||
progressBar.print(static_cast<int>(progress * 100.f));
|
||||
};
|
||||
task.perform(onProgress);
|
||||
}
|
||||
std::cout << "Done performing tasks" << std::endl;
|
||||
|
||||
// Done with the tasks, so we can terminate
|
||||
Engine::instance().terminate();
|
||||
}
|
||||
|
||||
|
||||
LTRACE("main::mainInitFunc(end)");
|
||||
}
|
||||
|
||||
@@ -924,24 +967,40 @@ void setSgctDelegateFunctions() {
|
||||
|
||||
return Engine::instance().windows().front()->id();
|
||||
};
|
||||
sgctDelegate.nameForWindow = [](int windowIdx) {
|
||||
ZoneScoped;
|
||||
|
||||
ghoul_assert(
|
||||
windowIdx >= 0 &&
|
||||
windowIdx < Engine::instance().windows().size(),
|
||||
"Invalid window index"
|
||||
);
|
||||
return Engine::instance().windows()[windowIdx]->name();
|
||||
};
|
||||
sgctDelegate.openGLProcedureAddress = [](const char* func) {
|
||||
ZoneScoped;
|
||||
|
||||
return glfwGetProcAddress(func);
|
||||
};
|
||||
sgctDelegate.getHorizFieldOfView = []() {
|
||||
sgctDelegate.horizFieldOfView = [](int windowIdx) {
|
||||
ZoneScoped;
|
||||
|
||||
return static_cast<double>(
|
||||
Engine::instance().windows().front()->horizFieldOfViewDegrees()
|
||||
ghoul_assert(
|
||||
windowIdx >= 0 &&
|
||||
windowIdx < Engine::instance().windows().size(),
|
||||
"Invalid window index"
|
||||
);
|
||||
return Engine::instance().windows()[windowIdx]->horizFieldOfViewDegrees();
|
||||
};
|
||||
sgctDelegate.setHorizFieldOfView = [](float hFovDeg) {
|
||||
sgctDelegate.setHorizFieldOfView = [](int windowIdx, float hFovDeg) {
|
||||
ZoneScoped;
|
||||
|
||||
for (std::unique_ptr<sgct::Window> const& w : Engine::instance().windows()) {
|
||||
w->setHorizFieldOfView(hFovDeg);
|
||||
}
|
||||
ghoul_assert(
|
||||
windowIdx >= 0 &&
|
||||
windowIdx < Engine::instance().windows().size(),
|
||||
"Invalid window index"
|
||||
);
|
||||
Engine::instance().windows()[windowIdx]->setHorizFieldOfView(hFovDeg);
|
||||
};
|
||||
#ifdef WIN32
|
||||
sgctDelegate.getNativeWindowHandle = [](size_t windowIndex) -> void* {
|
||||
@@ -1070,6 +1129,12 @@ void setSgctDelegateFunctions() {
|
||||
int main(int argc, char* argv[]) {
|
||||
ZoneScoped;
|
||||
|
||||
// For debugging purposes: Enforce Light Mode in Qt
|
||||
// qputenv("QT_QPA_PLATFORM", "windows:darkmode=0");
|
||||
|
||||
// For debugging purposes: Enforce Dark Mode in Qt
|
||||
// qputenv("QT_QPA_PLATFORM", "windows:darkmode=1");
|
||||
|
||||
#ifdef OPENSPACE_BREAK_ON_FLOATING_POINT_EXCEPTION
|
||||
_clearfp();
|
||||
_controlfp(_controlfp(0, 0) & ~(_EM_ZERODIVIDE | _EM_OVERFLOW), _MCW_EM);
|
||||
@@ -1119,41 +1184,56 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
CommandlineArguments commandlineArguments;
|
||||
parser.addCommand(std::make_unique<ghoul::cmdparser::SingleCommand<std::string>>(
|
||||
commandlineArguments.configuration, "--file", "-f",
|
||||
commandlineArguments.configuration,
|
||||
"--file",
|
||||
"-f",
|
||||
"Provides the path to the OpenSpace configuration file. Only the '${TEMPORARY}' "
|
||||
"path token is available and any other path has to be specified relative to the "
|
||||
"current working directory"
|
||||
));
|
||||
parser.addCommand(std::make_unique<ghoul::cmdparser::SingleCommand<std::string>>(
|
||||
commandlineArguments.windowConfig, "--config", "-c",
|
||||
commandlineArguments.windowConfig,
|
||||
"--config",
|
||||
"-c",
|
||||
"Specifies the window configuration file that should be used to start OpenSpace "
|
||||
"and that will override whatever is specified in the `openspace.cfg` or the "
|
||||
"settings. This value can include path tokens, so for example "
|
||||
"`${CONFIG}/single.json` is a valid value."
|
||||
));
|
||||
parser.addCommand(std::make_unique<ghoul::cmdparser::SingleCommand<std::string>>(
|
||||
commandlineArguments.profile, "--profile", "-p",
|
||||
commandlineArguments.profile,
|
||||
"--profile",
|
||||
"-p",
|
||||
"Specifies the profile that should be used to start OpenSpace and that overrides "
|
||||
"the profile specified in the `openspace.cfg` and the settings."
|
||||
));
|
||||
parser.addCommand(std::make_unique<ghoul::cmdparser::SingleCommand<std::string>>(
|
||||
commandlineArguments.propertyVisibility, "--propertyVisibility", "",
|
||||
commandlineArguments.propertyVisibility,
|
||||
"--propertyVisibility",
|
||||
"",
|
||||
"Specifies UI visibility settings for properties that this OpenSpace is using. "
|
||||
"This value overrides the values specified in the `openspace.cfg` and the "
|
||||
"settings and also the environment variable, if that value is provided. Allowed "
|
||||
"values for this parameter are: `Developer`, `AdvancedUser`, `User`, and "
|
||||
"`NoviceUser`."
|
||||
));
|
||||
parser.addCommand(std::make_unique<ghoul::cmdparser::SingleCommand<std::string>>(
|
||||
commandlineArguments.task,
|
||||
"--task",
|
||||
"-t",
|
||||
"Specifies a task that will be run after OpenSpace has been initialized. Once "
|
||||
"the task finishes, the application will automatically close again. All other "
|
||||
"commandline arguments are ignored, if a task is specified."
|
||||
));
|
||||
parser.addCommand(std::make_unique<ghoul::cmdparser::SingleCommandZeroArguments>(
|
||||
commandlineArguments.bypassLauncher, "--bypassLauncher", "-b",
|
||||
commandlineArguments.bypassLauncher,
|
||||
"--bypassLauncher",
|
||||
"-b",
|
||||
"Specifies whether the Launcher should be shown at startup or not. This value "
|
||||
"overrides the value specified in the `openspace.cfg` and the settings."
|
||||
));
|
||||
|
||||
// setCommandLine returns a reference to the vector that will be filled later
|
||||
const std::vector<std::string>& sgctArguments = parser.setCommandLine(
|
||||
{ argv, argv + argc }
|
||||
);
|
||||
parser.setCommandLine({ argv, argv + argc });
|
||||
|
||||
try {
|
||||
const bool showHelp = parser.execute();
|
||||
@@ -1166,8 +1246,16 @@ int main(int argc, char* argv[]) {
|
||||
LFATALC(e.component, e.message);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
// Take an actual copy of the arguments
|
||||
std::vector<std::string> arguments = sgctArguments;
|
||||
|
||||
if (commandlineArguments.task.has_value()) {
|
||||
// If a task was specified, we want to overwrite the used window and profile and
|
||||
// not display the launcher
|
||||
commandlineArguments.windowConfig = "${CONFIG}/single.json";
|
||||
commandlineArguments.profile = "empty";
|
||||
commandlineArguments.bypassLauncher = true;
|
||||
|
||||
taskToRun = *commandlineArguments.task;
|
||||
}
|
||||
|
||||
//
|
||||
// Set up SGCT functions for window delegate
|
||||
@@ -1451,21 +1539,20 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
settings.configuration =
|
||||
isGeneratedWindowConfig ? "" : global::configuration->windowConfiguration;
|
||||
const date::year_month_day now = date::year_month_day(
|
||||
floor<date::days>(std::chrono::system_clock::now())
|
||||
);
|
||||
settings.lastStartedDate = std::format(
|
||||
"{}-{:0>2}-{:0>2}",
|
||||
static_cast<int>(now.year()),
|
||||
static_cast<unsigned>(now.month()),
|
||||
static_cast<unsigned>(now.day())
|
||||
);
|
||||
|
||||
saveSettings(settings, findSettings());
|
||||
}
|
||||
|
||||
// Prepend the outgoing sgctArguments with the program name
|
||||
// as well as the configuration file that sgct is supposed to use
|
||||
arguments.insert(arguments.begin(), argv[0]);
|
||||
arguments.insert(arguments.begin() + 1, "-config");
|
||||
arguments.insert(
|
||||
arguments.begin() + 2,
|
||||
absPath(global::configuration->windowConfiguration).string()
|
||||
);
|
||||
|
||||
// Need to set this before the creation of the sgct::Engine
|
||||
|
||||
Log::instance().setLogToConsole(false);
|
||||
Log::instance().setShowTime(false);
|
||||
Log::instance().setShowLogLevel(false);
|
||||
@@ -1475,9 +1562,14 @@ int main(int argc, char* argv[]) {
|
||||
glfwWindowHint(GLFW_STENCIL_BITS, 8);
|
||||
#endif
|
||||
|
||||
std::filesystem::path winConf =
|
||||
commandlineArguments.windowConfig.has_value() ?
|
||||
*commandlineArguments.windowConfig :
|
||||
global::configuration->windowConfiguration;
|
||||
|
||||
// Determining SGCT configuration file
|
||||
LINFO(std::format(
|
||||
"SGCT Configuration file: {}", absPath(global::configuration->windowConfiguration)
|
||||
"SGCT Configuration file: {}", absPath(winConf)
|
||||
));
|
||||
|
||||
|
||||
@@ -1488,9 +1580,7 @@ int main(int argc, char* argv[]) {
|
||||
LDEBUG("Loading cluster information");
|
||||
config::Cluster cluster;
|
||||
try {
|
||||
cluster = loadCluster(
|
||||
absPath(global::configuration->windowConfiguration).string()
|
||||
);
|
||||
cluster = loadCluster(absPath(winConf).string());
|
||||
}
|
||||
catch (const std::runtime_error& e) {
|
||||
LFATALC("main", e.what());
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"type": "FisheyeProjection",
|
||||
"fov": 180.0,
|
||||
"quality": "1k",
|
||||
"tilt": 27.0,
|
||||
"tilt": 90.0,
|
||||
"background": { "r": 0.1, "g": 0.1, "b": 0.1, "a": 1.0 }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
"type": "FisheyeProjection",
|
||||
"fov": 180.0,
|
||||
"quality": "1k",
|
||||
"tilt": 27.0,
|
||||
"tilt": 90.0,
|
||||
"background": { "r": 0.1, "g": 0.1, "b": 0.1, "a": 1.0 }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,299 @@
|
||||
asset.require("actions/trails/toggle_all_trails")
|
||||
asset.require("actions/trails/toggle_trails_planets_moons")
|
||||
asset.require("actions/planets/planet_lighting")
|
||||
asset.require("actions/system/undo_event_fades")
|
||||
asset.require("actions/trails/toggle_all_minor_moon_trails")
|
||||
asset.require("actions/trails/on_off_all_minor_moons")
|
||||
local ToggleShutdown = {
|
||||
Identifier = "os.ToggleShutdown",
|
||||
Name = "Toggle shutdown",
|
||||
Command = "openspace.toggleShutdown()",
|
||||
Documentation = [[
|
||||
Toggles the shutdown that will stop OpenSpace after a grace period. Press again to
|
||||
cancel the shutdown during this period]],
|
||||
GuiPath = "/System",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
-- Friction actions
|
||||
|
||||
local ToggleRotationFriction = {
|
||||
Identifier = "os.ToggleRotationFriction",
|
||||
Name = "Toggle rotation friction",
|
||||
Command = [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.RotationalFriction")]],
|
||||
Documentation = [[Toggles the rotational friction of the camera. If it is disabled, the
|
||||
camera rotates around the focus object indefinitely]],
|
||||
GuiPath = "/Navigation",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local ToggleZoomFriction = {
|
||||
Identifier = "os.ToggleZoomFriction",
|
||||
Name = "Toggle zoom friction",
|
||||
Command = [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.ZoomFriction")]],
|
||||
Documentation = [[Toggles the zoom friction of the camera. If it is disabled, the camera
|
||||
rises up from or closes in towards the focus object indefinitely]],
|
||||
GuiPath = "/Navigation",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local ToggleRollFriction = {
|
||||
Identifier = "os.ToggleRollFriction",
|
||||
Name = "Toggle roll friction",
|
||||
Command = [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.RollFriction")]],
|
||||
Documentation = [[Toggles the roll friction of the camera. If it is disabled, the camera
|
||||
rolls around its own axis indefinitely]],
|
||||
GuiPath = "/Navigation",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
|
||||
-- UI actions
|
||||
|
||||
local ToggleMainGui = {
|
||||
Identifier = "os.ToggleMainGui",
|
||||
Name = "Toggle main GUI",
|
||||
Command = [[openspace.invertBooleanProperty("Modules.CefWebGui.Visible")]],
|
||||
Documentation = "Toggles the main GUI",
|
||||
GuiPath = "/System/GUI",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local ToggleNativeUi = {
|
||||
Identifier = "os.ToggleNativeUi",
|
||||
Name = "Show native GUI",
|
||||
Command = [[openspace.invertBooleanProperty("Modules.ImGUI.Enabled")]],
|
||||
Documentation = "Shows or hides the native UI",
|
||||
GuiPath = "/System/GUI",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local ReloadGui = {
|
||||
Identifier = "os.ReloadGui",
|
||||
Name = "Reload GUI",
|
||||
Command = [[openspace.setPropertyValueSingle("Modules.CefWebGui.Reload", nil)]],
|
||||
Documentation = "Reloads the GUI",
|
||||
GuiPath = "/System/GUI",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
|
||||
-- Rendering actions
|
||||
|
||||
local TakeScreenshot = {
|
||||
Identifier = "os.TakeScreenshot",
|
||||
Name = "Take screenshot",
|
||||
Command = "openspace.takeScreenshot()",
|
||||
Documentation = [[Saves the contents of the screen to a file in the ${SCREENSHOTS}
|
||||
directory]],
|
||||
GuiPath = "/System/Rendering",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local FadeToBlack = {
|
||||
Identifier = "os.FadeToBlack",
|
||||
Name = "Fade to/from black",
|
||||
Command = [[
|
||||
if openspace.propertyValue("RenderEngine.BlackoutFactor") > 0.5 then
|
||||
openspace.setPropertyValueSingle("RenderEngine.BlackoutFactor", 0.0, 3)
|
||||
else
|
||||
openspace.setPropertyValueSingle("RenderEngine.BlackoutFactor", 1.0, 3)
|
||||
end
|
||||
]],
|
||||
Documentation = [[Toggles the fade to black within 3 seconds or shows the rendering
|
||||
after 3 seconds]],
|
||||
GuiPath = "/Rendering",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local ToggleOverlays = {
|
||||
Identifier = "os.ToggleOverlays",
|
||||
Name = "Toggle dashboard and overlays",
|
||||
Command = [[
|
||||
local isEnabled = openspace.propertyValue("Dashboard.IsEnabled")
|
||||
openspace.setPropertyValueSingle("Dashboard.IsEnabled", not isEnabled)
|
||||
openspace.setPropertyValueSingle("RenderEngine.ShowLog", not isEnabled)
|
||||
openspace.setPropertyValueSingle("RenderEngine.ShowVersion", not isEnabled)
|
||||
]],
|
||||
Documentation = "Toggles the dashboard and overlays",
|
||||
GuiPath = "/System/GUI",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local ToggleMasterRendering = {
|
||||
Identifier = "os.ToggleMasterRendering",
|
||||
Name = "Toggle rendering on master",
|
||||
Command = [[openspace.invertBooleanProperty("RenderEngine.DisableMasterRendering")]],
|
||||
Documentation = "Toggles the rendering on master",
|
||||
GuiPath = "/System/Rendering",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
|
||||
-- Time actions
|
||||
|
||||
local TogglePauseInterpolated = {
|
||||
Identifier = "os.TogglePauseInterpolated",
|
||||
Name = "Toggle pause (interpolate)",
|
||||
Command = "openspace.time.pauseToggleViaKeyboard()",
|
||||
Documentation = "Smoothly starts and stops the simulation time",
|
||||
GuiPath = "/Time/Simulation Speed",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local TogglePauseImmediate = {
|
||||
Identifier = "os.TogglePauseImmediate",
|
||||
Name = "Toggle pause (immediate)",
|
||||
Command = "openspace.time.togglePause()",
|
||||
Documentation = "Immediately starts and stops the simulation time",
|
||||
GuiPath = "/Time/Simulation Speed",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local NextDeltaStepInterpolate = {
|
||||
Identifier = "os.NextDeltaStepInterpolate",
|
||||
Name = "Next simulation time step (interpolate)",
|
||||
Command = "openspace.time.interpolateNextDeltaTimeStep()",
|
||||
Documentation = [[Smoothly interpolates the simulation speed to the next simulation time
|
||||
step, if one exists]],
|
||||
GuiPath = "/Time/Simulation Speed",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local NextDeltaStepImmediate = {
|
||||
Identifier = "os.NextDeltaStepImmediate",
|
||||
Name = "Next simulation time step (immediate)",
|
||||
Command = "openspace.time.setNextDeltaTimeStep()",
|
||||
Documentation = [[Immediately set the simulation speed to the next simulation time step,
|
||||
if one exists]],
|
||||
GuiPath = "/Time/Simulation Speed",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local PreviousDeltaStepInterpolate = {
|
||||
Identifier = "os.PreviousDeltaStepInterpolate",
|
||||
Name = "Previous simulation time step (interpolate)",
|
||||
Command = "openspace.time.interpolatePreviousDeltaTimeStep()",
|
||||
Documentation = [[Smoothly interpolates the simulation speed to the previous simulation
|
||||
time step, if one exists]],
|
||||
GuiPath = "/Time/Simulation Speed",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local PreviousDeltaStepImmediate = {
|
||||
Identifier = "os.PreviousDeltaStepImmediate",
|
||||
Name = "Previous simulation time step (immediate)",
|
||||
Command = "openspace.time.setPreviousDeltaTimeStep()",
|
||||
Documentation = [[Immediately set the simulation speed to the previous simulation time
|
||||
step, if one exists]],
|
||||
GuiPath = "/Time/Simulation Speed",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local RealTimeDeltaStepInterpolate = {
|
||||
Identifier = "os.RealTimeDeltaStepInterpolate",
|
||||
Name = "Reset the simulation time to realtime (interpolate)",
|
||||
Command = "openspace.time.interpolateDeltaTime(1)",
|
||||
Documentation = "Smoothly interpolate the simulation speed to match real-time speed",
|
||||
GuiPath = "/Time/Simulation Speed",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local RealTimeDeltaStepImmediate = {
|
||||
Identifier = "os.RealTimeDeltaStepImmediate",
|
||||
Name = "Reset the simulation time to realtime (immediate)",
|
||||
Command = "openspace.time.setDeltaTime(1)",
|
||||
Documentation = "Immediately set the simulation speed to match real-time speed",
|
||||
GuiPath = "/Time/Simulation Speed",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.action.registerAction(ToggleShutdown)
|
||||
|
||||
-- Friction
|
||||
openspace.action.registerAction(ToggleRotationFriction)
|
||||
openspace.action.registerAction(ToggleZoomFriction)
|
||||
openspace.action.registerAction(ToggleRollFriction)
|
||||
|
||||
-- UI
|
||||
openspace.action.registerAction(ToggleMainGui)
|
||||
openspace.action.registerAction(ToggleNativeUi)
|
||||
openspace.action.registerAction(ReloadGui)
|
||||
|
||||
-- Rendering
|
||||
openspace.action.registerAction(TakeScreenshot)
|
||||
openspace.action.registerAction(FadeToBlack)
|
||||
openspace.action.registerAction(ToggleOverlays)
|
||||
openspace.action.registerAction(ToggleMasterRendering)
|
||||
|
||||
-- Time
|
||||
openspace.action.registerAction(TogglePauseInterpolated)
|
||||
openspace.action.registerAction(TogglePauseImmediate)
|
||||
openspace.action.registerAction(NextDeltaStepInterpolate)
|
||||
openspace.action.registerAction(NextDeltaStepImmediate)
|
||||
openspace.action.registerAction(PreviousDeltaStepInterpolate)
|
||||
openspace.action.registerAction(PreviousDeltaStepImmediate)
|
||||
openspace.action.registerAction(RealTimeDeltaStepInterpolate)
|
||||
openspace.action.registerAction(RealTimeDeltaStepImmediate)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
-- Time
|
||||
openspace.action.removeAction(RealTimeDeltaStepImmediate)
|
||||
openspace.action.removeAction(RealTimeDeltaStepInterpolate)
|
||||
openspace.action.removeAction(PreviousDeltaStepImmediate)
|
||||
openspace.action.removeAction(PreviousDeltaStepInterpolate)
|
||||
openspace.action.removeAction(NextDeltaStepImmediate)
|
||||
openspace.action.removeAction(NextDeltaStepInterpolate)
|
||||
openspace.action.removeAction(TogglePauseImmediate)
|
||||
openspace.action.removeAction(TogglePauseInterpolated)
|
||||
|
||||
-- Rendering
|
||||
openspace.action.removeAction(ToggleMasterRendering)
|
||||
openspace.action.removeAction(ToggleOverlays)
|
||||
openspace.action.removeAction(FadeToBlack)
|
||||
openspace.action.removeAction(TakeScreenshot)
|
||||
|
||||
-- UI
|
||||
openspace.action.removeAction(ReloadGui)
|
||||
openspace.action.removeAction(ToggleNativeUi)
|
||||
openspace.action.removeAction(ToggleMainGui)
|
||||
|
||||
-- Friction
|
||||
openspace.action.removeAction(ToggleRollFriction)
|
||||
openspace.action.removeAction(ToggleZoomFriction)
|
||||
openspace.action.removeAction(ToggleRotationFriction)
|
||||
|
||||
openspace.action.removeAction(ToggleShutdown)
|
||||
end)
|
||||
|
||||
|
||||
asset.export("ToggleShutdown", ToggleShutdown.Identifier)
|
||||
|
||||
asset.export("ToggleRotationFriction", ToggleRotationFriction.Identifier)
|
||||
asset.export("ToggleZoomFriction", ToggleZoomFriction.Identifier)
|
||||
asset.export("ToggleRollFriction", ToggleRollFriction.Identifier)
|
||||
|
||||
asset.export("ToggleMainGui", ToggleMainGui.Identifier)
|
||||
asset.export("ToggleNativeUi", ToggleNativeUi.Identifier)
|
||||
asset.export("ReloadGui", ReloadGui.Identifier)
|
||||
|
||||
asset.export("TakeScreenshot", TakeScreenshot.Identifier)
|
||||
asset.export("FadeToBlack", FadeToBlack.Identifier)
|
||||
asset.export("ToggleOverlays", ToggleOverlays.Identifier)
|
||||
asset.export("ToggleMasterRendering", ToggleMasterRendering.Identifier)
|
||||
|
||||
asset.export("TogglePauseInterpolated", TogglePauseInterpolated.Identifier)
|
||||
asset.export("TogglePauseImmediate", TogglePauseImmediate.Identifier)
|
||||
asset.export("NextDeltaStepInterpolate", NextDeltaStepInterpolate.Identifier)
|
||||
asset.export("NextDeltaStepImmediate", NextDeltaStepImmediate.Identifier)
|
||||
asset.export("PreviousDeltaStepInterpolate", PreviousDeltaStepInterpolate.Identifier)
|
||||
asset.export("PreviousDeltaStepImmediate", PreviousDeltaStepImmediate.Identifier)
|
||||
asset.export("RealTimeDeltaStepInterpolate", RealTimeDeltaStepInterpolate.Identifier)
|
||||
asset.export("RealTimeDeltaStepImmediate", RealTimeDeltaStepImmediate.Identifier)
|
||||
|
||||
|
||||
|
||||
asset.meta = {
|
||||
Name = "Actions - Default",
|
||||
Description = "Asset providing default actions that are useful in every profile",
|
||||
Author = "OpenSpace Team",
|
||||
URL = "http://openspaceproject.com",
|
||||
License = "MIT license"
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ local LookingNorth = {
|
||||
Command = [[
|
||||
local currentNavState = openspace.navigation.getNavigationState()
|
||||
local newNavState = {
|
||||
Pitch = math.pi / 2.0,
|
||||
Pitch = math.pi,
|
||||
Anchor = currentNavState["Anchor"],
|
||||
Yaw = currentNavState["Yaw"],
|
||||
Position = currentNavState["Position"],
|
||||
@@ -74,13 +74,36 @@ local LookingNorth = {
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local LookingEast = {
|
||||
Identifier = "os.nightsky.LookingEast",
|
||||
Name = "Looking East",
|
||||
Command = [[
|
||||
local lat, lon, alt = openspace.globebrowsing.geoPositionForCamera()
|
||||
local lon_rad = math.rad(lon)
|
||||
local upx = -math.sin(lon_rad)
|
||||
local upy = math.cos(lon_rad)
|
||||
local currentNavState = openspace.navigation.getNavigationState()
|
||||
local newNavState = {
|
||||
Pitch = math.pi,
|
||||
Anchor = currentNavState["Anchor"],
|
||||
Yaw = currentNavState["Yaw"],
|
||||
Position = currentNavState["Position"],
|
||||
Up = { upx, upy, 0 }
|
||||
}
|
||||
openspace.navigation.setNavigationState(newNavState)
|
||||
]],
|
||||
Documentation = "Sets the view looking up and East.",
|
||||
GuiPath = "/Night Sky/View",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local LookingSouth = {
|
||||
Identifier = "os.nightsky.LookingSouth",
|
||||
Name = "Looking South",
|
||||
Command = [[
|
||||
local currentNavState = openspace.navigation.getNavigationState()
|
||||
local newNavState = {
|
||||
Pitch = math.pi / 2.0,
|
||||
Pitch = math.pi,
|
||||
Anchor = currentNavState["Anchor"],
|
||||
Yaw = currentNavState["Yaw"],
|
||||
Position = currentNavState["Position"],
|
||||
@@ -88,22 +111,48 @@ local LookingSouth = {
|
||||
}
|
||||
openspace.navigation.setNavigationState(newNavState)
|
||||
]],
|
||||
Documentation = "Sets the view for a horizon looking South.",
|
||||
Documentation = "Sets the view looking up and South.",
|
||||
GuiPath = "/Night Sky/View",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local LookingWest = {
|
||||
Identifier = "os.nightsky.LookingWest",
|
||||
Name = "Looking West",
|
||||
Command = [[
|
||||
local lat, lon, alt = openspace.globebrowsing.geoPositionForCamera()
|
||||
local lon_rad = math.rad(lon)
|
||||
local upx = math.sin(lon_rad)
|
||||
local upy = -math.cos(lon_rad)
|
||||
local currentNavState = openspace.navigation.getNavigationState()
|
||||
local newNavState = {
|
||||
Pitch = math.pi,
|
||||
Anchor = currentNavState["Anchor"],
|
||||
Yaw = currentNavState["Yaw"],
|
||||
Position = currentNavState["Position"],
|
||||
Up = { upx, upy, 0 }
|
||||
}
|
||||
openspace.navigation.setNavigationState(newNavState)
|
||||
]],
|
||||
Documentation = "Sets the view looking up and West.",
|
||||
GuiPath = "/Night Sky/View",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.action.registerAction(LookUp)
|
||||
openspace.action.registerAction(LevelHorizonYaw)
|
||||
openspace.action.registerAction(LevelHorizonPitch)
|
||||
openspace.action.registerAction(LookingNorth)
|
||||
openspace.action.registerAction(LookingEast)
|
||||
openspace.action.registerAction(LookingSouth)
|
||||
openspace.action.registerAction(LookingWest)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.action.removeAction(LookingWest)
|
||||
openspace.action.removeAction(LookingSouth)
|
||||
openspace.action.removeAction(LookingEast)
|
||||
openspace.action.removeAction(LookingNorth)
|
||||
openspace.action.removeAction(LevelHorizonPitch)
|
||||
openspace.action.removeAction(LevelHorizonYaw)
|
||||
@@ -114,4 +163,6 @@ asset.export("LookUp", LookUp.Identifier)
|
||||
asset.export("LevelHorizonYaw", LevelHorizonYaw.Identifier)
|
||||
asset.export("LevelHorizonPitch", LevelHorizonPitch.Identifier)
|
||||
asset.export("LookingNorth", LookingNorth.Identifier)
|
||||
asset.export("LookingEast", LookingEast.Identifier)
|
||||
asset.export("LookingSouth", LookingSouth.Identifier)
|
||||
asset.export("LookingWest", LookingWest.Identifier)
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
local AddSunTrail = {
|
||||
Identifier = "os.nightsky.AddSunTrail",
|
||||
Name = "Add sun trail",
|
||||
Command = [[
|
||||
local date
|
||||
if is_declared("args") then
|
||||
if (args.Date == "NOW") then
|
||||
date = openspace.time.currentWallTime()
|
||||
elseif (args.Date == "UTC") then
|
||||
date = openspace.time.UTC()
|
||||
else
|
||||
date = args.Date
|
||||
end
|
||||
else
|
||||
date = openspace.time.UTC()
|
||||
end
|
||||
|
||||
local datePlus = openspace.time.advancedTime(date, '1d')
|
||||
|
||||
date = string.sub(date, 1, string.find(date, "T") - 1)
|
||||
datePlus = string.sub(datePlus, 1, string.find(datePlus, "T") - 1)
|
||||
|
||||
local SunTrailEarth = {
|
||||
Identifier = "SunTrailEarth" .. date,
|
||||
Parent = "Earth",
|
||||
Renderable = {
|
||||
Type = "RenderableTrailTrajectory",
|
||||
Translation = {
|
||||
Type = "SpiceTranslation",
|
||||
Target = "SUN",
|
||||
Observer = "EARTH",
|
||||
Frame = "IAU_EARTH",
|
||||
},
|
||||
EnableFade = false,
|
||||
StartTime = date,
|
||||
EndTime = datePlus,
|
||||
SampleInterval = 1000,
|
||||
ShowFullTrail = true,
|
||||
Color = { 0.9, 1.0, 0.0 },
|
||||
},
|
||||
Tag = { "sun_trail" },
|
||||
GUI = {
|
||||
Name = "Sun Trail " .. date,
|
||||
Path = "/Night Sky/Sun Trails",
|
||||
}
|
||||
}
|
||||
|
||||
openspace.addSceneGraphNode(SunTrailEarth)
|
||||
]],
|
||||
Documentation = [[
|
||||
Adds a trail for the sun, if an argument is provided, that date will be used instead of now
|
||||
]],
|
||||
GuiPath = "/Night Sky/Sun Trails",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.action.registerAction(AddSunTrail)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.action.removeAction(AddSunTrail)
|
||||
end)
|
||||
|
||||
asset.export("AddSunTrail", AddSunTrail.Identifier)
|
||||
@@ -0,0 +1,112 @@
|
||||
local textures = asset.resource({
|
||||
Name = "Cardinal Directions Textures",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "cardinal_directions_textures",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
|
||||
local FadeInConstellationLabels = {
|
||||
Identifier = "os.nightsky.FadeInConstellationLabels",
|
||||
Name = "Fade In Constellation Labels",
|
||||
Command = [[openspace.fadeIn("Scene.Constellations.Renderable.Labels",nil)]],
|
||||
Documentation = "Fades in the constllation labels",
|
||||
GuiPath = "/Constellations/Lines",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local FadeOutConstellationLabels = {
|
||||
Identifier = "os.nightsky.FadeOutConstellationLabels",
|
||||
Name = "Fade Out Constellation Labels",
|
||||
Command = [[openspace.fadeOut("Scene.Constellations.Renderable.Labels")]],
|
||||
Documentation = "Fades out the constellation labels",
|
||||
GuiPath = "/Constellations/Lines",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local ShowConstellationElements = {
|
||||
Identifier = "os.nightsky.ShowConstellationElements",
|
||||
Name = "Show Constellation Elements",
|
||||
Command = [[
|
||||
openspace.setPropertyValueSingle('Scene.Constellations.Renderable.DrawElements', true)
|
||||
openspace.setPropertyValueSingle('Scene.Constellations.Renderable.Fade', 0)
|
||||
local fadeSpeed = openspace.propertyValue("OpenSpaceEngine.FadeDuration")
|
||||
openspace.fadeIn("Scene.Constellations.Renderable", fadeSpeed, "")
|
||||
]],
|
||||
Documentation = "Shows the constellation lines with consideration of label state",
|
||||
GuiPath = "/Constellations/Lines",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local HideAllMarkings = {
|
||||
Identifier = "os.nightsky.HideAllMarkings",
|
||||
Name = "Hide All Markings",
|
||||
Command = [[
|
||||
openspace.fadeOut("Scene.Constellations.Renderable")
|
||||
openspace.fadeOut("{nightsky_marking}")
|
||||
openspace.fadeOut("{du_grid}")
|
||||
openspace.fadeOut("{du_grid_labels}")
|
||||
openspace.fadeOut("{image_constellation}")
|
||||
]],
|
||||
Documentation = "Hides all markings in the night sky",
|
||||
GuiPath = "/Night Sky/Markings",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local AddTickMarksBand = {
|
||||
Identifier = "os.nightsky.AddNeswBandMarks",
|
||||
Name = "Add a band to cardinal directions",
|
||||
Command = [[
|
||||
local tex = openspace.propertyValue("Scene.CardinalDirectionSphere.Renderable.Texture")
|
||||
if (string.find(tex, "small")) then
|
||||
openspace.setPropertyValueSingle("Scene.CardinalDirectionSphere.Renderable.Texture", "]].. textures:gsub("\\","/") .. [[nesw_lines_red_small.png")
|
||||
else
|
||||
openspace.setPropertyValueSingle("Scene.CardinalDirectionSphere.Renderable.Texture", "]].. textures:gsub("\\","/") .. [[nesw_lines_red.png")
|
||||
end
|
||||
]],
|
||||
Documentation = "Adds tick marks to the cardinal directions",
|
||||
GuiPath = "/Night Sky/Directions",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local RemoveTickMarksBand = {
|
||||
Identifier = "os.nightsky.RemoveNeswBandMarks",
|
||||
Name = "Add a band to cardinal directions",
|
||||
Command = [[
|
||||
local tex = openspace.propertyValue("Scene.CardinalDirectionSphere.Renderable.Texture")
|
||||
if (string.find(tex, "small")) then
|
||||
openspace.setPropertyValueSingle("Scene.CardinalDirectionSphere.Renderable.Texture", "]].. textures:gsub("\\","/") .. [[nesw_red_small.png")
|
||||
else
|
||||
openspace.setPropertyValueSingle("Scene.CardinalDirectionSphere.Renderable.Texture", "]].. textures:gsub("\\","/") .. [[nesw_red.png")
|
||||
end
|
||||
]],
|
||||
Documentation = "Removes tick marks to the cardinal directions",
|
||||
GuiPath = "/Night Sky/Directions",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.action.registerAction(FadeInConstellationLabels)
|
||||
openspace.action.registerAction(FadeOutConstellationLabels)
|
||||
openspace.action.registerAction(ShowConstellationElements)
|
||||
openspace.action.registerAction(HideAllMarkings)
|
||||
openspace.action.registerAction(AddTickMarksBand)
|
||||
openspace.action.registerAction(RemoveTickMarksBand)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.action.removeAction(RemoveTickMarksBand)
|
||||
openspace.action.removeAction(AddTickMarksBand)
|
||||
openspace.action.removeAction(HideAllMarkings)
|
||||
openspace.action.removeAction(ShowConstellationElements)
|
||||
openspace.action.removeAction(FadeOutConstellationLabels)
|
||||
openspace.action.removeAction(FadeInConstellationLabels)
|
||||
end)
|
||||
|
||||
asset.export("FadeInConstellationLabels", FadeInConstellationLabels.Identifier)
|
||||
asset.export("FadeOutConstellationLabels", FadeOutConstellationLabels.Identifier)
|
||||
asset.export("ShowConstellationElements", ShowConstellationElements.Identifier)
|
||||
asset.export("HideAllMarkings", HideAllMarkings.Identifier)
|
||||
asset.export("AddTickMarksBand", AddTickMarksBand.Identifier)
|
||||
asset.export("RemoveTickMarksBand", RemoveTickMarksBand.Identifier)
|
||||
@@ -0,0 +1,59 @@
|
||||
local NorthPole = {
|
||||
Identifier = "os.nightsky.position.NorthPole",
|
||||
Name = "Jump to the North Pole",
|
||||
Command = [[
|
||||
openspace.navigation.jumpToGeo("Earth", 90.0001, 0.0001, 500)
|
||||
local script = 'local wait = openspace.propertyValue("NavigationHandler.JumpToFadeDuration")openspace.action.triggerAction("os.nightsky.LookUp");openspace.setPropertyValueSingle("RenderEngine.BlackoutFactor", 1, wait)'
|
||||
local wait = openspace.propertyValue("NavigationHandler.JumpToFadeDuration")
|
||||
openspace.scheduleScript(script, wait + 0.1)
|
||||
]],
|
||||
Documentation = "",
|
||||
GuiPath = "/Night Sky/Position",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local SouthPole = {
|
||||
Identifier = "os.nightsky.position.SouthPole",
|
||||
Name = "Jump to the South Pole",
|
||||
Command = [[
|
||||
openspace.navigation.jumpToGeo("Earth", -89.9, 0.001, 2800);
|
||||
local script = 'local wait = openspace.propertyValue("NavigationHandler.JumpToFadeDuration")openspace.action.triggerAction("os.nightsky.LookUp");openspace.setPropertyValueSingle("RenderEngine.BlackoutFactor", 1, wait)'
|
||||
local wait = openspace.propertyValue("NavigationHandler.JumpToFadeDuration")
|
||||
openspace.scheduleScript(script, wait + 0.1)
|
||||
]],
|
||||
Documentation = "",
|
||||
GuiPath = "/Night Sky/Position",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local Equator = {
|
||||
Identifier = "os.nightsky.position.Equator",
|
||||
Name = "Jump to the Equator",
|
||||
Command = [[
|
||||
local _, long, _ = openspace.globebrowsing.geoPositionForCamera(false);
|
||||
openspace.navigation.jumpToGeo("Earth", 0.0001, long, 500);
|
||||
local script = 'local wait = openspace.propertyValue("NavigationHandler.JumpToFadeDuration")openspace.action.triggerAction("os.nightsky.LookUp");openspace.setPropertyValueSingle("RenderEngine.BlackoutFactor", 1, wait)'
|
||||
local wait = openspace.propertyValue("NavigationHandler.JumpToFadeDuration")
|
||||
openspace.scheduleScript(script, wait + 0.1)
|
||||
]],
|
||||
Documentation = "",
|
||||
GuiPath = "/Night Sky/Position",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.action.registerAction(NorthPole)
|
||||
openspace.action.registerAction(SouthPole)
|
||||
openspace.action.registerAction(Equator)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.action.removeAction(Equator)
|
||||
openspace.action.removeAction(SouthPole)
|
||||
openspace.action.removeAction(NorthPole)
|
||||
end)
|
||||
|
||||
asset.export("NorthPole", NorthPole.Identifier)
|
||||
asset.export("SouthPole", SouthPole.Identifier)
|
||||
asset.export("Equator", Equator.Identifier)
|
||||
@@ -0,0 +1,6 @@
|
||||
asset.require("actions/trails/toggle_all_trails")
|
||||
asset.require("actions/trails/toggle_trails_planets_moons")
|
||||
asset.require("actions/planets/planet_lighting")
|
||||
asset.require("actions/system/undo_event_fades")
|
||||
asset.require("actions/trails/toggle_all_minor_moon_trails")
|
||||
asset.require("actions/trails/on_off_all_minor_moons")
|
||||
@@ -31,14 +31,92 @@ openspace.time.setTime(openspace.time.advancedTime(openspace.time.currentTime(),
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local SiderealWeekIncrease = {
|
||||
Identifier = "os.time.siderealWeekIncrease",
|
||||
Name = "Advance 1 sidereal week",
|
||||
Command = [[
|
||||
openspace.time.setTime(openspace.time.advancedTime(openspace.time.currentTime(), 86164.0905 * 7));
|
||||
]],
|
||||
Documentation = [[Advances time by a sidereal week (Instant)]],
|
||||
GuiPath = "/Time",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local SiderealWeekDecrease = {
|
||||
Identifier = "os.time.siderealWeekDecrease",
|
||||
Name = "Decrement 1 sidereal week",
|
||||
Command = [[
|
||||
openspace.time.setTime(openspace.time.advancedTime(openspace.time.currentTime(), -86164.0905 * 7));
|
||||
]],
|
||||
Documentation = [[Decrements time by a sidereal week (Instant)]],
|
||||
GuiPath = "/Time",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local SolarDayIncrease = {
|
||||
Identifier = "os.time.SolarDayIncrease",
|
||||
Name = "Advance 1 solar day",
|
||||
Command = [[
|
||||
openspace.time.setTime(openspace.time.advancedTime(openspace.time.UTC(), "1d"));
|
||||
]],
|
||||
Documentation = [[Advances time by a solar day (Instant)]],
|
||||
GuiPath = "/Time",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local SolarDayDecrease = {
|
||||
Identifier = "os.time.SolarDayDecrease",
|
||||
Name = "Decrement 1 solar day",
|
||||
Command = [[
|
||||
openspace.time.setTime(openspace.time.advancedTime(openspace.time.UTC(), "-1d"));
|
||||
]],
|
||||
Documentation = [[Decrements time by a solar day (Instant)]],
|
||||
GuiPath = "/Time",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local SolarWeekIncrease = {
|
||||
Identifier = "os.time.SolarWeekIncrease",
|
||||
Name = "Advance 1 solar week",
|
||||
Command = [[
|
||||
openspace.time.setTime(openspace.time.advancedTime(openspace.time.UTC(), "7d"));
|
||||
]],
|
||||
Documentation = [[Advances time by a solar week (Instant)]],
|
||||
GuiPath = "/Time",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local SolarWeekDecrease = {
|
||||
Identifier = "os.time.SolarWeekDecrease",
|
||||
Name = "Decrement 1 solar week",
|
||||
Command = [[
|
||||
openspace.time.setTime(openspace.time.advancedTime(openspace.time.UTC(), "-7d"));
|
||||
]],
|
||||
Documentation = [[Decrements time by a solar week (Instant)]],
|
||||
GuiPath = "/Time",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.action.registerAction(ReverseRate)
|
||||
openspace.action.registerAction(SiderealDayIncrease)
|
||||
openspace.action.registerAction(SiderealDayDecrease)
|
||||
openspace.action.registerAction(SiderealWeekIncrease)
|
||||
openspace.action.registerAction(SiderealWeekDecrease)
|
||||
openspace.action.registerAction(SolarDayIncrease)
|
||||
openspace.action.registerAction(SolarDayDecrease)
|
||||
openspace.action.registerAction(SolarWeekIncrease)
|
||||
openspace.action.registerAction(SolarWeekDecrease)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.action.removeAction(SolarWeekDecrease)
|
||||
openspace.action.removeAction(SolarWeekIncrease)
|
||||
openspace.action.removeAction(SolarDayDecrease)
|
||||
openspace.action.removeAction(SolarDayIncrease)
|
||||
openspace.action.removeAction(SiderealWeekDecrease)
|
||||
openspace.action.removeAction(SiderealWeekIncrease)
|
||||
openspace.action.removeAction(SiderealDayDecrease)
|
||||
openspace.action.removeAction(SiderealDayIncrease)
|
||||
openspace.action.removeAction(ReverseRate)
|
||||
@@ -47,6 +125,12 @@ end)
|
||||
asset.export("ReverseRate", ReverseRate.Identifier)
|
||||
asset.export("SiderealDayIncrease", SiderealDayIncrease.Identifier)
|
||||
asset.export("SiderealDayDecrease", SiderealDayDecrease.Identifier)
|
||||
asset.export("SiderealWeekIncrease", SiderealWeekIncrease.Identifier)
|
||||
asset.export("SiderealWeekDecrease", SiderealWeekDecrease.Identifier)
|
||||
asset.export("SolarDayIncrease", SolarDayIncrease.Identifier)
|
||||
asset.export("SolarDayDecrease", SolarDayDecrease.Identifier)
|
||||
asset.export("SolarWeekIncrease", SolarWeekIncrease.Identifier)
|
||||
asset.export("SolarWeekDecrease", SolarWeekDecrease.Identifier)
|
||||
|
||||
|
||||
|
||||
|
||||
+2
-38
@@ -38,47 +38,11 @@ else
|
||||
asset.require("scene/solarsystem/planets/default_layers")
|
||||
end
|
||||
|
||||
asset.require("scene/digitaluniverse/2dF")
|
||||
asset.require("scene/digitaluniverse/2mass")
|
||||
asset.require("scene/digitaluniverse/6dF")
|
||||
asset.require("scene/digitaluniverse/abell")
|
||||
asset.require("scene/digitaluniverse/allsky_hydrogenalpha")
|
||||
asset.require("scene/digitaluniverse/allsky_visible")
|
||||
asset.require("scene/digitaluniverse/alternatestarlabels")
|
||||
asset.require("scene/digitaluniverse/backgroundradiation")
|
||||
asset.require("scene/digitaluniverse/brown_dwarfs")
|
||||
asset.require("scene/digitaluniverse/galaxy_clusters")
|
||||
asset.require("scene/digitaluniverse/constellationbounds")
|
||||
asset.require("scene/digitaluniverse/constellations")
|
||||
asset.require("scene/digitaluniverse/exoplanets")
|
||||
asset.require("scene/digitaluniverse/exoplanets_candidates")
|
||||
asset.require("scene/digitaluniverse/globularclusters")
|
||||
asset.require("scene/digitaluniverse/grids")
|
||||
asset.require("scene/digitaluniverse/galaxy_groups")
|
||||
asset.require("scene/digitaluniverse/h2regions")
|
||||
asset.require("scene/digitaluniverse/local_group_dwarfs")
|
||||
asset.require("scene/digitaluniverse/milkyway")
|
||||
asset.require("scene/digitaluniverse/milkyway_arm_labels")
|
||||
asset.require("scene/digitaluniverse/milkyway_label")
|
||||
asset.require("scene/digitaluniverse/obassociations")
|
||||
asset.require("scene/digitaluniverse/oort_cloud")
|
||||
asset.require("scene/digitaluniverse/openclusters")
|
||||
asset.require("scene/digitaluniverse/planetarynebulae")
|
||||
asset.require("scene/digitaluniverse/pulsars")
|
||||
asset.require("scene/digitaluniverse/quasars")
|
||||
asset.require("scene/digitaluniverse/star_uncertainty")
|
||||
asset.require("scene/digitaluniverse/starlabels")
|
||||
asset.require("scene/digitaluniverse/starorbits")
|
||||
asset.require("scene/digitaluniverse/stars")
|
||||
asset.require("scene/digitaluniverse/superclusters")
|
||||
asset.require("scene/digitaluniverse/supernovaremnants")
|
||||
asset.require("scene/digitaluniverse/tully")
|
||||
asset.require("scene/digitaluniverse/voids")
|
||||
asset.require("scene/digitaluniverse/white_dwarfs")
|
||||
asset.require("scene/digitaluniverse/digitaluniverse")
|
||||
asset.require("nightsky/nightsky")
|
||||
|
||||
asset.require("customization/globebrowsing")
|
||||
asset.require("actions/default_actions")
|
||||
asset.require("actions/solarsystem_actions")
|
||||
|
||||
asset.require("modules/exoplanets/exoplanets")
|
||||
asset.require("modules/skybrowser/skybrowser")
|
||||
|
||||
@@ -4,11 +4,10 @@
|
||||
asset.require("spice/core")
|
||||
|
||||
asset.require("dashboard/default_dashboard")
|
||||
-- Load default key bindings applicable to most scenes
|
||||
asset.require("./default_keybindings")
|
||||
|
||||
-- Load web gui
|
||||
local webGui = asset.require("util/webgui")
|
||||
-- Load default actions and key bindings applicable to most scenes
|
||||
asset.require("actions/default_actions")
|
||||
asset.require("./default_keybindings")
|
||||
|
||||
-- Scale the different UI components based on the operating system's DPI scaling value
|
||||
asset.require("util/dpiscaling")
|
||||
@@ -19,8 +18,12 @@ asset.require("util/launcher_images")
|
||||
-- Modules and component settings
|
||||
asset.require("modules/touch/default_settings")
|
||||
|
||||
-- Load web gui
|
||||
local webGui = asset.require("util/webgui")
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
webGui.setCefRoute("onscreen")
|
||||
openspace.setPropertyValueSingle("RenderEngine.VerticalLogOffset", 0.100000)
|
||||
openspace.setPropertyValueSingle("RenderEngine.VerticalLogOffset", 0.1)
|
||||
openspace.setPropertyValueSingle("Dashboard.StartPositionOffset", { 15.0, 49.0 })
|
||||
openspace.setPropertyValueSingle("RenderEngine.ShowCamera", false)
|
||||
end)
|
||||
|
||||
@@ -1,348 +1,76 @@
|
||||
local propertyHelper = asset.require("util/property_helper")
|
||||
|
||||
|
||||
|
||||
local ToggleNativeUi = {
|
||||
Identifier = "os.ToggleNativeUi",
|
||||
Name = "Show native GUI",
|
||||
Command = propertyHelper.invert("Modules.ImGUI.Enabled"),
|
||||
Documentation = "Shows or hides the native UI",
|
||||
GuiPath = "/System/GUI",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local ToggleShutdown = {
|
||||
Identifier = "os.ToggleShutdown",
|
||||
Name = "Toggle shutdown",
|
||||
Command = "openspace.toggleShutdown()",
|
||||
Documentation = [[
|
||||
Toggles the shutdown that will stop OpenSpace after a grace period. Press again to
|
||||
cancel the shutdown during this period]],
|
||||
GuiPath = "/System",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local TakeScreenshot = {
|
||||
Identifier = "os.TakeScreenshot",
|
||||
Name = "Take screenshot",
|
||||
Command = "openspace.takeScreenshot()",
|
||||
Documentation = [[Saves the contents of the screen to a file in the ${SCREENSHOTS}
|
||||
directory]],
|
||||
GuiPath = "/System/Rendering",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local TogglePauseInterpolated = {
|
||||
Identifier = "os.TogglePauseInterpolated",
|
||||
Name = "Toggle pause (interpolate)",
|
||||
Command = "openspace.time.pauseToggleViaKeyboard()",
|
||||
Documentation = "Smoothly starts and stops the simulation time",
|
||||
GuiPath = "/Time/Simulation Speed",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local TogglePauseImmediate = {
|
||||
Identifier = "os.TogglePauseImmediate",
|
||||
Name = "Toggle pause (immediate)",
|
||||
Command = "openspace.time.togglePause()",
|
||||
Documentation = "Immediately starts and stops the simulation time",
|
||||
GuiPath = "/Time/Simulation Speed",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local ToggleRotationFriction = {
|
||||
Identifier = "os.ToggleRotationFriction",
|
||||
Name = "Toggle rotation friction",
|
||||
Command = propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.RotationalFriction"),
|
||||
Documentation = [[Toggles the rotational friction of the camera. If it is disabled, the
|
||||
camera rotates around the focus object indefinitely]],
|
||||
GuiPath = "/Navigation",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local ToggleZoomFriction = {
|
||||
Identifier = "os.ToggleZoomFriction",
|
||||
Name = "Toggle zoom friction",
|
||||
Command = propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.ZoomFriction"),
|
||||
Documentation = [[Toggles the zoom friction of the camera. If it is disabled, the camera
|
||||
rises up from or closes in towards the focus object indefinitely]],
|
||||
GuiPath = "/Navigation",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local ToggleRollFriction = {
|
||||
Identifier = "os.ToggleRollFriction",
|
||||
Name = "Toggle roll friction",
|
||||
Command = propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.RollFriction"),
|
||||
Documentation = [[Toggles the roll friction of the camera. If it is disabled, the camera
|
||||
rolls around its own axis indefinitely]],
|
||||
GuiPath = "/Navigation",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local FadeToBlack = {
|
||||
Identifier = "os.FadeToBlack",
|
||||
Name = "Fade to/from black",
|
||||
Command = [[
|
||||
if openspace.propertyValue("RenderEngine.BlackoutFactor") > 0.5 then
|
||||
openspace.setPropertyValueSingle("RenderEngine.BlackoutFactor", 0.0, 3)
|
||||
else
|
||||
openspace.setPropertyValueSingle("RenderEngine.BlackoutFactor", 1.0, 3)
|
||||
end
|
||||
]],
|
||||
Documentation = [[Toggles the fade to black within 3 seconds or shows the rendering
|
||||
after 3 seconds]],
|
||||
GuiPath = "/Rendering",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local ToggleMainGui = {
|
||||
Identifier = "os.ToggleMainGui",
|
||||
Name = "Toggle main GUI",
|
||||
Command = propertyHelper.invert("Modules.CefWebGui.Visible"),
|
||||
Documentation = "Toggles the main GUI",
|
||||
GuiPath = "/System/GUI",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local ToggleOverlays = {
|
||||
Identifier = "os.ToggleOverlays",
|
||||
Name = "Toggle dashboard and overlays",
|
||||
Command = [[
|
||||
local isEnabled = openspace.propertyValue("Dashboard.IsEnabled")
|
||||
openspace.setPropertyValueSingle("Dashboard.IsEnabled", not isEnabled)
|
||||
openspace.setPropertyValueSingle("RenderEngine.ShowLog", not isEnabled)
|
||||
openspace.setPropertyValueSingle("RenderEngine.ShowVersion", not isEnabled)
|
||||
openspace.setPropertyValueSingle("RenderEngine.ShowCamera", not isEnabled)
|
||||
]],
|
||||
Documentation = "Toggles the dashboard and overlays",
|
||||
GuiPath = "/System/GUI",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local ToggleMasterRendering = {
|
||||
Identifier = "os.ToggleMasterRendering",
|
||||
Name = "Toggle rendering on master",
|
||||
Command = propertyHelper.invert("RenderEngine.DisableMasterRendering"),
|
||||
Documentation = "Toggles the rendering on master",
|
||||
GuiPath = "/System/Rendering",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local NextDeltaStepInterpolate = {
|
||||
Identifier = "os.NextDeltaStepInterpolate",
|
||||
Name = "Next simulation time step (interpolate)",
|
||||
Command = "openspace.time.interpolateNextDeltaTimeStep()",
|
||||
Documentation = [[Smoothly interpolates the simulation speed to the next simulation time
|
||||
step, if one exists]],
|
||||
GuiPath = "/Time/Simulation Speed",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local NextDeltaStepImmediate = {
|
||||
Identifier = "os.NextDeltaStepImmediate",
|
||||
Name = "Next simulation time step (immediate)",
|
||||
Command = "openspace.time.setNextDeltaTimeStep()",
|
||||
Documentation = [[Immediately set the simulation speed to the next simulation time step,
|
||||
if one exists]],
|
||||
GuiPath = "/Time/Simulation Speed",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local PreviousDeltaStepInterpolate = {
|
||||
Identifier = "os.PreviousDeltaStepInterpolate",
|
||||
Name = "Previous simulation time step (interpolate)",
|
||||
Command = "openspace.time.interpolatePreviousDeltaTimeStep()",
|
||||
Documentation = [[Smoothly interpolates the simulation speed to the previous simulation
|
||||
time step, if one exists]],
|
||||
GuiPath = "/Time/Simulation Speed",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local PreviousDeltaStepImmediate = {
|
||||
Identifier = "os.PreviousDeltaStepImmediate",
|
||||
Name = "Previous simulation time step (immediate)",
|
||||
Command = "openspace.time.setPreviousDeltaTimeStep()",
|
||||
Documentation = [[Immediately set the simulation speed to the previous simulation time
|
||||
step, if one exists]],
|
||||
GuiPath = "/Time/Simulation Speed",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local RealTimeDeltaStepInterpolate = {
|
||||
Identifier = "os.RealTimeDeltaStepInterpolate",
|
||||
Name = "Reset the simulation time to realtime (interpolate)",
|
||||
Command = "openspace.time.interpolateDeltaTime(1)",
|
||||
Documentation = "Smoothly interpolate the simulation speed to match real-time speed",
|
||||
GuiPath = "/Time/Simulation Speed",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local RealTimeDeltaStepImmediate = {
|
||||
Identifier = "os.RealTimeDeltaStepImmediate",
|
||||
Name = "Reset the simulation time to realtime (immediate)",
|
||||
Command = "openspace.time.setDeltaTime(1)",
|
||||
Documentation = "Immediately set the simulation speed to match real-time speed",
|
||||
GuiPath = "/Time/Simulation Speed",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local DateToNowInterpolate = {
|
||||
Identifier = "os.DateToNowInterpolate",
|
||||
Name = "Set the in-game time to now (interpolate)",
|
||||
Command = "openspace.time.interpolateTime(openspace.time.currentWallTime())",
|
||||
Documentation = "Immediately set the current in-game time to the 'now' time",
|
||||
GuiPath = "/Time/Simulation Speed",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local DateToNowImmediate = {
|
||||
Identifier = "os.DateToNowImmediate",
|
||||
Name = "Set the in-game time to now (immediate)",
|
||||
Command = "openspace.time.setTime(openspace.time.currentWallTime())",
|
||||
Documentation = "Smoothly interpolate the current in-game time to the 'now' time",
|
||||
GuiPath = "/Time/Simulation Speed",
|
||||
IsLocal = true
|
||||
}
|
||||
|
||||
local ReloadGui = {
|
||||
Identifier = "os.ReloadGui",
|
||||
Name = "Reload GUI",
|
||||
Command = [[openspace.setPropertyValueSingle("Modules.CefWebGui.Reload", nil)]],
|
||||
Documentation = "Reloads the GUI",
|
||||
GuiPath = "/System/GUI",
|
||||
IsLocal = true
|
||||
}
|
||||
local actions = asset.require("actions/default_actions")
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.action.registerAction(ToggleNativeUi)
|
||||
openspace.bindKey("F1", ToggleNativeUi.Identifier)
|
||||
openspace.bindKey("Ctrl+Q", actions.ToggleShutdown)
|
||||
|
||||
openspace.action.registerAction(ToggleShutdown)
|
||||
openspace.bindKey("ESC", ToggleShutdown.Identifier)
|
||||
openspace.bindKey("F12", actions.TakeScreenshot)
|
||||
openspace.bindKey("PRINT_SCREEN", actions.TakeScreenshot)
|
||||
|
||||
openspace.action.registerAction(TakeScreenshot)
|
||||
openspace.bindKey("F12", TakeScreenshot.Identifier)
|
||||
openspace.bindKey("PRINT_SCREEN", TakeScreenshot.Identifier)
|
||||
openspace.bindKey("SPACE", actions.TogglePauseInterpolated)
|
||||
openspace.bindKey("Shift+SPACE", actions.TogglePauseImmediate)
|
||||
|
||||
openspace.action.registerAction(TogglePauseInterpolated)
|
||||
openspace.bindKey("SPACE", TogglePauseInterpolated.Identifier)
|
||||
openspace.bindKey("F", actions.ToggleRotationFriction)
|
||||
openspace.bindKey("Shift+F", actions.ToggleZoomFriction)
|
||||
openspace.bindKey("Ctrl+F", actions.ToggleRollFriction)
|
||||
|
||||
openspace.action.registerAction(TogglePauseImmediate)
|
||||
openspace.bindKey("Shift+SPACE", TogglePauseImmediate.Identifier)
|
||||
openspace.bindKey("B", actions.FadeToBlack)
|
||||
|
||||
openspace.action.registerAction(ToggleRotationFriction)
|
||||
openspace.bindKey("F", ToggleRotationFriction.Identifier)
|
||||
openspace.bindKey("F1", actions.ToggleMainGui)
|
||||
openspace.bindKey("Shift+F1", actions.ToggleOverlays)
|
||||
|
||||
openspace.action.registerAction(ToggleZoomFriction)
|
||||
openspace.bindKey("Shift+F", ToggleZoomFriction.Identifier)
|
||||
openspace.bindKey("F2", actions.ToggleNativeUi)
|
||||
|
||||
openspace.action.registerAction(ToggleRollFriction)
|
||||
openspace.bindKey("Ctrl+F", ToggleRollFriction.Identifier)
|
||||
openspace.bindKey("Right", actions.NextDeltaStepInterpolate)
|
||||
openspace.bindKey("Shift+Right", actions.NextDeltaStepImmediate)
|
||||
|
||||
openspace.action.registerAction(FadeToBlack)
|
||||
openspace.bindKey("B", FadeToBlack.Identifier)
|
||||
openspace.bindKey("Left", actions.PreviousDeltaStepInterpolate)
|
||||
openspace.bindKey("Shift+Left", actions.PreviousDeltaStepImmediate)
|
||||
|
||||
openspace.action.registerAction(ToggleMainGui)
|
||||
openspace.bindKey("TAB", ToggleMainGui.Identifier)
|
||||
openspace.bindKey("Down", actions.RealTimeDeltaStepInterpolate)
|
||||
openspace.bindKey("Shift+Down", actions.RealTimeDeltaStepImmediate)
|
||||
|
||||
openspace.action.registerAction(ToggleOverlays)
|
||||
openspace.bindKey("Shift+TAB", ToggleOverlays.Identifier)
|
||||
|
||||
openspace.action.registerAction(ToggleMasterRendering)
|
||||
openspace.bindKey("Alt+R", ToggleMasterRendering.Identifier)
|
||||
|
||||
openspace.action.registerAction(NextDeltaStepInterpolate)
|
||||
openspace.bindKey("Right", NextDeltaStepInterpolate.Identifier)
|
||||
|
||||
openspace.action.registerAction(NextDeltaStepImmediate)
|
||||
openspace.bindKey("Shift+Right", NextDeltaStepImmediate.Identifier)
|
||||
|
||||
openspace.action.registerAction(PreviousDeltaStepInterpolate)
|
||||
openspace.bindKey("Left", PreviousDeltaStepInterpolate.Identifier)
|
||||
|
||||
openspace.action.registerAction(PreviousDeltaStepImmediate)
|
||||
openspace.bindKey("Shift+Left", PreviousDeltaStepImmediate.Identifier)
|
||||
|
||||
openspace.action.registerAction(RealTimeDeltaStepInterpolate)
|
||||
openspace.bindKey("Down", RealTimeDeltaStepInterpolate.Identifier)
|
||||
|
||||
openspace.action.registerAction(RealTimeDeltaStepImmediate)
|
||||
openspace.bindKey("Shift+Down", RealTimeDeltaStepImmediate.Identifier)
|
||||
|
||||
openspace.action.registerAction(DateToNowInterpolate)
|
||||
openspace.bindKey("Up", DateToNowInterpolate.Identifier)
|
||||
|
||||
openspace.action.registerAction(DateToNowImmediate)
|
||||
openspace.bindKey("Shift+Up", DateToNowImmediate.Identifier)
|
||||
|
||||
openspace.action.registerAction(ReloadGui)
|
||||
openspace.bindKey("F5", ReloadGui.Identifier)
|
||||
openspace.bindKey("F5", actions.ReloadGui)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.clearKey("F5")
|
||||
openspace.action.removeAction(ReloadGui)
|
||||
openspace.clearKey("F5") -- actions.ReloadGui
|
||||
|
||||
openspace.clearKey("Shift+Up")
|
||||
openspace.action.removeAction(DateToNowImmediate)
|
||||
openspace.clearKey("Shift+Down") -- actions.RealTimeDeltaStepImmediate
|
||||
openspace.clearKey("Down") -- actions.RealTimeDeltaStepInterpolate
|
||||
|
||||
openspace.clearKey("Up")
|
||||
openspace.action.removeAction(DateToNowInterpolate)
|
||||
openspace.clearKey("Shift+Left") -- actions.PreviousDeltaStepImmediate
|
||||
openspace.clearKey("Left") -- actions.PreviousDeltaStepInterpolate
|
||||
|
||||
openspace.clearKey("Shift+Down")
|
||||
openspace.action.removeAction(RealTimeDeltaStepImmediate)
|
||||
openspace.clearKey("Shift+Right") -- actions.NextDeltaStepImmediate
|
||||
openspace.clearKey("Right") -- actions.NextDeltaStepInterpolate
|
||||
|
||||
openspace.clearKey("Down")
|
||||
openspace.action.removeAction(RealTimeDeltaStepInterpolate)
|
||||
openspace.clearKey("F2") -- actions.ToggleNativeUi
|
||||
|
||||
openspace.clearKey("Shift+Left")
|
||||
openspace.action.removeAction(PreviousDeltaStepImmediate)
|
||||
openspace.clearKey("Shift+F1") -- actions.ToggleOverlays
|
||||
openspace.clearKey("F1") -- actions.ToggleMainGui
|
||||
|
||||
openspace.clearKey("Left")
|
||||
openspace.action.removeAction(PreviousDeltaStepInterpolate)
|
||||
openspace.clearKey("B") -- actions.FadeToBlack
|
||||
|
||||
openspace.clearKey("Shift+Right")
|
||||
openspace.action.removeAction(NextDeltaStepImmediate)
|
||||
openspace.clearKey("Ctrl+F") -- actions.ToggleRollFriction
|
||||
openspace.clearKey("Shift+F") -- actions.ToggleZoomFriction
|
||||
openspace.clearKey("F") -- actions.ToggleRotationFriction
|
||||
|
||||
openspace.clearKey("Right")
|
||||
openspace.action.removeAction(NextDeltaStepInterpolate)
|
||||
openspace.clearKey("Shift+SPACE") -- actions.TogglePauseImmediate
|
||||
openspace.clearKey("SPACE") -- actions.TogglePauseInterpolated
|
||||
|
||||
openspace.clearKey("Alt+R")
|
||||
openspace.action.removeAction(ToggleMasterRendering)
|
||||
openspace.clearKey("F12") -- actions.TakeScreenshot
|
||||
openspace.clearKey("PRINT_SCREEN") -- actions.TakeScreenshot
|
||||
|
||||
openspace.clearKey("Shift+TAB")
|
||||
openspace.action.removeAction(ToggleOverlays)
|
||||
|
||||
openspace.clearKey("TAB")
|
||||
openspace.action.removeAction(ToggleMainGui)
|
||||
|
||||
openspace.clearKey("B")
|
||||
openspace.action.removeAction(FadeToBlack)
|
||||
|
||||
openspace.clearKey("Ctrl+F")
|
||||
openspace.action.removeAction(ToggleRollFriction)
|
||||
|
||||
openspace.clearKey("Shift+F")
|
||||
openspace.action.removeAction(ToggleZoomFriction)
|
||||
|
||||
openspace.clearKey("F")
|
||||
openspace.action.removeAction(ToggleRotationFriction)
|
||||
|
||||
openspace.clearKey("Shift+SPACE")
|
||||
openspace.action.removeAction(TogglePauseImmediate)
|
||||
|
||||
openspace.clearKey("SPACE")
|
||||
openspace.action.removeAction(TogglePauseInterpolated)
|
||||
|
||||
openspace.clearKey("F12")
|
||||
openspace.clearKey("PRINT_SCREEN")
|
||||
openspace.action.removeAction(TakeScreenshot)
|
||||
|
||||
openspace.clearKey("ESC")
|
||||
openspace.action.removeAction(ToggleShutdown)
|
||||
|
||||
openspace.clearKey("F1")
|
||||
openspace.action.removeAction(ToggleNativeUi)
|
||||
openspace.clearKey("Ctrl+Q") -- actions.ToggleShutdown
|
||||
end)
|
||||
|
||||
|
||||
|
||||
asset.meta = {
|
||||
Name = "Default Keybindings",
|
||||
Description ="Asset with default key bindings that are useful for all profiles",
|
||||
Author = "OpenSpace Team",
|
||||
URL = "http://openspaceproject.com",
|
||||
License = "MIT license"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"data": [
|
||||
[ "2024-05-10T00:00:00Z", 2.33 ],
|
||||
[ "2024-05-10T03:00:00Z", 3 ],
|
||||
[ "2024-05-10T06:00:00Z", 3 ],
|
||||
[ "2024-05-10T09:00:00Z", 2.67 ],
|
||||
[ "2024-05-10T12:00:00Z", 2.33 ]
|
||||
]
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"data": [
|
||||
[ "2024-05-10T00:00:00Z", 2.33 ],
|
||||
[ "2024-05-10T03:00:00Z", true ],
|
||||
[ "2024-05-10T06:00:00Z", "Test string" ],
|
||||
[ "2024-05-10T09:00:00Z", { "a": 1.0, "b": 2.0 } ],
|
||||
[ "2024-05-10T12:00:00Z", [ 1.0, 2.0, 3.0 ] ],
|
||||
[ "2024-05-10T15:00:00Z", 3 ]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
-- Basic
|
||||
-- This example shows how to create a time-varying text dashboard item.
|
||||
|
||||
local Item = {
|
||||
Type = "DashboardItemTimeVaryingText",
|
||||
Identifier = "DashboardItemTimeVaryingText_Example",
|
||||
DataFile = asset.resource("data/dummydata.json"),
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.dashboard.addDashboardItem(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.dashboard.removeDashboardItem(Item)
|
||||
end)
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
-- Mixed
|
||||
-- This example shows how to create a time-varying text dashboard item that is using a
|
||||
-- mixed type of data entries in the `DataFile`.
|
||||
|
||||
local Item = {
|
||||
Type = "DashboardItemTimeVaryingText",
|
||||
Identifier = "DashboardItemTimeVaryingText_Example_Mixed",
|
||||
DataFile = asset.resource("data/dummydata_mixed.json"),
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.dashboard.addDashboardItem(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.dashboard.removeDashboardItem(Item)
|
||||
end)
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
-- Styled
|
||||
-- This example shows how to create a time-varying text dashboard item.
|
||||
-- It has a custom font size and text before the time varying text.
|
||||
|
||||
local Item = {
|
||||
Type = "DashboardItemTimeVaryingText",
|
||||
Identifier = "DashboardItemTimeVaryingText_Example_Styled",
|
||||
DataFile = asset.resource("data/dummydata.json"),
|
||||
FormatString = "Observed KP index: {}",
|
||||
FontSize = 40
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.dashboard.addDashboardItem(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.dashboard.removeDashboardItem(Item)
|
||||
end)
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
-- Scale by Distance to Camera
|
||||
-- This example creates a textured plane that is scaled based on the distance to the
|
||||
-- camera, so that it stays a constant size in screen space. The scale is limited so that
|
||||
-- the plane does not become larger or smaller than a given max height and min height, in
|
||||
-- meters.
|
||||
|
||||
local earth = asset.require("scene/solarsystem/planets/earth/earth")
|
||||
|
||||
local Node = {
|
||||
Identifier = "RenderablePlaneImageLocal_Example_ScaleByDistance",
|
||||
Renderable = {
|
||||
Type = "RenderablePlaneImageLocal",
|
||||
Size = 100000,
|
||||
Texture = openspace.absPath("${DATA}/test2.jpg"),
|
||||
DistanceScalingSettings = {
|
||||
ScaleByDistance = true,
|
||||
ApparentSizeMultiplier = 0.01,
|
||||
ScaleByDistanceMaxHeight = 200000,
|
||||
ScaleByDistanceMinHeight = 30000
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "RenderablePlaneImageLocal - ScaleByDistance",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(Node)
|
||||
end)
|
||||
+1
-1
@@ -15,7 +15,7 @@ local Node = {
|
||||
File = asset.resource("data/dummydata.csv"),
|
||||
-- Change the orientation render option to face the camera position instead
|
||||
-- of its view direction
|
||||
OrientationRenderOption = "Camera Position Normal",
|
||||
Billboard = "Camera Position Normal",
|
||||
-- Add a texture so we can more easily see how the orientation is changed
|
||||
Texture = {
|
||||
File = openspace.absPath("${DATA}/test3.jpg")
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
-- Only Far Renderable
|
||||
-- This example uses only shows a textured plane when the camera is further than the
|
||||
-- specified distance from the object and shows nothing if the camera is closer than that
|
||||
-- distance
|
||||
|
||||
local Node = {
|
||||
Identifier = "RenderableSwitch_Example-Far",
|
||||
Renderable = {
|
||||
Type = "RenderableSwitch",
|
||||
RenderableFar = {
|
||||
Type = "RenderablePlaneImageLocal",
|
||||
Size = 300000000000,
|
||||
Texture = openspace.absPath("${DATA}/test.jpg")
|
||||
},
|
||||
DistanceThreshold = 3000000000000
|
||||
},
|
||||
GUI = {
|
||||
Name = "RenderableSwitch - Far",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
-- Only Near Renderable
|
||||
-- This example uses only shows a textured plane when the camera is within the specified
|
||||
-- distance from the object and shows nothing if the camera is further away.
|
||||
|
||||
local Node = {
|
||||
Identifier = "RenderableSwitch_Example-Near",
|
||||
Renderable = {
|
||||
Type = "RenderableSwitch",
|
||||
RenderableNear = {
|
||||
Type = "RenderablePlaneImageLocal",
|
||||
Size = 300000000000,
|
||||
Texture = openspace.absPath("${DATA}/test.jpg")
|
||||
},
|
||||
DistanceThreshold = 2000000000000
|
||||
},
|
||||
GUI = {
|
||||
Name = "RenderableSwitch - Near",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
-- Basic
|
||||
-- This example shows how to create a renderable that switches between two textured planes
|
||||
-- in 3D space, where one texture is loaded from a local file on disk and the other is
|
||||
-- loaded from the internet though a web URL.
|
||||
-- The switch is done based on the distance from the camera to the renderable.
|
||||
|
||||
local Node = {
|
||||
Identifier = "RenderableSwitch_Example",
|
||||
Renderable = {
|
||||
Type = "RenderableSwitch",
|
||||
RenderableNear = {
|
||||
Type = "RenderablePlaneImageLocal",
|
||||
Size = 300000000000,
|
||||
Texture = openspace.absPath("${DATA}/test.jpg")
|
||||
},
|
||||
RenderableFar = {
|
||||
Type = "RenderablePlaneImageOnline",
|
||||
Size = 300000000000,
|
||||
URL = "http://data.openspaceproject.com/examples/renderableplaneimageonline.jpg"
|
||||
},
|
||||
DistanceThreshold = 2000000000000
|
||||
},
|
||||
GUI = {
|
||||
Name = "RenderableSwitch - Basic",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
-- Basic
|
||||
-- Creates a screenspace image plane with controls to for a blackout shape. Can be used
|
||||
-- when using a secondary projector to project content on a dome surface.
|
||||
|
||||
local inset = {
|
||||
Identifier = "ScreenSpaceInsetBlackout_Example",
|
||||
Type = "ScreenSpaceInsetBlackout",
|
||||
Name = "ScreenSpaceInsetBlackout Example - Basic",
|
||||
Blackoutshape = {
|
||||
-- Must always contain four corners in the following order:
|
||||
-- top-left, top-right, bottom-right, bottom-left
|
||||
Corners = { {0.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {0.0, 0.0} }
|
||||
},
|
||||
Scale = 1.0
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(inset)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(inset)
|
||||
end)
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
-- Calibration Pattern
|
||||
-- Creates a screenspace image plane with controls to for a blackout shape. Can be used
|
||||
-- when using a secondary projector to project content on a dome surface.
|
||||
|
||||
local texturePath = asset.resource({
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "calibration_pattern",
|
||||
Name = "ScreenSpaceInsetBlackout Calibration Pattern",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local inset = {
|
||||
Identifier = "ScreenSpaceInsetBlackout_Example_Calibration_Pattern",
|
||||
Type = "ScreenSpaceInsetBlackout",
|
||||
Name = "ScreenSpaceInsetBlackout Example - Calibration Pattern",
|
||||
Blackoutshape = {
|
||||
-- Must always contain four corners in the following order:
|
||||
-- top-left, top-right, bottom-right, bottom-left
|
||||
Corners = { {0.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {0.0, 0.0} },
|
||||
|
||||
CalibrationTexturePath = texturePath .. "calibration-pattern.png";
|
||||
},
|
||||
Scale = 1.0
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(inset)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(inset)
|
||||
end)
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
-- Points
|
||||
-- Creates a screenspace image plane with controls to for a blackout shape. Can be used
|
||||
-- when using a secondary projector to project content on a dome surface.
|
||||
|
||||
local inset = {
|
||||
Identifier = "ScreenSpaceInsetBlackout_Example_Points",
|
||||
Type = "ScreenSpaceInsetBlackout",
|
||||
Name = "ScreenSpaceInsetBlackout Example - Points",
|
||||
Blackoutshape = {
|
||||
-- Must always contain four corners in the following order:
|
||||
-- top-left, top-right, bottom-right, bottom-left
|
||||
Corners = { {0.0, 0.9}, {1.0, 0.9}, {0.9, 0.1}, {0.1, 0.1} },
|
||||
|
||||
-- Contains control points for top spline in order left to right
|
||||
Top = { {0.5, 1.0} },
|
||||
|
||||
-- Contains control points for right spline in order top to bottom
|
||||
Right = { },
|
||||
|
||||
-- Contains control points for bottom spline in order right to left
|
||||
Bottom = { {0.7, 0.2}, {0.3, 0.2} },
|
||||
|
||||
-- Contains control points for left spline in order bottom to top
|
||||
Left = { }
|
||||
},
|
||||
Scale = 1.0
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(inset)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(inset)
|
||||
end)
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"files": [
|
||||
{
|
||||
"timestamp": "2024-05-10 15:00:00.000",
|
||||
"url": "http://data.openspaceproject.com/examples/renderableplaneimageonline.jpg"
|
||||
},
|
||||
{
|
||||
"timestamp": "2024-05-10 15:10:00.000",
|
||||
"url": "https://data.openspaceproject.com/examples/renderableplaneimageonline_2.jpg"
|
||||
},
|
||||
{
|
||||
"timestamp": "2024-05-10 15:20:00.000",
|
||||
"url": "http://data.openspaceproject.com/examples/renderableplaneimageonline.jpg"
|
||||
}
|
||||
]
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
-- Basic
|
||||
-- Create a time-varying screenspace image plane that shows the content of images from
|
||||
-- web URLs based on in-game simulation time. The data in this example has images shown at
|
||||
-- 2024-05-10 between 15:00:00 and 15:20:00.
|
||||
|
||||
local Item = {
|
||||
Type = "ScreenSpaceTimeVaryingImageOnline",
|
||||
Identifier = "ScreenSpaceTimeVaryingImageOnline_Example",
|
||||
FilePath = asset.resource("data/example.json")
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
Binary file not shown.
@@ -0,0 +1,21 @@
|
||||
-- Nodes sonification
|
||||
-- This example adds the ISS and Tiangong space stations to the NodesTelemetry in the
|
||||
-- Telemetry module. This should be used together with the nodesSonification.scd file in
|
||||
-- SuperCollider to listen to an example sonification of the nodes.
|
||||
--
|
||||
-- This is a good foundation for creating your own sonification of any node(s) in
|
||||
-- OpenSpace. If you want to use this to create your own sonification, you can copy this
|
||||
-- file and the nodesSonification.scd file to your own asset folder and modify them to
|
||||
-- your liking. In this file, that modification would be to replace the ISS and Tiangong
|
||||
-- identifies with the identifiers of the node(s) you want to sonify instead.
|
||||
--
|
||||
-- For more information about sonification in OpenSpace and how to use it, see the
|
||||
-- documentation:
|
||||
-- https://docs.openspaceproject.com/latest/creating-data-assets/modules/telemetry/sonification.html
|
||||
|
||||
asset.require("scene/solarsystem/planets/earth/satellites/misc/iss")
|
||||
asset.require("scene/solarsystem/planets/earth/satellites/misc/tiangong")
|
||||
|
||||
asset.onInitialize(function ()
|
||||
openspace.telemetry.addNodes({ "ISS", "Tiangong" })
|
||||
end)
|
||||
@@ -0,0 +1,21 @@
|
||||
-- Voyager sonification
|
||||
-- This example adds the Voyager 1 and Voyager 2 probes to the NodesTelemetry in the
|
||||
-- Telemetry module. This should be used together with the voyager-sonification.scd file
|
||||
-- in SuperCollider to listen to an example sonification of the Voyager probes.
|
||||
--
|
||||
-- This is a good foundation for creating your own sonification of any node(s) in
|
||||
-- OpenSpace. If you want to use this to create your own sonification, you can copy this
|
||||
-- file and the voyager-sonification.scd file to your own asset folder and modify them to
|
||||
-- your liking. In this file, that modification would be to replace the Voyager 1 and 2
|
||||
-- identifiers with the identifiers of the node(s) you want to sonify instead.
|
||||
--
|
||||
-- For more information about sonification in OpenSpace and how to use it, see the
|
||||
-- documentation:
|
||||
-- https://docs.openspaceproject.com/latest/creating-data-assets/modules/telemetry/sonification.html
|
||||
|
||||
asset.require("scene/solarsystem/missions/voyager/voyager1")
|
||||
asset.require("scene/solarsystem/missions/voyager/voyager2")
|
||||
|
||||
asset.onInitialize(function ()
|
||||
openspace.telemetry.addNodes({ "Voyager_1", "Voyager_2" })
|
||||
end)
|
||||
@@ -0,0 +1,438 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
Platform.userExtensionDir
|
||||
NetAddr.langPort;
|
||||
NetAddr.localAddr;
|
||||
|
||||
/*****************************************************************************************
|
||||
* This is a SuperCollider file that needs to be run in the SuperCollider application *
|
||||
* that can be downloaded here: https://supercollider.github.io/ *
|
||||
* *
|
||||
* This is an example file that shows all the messages that the Telemetry module in *
|
||||
* OpenSpace can send over Open Sound Control (OSC). SuperCollider can then listen to *
|
||||
* these OSC messages and create sounds based on their content (a sonification). This *
|
||||
* example only listens to the messages and displays their content in the log to the *
|
||||
* right in the SuperCollider application. For a more extensive example that shows how *
|
||||
* to create sounds in SuperCollider based on the data from OpenSpace, see the *
|
||||
* planets-sonification.scd file located in data\assets\modules\telemetry\sonification. *
|
||||
* *
|
||||
* To run a SuperCollider file, click any line within the parentheses below, such as the *
|
||||
* marked line. When you have selected a line, press the CTRL and ENTER keys on your *
|
||||
* keyboard at the same time, and SuperCollider will run the code. You will see a *
|
||||
* message appear in the log to the right, the message should be: *
|
||||
* "-> OSCdef(Neptune, /Neptune, nil, nil, nil)". At this point, SuperCollider is ready *
|
||||
* to receive messages from OpenSpace. For a guide on how to enable and use the *
|
||||
* Telemetry module inside OpenSpace, see this documentation page: *
|
||||
* https://docs.openspaceproject.com/latest/creating-data-assets/modules/telemetry/ *
|
||||
* index.html *
|
||||
****************************************************************************************/
|
||||
|
||||
(
|
||||
|
||||
// To run this example, click this line and press CTRL + ENTER on the keyboard
|
||||
// When finished, press CTRL + . on you keyboard simultaneously to stop the sonification
|
||||
|
||||
// Camera sonification
|
||||
OSCdef.new(
|
||||
\Camera,
|
||||
{
|
||||
arg msg;
|
||||
|
||||
// msg[0] = OSC Label.
|
||||
// msg[1] = The x position of the camera in the world.
|
||||
// msg[2] = The y position of the camera in the world.
|
||||
// msg[3] = The z position of the camera in the world.
|
||||
// msg[4] = The w component of the quaternion rotation of the camera.
|
||||
// msg[5] = The x component of the quaternion rotation of the camera.
|
||||
// msg[6] = The y component of the quaternion rotation of the camera.
|
||||
// msg[7] = The z component of the quaternion rotation of the camera.
|
||||
// msg[8] = The movement speed of the camera, in the distance unit per second
|
||||
// specified by the next item.
|
||||
// msg[9] = The distance unit for the movement speed of the camera, as a string in
|
||||
// singular form with the first letter capitalized. For example,
|
||||
// "Kilometer".
|
||||
//
|
||||
// Note that the first seven items describe the position and orientation of the
|
||||
// camera. The first three items specify the x, y, and z positions of the camera
|
||||
// in the world, in relation to the solar system barycenter. The next four items
|
||||
// are the quaternion rotation of the camera in the order of w, x, y, and z.
|
||||
|
||||
("Camera: " + msg).postln;
|
||||
},
|
||||
'/Camera'
|
||||
);
|
||||
|
||||
// Focus sonification
|
||||
OSCdef.new(
|
||||
\Focus,
|
||||
{
|
||||
arg msg;
|
||||
|
||||
// msg[0] = OSC Label.
|
||||
// msg[1] = The identifier of the new focus in OpenSpace, as a string.
|
||||
|
||||
("Focus: " + msg).postln;
|
||||
},
|
||||
'/Focus'
|
||||
);
|
||||
|
||||
// Surround mode sonification
|
||||
OSCdef.new(
|
||||
\Mode,
|
||||
{
|
||||
arg msg;
|
||||
|
||||
// msg[0] = OSC Label.
|
||||
// msg[1] = The first item is an integer value that specifies what method was
|
||||
// used to calculate the angles. If the value is 0, then the method
|
||||
// used was the Horizontal angle calculation mode. In the case where
|
||||
// the value is 1, then the Circular angle calculation mode was used.
|
||||
// msg[2] = The second value is an integer value of either 0 or 1 that
|
||||
// determines if the additional elevation angle is used or not. If the
|
||||
// value is 1, the additional elevation angle is calculated. Otherwise,
|
||||
// if 0, the elevation angle is always set to 0.0.
|
||||
|
||||
("Mode: " + msg).postln;
|
||||
},
|
||||
'/Mode'
|
||||
);
|
||||
|
||||
// Time sonification
|
||||
OSCdef.new(
|
||||
\Time,
|
||||
{
|
||||
arg msg;
|
||||
|
||||
// msg[0] = OSC Label.
|
||||
// msg[1] = The speed of the simulation time, specified in the selected time unit
|
||||
// in the simulation, per real-life second. For example, 10 simulated
|
||||
// seconds per real-life second means that the simulation goes 10 times
|
||||
// faster than real-life.
|
||||
// msg[2] = The selected time unit for the speed of simulation time, as a string
|
||||
// in singular form with the first letter capitalized. For example,
|
||||
// "Day".
|
||||
// msg[3] = The current simulation time in OpenSpace specified in J2000 seconds,
|
||||
// that is, the number of seconds past the J2000 epoch
|
||||
// (i.e. January 1, 2000 12:00:00 TT).
|
||||
|
||||
("Time: " + msg).postln;
|
||||
},
|
||||
'/Time'
|
||||
);
|
||||
|
||||
// Nodes sonification, data map:
|
||||
// msg[0] = OSC Label (The identifier for each node).
|
||||
// msg[1] = The distance from the camera to the node, in the distance unit specified in
|
||||
// the last item.
|
||||
// msg[2] = The horizontal angle to the node, in radians, with the current angle
|
||||
// calculation mode taken into account. For more information, see
|
||||
// https://docs.openspaceproject.com/latest/creating-data-assets/modules/
|
||||
// telemetry/angle-information.html.
|
||||
// msg[3] = The elevation angle to the node, in radians, with the current angle
|
||||
// calculation mode taken into account. Again, see
|
||||
// https://docs.openspaceproject.com/latest/creating-data-assets/modules/
|
||||
// telemetry/angle-information.html for details.
|
||||
// msg[4] = The unit for the distance to the camera, as a string in singular form with
|
||||
// the first letter capitalized. For example, "Meter".
|
||||
|
||||
// ISS node
|
||||
OSCdef.new(
|
||||
\ISS,
|
||||
{
|
||||
arg msg;
|
||||
|
||||
// Follow the nodes sonification data map above
|
||||
|
||||
("ISS: " + msg).postln;
|
||||
},
|
||||
'/ISS'
|
||||
);
|
||||
|
||||
// Tiangong node
|
||||
OSCdef.new(
|
||||
\Tiangong,
|
||||
{
|
||||
arg msg;
|
||||
|
||||
// Follow the nodes sonification data map above
|
||||
|
||||
("Tiangong: " + msg).postln;
|
||||
},
|
||||
'/Tiangong'
|
||||
);
|
||||
|
||||
|
||||
// Planet related sonifications:
|
||||
// Compare planets
|
||||
OSCdef.new(
|
||||
\Compare,
|
||||
{
|
||||
arg msg;
|
||||
|
||||
// msg[0] = OSC Label.
|
||||
// msg[1] = The index of the first planet to be compared. See the list below on
|
||||
// how to convert the index to a planet name:
|
||||
// 0 -> None selected
|
||||
// 1 -> Mercury
|
||||
// 2 -> Venus
|
||||
// 3 -> Earth
|
||||
// 4 -> Mars
|
||||
// 5 -> Jupiter
|
||||
// 6 -> Saturn
|
||||
// 7 -> Uranus
|
||||
// 8 -> Neptune
|
||||
// msg[2] = The index of the second planet to be compared (will never be the same
|
||||
// as the first).
|
||||
// msg[3] = List of user interface settings for the comparison, which determines
|
||||
// which aspects of the sonification should be turned on or off. A value
|
||||
// of 0 means that a setting is turned off, and 1 means that it is turned
|
||||
// on. The order of the settings can be seen in the list below:
|
||||
// msg[3][0] = Size/day. 1 -> Size/day is turned on.
|
||||
// 0 -> Size/day is turned off.
|
||||
// msg[3][1] = Gravity
|
||||
// msg[3][2] = Temperature
|
||||
// msg[3][3] = Atmosphere
|
||||
// msg[3][4] = Moons
|
||||
// msg[3][5] = Rings
|
||||
|
||||
("Compare: " + msg).postln;
|
||||
|
||||
},
|
||||
'/Compare'
|
||||
);
|
||||
|
||||
// Planets overview
|
||||
OSCdef.new(
|
||||
\Overview,
|
||||
{
|
||||
arg msg;
|
||||
|
||||
// msg[0] = OSC Label.
|
||||
// msg[1] = List of user interface settings for the planets overview. This
|
||||
// determines which planets are part of the sonification or not. A value
|
||||
// of 0 means that the planet is turned off, and a 1 means that it is
|
||||
// turned on. The order of the settings can be seen in the list below:
|
||||
// msg[1][0] = Mercury. 1 -> Mercury is turned on.
|
||||
// 0 -> Mercury is turned off.
|
||||
// msg[1][1] = Venus
|
||||
// msg[1][2] = Earth
|
||||
// msg[1][3] = Mars
|
||||
// msg[1][4] = Jupiter
|
||||
// msg[1][5] = Saturn
|
||||
// msg[1][6] = Uranus
|
||||
// msg[1][7] = Neptune
|
||||
|
||||
("Overview: " + msg).postln;
|
||||
},
|
||||
'/Overview'
|
||||
);
|
||||
|
||||
// Planets sonifications, data map:
|
||||
// msg[0] = OSC Label (The name of the planet).
|
||||
// msg[1] = The distance from the camera to the planet in kilometers.
|
||||
// msg[2] = The horizontal angle in radians to the planet, with the current angle
|
||||
// calculation mode taken into account. For more information see
|
||||
// https://docs.openspaceproject.com/latest/creating-data-assets/modules/
|
||||
// telemetry/angle-information.html.
|
||||
// msg[3] = The elevation angle in radians to the planet, with the current angle
|
||||
// calculation mode taken into account. Again, see
|
||||
// https://docs.openspaceproject.com/latest/creating-data-assets/modules/
|
||||
// telemetry/angle-information.html for details.
|
||||
// msg[4] = List of user interface settings for the planet sonification, which aspects
|
||||
// of the sonification should be turned on or off. A value of 0 means that it
|
||||
// is turned off, and a 1 means that it is turned on. The order of the
|
||||
// settings can be seen in the table below. If the setting does not exist for
|
||||
// a planet, the value is always 0.
|
||||
// msg[4][0] = Size/day. 1 -> Size/day is turned on.
|
||||
// 0 -> Size/day is turned off.
|
||||
// msg[4][1] = Gravity
|
||||
// msg[4][2] = Temperature
|
||||
// msg[4][3] = Atmosphere
|
||||
// msg[4][4] = Moons
|
||||
// msg[4][5] = Rings
|
||||
// msg[5] = (optional) The distance from the camera to the first moon in kilometers.
|
||||
// msg[6] = (optional) The horizontal angle in radians to the first moon.
|
||||
// msg[7] = (optional) The elevation angle in radians to the first moon.
|
||||
// msg[8] = (optional) The distance from the camera to the second moon in kilometers.
|
||||
// msg[9] = (optional) The horizontal angle in radians to the second moon.
|
||||
// msg[10] = (optional) The elevation angle in radians to the second moon.
|
||||
// msg[...] = The data then continues in the same pattern for each of the planet's
|
||||
// moons, with three values per moon. The moons are given in order of
|
||||
// distance from the planet (closest first, farthest last) as specified in
|
||||
// the planets.asset file in the data\assets\modules\telemetry\sonification
|
||||
// folder.
|
||||
|
||||
// Mercury
|
||||
OSCdef.new(
|
||||
\Mercury,
|
||||
{
|
||||
arg msg;
|
||||
|
||||
// Follow the planets sonification data map above
|
||||
// Mercury does not have the GUI settings:
|
||||
// - Atmosphere
|
||||
// - Moons
|
||||
// - Rings
|
||||
// Mercury have no moon data since it does not have any moon
|
||||
|
||||
("Mercury: " + msg).postln;
|
||||
},
|
||||
'/Mercury'
|
||||
);
|
||||
|
||||
// Venus
|
||||
OSCdef.new(
|
||||
\Venus,
|
||||
{
|
||||
arg msg;
|
||||
|
||||
// Follow the planets sonification data map above
|
||||
// Venus does not have the GUI settings:
|
||||
// - Moons
|
||||
// - Rings
|
||||
// Venus have no moon data since it does not have any moon
|
||||
|
||||
("Venus: " + msg).postln;
|
||||
},
|
||||
'/Venus'
|
||||
);
|
||||
|
||||
// Earth
|
||||
OSCdef.new(
|
||||
\Earth,
|
||||
{
|
||||
arg msg;
|
||||
|
||||
// Follow the planets sonification data map above
|
||||
// Earth does not have the GUI settings:
|
||||
// - Rings
|
||||
// Earth have moon data for one moon:
|
||||
// - The Moon
|
||||
|
||||
("Earth: " + msg).postln;
|
||||
},
|
||||
'/Earth'
|
||||
);
|
||||
|
||||
// Mars
|
||||
OSCdef.new(
|
||||
\Mars,
|
||||
{
|
||||
arg msg;
|
||||
|
||||
// Follow the planets sonification data map above
|
||||
// Mars does not have the GUI settings:
|
||||
// - Rings
|
||||
// Mars have moon data for 2 moons in the following order:
|
||||
// - Phobos
|
||||
// - Deimos
|
||||
|
||||
("Mars: " + msg).postln;
|
||||
},
|
||||
'/Mars'
|
||||
);
|
||||
|
||||
// Jupiter
|
||||
OSCdef.new(
|
||||
\Jupiter,
|
||||
{
|
||||
arg msg;
|
||||
|
||||
// Follow the planets sonification data map above
|
||||
// Jupiter does not have the GUI settings:
|
||||
// - Rings (there are rings in real-life, but not in OpenSpace)
|
||||
// Jupiter have moon data for 4 moons in the following order:
|
||||
// - Io
|
||||
// - Europa
|
||||
// - Ganymede
|
||||
// - Callisto
|
||||
|
||||
("Jupiter: " + msg).postln;
|
||||
},
|
||||
'/Jupiter'
|
||||
);
|
||||
|
||||
// Saturn
|
||||
OSCdef.new(
|
||||
\Saturn,
|
||||
{
|
||||
arg msg;
|
||||
|
||||
// Follow the planets sonification data map above
|
||||
// Saturn have moon data for 8 moons in the following order:
|
||||
// - Dione
|
||||
// - Enceladus
|
||||
// - Hyperion
|
||||
// - Iapetus
|
||||
// - Mimas
|
||||
// - Rhea
|
||||
// - Tethys
|
||||
// - Titan
|
||||
|
||||
("Saturn: " + msg).postln;
|
||||
},
|
||||
'/Saturn'
|
||||
);
|
||||
|
||||
// Uranus
|
||||
OSCdef.new(
|
||||
\Uranus,
|
||||
{
|
||||
arg msg;
|
||||
|
||||
// Follow the planets sonification data map above
|
||||
// Uranus does not have the GUI settings:
|
||||
// - Rings (there are rings in real-life, but not in OpenSpace)
|
||||
// Uranus have moon data for 5 moons in the following order:
|
||||
// - Ariel
|
||||
// - Miranda
|
||||
// - Oberon
|
||||
// - Titania
|
||||
// - Umbriel
|
||||
|
||||
("Uranus: " + msg).postln;
|
||||
},
|
||||
'/Uranus'
|
||||
);
|
||||
|
||||
// Neptune
|
||||
OSCdef.new(
|
||||
\Neptune,
|
||||
{
|
||||
arg msg;
|
||||
|
||||
// Follow the planets sonification data map above
|
||||
// Neptune does not have the GUI settings:
|
||||
// - Rings (there are rings in real-life, but not in OpenSpace)
|
||||
// Neptune have moon data for 2 moons in the following order:
|
||||
// - Triton
|
||||
// - Nereid
|
||||
|
||||
("Neptune: " + msg).postln;
|
||||
},
|
||||
'/Neptune'
|
||||
);
|
||||
|
||||
)
|
||||
@@ -0,0 +1,390 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
Platform.userExtensionDir
|
||||
NetAddr.langPort;
|
||||
NetAddr.localAddr;
|
||||
|
||||
/*****************************************************************************************
|
||||
* This is a SuperCollider file that needs to be run in the SuperCollider application *
|
||||
* that can be downloaded here: https://supercollider.github.io/ *
|
||||
* *
|
||||
* This is an example file for the ISS and Tiangong space stations. This sonification *
|
||||
* will emit an impulse sound for both stations, with Tiangong having a higher pitch and *
|
||||
* ISS a lower pitch when the camera is close to either of the space stations. For a *
|
||||
* more extensive example that shows how to create sounds in SuperCollider based on the *
|
||||
* data from OpenSpace, see the planets-sonification.scd file located in *
|
||||
* data\assets\modules\telemetry\sonification. This sonification was made by Elias *
|
||||
* Elmquist. *
|
||||
* *
|
||||
* To run a SuperCollider file, click any line within the parentheses below, such as the *
|
||||
* marked line. When you have selected a line, press the CTRL and ENTER keys on your *
|
||||
* keyboard at the same time, and SuperCollider will run the code. You will see several *
|
||||
* messages appear in the log to the right, the last message should be: *
|
||||
* "---------- Sonification is ready ----------". At this point, SuperCollider is ready *
|
||||
* to receive messages from OpenSpace and produce the sonification. For a guide on how *
|
||||
* to enable and use the Telemetry module inside OpenSpace, see this documentation page: *
|
||||
* https://docs.openspaceproject.com/latest/creating-data-assets/modules/telemetry/ *
|
||||
* index.html *
|
||||
****************************************************************************************/
|
||||
|
||||
(
|
||||
|
||||
// To run this example, click this line and press CTRL + ENTER on the keyboard
|
||||
// When finished, press CTRL + . on you keyboard simultaneously to stop the sonification
|
||||
|
||||
s.quit;
|
||||
o = Server.default.options;
|
||||
|
||||
// TODO Update this to use the angle calculation setting in OpenSpace
|
||||
// 0: Stereo (Binaurual)
|
||||
// 1: VisC Dome
|
||||
// 2: Hayden
|
||||
~setup = 0;
|
||||
|
||||
if((~setup == 0),
|
||||
{~numSpeakerChannels = 2;}
|
||||
);
|
||||
|
||||
if((~setup == 1),
|
||||
{o.outDevice_("ASIO : Focusrite USB ASIO");
|
||||
~numSpeakerChannels = 8;
|
||||
}
|
||||
);
|
||||
|
||||
if((~setup == 2),
|
||||
{o.outDevice_("ASIO : ASIO MADIface USB");
|
||||
~numSpeakerChannels = 32;
|
||||
}
|
||||
);
|
||||
|
||||
o.numOutputBusChannels = ~numSpeakerChannels;
|
||||
|
||||
//3D
|
||||
~ampMode = 1;
|
||||
~focusType = 1;
|
||||
~lockedFocus = 0;
|
||||
~comparisonMode = 1;
|
||||
|
||||
// Setup which nodes to listen to in OpenSpace
|
||||
~oscLabel0 = \ISS;
|
||||
~oscLabel1 = \Tiangong;
|
||||
|
||||
s.reboot;
|
||||
s.waitForBoot{
|
||||
var loadSynths = {
|
||||
// Create a sound function to play a poof sound
|
||||
SynthDef(
|
||||
\synth,
|
||||
{
|
||||
arg out=0, gate=1, mamp=5, amp=0, baseAmp=1, freq=400, buf, loop=0, rate=1, da=0, atk=1, dcay=0, suslvl=1, rel=1, mute=1, trig=0, phase=0;
|
||||
var sig=0, env, t_gate=0;
|
||||
|
||||
t_gate = gate * LFPulse.kr(0.2,phase);
|
||||
|
||||
env = EnvGen.kr(
|
||||
Env.perc(0.01,1/0.5),
|
||||
t_gate,
|
||||
doneAction:0
|
||||
);
|
||||
|
||||
sig = BrownNoise.ar(1);
|
||||
sig = (BPF.ar(sig, freq*2, 0.004) * 50);
|
||||
sig = mamp * sig;
|
||||
sig = mute.lag(5) * (baseAmp*amp) * sig * env;
|
||||
|
||||
Out.ar(out, sig);
|
||||
}
|
||||
).add;
|
||||
|
||||
// Setup Ambisonics
|
||||
~order = 2; // set this to the order you want
|
||||
~numChannels = ((~order + 1)**2).asInteger;
|
||||
|
||||
// binaural decoder (~numChannels -> 2) - reads from 'bus' and sums into 'out'
|
||||
SynthDef.new(\binauralDecoder, { | bus, out = 0 |
|
||||
Out.ar(out, VSTPlugin.ar(In.ar(bus, ~numChannels), 2));
|
||||
}).add;
|
||||
|
||||
SynthDef.new(\allraDecoder, { | bus, out = 0 |
|
||||
Out.ar(out, VSTPlugin.ar(In.ar(bus, ~numChannels), ~numSpeakerChannels));
|
||||
}).add;
|
||||
|
||||
// stereo encoder (2 -> ~numChannels) - replaces stereo signal with ambisonics signal
|
||||
SynthDef.new(\stereoEncoder, { | bus = 0 |
|
||||
ReplaceOut.ar(bus, VSTPlugin.ar(In.ar(bus, 2), ~numChannels));
|
||||
}).add;
|
||||
|
||||
// ambisonics insert FX Surround (replaces input with output)
|
||||
SynthDef.new(\ambiFX, { | bus = 0, bypass |
|
||||
ReplaceOut.ar(bus, VSTPlugin.ar(In.ar(bus, ~numChannels), ~numChannels, bypass));
|
||||
}).add;
|
||||
|
||||
// helper Synth (throws audio from ambi bus to ambi master bus)
|
||||
SynthDef.new(\ambiThrow, { | from, to |
|
||||
Out.ar(to, In.ar(from, ~numChannels));
|
||||
}).add;
|
||||
};
|
||||
|
||||
|
||||
var initiateAmbisonic = {
|
||||
// bus + group
|
||||
~ambiMasterBus = Bus.audio(s, ~numChannels);
|
||||
~ambiMasterGroup = Group.new;
|
||||
|
||||
if((~setup == 0),
|
||||
// binaural decoder (writes to master output)
|
||||
{~decoder = VSTPluginController(Synth(\binauralDecoder, [\bus, ~ambiMasterBus, \out, 0], target: ~ambiMasterGroup, addAction: \addToTail)).open("BinauralDecoder");},
|
||||
// AllRA decoder
|
||||
{~decoder = VSTPluginController(Synth(\allraDecoder, [\bus, ~ambiMasterBus, \out, 0], target: ~ambiMasterGroup, addAction: \addToTail)).open("SimpleDecoder");}
|
||||
);
|
||||
|
||||
// ambisonics insert FX (replaces input with output)
|
||||
SynthDef.new(\ambiFX, { | bus = 0, bypass |
|
||||
ReplaceOut.ar(bus, VSTPlugin.ar(In.ar(bus, 2), ~numChannels, bypass));
|
||||
}).add;
|
||||
|
||||
// a group for ambisonic master effects
|
||||
~ambiMasterFXGroup = Group.before(~decoder.synth);
|
||||
};
|
||||
|
||||
var initiateSynths = {
|
||||
// create ambisonic busses
|
||||
~soundBus = Array.newClear(7);
|
||||
~numBus = ~soundBus.size;
|
||||
~ambiBus = Array.newClear(~numBus);
|
||||
~ambiGroup = Array.newClear(~numBus);
|
||||
~encoder = Array.newClear(~numBus);
|
||||
~sounds = Array.newClear(~numBus);
|
||||
|
||||
// First Poof
|
||||
~ambiBus[0] = Bus.audio(s, ~numChannels);
|
||||
~ambiGroup[0] = Group.before(~ambiMasterGroup);
|
||||
~sounds[0] = Synth.new(\synth, [\out, ~ambiBus[0], \freq, 200], ~ambiGroup[0], addAction: \addToHead);
|
||||
~encoder[0] = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBus[0]], target: ~ambiGroup[0], addAction: \addToTail));
|
||||
~encoder[0].open("StereoEncoder", action: { |self| self.set(6, 0.5) }); // 6 -> azimuth
|
||||
Synth(\ambiThrow, [\from, ~ambiBus[0], \to, ~ambiMasterBus], target: ~ambiGroup[0], addAction: \addToTail);
|
||||
|
||||
// Second Poof
|
||||
~ambiBus[1] = Bus.audio(s, ~numChannels);
|
||||
~ambiGroup[1] = Group.before(~ambiMasterGroup);
|
||||
~sounds[1] = Synth.new(\synth, [\out, ~ambiBus[1], \freq, 400, \phase, 0.3], ~ambiGroup[1], addAction: \addToHead);
|
||||
~encoder[1] = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBus[1]], target: ~ambiGroup[1], addAction: \addToTail));
|
||||
~encoder[1].open("StereoEncoder", action: { |self| self.set(6, 0.6) }); // 6 -> azimuth
|
||||
Synth(\ambiThrow, [\from, ~ambiBus[1], \to, ~ambiMasterBus], target: ~ambiGroup[1], addAction: \addToTail);
|
||||
|
||||
//Audio mixing of the sounds (if needed)
|
||||
~sounds[0].set(\baseAmp, 0.3);
|
||||
~sounds[1].set(\baseAmp, 0.3);
|
||||
|
||||
// Debugging spatial position
|
||||
//~encoder[0].editor;
|
||||
|
||||
// add an ambisonic master FX
|
||||
~ambiReverb = VSTPluginController(Synth(\ambiFX, [\bus, ~ambiMasterBus, \out, 0],
|
||||
target: ~ambiMasterFXGroup)).open("FdnReverb", action: { |self| self.set(1, 0.2) });
|
||||
};
|
||||
|
||||
var loadDecoder = {
|
||||
if((~setup == 1),
|
||||
{
|
||||
~decoder.iemPluginOSC("/SimpleDecoder/loadFile", thisProcess.nowExecutingPath.dirname +/+ "AmbiDecoders" +/+ "DomenVisC_5th.json");
|
||||
0.1.wait;
|
||||
~decoder.iemPluginOSC("/SimpleDecoder/swMode", 1);
|
||||
0.1.wait;
|
||||
~decoder.iemPluginOSC("/SimpleDecoder/swChannel", 4);
|
||||
0.1.wait;
|
||||
~decoder.iemPluginOSC("/SimpleDecoder/lowPassGain", -12);
|
||||
}
|
||||
);
|
||||
|
||||
if((~setup == 2),
|
||||
{
|
||||
~decoder.iemPluginOSC("/SimpleDecoder/loadFile", thisProcess.nowExecutingPath.dirname +/+ "AmbiDecoders" +/+ "HaydenIEM_5th_0deg_80top_rot180deg.json");
|
||||
0.1.wait;
|
||||
~decoder.iemPluginOSC("/SimpleDecoder/swMode", 1);
|
||||
0.1.wait;
|
||||
~decoder.iemPluginOSC("/SimpleDecoder/swChannel", 32);
|
||||
0.1.wait;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// Set which OSC labels to listen to
|
||||
var oscDef = {
|
||||
|
||||
//Horizontal mode
|
||||
~modeElSign = 1;
|
||||
~modeElPhase = 0.5;
|
||||
|
||||
//Circular mode (switch manually)
|
||||
//~modeElSign = -1;
|
||||
//~modeElPhase = 0.75;
|
||||
|
||||
//Size of hearable area
|
||||
~distanceLimit = 10;
|
||||
|
||||
//Ambient amp
|
||||
~ambientAmp = 1.0;
|
||||
|
||||
OSCdef.new(\Mode,
|
||||
{
|
||||
arg msg;
|
||||
|
||||
//msg[1] == 0 -> Horizontal
|
||||
//msg[1] == 1 -> Circular
|
||||
|
||||
//msg[2] == 0 -> Elevation on
|
||||
//msg[2] == 1 -> Elevation off
|
||||
|
||||
("SurroundMode:" + msg[1]).postln;
|
||||
|
||||
//Horizontal
|
||||
if(((msg[1]==0)),
|
||||
{~modeElSign = 1;
|
||||
~modeElPhase = 0.5;},
|
||||
{}
|
||||
);
|
||||
|
||||
//Circular
|
||||
if(((msg[1]==1)),
|
||||
{~modeElSign = -1;
|
||||
~modeElPhase = 0.75;},
|
||||
{}
|
||||
);
|
||||
|
||||
("~modeElSign:" + ~modeElSign).postln;
|
||||
("~modeElPhase:" + ~modeElPhase).postln;
|
||||
|
||||
},'/Mode');
|
||||
|
||||
OSCdef.new(
|
||||
~oscLabel0,
|
||||
{
|
||||
arg msg;
|
||||
var name, distance, invDistance, azimuth, amp, value, elevation;
|
||||
|
||||
//msg[1]: label distance
|
||||
//msg[2]: label azimuth
|
||||
//msg[3]: label elevation
|
||||
|
||||
// DEBUG: Uncomment this line to get console output of all messages from OpenSpace
|
||||
//(~oscLabel0 ++ ": " ++ msg).postln;
|
||||
|
||||
name = msg[0].asString;
|
||||
|
||||
distance = msg[1]/1000000;
|
||||
|
||||
//invDistance = ~distanceLimit-distance;
|
||||
|
||||
azimuth = (msg[2]/(2*pi))+0.5;
|
||||
elevation = ~modeElSign*(msg[3]/(2*pi))+~modeElPhase;
|
||||
|
||||
if((~ampMode == 1),
|
||||
{
|
||||
if((distance < ~distanceLimit),
|
||||
{amp = LinLin.kr(distance, 0, ~distanceLimit, 0, 1);
|
||||
|
||||
},
|
||||
{amp = ~ambientAmp;}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
(~oscLabel0 ++ "Amp: " ++ amp).postln;
|
||||
~sounds[0].set(\amp, amp);
|
||||
~encoder[0].do(_.set(6, azimuth));
|
||||
~encoder[0].do(_.set(7, elevation));
|
||||
},
|
||||
~oscLabel0
|
||||
);
|
||||
|
||||
OSCdef.new(
|
||||
~oscLabel1,
|
||||
{
|
||||
arg msg;
|
||||
var name, distance, invDistance, azimuth, amp, value, elevation;
|
||||
|
||||
//msg[1]: label distance
|
||||
//msg[2]: label azimuth
|
||||
//msg[3]: label elevation
|
||||
|
||||
// DEBUG: Uncomment this line to get console output of messages from OpenSpace
|
||||
//(~oscLabel1 ++ ": " ++ msg).postln;
|
||||
|
||||
name = msg[0].asString;
|
||||
|
||||
distance = msg[1]/10000;
|
||||
|
||||
//invDistance = ~distanceLimit-distance;
|
||||
|
||||
azimuth = (msg[2]/(2*pi))+0.5;
|
||||
elevation = ~modeElSign*(msg[3]/(2*pi))+~modeElPhase;
|
||||
|
||||
if((~ampMode == 1),
|
||||
{
|
||||
if((distance < ~distanceLimit),
|
||||
{amp = LinLin.kr(distance, 0, ~distanceLimit, 0, 1);
|
||||
|
||||
},
|
||||
{amp = ~ambientAmp;}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
(~oscLabel1 ++ "Amp: " ++ amp).postln;
|
||||
~sounds[1].set(\amp, amp);
|
||||
~encoder[1].do(_.set(6, azimuth));
|
||||
~encoder[1].do(_.set(7, elevation));
|
||||
|
||||
},
|
||||
~oscLabel1
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
// Start routine
|
||||
~startRoutine = Routine({
|
||||
0.5.wait;
|
||||
loadSynths.value;
|
||||
"--Loaded the synths--".postln;
|
||||
0.3.wait;
|
||||
initiateAmbisonic.value;
|
||||
"--Loaded the ambisonics--".postln;
|
||||
0.3.wait;
|
||||
initiateSynths.value;
|
||||
"--Initiated the synths--".postln;
|
||||
0.2.wait;
|
||||
loadDecoder.value;
|
||||
"--Loaded the decoder--".postln;
|
||||
0.2.wait;
|
||||
oscDef.value;
|
||||
"--Loaded the OSCdefs--".postln;
|
||||
"---------- Sonification is ready ----------".postln;
|
||||
});
|
||||
|
||||
~startRoutine.play(AppClock);
|
||||
}
|
||||
|
||||
)
|
||||
@@ -0,0 +1,402 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
Platform.userExtensionDir
|
||||
NetAddr.langPort;
|
||||
NetAddr.localAddr;
|
||||
|
||||
/*****************************************************************************************
|
||||
* This is a SuperCollider file that needs to be run in the SuperCollider application *
|
||||
* that can be downloaded here: https://supercollider.github.io/ *
|
||||
* *
|
||||
* This is an example file for the Voyager 1 and 2 space probes. This sonification will *
|
||||
* play and loop the Greetings to the Universe audio clip (one of the recordings *
|
||||
* included on the Golden Records aboard both probes) when the camera is close to either *
|
||||
* of the probes. For a more extensive example that shows how to create sounds in *
|
||||
* SuperCollider based on the data from OpenSpace, see the planets-sonification.scd file *
|
||||
* located in data\assets\modules\telemetry\sonification. This sonification was made by *
|
||||
* Elias Elmquist. *
|
||||
* *
|
||||
* To run a SuperCollider file, click any line within the parentheses below, such as the *
|
||||
* marked line. When you have selected a line, press the CTRL and ENTER keys on your *
|
||||
* keyboard at the same time, and SuperCollider will run the code. You will see several *
|
||||
* messages appear in the log to the right, the last message should be: *
|
||||
* "---------- Sonification is ready ----------". At this point, SuperCollider is ready *
|
||||
* to receive messages from OpenSpace and produce the sonification. For a guide on how *
|
||||
* to enable and use the Telemetry module inside OpenSpace, see the documentation page: *
|
||||
* https://docs.openspaceproject.com/latest/creating-data-assets/modules/telemetry/ *
|
||||
* index.html *
|
||||
****************************************************************************************/
|
||||
|
||||
(
|
||||
|
||||
// To run this example, click this line and press CTRL + ENTER on the keyboard
|
||||
// When finished, press CTRL + . on you keyboard simultaneously to stop the sonification
|
||||
|
||||
s.quit;
|
||||
o = Server.default.options;
|
||||
|
||||
// TODO Update this to use the angle calculation setting in OpenSpace
|
||||
// Set the surround setting
|
||||
// 0: Stereo (Binaurual)
|
||||
// 1: VisC Dome
|
||||
// 2: Hayden
|
||||
~setup = 0;
|
||||
|
||||
if((~setup == 0),
|
||||
{~numSpeakerChannels = 2;}
|
||||
);
|
||||
|
||||
if((~setup == 1),
|
||||
{o.outDevice_("ASIO : Focusrite USB ASIO");
|
||||
~numSpeakerChannels = 8;
|
||||
}
|
||||
);
|
||||
|
||||
if((~setup == 2),
|
||||
{o.outDevice_("ASIO : ASIO MADIface USB");
|
||||
~numSpeakerChannels = 32;
|
||||
}
|
||||
);
|
||||
|
||||
o.numOutputBusChannels = ~numSpeakerChannels;
|
||||
|
||||
//3D
|
||||
~ampMode = 1;
|
||||
~focusType = 1;
|
||||
~lockedFocus = 0;
|
||||
~comparisonMode = 1;
|
||||
|
||||
// Setup which nodes to listen to in OpenSpace
|
||||
~oscLabel0 = \Voyager_1;
|
||||
~oscLabel1 = \Voyager_2;
|
||||
|
||||
s.reboot;
|
||||
s.waitForBoot{
|
||||
// Load the Greetings to the Universe audio clip (located next to this file)
|
||||
var filePath = thisProcess.nowExecutingPath.dirname;
|
||||
var loadSamples = {
|
||||
~b1 = Buffer.read(s, filePath +/+ "Greetings_from_Earth_mono.wav");
|
||||
// To load another audio clip, copy the line above, change the variable name
|
||||
// and the path to the audio file
|
||||
};
|
||||
|
||||
var loadSynths = {
|
||||
// Create a sound function to play and loop the audio clip
|
||||
SynthDef(
|
||||
\audiofile,
|
||||
{
|
||||
arg out=0, gate=1, mamp=5, amp=0, baseAmp=1, buf, loop=0, rate=1, da=0, atk=1, dcay=0, suslvl=1, rel=1, mute=1, trig=0;
|
||||
var sig=0, env;
|
||||
|
||||
env = EnvGen.kr(
|
||||
Env.adsr(atk,dcay,suslvl,rel),
|
||||
gate,
|
||||
doneAction:da
|
||||
);
|
||||
|
||||
sig = PlayBuf.ar(1, buf, rate:rate, loop:loop, trigger:trig);
|
||||
sig = mamp * sig;
|
||||
sig = mute.lag(5) * (baseAmp*amp) * sig * env;
|
||||
|
||||
Out.ar(out, sig);
|
||||
}
|
||||
).add;
|
||||
|
||||
|
||||
// Setup Ambisonics
|
||||
~order = 2; // set this to the order you want
|
||||
~numChannels = ((~order + 1)**2).asInteger;
|
||||
|
||||
// binaural decoder (~numChannels -> 2) - reads from 'bus' and sums into 'out'
|
||||
SynthDef.new(\binauralDecoder, { | bus, out = 0 |
|
||||
Out.ar(out, VSTPlugin.ar(In.ar(bus, ~numChannels), 2));
|
||||
}).add;
|
||||
|
||||
SynthDef.new(\allraDecoder, { | bus, out = 0 |
|
||||
Out.ar(out, VSTPlugin.ar(In.ar(bus, ~numChannels), ~numSpeakerChannels));
|
||||
}).add;
|
||||
|
||||
// stereo encoder (2 -> ~numChannels) - replaces stereo signal with ambisonics signal
|
||||
SynthDef.new(\stereoEncoder, { | bus = 0 |
|
||||
ReplaceOut.ar(bus, VSTPlugin.ar(In.ar(bus, 2), ~numChannels));
|
||||
}).add;
|
||||
|
||||
// ambisonics insert FX Surround (replaces input with output)
|
||||
SynthDef.new(\ambiFX, { | bus = 0, bypass |
|
||||
ReplaceOut.ar(bus, VSTPlugin.ar(In.ar(bus, ~numChannels), ~numChannels, bypass));
|
||||
}).add;
|
||||
|
||||
// helper Synth (throws audio from ambi bus to ambi master bus)
|
||||
SynthDef.new(\ambiThrow, { | from, to |
|
||||
Out.ar(to, In.ar(from, ~numChannels));
|
||||
}).add;
|
||||
};
|
||||
|
||||
var initiateAmbisonic = {
|
||||
// bus + group
|
||||
~ambiMasterBus = Bus.audio(s, ~numChannels);
|
||||
~ambiMasterGroup = Group.new;
|
||||
|
||||
if((~setup == 0),
|
||||
// binaural decoder (writes to master output)
|
||||
{~decoder = VSTPluginController(Synth(\binauralDecoder, [\bus, ~ambiMasterBus, \out, 0], target: ~ambiMasterGroup, addAction: \addToTail)).open("BinauralDecoder");},
|
||||
// AllRA decoder
|
||||
{~decoder = VSTPluginController(Synth(\allraDecoder, [\bus, ~ambiMasterBus, \out, 0], target: ~ambiMasterGroup, addAction: \addToTail)).open("SimpleDecoder");}
|
||||
);
|
||||
|
||||
// ambisonics insert FX (replaces input with output)
|
||||
SynthDef.new(\ambiFX, { | bus = 0, bypass |
|
||||
ReplaceOut.ar(bus, VSTPlugin.ar(In.ar(bus, 2), ~numChannels, bypass));
|
||||
}).add;
|
||||
|
||||
// a group for ambisonic master effects
|
||||
~ambiMasterFXGroup = Group.before(~decoder.synth);
|
||||
};
|
||||
|
||||
var initiateSynths = {
|
||||
// create ambisonic busses
|
||||
~soundBus = Array.newClear(7);
|
||||
~numBus = ~soundBus.size;
|
||||
~ambiBus = Array.newClear(~numBus);
|
||||
~ambiGroup = Array.newClear(~numBus);
|
||||
~encoder = Array.newClear(~numBus);
|
||||
~sounds = Array.newClear(~numBus);
|
||||
|
||||
// First Audio clip
|
||||
~ambiBus[0] = Bus.audio(s, ~numChannels);
|
||||
~ambiGroup[0] = Group.before(~ambiMasterGroup);
|
||||
~sounds[0] = Synth.new(\audiofile, [\out, ~ambiBus[0], \buf, ~b1], ~ambiGroup[0], addAction: \addToHead);
|
||||
~encoder[0] = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBus[0]], target: ~ambiGroup[0], addAction: \addToTail));
|
||||
~encoder[0].open("StereoEncoder", action: { |self| self.set(6, 0.5) }); // 6 -> azimuth
|
||||
Synth(\ambiThrow, [\from, ~ambiBus[0], \to, ~ambiMasterBus], target: ~ambiGroup[0], addAction: \addToTail);
|
||||
|
||||
// Second Audio clip (if needed)
|
||||
/*~ambiBus[1] = Bus.audio(s, ~numChannels);
|
||||
~ambiGroup[1] = Group.before(~ambiMasterGroup);
|
||||
~sounds[1] = Synth.new(\audiofile, [\out, ~ambiBus[1], \buf, ~b2], ~ambiGroup[1], addAction: \addToHead);
|
||||
~encoder[1] = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBus[1]], target: ~ambiGroup[1], addAction: \addToTail));
|
||||
~encoder[1].open("StereoEncoder", action: { |self| self.set(6, 0.6) }); // 6 -> azimuth
|
||||
Synth(\ambiThrow, [\from, ~ambiBus[1], \to, ~ambiMasterBus], target: ~ambiGroup[1], addAction: \addToTail);
|
||||
|
||||
//Audio mixing of the sounds (if needed)
|
||||
~sounds[0].set(\baseAmp, 0.3);
|
||||
~sounds[1].set(\baseAmp, 0.3);*/
|
||||
|
||||
// Debugging spatial position
|
||||
//~encoder[0].editor;
|
||||
|
||||
~sounds[0].set(\baseAmp, 0.3);
|
||||
|
||||
// add an ambisonic master FX
|
||||
~ambiReverb = VSTPluginController(Synth(\ambiFX, [\bus, ~ambiMasterBus, \out, 0],
|
||||
target: ~ambiMasterFXGroup)).open("FdnReverb", action: { |self| self.set(1, 0.2) });
|
||||
|
||||
};
|
||||
|
||||
var loadDecoder = {
|
||||
if((~setup == 1),
|
||||
{
|
||||
~decoder.iemPluginOSC("/SimpleDecoder/loadFile", thisProcess.nowExecutingPath.dirname +/+ "AmbiDecoders" +/+ "DomenVisC_5th.json");
|
||||
0.1.wait;
|
||||
~decoder.iemPluginOSC("/SimpleDecoder/swMode", 1);
|
||||
0.1.wait;
|
||||
~decoder.iemPluginOSC("/SimpleDecoder/swChannel", 4);
|
||||
0.1.wait;
|
||||
~decoder.iemPluginOSC("/SimpleDecoder/lowPassGain", -12);
|
||||
}
|
||||
);
|
||||
|
||||
if((~setup == 2),
|
||||
{
|
||||
~decoder.iemPluginOSC("/SimpleDecoder/loadFile", thisProcess.nowExecutingPath.dirname +/+ "AmbiDecoders" +/+ "HaydenIEM_5th_0deg_80top_rot180deg.json");
|
||||
0.1.wait;
|
||||
~decoder.iemPluginOSC("/SimpleDecoder/swMode", 1);
|
||||
0.1.wait;
|
||||
~decoder.iemPluginOSC("/SimpleDecoder/swChannel", 32);
|
||||
0.1.wait;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// Set which OSC labels to listen to
|
||||
var oscDef = {
|
||||
|
||||
|
||||
//Horizontal mode
|
||||
~modeElSign = 1;
|
||||
~modeElPhase = 0.5;
|
||||
|
||||
//Circular mode (switch manually)
|
||||
//~modeElSign = -1;
|
||||
//~modeElPhase = 0.75;
|
||||
|
||||
//Size of hearable area
|
||||
~distanceLimit = 0.5;
|
||||
|
||||
//Ambient amp
|
||||
~ambientAmp = 1.0;
|
||||
|
||||
OSCdef.new(\Mode,
|
||||
{
|
||||
arg msg;
|
||||
|
||||
//msg[1] == 0 -> Horizontal
|
||||
//msg[1] == 1 -> Circular
|
||||
|
||||
//msg[2] == 0 -> Elevation on
|
||||
//msg[2] == 1 -> Elevation off
|
||||
|
||||
("SurroundMode:" + msg[1]).postln;
|
||||
|
||||
//Horizontal
|
||||
if(((msg[1]==0)),
|
||||
{~modeElSign = 1;
|
||||
~modeElPhase = 0.5;},
|
||||
{}
|
||||
);
|
||||
|
||||
//Circular
|
||||
if(((msg[1]==1)),
|
||||
{~modeElSign = -1;
|
||||
~modeElPhase = 0.75;},
|
||||
{}
|
||||
);
|
||||
|
||||
("~modeElSign:" + ~modeElSign).postln;
|
||||
("~modeElPhase:" + ~modeElPhase).postln;
|
||||
|
||||
},'/Mode');
|
||||
|
||||
OSCdef.new(
|
||||
~oscLabel0,
|
||||
{
|
||||
arg msg;
|
||||
var name, distance, invDistance, azimuth, amp, value, elevation;
|
||||
|
||||
//msg[1]: label distance
|
||||
//msg[2]: label azimuth
|
||||
//msg[3]: label elevation
|
||||
|
||||
// DEBUG: Uncomment this line to get console output of all messages from OpenSpace
|
||||
//(~oscLabel0 ++ ": " ++ msg).postln;
|
||||
|
||||
name = msg[0].asString;
|
||||
|
||||
distance = msg[1]/1000000;
|
||||
|
||||
//invDistance = ~distanceLimit-distance;
|
||||
|
||||
azimuth = (msg[2]/(2*pi))+0.5;
|
||||
elevation = ~modeElSign*(msg[3]/(2*pi))+~modeElPhase;
|
||||
|
||||
if((~ampMode == 1),
|
||||
{
|
||||
if((distance < ~distanceLimit),
|
||||
{amp = LinLin.kr(distance, 0, ~distanceLimit, 0, 1);
|
||||
|
||||
},
|
||||
{amp = ~ambientAmp;}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
(~oscLabel0 ++ "Amp: " ++ amp).postln;
|
||||
~sounds[0].set(\amp, amp);
|
||||
~encoder[0].do(_.set(6, azimuth));
|
||||
~encoder[0].do(_.set(7, elevation));
|
||||
},
|
||||
~oscLabel0
|
||||
);
|
||||
|
||||
OSCdef.new(
|
||||
~oscLabel1,
|
||||
{
|
||||
arg msg;
|
||||
var name, distance, invDistance, azimuth, amp, value, elevation;
|
||||
|
||||
//msg[1]: label distance
|
||||
//msg[2]: label azimuth
|
||||
//msg[3]: label elevation
|
||||
|
||||
// DEBUG: Uncomment this line to get console output of all messages from OpenSpace
|
||||
//(~oscLabel1 ++ ": " ++ msg).postln;
|
||||
|
||||
name = msg[0].asString;
|
||||
|
||||
distance = msg[1]/1000000;
|
||||
|
||||
//invDistance = ~distanceLimit-distance;
|
||||
|
||||
azimuth = (msg[2]/(2*pi))+0.5;
|
||||
elevation = ~modeElSign*(msg[3]/(2*pi))+~modeElPhase;
|
||||
|
||||
if((~ampMode == 1),
|
||||
{
|
||||
if((distance < ~distanceLimit),
|
||||
{amp = LinLin.kr(distance, 0, ~distanceLimit, 0, 1);
|
||||
|
||||
},
|
||||
{amp = ~ambientAmp;}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
(~oscLabel1 ++ "Amp: " ++ amp).postln;
|
||||
~sounds[0].set(\amp, amp);
|
||||
~encoder[0].do(_.set(6, azimuth));
|
||||
~encoder[0].do(_.set(7, elevation));
|
||||
},
|
||||
~oscLabel1
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
// Start routine
|
||||
~startRoutine = Routine({
|
||||
0.5.wait;
|
||||
loadSamples.value;
|
||||
"--Loaded the data--".postln;
|
||||
0.2.wait;
|
||||
loadSynths.value;
|
||||
"--Loaded the synths--".postln;
|
||||
0.3.wait;
|
||||
initiateAmbisonic.value;
|
||||
"--Loaded the ambisonics--".postln;
|
||||
0.3.wait;
|
||||
initiateSynths.value;
|
||||
"--Initiated the synths--".postln;
|
||||
0.2.wait;
|
||||
loadDecoder.value;
|
||||
"--Loaded the decoder--".postln;
|
||||
0.2.wait;
|
||||
oscDef.value;
|
||||
"--Loaded the OSCdefs--".postln;
|
||||
"---------- Sonification is ready ----------".postln;
|
||||
});
|
||||
|
||||
~startRoutine.play(AppClock);
|
||||
}
|
||||
|
||||
)
|
||||
@@ -0,0 +1,44 @@
|
||||
-- CK Multiple
|
||||
-- This example creates a time frame based on the information provided by multiple SPICE
|
||||
-- kernel files that contain orientation information about the same object. The created
|
||||
-- scene graph node will only be valid whenever any window in any of the provided kernels
|
||||
-- contains information about refernence frame "-98000", which is the intertial
|
||||
-- orientation frame for the New Horizons spacecraft.
|
||||
|
||||
-- We need a SPICE kernel to work with in this example
|
||||
local data = asset.resource({
|
||||
Name = "New Horizons Kernels",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "newhorizons_kernels",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local Node = {
|
||||
Identifier = "TimeFrameKernel_Example_CK_Multiple",
|
||||
TimeFrame = {
|
||||
Type = "TimeFrameKernel",
|
||||
CK = {
|
||||
Kernels = {
|
||||
data .. "nh_apf_20150404_20150420_001.bc",
|
||||
data .. "nh_apf_20150420_20150504_001.bc",
|
||||
data .. "new-horizons_1121.tsc"
|
||||
},
|
||||
Reference = "-98000"
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableCartesianAxes"
|
||||
},
|
||||
GUI = {
|
||||
Name = "TimeFrameKernel - Basic (CK, Multiple)",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(Node)
|
||||
end)
|
||||
@@ -0,0 +1,42 @@
|
||||
-- CK Basic
|
||||
-- This example creates a time frame based on the information provided by a single SPICE
|
||||
-- kernel file. The created scene graph node will only be valid whenever the provided
|
||||
-- kernel contains information about about the reference frame "-98000", which is the
|
||||
-- interial orientation frame for the New Horizons spacecraft.
|
||||
|
||||
-- We need a SPICE kernel to work with in this example
|
||||
local data = asset.resource({
|
||||
Name = "New Horizons Kernels",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "newhorizons_kernels",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local Node = {
|
||||
Identifier = "TimeFrameKernel_Example_CK",
|
||||
TimeFrame = {
|
||||
Type = "TimeFrameKernel",
|
||||
CK = {
|
||||
Kernels = {
|
||||
data .. "nh_apf_20150404_20150420_001.bc",
|
||||
data .. "new-horizons_1121.tsc",
|
||||
},
|
||||
Reference = "-98000"
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableCartesianAxes"
|
||||
},
|
||||
GUI = {
|
||||
Name = "TimeFrameKernel - Basic (CK)",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(Node)
|
||||
end)
|
||||
@@ -0,0 +1,48 @@
|
||||
-- Combined example
|
||||
-- This example creates a time frame based on the information provided by multiple SPICE
|
||||
-- kernel files. The created scene graph node will only be valid whenever the provided
|
||||
-- kernels contain information positional information about the object "JUICE" as well as
|
||||
-- orientation information for the reference frame "-28002" which is the measured attitude
|
||||
-- for the JUICE spacecraft. The time frame will only be valid if both pieces of data are
|
||||
-- available.
|
||||
|
||||
-- We need a SPICE kernel to work with in this example
|
||||
local data = asset.resource({
|
||||
Name = "JUICE Kernels",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "juice_kernels",
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local Node = {
|
||||
Identifier = "TimeFrameKernel_Example_Combined_SPK-CK",
|
||||
TimeFrame = {
|
||||
Type = "TimeFrameKernel",
|
||||
SPK = {
|
||||
Kernels = data .. "juice_orbc_000031_230414_310721_v03.bsp",
|
||||
Object = "JUICE"
|
||||
},
|
||||
CK = {
|
||||
Kernels = {
|
||||
data .. "juice_sc_meas_230413_230415_s230414_v01.bc",
|
||||
data .. "juice_step_230414_v01.tsc"
|
||||
},
|
||||
Reference = "-28002"
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableCartesianAxes"
|
||||
},
|
||||
GUI = {
|
||||
Name = "TimeFrameKernel - Combined (SPK+CK)",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(Node)
|
||||
end)
|
||||
@@ -0,0 +1,42 @@
|
||||
-- SPK Multiple
|
||||
-- This example creates a time frame based on the information provided by multiple SPICE
|
||||
-- kernel files that contain position information about the same object. The created scene
|
||||
-- graph node will only be valid whenever any window in any of the provided kernels
|
||||
-- contains information about object "VOYAGER 1".
|
||||
|
||||
-- We need a SPICE kernel to work with in this example
|
||||
local data = asset.resource({
|
||||
Name = "Voyager 1 Kernels",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "voyager1_spice",
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local Node = {
|
||||
Identifier = "TimeFrameKernel_Example_SPK_Multiple",
|
||||
TimeFrame = {
|
||||
Type = "TimeFrameKernel",
|
||||
SPK = {
|
||||
Kernels = {
|
||||
data .. "vgr1_jup230.bsp",
|
||||
data .. "vgr1_sat337.bsp"
|
||||
},
|
||||
Object = "VOYAGER 1"
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableCartesianAxes"
|
||||
},
|
||||
GUI = {
|
||||
Name = "TimeFrameKernel - Basic (SPK, Multiple)",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(Node)
|
||||
end)
|
||||
@@ -0,0 +1,40 @@
|
||||
-- SPK Basic
|
||||
-- This example creates a time frame based on the information provided by a single SPICE
|
||||
-- kernel file. The created scene graph node will only be valid whenever the provided
|
||||
-- kernel contains information about object "-915", which is Apollo 15. In this specific
|
||||
-- case, the Apollo15 kernel contains two windows of valid data, both of which are used by
|
||||
-- this time frame.
|
||||
|
||||
-- We need a SPICE kernel to work with in this example
|
||||
local data = asset.resource({
|
||||
Name = "Apollo Kernels",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "apollo_spice",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local Node = {
|
||||
Identifier = "TimeFrameKernel_Example_SPK",
|
||||
TimeFrame = {
|
||||
Type = "TimeFrameKernel",
|
||||
SPK = {
|
||||
Kernels = data .. "apollo15-1.bsp",
|
||||
Object = "-915"
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableCartesianAxes"
|
||||
},
|
||||
GUI = {
|
||||
Name = "TimeFrameKernel - Basic (SPK)",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(Node)
|
||||
end)
|
||||
@@ -1,5 +1,4 @@
|
||||
asset.onInitialize(function()
|
||||
openspace.setPropertyValueSingle("Modules.Exoplanets.Enabled", true)
|
||||
openspace.setPropertyValueSingle("Modules.Exoplanets.ShowComparisonCircle", false)
|
||||
openspace.setPropertyValueSingle("Modules.Exoplanets.ShowHabitableZone", true)
|
||||
openspace.setPropertyValueSingle("Modules.Exoplanets.UseOptimisticZone", true)
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
asset.onInitialize(function()
|
||||
openspace.setPropertyValueSingle("Modules.SkyBrowser.Enabled", true)
|
||||
openspace.setPropertyValueSingle("Modules.SkyBrowser.ShowTitleInGuiBrowser", false)
|
||||
-- More settings are available, but for now using the default values
|
||||
end)
|
||||
|
||||
|
||||
|
||||
asset.meta = {
|
||||
Name = "SkyBrowser Module Default Settings",
|
||||
Description = "Some default settings related to the SkyBrowser module",
|
||||
Author = "OpenSpace Team",
|
||||
URL = "http://openspaceproject.com",
|
||||
License = "MIT license"
|
||||
}
|
||||
@@ -1,2 +1 @@
|
||||
asset.require("./default_settings")
|
||||
asset.require("./hover_circle")
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,81 @@
|
||||
-- For more information about sonification in OpenSpace and how to use it, see the
|
||||
-- documentation:
|
||||
-- https://docs.openspaceproject.com/latest/creating-data-assets/modules/telemetry/sonification.html
|
||||
|
||||
asset.require("scene/solarsystem/planets/planets")
|
||||
|
||||
asset.onInitialize(function ()
|
||||
-- Note that the planets need to be in this order
|
||||
local planets = {
|
||||
{
|
||||
Name = "Mercury"
|
||||
},
|
||||
{
|
||||
Name = "Venus"
|
||||
},
|
||||
{
|
||||
Name = "Earth",
|
||||
Moons = {
|
||||
"Moon"
|
||||
}
|
||||
},
|
||||
{
|
||||
Name = "Mars",
|
||||
Moons = {
|
||||
"Phobos",
|
||||
"Deimos"
|
||||
}
|
||||
},
|
||||
{
|
||||
Name = "Jupiter",
|
||||
Moons = {
|
||||
"Io",
|
||||
"Europa",
|
||||
"Ganymede",
|
||||
"Callisto"
|
||||
}
|
||||
},
|
||||
{
|
||||
Name = "Saturn",
|
||||
Moons = {
|
||||
"Dione",
|
||||
"Enceladus",
|
||||
"Hyperion",
|
||||
"Iapetus",
|
||||
"Mimas",
|
||||
"Rhea",
|
||||
"Tethys",
|
||||
"Titan"
|
||||
}
|
||||
},
|
||||
{
|
||||
Name = "Uranus",
|
||||
Moons = {
|
||||
"Ariel",
|
||||
"Miranda",
|
||||
"Oberon",
|
||||
"Titania",
|
||||
"Umbriel"
|
||||
}
|
||||
},
|
||||
{
|
||||
Name = "Neptune",
|
||||
Moons = {
|
||||
"Triton",
|
||||
"Nereid"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
openspace.sonification.addPlanets(planets)
|
||||
end)
|
||||
|
||||
|
||||
asset.meta = {
|
||||
Name = "PlanetSonification planets",
|
||||
Version = "1.0",
|
||||
Description = "The list of planets in the PlanetSonification",
|
||||
Author = "OpenSpace Team",
|
||||
URL = "http://openspaceproject.com",
|
||||
License = "MIT license"
|
||||
}
|
||||
@@ -2,6 +2,14 @@ local earthAsset = asset.require("scene/solarsystem/planets/earth/earth")
|
||||
|
||||
|
||||
|
||||
local labels = asset.resource({
|
||||
Name = "AltAz Label Files",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "alt_az_labels",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
|
||||
local AltAzGridPosition = {
|
||||
Identifier = "AltAzGridPosition",
|
||||
Parent = earthAsset.Earth.Identifier,
|
||||
@@ -52,6 +60,7 @@ local AltAzGrid = {
|
||||
LineWidth = 2.0,
|
||||
RenderBinMode = "PostDeferredTransparent"
|
||||
},
|
||||
Tag = { "nightsky_marking" },
|
||||
GUI = {
|
||||
Name = "Altitude-Azimuth Grid",
|
||||
Description = [[A local Altitude/Azimuth grid centered around your position on a
|
||||
@@ -62,6 +71,39 @@ local AltAzGrid = {
|
||||
}
|
||||
}
|
||||
|
||||
local AltAzGridLabels = {
|
||||
Identifier = "AltAzGridLabels",
|
||||
Parent = AltAzGridPosition.Identifier,
|
||||
Transform = {
|
||||
Rotation = {
|
||||
Type = "StaticRotation",
|
||||
Rotation = { -math.pi / 2.0, math.pi, 0.0 }
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderablePointCloud",
|
||||
Enabled = false,
|
||||
Labels = {
|
||||
Enabled = true,
|
||||
File = labels .. "eclip.label",
|
||||
Color = { 0.5, 0.5, 0.5 },
|
||||
FaceCamera = false,
|
||||
Size = 14.8,
|
||||
MinMaxSize = { 2, 70 },
|
||||
Unit = "pc",
|
||||
},
|
||||
Opacity = 0.65,
|
||||
RenderBinMode = "PostDeferredTransparent"
|
||||
},
|
||||
Tag = { "nightsky_marking" },
|
||||
GUI = {
|
||||
Name = "Altitude-Azimuth Grid Labels",
|
||||
Description = [[Labels for the Altitude-Azimuth Grid]],
|
||||
Path = "/Night Sky/Coordinate Systems/Altitude-Azimuth"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
local ShowAltaz = {
|
||||
Identifier = "os.nightsky.ShowAltaz",
|
||||
Name = "Show Alt/Az grid",
|
||||
@@ -105,6 +147,7 @@ local ToggleAltaz = {
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(AltAzGridPosition)
|
||||
openspace.addSceneGraphNode(AltAzGrid)
|
||||
openspace.addSceneGraphNode(AltAzGridLabels)
|
||||
openspace.action.registerAction(ShowAltaz)
|
||||
openspace.action.registerAction(HideAltaz)
|
||||
openspace.action.registerAction(ToggleAltaz)
|
||||
@@ -115,12 +158,14 @@ asset.onDeinitialize(function()
|
||||
openspace.action.removeAction(ToggleAltaz)
|
||||
openspace.action.removeAction(HideAltaz)
|
||||
openspace.action.removeAction(ShowAltaz)
|
||||
openspace.removeSceneGraphNode(AltAzGridLabels)
|
||||
openspace.removeSceneGraphNode(AltAzGrid)
|
||||
openspace.removeSceneGraphNode(AltAzGridPosition)
|
||||
end)
|
||||
|
||||
asset.export(AltAzGridPosition)
|
||||
asset.export(AltAzGrid)
|
||||
asset.export(AltAzGridLabels)
|
||||
asset.export("ShowAltaz", ShowAltaz.Identifier)
|
||||
asset.export("HideAltaz", HideAltaz.Identifier)
|
||||
asset.export("ToggleAltaz", ToggleAltaz.Identifier)
|
||||
|
||||
@@ -56,8 +56,10 @@ local CardinalDirectionSphere = {
|
||||
Texture = textures .. "nesw_red.png",
|
||||
Orientation = "Inside",
|
||||
MirrorTexture = true,
|
||||
RenderBinMode = "PostDeferredTransparent"
|
||||
RenderBinMode = "PostDeferredTransparent",
|
||||
DisableDepth = true
|
||||
},
|
||||
Tag = {"nightsky_marking"},
|
||||
GUI = {
|
||||
Name = "Cardinal Directions",
|
||||
Description = [[A textured sphere showing the cardinal directions.
|
||||
|
||||
@@ -34,9 +34,10 @@ local EclipticLine = {
|
||||
Opacity = 0.8,
|
||||
Color = { 0.5, 0.24, 0.24 },
|
||||
LineWidth = 4.0,
|
||||
GridSegments = { 1, 1 },
|
||||
GridSegments = {1 , 1},
|
||||
Enabled = asset.enabled
|
||||
},
|
||||
Tag = { "nightsky_marking" },
|
||||
GUI = {
|
||||
Name = "Ecliptic",
|
||||
Description = "A line representation of the Ecliptic plane.",
|
||||
@@ -63,6 +64,7 @@ local EclipticBand = {
|
||||
Opacity = 0.05,
|
||||
Enabled = asset.enabled
|
||||
},
|
||||
Tag = { "nightsky_marking" },
|
||||
GUI = {
|
||||
Name = "Ecliptic Band",
|
||||
Description = "A band representation of the Ecliptic plane.",
|
||||
|
||||
@@ -27,9 +27,10 @@ local EquatorialLine = {
|
||||
Opacity = 0.8,
|
||||
Color = { 0.6, 0.6, 0.2 },
|
||||
LineWidth = 4.0,
|
||||
GridSegments = { 1, 1 },
|
||||
GridSegments = {1, 1},
|
||||
Enabled = asset.enabled
|
||||
},
|
||||
Tag = { "nightsky_marking" },
|
||||
GUI = {
|
||||
Name = "Celestial Equator",
|
||||
Description = "A line representation of the Equatorial plane.",
|
||||
|
||||
@@ -19,6 +19,7 @@ local GalacticLine = {
|
||||
GridSegments = { 1, 1 },
|
||||
Enabled = asset.enabled
|
||||
},
|
||||
Tag = { "nightsky_marking" },
|
||||
GUI = {
|
||||
Name = "Galactic Equator",
|
||||
Description = "A line representation of the Galactic Equator plane.",
|
||||
|
||||
@@ -22,6 +22,7 @@ local MeridianPosition = {
|
||||
UseCamera = true
|
||||
}
|
||||
},
|
||||
Tag = { "nightsky_marking" },
|
||||
GUI = {
|
||||
Name = "Local Meridian Position",
|
||||
Path = "/Night Sky/Coordinate Systems/Altitude-Azimuth",
|
||||
@@ -44,9 +45,9 @@ local MeridianPlane = {
|
||||
Color = { 0.4, 0.8, 0.4 },
|
||||
LineWidth = 6.0,
|
||||
GridSegments = { 1, 1 },
|
||||
Enabled = asset.enabled,
|
||||
RenderBinMode = "PostDeferredTransparent"
|
||||
Enabled = asset.enabled
|
||||
},
|
||||
Tag = { "nightsky_marking" },
|
||||
GUI = {
|
||||
Name = "Local Meridian",
|
||||
Description = [[A line representation of the Local Meridian]],
|
||||
|
||||
@@ -9,6 +9,10 @@ asset.require("./zenith", false)
|
||||
asset.require("./planets", false)
|
||||
asset.require("actions/nightsky/camera", false)
|
||||
asset.require("actions/nightsky/daytime", false)
|
||||
asset.require("actions/nightsky/createsuntrails", false)
|
||||
asset.require("actions/nightsky/misc", false)
|
||||
asset.require("actions/nightsky/position", false)
|
||||
asset.require("actions/time", false)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -13,17 +13,33 @@ local textures = asset.resource({
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local csv = asset.resource({
|
||||
Name = "Zero Point Data",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "zeropoint_data",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
|
||||
local Mercury = {
|
||||
Identifier = "NightSkyMercury",
|
||||
Parent = mercury.MercuryBarycenter.Identifier,
|
||||
Renderable = {
|
||||
Type = "RenderablePlaneImageLocal",
|
||||
Billboard = true,
|
||||
Type = "RenderablePointCloud",
|
||||
File = csv .. "zeropointdata.csv",
|
||||
Coloring = {
|
||||
FixedColor = { 0.608, 0.604, 0.455 }
|
||||
},
|
||||
Texture = {
|
||||
File = textures .. "glare.png"
|
||||
},
|
||||
SizeSettings = {
|
||||
ScaleFactor = 10,
|
||||
ScaleExponent = 15,
|
||||
MaxSize = 0.209,
|
||||
EnableMaxSizeControl = true
|
||||
},
|
||||
Enabled = asset.enabled,
|
||||
Size = 2439700 * 500,
|
||||
Texture = textures .. "glare.png",
|
||||
MultiplyColor = { 0.608, 0.604, 0.455 },
|
||||
DimInAtmosphere = true,
|
||||
RenderBinMode = "PostDeferredTransparent"
|
||||
},
|
||||
@@ -41,12 +57,21 @@ local Venus = {
|
||||
Identifier = "NightSkyVenus",
|
||||
Parent = venus.VenusBarycenter.Identifier,
|
||||
Renderable = {
|
||||
Type = "RenderablePlaneImageLocal",
|
||||
Type = "RenderablePointCloud",
|
||||
File = csv .. "zeropointdata.csv",
|
||||
Coloring = {
|
||||
FixedColor = { 1.0 , 0.992, 0.757 }
|
||||
},
|
||||
Texture = {
|
||||
File = textures .. "glare.png"
|
||||
},
|
||||
SizeSettings = {
|
||||
ScaleFactor = 10,
|
||||
ScaleExponent = 15,
|
||||
MaxSize = 1.14,
|
||||
EnableMaxSizeControl = true
|
||||
},
|
||||
Enabled = asset.enabled,
|
||||
Billboard = true,
|
||||
Size = 6051900 * 700,
|
||||
Texture = textures .. "glare.png",
|
||||
MultiplyColor = { 1.0 , 0.992, 0.757 },
|
||||
DimInAtmosphere = true,
|
||||
RenderBinMode = "PostDeferredTransparent"
|
||||
},
|
||||
@@ -64,12 +89,21 @@ local Mars = {
|
||||
Identifier = "NightSkyMars",
|
||||
Parent = mars.MarsBarycenter.Identifier,
|
||||
Renderable = {
|
||||
Type = "RenderablePlaneImageLocal",
|
||||
Type = "RenderablePointCloud",
|
||||
File = csv .. "zeropointdata.csv",
|
||||
Coloring = {
|
||||
FixedColor = { 0.756, 0.267, 0.054 }
|
||||
},
|
||||
Texture = {
|
||||
File = textures .. "glare.png"
|
||||
},
|
||||
SizeSettings = {
|
||||
ScaleFactor = 10,
|
||||
ScaleExponent = 15,
|
||||
MaxSize = 0.404, --mars max angular size / 62
|
||||
EnableMaxSizeControl = true
|
||||
},
|
||||
Enabled = asset.enabled,
|
||||
Billboard = true,
|
||||
Size = 3396190 * 1000,
|
||||
Texture = textures .. "glare.png",
|
||||
MultiplyColor = { 0.756, 0.267, 0.054 },
|
||||
DimInAtmosphere = true,
|
||||
RenderBinMode = "PostDeferredTransparent"
|
||||
},
|
||||
@@ -85,12 +119,21 @@ local Jupiter = {
|
||||
Identifier = "NightSkyJupiter",
|
||||
Parent = jupiter.JupiterBarycenter.Identifier,
|
||||
Renderable = {
|
||||
Type = "RenderablePlaneImageLocal",
|
||||
Type = "RenderablePointCloud",
|
||||
File = csv .. "zeropointdata.csv",
|
||||
Coloring = {
|
||||
FixedColor = { 0.608, 0.604, 0.455 },
|
||||
},
|
||||
Texture = {
|
||||
File = textures .. "glare.png"
|
||||
},
|
||||
SizeSettings = {
|
||||
ScaleFactor = 10,
|
||||
ScaleExponent = 15,
|
||||
MaxSize = 0.82,
|
||||
EnableMaxSizeControl = true
|
||||
},
|
||||
Enabled = asset.enabled,
|
||||
Billboard = true,
|
||||
Size = 71492000 * 400,
|
||||
Texture = textures .. "glare.png",
|
||||
MultiplyColor = { 0.608, 0.604, 0.455 },
|
||||
DimInAtmosphere = true,
|
||||
RenderBinMode = "PostDeferredTransparent"
|
||||
},
|
||||
@@ -108,12 +151,19 @@ local Saturn = {
|
||||
Identifier = "NightSkySaturn",
|
||||
Parent = saturn.SaturnBarycenter.Identifier,
|
||||
Renderable = {
|
||||
Type = "RenderablePlaneImageLocal",
|
||||
Type = "RenderablePointCloud",
|
||||
File = csv .. "zeropointdata.csv",
|
||||
Coloring = {
|
||||
FixedColor = { 0.85098, 0.843137, 0.619608 },
|
||||
},
|
||||
Texture = {
|
||||
File = textures .. "glare.png"
|
||||
},
|
||||
SizeSettings = {
|
||||
MaxSize = 0.332,
|
||||
EnableMaxSizeControl = true
|
||||
},
|
||||
Enabled = asset.enabled,
|
||||
Billboard = true,
|
||||
Size = 60268000 * 500,
|
||||
Texture = textures .. "glare.png",
|
||||
MultiplyColor = { 0.608, 0.604, 0.455 },
|
||||
DimInAtmosphere = true,
|
||||
RenderBinMode = "PostDeferredTransparent"
|
||||
},
|
||||
|
||||
@@ -31,6 +31,7 @@ local ZenithPosition = {
|
||||
UseCamera = true
|
||||
}
|
||||
},
|
||||
Tag = { "nightsky_marking" },
|
||||
GUI = {
|
||||
Name = "Zenith Position",
|
||||
Path = "/Night Sky/Coordinate Systems/Altitude-Azimuth",
|
||||
@@ -56,6 +57,7 @@ local ZenithDot = {
|
||||
Texture = textures .. "point3A.png",
|
||||
BlendMode = "Additive"
|
||||
},
|
||||
Tag = { "nightsky_marking" },
|
||||
GUI = {
|
||||
Name = "Zenith",
|
||||
Description = [[A dot representation of the Local Zenith, based on the camera's
|
||||
|
||||
@@ -42,7 +42,7 @@ local Object = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "6dF Galaxies",
|
||||
Path = "/Universe/Deep Sky Surveys",
|
||||
Path = "/Universe/Nearby Surveys",
|
||||
Description = [[The Six-degree Field (6dF) Galaxy Survey mapped nearly half the sky
|
||||
from the Anglo-Australian Observatory. Because it's a southern hemisphere survey,
|
||||
there is no coverage in these data for the northern hemisphere's sky. As with all
|
||||
|
||||
@@ -28,7 +28,7 @@ local Object = {
|
||||
DisableDepth = true
|
||||
},
|
||||
GUI = {
|
||||
Name = "Hydrogen Alpha",
|
||||
Name = "Hydrogen-alpha All-sky",
|
||||
Path = "/Milky Way/All Sky Images",
|
||||
Description = [[Hydrogen-alpha is a term that describes light from the ground state of
|
||||
the hydrogen atom. When an electron in an atom moves from one energy level to a
|
||||
|
||||
@@ -29,7 +29,7 @@ local Object = {
|
||||
},
|
||||
Tag = { "daytime_hidden" },
|
||||
GUI = {
|
||||
Name = "Visible Milky Way",
|
||||
Name = "Visible All-sky",
|
||||
Path = "/Milky Way/All Sky Images",
|
||||
Description = [[An all-sky image of the night sky as our eye sees it (in the visible
|
||||
spectrum), with the stars removed. You will see the brightest part of the Galaxy if
|
||||
|
||||
@@ -35,7 +35,7 @@ local COBE = {
|
||||
DisableDepth = true
|
||||
},
|
||||
GUI = {
|
||||
Name = "1990 COBE CMB",
|
||||
Name = "COBE",
|
||||
Path = "/Universe/Cosmic Microwave Background",
|
||||
Description = [[In 1990, COBE, the Cosmic Background Explorer, took the first
|
||||
detailed map of the cosmic microwave background light. The red areas are
|
||||
@@ -69,7 +69,7 @@ local WMAP = {
|
||||
DisableDepth = true
|
||||
},
|
||||
GUI = {
|
||||
Name = "2003 WMAP CMB",
|
||||
Name = "WMAP",
|
||||
Path = "/Universe/Cosmic Microwave Background",
|
||||
Description = [[WMAP, the Wilkinson Microwave Anisotropy Probe, released this all-sky
|
||||
image of the cosmic microwave background light in 2003. The blue colors are slightly
|
||||
@@ -102,7 +102,7 @@ local Planck = {
|
||||
DisableDepth = true
|
||||
},
|
||||
GUI = {
|
||||
Name = "2013 Planck CMB",
|
||||
Name = "Planck",
|
||||
Path = "/Universe/Cosmic Microwave Background",
|
||||
Description = [[The Planck mission's 2013 image of the cosmic microwave background
|
||||
light release is the most detailed view of the CMB we have to date. The orange
|
||||
@@ -117,6 +117,11 @@ asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(COBE)
|
||||
openspace.addSceneGraphNode(WMAP)
|
||||
openspace.addSceneGraphNode(Planck)
|
||||
|
||||
openspace.setGuiOrder(
|
||||
"/Universe/Cosmic Microwave Background",
|
||||
{ COBE.Identifier, WMAP.Identifier, Planck.Identifier }
|
||||
)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
|
||||
@@ -9,7 +9,7 @@ local speck = asset.resource({
|
||||
Name = "Brown Dwarf Speck Files",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "digitaluniverse_brown_dwarfs_speck",
|
||||
Version = 1
|
||||
Version = 2
|
||||
})
|
||||
|
||||
|
||||
@@ -36,6 +36,13 @@ local Object = {
|
||||
ScaleExponent = 15.8,
|
||||
MaxSize = 0.7,
|
||||
EnableMaxSizeControl = true
|
||||
},
|
||||
Labels = {
|
||||
File = speck .. "bd.label",
|
||||
Color = { 0.6, 0.3, 0.4 },
|
||||
Size = 13.75,
|
||||
MinMaxSize = { 4, 30 },
|
||||
Unit = "pc"
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
@@ -72,7 +79,7 @@ asset.export(Object)
|
||||
|
||||
asset.meta = {
|
||||
Name = "Brown Dwarfs",
|
||||
Author = "Brian Abbott, Zack Reeves, Jackie Faherty (AMNH)",
|
||||
Author = "Brian Abbott, Zack Reeves, Ally Baldelli, Jackie Faherty (AMNH)",
|
||||
Description = Object.GUI.Description,
|
||||
License = "AMNH Digital Universe",
|
||||
URL = "https://www.amnh.org/research/hayden-planetarium/digital-universe",
|
||||
|
||||
@@ -35,6 +35,7 @@ local Object = {
|
||||
Scale = 10e17
|
||||
}
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
Name = "Constellation Boundaries",
|
||||
Path = "/Milky Way/Constellations",
|
||||
|
||||
@@ -66,7 +66,7 @@ local DeepSkyObjectsImages = {
|
||||
},
|
||||
-- Use fixed orientation, and rotate planes based on orientation information in
|
||||
-- the dataset
|
||||
OrientationRenderOption = "Fixed Rotation",
|
||||
Billboard = "Fixed Rotation",
|
||||
UseOrientationData = true,
|
||||
Unit = "pc",
|
||||
SizeSettings = {
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
-- The only reason the SDSS asset is loaded at the top of this list is to start the
|
||||
-- loading as soon as possible, as this asset is the most time intensive to initialize and
|
||||
-- we want to minimize the waiting time on startup
|
||||
asset.require("./sdss")
|
||||
|
||||
asset.require("./2dF")
|
||||
asset.require("./2mass")
|
||||
asset.require("./6dF")
|
||||
asset.require("./abell")
|
||||
asset.require("./allsky_hydrogenalpha")
|
||||
asset.require("./allsky_visible")
|
||||
asset.require("./alternatestarlabels")
|
||||
asset.require("./backgroundradiation")
|
||||
asset.require("./backgroundradiation_multiverse")
|
||||
asset.require("./brown_dwarfs")
|
||||
@@ -28,7 +33,6 @@ asset.require("./planetarynebulae")
|
||||
asset.require("./pulsars")
|
||||
asset.require("./quasars")
|
||||
asset.require("./starlabels")
|
||||
asset.require("./alternatestarlabels")
|
||||
asset.require("./starorbits")
|
||||
asset.require("./star_uncertainty")
|
||||
asset.require("./stars")
|
||||
|
||||
@@ -9,7 +9,7 @@ local speck = asset.resource({
|
||||
Name = "Exoplanets Speck Files",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "digitaluniverse_exoplanets_speck",
|
||||
Version = 4
|
||||
Version = 5
|
||||
})
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ local Object = {
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Exoplanets",
|
||||
Name = "Exoplanet Systems",
|
||||
Path = "/Milky Way/Exoplanets",
|
||||
Description = [[Extrasolar planets, or exoplanets, are a relatively new phenomenon in
|
||||
astronomy - no observational evidence was available until 1995. To the eye,
|
||||
@@ -67,7 +67,7 @@ asset.export(Object)
|
||||
asset.meta = {
|
||||
Name = "Exoplanets",
|
||||
Description = Object.GUI.Description,
|
||||
Author = "Brian Abbott, Zack Reeves (AMNH)",
|
||||
Author = "Brian Abbott, Zack Reeves, Ally Baldelli (AMNH)",
|
||||
URL = "https://www.amnh.org/research/hayden-planetarium/digital-universe",
|
||||
License = "AMNH Digital Universe"
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ local speck = asset.resource({
|
||||
Name = "Exoplanets Candidates Speck Files",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "digitaluniverse_exoplanets_candidates_speck",
|
||||
Version = 2
|
||||
Version = 3
|
||||
})
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ local Object = {
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Exoplanetary Candidates",
|
||||
Name = "Exoplanet Candidates",
|
||||
Path = "/Milky Way/Exoplanets",
|
||||
Description = [[The exoplanet candidate stars are likely hosts for exoplanets. These
|
||||
are stars plucked from NASA's Kepler and TESS space telescopes. Further observations
|
||||
@@ -69,7 +69,7 @@ asset.export(Object)
|
||||
asset.meta = {
|
||||
Name = "Exoplanetary Candidates",
|
||||
Description = Object.GUI.Description,
|
||||
Author = "Brian Abbott, Zack Reeves, Emily Rice, and Jason No (AMNH)",
|
||||
Author = "Brian Abbott, Ally Baldelli, Zack Reeves, Emily Rice, and Jason No (AMNH)",
|
||||
URL = "https://www.amnh.org/research/hayden-planetarium/digital-universe",
|
||||
License = "AMNH Digital Universe"
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ local RadioSphere = {
|
||||
Color = { 0.3, 0.84, 1.0 },
|
||||
LineWidth = 2.0
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
Name = "Radio Sphere",
|
||||
Path = "/Milky Way/Grids",
|
||||
@@ -102,8 +103,10 @@ local EquatorialSphere = {
|
||||
Opacity = 1.0,
|
||||
Color = { 0.3, 0.3, 0.15 },
|
||||
LineWidth = 2.0,
|
||||
GridSegments = { 18, 24 },
|
||||
LatSegments = 36,
|
||||
LongSegments = 24,
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
Name = "Equatorial Coordinates",
|
||||
Path = "/Night Sky/Coordinate Systems/Equatorial",
|
||||
@@ -131,6 +134,7 @@ local EquatorialSphereLabels = {
|
||||
Unit = "pc",
|
||||
TransformationMatrix = EquatorialTransformationMatrix
|
||||
},
|
||||
Tag = { "du_grid_labels" },
|
||||
GUI = {
|
||||
Name = "Equatorial Coordinates Labels",
|
||||
Path = "/Night Sky/Coordinate Systems/Equatorial",
|
||||
@@ -159,6 +163,7 @@ local EclipticSphere = {
|
||||
Color = { 0.3, 0.15, 0.15 },
|
||||
LineWidth = 2.0
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
Name = "Ecliptic Coordinates",
|
||||
Path = "/Night Sky/Coordinate Systems/Ecliptic",
|
||||
@@ -186,6 +191,7 @@ local EclipticSphereLabels = {
|
||||
Unit = "pc",
|
||||
TransformationMatrix = EclipticTransformationMatrix
|
||||
},
|
||||
Tag = { "du_grid_labels" },
|
||||
GUI = {
|
||||
Name = "Ecliptic Coordinates Labels",
|
||||
Path = "/Night Sky/Coordinate Systems/Ecliptic",
|
||||
@@ -210,6 +216,7 @@ local GalacticSphere = {
|
||||
Opacity = 1.0,
|
||||
Color = { 0.05, 0.25, 0.25 }
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
Name = "Galactic Coordinates",
|
||||
Path = "/Night Sky/Coordinate Systems/Galactic",
|
||||
@@ -235,6 +242,7 @@ local GalacticSphereLabels = {
|
||||
Opacity = 0.65,
|
||||
Unit = "pc"
|
||||
},
|
||||
Tag = { "du_grid_labels" },
|
||||
GUI = {
|
||||
Name = "Galactic Coordinates Labels",
|
||||
Path = "/Night Sky/Coordinate Systems/Galactic",
|
||||
@@ -268,6 +276,7 @@ local Plane1lh = {
|
||||
Segments = { 20, 20 },
|
||||
Size = { 2 * LightHour, 2 * LightHour }
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
Name = "1-light-hour Grid",
|
||||
Path = "/Solar System/Grids",
|
||||
@@ -301,6 +310,7 @@ local Plane1ld = {
|
||||
Segments = { 20, 20 },
|
||||
Size = { 2 * LightDay, 2 * LightDay }
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
Name = "1-light-day Grid",
|
||||
Path = "/Solar System/Grids",
|
||||
@@ -334,6 +344,7 @@ local Plane1lm = {
|
||||
Segments = { 20, 20 },
|
||||
Size = { 2 * LightMonth, 2 * LightMonth }
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
Name = "1-light-month Grid",
|
||||
Path = "/Solar System/Grids",
|
||||
@@ -367,6 +378,7 @@ local Plane1ly = {
|
||||
Segments = { 20, 20 },
|
||||
Size = { 2 * LightYear, 2 * LightYear }
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
Name = "1-light-year Grid",
|
||||
Path = "/Solar System/Grids",
|
||||
@@ -400,6 +412,7 @@ local Plane10ly = {
|
||||
Segments = { 20, 20 },
|
||||
Size = { 10 * 2 * LightYear, 10 * 2 * LightYear }
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
Name = "10-light-year Grid",
|
||||
Path = "/Milky Way/Grids",
|
||||
@@ -433,6 +446,7 @@ local Plane100ly = {
|
||||
Segments = { 20, 20 },
|
||||
Size = { 100 * 2 * LightYear, 100 * 2 * LightYear }
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
Name = "100-light-year Grid",
|
||||
Path = "/Milky Way/Grids",
|
||||
@@ -466,6 +480,7 @@ local Plane1kly = {
|
||||
Segments = { 20, 20 },
|
||||
Size = { 1000 * 2 * LightYear, 1000 * 2 * LightYear }
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
Name = "1,000-light-year Grid",
|
||||
Path = "/Milky Way/Grids",
|
||||
@@ -499,6 +514,7 @@ local Plane10kly = {
|
||||
Segments = { 20, 20 },
|
||||
Size = { 10000 * 2 * LightYear, 10000 * 2 * LightYear }
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
Name = "10,000-light-year Grid",
|
||||
Path = "/Milky Way/Grids",
|
||||
@@ -527,6 +543,7 @@ local Plane100kly = {
|
||||
HighlightRate = { 5, 5 },
|
||||
Size = { 100000 * 2 * LightYear, 100000 * 2 * LightYear }
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
Name = "100,000-light-year Grid",
|
||||
Path = "/Universe/Grids",
|
||||
@@ -555,6 +572,7 @@ local Plane1Mly = {
|
||||
HighlightRate = { 5, 5 },
|
||||
Size = { 1E6 * 2 * LightYear, 1E6 * 2 * LightYear }
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
Name = "1-million-light-year Grid",
|
||||
Path = "/Universe/Grids",
|
||||
@@ -583,6 +601,7 @@ local Plane10Mly = {
|
||||
HighlightRate = { 5, 5 },
|
||||
Size = { 10E6 * 2 * LightYear, 10E6 * 2 * LightYear }
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
Name = "10-million-light-year Grid",
|
||||
Path = "/Universe/Grids",
|
||||
@@ -611,6 +630,7 @@ local Plane100Mly = {
|
||||
HighlightRate = { 5, 5 },
|
||||
Size = { 100E6 * 2 * LightYear, 100E6 * 2 * LightYear }
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
Name = "100-million-light-year Grid",
|
||||
Path = "/Universe/Grids",
|
||||
@@ -639,6 +659,7 @@ local Plane20Gly = {
|
||||
HighlightRate = { 5, 5 },
|
||||
Size = { 20E9 * 2 * LightYear, 20E9 * 2 * LightYear }
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
Name = "20-billion-light-year Grid",
|
||||
Path = "/Universe/Grids",
|
||||
|
||||
@@ -24,7 +24,7 @@ local Object = {
|
||||
},
|
||||
-- Use fixed orientation, and rotate planes based on orientation information in
|
||||
-- the dataset
|
||||
OrientationRenderOption = "Fixed Rotation",
|
||||
Billboard = "Fixed Rotation",
|
||||
UseOrientationData = true,
|
||||
Unit = "pc",
|
||||
Fading = {
|
||||
@@ -38,7 +38,7 @@ local Object = {
|
||||
},
|
||||
},
|
||||
GUI = {
|
||||
Name = "Milky Way Galaxy Image",
|
||||
Name = "Milky Way Image",
|
||||
Path = "/Milky Way/Galaxy",
|
||||
Description = [[The exterior view of the Milky Way is represented here by a
|
||||
two-dimensional image. The image is that of NGC 1232, a galaxy thought to resemble
|
||||
|
||||
@@ -25,7 +25,7 @@ local Object = {
|
||||
},
|
||||
-- Use fixed orientation, and rotate planes based on orientation information in
|
||||
-- the dataset
|
||||
OrientationRenderOption = "Fixed Rotation",
|
||||
Billboard = "Fixed Rotation",
|
||||
UseOrientationData = true,
|
||||
Unit = "pc",
|
||||
Fading = {
|
||||
@@ -39,7 +39,7 @@ local Object = {
|
||||
},
|
||||
},
|
||||
GUI = {
|
||||
Name = "Milky Way Arms Labels",
|
||||
Name = "Milky Way Arm Labels",
|
||||
Path = "/Milky Way/Galaxy",
|
||||
Description = [[This is an image that contains labels for the Milky Way's spiral
|
||||
arms. We label them in this manner--"hard-coding" the labels into an image rather
|
||||
|
||||
@@ -39,7 +39,7 @@ local Object = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Oort Sphere",
|
||||
Path = "/Solar System/Comets",
|
||||
Path = "/Solar System/Comets/Oort Cloud",
|
||||
Description = [[The Oort cloud is a region of space surrounding the Sun where comets
|
||||
are believed to originate. It is believed to extend from 20,000-100,000 Astronomical
|
||||
Units (AU), with its greatest concentration around 50,000 AU (1 AU is the average
|
||||
|
||||
@@ -43,7 +43,7 @@ local Object = {
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Sloan Digital Sky Survey",
|
||||
Name = "Sloan Galaxies",
|
||||
Path = "/Universe/Deep Sky Surveys",
|
||||
Description = [[The Sloan Digital Sky Survey (SDSS) is an ambitious project to image
|
||||
about 35% of the sky, deep into the universe. The SDSS galaxies form triangular
|
||||
|
||||
@@ -86,7 +86,7 @@ local TullyGalaxiesImages = {
|
||||
TransformationMatrix = transforms.Supergalactic,
|
||||
-- Use fixed orientation, and rotate planes based on orientation information in
|
||||
-- the dataset
|
||||
OrientationRenderOption = "Fixed Rotation",
|
||||
Billboard = "Fixed Rotation",
|
||||
UseOrientationData = true,
|
||||
Unit = "Mpc",
|
||||
Fading = {
|
||||
@@ -102,7 +102,7 @@ local TullyGalaxiesImages = {
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Tully Galaxies Images",
|
||||
Name = "Tully Galaxy Images",
|
||||
Path = "/Universe/Nearby Surveys",
|
||||
Description = [[Each Tully galaxy is represented by an image that represents its
|
||||
morphological type (spiral, elliptical, etc.). Most of these come from The Galaxy
|
||||
|
||||
@@ -89,7 +89,7 @@ local function createConstellations(baseIdentifier, guiPath, constellationfile)
|
||||
Opacity = 0.1,
|
||||
DimInAtmosphere = true
|
||||
},
|
||||
Tag = { "ImageConstellation", group, "daytime_hidden" },
|
||||
Tag = { "image_constellation", "zodiac_" .. group, "daytime_hidden" },
|
||||
GUI = {
|
||||
Name = name .. " Image",
|
||||
Path = "/Milky Way/Constellations/" .. guiPath,
|
||||
|
||||
@@ -14,7 +14,7 @@ local KiloParsec = 3.086E19
|
||||
|
||||
local MilkyWayVolume = {
|
||||
Identifier = "MilkyWayVolume",
|
||||
Parent = transforms.SolarSystemBarycenter.Identifier,
|
||||
-- No parent; this node is attached to the scene graph root
|
||||
Transform = {
|
||||
Translation = {
|
||||
Type = "StaticTranslation",
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
local propertyHelper = asset.require("util/property_helper")
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sunAsset = asset.require("scene/solarsystem/sun/sun")
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
local heliosphereTransforms = asset.require("scene/solarsystem/sun/transforms_heliosphere")
|
||||
local propertyHelper = asset.require("util/property_helper")
|
||||
local rot = asset.require("./carrington_to_heeq_rotation")
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
local heliosphereTransforms = asset.require("scene/solarsystem/sun/transforms_heliosphere")
|
||||
local propertyHelper = asset.require("util/property_helper")
|
||||
local rot = asset.require("./carrington_to_heeq_rotation")
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
local propertyHelper = asset.require("util/property_helper")
|
||||
local transforms = asset.require("scene/solarsystem/sun/transforms_heliosphere")
|
||||
local rot = asset.require("./carrington_to_heeq_rotation")
|
||||
|
||||
|
||||
@@ -261,3 +261,14 @@ asset.export(Apollo11LemDescentModel)
|
||||
asset.export(Apollo11LemLandedModel)
|
||||
asset.export(Apollo11MoonTrail)
|
||||
asset.export(Apollo11LemTrail)
|
||||
|
||||
|
||||
|
||||
asset.meta = {
|
||||
Name = "Apollo 11",
|
||||
Description = [[A meta asset that will include all of the other assets to show the
|
||||
Apollo 11 launch, orbit, and landing sequence.]],
|
||||
Author = "OpenSpace Team",
|
||||
URL = "http://openspaceproject.com",
|
||||
License = "MIT license"
|
||||
}
|
||||
|
||||
@@ -34,3 +34,14 @@ end)
|
||||
|
||||
asset.export("ID", ID)
|
||||
asset.export("Frame", Frame)
|
||||
|
||||
|
||||
|
||||
asset.meta = {
|
||||
Name = "Apollo 11 Kernel",
|
||||
Description = [[This asset downloads and provides the kernels needed for the Apollo 11
|
||||
launch, trans-lunar injection, and moon orbit.]],
|
||||
Author = "OpenSpace Team",
|
||||
URL = "http://openspaceproject.com",
|
||||
License = "MIT license"
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user