This commit is contained in:
Ylva Selling
2023-04-17 12:46:54 -04:00
351 changed files with 13887 additions and 1152 deletions

1
.gitignore vendored
View File

@@ -41,3 +41,4 @@ COMMIT.md
# SkyBrowser Module downloaded data
/modules/skybrowser/wwtimagedata
doc
config/schema/sgct.schema.json

3
.gitmodules vendored
View File

@@ -32,6 +32,9 @@
[submodule "support/coding/codegen"]
path = support/coding/codegen
url = https://github.com/OpenSpace/codegen
[submodule "modules/globebrowsing/ext/geos"]
path = modules/globebrowsing/ext/geos
url = https://github.com/OpenSpace/geos.git
[submodule "documentation"]
path = documentation
url = https://github.com/OpenSpace/OpenSpace-Documentation-Dist.git

View File

@@ -121,12 +121,21 @@ target_link_libraries(OpenSpace PRIVATE sgct)
set_target_properties(sgct PROPERTIES FOLDER "External")
set_target_properties(glfw PROPERTIES FOLDER "External")
set_target_properties(SGCTTest PROPERTIES FOLDER "External")
if (TARGET SGCTTest)
set_target_properties(SGCTTest PROPERTIES FOLDER "External")
endif ()
if (UNIX AND (NOT APPLE))
target_link_libraries(OpenSpace PRIVATE Xcursor Xinerama X11)
endif ()
add_custom_command(TARGET OpenSpace POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/ext/sgct/sgct.schema.json
${CMAKE_CURRENT_SOURCE_DIR}/../../config/schema/sgct.schema.json
COMMAND_EXPAND_LISTS
)
end_header("Dependency: SGCT")
begin_header("Dependency: Profile Editor")

View File

@@ -29,6 +29,8 @@
#include "sgctedit/sgctedit.h"
#include <openspace/scene/profile.h>
#include <sgct/error.h>
#include <sgct/readconfig.h>
#include <QApplication>
#include <optional>
@@ -79,15 +81,28 @@ public:
*/
std::string selectedWindowConfig() const;
/**
* Returns true if the window configuration filename selected in the combo box
* is a file in the user configurations section
*
* \return true if window configuration is a user configuration file
*/
bool isUserConfigSelected() const;
private:
QWidget* createCentralWidget();
void setBackgroundImage(const std::string& syncPath);
void openProfileEditor(const std::string& profile, bool isUserProfile);
void openWindowEditor();
void openWindowEditor(const std::string& winCfg, bool isUserWinCfg);
void editRefusalDialog(const std::string& title, const std::string& msg,
const std::string& detailedText);
void populateProfilesList(std::string preset);
void populateWindowConfigsList(std::string preset);
void handleReturnFromWindowEditor(const sgct::config::Cluster& cluster,
std::filesystem::path savePath, const std::string& saveWindowCfgPath);
bool versionCheck(sgct::config::GeneratorVersion& v) const;
const std::string _assetPath;
const std::string _userAssetPath;
@@ -95,14 +110,19 @@ private:
const std::string _userConfigPath;
const std::string _profilePath;
const std::string _userProfilePath;
const std::vector<std::string>& _readOnlyWindowConfigs;
const std::vector<std::string>& _readOnlyProfiles;
bool _shouldLaunch = false;
int _userAssetCount = 0;
int _userConfigStartingIdx = 0;
int _userConfigCount = 0;
int _preDefinedConfigStartingIdx = 0;
const std::string _sgctConfigName;
int _windowConfigBoxIndexSgctCfgDefault = 0;
QComboBox* _profileBox = nullptr;
QComboBox* _windowConfigBox = nullptr;
QLabel* _backgroundImage = nullptr;
QPushButton* _editWindowButton = nullptr;
};
#endif // __OPENSPACE_UI_LAUNCHER___LAUNCHERWINDOW___H__

View File

@@ -48,10 +48,12 @@ public:
* \param winColors An array of QColor objects for window colors. The indexing of
* this array matches the window indexing used elsewhere in the
* class. This allows for a unique color for each window.
* \param resetToDefault If set to true, all display and window settings will be
* initialized to their default values.
* \param parent The parent to which this widget belongs
*/
DisplayWindowUnion(const std::vector<QRect>& monitorSizeList,
int nMaxWindows, const std::array<QColor, 4>& windowColors,
int nMaxWindows, const std::array<QColor, 4>& windowColors, bool resetToDefault,
QWidget* parent = nullptr);
/**
@@ -59,7 +61,15 @@ public:
*
* \return vector of pointers of WindowControl objects
*/
std::vector<WindowControl*> windowControls() const;
std::vector<WindowControl*> activeWindowControls() const;
/**
* Returns a vector of pointers to the WindowControl objects for all windows, whether
* they are visible or not.
*
* \return vector of pointers of all WindowControl objects
*/
std::vector<WindowControl*>& windowControls();
/**
* When called will add a new window to the set of windows, which will, in turn, send
@@ -73,6 +83,14 @@ public:
*/
void removeWindow();
/**
* Returns the number of windows that are displayed (there can be more window
* objects than are currently displayed).
*
* \return the number of displayed windows in the current configuration
*/
unsigned int numWindowsDisplayed() const;
signals:
/**
* This signal is emitted when a windowhas changed.
@@ -92,7 +110,7 @@ signals:
private:
void createWidgets(int nMaxWindows, std::vector<QRect> monitorResolutions,
std::array<QColor, 4> windowColors);
std::array<QColor, 4> windowColors, bool resetToDefault);
void showWindows();
unsigned int _nWindowsDisplayed = 0;

View File

@@ -62,6 +62,23 @@ public:
*/
bool showUiOnFirstWindow() const;
/**
* Sets the value of the checkbox for putting the GUI only on the first window.
* If this is enabled, then the first window will draw2D but not draw3D. All
* subsequent windows will be the opposite of this.
*
* \param setUiOnFirstWindow boolean value, if set true then the GUI will only
* be on the first window
*/
void setShowUiOnFirstWindow(bool setUiOnFirstWindow);
/**
* Sets the value of the checkbox for enabling VSync.
*
* \param enableVsync boolean value, if set true then VSync is enabled
*/
void setVsync(bool enableVsync);
private:
sgct::quat _orientationValue = sgct::quat(0.f, 0.f, 0.f, 0.f);
QCheckBox* _checkBoxVsync = nullptr;

View File

@@ -28,6 +28,7 @@
#include <QDialog>
#include <sgct/config.h>
#include <sgctedit/windowcontrol.h>
#include <QColor>
#include <array>
#include <filesystem>
@@ -38,12 +39,16 @@ class SettingsWidget;
class QBoxLayout;
class QWidget;
const sgct::config::GeneratorVersion versionMin { "SgctWindowConfig", 1, 1 };
const sgct::config::GeneratorVersion versionLegacy18 { "OpenSpace", 0, 18 };
const sgct::config::GeneratorVersion versionLegacy19 { "OpenSpace", 0, 19 };
class SgctEdit final : public QDialog {
Q_OBJECT
public:
/**
* Constructor for SgctEdit class, the underlying class for the full window
* configuration editor
* configuration editor. Used when creating a new config.
*
* \param parent The Qt QWidget parent object
* \param userConfigPath A string containing the file path of the user config
@@ -51,6 +56,22 @@ public:
*/
SgctEdit(QWidget* parent, std::string userConfigPath);
/**
* Constructor for SgctEdit class, the underlying class for the full window
* configuration editor. Used when editing an existing config.
*
* \param cluster The #sgct::config::Cluster object containing all data of the
* imported window cluster configuration.
* \param configName The name of the window configuration filename
* \param configBasePath The path to the folder where default config files reside
* \param configsReadOnly vector list of window config names that are read-only and
* must not be overwritten
* \param parent Pointer to parent Qt widget
*/
SgctEdit(sgct::config::Cluster& cluster, const std::string& configName,
std::string& configBasePath, const std::vector<std::string>& configsReadOnly,
QWidget* parent);
/**
* Returns the saved filename
*
@@ -66,8 +87,16 @@ public:
sgct::config::Cluster cluster() const;
private:
void createWidgets(const std::vector<QRect>& monitorSizes);
sgct::config::Cluster generateConfiguration() const;
std::vector<QRect> createMonitorInfoSet();
void createWidgets(const std::vector<QRect>& monitorSizes, unsigned int nWindows,
bool setToDefaults);
void generateConfiguration();
void generateConfigSetupVsync();
void generateConfigUsers();
void generateConfigAddresses(sgct::config::Node& node);
void generateConfigResizeWindowsAccordingToSelected(sgct::config::Node& node);
void generateConfigIndividualWindowSettings(sgct::config::Node& node);
void setupProjectionTypeInGui(sgct::config::Viewport& vPort, WindowControl* wCtrl);
void save();
void apply();
@@ -82,12 +111,15 @@ private:
QColor(0x44, 0xAF, 0x69),
QColor(0xF8, 0x33, 0x3C)
};
std::string _configurationFilename;
const std::vector<std::string> _readOnlyConfigs;
QBoxLayout* _layoutButtonBox = nullptr;
QPushButton* _saveButton = nullptr;
QPushButton* _cancelButton = nullptr;
QPushButton* _applyButton = nullptr;
std::string _saveTarget;
bool _didImportValues = false;
};
#endif // __OPENSPACE_UI_LAUNCHER___SGCTEDIT___H__

View File

@@ -41,6 +41,14 @@ class QSpinBox;
class WindowControl final : public QWidget {
Q_OBJECT
public:
enum class ProjectionIndices {
Planar = 0,
Fisheye,
SphericalMirror,
Cylindrical,
Equirectangular
};
/**
* Constructor for WindowControl class, which contains settings and configuration
* for individual windows
@@ -52,7 +60,8 @@ public:
* \param winColor A QColor object for this window's unique color
*/
WindowControl(int monitorIndex, int windowIndex,
const std::vector<QRect>& monitorDims, const QColor& winColor, QWidget* parent);
const std::vector<QRect>& monitorDims, const QColor& winColor,
bool resetToDefault, QWidget* parent);
/**
* Makes the window label at top of a window control column visible
@@ -66,20 +75,100 @@ public:
*/
void resetToDefaults();
sgct::config::Window generateWindowInformation() const;
/**
* Sets the window dimensions
*
* \param newDims The x, y dimensions to set the window to
*/
void setDimensions(QRectF newDims);
/**
* Sets the monitor selection combobox
*
* \param monitorIndex The zero-based monitor index to set the combobox selection to
*/
void setMonitorSelection(int monitorIndex);
/**
* Sets the window name in the text edit box
*
* \param windowName The window title to set
*/
void setWindowName(const std::string& windowName);
/**
* Sets the window's decoration status. If set to true, then the window has a
* border. If false it is borderless
*
* \param hasWindowDecoration boolean for if window has decoration (border)
*/
void setDecorationState(bool hasWindowDecoration);
/**
* Generates window configuration (sgct::config::Window struct) based on the
* GUI settings.
*
* \param window The sgct::config::Window struct that is passed into the function
* and modified with the generated window content
*/
void generateWindowInformation(sgct::config::Window& window) const;
/**
* Sets the window's projection type to planar, with the accompanying parameters
* for horizontal and vertical FOV.
*
* \param hfov float value for horizontal field of view angle (degrees)
* \param vfov float value for vertical field of view angle (degrees)
*/
void setProjectionPlanar(float hfov, float vfov);
/**
* Sets the window's projection type to fisheye, with the accompanying quality
* setting and spout option
*
* \param quality int value for number of vertical lines of resolution. This will
* be compared against the QualityValues array in order to set the
* correct combobox index
* \param spoutOutput bool for enabling the spout output option
*/
void setProjectionFisheye(int quality, bool spoutOutput);
/**
* Sets the window's projection type to spherical mirror, with the accompanying
* quality setting
*
* \param quality int value for number of vertical lines of resolution. This will
* be compared against the QualityValues array in order to set the
* correct combobox index
*/
void setProjectionSphericalMirror(int quality);
/**
* Sets the window's projection type to cylindrical, with the accompanying quality
* setting and height offset value
*
* \param quality int value for number of vertical lines of resolution. This will
* be compared against the QualityValues array in order to set the
* correct combobox index
* \param heightOffset float value for height offset to be applied
*/
void setProjectionCylindrical(int quality, float heightOffset);
/**
* Sets the window's projection type to equirectangular, with the accompanying
* quality setting and spout option
*
* \param quality int value for number of vertical lines of resolution. This will
* be compared against the QualityValues array in order to set the
* correct combobox index
* \param spoutOutput bool for enabling the spout output option
*/
void setProjectionEquirectangular(int quality, bool spoutOutput);
signals:
void windowChanged(int monitorIndex, int windowIndex, const QRectF& newDimensions);
private:
enum class ProjectionIndices {
Planar = 0,
Fisheye,
SphericalMirror,
Cylindrical,
Equirectangular
};
void createWidgets(const QColor& windowColor);
QWidget* createPlanarWidget();
QWidget* createFisheyeWidget();
@@ -98,6 +187,7 @@ private:
sgct::config::Projections generateProjectionInformation() const;
void updatePlanarLockedFov();
void setQualityComboBoxFromLinesResolution(int lines, QComboBox* combo);
static constexpr float IdealAspectRatio = 16.f / 9.f;
float _aspectRatioSize = IdealAspectRatio;

View File

@@ -175,16 +175,12 @@ namespace {
}
void saveWindowConfig(QWidget* parent, const std::filesystem::path& path,
sgct::config::Cluster& cluster)
const sgct::config::Cluster& cluster)
{
std::ofstream outFile;
try {
outFile.open(path, std::ofstream::out);
sgct::config::GeneratorVersion genEntry = sgct::config::GeneratorVersion{
"OpenSpace",
OPENSPACE_VERSION_MAJOR,
OPENSPACE_VERSION_MINOR
};
sgct::config::GeneratorVersion genEntry = versionMin;
outFile << sgct::serializeConfig(
cluster,
genEntry
@@ -217,6 +213,7 @@ LauncherWindow::LauncherWindow(bool profileEnabled,
, _userProfilePath(
absPath(globalConfig.pathTokens.at("USER_PROFILES")).string() + '/'
)
, _readOnlyWindowConfigs(globalConfig.readOnlyWindowConfigs)
, _readOnlyProfiles(globalConfig.readOnlyProfiles)
, _sgctConfigName(sgctConfigName)
{
@@ -246,9 +243,10 @@ LauncherWindow::LauncherWindow(bool profileEnabled,
populateProfilesList(globalConfig.profile);
_profileBox->setEnabled(profileEnabled);
populateWindowConfigsList(_sgctConfigName);
_windowConfigBox->setEnabled(sgctConfigEnabled);
populateWindowConfigsList(_sgctConfigName);
// Trigger currentIndexChanged so the preview file read is performed
_windowConfigBox->currentIndexChanged(_windowConfigBox->currentIndex());
std::filesystem::path p = absPath(
globalConfig.pathTokens.at("SYNC") + "/http/launcher_images"
@@ -343,13 +341,31 @@ QWidget* LauncherWindow::createCentralWidget() {
connect(
newWindowButton, &QPushButton::released,
[this]() {
openWindowEditor();
openWindowEditor("", true);
}
);
newWindowButton->setObjectName("small");
newWindowButton->setGeometry(geometry::NewWindowButton);
newWindowButton->setCursor(Qt::PointingHandCursor);
_editWindowButton = new QPushButton("Edit", centralWidget);
connect(
_editWindowButton,
&QPushButton::released,
[this]() {
std::filesystem::path pathSelected = absPath(selectedWindowConfig());
bool isUserConfig = isUserConfigSelected();
std::string fileSelected = pathSelected.generic_string();
if (std::filesystem::is_regular_file(pathSelected)) {
openWindowEditor(fileSelected, isUserConfig);
}
}
);
_editWindowButton->setVisible(true);
_editWindowButton->setObjectName("small");
_editWindowButton->setGeometry(geometry::EditWindowButton);
_editWindowButton->setCursor(Qt::PointingHandCursor);
return centralWidget;
}
@@ -537,15 +553,26 @@ bool handleConfigurationFile(QComboBox& box, const std::filesystem::directory_en
void LauncherWindow::populateWindowConfigsList(std::string preset) {
namespace fs = std::filesystem;
// Disconnect the signal for new window config selection during population process
disconnect(
_windowConfigBox,
QOverload<int>::of(&QComboBox::currentIndexChanged),
nullptr,
nullptr
);
_windowConfigBox->clear();
_userConfigCount = 0;
_userConfigStartingIdx = 0;
_preDefinedConfigStartingIdx = 0;
_windowConfigBox->addItem(QString::fromStdString("--- User Configurations ---"));
const QStandardItemModel* model =
qobject_cast<const QStandardItemModel*>(_windowConfigBox->model());
model->item(_userConfigCount)->setEnabled(false);
++_userConfigCount;
_userConfigCount++;
_userConfigStartingIdx++;
_preDefinedConfigStartingIdx++;
bool hasXmlConfig = false;
@@ -560,14 +587,16 @@ void LauncherWindow::populateWindowConfigsList(std::string preset) {
for (const fs::directory_entry& p : files) {
bool isConfigFile = handleConfigurationFile(*_windowConfigBox, p);
if (isConfigFile) {
++_userConfigCount;
_userConfigCount++;
_userConfigStartingIdx++;
_preDefinedConfigStartingIdx++;
}
hasXmlConfig |= p.path().extension() == ".xml";
}
_windowConfigBox->addItem(QString::fromStdString("--- OpenSpace Configurations ---"));
model = qobject_cast<const QStandardItemModel*>(_windowConfigBox->model());
model->item(_userConfigCount)->setEnabled(false);
_preDefinedConfigStartingIdx++;
if (std::filesystem::exists(_configPath)) {
// Sort files
@@ -601,7 +630,10 @@ void LauncherWindow::populateWindowConfigsList(std::string preset) {
}
// Always add the .cfg sgct default as first item
_windowConfigBox->insertItem(0, QString::fromStdString(_sgctConfigName));
_windowConfigBox->insertItem(
_windowConfigBoxIndexSgctCfgDefault,
QString::fromStdString(_sgctConfigName)
);
// Try to find the requested configuration file and set it as the current one. As we
// have support for function-generated configuration files that will not be in the
// list we need to add a preset that doesn't exist a file for
@@ -611,12 +643,63 @@ void LauncherWindow::populateWindowConfigsList(std::string preset) {
}
else {
// Add the requested preset at the top
_windowConfigBox->insertItem(1, QString::fromStdString(preset));
_windowConfigBox->insertItem(
_windowConfigBoxIndexSgctCfgDefault + 1,
QString::fromStdString(preset)
);
// Increment the user config count because there is an additional option added
// before the user config options
_userConfigCount++;
_windowConfigBox->setCurrentIndex(1);
_userConfigStartingIdx++;
_preDefinedConfigStartingIdx++;
_windowConfigBox->setCurrentIndex(_windowConfigBoxIndexSgctCfgDefault + 1);
}
connect(
_windowConfigBox,
QOverload<int>::of(&QComboBox::currentIndexChanged),
[this](int newIndex) {
std::filesystem::path pathSelected = absPath(selectedWindowConfig());
std::string fileSelected = pathSelected.generic_string();
if (newIndex == _windowConfigBoxIndexSgctCfgDefault) {
_editWindowButton->setEnabled(false);
_editWindowButton->setToolTip(
"Cannot edit the 'Default' configuration since it is not a file"
);
}
else if (newIndex >= _preDefinedConfigStartingIdx) {
_editWindowButton->setEnabled(false);
_editWindowButton->setToolTip(
QString::fromStdString(fmt::format(
"Cannot edit '{}' since it is one of the configuration "
"files provided in the OpenSpace installation", fileSelected))
);
}
else {
try {
sgct::config::GeneratorVersion previewGenVersion =
sgct::readConfigGenerator(fileSelected);
if (!versionCheck(previewGenVersion)) {
_editWindowButton->setEnabled(false);
_editWindowButton->setToolTip(QString::fromStdString(fmt::format(
"This file does not meet the minimum required version of {}.",
versionMin.versionString()
)));
return;
}
}
catch (const std::runtime_error& e) {
// Ignore an exception here because clicking the edit button will
// bring up an explanatory error message
}
_editWindowButton->setEnabled(true);
_editWindowButton->setToolTip("");
}
}
);
}
bool LauncherWindow::versionCheck(sgct::config::GeneratorVersion& v) const {
return (v.versionCheck(versionMin) || v == versionLegacy18 || v == versionLegacy19);
}
void LauncherWindow::openProfileEditor(const std::string& profile, bool isUserProfile) {
@@ -659,18 +742,112 @@ void LauncherWindow::openProfileEditor(const std::string& profile, bool isUserPr
}
}
void LauncherWindow::openWindowEditor() {
SgctEdit editor(this, _userConfigPath);
int ret = editor.exec();
if (ret == QDialog::DialogCode::Accepted) {
sgct::config::Cluster cluster = editor.cluster();
void LauncherWindow::editRefusalDialog(const std::string& title, const std::string& msg,
const std::string& detailedText)
{
QMessageBox msgBox(this);
msgBox.setText(QString::fromStdString(msg));
msgBox.setWindowTitle(QString::fromStdString(title));
msgBox.setDetailedText(QString::fromStdString(detailedText));
msgBox.setIcon(QMessageBox::Warning);
msgBox.exec();
}
std::filesystem::path savePath = editor.saveFilename();
saveWindowConfig(this, savePath, cluster);
// Truncate path to convert this back to path relative to _userConfigPath
std::string p = savePath.string().substr(_userConfigPath.size());
populateWindowConfigsList(p);
void LauncherWindow::openWindowEditor(const std::string& winCfg, bool isUserWinCfg) {
using namespace sgct;
std::string saveWindowCfgPath = isUserWinCfg ? _userConfigPath : _configPath;
int ret = QDialog::DialogCode::Rejected;
config::Cluster preview;
if (winCfg.empty()) {
SgctEdit editor(this, _userConfigPath);
ret = editor.exec();
if (ret == QDialog::DialogCode::Accepted) {
handleReturnFromWindowEditor(
editor.cluster(),
editor.saveFilename(),
saveWindowCfgPath
);
}
}
else {
try {
config::GeneratorVersion previewGenVersion = readConfigGenerator(winCfg);
loadFileAndSchemaThenValidate(
winCfg,
_configPath + "/schema/sgct.schema.json",
"This configuration file is unable to generate a proper display"
);
loadFileAndSchemaThenValidate(
winCfg,
_configPath + "/schema/sgcteditor.schema.json",
"This configuration file is valid for generating a display, but "
"its format does not match the window editor requirements and "
"cannot be opened in the editor"
);
if (versionCheck(previewGenVersion)) {
try {
preview = readConfig(
winCfg,
"This configuration file is unable to generate a proper display "
"due to a problem detected in the readConfig function"
);
}
catch (const std::runtime_error& e) {
//Re-throw an SGCT error exception with the runtime exception message
throw std::runtime_error(
fmt::format(
"Importing of this configuration file failed because of a "
"problem detected in the readConfig function:\n\n{}", e.what()
)
);
}
SgctEdit editor(
preview,
winCfg,
saveWindowCfgPath,
_readOnlyWindowConfigs,
this
);
ret = editor.exec();
if (ret == QDialog::DialogCode::Accepted) {
handleReturnFromWindowEditor(
editor.cluster(),
editor.saveFilename(),
saveWindowCfgPath
);
}
}
else {
editRefusalDialog(
"File Format Version Error",
fmt::format(
"File '{}' does not meet the minimum required version of {}.",
winCfg, versionMin.versionString()
),
""
);
}
}
catch (const std::runtime_error& e) {
editRefusalDialog(
"Format Validation Error",
fmt::format("Parsing error found in file '{}'", winCfg),
e.what()
);
}
}
}
void LauncherWindow::handleReturnFromWindowEditor(const sgct::config::Cluster& cluster,
std::filesystem::path savePath,
const std::string& saveWindowCfgPath)
{
savePath.replace_extension(".json");
saveWindowConfig(this, savePath, cluster);
// Truncate path to convert this back to path relative to _userConfigPath
std::string p = std::filesystem::proximate(savePath, saveWindowCfgPath).string();
populateWindowConfigsList(p);
}
bool LauncherWindow::wasLaunchSelected() const {
@@ -694,3 +871,8 @@ std::string LauncherWindow::selectedWindowConfig() const {
return "${USER_CONFIG}/" + _windowConfigBox->currentText().toStdString();
}
}
bool LauncherWindow::isUserConfigSelected() const {
int selectedIndex = _windowConfigBox->currentIndex();
return (selectedIndex <= _userConfigCount);
}

View File

@@ -36,16 +36,22 @@
DisplayWindowUnion::DisplayWindowUnion(const std::vector<QRect>& monitorSizeList,
int nMaxWindows,
const std::array<QColor, 4>& windowColors,
QWidget* parent)
bool resetToDefault, QWidget* parent)
: QWidget(parent)
{
createWidgets(nMaxWindows, monitorSizeList, windowColors);
createWidgets(
nMaxWindows,
monitorSizeList,
windowColors,
resetToDefault
);
showWindows();
}
void DisplayWindowUnion::createWidgets(int nMaxWindows,
std::vector<QRect> monitorResolutions,
std::array<QColor, 4> windowColors)
std::array<QColor, 4> windowColors,
bool resetToDefault)
{
// Add all window controls (some will be hidden from GUI initially)
for (int i = 0; i < nMaxWindows; ++i) {
@@ -57,6 +63,7 @@ void DisplayWindowUnion::createWidgets(int nMaxWindows,
i,
monitorResolutions,
windowColors[i],
resetToDefault,
this
);
_windowControl.push_back(ctrl);
@@ -120,7 +127,7 @@ void DisplayWindowUnion::createWidgets(int nMaxWindows,
layout->addStretch();
}
std::vector<WindowControl*> DisplayWindowUnion::windowControls() const {
std::vector<WindowControl*> DisplayWindowUnion::activeWindowControls() const {
std::vector<WindowControl*> res;
res.reserve(_nWindowsDisplayed);
for (unsigned int i = 0; i < _nWindowsDisplayed; ++i) {
@@ -129,6 +136,10 @@ std::vector<WindowControl*> DisplayWindowUnion::windowControls() const {
return res;
}
std::vector<WindowControl*>& DisplayWindowUnion::windowControls() {
return _windowControl;
}
void DisplayWindowUnion::addWindow() {
if (_nWindowsDisplayed < _windowControl.size()) {
_windowControl[_nWindowsDisplayed]->resetToDefaults();
@@ -144,6 +155,10 @@ void DisplayWindowUnion::removeWindow() {
}
}
unsigned int DisplayWindowUnion::numWindowsDisplayed() const {
return _nWindowsDisplayed;
}
void DisplayWindowUnion::showWindows() {
for (size_t i = 0; i < _windowControl.size(); ++i) {
_windowControl[i]->setVisible(i < _nWindowsDisplayed);

View File

@@ -80,3 +80,11 @@ bool SettingsWidget::vsync() const {
bool SettingsWidget::showUiOnFirstWindow() const {
return _showUiOnFirstWindow->isChecked();
}
void SettingsWidget::setShowUiOnFirstWindow(bool setUiOnFirstWindow) {
_showUiOnFirstWindow->setChecked(setUiOnFirstWindow);
}
void SettingsWidget::setVsync(bool enableVsync) {
_checkBoxVsync->setChecked(enableVsync);
}

View File

@@ -27,7 +27,6 @@
#include <sgctedit/displaywindowunion.h>
#include <sgctedit/monitorbox.h>
#include <sgctedit/settingswidget.h>
#include <sgctedit/windowcontrol.h>
#include <ghoul/filesystem/filesystem.h>
#include <QApplication>
#include <QFileDialog>
@@ -65,15 +64,160 @@ namespace {
// We got to the end without running into any problems, so we are golden
return false;
}
template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
} // namespace
SgctEdit::SgctEdit(QWidget* parent, std::string userConfigPath)
: QDialog(parent)
, _userConfigPath(std::move(userConfigPath))
{
QList<QScreen*> screens = qApp->screens();
setWindowTitle("Window Configuration Editor");
createWidgets(createMonitorInfoSet(), 1, true);
}
SgctEdit::SgctEdit(sgct::config::Cluster& cluster, const std::string& configName,
std::string& configBasePath,
const std::vector<std::string>& configsReadOnly, QWidget* parent)
: QDialog(parent)
, _cluster(cluster)
, _userConfigPath(configBasePath)
, _configurationFilename(configName)
, _readOnlyConfigs(configsReadOnly)
, _didImportValues(true)
{
setWindowTitle("Window Configuration Editor");
size_t nWindows = _cluster.nodes.front().windows.size();
bool firstWindowGuiIsEnabled = (nWindows > 1);
std::vector<QRect> monitorSizes = createMonitorInfoSet();
createWidgets(monitorSizes, nWindows, false);
size_t existingWindowsControlSize = _displayWidget->windowControls().size();
for (size_t i = 0; i < nWindows; ++i) {
sgct::config::Window& w = _cluster.nodes.front().windows[i];
WindowControl* wCtrl = _displayWidget->windowControls()[i];
if (i < existingWindowsControlSize && wCtrl) {
unsigned int monitorNum = 0;
if (w.monitor) {
monitorNum = static_cast<unsigned int>(w.monitor.value());
if (monitorNum > (monitorSizes.size() - 1)) {
monitorNum = 0;
}
}
unsigned int posX = 0;
unsigned int posY = 0;
wCtrl->setMonitorSelection(monitorNum);
if (w.pos.has_value()) {
posX = w.pos.value().x;
posY = w.pos.value().y;
// Convert offsets to coordinates relative to the selected monitor bounds,
// since window offsets are stored n the sgct config file relative to the
// coordinates of the total "canvas" of all displays
if (monitorSizes.size() > monitorNum) {
posX -= monitorSizes[monitorNum].x();
posY -= monitorSizes[monitorNum].y();
}
}
QRectF newDims(
posX,
posY,
w.size.x,
w.size.y
);
wCtrl->setDimensions(newDims);
if (w.name.has_value()) {
wCtrl->setWindowName(w.name.value());
}
wCtrl->setDecorationState(w.isDecorated.value());
}
// If first window only renders 2D, and all subsequent windows render 3D, then
// will enable the checkbox option for showing GUI only on first window
if (w.draw2D.has_value() && w.draw3D.has_value()) {
firstWindowGuiIsEnabled &= (i == 0) ? w.draw2D.value() : !w.draw2D.value();
firstWindowGuiIsEnabled &= (i == 0) ? !w.draw3D.value() : w.draw3D.value();
}
else {
firstWindowGuiIsEnabled = false;
}
setupProjectionTypeInGui(w.viewports.back(), wCtrl);
}
_settingsWidget->setShowUiOnFirstWindow(firstWindowGuiIsEnabled);
_settingsWidget->setVsync(
_cluster.settings &&
_cluster.settings.value().display &&
_cluster.settings.value().display.value().swapInterval
);
}
void SgctEdit::setupProjectionTypeInGui(sgct::config::Viewport& vPort,
WindowControl* wCtrl)
{
std::visit(overloaded{
[&](sgct::config::CylindricalProjection p) {
if (p.quality && p.heightOffset) {
wCtrl->setProjectionCylindrical(
*p.quality,
*p.heightOffset
);
}
},
[&](sgct::config::EquirectangularProjection p) {
if (p.quality) {
wCtrl->setProjectionEquirectangular(
*p.quality,
false
);
}
},
[&](sgct::config::FisheyeProjection p) {
if (p.quality) {
wCtrl->setProjectionFisheye(
*p.quality,
false
);
}
},
[&](sgct::config::PlanarProjection p) {
wCtrl->setProjectionPlanar(
(std::abs(p.fov.left) + std::abs(p.fov.right)),
(std::abs(p.fov.up) + std::abs(p.fov.down))
);
},
[&](sgct::config::SphericalMirrorProjection p) {
if (p.quality) {
wCtrl->setProjectionSphericalMirror(
*p.quality
);
}
},
[&](sgct::config::SpoutOutputProjection p) {
if (p.quality) {
if (p.mapping ==
sgct::config::SpoutOutputProjection::Mapping::Equirectangular)
{
wCtrl->setProjectionEquirectangular(
*p.quality,
true
);
}
else if (p.mapping ==
sgct::config::SpoutOutputProjection::Mapping::Fisheye)
{
wCtrl->setProjectionFisheye(
*p.quality,
true
);
}
}
},
[&](sgct::config::NoProjection) {},
[&](sgct::config::ProjectionPlane) {},
[&](sgct::config::SpoutFlatProjection) {}
}, vPort.projection);
}
std::vector<QRect> SgctEdit::createMonitorInfoSet() {
QList<QScreen*> screens = qApp->screens();
int nScreensManaged = std::min(static_cast<int>(screens.length()), 4);
std::vector<QRect> monitorSizes;
for (int s = 0; s < nScreensManaged; ++s) {
@@ -88,11 +232,12 @@ SgctEdit::SgctEdit(QWidget* parent, std::string userConfigPath)
static_cast<int>(actualHeight * screens[s]->devicePixelRatio())
);
}
createWidgets(monitorSizes);
return monitorSizes;
}
void SgctEdit::createWidgets(const std::vector<QRect>& monitorSizes) {
void SgctEdit::createWidgets(const std::vector<QRect>& monitorSizes,
unsigned int nWindows, bool setToDefaults)
{
QBoxLayout* layout = new QVBoxLayout(this);
layout->setSizeConstraint(QLayout::SetFixedSize);
@@ -118,6 +263,7 @@ void SgctEdit::createWidgets(const std::vector<QRect>& monitorSizes) {
monitorSizes,
MaxNumberWindows,
_colorsForWindows,
setToDefaults,
this
);
connect(
@@ -128,7 +274,9 @@ void SgctEdit::createWidgets(const std::vector<QRect>& monitorSizes) {
_displayWidget, &DisplayWindowUnion::nWindowsChanged,
monitorBox, &MonitorBox::nWindowsDisplayedChanged
);
_displayWidget->addWindow();
for (unsigned int i = 0; i < nWindows; ++i) {
_displayWidget->addWindow();
}
displayLayout->addWidget(_displayWidget);
@@ -152,7 +300,8 @@ void SgctEdit::createWidgets(const std::vector<QRect>& monitorSizes) {
connect(_cancelButton, &QPushButton::released, this, &SgctEdit::reject);
layoutButtonBox->addWidget(_cancelButton);
_saveButton = new QPushButton("Save As");
_saveButton = _didImportValues ?
new QPushButton("Save") : new QPushButton("Save As");
_saveButton->setToolTip("Save configuration changes");
_saveButton->setFocusPolicy(Qt::NoFocus);
connect(_saveButton, &QPushButton::released, this, &SgctEdit::save);
@@ -173,8 +322,8 @@ std::filesystem::path SgctEdit::saveFilename() const {
}
void SgctEdit::save() {
sgct::config::Cluster cluster = generateConfiguration();
if (hasWindowIssues(cluster)) {
generateConfiguration();
if (hasWindowIssues(_cluster)) {
int ret = QMessageBox::warning(
this,
"Window Sizes Incompatible",
@@ -190,27 +339,32 @@ void SgctEdit::save() {
}
}
QString fileName = QFileDialog::getSaveFileName(
this,
"Save Window Configuration File",
QString::fromStdString(_userConfigPath),
"Window Configuration (*.json)",
nullptr
#ifdef __linux__
// Linux in Qt5 and Qt6 crashes when trying to access the native dialog here
, QFileDialog::DontUseNativeDialog
#endif
);
if (!fileName.isEmpty()) {
_saveTarget = fileName.toStdString();
_cluster = std::move(cluster);
if (_didImportValues) {
_saveTarget = _configurationFilename;
accept();
}
else {
QString fileName = QFileDialog::getSaveFileName(
this,
"Save Window Configuration File",
QString::fromStdString(_userConfigPath),
"Window Configuration (*.json)",
nullptr
#ifdef __linux__
// Linux in Qt5 and Qt6 crashes when trying to access the native dialog here
, QFileDialog::DontUseNativeDialog
#endif
);
if (!fileName.isEmpty()) {
_saveTarget = fileName.toStdString();
accept();
}
}
}
void SgctEdit::apply() {
sgct::config::Cluster cluster = generateConfiguration();
if (hasWindowIssues(cluster)) {
generateConfiguration();
if (hasWindowIssues(_cluster)) {
int ret = QMessageBox::warning(
this,
"Window Sizes Incompatible",
@@ -235,63 +389,101 @@ void SgctEdit::apply() {
std::filesystem::create_directories(absPath(userCfgTempDir));
}
_saveTarget = userCfgTempDir + "/apply-without-saving.json";
_cluster = std::move(cluster);
accept();
}
sgct::config::Cluster SgctEdit::generateConfiguration() const {
sgct::config::Cluster cluster;
void SgctEdit::generateConfiguration() {
_cluster.scene = sgct::config::Scene();
_cluster.scene->orientation = _settingsWidget->orientation();
if (_cluster.nodes.empty()) {
_cluster.nodes.push_back(sgct::config::Node());
}
sgct::config::Node& node = _cluster.nodes.back();
sgct::config::Scene scene;
scene.orientation = _settingsWidget->orientation();
cluster.scene = std::move(scene);
cluster.masterAddress = "localhost";
generateConfigSetupVsync();
generateConfigUsers();
generateConfigAddresses(node);
generateConfigResizeWindowsAccordingToSelected(node);
generateConfigIndividualWindowSettings(node);
}
void SgctEdit::generateConfigSetupVsync() {
if (_settingsWidget->vsync()) {
sgct::config::Settings::Display display;
display.swapInterval = 1;
sgct::config::Settings settings;
settings.display = display;
cluster.settings = settings;
}
sgct::config::Node node;
node.address = "localhost";
node.port = 20401;
// Save Windows
unsigned int windowIndex = 0;
for (WindowControl* wCtrl : _displayWidget->windowControls()) {
sgct::config::Window window = wCtrl->generateWindowInformation();
window.id = windowIndex++;
node.windows.push_back(std::move(window));
}
if (_settingsWidget->showUiOnFirstWindow()) {
sgct::config::Window& window = node.windows.front();
window.viewports.back().isTracked = false;
window.tags.push_back("GUI");
window.draw2D = true;
window.draw3D = false;
// Disable 2D rendering on all non-GUI windows
for (size_t w = 1; w < node.windows.size(); ++w) {
node.windows[w].draw2D = false;
if (!_cluster.settings || !_cluster.settings->display ||
!_cluster.settings->display->swapInterval)
{
sgct::config::Settings::Display display;
display.swapInterval = 1;
sgct::config::Settings settings;
settings.display = display;
_cluster.settings = settings;
}
}
else {
_cluster.settings = std::nullopt;
}
}
cluster.nodes.push_back(node);
void SgctEdit::generateConfigUsers() {
if (!_didImportValues) {
sgct::config::User user;
user.eyeSeparation = 0.065f;
user.position = { 0.f, 0.f, 4.f };
_cluster.users = { user };
}
}
sgct::config::User user;
user.eyeSeparation = 0.065f;
user.position = sgct::vec3(0.f, 0.f, 4.f);
cluster.users = { user };
void SgctEdit::generateConfigAddresses(sgct::config::Node& node) {
if (!_didImportValues) {
_cluster.masterAddress = "localhost";
node.address = "localhost";
node.port = 20401;
}
}
return cluster;
void SgctEdit::generateConfigResizeWindowsAccordingToSelected(sgct::config::Node& node) {
std::vector<WindowControl*> windowControls = _displayWidget->activeWindowControls();
for (size_t wIdx = 0; wIdx < windowControls.size(); ++wIdx) {
if (node.windows.size() <= wIdx) {
node.windows.push_back(sgct::config::Window());
}
if (windowControls[wIdx]) {
windowControls[wIdx]->generateWindowInformation(
node.windows[wIdx]
);
}
}
while (node.windows.size() > windowControls.size()) {
node.windows.pop_back();
}
}
void SgctEdit::generateConfigIndividualWindowSettings(sgct::config::Node& node) {
for (size_t i = 0; i < node.windows.size(); ++i) {
// First apply default settings to each window...
node.windows[i].id = i;
node.windows[i].draw2D = true;
node.windows[i].draw3D = true;
node.windows[i].viewports.back().isTracked = true;
node.windows[i].tags.erase(
std::remove(
node.windows[i].tags.begin(),
node.windows[i].tags.end(),
"GUI"
),
node.windows[i].tags.end()
);
// If "show UI on first window" option is enabled, then modify the settings
// depending on if this is the first window or not
if (_settingsWidget->showUiOnFirstWindow()) {
if (i == 0) {
node.windows[i].viewports.back().isTracked = false;
node.windows[i].tags.push_back("GUI");
}
node.windows[i].draw2D = (i == 0);
node.windows[i].draw3D = (i != 0);
}
}
}
sgct::config::Cluster SgctEdit::cluster() const {

View File

@@ -43,15 +43,22 @@ namespace {
"Primary", "Secondary", "Tertiary", "Quaternary"
};
constexpr int nQualityTypes = 10;
const QList<QString> QualityTypes = {
"Low (256)", "Medium (512)", "High (1K)", "1.5K (1536)", "2K (2048)", "4K (4096)",
"8K (8192)", "16K (16384)", "32K (32768)", "64K (65536)"
};
constexpr int QualityValues[10] = {
constexpr int QualityValues[nQualityTypes] = {
256, 512, 1024, 1536, 2048, 4096, 8192, 16384, 32768, 65536
};
const QList<QString> ProjectionTypes = {
"Planar Projection", "Fisheye", "Spherical Mirror Projection",
"Cylindrical Projection", "Equirectangular Projection"
};
constexpr std::array<QRectF, 4> DefaultWindowSizes = {
QRectF(50.f, 50.f, 1280.f, 720.f),
QRectF(150.f, 150.f, 1280.f, 720.f),
@@ -59,7 +66,7 @@ namespace {
QRectF(150.f, 150.f, 1280.f, 720.f)
};
constexpr int LineEditWidthFixedWindowSize = 50;
constexpr int LineEditWidthFixedWindowSize = 64;
constexpr float DefaultFovLongEdge = 80.f;
constexpr float DefaultFovShortEdge = 50.534f;
constexpr float DefaultHeightOffset = 0.f;
@@ -81,7 +88,7 @@ namespace {
WindowControl::WindowControl(int monitorIndex, int windowIndex,
const std::vector<QRect>& monitorDims,
const QColor& winColor, QWidget* parent)
const QColor& winColor, bool resetToDefault, QWidget* parent)
: QWidget(parent)
, _monitorIndexDefault(monitorIndex)
, _windowIndex(windowIndex)
@@ -90,7 +97,9 @@ WindowControl::WindowControl(int monitorIndex, int windowIndex,
, _unlockIcon(":/images/outline_unlocked.png")
{
createWidgets(winColor);
resetToDefaults();
if (resetToDefault) {
resetToDefaults();
}
}
void WindowControl::createWidgets(const QColor& windowColor) {
@@ -293,11 +302,11 @@ void WindowControl::createWidgets(const QColor& windowColor) {
_projectionType = new QComboBox;
_projectionType->addItems({
"Planar Projection",
"Fisheye",
"Spherical Mirror Projection",
"Cylindrical Projection",
"Equirectangular Projection"
ProjectionTypes[0],
ProjectionTypes[1],
ProjectionTypes[2],
ProjectionTypes[3],
ProjectionTypes[4]
});
_projectionType->setToolTip("Select from the supported window projection types");
_projectionType->setCurrentIndex(0);
@@ -625,10 +634,30 @@ void WindowControl::resetToDefaults() {
emit windowChanged(_monitorIndexDefault, _windowIndex, _windowDimensions);
}
void WindowControl::setDimensions(QRectF newDims) {
_windowDimensions = newDims;
_sizeX->setValue(_windowDimensions.width());
_sizeY->setValue(_windowDimensions.height());
_offsetX->setValue(_windowDimensions.x());
_offsetY->setValue(_windowDimensions.y());
}
void WindowControl::setMonitorSelection(int monitorIndex) {
_monitor->setCurrentIndex(monitorIndex);
}
void WindowControl::showWindowLabel(bool show) {
_windowNumber->setVisible(show);
}
void WindowControl::setWindowName(const std::string& windowName) {
_windowName->setText(QString::fromStdString(windowName));
}
void WindowControl::setDecorationState(bool hasWindowDecoration) {
_windowDecoration->setChecked(hasWindowDecoration);
}
sgct::config::Projections WindowControl::generateProjectionInformation() const {
ProjectionIndices type =
static_cast<WindowControl::ProjectionIndices>(_projectionType->currentIndex());
@@ -706,9 +735,9 @@ sgct::config::Projections WindowControl::generateProjectionInformation() const {
}
}
sgct::config::Window WindowControl::generateWindowInformation() const {
sgct::config::Window window;
window.size = sgct::ivec2(_sizeX->text().toInt(), _sizeY->text().toInt());
void WindowControl::generateWindowInformation(sgct::config::Window& window) const {
window.size = { _sizeX->text().toInt(), _sizeY->text().toInt() };
window.monitor = _monitor->currentIndex();
QRect resolution = _monitorResolutions[_monitor->currentIndex()];
window.pos = sgct::ivec2(
resolution.x() + _offsetX->text().toInt(),
@@ -720,17 +749,56 @@ sgct::config::Window WindowControl::generateWindowInformation() const {
vp.position = sgct::vec2(0.f, 0.f);
vp.size = sgct::vec2(1.f, 1.f);
vp.projection = generateProjectionInformation();
window.viewports.clear();
window.viewports.push_back(vp);
window.isDecorated = _windowDecoration->isChecked();
if (window.isFullScreen) {
window.monitor = _monitor->currentIndex();
}
if (!_windowName->text().isEmpty()) {
window.name = _windowName->text().toStdString();
}
return window;
}
void WindowControl::setProjectionPlanar(float hfov, float vfov) {
_planar.fovH->setValue(hfov);
_planar.fovV->setValue(vfov);
_projectionType->setCurrentIndex(static_cast<int>(ProjectionIndices::Planar));
}
void WindowControl::setProjectionFisheye(int quality, bool spoutOutput) {
setQualityComboBoxFromLinesResolution(quality, _fisheye.quality);
_fisheye.spoutOutput->setChecked(spoutOutput);
_projectionType->setCurrentIndex(static_cast<int>(ProjectionIndices::Fisheye));
}
void WindowControl::setProjectionSphericalMirror(int quality) {
setQualityComboBoxFromLinesResolution(quality, _sphericalMirror.quality);
_projectionType->setCurrentIndex(
static_cast<int>(ProjectionIndices::SphericalMirror)
);
}
void WindowControl::setProjectionCylindrical(int quality, float heightOffset) {
setQualityComboBoxFromLinesResolution(quality, _cylindrical.quality);
_cylindrical.heightOffset->setValue(heightOffset);
_projectionType->setCurrentIndex(static_cast<int>(ProjectionIndices::Cylindrical));
}
void WindowControl::setProjectionEquirectangular(int quality, bool spoutOutput) {
setQualityComboBoxFromLinesResolution(quality, _equirectangular.quality);
_equirectangular.spoutOutput->setChecked(spoutOutput);
_projectionType->setCurrentIndex(
static_cast<int>(ProjectionIndices::Equirectangular)
);
}
void WindowControl::setQualityComboBoxFromLinesResolution(int lines, QComboBox* combo) {
ghoul_assert(combo, "Invalid pointer");
for (unsigned int v = 0; v < nQualityTypes; ++v) {
if (lines == QualityValues[v]) {
combo->setCurrentIndex(v);
break;
}
}
}
void WindowControl::onSizeXChanged(int newValue) {

View File

@@ -0,0 +1,322 @@
{
"$id": "schema2e",
"$defs": {
"cylindricalprojection": {
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "CylindricalProjection",
"default": "CylindricalProjection",
"readOnly": true
},
"quality": {
"$ref": "sgct.schema.json#/$defs/projectionquality"
},
"heightOffset": {
"type": "number",
"title": "Height Offset",
"description": "Offsets the height from which the cylindrical projection is generated. This is, in general, only necessary if the user position is offset and you want to counter that offset to continue producing a “standard” cylindrical projection"
}
},
"required": [ "type" ],
"additionalProperties": false,
"description": "This projection method renders the scene into a view that can be mapped on the inside or outside of a cylinder. This projection method is support by some live media curation tools. The forward-facing direction will be at the left border of the image unless changed via the rotation option"
},
"fisheyeprojection": {
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "FisheyeProjection",
"default": "FisheyeProjection",
"readOnly": true
},
"quality": {
"$ref": "sgct.schema.json#/$defs/projectionquality"
}
},
"required": [ "type" ],
"additionalProperties": false,
"description": "Describes a fisheye projection that is used to render into its parent Viewport. This uses a default of 180 degrees field of view and has a 1:1 aspect ratio. This projection type counts as a non-linear projection, which requires 4-6 render passes of the application, meaning that the application might render slower when using these kind of projections than a flat projection. In either case, the application does not need to be aware of the projection as this abstract is handled internally and the applications draw method is only called multiple times per frame with different projection methods that are used to create the full fisheye projection"
},
"planarprojection": {
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "PlanarProjection",
"default": "PlanarProjection",
"readOnly": true
},
"fov": {
"$ref": "sgct.schema.json#/$defs/fovhorizontalvertical",
"title": "Camera Field-of-View",
"description": "This element describes the field of view used the camera in this planar projection"
}
},
"additionalProperties": false,
"description": "Describes a projection for the Viewport that is a flat projection described by simple frustum, which may be asymmetric"
},
"sphericalmirrorprojection": {
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "SphericalMirrorProjection",
"default": "SphericalMirrorProjection",
"readOnly": true
},
"quality": {
"$ref": "sgct.schema.json#/$defs/projectionquality"
}
},
"required": [ "type" ],
"additionalProperties": false,
"description": "Used to create a projection used for Paul Bourke's spherical mirror setup (see here), which makes it possible to use an off-the-shelf projector to create a planetarium-like environment by bouncing the image of a shiny metal mirror. Please note that this is not the only way to produce these kind of images. Depending on your setup and availability of warping meshes, it might suffice to use the FisheyeProjection node type instead and add a single mesh to the parent Viewport instead. The config folder in SGCT contains an example of this using a default 16x9 warping mesh. This projection type specifically deals with the case where you have four different meshes, one for the bottom, top, left, and right parts of the distorted image"
},
"spoutoutputprojection": {
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "SpoutOutputProjection",
"default": "SpoutOutputProjection",
"readOnly": true
},
"quality": {
"$ref": "sgct.schema.json#/$defs/projectionquality"
},
"mapping": {
"type": "string",
"enum": [ "fisheye", "equirectangular" ],
"title": "Mapping",
"description": "Determines the type of sharing that occurs with this projection and thus how many and which texture is shared via Spout. For the “fisheye” and “equirectangular”, only the single, final reprojected image is shared, for the “cubemap” method, all selected cubemaps will be provided through the Spout interface. The default value is “cubemap”"
},
"mappingspoutname": {
"type": "string",
"title": "Mapping Spout Name",
"description": "Sets the name of the texture if the mapping type is 'fisheye' or 'equirectangular'. If the mapping is 'cubemap', this value is ignored"
}
},
"required": [ "type", "mapping" ],
"additionalProperties": false,
"description": "Provides the ability to share a fully reprojected image using the Spout library. This library only supports the Windows operating system, so this projection will only work on Windows machines. Spout's functionality is the abilty to shared textures between different applications on the same machine, making it possible to render images using SGCT and making them available to other real-time applications on the same machine for further processing. Spout uses a textual name for accessing which texture should be used for sharing. The SpoutOutputProjection has three different output types, outputting each cube map face, sharing a fisheye image, or sharing an equirectangular projection, as determined by the mapping attribute"
},
"projection": {
"oneOf": [
{
"$ref": "#/$defs/planarprojection",
"title": "Planar Projection"
},
{
"$ref": "#/$defs/fisheyeprojection",
"title": "Fisheye Projection"
},
{
"$ref": "#/$defs/sphericalmirrorprojection",
"title": "Spherical Mirror Projection"
},
{
"$ref": "#/$defs/spoutoutputprojection",
"title": "Spout Output Projection"
},
{
"$ref": "#/$defs/cylindricalprojection",
"title": "Cylindrical Projection"
},
{
"$ref": "sgct.schema.json#/$defs/equirectangularprojection",
"title": "Equirectangular Projection"
}
],
"title": "Projection"
},
"node": {
"type": "object",
"properties": {
"address": {
"$ref": "sgct.schema.json#/$defs/address"
},
"port": {
"$ref": "sgct.schema.json#/$defs/port"
},
"windows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"border": {
"$ref": "sgct.schema.json#/$defs/windowborder"
},
"draw2d": {
"$ref": "sgct.schema.json#/$defs/draw2d"
},
"draw3d": {
"$ref": "sgct.schema.json#/$defs/draw3d"
},
"monitor": {
"$ref": "sgct.schema.json#/$defs/monitor"
},
"id": {
"$ref": "sgct.schema.json#/$defs/id"
},
"name": {
"$ref": "sgct.schema.json#/$defs/windowname"
},
"pos": {
"$ref": "sgct.schema.json#/$defs/windowpos"
},
"size": {
"$ref": "sgct.schema.json#/$defs/windowsize"
},
"tags": {
"$ref": "sgct.schema.json#/$defs/tags"
},
"viewports": {
"type": "array",
"items": {
"type": "object",
"properties": {
"pos": {
"$ref": "sgct.schema.json#/$defs/viewportpos"
},
"size": {
"$ref": "sgct.schema.json#/$defs/viewportsize"
},
"projection": {
"$ref": "sgct.schema.json#/$defs/projection"
},
"tracked": {
"$ref": "sgct.schema.json#/$defs/tracked"
}
}
},
"title": "Viewports"
}
},
"required": [ "pos", "size", "viewports" ]
},
"title": "Windows",
"description": "Specifies a single window that is used to render content into. There can be an arbitrary(-ish) number of windows for each node and they all will be created and initialized at start time. Each window has at least one Viewport that specifies exactly where in the window the rendering occurs with which parameters"
}
},
"required": [ "address", "port", "windows" ],
"additionalProperties": false,
"description": "Defines a single computing node that is contained in the described cluster. In general this corresponds to a single computer, but it is also possible to create multiple nodes on a local machine by using the 127.0.0.x IP address with x from 0 to 255. It is not possible to create multiple nodes on the same remote computer, however"
},
"scene": {
"type": "object",
"properties": {
"orientation": {
"$ref": "sgct.schema.json#/$defs/quat",
"title": "Orientation",
"description": "Describes a fixed orientation of the global scene"
}
},
"required": [ "orientation" ],
"additionalProperties": false,
"description": "Determines an overall orientation of the scene. It consists only of an Orientation, which is included in the projection matrix that is passed to the rendering function callback of the specific application. This node can be used to customize the rendering for a specific rendering window. A common use-case in planetariums, for example, is to account for a tilt in the display system by providing an Orientation with the same pitch as the planetarium surface. This makes it possible to reuse the same application between the planetarium dome and fixed setups without the need for special care"
},
"display": {
"type": "object",
"properties": {
"swapinterval": {
"type": "integer",
"minimum": 0,
"title": "Swap Interval",
"description": "Determines the swap interval for the application. This determines the amount of V-Sync that should occur for the application. The two most common values for this are 0 for disabling V-Sync and 1 for regular V-Sync. The number provided determines the number of screen updates to wait before swapping the backbuffers and returning. For example on a 60Hz monitor, swapinterval=\"1\" would lead to a maximum of 60Hz frame rate, swapinterval=\"2\" would lead to a maximum of 30Hz frame rate. Using the same values for a 144Hz monitor would be a refresh rate of 144 and 72 respectively. The default value is 0, meaning that V-Sync is disabled"
}
},
"title": "Display",
"additionalProperties": false,
"description": "Settings specific for the handling of display-related settings for the whole application"
},
"settings": {
"type": "object",
"properties": {
"display": {
"$ref": "#/$defs/display"
}
},
"additionalProperties": false,
"description": "Controls global settings that affect the overall behavior of the SGCT library that are not limited just to a single window"
},
"user": {
"type": "object",
"properties": {
"name": {
"type": "string",
"title": "Name",
"description": "Specifies the name of this user. Each user needs to have a unique name, but there also has to be exactly one user present that has an empty name (or without a name attribute) which is used as the default user"
},
"eyeseparation": {
"type": "number",
"minimum": 0.0,
"title": "Eye Separation",
"description": "Determines the eye separation used for stereoscopic viewports. If no viewports in the configuration are using stereo, this setting is ignored"
},
"pos": {
"$ref": "sgct.schema.json#/$defs/vec3",
"title": "Position",
"description": "A linear offset of the user position. Must define three float attributes x, y, and z. The default values are x=0, y=0, z=0, meaning that no linear offset is applied to the user's position"
}
},
"additionalProperties": false,
"required": [ "pos" ],
"description": "Specifies a user position and parameters. In most cases, only a single unnamed user is necessary. However, in more general cases, it is possible to assign Users to specific Viewports to provide a more fine-grained control over the rendering that occurs in that viewport"
}
},
"type": "object",
"properties": {
"masteraddress": {
"$ref": "sgct.schema.json#/$defs/masteraddress"
},
"nodes": {
"type": "array",
"items": { "$ref": "#/$defs/node" },
"title": "Nodes"
},
"scene": {
"$ref": "#/$defs/scene",
"title": "Scene"
},
"settings": {
"$ref": "#/$defs/settings",
"title": "Settings"
},
"version": {
"type": "integer"
},
"users": {
"type": "array",
"items": { "$ref": "#/$defs/user" },
"title": "Users"
},
"generator": {
"type": "object",
"properties": {
"name": { "type": "string" },
"major": { "type": "integer" },
"minor": { "type": "integer" }
},
"required": [ "name", "major", "minor" ]
}
},
"additionalProperties": false,
"required": [
"version", "masteraddress", "scene", "users", "generator"
]
}

View File

@@ -0,0 +1,110 @@
local level_horizon_yaw = {
Identifier = "os.nightsky.level_horizon_yaw",
Name = "Level Horizon Yaw",
Command = [[
local currentNavState = openspace.navigation.getNavigationState();
local newNavState = {};
newNavState["Pitch"] = currentNavState["Pitch"];
newNavState["Anchor"] = currentNavState["Anchor"];
newNavState["Yaw"] = 0.0;
newNavState["Position"] = currentNavState["Position"];
newNavState["Up"] = currentNavState["Up"];
openspace.navigation.setNavigationState(newNavState)
]],
Documentation = "Levels the horizon horizontally.",
GuiPath = "/Night Sky/View",
IsLocal = false
}
local look_up = {
Identifier = "os.nightsky.look_up",
Name = "Look up",
Command = [[
local currentNavState = openspace.navigation.getNavigationState();
local newNavState = {};
newNavState["Pitch"] = math.pi;
newNavState["Anchor"] = currentNavState["Anchor"];
newNavState["Yaw"] = currentNavState["Yaw"];
newNavState["Position"] = currentNavState["Position"];
newNavState["Up"] = currentNavState["Up"];
openspace.navigation.setNavigationState(newNavState)
]],
Documentation = "Sets the view to be looking at the zenith",
GuiPath = "/Night Sky/View",
IsLocal = false
}
local level_horizon_pitch = {
Identifier = "os.nightsky.level_horizon_pitch",
Name = "Level Horizon Pitch",
Command = [[
local currentNavState = openspace.navigation.getNavigationState();
local newNavState = {};
newNavState["Pitch"] = math.pi / 2.0;
newNavState["Anchor"] = currentNavState["Anchor"];
newNavState["Yaw"] = currentNavState["Yaw"];
newNavState["Position"] = currentNavState["Position"];
newNavState["Up"] = currentNavState["Up"];
openspace.navigation.setNavigationState(newNavState)
]],
Documentation = "Levels the view to the horizon.",
GuiPath = "/Night Sky/View",
IsLocal = false
}
local looking_north = {
Identifier = "os.nightsky.looking_north",
Name = "Looking North",
Command = [[
local currentNavState = openspace.navigation.getNavigationState();
local newNavState = {};
newNavState["Pitch"] = math.pi / 2.0;
newNavState["Anchor"] = currentNavState["Anchor"];
newNavState["Yaw"] = currentNavState["Yaw"];
newNavState["Position"] = currentNavState["Position"];
newNavState["Up"] = { 0.0, 0.0, 1.0 };
openspace.navigation.setNavigationState(newNavState)
]],
Documentation = "Sets the view for a horizon looking North.",
GuiPath = "/Night Sky/View",
IsLocal = false
}
local looking_south = {
Identifier = "os.nightsky.looking_south",
Name = "Looking South",
Command = [[
local currentNavState = openspace.navigation.getNavigationState();
local newNavState = {};
newNavState["Pitch"] = math.pi / 2.0;
newNavState["Anchor"] = currentNavState["Anchor"];
newNavState["Yaw"] = currentNavState["Yaw"];
newNavState["Position"] = currentNavState["Position"];
newNavState["Up"] = { 0.0, 0.0, -1.0 };
openspace.navigation.setNavigationState(newNavState)
]],
Documentation = "Sets the view for a horizon looking South.",
GuiPath = "/Night Sky/View",
IsLocal = false
}
asset.onInitialize(function()
openspace.action.registerAction(look_up)
openspace.action.registerAction(level_horizon_yaw)
openspace.action.registerAction(level_horizon_pitch)
openspace.action.registerAction(looking_north)
openspace.action.registerAction(looking_south)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(looking_south)
openspace.action.removeAction(looking_north)
openspace.action.removeAction(level_horizon_pitch)
openspace.action.removeAction(level_horizon_yaw)
openspace.action.removeAction(look_up)
end)
asset.export(look_up)
asset.export(level_horizon_yaw)
asset.export(level_horizon_pitch)
asset.export(looking_north)
asset.export(looking_south)

View File

@@ -0,0 +1,30 @@
local enableDimming = {
Identifier = "os.nightsky.enable_dimming",
Name = "Enable atmosphere dimming",
Command = "openspace.setPropertyValue('{daytime_hidden}.Renderable.DimInAtmosphere', true)",
Documentation = "Sets items like the stars and constellations to be hidden during the day",
GuiPath = "/Night Sky/Daytime",
IsLocal = false
}
local disableDimming = {
Identifier = "os.nightsky.disable_dimming",
Name = "Disable atmosphere dimming",
Command = "openspace.setPropertyValue('{daytime_hidden}.Renderable.DimInAtmosphere', false)",
Documentation = "Sets items like the stars and constellations to be shown during the day",
GuiPath = "/Night Sky/Daytime",
IsLocal = false
}
asset.onInitialize(function()
openspace.action.registerAction(enableDimming)
openspace.action.registerAction(disableDimming)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(disableDimming)
openspace.action.removeAction(enableDimming)
end)
asset.export(enableDimming)
asset.export(disableDimming)

View File

@@ -53,6 +53,7 @@ asset.require("scene/digitaluniverse/superclusters")
asset.require("scene/digitaluniverse/supernovaremnants")
asset.require("scene/digitaluniverse/tully")
asset.require("scene/digitaluniverse/voids")
asset.require("nightsky/nightsky")
asset.require("customization/globebrowsing")
asset.require("util/default_actions")

View File

@@ -0,0 +1,79 @@
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
local sunAsset = asset.require('scene/solarsystem/sun/sun')
local modelFolder = asset.syncedResource({
Name = "Scale Model Arc de Triomphe",
Type = "HttpSynchronization",
Identifier = "scale_model_arc_de_triomphe",
Version = 1
})
local scaleModel = {
Identifier = "Scale_ArcDeTriomphe",
Parent = earthAsset.Earth.Identifier,
--Note: Lat/Lon/Scale values comes from alignment with Esri World Imagery 2D layer
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = earthAsset.Earth.Identifier,
Latitude = 48.87389,
Longitude = 2.29492,
Altitude = 0.0,
UseHeightmap = true
},
Rotation = {
Type = "GlobeRotation",
Globe = earthAsset.Earth.Identifier,
Latitude = 48.87389,
Longitude = 2.29492,
UseHeightmap = false
}
},
Renderable = {
Type = "RenderableModel",
GeometryFile = modelFolder .. "Fr_arch_OBJ.osmodel",
LightSources = { sunAsset.LightSource },
},
GUI = {
Name = "Arc de Triomphe",
Path = "/Scale Objects"
}
}
local updatePositionAction = {
Identifier = "os.scale_models.drop_arc_de_triomphe",
Name = "Drop Arc de Triomphe under camera",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera('Scale_ArcDeTriomphe')
]],
Documentation = "Updates the Arc de Triomphe position based on the globe location of the camera",
GuiPath = "/Scale Objects",
IsLocal = false
}
local resetPositionAction = {
Identifier = "os.scale_models.reset_arc_de_triomphe",
Name = "Reset Arc de Triomphe position",
Command = [[
openspace.globebrowsing.setNodePosition('Scale_ArcDeTriomphe', ']] .. earthAsset.Earth.Identifier .. [[', 48.87389, 2.29492)
]],
Documentation = "Resets the Arc de Triomphe back to it's actual location",
GuiPath = "/Scale Objects",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(scaleModel)
openspace.action.registerAction(updatePositionAction)
openspace.action.registerAction(resetPositionAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(resetPositionAction)
openspace.action.removeAction(updatePositionAction)
openspace.removeSceneGraphNode(scaleModel)
end)
asset.export(scaleModel)
asset.export(updatePositionAction)
asset.export(resetPositionAction)

View File

@@ -0,0 +1,81 @@
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
local sunAsset = asset.require('scene/solarsystem/sun/sun')
local modelFolder = asset.syncedResource({
Name = "Scale Model Big Ben",
Type = "HttpSynchronization",
Identifier = "scale_model_big_ben",
Version = 1
})
local scaleModel = {
Identifier = "Scale_BigBen",
Parent = earthAsset.Earth.Identifier,
--Note: Lat/Lon/Scale values comes from alignment with Esri World Imagery 2D layer
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = earthAsset.Earth.Identifier,
Latitude = 51.50079,
Longitude = -0.124279,
Altitude = 0.0,
UseHeightmap = true
},
Rotation = {
Type = "GlobeRotation",
Globe = earthAsset.Earth.Identifier,
Latitude = 51.50079,
Longitude = -0.124279,
UseHeightmap = false
}
},
Renderable = {
Type = "RenderableModel",
GeometryFile = modelFolder .. "bigben.osmodel",
RotationVector = { 0.0, 265.0, 0.0 },
LightSources = { sunAsset.LightSource },
ModelScale = "Millimeter"
},
GUI = {
Name = "Big Ben",
Path = "/Scale Objects"
}
}
local updatePositionAction = {
Identifier = "os.scale_models.drop_big_ben",
Name = "Drop Big Ben under camera",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera('Scale_BigBen')
]],
Documentation = "Updates the Big Ben position based on the globe location of the camera",
GuiPath = "/Scale Objects",
IsLocal = false
}
local resetPositionAction = {
Identifier = "os.scale_models.reset_big_ben",
Name = "Reset Big Ben position",
Command = [[
openspace.globebrowsing.setNodePosition('Scale_BigBen', ']] .. earthAsset.Earth.Identifier .. [[', 51.50079, -0.124279)
]],
Documentation = "Resets the Big Ben back to it's actual location",
GuiPath = "/Scale Objects",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(scaleModel)
openspace.action.registerAction(updatePositionAction)
openspace.action.registerAction(resetPositionAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(resetPositionAction)
openspace.action.removeAction(updatePositionAction)
openspace.removeSceneGraphNode(scaleModel)
end)
asset.export(scaleModel)
asset.export(updatePositionAction)
asset.export(resetPositionAction)

View File

@@ -0,0 +1,82 @@
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
local sunAsset = asset.require('scene/solarsystem/sun/sun')
local modelFolder = asset.syncedResource({
Name = "Scale Burj Khalifa",
Type = "UrlSynchronization",
Identifier = "scale_model_burj_khalifa",
Url = "https://wms.openspace.amnh.org/static/sync/url/scalemodels/Burj_Khalifa.osmodel",
Filename = "Burj_Khalifa.osmodel",
Override = false
})
local scaleModel = {
Identifier = "Scale_BurjKhalifa",
Parent = earthAsset.Earth.Identifier,
--Note: Lat/Lon/Scale values comes from alignment with Esri World Imagery 2D layer
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = earthAsset.Earth.Identifier,
Latitude = 25.196715,
Longitude = 55.273972,
Altitude = -3.0,
UseHeightmap = true
},
Rotation = {
Type = "GlobeRotation",
Globe = earthAsset.Earth.Identifier,
Latitude = 25.196715,
Longitude = 55.273972,
UseHeightmap = false
}
},
Renderable = {
Type = "RenderableModel",
GeometryFile = modelFolder .. "Burj_Khalifa.osmodel",
LightSources = { sunAsset.LightSource },
ModelScale = "Centimeter"
},
GUI = {
Name = "Burj Khalifa",
Path = "/Scale Objects"
}
}
local updatePositionAction = {
Identifier = "os.scale_models.drop_burj_khalifa",
Name = "Drop Burj Khalifa under camera",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera('Scale_BurjKhalifa')
]],
Documentation = "Updates the Burj Khalifa position based on the globe location of the camera",
GuiPath = "/Scale Objects",
IsLocal = false
}
local resetPositionAction = {
Identifier = "os.os.scale_models.reset_burj_khalifa",
Name = "Reset Burj Khalifa position",
Command = [[
openspace.globebrowsing.setNodePosition('Scale_BurjKhalifa', ']] .. earthAsset.Earth.Identifier .. [[', 25.196715, 55.273972)
]],
Documentation = "Resets the Burj Khalifa back to it's actual location",
GuiPath = "/Scale Objects",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(scaleModel)
openspace.action.registerAction(updatePositionAction)
openspace.action.registerAction(resetPositionAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(resetPositionAction)
openspace.action.removeAction(updatePositionAction)
openspace.removeSceneGraphNode(scaleModel)
end)
asset.export(scaleModel)
asset.export(updatePositionAction)
asset.export(resetPositionAction)

View File

@@ -2,30 +2,30 @@ local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
local sunAsset = asset.require('scene/solarsystem/sun/sun')
local modelFolder = asset.syncedResource({
Name = "Eiffel Tower Model",
Name = "Scale Eiffel Tower",
Type = "HttpSynchronization",
Identifier = "eiffel_tower_model",
Identifier = "scale_model_eiffel_tower",
Version = 1
})
local eiffelTower = {
Identifier = "eiffelTower",
local scaleModel = {
Identifier = "Scale_EiffelTower",
Parent = earthAsset.Earth.Identifier,
--Note: Lat/Lon/Scale values comes from alignment with Esri World Imagery 2D layer
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = earthAsset.Earth.Identifier,
Longitude = 2.29448,
Latitude = 48.85824,
Longitude = 2.29448,
Altitude = 0.0,
UseHeightmap = true
},
Rotation = {
Type = "GlobeRotation",
Globe = earthAsset.Earth.Identifier,
Longitude = 2.29448,
Latitude = 48.85824,
Longitude = 2.29448,
UseHeightmap = false
},
Scale = {
@@ -36,9 +36,9 @@ local eiffelTower = {
Renderable = {
Type = "RenderableModel",
GeometryFile = modelFolder .. "eiffeltower.osmodel",
ModelScale = "Centimeter",
RotationVector = { 0.0, 45.0, 0.0 },
LightSources = { sunAsset.LightSource }
LightSources = { sunAsset.LightSource },
ModelScale = "Centimeter"
},
GUI = {
Name = "Eiffel Tower",
@@ -47,18 +47,10 @@ local eiffelTower = {
}
local updatePositionAction = {
Identifier = "os.drop_eiffel_tower",
Name = "Drop Eiffel tower under camera",
Identifier = "os.scale_models.drop_eiffel_tower",
Name = "Drop Eiffel Tower under camera",
Command = [[
local lat, lon, alt = openspace.globebrowsing.getGeoPositionForCamera();
local camera = openspace.navigation.getNavigationState();
openspace.setParent('eiffelTower', camera.Anchor)
openspace.setPropertyValueSingle('Scene.eiffelTower.Translation.Globe', camera.Anchor);
openspace.setPropertyValueSingle('Scene.eiffelTower.Translation.Latitude', lat);
openspace.setPropertyValueSingle('Scene.eiffelTower.Translation.Longitude', lon);
openspace.setPropertyValueSingle('Scene.eiffelTower.Rotation.Globe', camera.Anchor);
openspace.setPropertyValueSingle('Scene.eiffelTower.Rotation.Latitude', lat);
openspace.setPropertyValueSingle('Scene.eiffelTower.Rotation.Longitude', lon);
openspace.globebrowsing.setNodePositionFromCamera('Scale_EiffelTower')
]],
Documentation = "Updates the Eiffel Tower position based on the globe location of the camera",
GuiPath = "/Scale Objects",
@@ -66,29 +58,18 @@ local updatePositionAction = {
}
local resetPositionAction = {
Identifier = "os.reset_eiffel_tower",
Name = "Reset Eiffel tower position",
Identifier = "os.os.scale_models.reset_eiffel_tower",
Name = "Reset Eiffel Tower position",
Command = [[
-- same position as above
local lat = 48.85824
local lon = 2.29448
local globe = ']] .. earthAsset.Earth.Identifier .. [['
openspace.setParent('eiffelTower', globe)
openspace.setPropertyValueSingle('Scene.eiffelTower.Translation.Globe', globe);
openspace.setPropertyValueSingle('Scene.eiffelTower.Translation.Latitude', lat);
openspace.setPropertyValueSingle('Scene.eiffelTower.Translation.Longitude', lon);
openspace.setPropertyValueSingle('Scene.eiffelTower.Rotation.Globe', globe);
openspace.setPropertyValueSingle('Scene.eiffelTower.Rotation.Latitude', lat);
openspace.setPropertyValueSingle('Scene.eiffelTower.Rotation.Longitude', lon);
openspace.globebrowsing.setNodePosition('Scale_EiffelTower', ']] .. earthAsset.Earth.Identifier .. [[', 48.85824, 2.29448)
]],
Documentation = "Updates the Eiffel Tower position based on the globe location of the camera",
Documentation = "Resets the Eiffel Tower back to it's actual location",
GuiPath = "/Scale Objects",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(eiffelTower)
openspace.addSceneGraphNode(scaleModel)
openspace.action.registerAction(updatePositionAction)
openspace.action.registerAction(resetPositionAction)
end)
@@ -96,7 +77,9 @@ end)
asset.onDeinitialize(function()
openspace.action.removeAction(resetPositionAction)
openspace.action.removeAction(updatePositionAction)
openspace.removeSceneGraphNode(eiffelTower)
openspace.removeSceneGraphNode(scaleModel)
end)
asset.export(eiffelTower)
asset.export(scaleModel)
asset.export(updatePositionAction)
asset.export(resetPositionAction)

View File

@@ -0,0 +1,84 @@
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
local sunAsset = asset.require('scene/solarsystem/sun/sun')
local modelFolder = asset.syncedResource({
Name = "Scale Empire State Building",
Type = "HttpSynchronization",
Identifier = "scale_model_empire_state",
Version = 1
})
local scaleModel = {
Identifier = "Scale_EmpireStateBuilding",
Parent = earthAsset.Earth.Identifier,
--Note: Lat/Lon/Scale values comes from alignment with Esri World Imagery 2D layer
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = earthAsset.Earth.Identifier,
Latitude = 40.748441,
Longitude = -73.985664,
Altitude = 0.0,
UseHeightmap = true
},
Rotation = {
Type = "GlobeRotation",
Globe = earthAsset.Earth.Identifier,
Latitude = 40.748441,
Longitude = -73.985664,
UseHeightmap = false
},
Scale = {
Type = "StaticScale",
Scale = 0.5
}
},
Renderable = {
Type = "RenderableModel",
GeometryFile = modelFolder .. "Empire_State_fbx.osmodel",
RotationVector = { 0.0, 60.0, 0.0 },
LightSources = { sunAsset.LightSource }
},
GUI = {
Name = "Empire State Building",
Path = "/Scale Objects"
}
}
local updatePositionAction = {
Identifier = "os.scale_models.drop_empire_state_building",
Name = "Drop Empire State Building under camera",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera('Scale_EmpireStateBuilding')
]],
Documentation = "Updates the Empire State Building position based on the globe location of the camera",
GuiPath = "/Scale Objects",
IsLocal = false
}
local resetPositionAction = {
Identifier = "os.os.scale_models.reset_empire_state_building",
Name = "Reset Empire State Building position",
Command = [[
openspace.globebrowsing.setNodePosition('Scale_EmpireStateBuilding', ']] .. earthAsset.Earth.Identifier .. [[', 40.748441, -73.985664)
]],
Documentation = "Resets the Empire State Building back to it's actual location",
GuiPath = "/Scale Objects",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(scaleModel)
openspace.action.registerAction(updatePositionAction)
openspace.action.registerAction(resetPositionAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(resetPositionAction)
openspace.action.removeAction(updatePositionAction)
openspace.removeSceneGraphNode(scaleModel)
end)
asset.export(scaleModel)
asset.export(updatePositionAction)
asset.export(resetPositionAction)

View File

@@ -0,0 +1,86 @@
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
local sunAsset = asset.require('scene/solarsystem/sun/sun')
local modelFolder = asset.syncedResource({
Name = "Scale Gateway Arch",
Type = "UrlSynchronization",
Identifier = "scale_model_gateway_arch",
Url = "https://wms.openspace.amnh.org/static/sync/url/scalemodels/GatewayArch_fbx.osmodel",
Filename = "GatewayArch_fbx.osmodel",
Override = false
})
local scaleModel = {
Identifier = "Scale_GatewayArch",
Parent = earthAsset.Earth.Identifier,
--Note: Lat/Lon/Scale values comes from alignment with Esri World Imagery 2D layer
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = earthAsset.Earth.Identifier,
Latitude = 38.624880,
Longitude = -90.184939,
Altitude = 0.0,
UseHeightmap = true
},
Rotation = {
Type = "GlobeRotation",
Globe = earthAsset.Earth.Identifier,
Latitude = 38.624880,
Longitude = -90.184939,
UseHeightmap = false
},
Scale = {
Type = "StaticScale",
Scale = 0.5
}
},
Renderable = {
Type = "RenderableModel",
GeometryFile = modelFolder .. "GatewayArch_fbx.osmodel",
RotationVector = { 0.0, 157, 0.0 },
LightSources = { sunAsset.LightSource }
},
GUI = {
Name = "Gateway Arch",
Path = "/Scale Objects"
}
}
local updatePositionAction = {
Identifier = "os.scale_models.drop_gateway_arch",
Name = "Drop Gateway Arch under camera",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera('Scale_GatewayArch')
]],
Documentation = "Updates the Gateway Arch position based on the globe location of the camera",
GuiPath = "/Scale Objects",
IsLocal = false
}
local resetPositionAction = {
Identifier = "os.os.scale_models.reset_gateway_arch",
Name = "Reset Gateway Arch position",
Command = [[
openspace.globebrowsing.setNodePosition('Scale_GatewayArch', ']] .. earthAsset.Earth.Identifier .. [[', 38.624880, -90.184939)
]],
Documentation = "Resets the Gateway Arch back to it's actual location",
GuiPath = "/Scale Objects",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(scaleModel)
openspace.action.registerAction(updatePositionAction)
openspace.action.registerAction(resetPositionAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(resetPositionAction)
openspace.action.removeAction(updatePositionAction)
openspace.removeSceneGraphNode(scaleModel)
end)
asset.export(scaleModel)
asset.export(updatePositionAction)
asset.export(resetPositionAction)

View File

@@ -0,0 +1,87 @@
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
local sunAsset = asset.require('scene/solarsystem/sun/sun')
local modelFolder = asset.syncedResource({
Name = "Scale Golden Gate Bridge",
Type = "UrlSynchronization",
Identifier = "scale_model_golden_gate_bridge",
Url = "https://wms.openspace.amnh.org/static/sync/url/scalemodels/golden_gate.osmodel",
Filename = "golden_gate.osmodel",
Override = false
})
local scaleModel = {
Identifier = "Scale_GoldenGateBridge",
Parent = earthAsset.Earth.Identifier,
--Note: Lat/Lon/Scale values comes from alignment with Esri World Imagery 2D layer
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = earthAsset.Earth.Identifier,
Latitude = 37.816116,
Longitude = -122.477890,
Altitude = 120.0,
UseHeightmap = true
},
Rotation = {
Type = "GlobeRotation",
Globe = earthAsset.Earth.Identifier,
Latitude = 37.816116,
Longitude = -122.477890,
UseHeightmap = false
},
Scale = {
Type = "StaticScale",
Scale = 0.2
}
},
Renderable = {
Type = "RenderableModel",
GeometryFile = modelFolder .. "golden_gate.osmodel",
ForceRenderInvisible = true,
RotationVector = { 0.0, 95.4, 0.0 },
LightSources = { sunAsset.LightSource }
},
GUI = {
Name = "Golden Gate Bridge",
Path = "/Scale Objects"
}
}
local updatePositionAction = {
Identifier = "os.scale_models.drop_golden_gate_bridge",
Name = "Drop Golden Gate Bridge under camera",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera('Scale_GoldenGateBridge')
]],
Documentation = "Updates the Golden Gate Bridge position based on the globe location of the camera",
GuiPath = "/Scale Objects",
IsLocal = false
}
local resetPositionAction = {
Identifier = "os.os.scale_models.reset_golden_gate_bridge",
Name = "Reset Golden Gate Bridge position",
Command = [[
openspace.globebrowsing.setNodePosition('Scale_GoldenGateBridge', ']] .. earthAsset.Earth.Identifier .. [[', 37.816116, -122.477890)
]],
Documentation = "Resets the Golden Gate Bridge back to it's actual location",
GuiPath = "/Scale Objects",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(scaleModel)
openspace.action.registerAction(updatePositionAction)
openspace.action.registerAction(resetPositionAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(resetPositionAction)
openspace.action.removeAction(updatePositionAction)
openspace.removeSceneGraphNode(scaleModel)
end)
asset.export(scaleModel)
asset.export(updatePositionAction)
asset.export(resetPositionAction)

View File

@@ -0,0 +1,79 @@
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
local sunAsset = asset.require('scene/solarsystem/sun/sun')
local modelFolder = asset.syncedResource({
Name = "Scale Kuala Lumpur Tower",
Type = "HttpSynchronization",
Identifier = "scale_model_kuala_lumpur_tower",
Version = 1
})
local scaleModel = {
Identifier = "Scale_KualaLumpurTower",
Parent = earthAsset.Earth.Identifier,
--Note: Lat/Lon/Scale values comes from alignment with Esri World Imagery 2D layer
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = earthAsset.Earth.Identifier,
Latitude = 3.152878,
Longitude = 101.703533,
Altitude = 0.0,
UseHeightmap = true
},
Rotation = {
Type = "GlobeRotation",
Globe = earthAsset.Earth.Identifier,
Latitude = 3.152878,
Longitude = 101.703533,
UseHeightmap = false
}
},
Renderable = {
Type = "RenderableModel",
GeometryFile = modelFolder .. "menara_kl_FBX.osmodel",
LightSources = { sunAsset.LightSource }
},
GUI = {
Name = "Kuala Lumpur Tower",
Path = "/Scale Objects"
}
}
local updatePositionAction = {
Identifier = "os.scale_models.drop_kuala_lumpur_tower",
Name = "Drop Kuala Lumpur Tower under camera",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera('Scale_KualaLumpurTower')
]],
Documentation = "Updates the Kuala Lumpur Tower position based on the globe location of the camera",
GuiPath = "/Scale Objects",
IsLocal = false
}
local resetPositionAction = {
Identifier = "os.os.scale_models.reset_kuala_lumpur_tower",
Name = "Reset Kuala Lumpur Tower position",
Command = [[
openspace.globebrowsing.setNodePosition('Scale_KualaLumpurTower', ']] .. earthAsset.Earth.Identifier .. [[', 3.152878, 101.703533)
]],
Documentation = "Resets the Kuala Lumpur Tower back to it's actual location",
GuiPath = "/Scale Objects",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(scaleModel)
openspace.action.registerAction(updatePositionAction)
openspace.action.registerAction(resetPositionAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(resetPositionAction)
openspace.action.removeAction(updatePositionAction)
openspace.removeSceneGraphNode(scaleModel)
end)
asset.export(scaleModel)
asset.export(updatePositionAction)
asset.export(resetPositionAction)

View File

@@ -0,0 +1,80 @@
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
local sunAsset = asset.require('scene/solarsystem/sun/sun')
local modelFolder = asset.syncedResource({
Name = "Scale Rose Bowl",
Type = "HttpSynchronization",
Identifier = "scale_model_rose_bowl",
Version = 1
})
local scaleModel = {
Identifier = "Scale_RoseBowl",
Parent = earthAsset.Earth.Identifier,
--Note: Lat/Lon/Scale values comes from alignment with Esri World Imagery 2D layer
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = earthAsset.Earth.Identifier,
Latitude = 34.161318,
Longitude = -118.167623,
Altitude = 0.0,
UseHeightmap = true
},
Rotation = {
Type = "GlobeRotation",
Globe = earthAsset.Earth.Identifier,
Latitude = 34.161318,
Longitude = -118.167623,
UseHeightmap = false
}
},
Renderable = {
Type = "RenderableModel",
GeometryFile = modelFolder .. "rose_bowl.gltf",
RotationVector = { 0.0, 98.68, 0.0 },
LightSources = { sunAsset.LightSource }
},
GUI = {
Name = "Rose Bowl",
Path = "/Scale Objects"
}
}
local updatePositionAction = {
Identifier = "os.scale_models.drop_rose_bowl",
Name = "Drop Rose Bowl under camera",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera('Scale_RoseBowl')
]],
Documentation = "Updates the Rose Bowl position based on the globe location of the camera",
GuiPath = "/Scale Objects",
IsLocal = false
}
local resetPositionAction = {
Identifier = "os.os.scale_models.reset_rose_bowl",
Name = "Reset Rose Bowl position",
Command = [[
openspace.globebrowsing.setNodePosition('Scale_RoseBowl', ']] .. earthAsset.Earth.Identifier .. [[', 34.161318, -118.167623)
]],
Documentation = "Resets the Rose Bowl back to it's actual location",
GuiPath = "/Scale Objects",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(scaleModel)
openspace.action.registerAction(updatePositionAction)
openspace.action.registerAction(resetPositionAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(resetPositionAction)
openspace.action.removeAction(updatePositionAction)
openspace.removeSceneGraphNode(scaleModel)
end)
asset.export(scaleModel)
asset.export(updatePositionAction)
asset.export(resetPositionAction)

View File

@@ -0,0 +1,80 @@
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
local sunAsset = asset.require('scene/solarsystem/sun/sun')
local modelFolder = asset.syncedResource({
Name = "Scale School Bus",
Type = "HttpSynchronization",
Identifier = "scale_model_school_bus",
Version = 1
})
local scaleModel = {
Identifier = "Scale_SchoolBus",
Parent = earthAsset.Earth.Identifier,
--Note: Lat/Lon/Scale values comes from alignment with Esri World Imagery 2D layer
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = earthAsset.Earth.Identifier,
Latitude = 40.780671,
Longitude = -73.971701,
Altitude = 0.78,
UseHeightmap = true
},
Rotation = {
Type = "GlobeRotation",
Globe = earthAsset.Earth.Identifier,
Latitude = 40.780671,
Longitude = -73.971701,
UseHeightmap = false
}
},
Renderable = {
Type = "RenderableModel",
GeometryFile = modelFolder .. "school_bus.gltf",
RotationVector = { 0.0, 90.0, 0.0 },
LightSources = { sunAsset.LightSource }
},
GUI = {
Name = "School bus",
Path = "/Scale Objects"
}
}
local updatePositionAction = {
Identifier = "os.scale_models.drop_school_bus",
Name = "Drop school bus under camera",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera('Scale_SchoolBus')
]],
Documentation = "Updates the school bus position based on the globe location of the camera",
GuiPath = "/Scale Objects",
IsLocal = false
}
local resetPositionAction = {
Identifier = "os.os.scale_models.reset_school_bus",
Name = "Reset School bus position",
Command = [[
openspace.globebrowsing.setNodePosition('Scale_SchoolBus', ']] .. earthAsset.Earth.Identifier .. [[', 40.780671, -73.971701)
]],
Documentation = "Resets the school bus back to it's actual location",
GuiPath = "/Scale Objects",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(scaleModel)
openspace.action.registerAction(updatePositionAction)
openspace.action.registerAction(resetPositionAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(resetPositionAction)
openspace.action.removeAction(updatePositionAction)
openspace.removeSceneGraphNode(scaleModel)
end)
asset.export(scaleModel)
asset.export(updatePositionAction)
asset.export(resetPositionAction)

View File

@@ -0,0 +1,80 @@
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
local sunAsset = asset.require('scene/solarsystem/sun/sun')
local modelFolder = asset.syncedResource({
Name = "Scale Model Scientist",
Type = "HttpSynchronization",
Identifier = "scale_model_scientist",
Version = 1
})
local scaleModel = {
Identifier = "Scale_Scientist",
Parent = earthAsset.Earth.Identifier,
--Note: Lat/Lon/Scale values comes from alignment with Esri World Imagery 2D layer
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = earthAsset.Earth.Identifier,
Latitude = 34.201639,
Longitude = -118.171319,
Altitude = 0.78,
UseHeightmap = true
},
Rotation = {
Type = "GlobeRotation",
Globe = earthAsset.Earth.Identifier,
Latitude = 34.201639,
Longitude = -118.171319,
UseHeightmap = false
}
},
Renderable = {
Type = "RenderableModel",
GeometryFile = modelFolder .. "scientist.gltf",
RotationVector = { 0.0, 90.0, 0.0 },
LightSources = { sunAsset.LightSource }
},
GUI = {
Name = "Scientist",
Path = "/Scale Objects"
}
}
local updatePositionAction = {
Identifier = "os.scale_models.drop_scientist",
Name = "Drop Scientist under camera",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera('Scale_Scientist')
]],
Documentation = "Updates the Scientist position based on the globe location of the camera",
GuiPath = "/Scale Objects",
IsLocal = false
}
local resetPositionAction = {
Identifier = "os.os.scale_models.reset_scientist",
Name = "Reset Scientist position",
Command = [[
openspace.globebrowsing.setNodePosition('Scale_Scientist', ']] .. earthAsset.Earth.Identifier .. [[', 34.201639, -118.171319)
]],
Documentation = "Resets the Scientist back to it's actual location",
GuiPath = "/Scale Objects",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(scaleModel)
openspace.action.registerAction(updatePositionAction)
openspace.action.registerAction(resetPositionAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(resetPositionAction)
openspace.action.removeAction(updatePositionAction)
openspace.removeSceneGraphNode(scaleModel)
end)
asset.export(scaleModel)
asset.export(updatePositionAction)
asset.export(resetPositionAction)

View File

@@ -0,0 +1,80 @@
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
local sunAsset = asset.require('scene/solarsystem/sun/sun')
local modelFolder = asset.syncedResource({
Name = "Scale Model Statue of Liberty",
Type = "HttpSynchronization",
Identifier = "scale_model_statue_of_liberty",
Version = 1
})
local scaleModel = {
Identifier = "Scale_StatueOfLiberty",
Parent = earthAsset.Earth.Identifier,
--Note: Lat/Lon/Scale values comes from alignment with Esri World Imagery 2D layer
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = earthAsset.Earth.Identifier,
Latitude = 40.689206,
Longitude = -74.044487,
Altitude = -3,
UseHeightmap = true
},
Rotation = {
Type = "GlobeRotation",
Globe = earthAsset.Earth.Identifier,
Latitude = 40.689206,
Longitude = -74.044487,
UseHeightmap = false
}
},
Renderable = {
Type = "RenderableModel",
GeometryFile = modelFolder .. "STATUE_OF_LIBERTY.osmodel",
RotationVector = { 0.0, 235.0, 0.0 },
LightSources = { sunAsset.LightSource }
},
GUI = {
Name = "Statue of Liberty",
Path = "/Scale Objects"
}
}
local updatePositionAction = {
Identifier = "os.scale_models.drop_statue_of_libery",
Name = "Drop Statue of Liberty under camera",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera('Scale_StatueOfLiberty')
]],
Documentation = "Updates the Statue of Liberty position based on the globe location of the camera",
GuiPath = "/Scale Objects",
IsLocal = false
}
local resetPositionAction = {
Identifier = "os.scale_models.reset_statue_of_libery",
Name = "Reset Statue of Liberty position",
Command = [[
openspace.globebrowsing.setNodePosition('Scale_StatueOfLiberty', ']] .. earthAsset.Earth.Identifier .. [[', 40.689206, -74.044487)
]],
Documentation = "Resets the Statue of Liberty back to it's actual location",
GuiPath = "/Scale Objects",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(scaleModel)
openspace.action.registerAction(updatePositionAction)
openspace.action.registerAction(resetPositionAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(resetPositionAction)
openspace.action.removeAction(updatePositionAction)
openspace.removeSceneGraphNode(scaleModel)
end)
asset.export(scaleModel)
asset.export(updatePositionAction)
asset.export(resetPositionAction)

View File

@@ -0,0 +1,49 @@
local earth = asset.require('scene/solarsystem/planets/earth/earth')
local earthIdentifier = earth.Earth.Identifier
local sun = asset.require("scene/solarsystem/sun/sun")
local data = asset.syncedResource({
Name = "GeoJSON Example Africa",
Type = "UrlSynchronization",
Identifier = "geojson_example_polygon_extruded_africa",
Url = "http://liu-se.cdn.openspaceproject.com/files/examples/geojson/polygon_extruded_africa.geojson"
})
local Example_Polygon = {
Identifier = "Earth-Polygon-withLights",
File = data .. "polygon_extruded_africa.geojson",
HeightOffset = 20000.0,
DefaultProperties = {
Color = { 0.0, 1.0, 0.0 },
FillColor = { 0.5, 0.6, 0.5 },
LineWidth = 0.5,
FillOpacity = 1.0,
PerformShading = true
},
LightSources = {
sun.LightSource
},
Name = "Extruded and Shaded Polygon (lit by Sun)"
}
asset.onInitialize(function()
openspace.globebrowsing.addGeoJson(earthIdentifier, Example_Polygon)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteGeoJson(earthIdentifier, Example_Polygon)
end)
asset.export(Example_Polygon)
asset.meta = {
Name = "GeoJson Example - Extruded and Shaded Polygon",
Version = "1.0",
Description = [[GeoJson example asset demonstrating how to apply shading from light
sources on polygons]],
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -0,0 +1,39 @@
local earth = asset.require('scene/solarsystem/planets/earth/earth')
local earthIdentifier = earth.Earth.Identifier
local data = asset.syncedResource({
Name = "GeoJSON Example Lines",
Type = "UrlSynchronization",
Identifier = "geojson_example_lines",
Url = "http://liu-se.cdn.openspaceproject.com/files/examples/geojson/lines.geojson"
})
local Example_Lines = {
Identifier = "Lines-Example",
File = data .. "lines.geojson",
HeightOffset = 20000.0,
DefaultProperties = {
LineWidth = 2.0
},
Name = "Example Lines"
}
asset.onInitialize(function()
openspace.globebrowsing.addGeoJson(earthIdentifier, Example_Lines)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteGeoJson(earthIdentifier, Example_Lines)
end)
asset.export(Example_Lines)
asset.meta = {
Name = "GeoJson Example - Lines",
Version = "1.0",
Description = [[GeoJson example asset with lines]],
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -0,0 +1,58 @@
local earth = asset.require('scene/solarsystem/planets/earth/earth')
local earthIdentifier = earth.Earth.Identifier
local data = asset.syncedResource({
Name = "GeoJSON Example Polygon Multiple",
Type = "UrlSynchronization",
Identifier = "geojson_example_polygon_multiple",
Url = {
"http://liu-se.cdn.openspaceproject.com/files/examples/geojson/polygon_multiple.geojson",
"http://liu-se.cdn.openspaceproject.com/files/examples/geojson/polygon_different_heights.geojson"
}
})
local Example_Polygon = {
Identifier = "Earth-Polygon",
File = data .. "polygon_multiple.geojson",
HeightOffset = 20000.0,
DefaultProperties = {
Color = { 1.0, 0.0, 0.0 },
LineWidth = 2.0
},
Name = "Polygon (Multiple)"
}
local Example_Polygon_Diff_Heights = {
Identifier = "Earth-Polygon-Different-Heights",
File = data .. "polygon_different_heights.geojson",
HeightOffset = 20000.0,
DefaultProperties = {
Color = { 0.5, 0.0, 1.0 },
LineWidth = 2.0
},
Name = "Polygon (Different heights)",
Description = "A GeoJSON test layer with some different heights"
}
asset.onInitialize(function()
openspace.globebrowsing.addGeoJson(earthIdentifier, Example_Polygon)
openspace.globebrowsing.addGeoJson(earthIdentifier, Example_Polygon_Diff_Heights)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteGeoJson(earthIdentifier, Example_Polygon)
openspace.globebrowsing.deleteGeoJson(earthIdentifier, Example_Polygon_Diff_Heights)
end)
asset.export(Example_Polygon)
asset.export(Example_Polygon_Diff_Heights)
asset.meta = {
Name = "GeoJson Example - Multiple Polygons",
Version = "1.0",
Description = [[GeoJson example asset with multiple polygons]],
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -0,0 +1,40 @@
local earth = asset.require('scene/solarsystem/planets/earth/earth')
local earthIdentifier = earth.Earth.Identifier
local data = asset.syncedResource({
Name = "GeoJSON Example Outfacing",
Type = "UrlSynchronization",
Identifier = "geojson_example_points",
Url = "http://liu-se.cdn.openspaceproject.com/files/examples/geojson/points.geojson"
})
local Example_Points = {
Identifier = "Points-Example",
File = data .. "points.geojson",
HeightOffset = 20000.0,
DefaultProperties = {
PointSize = 10.0
},
Name = "Example Points"
}
asset.onInitialize(function()
openspace.globebrowsing.addGeoJson(earthIdentifier, Example_Points)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteGeoJson(earthIdentifier, Example_Points)
end)
asset.export(Example_Points)
asset.meta = {
Name = "GeoJson Example - Points",
Version = "1.0",
Description = [[GeoJson example asset with points that are facing the camera
(default)]],
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -0,0 +1,41 @@
local earth = asset.require('scene/solarsystem/planets/earth/earth')
local earthIdentifier = earth.Earth.Identifier
local data = asset.syncedResource({
Name = "GeoJSON Example Outfacing",
Type = "UrlSynchronization",
Identifier = "geojson_example_points",
Url = "http://liu-se.cdn.openspaceproject.com/files/examples/geojson/points.geojson"
})
local Example_Points = {
Identifier = "Points-Example-outfacing",
File = data .. "points.geojson",
HeightOffset = 20000.0,
DefaultProperties = {
PointSize = 10.0
},
PointRenderMode = "Globe Normal",
Name = "Example Points (align to globe normal)"
}
asset.onInitialize(function()
openspace.globebrowsing.addGeoJson(earthIdentifier, Example_Points)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteGeoJson(earthIdentifier, Example_Points)
end)
asset.export(Example_Points)
asset.meta = {
Name = "GeoJson Example - Outfacing Points",
Version = "1.0",
Description = [[GeoJson example asset with point that are aligned to "stick out" of
the globe, i.e. face out of the planet]],
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -0,0 +1,39 @@
local earth = asset.require('scene/solarsystem/planets/earth/earth')
local earthIdentifier = earth.Earth.Identifier
local data = asset.syncedResource({
Name = "GeoJSON Example Polygon with holes",
Type = "UrlSynchronization",
Identifier = "geojson_example_polygon_with_holes",
Url = "http://liu-se.cdn.openspaceproject.com/files/examples/geojson/polygon_with_holes.geojson"
})
local Example_Holes = {
Identifier = "PolygonWithHoles",
File = data .. "polygon_with_holes.geojson",
HeightOffset = 2000.0,
DefaultProperties = {
Color = { 0.0, 1.0, 1.0 }
},
Name = "Example Polygon (holes)"
}
asset.onInitialize(function()
openspace.globebrowsing.addGeoJson(earthIdentifier, Example_Holes)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteGeoJson(earthIdentifier, Example_Holes)
end)
asset.export(Example_Holes)
asset.meta = {
Name = "GeoJson Example - Polygon with holes",
Version = "1.0",
Description = [[GeoJson example asset with polygon that has holes in it]],
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -0,0 +1,41 @@
local mars = asset.require('scene/solarsystem/planets/mars/mars')
local marsIdentifier = mars.Mars.Identifier
local data = asset.syncedResource({
Name = "GeoJSON Example Path Perseverance",
Type = "UrlSynchronization",
Identifier = "geojson_example_path_perseverance",
Url = "http://liu-se.cdn.openspaceproject.com/files/examples/geojson/path_perseverance.geojson"
})
local Example_RoverPath = {
Identifier = "Mars-Perseverance-Path",
File = data .. "path_perseverance.geojson",
HeightOffset = 10.0,
IgnoreHeights = true, -- Ignores height values from the file itself
DefaultProperties = {
LineWidth = 2.0
},
Name = "Perseverance Rover Path"
}
asset.onInitialize(function()
openspace.globebrowsing.addGeoJson(marsIdentifier, Example_RoverPath)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteGeoJson(marsIdentifier, Example_RoverPath)
end)
asset.export(Example_RoverPath)
asset.meta = {
Name = "GeoJson Example - Rover path",
Version = "1.0",
Description = [[GeoJson example asset that renderes a snapshot of the path of the
Perseverance Rover on Mars. Data from: https://mars.nasa.gov/mars2020/mission/where-is-the-rover/]],
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -0,0 +1,42 @@
local earth = asset.require('scene/solarsystem/planets/earth/earth')
local earthIdentifier = earth.Earth.Identifier
local data = asset.syncedResource({
Name = "GeoJSON Example Toronto Neighborhoods",
Type = "UrlSynchronization",
Identifier = "geojson_example_toronto_neighborhoods",
Url = "http://liu-se.cdn.openspaceproject.com/files/examples/geojson/toronto_neighborhoods.geojson"
})
local Example_Toronto = {
Identifier = "Toronto-Neighborhoods",
File = data .. "toronto_neighborhoods.geojson",
HeightOffset = 1000.0,
DefaultProperties = {
Color = { 0.0, 1.0, 0.0 },
FillColor = { 0.2, 0.33, 0.2 },
LineWidth = 2.0,
},
Name = "Toronto Neighbourhoods"
}
asset.onInitialize(function()
openspace.globebrowsing.addGeoJson(earthIdentifier, Example_Toronto)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteGeoJson(earthIdentifier, Example_Toronto)
end)
asset.export(Example_Toronto)
asset.meta = {
Name = "GeoJson Example - Toronto neighborhoods",
Version = "1.0",
Description = [[GeoJson example asset that shows the neighborhoods of the city Toronto,
Canada, as polygons. Data source: https://handsondataviz.org/geojsonio.html]],
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -4,7 +4,7 @@ local data = asset.syncedResource({
Name = "Example Globe Video",
Type = "UrlSynchronization",
Identifier = "example_globe_video",
Url = "http://liu-se.cdn.openspaceproject.com/files/examples/test-video.mp4"
Url = "http://liu-se.cdn.openspaceproject.com/files/examples/video/test-video.mp4"
})
local layer = {

View File

@@ -4,7 +4,7 @@ local data = asset.syncedResource({
Name = "Example Globe Video",
Type = "UrlSynchronization",
Identifier = "example_globe_video",
Url = "http://liu-se.cdn.openspaceproject.com/files/examples/test-video.mp4"
Url = "http://liu-se.cdn.openspaceproject.com/files/examples/video/test-video.mp4"
})

View File

@@ -2,14 +2,14 @@ local data = asset.syncedResource({
Name = "Example Globe Video",
Type = "UrlSynchronization",
Identifier = "example_globe_video",
Url = "http://liu-se.cdn.openspaceproject.com/files/examples/test-video.mp4"
Url = "http://liu-se.cdn.openspaceproject.com/files/examples/video/chlorophyll_model_2048.mp4"
})
local spec = {
Type = "ScreenSpaceVideo",
Identifier = "ScreenSpaceVideoExample",
Name = "Screen Space Video Example",
Video = data .. "/test-video.mp4"
Video = data .. "/chlorophyll_model_2048.mp4"
};
asset.onInitialize(function()

View File

@@ -2,7 +2,7 @@ local data = asset.syncedResource({
Name = "Example Globe Video",
Type = "UrlSynchronization",
Identifier = "example_globe_video",
Url = "http://liu-se.cdn.openspaceproject.com/files/examples/test-video.mp4"
Url = "http://liu-se.cdn.openspaceproject.com/files/examples/video/test-video.mp4"
})
local sphere = {

View File

@@ -4,7 +4,7 @@ local data = asset.syncedResource({
Name = "Example Globe Video",
Type = "UrlSynchronization",
Identifier = "example_globe_video",
Url = "http://liu-se.cdn.openspaceproject.com/files/examples/test-video.mp4"
Url = "http://liu-se.cdn.openspaceproject.com/files/examples/video/test-video.mp4"
})
local spec = {

View File

@@ -0,0 +1,109 @@
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
local gridPosition = {
Identifier = "AltAzGridPosition",
Parent = earthAsset.Earth.Identifier,
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = earthAsset.Earth.Identifier,
Latitude = 0.0,
Longitude = 0.0,
Altitude = 0.0,
UseHeightmap = false,
UseCamera = true
},
Rotation = {
Type = "GlobeRotation",
Globe = earthAsset.Earth.Identifier,
Latitude = 0.0,
Longitude = 0.0,
UseHeightmap = false,
UseCamera = true
}
},
GUI = {
Name = "Altitude/Azimuth Grid Position",
Path = "/Other/Grids",
Hidden = true
}
}
local grid = {
Identifier = "AltAzGrid",
Parent = gridPosition.Identifier,
Transform = {
Scale = {
Type = "StaticScale",
Scale = 50000
},
Rotation = {
Type = "StaticRotation",
Rotation = { -math.pi / 2.0, 0.0, 0.0 }
},
},
Renderable = {
Type = "RenderableSphericalGrid",
Enabled = asset.enabled,
Opacity = 0.8,
Color = { 0.4, 0.8, 0.4 },
LineWidth = 2.0,
RenderBinMode = "PostDeferredTransparent"
},
GUI = {
Name = "Altitude/Azimuth Grid",
Path = "/Other/Grids"
}
}
local showAction = {
Identifier = "os.nightsky.show_altaz",
Name = "Show Alt/Az grid",
Command = [[
local lat, lon, alt = openspace.globebrowsing.getGeoPositionForCamera();
local camera = openspace.navigation.getNavigationState();
openspace.setParent('AltAzGridPosition', camera.Anchor)
openspace.setPropertyValueSingle('Scene.AltAzGridPosition.Translation.Globe', camera.Anchor);
openspace.setPropertyValueSingle('Scene.AltAzGridPosition.Translation.Latitude', lat);
openspace.setPropertyValueSingle('Scene.AltAzGridPosition.Translation.Longitude', lon);
openspace.setPropertyValueSingle('Scene.AltAzGridPosition.Rotation.Globe', camera.Anchor);
openspace.setPropertyValueSingle('Scene.AltAzGridPosition.Rotation.Latitude', lat);
openspace.setPropertyValueSingle('Scene.AltAzGridPosition.Rotation.Longitude', lon);
openspace.setPropertyValueSingle('Scene.AltAzGrid.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.AltAzGrid.Renderable.Fade', 0.0);
openspace.setPropertyValueSingle('Scene.AltAzGrid.Renderable.Fade', 1.0, 1.0);
]],
Documentation = "Shows a local Altitude/Azimuth grid centered around your position",
GuiPath = "/Night Sky/Lines and Grids",
IsLocal = false
}
local hideAction = {
Identifier = "os.nightsky.hide_altaz",
Name = "Hide Alt/Az grid",
Command = [[
openspace.setPropertyValueSingle('Scene.AltAzGrid.Renderable.Fade', 0, 1);
]],
Documentation = "Hides the Alt/Az grid",
GuiPath = "/Night Sky/Lines and Grids",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(gridPosition)
openspace.addSceneGraphNode(grid)
openspace.action.registerAction(hideAction)
openspace.action.registerAction(showAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(showAction)
openspace.action.removeAction(hideAction)
openspace.removeSceneGraphNode(grid)
openspace.removeSceneGraphNode(gridPosition)
end)
asset.export(showAction)
asset.export(hideAction)
asset.export(grid)

View File

@@ -0,0 +1,139 @@
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
local textures = asset.syncedResource({
Name = "Cardinal Direction Textures",
Type = "UrlSynchronization",
Identifier = "cardinal_direction_textures",
Url = {
"https://wms.openspace.amnh.org/static/sync/url/directions/sphere.png",
"https://wms.openspace.amnh.org/static/sync/url/directions/sphere2.png",
"https://wms.openspace.amnh.org/static/sync/url/directions/sphere3.png",
"https://wms.openspace.amnh.org/static/sync/url/directions/sphere4.png",
"https://wms.openspace.amnh.org/static/sync/url/directions/sphere5.png"
},
Override = false
})
local Position = {
Identifier = "CardinalDirectionsPosition",
Parent = earthAsset.Earth.Identifier,
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = earthAsset.Earth.Identifier,
Latitude = 0.0,
Longitude = 0.0,
Altitude = 0.0,
UseCamera = true
},
Rotation = {
Type = "GlobeRotation",
Globe = earthAsset.Earth.Identifier,
Latitude = 0.0,
Longitude = 0.0,
UseCamera = true,
Angle = 270.0
}
},
GUI = {
Name = "Cardinal Directions Position",
Path = "/Other/Night Sky",
Hidden = true
}
}
local sphere = {
Identifier = "CardinalDirectionSphere",
Parent = Position.Identifier,
Transform = {
Rotation = {
Type = "StaticRotation",
Rotation = { -math.pi/2, 0.0, 0.0 }
},
},
Renderable = {
Type = "RenderableSphere",
Enabled = asset.enabled,
Size = 50000,
Segments = 80,
Opacity = 0.9,
Texture = textures .. 'sphere.png',
Orientation = "Inside",
MirrorTexture = true,
RenderBinMode = "PostDeferredTransparent"
},
GUI = {
Name = "Cardinal Directions",
Path = "/Other/Night Sky"
}
}
local showCommand = [[
local lat, lon, alt = openspace.globebrowsing.getGeoPositionForCamera();
local camera = openspace.navigation.getNavigationState();
openspace.setParent('CardinalDirectionsPosition', camera.Anchor)
openspace.setPropertyValueSingle('Scene.CardinalDirectionsPosition.Translation.Globe', camera.Anchor);
openspace.setPropertyValueSingle('Scene.CardinalDirectionsPosition.Translation.Latitude', lat);
openspace.setPropertyValueSingle('Scene.CardinalDirectionsPosition.Translation.Longitude', lon);
openspace.setPropertyValueSingle('Scene.CardinalDirectionsPosition.Rotation.Globe', camera.Anchor);
openspace.setPropertyValueSingle('Scene.CardinalDirectionsPosition.Rotation.Latitude', lat);
openspace.setPropertyValueSingle('Scene.CardinalDirectionsPosition.Rotation.Longitude', lon);
openspace.setPropertyValueSingle('Scene.CardinalDirectionSphere.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.CardinalDirectionSphere.Renderable.Fade', 0.0);
openspace.setPropertyValueSingle('Scene.CardinalDirectionSphere.Renderable.Fade', 1.0, 1.0);
]]
local showBandAction = {
Identifier = "os.nightsky.show_nesw_band",
Name = "Show cardinal directions (with ticks)",
Command = "openspace.setPropertyValueSingle('Scene.CardinalDirectionSphere.Renderable.Texture','"
.. textures:gsub("\\","/") .. "sphere5.png')"
.. showCommand,
Documentation = "Shows the cardinal direction sphere with letters and circle with tick marks",
GuiPath = "/Night Sky/Directions",
IsLocal = false
}
local showLettersAction = {
Identifier = "os.nightsky.show_nesw_letters",
Name = "Show cardinal directions (letters only)",
Command = "openspace.setPropertyValueSingle('Scene.CardinalDirectionSphere.Renderable.Texture','"
.. textures:gsub("\\","/") .. "sphere.png')"
.. showCommand,
Documentation = "Shows the cardinal direction sphere with letters only",
GuiPath = "/Night Sky/Directions",
IsLocal = false
}
local hideAction = {
Identifier = "os.nightsky.hide_nesw",
Name = "Hide cardinal directions",
Command = [[
openspace.setPropertyValueSingle('Scene.CardinalDirectionSphere.Renderable.Fade', 0.0, 1.0);
]],
Documentation = "Hides the cardinal directions",
GuiPath = "/Night Sky/Directions",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Position)
openspace.addSceneGraphNode(sphere)
openspace.action.registerAction(hideAction)
openspace.action.registerAction(showBandAction)
openspace.action.registerAction(showLettersAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(showLettersAction)
openspace.action.removeAction(showBandAction)
openspace.action.removeAction(hideAction)
openspace.removeSceneGraphNode(sphere)
openspace.removeSceneGraphNode(Position)
end)
asset.export(showBandAction)
asset.export(showLettersAction)
asset.export(hideAction)
asset.export(sphere)
asset.export(Position)

View File

@@ -0,0 +1,140 @@
local transforms = asset.require("scene/solarsystem/sun/transforms")
local textures = asset.syncedResource({
Name = "Ecliptic Band Textures",
Type = "HttpSynchronization",
Identifier = "ecliptic_band_textures",
Version = 1
})
local eclipticRotationMatrix = {
-0.05487554, 0.4941095, -0.8676661,
-0.9938214, -0.1109906, -0.0003515167,
-0.09647644, 0.8622859, 0.4971472
}
local line = {
Identifier = "EclipticLine",
Parent = transforms.SolarSystemBarycenter.Name,
Transform = {
Scale = {
Type = "StaticScale",
Scale = 4.28601E17;
},
Rotation = {
Type = "StaticRotation",
Rotation = eclipticRotationMatrix
}
},
Renderable = {
Type = "RenderableRadialGrid",
Opacity = 0.8,
Color = { 1.0, 1.0, 1.0 },
LineWidth = 3.0,
GridSegments = { 1, 1 },
Radii = { 0.5, 0.5 },
Enabled = asset.enabled
},
GUI = {
Name = "Ecliptic Line",
Path = "/Other/Lines"
}
}
local band = {
Identifier = "EclipticBand",
Parent = transforms.SolarSystemBarycenter.Name,
Transform = {
Rotation = {
Type = "StaticRotation",
Rotation = eclipticRotationMatrix
}
},
Renderable = {
Type = "RenderableSphere",
Texture = textures .. "band.png",
Size = 4.28601E17,
Segments = 50,
DisableFadeInOut = true,
Orientation = "Inside",
Opacity = 0.05,
Enabled = asset.enabled
},
GUI = {
Name = "Ecliptic Band",
Path = "/Other/Lines"
}
}
local showLineAction = {
Identifier = "os.nightsky.show_ecliptic_line",
Name = "Show ecliptic line",
Command = [[
openspace.setPropertyValueSingle('Scene.EclipticLine.Renderable.Fade', 0.0);
openspace.setPropertyValueSingle('Scene.EclipticLine.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.EclipticLine.Renderable.Fade', 1.0, 1.0);
]],
Documentation = "Shows the ecliptic line",
GuiPath = "/Night Sky/Lines and Grids",
IsLocal = false
}
local hideLineAction = {
Identifier = "os.nightsky.hide_ecliptic_line",
Name = "Hide ecliptic line",
Command = [[
openspace.setPropertyValueSingle('Scene.EclipticLine.Renderable.Fade', 0.0, 1.0);
]],
Documentation = "Hides the ecliptic line",
GuiPath = "/Night Sky/Lines and Grids",
IsLocal = false
}
local showBandAction = {
Identifier = "os.nightsky.show_ecliptic_band",
Name = "Show ecliptic band",
Command = [[
openspace.setPropertyValueSingle('Scene.EclipticBand.Renderable.Fade', 0.0);
openspace.setPropertyValueSingle('Scene.EclipticBand.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.EclipticBand.Renderable.Fade', 1.0, 1.0);
]],
Documentation = "Shows the ecliptic band",
GuiPath = "/Night Sky/Lines and Grids",
IsLocal = false
}
local hideBandAction = {
Identifier = "os.nightsky.hide_ecliptic_band",
Name = "Hide ecliptic band",
Command = [[
openspace.setPropertyValueSingle('Scene.EclipticBand.Renderable.Fade', 0.0, 1.0);
]],
Documentation = "Hides the ecliptic band",
GuiPath = "/Night Sky/Lines and Grids",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(line)
openspace.addSceneGraphNode(band)
openspace.action.registerAction(showLineAction)
openspace.action.registerAction(hideLineAction)
openspace.action.registerAction(showBandAction)
openspace.action.registerAction(hideBandAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(hideLineAction)
openspace.action.removeAction(showLineAction)
openspace.action.removeAction(hideBandAction)
openspace.action.removeAction(showBandAction)
openspace.removeSceneGraphNode(band)
openspace.removeSceneGraphNode(line)
end)
asset.export(band)
asset.export(line)
asset.export(showLineAction)
asset.export(hideLineAction)
asset.export(showBandAction)
asset.export(hideBandAction)

View File

@@ -0,0 +1,75 @@
local transforms = asset.require("scene/solarsystem/sun/transforms")
local equatorialRotationMatrix = {
-0.05487554, 0.4941095, -0.8676661,
-0.8734371, -0.4448296, -0.1980764,
-0.483835, 0.7469823, 0.4559838
}
local line = {
Identifier = "EquatorialLine",
Parent = transforms.SolarSystemBarycenter.Name,
Transform = {
Scale = {
Type = "StaticScale",
Scale = 4.28601E17;
},
Rotation = {
Type = "StaticRotation",
Rotation = equatorialRotationMatrix
}
},
Renderable = {
Type = "RenderableRadialGrid",
Opacity = 0.8,
Color = { 1.0, 1.0, 1.0 },
LineWidth = 3.0,
GridSegments = { 1, 1 },
Radii = { 0.5, 0.5 },
Enabled = asset.enabled
},
GUI = {
Name = "Equatorial Line",
Path = "/Other/Lines"
}
}
local showLineAction = {
Identifier = "os.nightsky.show_equatorial_line",
Name = "Show equatorial line",
Command = [[
openspace.setPropertyValueSingle('Scene.EquatorialLine.Renderable.Fade', 0.0);
openspace.setPropertyValueSingle('Scene.EquatorialLine.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.EquatorialLine.Renderable.Fade', 1.0, 1.0);
]],
Documentation = "Shows the equatorial line",
GuiPath = "/Night Sky/Lines and Grids",
IsLocal = false
}
local hideLineAction = {
Identifier = "os.nightsky.hide_equatorial_line",
Name = "Hide equatorial line",
Command = [[
openspace.setPropertyValueSingle('Scene.EquatorialLine.Renderable.Fade', 0.0, 1.0);
]],
Documentation = "Hides the equatorial line",
GuiPath = "/Night Sky/Lines and Grids",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(line)
openspace.action.registerAction(showLineAction)
openspace.action.registerAction(hideLineAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(hideLineAction)
openspace.action.removeAction(showLineAction)
openspace.removeSceneGraphNode(line)
end)
asset.export(line)
asset.export(showLineAction)
asset.export(hideLineAction)

View File

@@ -0,0 +1,65 @@
local transforms = asset.require("scene/solarsystem/sun/transforms")
local band = {
Identifier = "GalacticBand",
Parent = transforms.SolarSystemBarycenter.Name,
Transform = {
Scale = {
Type = "StaticScale",
Scale = 9.46377307652E18;
}
},
Renderable = {
Type = "RenderableRadialGrid",
Opacity = 0.8,
Color = { 1.0, 1.0, 1.0 },
LineWidth = 3.0,
GridSegments = { 1, 1 },
Radii = { 0.5, 0.5 },
Enabled = asset.enabled
},
GUI = {
Name = "Galactic Band",
Path = "/Other/Lines"
}
}
local showAction = {
Identifier = "os.nightsky.show_galactic_band",
Name = "Show galactic band",
Command = [[
openspace.setPropertyValueSingle('Scene.GalacticBand.Renderable.Fade', 0.0);
openspace.setPropertyValueSingle('Scene.GalacticBand.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.GalacticBand.Renderable.Fade', 1.0, 1.0);
]],
Documentation = "Shows the galactic band",
GuiPath = "/Night Sky/Lines and Grids",
IsLocal = false
}
local hideAction = {
Identifier = "os.nightsky.hide_galactic_band",
Name = "Hide galactic band",
Command = [[
openspace.setPropertyValueSingle('Scene.GalacticBand.Renderable.Fade', 0.0, 1.0);
]],
Documentation = "Hides the galactic band",
GuiPath = "/Night Sky/Lines and Grids",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(band)
openspace.action.registerAction(showAction)
openspace.action.registerAction(hideAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(hideAction)
openspace.action.removeAction(showAction)
openspace.removeSceneGraphNode(band)
end)
asset.export(band)
asset.export(showAction)
asset.export(hideAction)

View File

@@ -0,0 +1,186 @@
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
local textures = asset.syncedResource({
Name = "Ground Panorama Textures",
Type = "UrlSynchronization",
Identifier = "ground_panorama_textures",
Url = {
"https://wms.openspace.amnh.org/static/sync/url/panos/0.png",
"https://wms.openspace.amnh.org/static/sync/url/panos/1.png",
"https://wms.openspace.amnh.org/static/sync/url/panos/2.png",
"https://wms.openspace.amnh.org/static/sync/url/panos/3.png",
"https://wms.openspace.amnh.org/static/sync/url/panos/4.png",
"https://wms.openspace.amnh.org/static/sync/url/panos/5.png",
"https://wms.openspace.amnh.org/static/sync/url/panos/6.png",
},
Override = false
})
local position = {
Identifier = "GroundPanoPosition",
Parent = earthAsset.Earth.Identifier,
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = earthAsset.Earth.Identifier,
Latitude = 34.201639,
Longitude = -118.171319,
Altitude = 10.0,
UseCamera = true,
UseCameraAltitude = true
},
Rotation = {
Type = "GlobeRotation",
Globe = earthAsset.Earth.Identifier,
Latitude = 34.201639,
Longitude = -118.171319,
UseHeightmap = false,
Angle = 270.0
}
},
GUI = {
Name = "Ground Pano Position",
Path = "/Other/Night Sky",
Hidden = true
}
}
local sphere = {
Identifier = "GroundPanoSphere",
Parent = position.Identifier,
Transform = {
Rotation = {
Type = "StaticRotation",
Rotation = { -math.pi/2, 0.0, 0.0 }
},
},
Renderable = {
Type = "RenderableSphere",
Size = 8.5,
Segments = 40,
Opacity = 1.0,
Enabled = asset.enabled,
Texture = textures .. "3.png",
Orientation = "Inside",
MirrorTexture = true,
FadeOutThreshold = 1.00,
Background = true,
RenderBinMode = "Overlay"
},
GUI = {
Name = "Ground Panorama",
Path = "/Other/Night Sky"
}
}
local showCommand = [[
local lat, lon, alt = openspace.globebrowsing.getGeoPositionForCamera();
local camera = openspace.navigation.getNavigationState();
openspace.setParent('GroundPanoPosition', camera.Anchor)
openspace.setPropertyValueSingle('Scene.GroundPanoPosition.Translation.Globe', camera.Anchor);
openspace.setPropertyValueSingle('Scene.GroundPanoPosition.Translation.Latitude', lat);
openspace.setPropertyValueSingle('Scene.GroundPanoPosition.Translation.Longitude', lon);
openspace.setPropertyValueSingle('Scene.GroundPanoPosition.Translation.Altitude', alt);
openspace.setPropertyValueSingle('Scene.GroundPanoPosition.Rotation.Globe', camera.Anchor);
openspace.setPropertyValueSingle('Scene.GroundPanoPosition.Rotation.Latitude', lat);
openspace.setPropertyValueSingle('Scene.GroundPanoPosition.Rotation.Longitude', lon);
openspace.setPropertyValueSingle('Scene.GroundPanoSphere.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.GroundPanoSphere.Renderable.Fade', 0.0);
openspace.setPropertyValueSingle('Scene.GroundPanoSphere.Renderable.Fade', 1.0, 1.0);
]]
local setTextureCommand = function(scene)
local command = 'openspace.setPropertyValueSingle("Scene.GroundPanoSphere.Renderable.Texture", "'
command = command .. textures
if (scene == "forest") then
command = command .. "1"
elseif (scene == 'city') then
command = command .. "2"
elseif (scene == 'backyard') then
command = command .. "3"
elseif (scene == 'desert') then
command = command .. "4"
else
openspace.printDebug("unknown scene")
end
command = command .. '.png")'
command = command:gsub( "\\", "\\\\")
return command
end
local showForestAction = {
Identifier = "os.nightsky.show_forest_pano",
Name = "Show forest panorama",
Command = setTextureCommand("forest") .. showCommand,
Documentation = "Shows the panorama sphere with a forest scene",
GuiPath = "/Night Sky/Panoramas",
IsLocal = false
}
local showCityAction = {
Identifier = "os.nightsky.show_city_pano",
Name = "Show city panorama",
Command = setTextureCommand("city") .. showCommand,
Documentation = "Shows the panorama sphere with a city scene",
GuiPath = "/Night Sky/Panoramas",
IsLocal = false
}
local showBackyardAction = {
Identifier = "os.nightsky.show_backyard_pano",
Name = "Show backyard panorama",
Command = setTextureCommand("backyard") .. showCommand,
Documentation = "Shows the panorama sphere with a backyard scene",
GuiPath = "/Night Sky/Panoramas",
IsLocal = false
}
local showDesertAction = {
Identifier = "os.nightsky.show_desert_pano",
Name = "Show desert panorama",
Command = setTextureCommand("desert") .. showCommand,
Documentation = "Shows the panorama sphere with a desert scene",
GuiPath = "/Night Sky/Panoramas",
IsLocal = false
}
local hideAction = {
Identifier = "os.nightsky.hide_ground_pano",
Name = "Hide ground panorama",
Command = [[
-- same position as above
openspace.setPropertyValueSingle('Scene.GroundPanoSphere.Renderable.Fade', 0.0, 0.5);
]],
Documentation = "Hides the ground panorama",
GuiPath = "/Night Sky/Panoramas",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(position)
openspace.addSceneGraphNode(sphere)
openspace.action.registerAction(hideAction)
openspace.action.registerAction(showForestAction)
openspace.action.registerAction(showCityAction)
openspace.action.registerAction(showBackyardAction)
openspace.action.registerAction(showDesertAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(showForestAction)
openspace.action.removeAction(showCityAction)
openspace.action.removeAction(showBackyardAction)
openspace.action.removeAction(showDesertAction)
openspace.action.removeAction(hideAction)
openspace.removeSceneGraphNode(sphere)
openspace.removeSceneGraphNode(position)
end)
asset.export(position)
asset.export(sphere)
asset.export(hideAction)
asset.export(showForestAction)
asset.export(showCityAction)
asset.export(showBackyardAction)
asset.export(showDesertAction)

View File

@@ -0,0 +1,248 @@
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
local textures = asset.syncedResource({
Name = "Light Pollution Textures",
Type = "HttpSynchronization",
Identifier = "light_pollution_textures",
Version = 1
})
local sphere = {
Identifier = "LightPollutionSphere",
Parent = earthAsset.Earth.Identifier,
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = earthAsset.Earth.Identifier,
Latitude = 34.201639,
Longitude = -118.171319,
Altitude = 10.0,
UseCamera = true,
UseCameraAltitude = true
},
Rotation = {
Type = "GlobeRotation",
Globe = earthAsset.Earth.Identifier,
Latitude = 34.201639,
Longitude = -118.171319,
UseHeightmap = false,
Angle = 270.0
}
},
Renderable = {
Type = "RenderableSphere",
Size = 8.5,
Segments = 40,
Opacity = 0.0,
Enabled = asset.enabled,
Texture = textures .. "fullsphere.png",
Orientation = "Inside",
MirrorTexture = true,
FadeOutThreshold = 1.00,
Background = true,
RenderBinMode = "PostDeferredTransparent",
Enabled = asset.enabled
},
GUI = {
Name = "Light Pollution Sphere",
Path = "/Other/Night Sky",
Hidden = false
}
}
local pollution_1 = {
Identifier = "os.nightsky.set_light_pollution_level_1",
Name = "Set light pollution level 1",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera("LightPollutionSphere", true)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Fade', 1.0);
openspace.setPropertyValueSingle("Scene.MilkyWay.Renderable.Fade", 0.9, 0.3)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Opacity', 0.01, 0.5);
openspace.setPropertyValueSingle('Scene.Stars.Renderable.ParametersOwner.MagnitudeExponent', 6.1, 0.3);
]],
Documentation = "Adds a light pollution sphere and lowers the level of the stars by 0.1",
GuiPath = "/Night Sky/Light Pollution",
IsLocal = false
}
local pollution_2 = {
Identifier = "os.nightsky.set_light_pollution_level_2",
Name = "Set light pollution level 2",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera("LightPollutionSphere", true)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Fade', 1.0);
openspace.setPropertyValueSingle("Scene.MilkyWay.Renderable.Fade", 0.8, 0.3)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Opacity', 0.02, 0.5);
openspace.setPropertyValueSingle('Scene.Stars.Renderable.ParametersOwner.MagnitudeExponent', 6.0, 0.3);
]],
Documentation = "Adds a light pollution sphere and lowers the level of the stars by 0.2",
GuiPath = "/Night Sky/Light Pollution",
IsLocal = false
}
local pollution_3 = {
Identifier = "os.nightsky.set_light_pollution_level_3",
Name = "Set light pollution level 3",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera("LightPollutionSphere", true)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Fade', 1.0);
openspace.setPropertyValueSingle("Scene.MilkyWay.Renderable.Fade", 0.7, 0.3)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Opacity', 0.03, 0.5);
openspace.setPropertyValueSingle('Scene.Stars.Renderable.ParametersOwner.MagnitudeExponent', 5.9, 0.3);
]],
Documentation = "Adds a light pollution sphere and lowers the level of the stars by 0.3",
GuiPath = "/Night Sky/Light Pollution",
IsLocal = false
}
local pollution_4 = {
Identifier = "os.nightsky.set_light_pollution_level_4",
Name = "Set light pollution level 4",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera("LightPollutionSphere", true)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Fade', 1.0);
openspace.setPropertyValueSingle("Scene.MilkyWay.Renderable.Fade", 0.6, 0.3)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Opacity', 0.04, 0.5);
openspace.setPropertyValueSingle('Scene.Stars.Renderable.ParametersOwner.MagnitudeExponent', 5.8, 0.3);
]],
Documentation = "Adds a light pollution sphere and lowers the level of the stars by 0.4",
GuiPath = "/Night Sky/Light Pollution",
IsLocal = false
}
local pollution_5 = {
Identifier = "os.nightsky.set_light_pollution_level_5",
Name = "Set light pollution level 5",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera("LightPollutionSphere", true)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Fade', 1.0);
openspace.setPropertyValueSingle("Scene.MilkyWay.Renderable.Fade", 0.5, 0.3)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Opacity', 0.05, 0.5);
openspace.setPropertyValueSingle('Scene.Stars.Renderable.ParametersOwner.MagnitudeExponent', 5.8, 0.4);
]],
Documentation = "Adds a light pollution sphere and lowers the level of the stars by 0.5",
GuiPath = "/Night Sky/Light Pollution",
IsLocal = false
}
local pollution_6 = {
Identifier = "os.nightsky.set_light_pollution_level_6",
Name = "Set light pollution level 6",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera("LightPollutionSphere", true)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Fade', 1.0);
openspace.setPropertyValueSingle("Scene.MilkyWay.Renderable.Fade", 0.4, 0.3)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Opacity', 0.06, 0.5);
openspace.setPropertyValueSingle('Scene.Stars.Renderable.ParametersOwner.MagnitudeExponent', 5.7, 0.4);
]],
Documentation = "Adds a light pollution sphere and lowers the level of the stars by 0.6",
GuiPath = "/Night Sky/Light Pollution",
IsLocal = false
}
local pollution_7 = {
Identifier = "os.nightsky.set_light_pollution_level_7",
Name = "Set light pollution level 7",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera("LightPollutionSphere", true)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Fade', 1.0);
openspace.setPropertyValueSingle("Scene.MilkyWay.Renderable.Fade", 0.3, 0.3)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Opacity', 0.07, 0.5);
openspace.setPropertyValueSingle('Scene.Stars.Renderable.ParametersOwner.MagnitudeExponent', 5.6, 0.4);
]],
Documentation = "Adds a light pollution sphere and lowers the level of the stars by 0.7",
GuiPath = "/Night Sky/Light Pollution",
IsLocal = false
}
local pollution_8 = {
Identifier = "os.nightsky.set_light_pollution_level_8",
Name = "Set light pollution level 8",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera("LightPollutionSphere", true)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Fade', 1.0);
openspace.setPropertyValueSingle("Scene.MilkyWay.Renderable.Fade", 0.2, 0.3)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Opacity', 0.08, 0.5);
openspace.setPropertyValueSingle('Scene.Stars.Renderable.ParametersOwner.MagnitudeExponent', 5.5, 0.4);
]],
Documentation = "Adds a light pollution sphere and lowers the level of the stars by 0.8",
GuiPath = "/Night Sky/Light Pollution",
IsLocal = false
}
local pollution_9 = {
Identifier = "os.nightsky.set_light_pollution_level_9",
Name = "Set light pollution level 9",
Command = [[
openspace.globebrowsing.setNodePositionFromCamera("LightPollutionSphere", true)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Enabled', true)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Fade', 1.0)
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Opacity', 0.09, 0.5)
openspace.setPropertyValueSingle("Scene.MilkyWay.Renderable.Fade", 0.1, 0.3)
openspace.setPropertyValueSingle('Scene.Stars.Renderable.ParametersOwner.MagnitudeExponent', 5.4, 0.4)
]],
Documentation = "Adds a light pollution sphere and lowers the level of the stars by 0.9",
GuiPath = "/Night Sky/Light Pollution",
IsLocal = false
}
local hideAction = {
Identifier = "os.nightsky.undo_light_pollution",
Name = "Undo light pollution",
Command = [[
openspace.setPropertyValueSingle('Scene.LightPollutionSphere.Renderable.Fade', 0.0, 0.3)
openspace.setPropertyValueSingle('Scene.Stars.Renderable.ParametersOwner.MagnitudeExponent', 6.2, 0.3)
openspace.setPropertyValueSingle("Scene.MilkyWay.Renderable.Fade", 1.0, 0.3)
]],
Documentation = "Hides the light pollution sphere and resets the stars",
GuiPath = "/Night Sky/Light Pollution",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(sphere)
openspace.action.registerAction(hideAction)
openspace.action.registerAction(pollution_1)
openspace.action.registerAction(pollution_2)
openspace.action.registerAction(pollution_3)
openspace.action.registerAction(pollution_4)
openspace.action.registerAction(pollution_5)
openspace.action.registerAction(pollution_6)
openspace.action.registerAction(pollution_7)
openspace.action.registerAction(pollution_8)
openspace.action.registerAction(pollution_9)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(pollution_9)
openspace.action.removeAction(pollution_8)
openspace.action.removeAction(pollution_7)
openspace.action.removeAction(pollution_6)
openspace.action.removeAction(pollution_5)
openspace.action.removeAction(pollution_4)
openspace.action.removeAction(pollution_3)
openspace.action.removeAction(pollution_2)
openspace.action.removeAction(pollution_1)
openspace.action.removeAction(hideAction)
openspace.removeSceneGraphNode(sphere)
end)
asset.export(sphere)
asset.export(hideAction)
asset.export(pollution_1)
asset.export(pollution_2)
asset.export(pollution_3)
asset.export(pollution_4)
asset.export(pollution_5)
asset.export(pollution_6)
asset.export(pollution_7)
asset.export(pollution_8)
asset.export(pollution_9)

View File

@@ -0,0 +1,105 @@
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
local position = {
Identifier = "MeridianPosition",
Parent = earthAsset.Earth.Identifier,
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = earthAsset.Earth.Identifier,
Latitude = 0.0,
Longitude = 0.0,
Altitude = 0.0,
UseCamera = true
},
Rotation = {
Type = "GlobeRotation",
Globe = earthAsset.Earth.Identifier,
Latitude = 0.0,
Longitude = 0.0,
UseCamera = true
}
},
GUI = {
Name = "Local Meridian Position",
Path = "/Other/Lines",
Hidden = true
}
}
local plane = {
Identifier = "Meridian",
Parent = position.Identifier,
Transform = {
Scale = {
Type = "StaticScale",
Scale = 1000000
},
},
Renderable = {
Type = "RenderableRadialGrid",
Opacity = 0.8,
Color = { 1.0, 1.0, 1.0 },
LineWidth = 3.0,
GridSegments = { 1, 1 },
Radii = { 0.5, 0.5 },
Enabled = asset.enabled,
RenderBinMode = "PostDeferredTransparent"
},
GUI = {
Name = "Local Meridian",
Path = "/Other/Lines"
}
}
local showAction = {
Identifier = "os.nightsky.show_meridian",
Name = "Show local meridian",
Command = [[
local lat, lon, alt = openspace.globebrowsing.getGeoPositionForCamera();
local camera = openspace.navigation.getNavigationState();
openspace.setParent('MeridianPosition', camera.Anchor)
openspace.setPropertyValueSingle('Scene.MeridianPosition.Translation.Globe', camera.Anchor);
openspace.setPropertyValueSingle('Scene.MeridianPosition.Translation.Latitude', lat);
openspace.setPropertyValueSingle('Scene.MeridianPosition.Translation.Longitude', lon);
openspace.setPropertyValueSingle('Scene.MeridianPosition.Rotation.Globe', camera.Anchor);
openspace.setPropertyValueSingle('Scene.MeridianPosition.Rotation.Latitude', lat);
openspace.setPropertyValueSingle('Scene.MeridianPosition.Rotation.Longitude', lon);
openspace.setPropertyValueSingle('Scene.Meridian.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.Meridian.Renderable.Fade', 0.0);
openspace.setPropertyValueSingle('Scene.Meridian.Renderable.Fade', 1.0, 1.0);
]],
Documentation = "Shows a line for the local meridian",
GuiPath = "/Night Sky/Lines and Grids",
IsLocal = false
}
local hideAction = {
Identifier = "os.nightsky.hide_meridian",
Name = "Hide local meridian",
Command = [[
openspace.setPropertyValueSingle('Scene.Meridian.Renderable.Fade', 0.0, 1.0);
]],
Documentation = "Hides the line for the local meridian",
GuiPath = "/Night Sky/Lines and Grids",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(position)
openspace.addSceneGraphNode(plane)
openspace.action.registerAction(hideAction)
openspace.action.registerAction(showAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(showAction)
openspace.action.removeAction(hideAction)
openspace.removeSceneGraphNode(plane)
openspace.removeSceneGraphNode(position)
end)
asset.export(position)
asset.export(plane)
asset.export(hideAction)
asset.export(showAction)

View File

@@ -0,0 +1,12 @@
asset.require("./altaz", false)
asset.require("./cardinal_directions", false)
asset.require("./ecliptic_band", false)
asset.require("./equatorial_band", false)
asset.require("./galactic_band", false)
asset.require("./ground_panoramas", false)
asset.require("./meredian", false)
asset.require("./light_pollution", false)
asset.require("./zenith", false)
asset.require("./planets", false)
asset.require("actions/nightsky/camera", false)
asset.require("actions/nightsky/daytime", false)

View File

@@ -0,0 +1,173 @@
local mercury = asset.require('scene/solarsystem/planets/mercury/transforms')
local venus = asset.require('scene/solarsystem/planets/venus/transforms')
local mars = asset.require('scene/solarsystem/planets/mars/transforms')
local jupiter = asset.require('scene/solarsystem/planets/jupiter/transforms')
local saturn = asset.require('scene/solarsystem/planets/saturn/transforms')
local textures = asset.syncedResource({
Name = "Night Sky Planet Textures",
Type = "HttpSynchronization",
Identifier = "night_sky_planet_textures",
Version = 1
})
local Mercury = {
Identifier = "NightSkyMercury",
Parent = mercury.MercuryBarycenter.Identifier,
Renderable = {
Type = "RenderablePlaneImageLocal",
Billboard = true,
Enabled = asset.enabled,
Size = 2439700 * 500,
Texture = textures .. "glare.png",
MultiplyColor = { 0.608, 0.604, 0.455 },
DimInAtmosphere = true,
RenderBinMode = "PostDeferredTransparent"
},
Tag = { "nightsky_billboard"},
GUI = {
Name = "Night Sky Mercury",
Path = "/Other/Night Sky/Planets"
}
}
local Venus = {
Identifier = "NightSkyVenus",
Parent = venus.VenusBarycenter.Identifier,
Renderable = {
Type = "RenderablePlaneImageLocal",
Enabled = asset.enabled,
Billboard = true,
Size = 6051900 * 500,
Texture = textures .. "glare.png",
MultiplyColor = { 0.608, 0.604, 0.455 },
DimInAtmosphere = true,
RenderBinMode = "PostDeferredTransparent"
},
Tag = { "nightsky_billboard"},
GUI = {
Name = "Night Sky Venus",
Path = "/Other/Night Sky/Planets"
}
}
local Mars = {
Identifier = "NightSkyMars",
Parent = mars.MarsBarycenter.Identifier,
Renderable = {
Type = "RenderablePlaneImageLocal",
Enabled = asset.enabled,
Billboard = true,
Size = 3396190 * 1000,
Texture = textures .. "glare.png",
MultiplyColor = { 0.756, 0.267, 0.054 },
DimInAtmosphere = true,
RenderBinMode = "PostDeferredTransparent"
},
Tag = { "nightsky_billboard"},
GUI = {
Name = "Night Sky Mars",
Path = "/Other/Night Sky/Planets"
}
}
local Jupiter = {
Identifier = "NightSkyJupiter",
Parent = jupiter.JupiterBarycenter.Identifier,
Renderable = {
Type = "RenderablePlaneImageLocal",
Enabled = asset.enabled,
Billboard = true,
Size = 71492000 * 400,
Texture = textures .. "glare.png",
MultiplyColor = { 0.608, 0.604, 0.455 },
DimInAtmosphere = true,
RenderBinMode = "PostDeferredTransparent"
},
Tag = { "nightsky_billboard"},
GUI = {
Name = "Night Sky Jupiter",
Path = "/Other/Night Sky/Planets"
}
}
local Saturn = {
Identifier = "NightSkySaturn",
Parent = saturn.SaturnBarycenter.Identifier,
Renderable = {
Type = "RenderablePlaneImageLocal",
Enabled = asset.enabled,
Billboard = true,
Size = 60268000 * 500,
Texture = textures .. "glare.png",
MultiplyColor = { 0.608, 0.604, 0.455 },
DimInAtmosphere = true,
RenderBinMode = "PostDeferredTransparent"
},
Tag = { "nightsky_billboard"},
GUI = {
Name = "Night Sky Saturn",
Path = "/Other/Night Sky/Planets"
}
}
local showAction = {
Identifier = "os.nightsky.show_night_sky_planets",
Name = "Show night sky planets",
Command = [[
openspace.setPropertyValueSingle('Scene.NightSkyMercury.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.NightSkyVenus.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.NightSkyMars.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.NightSkyJupiter.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.NightSkySaturn.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.NightSkyMercury.Renderable.Fade', 0.0);
openspace.setPropertyValueSingle('Scene.NightSkyVenus.Renderable.Fade', 0.0);
openspace.setPropertyValueSingle('Scene.NightSkyMars.Renderable.Fade', 0.0);
openspace.setPropertyValueSingle('Scene.NightSkyJupiter.Renderable.Fade', 0.0);
openspace.setPropertyValueSingle('Scene.NightSkySaturn.Renderable.Fade', 0.0);
openspace.setPropertyValueSingle('Scene.NightSkyMercury.Renderable.Fade', 1.0, 0.25);
openspace.setPropertyValueSingle('Scene.NightSkyVenus.Renderable.Fade', 1.0, 0.25);
openspace.setPropertyValueSingle('Scene.NightSkyMars.Renderable.Fade', 1.0, 0.25);
openspace.setPropertyValueSingle('Scene.NightSkyJupiter.Renderable.Fade', 1.0, 0.25);
openspace.setPropertyValueSingle('Scene.NightSkySaturn.Renderable.Fade', 1.0, 0.25);
]],
Documentation = "Show night sky versions of the planets",
GuiPath = "/Night Sky/Planets",
IsLocal = false
}
local hideAction = {
Identifier = "os.nightsky.hide_night_sky_planets",
Name = "Hide night sky planets",
Command = [[
openspace.setPropertyValueSingle('Scene.NightSkyMercury.Renderable.Fade', 0.0, 1.0);
openspace.setPropertyValueSingle('Scene.NightSkyVenus.Renderable.Fade', 0.0, 1.0);
openspace.setPropertyValueSingle('Scene.NightSkyMars.Renderable.Fade', 0.0, 1.0);
openspace.setPropertyValueSingle('Scene.NightSkyJupiter.Renderable.Fade', 0.0, 1.0);
openspace.setPropertyValueSingle('Scene.NightSkySaturn.Renderable.Fade', 0.0, 1.0);
]],
Documentation = "Hides night sky versions of the planets",
GuiPath = "/Night Sky/Planets",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Mercury)
openspace.addSceneGraphNode(Venus)
openspace.addSceneGraphNode(Mars)
openspace.addSceneGraphNode(Jupiter)
openspace.addSceneGraphNode(Saturn)
openspace.action.registerAction(showAction)
openspace.action.registerAction(hideAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(hideAction)
openspace.action.removeAction(showAction)
openspace.removeSceneGraphNode(Saturn)
openspace.removeSceneGraphNode(Jupiter)
openspace.removeSceneGraphNode(Mars)
openspace.removeSceneGraphNode(Venus)
openspace.removeSceneGraphNode(Mercury)
end)

View File

@@ -0,0 +1,112 @@
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
local textures = asset.syncedResource({
Name = "Zenith Textures",
Type = "HttpSynchronization",
Identifier = "zenith_textures",
Version = 1
})
local position = {
Identifier = "ZenithPosition",
Parent = earthAsset.Earth.Identifier,
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = earthAsset.Earth.Identifier,
Latitude = 0.0,
Longitude = 0.0,
Altitude = 100000000.0,
UseCamera = true
},
Rotation = {
Type = "GlobeRotation",
Globe = earthAsset.Earth.Identifier,
Latitude = 0.0,
Longitude = 0.0,
UseHeightmap = false,
UseCamera = true
}
},
GUI = {
Name = "Zenith Position",
Path = "/Other/Points",
Hidden = true
}
}
local plane = {
Identifier = "ZenithDot",
Parent = position.Identifier,
Transform = {
Rotation = {
Type = "StaticRotation",
Rotation = { -math.pi, 0.0, 0.0 }
},
},
Renderable = {
Type = "RenderablePlaneImageLocal",
Enabled = asset.enabled,
Size = 1000000,
Origin = "Center",
Billboard = true,
Texture = textures .. "point3A.png",
BlendMode = "Additive"
},
GUI = {
Name = "Zenith",
Path = "/Other/Points"
}
}
local showAction = {
Identifier = "os.nightsky.show_zenith",
Name = "Show local zenith",
Command = [[
local lat, lon, alt = openspace.globebrowsing.getGeoPositionForCamera();
local camera = openspace.navigation.getNavigationState();
openspace.setParent('ZenithPosition', camera.Anchor)
openspace.setPropertyValueSingle('Scene.ZenithPosition.Translation.Globe', camera.Anchor);
openspace.setPropertyValueSingle('Scene.ZenithPosition.Translation.Latitude', lat);
openspace.setPropertyValueSingle('Scene.ZenithPosition.Translation.Longitude', lon);
openspace.setPropertyValueSingle('Scene.ZenithPosition.Rotation.Globe', camera.Anchor);
openspace.setPropertyValueSingle('Scene.ZenithPosition.Rotation.Latitude', lat);
openspace.setPropertyValueSingle('Scene.ZenithPosition.Rotation.Longitude', lon);
openspace.setPropertyValueSingle('Scene.ZenithDot.Renderable.Enabled', true);
openspace.setPropertyValueSingle('Scene.ZenithDot.Renderable.Fade', 0.0);
openspace.setPropertyValueSingle('Scene.ZenithDot.Renderable.Fade', 1.0, 1.0);
]],
Documentation = "Shows a dot for the local zenith",
GuiPath = "/Night Sky/Lines and Grids",
IsLocal = false
}
local hideAction = {
Identifier = "os.nightsky.hide_zenith",
Name = "Hide local zenith",
Command = [[
openspace.setPropertyValueSingle('Scene.ZenithDot.Renderable.Fade', 0.0, 1.0);
]],
Documentation = "Hides the dot for the local zenith",
GuiPath = "/Night Sky/Lines and Grids",
IsLocal = false
}
asset.onInitialize(function()
openspace.addSceneGraphNode(position)
openspace.addSceneGraphNode(plane)
openspace.action.registerAction(hideAction)
openspace.action.registerAction(showAction)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(showAction)
openspace.action.removeAction(hideAction)
openspace.removeSceneGraphNode(plane)
openspace.removeSceneGraphNode(position)
end)
asset.export(position)
asset.export(plane)
asset.export(hideAction)
asset.export(showAction)

View File

@@ -55,8 +55,9 @@ local constellations = {
NamesFile = speck .. "constellations.dat",
Colors = { { 0.6, 0.4, 0.4 }, { 0.8, 0.0, 0.0 }, { 0.0, 0.3, 0.8 } },
Unit = "pc",
-- Selection = zodiacs
DimInAtmosphere = true
},
Tag = {"daytime_hidden"},
GUI = {
Name = "Constellations",
Path = "/Milky Way/Constellations",

View File

@@ -18,7 +18,7 @@ local sphere = {
Type = "RenderableSphere",
Size = 9.2E21,
Segments = 40,
Opacity = 0.35,
Opacity = 0.25,
Texture = sphereTextures .. "DarkUniverse_mellinger_4k.jpg",
Orientation = "Inside",
MirrorTexture = true,
@@ -26,6 +26,7 @@ local sphere = {
Background = true,
DimInAtmosphere = true,
},
Tag = {"daytime_hidden"},
GUI = {
Name = "Milky Way Sphere",
Path = "/Milky Way",

View File

@@ -50,6 +50,7 @@ local stars = {
},
DimInAtmosphere = true,
},
Tag = {"daytime_hidden"},
GUI = {
Name = "Stars",
Path = "/Milky Way/Stars",

View File

@@ -75,9 +75,10 @@ local createConstellations = function (baseIdentifier, guiPath, constellationfil
LazyLoading = true,
Texture = images .. imageName,
BlendMode = "Additive",
Opacity = 0.1
Opacity = 0.1,
DimInAtmosphere = true
},
Tag = { "ImageConstellation", group },
Tag = { "ImageConstellation", group, "daytime_hidden" },
GUI = {
Name = name .. " Image",
Path = "/Milky Way/" .. guiPath,
@@ -148,7 +149,7 @@ local hide_zodiac_art = {
Command = [[
openspace.fadeOut("{zodiac}")
]],
Documentation = "fades down zodiac art work",
Documentation = "Fades down zodiac art work",
GuiPath = "/Constellations/Art",
IsLocal = false
}

View File

@@ -8,6 +8,7 @@ asset.require("./layers/colorlayers/aqua_modis_temporal", false)
asset.require("./layers/colorlayers/terra_modis_temporal", false)
asset.require("./layers/colorlayers/bmng_utah", false)
asset.require("./layers/colorlayers/bmng_sweden", false)
asset.require("./layers/colorlayers/bmng_newyork", false)
asset.require("./layers/colorlayers/amsr2_gcom_w1_sea_ice_concentration_temporal", false)
asset.require("./layers/colorlayers/modis_terra_chlorophyll_a_temporal", false)
asset.require("./layers/colorlayers/ghrsst_l4_mur_sea_surface_temperature_temporal", false)
@@ -31,6 +32,7 @@ asset.require("./layers/overlays/size_reference", false)
-- Watermasks
asset.require("./layers/watermasks/gebco_sweden", false)
asset.require("./layers/watermasks/gebco_utah", false)
asset.require("./layers/watermasks/gebco_newyork", false)
asset.require("./layers/watermasks/modis_water_mask", true)

View File

@@ -0,0 +1,31 @@
local globeIdentifier = asset.require("../../earth").Earth.Identifier
local layer = {
Identifier = "BMNG_NewYork",
Name = "BMNG [New York]",
Enabled = asset.enabled,
FilePath = asset.localResource("bmng_newyork.wms"),
Description = [[Web loaded full resolution map of Blue Marble Next Generation. This map
is hosted on the OpenSpace servers in New York]],
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Blue Marble Next Generation (New York)",
Version = "1.1",
Description = [[Web loaded full resolution map of Blue Marble Next Generation. This map
is hosted on the OpenSpace servers in New York]],
Author = "OpenSpace Team",
URL = "https://visibleearth.nasa.gov/collection/1484/blue-marble",
License = "NASA"
}

View File

@@ -0,0 +1,21 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://wms.openspace.amnh.org/Earth/Bmng/tile/${z}/${y}/${x}</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<SizeX>86400</SizeX>
<SizeY>43200</SizeY>
<TileLevel>8</TileLevel>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>EPSG:4326</Projection>
<BlockSizeX>240</BlockSizeX>
<BlockSizeY>240</BlockSizeY>
<BandsCount>3</BandsCount>
<MaxConnections>10</MaxConnections>
<Timeout>5</Timeout>
</GDAL_WMS>

View File

@@ -0,0 +1,29 @@
local globeIdentifier = asset.require("../../earth").Earth.Identifier
local layer = {
Name = "Gebco [New York]",
Identifier = "Gebco_NewYork",
Enabled = asset.enabled,
FilePath = asset.localResource("gebco_newyork.wms")
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globeIdentifier, "WaterMasks", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globeIdentifier, "WaterMasks", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Gebco WaterMask Layer (New York)",
Version = "1.0",
Description = "WaterMask layer for Earth globe",
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -0,0 +1,21 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://wms.openspace.amnh.org/Earth/Gebco/tile/${z}/${y}/${x}</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<SizeX>43200</SizeX>
<SizeY>21600</SizeY>
<TileLevel>6</TileLevel>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>EPSG:4326</Projection>
<BlockSizeX>360</BlockSizeX>
<BlockSizeY>360</BlockSizeY>
<BandsCount>1</BandsCount>
<MaxConnections>10</MaxConnections>
<Timeout>5</Timeout>
</GDAL_WMS>

View File

@@ -1,20 +1,27 @@
-- Color layers
asset.require("./layers/colorlayers/wac_utah", true)
asset.require("./layers/colorlayers/wac_sweden", false)
asset.require("./layers/colorlayers/wac_newyork", false)
asset.require("./layers/colorlayers/clemuvvis_utah", false)
asset.require("./layers/colorlayers/clemuvvis_sweden", false)
asset.require("./layers/colorlayers/clemuvvis_newyork", false)
asset.require("./layers/colorlayers/uvvishybrid_utah", false)
asset.require("./layers/colorlayers/uvvishybrid_sweden", false)
asset.require("./layers/colorlayers/uvvishybrid_newyork", false)
asset.require("./layers/colorlayers/kaguya_utah", false)
asset.require("./layers/colorlayers/kaguya_sweden", false)
asset.require("./layers/colorlayers/kaguya_newyork", false)
asset.require("./layers/colorlayers/lola_clr_shade_utah", false)
asset.require("./layers/colorlayers/lola_clr_shade_sweden", false)
asset.require("./layers/colorlayers/lola_clr_shade_newyork", false)
asset.require("./layers/colorlayers/lola_shade_utah", false)
asset.require("./layers/colorlayers/lola_shade_sweden", false)
asset.require("./layers/colorlayers/lola_shade_newyork", false)
-- Height layers
asset.require("./layers/heightlayers/loladem_utah", true)
asset.require("./layers/heightlayers/loladem_sweden", false)
asset.require("./layers/heightlayers/loladem_newyork", false)
asset.meta = {

View File

@@ -0,0 +1,42 @@
local globeIdentifier = asset.require("../../moon").Moon.Identifier
local layer = {
Identifier = "Apollo15Metric_NewYork",
Name = "Apollo 15 Metric Cam [New York]",
Enabled = asset.enabled,
FilePath = asset.localResource("apollo_15_metric_newyork.wms"),
Settings = {
Gamma = 1.0,
Multiplier = 1.0
},
Description = [[The Apollo 15 Metric (Mapping) Camera obtained high-quality metric photographs,
on black and white film, with high geometric precision of the lunar surface from lunar orbit
combined with time-correlated stellar photography for selenodetic/cartographic control.
A laser altimeter was operated with it. The Metric Camera also provided supporting
photographic data for the Scientific Instrument Module (SIM) Panoramic Camera and
other Command Service Module (CSM) photographic experiments. The Apollo 15 metric camera
took 3375 frames, some of which were taken over unlighted terrain in support
of the laser altimeter. (Description from NASA PDS)]]
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Kaguya [New York]",
Version = "1.1",
Description = [[Moon SELENE Kaguya TC Global Orthomosaic 474m v2 layer for Moon globe.
This map is hosted on the OpenSpace server in New York]],
Author = "USGS",
URL = "https://trek.nasa.gov/moon/TrekWS/rest/cat/metadata/fgdc/html?label=Apollo15_MetricCam_Mosaic_Global_4096ppd",
License = "NASA/PDS"
}

View File

@@ -0,0 +1,21 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>https://wms.openspace.amnh.org/Moon/Apollo15_MetricCam/tile/${z}/${y}/${x}</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<SizeX>655360</SizeX>
<SizeY>327680</SizeY>
<TileLevel>9</TileLevel>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>GEOGCS["GCS_Moon_2000",DATUM["Moon_2000",SPHEROID["Moon_2000_IAU_IAG",1737400,0]],PRIMEM["Reference_Meridian",0],UNIT["degree",0.0174532925199433]]</Projection>
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>1</BandsCount>
<MaxConnections>10</MaxConnections>
<Timeout>5</Timeout>
</GDAL_WMS>

View File

@@ -0,0 +1,38 @@
local globeIdentifier = asset.require("../../moon").Moon.Identifier
local layer = {
Identifier = "ClemUvvis_NewYork",
Name = "Clem Uvvis [New York]",
Enabled = asset.enabled,
FilePath = asset.localResource("clemuvvis_newyork.wms"),
Settings = {
Gamma = 1.14,
Multiplier = 1.4
},
Description = [[The Clementine Ultraviolet/Visible (UVVIS) Version 2 mosaic is a
grayscale data set representing the albedo (brightness of the lunar surface) as
measured at the 750 nanometer (nm) wavelength by the UVVIS camera (Lee, et al., 2009).
Resolution of this mosaic is 118 meters per pixel (m)]]
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Clem Uvvis [New York]",
Version = "1.1",
Description = [[Moon Clementine UVVIS Global Mosaic 118m v2 map of the Moon. This map
is hosted on the OpenSpace server in New York]],
Author = "USGS",
URL = "https://astrogeology.usgs.gov/search/map/Moon/Clementine/UVVIS/Lunar_Clementine_UVVIS_750nm_Global_Mosaic_118m_v2",
License = "NASA/PDS"
}

View File

@@ -0,0 +1,20 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://wms.openspace.amnh.org/Moon/Clem_Uvvis/tile/${z}/${y}/${x}</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<SizeX>92160</SizeX>
<SizeY>46080</SizeY>
<TileLevel>7</TileLevel>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>GEOGCS["GCS_Moon_2000",DATUM["D_Moon_2000",SPHEROID["Moon_2000_IAU_IAG",1737400.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]</Projection>
<BlockSizeX>360</BlockSizeX>
<BlockSizeY>360</BlockSizeY>
<BandsCount>1</BandsCount>
<MaxConnections>10</MaxConnections>
</GDAL_WMS>

View File

@@ -0,0 +1,38 @@
local globeIdentifier = asset.require("../../moon").Moon.Identifier
local layer = {
Identifier = "Kaguya_NewYork",
Name = "Kaguya [New York]",
Enabled = asset.enabled,
FilePath = asset.localResource("kaguya_newyork.vrt"),
Settings = {
Gamma = 1.0,
Multiplier = 1.23
},
Description = [[This near-global mosaic was generated using data from the SELenological
and Engineering Explorer (SELENE) "Kaguya" Terrain Camera (TC) instrument. TC source
data originated as map-projected tiles at ~10 meters per pixel (m) spatial
resolution]]
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Kaguya [New York]",
Version = "1.1",
Description = [[Moon SELENE Kaguya TC Global Orthomosaic 474m v2 layer for Moon globe.
This map is hosted on the OpenSpace server in New York]],
Author = "USGS",
URL = "https://astrogeology.usgs.gov/search/map/Moon/Kaguya/TC/Ortho/v02/Lunar_Kaguya_TC_Ortho_Global_64ppd_v02",
License = "NASA/PDS"
}

View File

@@ -0,0 +1,28 @@
<VRTDataset rasterXSize="1474560" rasterYSize="737280">
<SRS>GEOGCS["GCS_Moon_2000",DATUM["D_Moon_2000",SPHEROID["Moon_2000_IAU_IAG",1737400.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]</SRS>
<GeoTransform> -1.8000000000000000e+02, 2.4414062500000000e-04, 0.0000000000000000e+00, 9.0000000000000000e+01, 0.0000000000000000e+00, -2.4414062500000000e-04</GeoTransform>
<VRTRasterBand dataType="Byte" band="1">
<ColorInterp>Gray</ColorInterp>
<SimpleSource>
<SourceFilename relativeToVRT="1">kaguya_newyork.wms</SourceFilename>
<SourceBand>1</SourceBand>
<SourceProperties RasterXSize="1474560" RasterYSize="737280" DataType="Byte" BlockXSize="360" BlockYSize="360" />
<SrcRect xOff="0" yOff="0" xSize="1474560" ySize="737280" />
<DstRect xOff="0" yOff="0" xSize="1474560" ySize="737280" />
</SimpleSource>
</VRTRasterBand>
<VRTRasterBand dataType="Byte" band="2">
<ColorInterp>Alpha</ColorInterp>
<NoDataValue>0</NoDataValue>
<ComplexSource>
<SourceFilename relativeToVRT="1">kaguya_newyork.wms</SourceFilename>
<SourceBand>1</SourceBand>
<SourceProperties RasterXSize="1474560" RasterYSize="737280" DataType="Byte" BlockXSize="360" BlockYSize="360" />
<SrcRect xOff="0" yOff="0" xSize="1474560" ySize="737280" />
<DstRect xOff="0" yOff="0" xSize="1474560" ySize="737280" />
<ScaleOffset>255</ScaleOffset>
<ScaleRatio>0</ScaleRatio>
<NODATA>0</NODATA>
</ComplexSource>
</VRTRasterBand>
</VRTDataset>

View File

@@ -0,0 +1,21 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://wms.openspace.amnh.org/Moon/Kaguya/tile/${z}/${y}/${x}</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<SizeX>1474560</SizeX>
<SizeY>737280</SizeY>
<TileLevel>11</TileLevel>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>GEOGCS["GCS_Moon_2000",DATUM["D_Moon_2000",SPHEROID["Moon_2000_IAU_IAG",1737400.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]</Projection>
<BlockSizeX>360</BlockSizeX>
<BlockSizeY>360</BlockSizeY>
<BandsCount>1</BandsCount>
<MaxConnections>10</MaxConnections>
<Timeout>5</Timeout>
</GDAL_WMS>

View File

@@ -0,0 +1,35 @@
local globeIdentifier = asset.require("./../../moon").Moon.Identifier
local layer = {
Identifier = "LO_MR_Mosaic_NewYork",
Name = "Moon Lunar Orbiter Digital Photographic Global Mosaic 59m v1 [New York]",
Enabled = asset.enabled,
Description = [[This Lunar Orbiter (LO) mosaic of the Moon was constructed using photographs acquired by LO III, IV and V. Work towards constructing the global mosaic spanned over seven years. Earlier work involved scanning and processing more than 30, 000 35-mm film strips from the LO high- and medium-resolution cameras (HR and MR, respectively).
Digital film strips were cartographically processed to construct more than 200 individual frames and then geodetically corrected using the most recent lunar control network and topographic model (Gaddis et al., 2001). The result of this work is a moderate resolution, near-global, cartographically controlled digital mosaic of the Moon (Becker et al., 2008). The nominal resolution of the mosaic is ~60 meters per pixel (m).
This represents new Jpeg2000 mosaic which includes a couple updated tiles that were missing from the original March 2008 release. For this image a lossy compression using a quality flag of 10 was used. There should be almost no noticeable loss of data. ]],
FilePath = asset.localResource("lo_mr_mosaic_newyork.wms")
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Moon Lunar Orbiter Digital Photographic Global Mosaic [New York]",
Version = "1.0",
Description = [[Moon Lunar Orbiter Digital Photographic Global Mosaic 59m v1. This
map is hosted on the OpenSpace server in New York]],
Author = "USGS",
URL = "https://astrogeology.usgs.gov/search/map/Moon/LMMP/LOLA-derived/Lunar_LRO_LOLA_ClrShade_Global_128ppd_v04",
License = "NASA/PDS"
}

View File

@@ -0,0 +1,21 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://wms.openspace.amnh.org/Moon/LO_MR_Mosaic_Global_59m/tile/${z}/${y}/${x}</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<SizeX>184320</SizeX>
<SizeY>92160</SizeY>
<TileLevel>8</TileLevel>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>GEOGCS["GCS_Moon_2000",DATUM["D_Moon_2000",SPHEROID["Moon_2000_IAU_IAG",1737400.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]</Projection>
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>1</BandsCount>
<MaxConnections>10</MaxConnections>
<Timeout>5</Timeout>
</GDAL_WMS>

View File

@@ -0,0 +1,38 @@
local globeIdentifier = asset.require("./../../moon").Moon.Identifier
local layer = {
Identifier = "Lola_Clr_Shade_NewYork",
Name = "LRO LOLA Color Shaded Relief 388m v4 [New York]",
Enabled = asset.enabled,
Description = [[This is a colorized shaded-relief of a original polar digital elevation
model (DEM) from the Lunar Orbiter Laser Altimeter (LOLA; Smith et al., 2010), an
instrument on the National Aeronautics and Space Agency (NASA) Lunar Reconnaissance
Orbiter (LRO) spacecraft (Tooley et al., 2010). The DEM is a shape map (radius) of the
Moon at a resolution 100 meters per pixel (m) based on altimetry data acquired through
September, 2011 by the LOLA instrument. The ground tracks were interpolated using the
Generic Mapping Tools programs "surface" and "grdblend". Map values are referred to a
radius of 1,737,400 m]],
FilePath = asset.localResource("lola_clr_shade_newyork.wms")
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Lola Color Shade [New York]",
Version = "1.1",
Description = [[Moon LRO LOLA Color Shaded Relief 388m v4 layer for Moon globe. This
map is hosted on the OpenSpace server in New York]],
Author = "USGS",
URL = "https://astrogeology.usgs.gov/search/map/Moon/LMMP/LOLA-derived/Lunar_LRO_LOLA_ClrShade_Global_128ppd_v04",
License = "NASA/PDS"
}

View File

@@ -0,0 +1,20 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://wms.openspace.amnh.org/Moon/Lola_Clr_Shade/tile/${z}/${y}/${x}</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<SizeX>92160</SizeX>
<SizeY>46080</SizeY>
<TileLevel>7</TileLevel>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>GEOGCS["GCS_Moon_2000",DATUM["D_Moon_2000",SPHEROID["Moon_2000_IAU_IAG",1737400.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]</Projection>
<BlockSizeX>360</BlockSizeX>
<BlockSizeY>360</BlockSizeY>
<BandsCount>3</BandsCount>
<MaxConnections>10</MaxConnections>
</GDAL_WMS>

View File

@@ -0,0 +1,38 @@
local globeIdentifier = asset.require("../../moon").Moon.Identifier
local layer = {
Identifier = "Lola_Shade_NewYork",
Name = "Lola Shade [New York]",
Enabled = asset.enabled,
Description = [[This is a shaded-relief of a original polar digital elevation model
(DEM) from the Lunar Orbiter Laser Altimeter (LOLA; Smith et al., 2010), an instrument
on the National Aeronautics and Space Agency (NASA) Lunar Reconnaissance Orbiter (LRO)
spacecraft (Tooley et al., 2010). The DEM is a shape map (radius) of the Moon at a
resolution 100 meters per pixel (m) based on altimetry data acquired through September,
2011 by the LOLA instrument. The ground tracks were interpolated using the Generic
Mapping Tools programs "surface" and "grdblend". Map values are referred to a radius
of 1,737,400 m]],
FilePath = asset.localResource("lola_shade_newyork.wms")
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Lola Shade [New York]",
Version = "1.1",
Description = [[Moon LRO LOLA Shaded Relief 237m v4 layer for Moon globe. This
map is hosted on the OpenSpace server in New York]],
Author = "USGS",
URL = "https://astrogeology.usgs.gov/search/map/Moon/LMMP/LOLA-derived/Lunar_LRO_LOLA_Shade_Global_128ppd_v04",
License = "NASA/PDS"
}

View File

@@ -0,0 +1,20 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://wms.openspace.amnh.org/Moon/Lola_Shade/tile/${z}/${y}/${x}</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<SizeX>92160</SizeX>
<SizeY>46080</SizeY>
<TileLevel>7</TileLevel>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>GEOGCS["GCS_Moon_2000",DATUM["D_Moon_2000",SPHEROID["Moon_2000_IAU_IAG",1737400.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]</Projection>
<BlockSizeX>360</BlockSizeX>
<BlockSizeY>360</BlockSizeY>
<BandsCount>1</BandsCount>
<MaxConnections>10</MaxConnections>
</GDAL_WMS>

View File

@@ -0,0 +1,43 @@
local globeIdentifier = asset.require("../../moon").Moon.Identifier
local layer = {
Identifier = "UvvisHybrid_NewYork",
Name = "Uvvis Hybrid [New York]",
Enabled = asset.enabled,
FilePath = asset.localResource("uvvishybrid_newyork.wms"),
Settings = {
Gamma = 0.52,
Multiplier = 0.65
},
Description = [[The is a blend (or overlay) of the U.S. Geological Survey (USGS)
Clementine Ultraviolet/Visible (UVVIS) V2 mosaic and the original USGS Lunar Orbiter
mosaic. The Clementine 750 nm Version 2 mosaic is a grayscale data set representing
the albedo (brightness of the lunar surface) as measured at the 750 nm wavelength by
the UVVIS camera. The original base map was radiometrically and geometrically
controlled, photometrically modeled global image mosaic compiled using more than
43,000 images from the 750 nanometer filter observations of the UVVIS
(Lee et al., 2009)]]
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Uvvis Hybrid [New York]",
Version = "1.1",
Description = [[Moon Lunar Orbiter - Clementine UVVISv2 Hybrid Mosaic 59m v1 map of the
Moon. This map is hosted on the OpenSpace server in New York]],
Author = "USGS",
URL = "https://astrogeology.usgs.gov/search/map/Moon/Lunar-Orbiter/Lunar_LO_UVVISv2_Hybrid_Mosaic_Global_59m",
License = "NASA/PDS"
}

View File

@@ -0,0 +1,20 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://wms.openspace.amnh.org/Moon/Uvvis_Hybrid/tile/${z}/${y}/${x}</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<SizeX>184320</SizeX>
<SizeY>92160</SizeY>
<TileLevel>8</TileLevel>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>GEOGCS["GCS_Moon_2000",DATUM["D_Moon_2000",SPHEROID["Moon_2000_IAU_IAG",1737400.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]</Projection>
<BlockSizeX>360</BlockSizeX>
<BlockSizeY>360</BlockSizeY>
<BandsCount>1</BandsCount>
<MaxConnections>10</MaxConnections>
</GDAL_WMS>

View File

@@ -0,0 +1,34 @@
local globeIdentifier = asset.require("../../moon").Moon.Identifier
local layer = {
Identifier = "WAC_NewYork",
Name = "WAC [New York]",
Enabled = asset.enabled,
Description = [[Lunar Reconnaissance Orbiter Camera (LROC) Wide Angle Camera (WAC) aboard the Lunar Reconnaissance Orbiter (LRO) has allowed the instrument team to create a global mosaic comprised of over 15,000 images acquired between November 2009 and February 2011. The WAC maps the whole Moon in one month, however the solar incidence angle at the equator changes about 28° from the beginning to the end of the month. To even out the incidence angle variations (generally angles between 55-75 degrees), this morphology mosaic (at 643 nm), is comprised of data collected over three periods (1/20/2010 to 1/28/2010, 5/30/2010 to 6/6/2010, 7/24/2010 to 7/31/2010).
The South Pole mosaic images were acquired 8/10/10 to 9/19/10 and the north polar images 4/22/10 to 5/19/10. Some gores were filled with data taken at other times. The non-polar images were map projected onto the GLD100, WAC-derived 100 meters per pixel (m), while polar images were map projected on the Lunar Orbiter Laser Altimeter (LOLA) shape model (80° to 90° N/S) and the GLD100 (60° to 80° N/S). In addition, the LOLA derived crossover corrected ephemeris and an improved camera pointing provide accurate positioning of each WAC image. Because the polar images were acquired at a different season than the equatorial images, and the lunar photometric function is not perfectly known, there can be a brightness difference where the polar mosaics meet the equatorial mosaics. This has been greatly reduced in version 3 (created in June 2013). (Description from URL)]],
FilePath = asset.localResource("wac_newyork.wms"),
Settings = { Gamma = 0.84 }
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "WAC [New York]",
Version = "2.0",
Description = [[Wide Angle Color map of the Moon. This map is hosted on the OpenSpace
server in New York]],
Author = "USGS",
URL = "https://astrogeology.usgs.gov/search/map/Moon/LRO/LROC_WAC/Lunar_LRO_LROC-WAC_Mosaic_global_100m_June2013",
License = "NASA/PDS"
}

View File

@@ -0,0 +1,20 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://wms.openspace.amnh.org/Moon/WAC3/tile/${z}/${y}/${x}</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<SizeX>109164</SizeX>
<SizeY>54582</SizeY>
<TileLevel>8</TileLevel>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>GEOGCS["GCS_Moon_2000",DATUM["D_Moon_2000",SPHEROID["Moon_2000_IAU_IAG",1737400.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]</Projection>
<BlockSizeX>360</BlockSizeX>
<BlockSizeY>360</BlockSizeY>
<BandsCount>1</BandsCount>
<MaxConnections>10</MaxConnections>
</GDAL_WMS>

View File

@@ -0,0 +1,40 @@
local globeIdentifier = asset.require("../../moon").Moon.Identifier
local layer = {
Identifier = "WAC_V1_NewYork",
Name = "WAC V1 [New York]",
Enabled = asset.enabled,
Description = [[Lunar Reconnaissance Orbiter Camera (LROC) Wide Angle Camera (WAC)
aboard the Lunar Reconnaissance Orbiter (LRO) has allowed the instrument team to
create a global mosaic comprised of over 15,000 images acquired between November 2009
and February 2011. The WAC maps the whole Moon in one month, however the solar
incidence angle at the equator changes about 28° from the beginning to the end of the
month. To even out the incidence angle variations (generally angles between 55-75
degrees), this morphology mosaic (at 643 nm), is comprised of data collected over
three periods (1/20/2010 to 1/28/2010, 5/30/2010 to 6/6/2010, 7/24/2010 to 7/31/2010).
(Description from URL)]],
FilePath = asset.localResource("wac_v1_newyork.wms"),
Settings = { Gamma = 0.84 }
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "WAC [New York]",
Version = "1.2",
Description = [[Wide Angle Color map of the Moon. This map is hosted on the OpenSpace
server in New York]],
Author = "USGS",
URL = "https://astrogeology.usgs.gov/search/map/Moon/LRO/LROC_WAC/Lunar_LRO_LROC-WAC_Mosaic_global_100m_June2013",
License = "NASA/PDS"
}

View File

@@ -0,0 +1,20 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://wms.openspace.amnh.org/Moon/WAC/tile/${z}/${y}/${x}</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<SizeX>109164</SizeX>
<SizeY>54582</SizeY>
<TileLevel>8</TileLevel>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>GEOGCS["GCS_Moon_2000",DATUM["D_Moon_2000",SPHEROID["Moon_2000_IAU_IAG",1737400.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]</Projection>
<BlockSizeX>256</BlockSizeX>
<BlockSizeY>256</BlockSizeY>
<BandsCount>1</BandsCount>
<MaxConnections>10</MaxConnections>
</GDAL_WMS>

View File

@@ -0,0 +1,38 @@
local globeIdentifier = asset.require("../../moon").Moon.Identifier
local layer = {
Identifier = "LolaDem_NewYork",
Name = "Lola DEM [New York]",
Enabled = asset.enabled,
FilePath = asset.localResource("loladem_newyork.wms"),
TilePixelSize = 360,
Settings = { Multiplier = 0.5 },
Description = [[This digital elevation model (DEM) is based on data from the Lunar
Orbiter Laser Altimeter (LOLA; Smith et al., 2010), an instrument on the National
Aeronautics and Space Agency (NASA) Lunar Reconnaissance Orbiter (LRO) spacecraft
(Tooley et al., 2010). The created DEM represents more than 6.5 billion measurements
gathered between July 2009 and July 2013, adjusted for consistency in the coordinate
system described below, and then converted to lunar radii (Mazarico et al., 2012)]]
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globeIdentifier, "HeightLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globeIdentifier, "HeightLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Lola DEM [New York]",
Version = "1.1",
Description = [[Moon LRO LOLA DEM 118m v1 layer for Moon globe. This map is hosted on
the OpenSpace server in New York]],
Author = "USGS",
URL = "https://astrogeology.usgs.gov/search/map/Moon/LRO/LOLA/Lunar_LRO_LOLA_Global_LDEM_118m_Mar2014",
License = "NASA/PDS"
}

View File

@@ -0,0 +1,22 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://wms.openspace.amnh.org/Moon/Lola_Dem/tile/${z}/${y}/${x}</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<SizeX>92160</SizeX>
<SizeY>46080</SizeY>
<TileLevel>7</TileLevel>
<YOrigin>top</YOrigin>
</DataWindow>
<DataType>Int16</DataType>
<Projection>GEOGCS["GCS_Moon_2000",DATUM["D_Moon_2000",SPHEROID["Moon_2000_IAU_IAG",1737400.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]</Projection>
<BlockSizeX>360</BlockSizeX>
<BlockSizeY>360</BlockSizeY>
<BandsCount>1</BandsCount>
<MaxConnections>10</MaxConnections>
<Timeout>5</Timeout>
</GDAL_WMS>

View File

@@ -1,7 +1,9 @@
local colorLayersPath = "./layers/colorlayers"
asset.require(colorLayersPath .. "/europa_texture", false)
asset.require(colorLayersPath .. "/voyager_global_mosaic_local", true)
asset.require(colorLayersPath .. "/voyager_global_mosaic_local", false)
asset.require(colorLayersPath .. "/voyager_global_mosaic_sweden", false)
asset.require(colorLayersPath .. "/voyager_global_mosaic_newyork", true)
asset.meta = {

View File

@@ -0,0 +1,39 @@
local globeIdentifier = asset.require("../../europa").Europa.Identifier
local layer = {
Identifier = "Voyager_Global_Mosaic_NewYork",
Name = "Voyager Global Mosaic [New York]",
Enabled = asset.enabled,
FilePath = asset.localResource("voyager_global_mosaic_newyork.wms"),
BlendMode = "Color",
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Voyager Global Mosaic [New York]",
Version = "1.1",
Description = [[Europa Voyager - Galileo SSI Global Mosaic 500m v2. This global map
base of Europa utilizes the best image quality and moderate resolution coverage
supplied by the Galileo SSI (Solid-State Imaging) instrument and Voyager 1 and 2.
The image data was selected on the basis of overall image quality, reasonable
input resolution (from 20 km/pixel for gap fill to as high as 200 meters per
pixel[m]), and availability of moderate viewing and sun angles for topography.
The map projections are based on a sphere having a radius of 1,562.09 kilometers.
A Simple Cylindrical projection was used at a resolution of 500 m. (Description
from URL)]],
Author = "USGS",
URL = "https://astrogeology.usgs.gov/search/map/Europa/Voyager-Galileo/" ..
"Europa_Voyager_GalileoSSI_global_mosaic_500m",
License = "NASA/PDS"
}

View File

@@ -0,0 +1,20 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://wms.openspace.amnh.org/Europa/Voyager_GalileoSSI_global_mosaic_500m/tile/${z}/${y}/${x}</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<SizeX>19631</SizeX>
<SizeY>9816</SizeY>
<TileLevel>7</TileLevel>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>EPSG:4326</Projection>
<BlockSizeX>256</BlockSizeX>
<BlockSizeY>256</BlockSizeY>
<BandsCount>1</BandsCount>
<MaxConnections>10</MaxConnections>
</GDAL_WMS>

View File

@@ -1,7 +1,7 @@
local globeIdentifier = asset.require("../../europa").Europa.Identifier
local layer = {
Identifier = "Voyager_Global_Mosaic",
Identifier = "Voyager_Global_Mosaic_sweden",
Name = "Voyager Global Mosaic [Sweden]",
Enabled = asset.enabled,
FilePath = asset.localResource("voyager_global_mosaic_sweden.wms"),
@@ -21,7 +21,7 @@ asset.export("layer", layer)
asset.meta = {
Name = "Voyager Global Mosaic",
Name = "Voyager Global Mosaic [Sweden]",
Version = "1.1",
Description = [[Europa Voyager - Galileo SSI Global Mosaic 500m v2. This global map
base of Europa utilizes the best image quality and moderate resolution coverage

View File

@@ -2,25 +2,32 @@
asset.require("./layers/colorlayers/mars_texture", false)
asset.require("./layers/colorlayers/moc_wa_color_utah", true)
asset.require("./layers/colorlayers/moc_wa_color_sweden", false)
asset.require("./layers/colorlayers/moc_wa_color_newyork", false)
asset.require("./layers/colorlayers/viking_mdim_utah", false)
asset.require("./layers/colorlayers/viking_mdim_sweden", false)
asset.require("./layers/colorlayers/viking_mdim_newyork", false)
asset.require("./layers/colorlayers/mola_pseudo_color_utah", false)
asset.require("./layers/colorlayers/mola_pseudo_color_sweden", false)
asset.require("./layers/colorlayers/mola_pseudo_color_newyork", false)
asset.require("./layers/colorlayers/mola_hrsc_utah", false)
asset.require("./layers/colorlayers/mola_hrsc_sweden", false)
asset.require("./layers/colorlayers/mola_hrsc_newyork", false)
asset.require("./layers/colorlayers/themis_ir_day_utah", false)
asset.require("./layers/colorlayers/themis_ir_day_sweden", false)
asset.require("./layers/colorlayers/themis_ir_day_newyork", false)
asset.require("./layers/colorlayers/themis_ir_night_utah", false)
asset.require("./layers/colorlayers/themis_ir_night_sweden", false)
asset.require("./layers/colorlayers/themis_ir_night_newyork", false)
asset.require("./layers/colorlayers/ctx_mosaic_utah", false)
asset.require("./layers/colorlayers/ctx_mosaic_sweden", false)
asset.require("./layers/colorlayers/ctx_mosaic_newyork", false)
asset.require("./layers/colorlayers/ctx_blended", false)
asset.require("./layers/colorlayers/hirise", false)
asset.require("./layers/colorlayers/hirisels", false)
-- Height layers
asset.require("./layers/heightlayers/mola_sweden", false)
asset.require("./layers/heightlayers/mola_utah", false)
asset.require("./layers/heightlayers/mola_sweden", false)
asset.require("./layers/heightlayers/MDEM200M", true)
asset.require("./layers/heightlayers/hirisels", false)

View File

@@ -0,0 +1,31 @@
local globeIdentifier = asset.require("../../mars").Mars.Identifier
local layer = {
Identifier = "CTX_Mosaic_NewYork",
Name = "CTX Mosaic [New York]",
Enabled = asset.enabled,
FilePath = asset.localResource("ctx_mosaic_newyork.wms"),
BlendMode = "Color"
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "CTX Mosaic [New York]",
Version = "1.0",
Description = [[CTX Mosaic layer for Mars globe. This layer is served from the
OpenSpace servers in New York]],
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -0,0 +1,23 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://wms.openspace.amnh.org/Mars/CTX/tile/${z}/${y}/${x}</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<SizeX>4194304</SizeX>
<SizeY>2097152</SizeY>
<TileLevel>13</TileLevel>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>GEOGCS[&quot;Mars 2000&quot;, DATUM[&quot;D_Mars_2000&quot;, SPHEROID[&quot;MARS_2000_IAU_IAG&quot;,3396190.0,169.894447222361179]],PRIMEM[&quot;Greenwich&quot;0],UNIT[&quot;Decimal_Degree&quot;,0.0174532925199433]]</Projection>
<BlockSizeX>256</BlockSizeX>
<BlockSizeY>256</BlockSizeY>
<BandsCount>2</BandsCount>
<MaxConnections>10</MaxConnections>
<ZeroBlockHttpCodes>400,204,404</ZeroBlockHttpCodes>
<ZeroBlockOnServerException>true</ZeroBlockOnServerException>
<Timeout>5</Timeout>
</GDAL_WMS>

View File

@@ -0,0 +1,38 @@
local globeIdentifier = asset.require("../../mars").Mars.Identifier
local layer = {
Identifier = "MOC_WA_Color_NewYork",
Name = "MOC WA Color [New York]",
Enabled = asset.enabled,
FilePath = asset.localResource("moc_wa_color_newyork.wms"),
Settings = {
Gamma = 1.6,
Multiplier = 1.07
},
Description = [[This map is an AMNH version of the global mossaic produced by the
Mars Global Surveyor Wide Angle Camera. This version has color added and the
shadows subdued based on the MOLA DTM. Data Reference:
https://www.jpl.nasa.gov/spaceimages/details.php?id=PIA03467]]
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "MOC WA Color [New York]",
Version = "1.1",
Description = [[Main color map layer for Mars. This map is hosted
on the OpenSpace server in New York]],
Author = "OpenSpace Team",
URL = "http://www.openspaceproject.com",
License = "NASA/PDS"
}

View File

@@ -0,0 +1,20 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://wms.openspace.amnh.org/Mars/Color/tile/${z}/${y}/${x}</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<SizeX>92160</SizeX>
<SizeY>46080</SizeY>
<TileLevel>7</TileLevel>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>GEOGCS["Mars2000",DATUM["D_Mars_2000",SPHEROID["Mars_2000_IAU_IAG",3396190,169.8944472236118]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]]</Projection>
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>3</BandsCount>
<MaxConnections>10</MaxConnections>
</GDAL_WMS>

View File

@@ -0,0 +1,34 @@
local globeIdentifier = asset.require("../../mars").Mars.Identifier
local layer = {
Identifier = "MOLA_HRSC_NewYork",
Name = "MOLA HRSC [New York]",
Enabled = asset.enabled,
FilePath = asset.localResource("mola_hrsc_newyork.wms"),
Description = [[This map layer is colorzied based elevation data from MOLA and HRSC.
Compared to MOLA Psuedo Color, this layer has no terrain shading, which is
suitable for use when combing with other layers. Data Reference:
https://astrogeology.usgs.gov/search/map/Mars/Topography/HRSC_MOLA_Blend/Mars_HRSC_MOLA_BlendDEM_Global_200mp_v2]]
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "MOLA HRSC [New York]",
Version = "1.1",
Description = [[Colorzied elevation data for Mars. This map is hosted on the OpenSpace
server in New York]],
Author = "OpenSpace Team",
URL = "http://www.openspaceproject.com",
License = "NASA/PDS"
}

View File

@@ -0,0 +1,20 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://wms.openspace.amnh.org/Mars/Mola_HRSC/tile/${z}/${y}/${x}</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<SizeX>106694</SizeX>
<SizeY>53347</SizeY>
<TileLevel>7</TileLevel>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>GEOGCS["GCS_Mars_2000_Sphere",DATUM["D_Mars_2000_Sphere",SPHEROID["Mars_2000_Sphere_IAU_IAG",3396190.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]</Projection>
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>3</BandsCount>
<MaxConnections>10</MaxConnections>
</GDAL_WMS>

View File

@@ -0,0 +1,45 @@
local globeIdentifier = asset.require("../../mars").Mars.Identifier
local layer = {
Identifier = "MOLA_Pseudo_Color_NewYork",
Name = "MOLA Pseudo Color [New York]",
Enabled = asset.enabled,
FilePath = asset.localResource("mola_pseudo_color_newyork.wms"),
Description = [[This map is based on data from the Mars Orbiter Laser Altimeter (MOLA)
(Smith, et al., 2001), an instrument on NASA's Mars Global Surveyor (MGS)
spacecraft (Albee, et al., 2001). The image used for the base of this map
represents more than 600 million measurements gathered between 1999 and 2001,
adjusted for consistency (Neumann, et al., 2001; Neumann, et al., 2003) and
converted to planetary radii. These have been converted to elevations above the
areoid as determined from a Martian gravity field solution GMM-2B (Lemoine, et
al., 2001), truncated to degree and order 50, and oriented according to current
standards (see below). The average accuracy of each point is originally ~100
meters in horizontal position and ~1 meter in radius (Neumann, et al., 2001;
Neumann, et al., 2003). However, the total elevation uncertainty is at least ±3 m
due to the global error in the areoid (±1.8 meters; Lemoine, et al., 2001) and
regional uncertainties in its shape (Neumann, 2002). Pixel resolution of this map
is 463 meters per pixel (m). (Description from URL). Data Reference: (See URL)]]
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "MOLA Pseudo Color [New York]",
Version = "1.1",
Description = [[Colorzied elevation data for Mars (with shading). This map is hosted
on the OpenSpace server in New York]],
Author = "USGS",
URL = "https://astrogeology.usgs.gov/search/map/Mars/GlobalSurveyor/MOLA/" ..
"Mars_MGS_MOLA_ClrShade_merge_global_463m",
License = "NASA/PDS"
}

View File

@@ -0,0 +1,20 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://wms.openspace.amnh.org/Mars/Mola_PseudoColor/tile/${z}/${y}/${x}</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<SizeX>46080</SizeX>
<SizeY>23040</SizeY>
<TileLevel>6</TileLevel>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>GEOGCS["GCS_Mars_2000_Sphere",DATUM["D_Mars_2000_Sphere",SPHEROID["Mars_2000_Sphere_IAU_IAG",3396190.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]</Projection>
<BlockSizeX>360</BlockSizeX>
<BlockSizeY>360</BlockSizeY>
<BandsCount>3</BandsCount>
<MaxConnections>10</MaxConnections>
</GDAL_WMS>

View File

@@ -0,0 +1,42 @@
local globeIdentifier = asset.require("../../mars").Mars.Identifier
local layer = {
Identifier = "Themis_IR_Day_NewYork",
Name = "Themis IR Day [New York]",
Enabled = asset.enabled,
FilePath = asset.localResource("themis_ir_day_newyork.wms"),
BlendMode = "Color",
Description = [[This mosaic represents the Thermal Emission Imaging System (THEMIS)
-daytime infrared (IR) 100 meter/pixel mosaic (version 12) released in the summer
of 2014 by Arizona State University. Values represent only a visual representation
of day-time temperatures. The original values have been stretched and blended to
make a more seamless mosaic. <br><br> Reference: * Edwards, C. S., K. J. Nowicki,
P. R. Christensen, J. Hill, N. Gorelick, and K. Murray (2011), Mosaicking of
global planetary image datasets: 1. Techniques and data processing for Thermal
Emission Imaging System (THEMIS) multi-spectral data, J. Geophys. Res., 116,
E10008, doi:10.1029/2010JE003755. http://dx.doi.org/10.1029/2010JE003755
(Description from URL)]]
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globeIdentifier, "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Themis IR Day [New York]",
Version = "1.1",
Description = [[Themis Day layer for Mars. This map is hosted on the OpenSpace server
in New York]],
Author = "USGS",
URL = "https://astrogeology.usgs.gov/search/map/Mars/Odyssey/THEMIS-IR-Mosaic-ASU/" ..
"Mars_MO_THEMIS-IR-Day_mosaic_global_100m_v12",
License = "NASA/PDS"
}

View File

@@ -0,0 +1,20 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http:/wms.openspace.amnh.org/Mars/Themis_IR_Day/tile/${z}/${y}/${x}</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<SizeX>213390</SizeX>
<SizeY>106695</SizeY>
<TileLevel>9</TileLevel>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>GEOGCS["GCS_Mars_2000_Sphere",DATUM["D_Mars_2000_Sphere",SPHEROID["Mars_2000_Sphere_IAU_IAG",3396190.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]</Projection>
<BlockSizeX>256</BlockSizeX>
<BlockSizeY>256</BlockSizeY>
<BandsCount>1</BandsCount>
<MaxConnections>10</MaxConnections>
</GDAL_WMS>

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