diff --git a/CMakeLists.txt b/CMakeLists.txt index c3e35daafc..81d0833e7c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,9 +27,9 @@ cmake_minimum_required(VERSION 3.10 FATAL_ERROR) project(OpenSpace) set(OPENSPACE_VERSION_MAJOR 0) -set(OPENSPACE_VERSION_MINOR 16) -set(OPENSPACE_VERSION_PATCH 0) -set(OPENSPACE_VERSION_STRING "Beta-8") +set(OPENSPACE_VERSION_MINOR 17) +set(OPENSPACE_VERSION_PATCH -1) +set(OPENSPACE_VERSION_STRING "Beta-10 [RC1]") set(OPENSPACE_BASE_DIR "${PROJECT_SOURCE_DIR}") set(OPENSPACE_CMAKE_EXT_DIR "${OPENSPACE_BASE_DIR}/support/cmake") diff --git a/apps/OpenSpace/CMakeLists.txt b/apps/OpenSpace/CMakeLists.txt index 7622653bf6..c43e141b3f 100644 --- a/apps/OpenSpace/CMakeLists.txt +++ b/apps/OpenSpace/CMakeLists.txt @@ -116,13 +116,13 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/ext/sgct) target_link_libraries(OpenSpace PRIVATE sgct) set_folder_location(sgct "External") -set_folder_location(glfw "External/SGCT") -set_folder_location(miniziplibstatic "External/SGCT") -set_folder_location(png16_static "External/SGCT") -set_folder_location(quat "External/SGCT") -set_folder_location(tinyxml2static "External/SGCT") -set_folder_location(vrpn "External/SGCT") -set_folder_location(zlibstatic "External/SGCT") +set_folder_location(glfw "External") +set_folder_location(miniziplibstatic "External") +set_folder_location(png16_static "External") +set_folder_location(quat "External") +set_folder_location(tinyxml2static "External") +set_folder_location(vrpn "External") +set_folder_location(zlibstatic "External") if (UNIX AND (NOT APPLE)) target_link_libraries(OpenSpace PRIVATE Xcursor Xinerama X11) diff --git a/apps/OpenSpace/ext/launcher/include/launcherwindow.h b/apps/OpenSpace/ext/launcher/include/launcherwindow.h index 2c1b17bb0c..508c0442cc 100644 --- a/apps/OpenSpace/ext/launcher/include/launcherwindow.h +++ b/apps/OpenSpace/ext/launcher/include/launcherwindow.h @@ -96,6 +96,7 @@ private: bool _shouldLaunch = false; int _userAssetCount = 0; int _userConfigCount = 0; + const std::string _sgctConfigName; QComboBox* _profileBox = nullptr; QComboBox* _windowConfigBox = nullptr; diff --git a/apps/OpenSpace/ext/launcher/include/profile/modulesdialog.h b/apps/OpenSpace/ext/launcher/include/profile/modulesdialog.h index 6ca0c5b209..6533eff4ba 100644 --- a/apps/OpenSpace/ext/launcher/include/profile/modulesdialog.h +++ b/apps/OpenSpace/ext/launcher/include/profile/modulesdialog.h @@ -82,7 +82,7 @@ private: QLineEdit* _loadedEdit = nullptr; QLabel* _notLoadedLabel = nullptr; QLineEdit* _notLoadedEdit = nullptr; - + QPushButton* _buttonAdd = nullptr; QPushButton* _buttonRemove = nullptr; QPushButton* _buttonSave = nullptr; diff --git a/apps/OpenSpace/ext/launcher/src/launcherwindow.cpp b/apps/OpenSpace/ext/launcher/src/launcherwindow.cpp index 631c1bb27b..99672c1d57 100644 --- a/apps/OpenSpace/ext/launcher/src/launcherwindow.cpp +++ b/apps/OpenSpace/ext/launcher/src/launcherwindow.cpp @@ -141,13 +141,16 @@ LauncherWindow::LauncherWindow(bool profileEnabled, bool sgctConfigEnabled, std::string sgctConfigName, QWidget* parent) : QMainWindow(parent) - , _assetPath(absPath(globalConfig.pathTokens.at("ASSETS")) + '/') - , _userAssetPath(absPath(globalConfig.pathTokens.at("USER_ASSETS")) + '/') - , _configPath(absPath(globalConfig.pathTokens.at("CONFIG")) + '/') - , _userConfigPath(absPath(globalConfig.pathTokens.at("USER_CONFIG")) + '/') - , _profilePath(absPath(globalConfig.pathTokens.at("PROFILES")) + '/') - , _userProfilePath(absPath(globalConfig.pathTokens.at("USER_PROFILES")) + '/') + , _assetPath(absPath(globalConfig.pathTokens.at("ASSETS")).string() + '/') + , _userAssetPath(absPath(globalConfig.pathTokens.at("USER_ASSETS")).string() + '/') + , _configPath(absPath(globalConfig.pathTokens.at("CONFIG")).string() + '/') + , _userConfigPath(absPath(globalConfig.pathTokens.at("USER_CONFIG")).string() + '/') + , _profilePath(absPath(globalConfig.pathTokens.at("PROFILES")).string() + '/') + , _userProfilePath( + absPath(globalConfig.pathTokens.at("USER_PROFILES")).string() + '/' + ) , _readOnlyProfiles(globalConfig.readOnlyProfiles) + , _sgctConfigName(sgctConfigName) { Q_INIT_RESOURCE(resources); @@ -175,14 +178,16 @@ LauncherWindow::LauncherWindow(bool profileEnabled, populateProfilesList(globalConfig.profile); _profileBox->setEnabled(profileEnabled); - populateWindowConfigsList(sgctConfigName); + populateWindowConfigsList(_sgctConfigName); _windowConfigBox->setEnabled(sgctConfigEnabled); - std::string p = absPath(globalConfig.pathTokens.at("SYNC") + "/http/launcher_images"); + std::filesystem::path p = absPath( + globalConfig.pathTokens.at("SYNC") + "/http/launcher_images" + ); if (std::filesystem::exists(p)) { try { - setBackgroundImage(p); + setBackgroundImage(p.string()); } catch (const std::exception& e) { std::cerr << "Error occurrred while reading background images: " << e.what(); @@ -454,7 +459,10 @@ std::string LauncherWindow::selectedProfile() const { } std::string LauncherWindow::selectedWindowConfig() const { - if (_windowConfigBox->currentIndex() > _userAssetCount) { + int idx = _windowConfigBox->currentIndex(); + if (idx == 0) { + return _sgctConfigName; + } else if (idx > _userAssetCount) { return "${CONFIG}/" + _windowConfigBox->currentText().toStdString(); } else { diff --git a/apps/OpenSpace/ext/launcher/src/profile/assetsdialog.cpp b/apps/OpenSpace/ext/launcher/src/profile/assetsdialog.cpp index 072022c65a..c2573cc381 100644 --- a/apps/OpenSpace/ext/launcher/src/profile/assetsdialog.cpp +++ b/apps/OpenSpace/ext/launcher/src/profile/assetsdialog.cpp @@ -63,7 +63,7 @@ namespace { int startIndex = 0; std::string token = "${USER_ASSETS}/"; if (path.find(token) == 0) { - startIndex = token.length(); + startIndex = static_cast(token.length()); } const size_t slash = path.find_first_of('/', startIndex); const bool endOfPath = (slash == std::string::npos); diff --git a/apps/OpenSpace/ext/launcher/src/profile/keybindingsdialog.cpp b/apps/OpenSpace/ext/launcher/src/profile/keybindingsdialog.cpp index baa366a879..273dde9ab6 100644 --- a/apps/OpenSpace/ext/launcher/src/profile/keybindingsdialog.cpp +++ b/apps/OpenSpace/ext/launcher/src/profile/keybindingsdialog.cpp @@ -460,9 +460,6 @@ void KeybindingsDialog::listItemRemove() { } void KeybindingsDialog::transitionToEditMode() { - _list->setDisabled(true); - _addButton->setDisabled(true); - _removeButton->setDisabled(true); _saveButton->setDisabled(true); _cancelButton->setDisabled(true); _buttonBox->setDisabled(true); diff --git a/apps/OpenSpace/ext/launcher/src/profile/modulesdialog.cpp b/apps/OpenSpace/ext/launcher/src/profile/modulesdialog.cpp index 5f7ad9f7f4..7359026d7e 100644 --- a/apps/OpenSpace/ext/launcher/src/profile/modulesdialog.cpp +++ b/apps/OpenSpace/ext/launcher/src/profile/modulesdialog.cpp @@ -297,9 +297,6 @@ void ModulesDialog::listItemRemove() { } void ModulesDialog::transitionToEditMode() { - _list->setDisabled(true); - _buttonAdd->setDisabled(true); - _buttonRemove->setDisabled(true); _buttonSave->setDisabled(true); _buttonCancel->setDisabled(true); _buttonBox->setDisabled(true); diff --git a/apps/OpenSpace/ext/launcher/src/profile/propertiesdialog.cpp b/apps/OpenSpace/ext/launcher/src/profile/propertiesdialog.cpp index 8e1f9477f9..3a9441154e 100644 --- a/apps/OpenSpace/ext/launcher/src/profile/propertiesdialog.cpp +++ b/apps/OpenSpace/ext/launcher/src/profile/propertiesdialog.cpp @@ -302,9 +302,6 @@ void PropertiesDialog::listItemRemove() { } void PropertiesDialog::transitionToEditMode() { - _list->setDisabled(true); - _addButton->setDisabled(true); - _removeButton->setDisabled(true); _saveButton->setDisabled(true); _cancelButton->setDisabled(true); _buttonBox->setDisabled(true); diff --git a/apps/OpenSpace/ext/launcher/src/profile/scriptlogdialog.cpp b/apps/OpenSpace/ext/launcher/src/profile/scriptlogdialog.cpp index c82fd8aa57..906a855c13 100644 --- a/apps/OpenSpace/ext/launcher/src/profile/scriptlogdialog.cpp +++ b/apps/OpenSpace/ext/launcher/src/profile/scriptlogdialog.cpp @@ -39,7 +39,7 @@ ScriptlogDialog::ScriptlogDialog(QWidget* parent) setWindowTitle("Scriptlog"); createWidgets(); - QFile file(QString::fromStdString(absPath("${LOGS}/scriptLog.txt"))); + QFile file(QString::fromStdString(absPath("${LOGS}/scriptLog.txt").string())); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&file); while (!in.atEnd()) { diff --git a/apps/OpenSpace/ext/sgct b/apps/OpenSpace/ext/sgct index 669fbc16a9..2a3ef78f72 160000 --- a/apps/OpenSpace/ext/sgct +++ b/apps/OpenSpace/ext/sgct @@ -1 +1 @@ -Subproject commit 669fbc16a9910b28333427f5e07235baa43ea7a6 +Subproject commit 2a3ef78f721e919531bb05b0cedab2dabe2bb0be diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index 9adc728a07..dfd8b32c52 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -61,6 +61,7 @@ #include #include #include +#include #include #ifdef WIN32 @@ -223,9 +224,9 @@ void mainInitFunc(GLFWwindow*) { // // We save the startup value of the screenshots just in case we want to add a date // to them later in the RenderEngine - std::string screenshotPath = absPath("${SCREENSHOTS}"); + std::filesystem::path screenshotPath = absPath("${SCREENSHOTS}"); FileSys.registerPathToken("${STARTUP_SCREENSHOT}", screenshotPath); - Settings::instance().setCapturePath(screenshotPath); + Settings::instance().setCapturePath(screenshotPath.string()); LDEBUG("Initializing OpenSpace Engine started"); global::openSpaceEngine->initialize(); @@ -234,11 +235,11 @@ void mainInitFunc(GLFWwindow*) { #ifndef __APPLE__ // Apparently: "Cocoa: Regular windows do not have icons on macOS" { - std::string path = absPath("${DATA}/openspace-icon.png"); + std::filesystem::path path = absPath("${DATA}/openspace-icon.png"); int x; int y; int n; - unsigned char* data = stbi_load(path.c_str(), &x, &y, &n, 0); + unsigned char* data = stbi_load(path.string().c_str(), &x, &y, &n, 0); GLFWimage icons[1]; icons[0].pixels = data; @@ -975,14 +976,6 @@ std::string setWindowConfigPresetForGui(const std::string labelFromCfgFile, } else { preset = config.windowConfiguration; - if (preset.find('/') != std::string::npos) { - preset.erase(0, preset.find_last_of('/') + 1); - } - if (preset.length() >= xmlExt.length()) { - if (preset.substr(preset.length() - xmlExt.length()) == xmlExt) { - preset = preset.substr(0, preset.length() - xmlExt.length()); - } - } } return preset; } @@ -1004,7 +997,14 @@ std::string selectedSgctProfileFromLauncher(LauncherWindow& lw, bool hasCliSGCTC } } else { - config += xmlExt; + if ( (config.length() >= xmlExt.length()) + && (0 == config.compare(config.length() - xmlExt.length(), xmlExt.length(), xmlExt)) ) { + //user customzied sgct config + } + else { + config += xmlExt; + } + } global::configuration->windowConfiguration = config; } @@ -1039,7 +1039,7 @@ int main(int argc, char* argv[]) { // to make it possible to find other files in the same directory. FileSys.registerPathToken( "${BIN}", - ghoul::filesystem::File(absPath(argv[0])).directoryName(), + std::filesystem::path(argv[0]).parent_path(), ghoul::filesystem::FileSystem::Override::Yes ); @@ -1077,7 +1077,7 @@ int main(int argc, char* argv[]) { bool showHelp = parser.execute(); if (showHelp) { - parser.displayHelp(std::cout); + std::cout << parser.helpText(); exit(EXIT_SUCCESS); } // Take an actual copy of the arguments @@ -1092,28 +1092,32 @@ int main(int argc, char* argv[]) { std::string windowConfiguration; try { // Find configuration - std::string configurationFilePath = commandlineArguments.configurationName; - if (commandlineArguments.configurationName.empty()) { + std::filesystem::path configurationFilePath; + if (!commandlineArguments.configurationName.empty()) { + configurationFilePath = absPath(commandlineArguments.configurationName); + } + else { LDEBUG("Finding configuration"); configurationFilePath = configuration::findConfiguration(); } - configurationFilePath = absPath(configurationFilePath); - if (!FileSys.fileExists(configurationFilePath)) { - LFATALC("main", "Could not find configuration: " + configurationFilePath); + if (!std::filesystem::is_regular_file(configurationFilePath)) { + LFATALC( + "main", + fmt::format("Could not find configuration {}", configurationFilePath) + ); exit(EXIT_FAILURE); } - LINFO(fmt::format("Configuration Path: '{}'", configurationFilePath)); + LINFO(fmt::format("Configuration Path: {}", configurationFilePath)); // Register the base path as the directory where the configuration file lives - std::string base = ghoul::filesystem::File(configurationFilePath).directoryName(); - constexpr const char* BasePathToken = "${BASE}"; - FileSys.registerPathToken(BasePathToken, base); + std::filesystem::path base = configurationFilePath.parent_path(); + FileSys.registerPathToken("${BASE}", base); // Loading configuration from disk LDEBUG("Loading configuration from disk"); *global::configuration = configuration::loadConfigurationFromFile( - configurationFilePath, + configurationFilePath.string(), commandlineArguments.configurationOverride ); @@ -1217,7 +1221,7 @@ int main(int argc, char* argv[]) { // as well as the configuration file that sgct is supposed to use arguments.insert(arguments.begin(), argv[0]); arguments.insert(arguments.begin() + 1, "-config"); - arguments.insert(arguments.begin() + 2, absPath(windowConfiguration)); + arguments.insert(arguments.begin() + 2, absPath(windowConfiguration).string()); // Need to set this before the creation of the sgct::Engine @@ -1233,7 +1237,7 @@ int main(int argc, char* argv[]) { LDEBUG("Creating SGCT Engine"); std::vector arg(argv + 1, argv + argc); Configuration config = parseArguments(arg); - config::Cluster cluster = loadCluster(absPath(windowConfiguration)); + config::Cluster cluster = loadCluster(absPath(windowConfiguration).string()); Engine::Callbacks callbacks; callbacks.initOpenGL = mainInitFunc; diff --git a/apps/TaskRunner/main.cpp b/apps/TaskRunner/main.cpp index 7e038fe34d..1bd16c6394 100644 --- a/apps/TaskRunner/main.cpp +++ b/apps/TaskRunner/main.cpp @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -117,18 +116,21 @@ int main(int argc, char** argv) { // to make it possible to find other files in the same directory. FileSys.registerPathToken( "${BIN}", - ghoul::filesystem::File(absPath(argv[0])).directoryName(), + std::filesystem::path(argv[0]).parent_path(), ghoul::filesystem::FileSystem::Override::Yes ); - std::string configFile = configuration::findConfiguration(); + std::filesystem::path configFile = configuration::findConfiguration(); // Register the base path as the directory where the configuration file lives - std::string base = ghoul::filesystem::File(configFile).directoryName(); + std::filesystem::path base = configFile.parent_path(); constexpr const char* BasePathToken = "${BASE}"; FileSys.registerPathToken(BasePathToken, base); - *global::configuration = configuration::loadConfigurationFromFile(configFile, ""); + *global::configuration = configuration::loadConfigurationFromFile( + configFile.string(), + "" + ); openspace::global::openSpaceEngine->registerPathTokens(); global::openSpaceEngine->initialize(); @@ -160,7 +162,7 @@ int main(int argc, char** argv) { // If no task file was specified in as argument, run in CLI mode. LINFO(fmt::format("Task root: {}", absPath("${TASKS}"))); - FileSys.setCurrentDirectory(ghoul::filesystem::Directory(absPath("${TASKS}"))); + std::filesystem::current_path(absPath("${TASKS}")); std::cout << "TASK > "; while (std::cin >> tasksPath) { diff --git a/config/equirectangular_gui.xml b/config/equirectangular_gui.xml new file mode 100644 index 0000000000..98c6d545bb --- /dev/null +++ b/config/equirectangular_gui.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/assets/customization/globebrowsing.asset b/data/assets/customization/globebrowsing.asset index f5ad4193cd..fe03f650af 100644 --- a/data/assets/customization/globebrowsing.asset +++ b/data/assets/customization/globebrowsing.asset @@ -4,6 +4,7 @@ local CreateFocusNodes = false local AddMarsLayers = true local AddMoonLayers = true local AddMercuryLayers = true +local DataFolder = openspace.absPath('${BASE}/../OpenSpaceData') ---------------------------------------- -- If you add layers for different planets than listed here, be sure to add an @@ -25,11 +26,11 @@ local vrt_folders = { -- example: 'C:/OpenSpace/GlobeBrowsingData/Mars/CTX' -- We recommend using this folder for CTX - openspace.absPath('${BASE}/../OpenSpaceData/Mars/CTX'), + DataFolder .. '/Mars/CTX', -- if not and you have a custom path for CTX layers, enter it below '', -- We recommend using this folder for HiRISE - openspace.absPath('${BASE}/../OpenSpaceData/Mars/HiRISE'), + DataFolder .. '/Mars/HiRISE', -- if not and you have a custom path for HiRISE layers, enter it below '' }, @@ -39,8 +40,8 @@ local vrt_folders = { -- if areas overlap, images from the lower results will overwrite the images from former -- results -- example: 'C:/OpenSpace/GlobeBrowsingData/Moon' - openspace.absPath('${BASE}/../OpenSpaceData/Moon'), - openspace.absPath('${BASE}/../OpenSpaceData/Apollo'), + DataFolder .. '/Moon', + DataFolder .. '/Apollo', '' }, Mercury = { @@ -49,7 +50,7 @@ local vrt_folders = { -- if areas overlap, images from the lower results will overwrite the images from former -- results -- example: 'C:/OpenSpace/GlobeBrowsingData/Mercury' - openspace.absPath('${BASE}/../OpenSpaceData/Mercury'), + DataFolder .. '/Mercury', '' } } diff --git a/data/assets/examples/discs.asset b/data/assets/examples/discs.asset index 5dcdbc8924..9bb583e96d 100644 --- a/data/assets/examples/discs.asset +++ b/data/assets/examples/discs.asset @@ -1,8 +1,8 @@ local assetHelper = asset.require('util/asset_helper') -- @TODO (emmbr 2020-02-03) Potential threading issue later on? This will run on the main thread -local cyanTexture = openspace.createSingeColorImage("example_disc_color1", {0.0, 1.0, 1.0}) -local purpleTexture = openspace.createSingeColorImage("example_disc_color2", {0.5, 0.0, 0.5}) +local cyanTexture = openspace.createSingleColorImage("example_disc_color1", {0.0, 1.0, 1.0}) +local purpleTexture = openspace.createSingleColorImage("example_disc_color2", {0.5, 0.0, 0.5}) local BasicDisc = { Identifier = "BasicDisc", diff --git a/data/assets/examples/grids.asset b/data/assets/examples/grids.asset index 55468bd399..37ebad89e2 100644 --- a/data/assets/examples/grids.asset +++ b/data/assets/examples/grids.asset @@ -17,8 +17,7 @@ local radialGrid = { Color = { 0.6, 1.0, 0.7 }, LineWidth = 3.0, GridSegments = { 3, 4 }, - OuterRadius = 1.0, - InnerRadius = 0.2, + Radii = { 0.2, 1.0 }, Enabled = false }, GUI = { diff --git a/data/assets/examples/primitives.asset b/data/assets/examples/primitives.asset index d30014306d..23a64b1a0b 100644 --- a/data/assets/examples/primitives.asset +++ b/data/assets/examples/primitives.asset @@ -16,7 +16,7 @@ local circle = { LineWidth = 3.0, GridSegments = { 1, 1 }, CircleSegments = 64, - OuterRadius = 1.0 + Radii = { 0.0, 1.0 } }, GUI = { Name = "Example Circle", @@ -29,7 +29,7 @@ local ellipse = { Transform = { Scale = { Type = "NonUniformStaticScale", - Scale = {1.5, 1.0, 1.0} + Scale = { 1.5, 1.0, 1.0 } } }, Renderable = { @@ -38,7 +38,7 @@ local ellipse = { LineWidth = 3.0, GridSegments = { 1, 1 }, CircleSegments = 64, - OuterRadius = scale + Radii = { 0.0, scale } }, GUI = { Name = "Example Ellipse", diff --git a/data/assets/global/openspacebookmarks.asset b/data/assets/global/openspacebookmarks.asset index 1f6e91e96f..2d3893d1a3 100644 --- a/data/assets/global/openspacebookmarks.asset +++ b/data/assets/global/openspacebookmarks.asset @@ -15,7 +15,7 @@ local bookmarksCSV = asset.syncedResource({ local nodes = {} asset.onInitialize(function () - nodes = bookmarkHelper.getBookmarks('OpenSpace Bookmarks', bookmarksCSV .. '/bookmarks.csv.txt') + nodes = bookmarkHelper.getBookmarks('OpenSpace Bookmarks', bookmarksCSV .. '/bookmarks.csv') for _, n in ipairs(nodes) do openspace.addSceneGraphNode(n); end diff --git a/data/assets/scene/digitaluniverse/2dF.asset b/data/assets/scene/digitaluniverse/2dF.asset index 23f44a447c..4c881fe192 100644 --- a/data/assets/scene/digitaluniverse/2dF.asset +++ b/data/assets/scene/digitaluniverse/2dF.asset @@ -24,13 +24,13 @@ local object = { Color = { 1.0, 1.0, 1.0 }, Opacity = 1.0, File = speck .. "/2dF.speck", + Unit = "Mpc", Texture = textures .. "/point3A.png", ColorMap = speck .. "/2dF.cmap", ColorOption = { "redshift", "proximity" }, ColorRange = { { 0.0, 0.075 }, { 1.0, 25.0 } }, - Unit = "Mpc", ScaleFactor = 520.0, - BillboardMaxSize = 4.7, + BillboardMinMaxSize = { 0.0, 4.7 }, EnablePixelSizeControl = true }, GUI = { diff --git a/data/assets/scene/digitaluniverse/2mass.asset b/data/assets/scene/digitaluniverse/2mass.asset index f69905f48c..5e5cfa091d 100644 --- a/data/assets/scene/digitaluniverse/2mass.asset +++ b/data/assets/scene/digitaluniverse/2mass.asset @@ -24,15 +24,15 @@ local object = { Color = { 1.0, 0.4, 0.2 }, Opacity = 1.0, File = speck .. "/2MASS.speck", + Unit = "Mpc", Texture = textures .. "/point3A.png", ColorMap = speck .. "/lss.cmap", ColorOption = { "redshift", "prox5Mpc" }, ColorRange = { { 0.0, 0.075 }, { 1.0, 50.0 } }, - Unit = "Mpc", CorrectionSizeEndDistance = 20.6, CorrectionSizeFactor = 15.0, ScaleFactor = 510.78, - BillboardMaxSize = 11.15, + BillboardMinMaxSize = { 0.0, 11.15 }, EnablePixelSizeControl = true }, GUI = { diff --git a/data/assets/scene/digitaluniverse/6dF.asset b/data/assets/scene/digitaluniverse/6dF.asset index 8e45fad8b5..90f9ed8634 100644 --- a/data/assets/scene/digitaluniverse/6dF.asset +++ b/data/assets/scene/digitaluniverse/6dF.asset @@ -24,14 +24,14 @@ local object = { Color = { 1.0, 1.0, 0.0 }, Opacity = 1.0, File = speck .. "/6dF.speck", + Unit = "Mpc", Texture = textures .. "/point3A.png", ColorMap = speck .. "/6dF.cmap", ColorOption = { "redshift", "proximity" }, ColorRange = { { 0.0, 0.075 }, { 1.0, 10.0 } }, - Unit = "Mpc", ScaleFactor = 534.0, - BillboardMaxSize = 9.0, - EnablePixelSizeControl = true, + BillboardMinMaxSize = { 0.0, 9.0 }, + EnablePixelSizeControl = true }, GUI = { Name = "6dF Galaxies", diff --git a/data/assets/scene/digitaluniverse/abell.asset b/data/assets/scene/digitaluniverse/abell.asset index da0a05fd02..38863eba9d 100644 --- a/data/assets/scene/digitaluniverse/abell.asset +++ b/data/assets/scene/digitaluniverse/abell.asset @@ -27,10 +27,10 @@ local object = { File = speck .. "/abell.speck", Texture = textures .. "/point3A.png", LabelFile = speck .. "/abell.label", + Unit = "Mpc", TextColor = { 0.0, 0.8, 0.0 }, TextSize = 22, - TextMinSize = 10.0, - Unit = "Mpc", + TextMinMaxSize = { 10, 12 }, TransformationMatrix = { -0.7357425748, 0.67726129641, 0.0, 0.0, -0.074553778365, -0.080991471307, 0.9939225904, 0.0, @@ -38,7 +38,7 @@ local object = { 0.0, 0.0, 0.0, 1.0 }, ScaleFactor = 520.0, - BillboardMaxSize = 7.0, + BillboardMinMaxSize = { 0.0, 7.0 }, EnablePixelSizeControl = true }, GUI = { diff --git a/data/assets/scene/digitaluniverse/alternatestarlabels.asset b/data/assets/scene/digitaluniverse/alternatestarlabels.asset index 2a58510736..5e19b98207 100644 --- a/data/assets/scene/digitaluniverse/alternatestarlabels.asset +++ b/data/assets/scene/digitaluniverse/alternatestarlabels.asset @@ -17,11 +17,11 @@ local object = { Color = { 1.0, 1.0, 1.0 }, Opacity = 0.65, LabelFile = speck .. "/stars-altlbl.label", + Unit = "pc", TextColor = { 0.4, 0.4, 0.4 }, DrawLabels = true, TextSize = 14.7, - TextMinSize = 6.0, - Unit = "pc" + TextMinMaxSize = { 6, 20 } }, GUI = { Name = "Stars Labels - Alternate", diff --git a/data/assets/scene/digitaluniverse/clusters.asset b/data/assets/scene/digitaluniverse/clusters.asset index 6b8ef0e794..03c232a957 100644 --- a/data/assets/scene/digitaluniverse/clusters.asset +++ b/data/assets/scene/digitaluniverse/clusters.asset @@ -17,11 +17,11 @@ local object = { Color = { 1.0, 1.0, 1.0 }, Opacity = 0.65, LabelFile = speck .. "/galclust.label", + Unit = "Mpc", TextColor = { 1.0, 0.44, 0.0 }, DrawLabels = true, TextSize = 22, - TextMinSize = 8.0, - Unit = "Mpc", + TextMinMaxSize = { 8, 20 }, TransformationMatrix = { -0.7357425748, 0.67726129641, 0.0, 0.0, -0.074553778365, -0.080991471307, 0.9939225904, 0.0, diff --git a/data/assets/scene/digitaluniverse/constellations.asset b/data/assets/scene/digitaluniverse/constellations.asset index e043c1734e..a96db07f75 100644 --- a/data/assets/scene/digitaluniverse/constellations.asset +++ b/data/assets/scene/digitaluniverse/constellations.asset @@ -20,8 +20,7 @@ local constellationsExtragalactic = { TextColor = { 0.8, 0.8, 0.8 }, TextOpacity = 0.4, TextSize = 20.0, - TextMinSize = 20.0, - TextMaxSize = 30.0, + TextMinMaxSize = { 20, 30 }, MeshColor = { { 0.6, 0.4, 0.4 }, { 0.8, 0.0, 0.0 }, { 0.0, 0.3, 0.8 } }, Unit = "Mpc" }, @@ -42,8 +41,7 @@ local constellations = { TextColor = { 0.8, 0.8, 0.8 }, TextOpacity = 0.3, TextSize = 14.5, - TextMaxSize = 170.0, - TextMinSize = 8.0, + TextMinMaxSize = { 8, 170 }, MeshColor = { { 0.6, 0.4, 0.4 }, { 0.8, 0.0, 0.0 }, { 0.0, 0.3, 0.8 } }, Unit = "pc" }, diff --git a/data/assets/scene/digitaluniverse/deepsky.asset b/data/assets/scene/digitaluniverse/deepsky.asset index 7272af3a06..b8d91282b0 100644 --- a/data/assets/scene/digitaluniverse/deepsky.asset +++ b/data/assets/scene/digitaluniverse/deepsky.asset @@ -30,15 +30,12 @@ local deepSkyPoints = { --ColorOption = { "prox5Mpc" }, --ColorRange = { { 1.0, 30.0 } }, LabelFile = speck .. "/dso.label", + Unit = "pc", TextColor = { 0.1, 0.4, 0.6 }, TextSize = 20.50, - TextMinSize = 16.0, - Unit = "pc", - -- Fade in value in the same unit as "Unit" - --FadeInDistances = { 0.05, 1.0 }, - -- Max size in pixels - BillboardMaxSize = 8.22, - BillboardMinSize = 0.0, + TextMinMaxSize = { 16, 20 }, + --FadeInDistances = { 0.05, 1.0 }, -- Fade in value in the same unit as "Unit" + BillboardMinMaxSize = { 0.0, 8.22 }, -- in pixels --CorrectionSizeEndDistance = 22.0, --CorrectionSizeFactor = 10.45 EnablePixelSizeControl = true diff --git a/data/assets/scene/digitaluniverse/dwarfs.asset b/data/assets/scene/digitaluniverse/dwarfs.asset index 7919dc2038..c4922feb04 100644 --- a/data/assets/scene/digitaluniverse/dwarfs.asset +++ b/data/assets/scene/digitaluniverse/dwarfs.asset @@ -26,18 +26,18 @@ local object = { File = speck .. "/dwarfs.speck", Texture = textures .. "/point3.png", LabelFile = speck .. "/dwarfs.label", + Unit = "pc", ColorMap = speck .. "/dwarfs.cmap", ColorOption = { "typeindex" }, --ColorRange = { { 1.0, 4.0} }, TextColor = { 0.5, 0.1, 0.2 }, TextSize = 14.6, - TextMinSize = 10.0, + TextMinMaxSize = { 10, 20 }, ScaleFactor = 372.1, --CorrectionSizeEndDistance = 16.1, --CorrectionSizeFactor = 7.75, - BillboardMaxSize = 20.0, - EnablePixelSizeControl = true, - Unit = "pc" + BillboardMinMaxSize = { 0.0, 20.0 }, + EnablePixelSizeControl = true }, GUI = { Name = "Brown Dwarfs", diff --git a/data/assets/scene/digitaluniverse/exoplanets.asset b/data/assets/scene/digitaluniverse/exoplanets.asset index 4fb990c4e4..27ccda1a29 100644 --- a/data/assets/scene/digitaluniverse/exoplanets.asset +++ b/data/assets/scene/digitaluniverse/exoplanets.asset @@ -27,15 +27,14 @@ local object = { Texture = textures .. "/target-blue.png", File = speck .. "/expl.speck", LabelFile = speck .. "/expl.label", + Unit = "pc", ScaleFactor = 388.67923, TextColor = { 0.3, 0.3, 0.8 }, TextSize = 14.8, - TextMaxSize = 200.0, - TextMinSize = 10.0, + TextMinMaxSize = { 10, 100 }, CorrectionSizeEndDistance = 15.23, CorrectionSizeFactor = 13.3, - Unit = "pc", - BillboardMaxSize = 75.0, + BillboardMinMaxSize = { 0.0, 75.0 }, EnablePixelSizeControl = true, }, GUI = { diff --git a/data/assets/scene/digitaluniverse/globularclusters.asset b/data/assets/scene/digitaluniverse/globularclusters.asset index 179fe2cbc9..77e85d35c5 100644 --- a/data/assets/scene/digitaluniverse/globularclusters.asset +++ b/data/assets/scene/digitaluniverse/globularclusters.asset @@ -27,13 +27,12 @@ local object = { Texture = textures .. "/point4.png", PolygonSides = 5, LabelFile = speck .. "/gc.label", + Unit = "pc", TextColor = { 0.5, 0.5, 0.0 }, ScaleFactor = 431.0, TextSize = 16.7, - TextMinSize = 4.0, - TextMaxSize = 20, - Unit = "pc", - BillboardMaxSize = 500, + TextMinMaxSize = { 4, 20 }, + BillboardMinMaxSize = { 0.0, 500.0 }, EnablePixelSizeControl = true, }, GUI = { diff --git a/data/assets/scene/digitaluniverse/grids.asset b/data/assets/scene/digitaluniverse/grids.asset index 56caaca447..9ba8ad9a53 100644 --- a/data/assets/scene/digitaluniverse/grids.asset +++ b/data/assets/scene/digitaluniverse/grids.asset @@ -110,12 +110,11 @@ local eclipticLabels = { Color = { 1.0, 1.0, 1.0 }, Opacity = 0.65, LabelFile = speck .. "/eclip.label", + Unit = "pc", DrawLabels = true, TextColor = { 0.5, 0.5, 0.5 }, TextSize = 14.75, - TextMinSize = 1.3, - TextMaxSize = 50.0, - Unit = "pc", + TextMinMaxSize = { 1, 50 }, TransformationMatrix = { -0.05487554, 0.4941095, -0.8676661, 0.0, -0.9938214 , -0.1109906, -0.0003515167, 0.0, @@ -164,12 +163,11 @@ local equatorialLabels = { Color = { 1.0, 1.0, 1.0 }, Opacity = 0.65, LabelFile = speck .. "/radec.label", + Unit = "pc", DrawLabels = true, TextColor = { 0.5, 0.5, 0.5 }, TextSize = 14.5, - TextMinSize = 1.7, - TextMaxSize = 70.0, - Unit = "pc", + TextMinMaxSize = { 2, 70 }, TransformationMatrix = { -0.05487554, 0.4941095, -0.8676661, 0.0, -0.8734371 , -0.4448296, -0.1980764, 0.0, @@ -214,12 +212,11 @@ local galacticLabels = { Color = { 1.0, 1.0, 1.0 }, Opacity = 0.65, LabelFile = speck .. "/galac.label", + Unit = "pc", DrawLabels = true, TextColor = { 0.5, 0.5, 0.5 }, TextSize = 15.8, - TextMinSize = 0.5, - TextMaxSize = 100.0, - Unit = "pc" + TextMinMaxSize = { 1, 100 } }, GUI = { Name = "Galactic Sphere Labels", @@ -245,8 +242,7 @@ local plane1ld = { LabelFile = speck .. "/1ld.label", TextColor = { 0.0, 0.2, 0.5 }, TextSize = 10.3, - TextMinSize = 0.5, - TextMaxSize = 30.0, + TextMinMaxSize = { 0, 30 }, Unit = "Km" }, GUI = { @@ -273,8 +269,7 @@ local plane1lm = { LabelFile = speck .. "/1lm.label", TextColor = { 0.0, 0.2, 0.5 }, TextSize = 11.8, - TextMinSize = 0.5, - TextMaxSize = 30.0, + TextMinMaxSize = { 0, 30 }, Unit = "pc" }, GUI = { @@ -301,8 +296,7 @@ local plane1ly = { LabelFile = speck .. "/1ly.label", TextColor = { 0.0, 0.2, 0.5 }, TextSize = 13.0, - TextMinSize = 0.5, - TextMaxSize = 30.0, + TextMinMaxSize = { 0, 30 }, Unit = "pc" }, GUI = { @@ -329,8 +323,7 @@ local plane10ly = { LabelFile = speck .. "/10ly.label", TextColor = { 0.0, 0.2, 0.5 }, TextSize = 14.17, - TextMinSize = 0.5, - TextMaxSize = 30.0, + TextMinMaxSize = { 0, 30 }, Unit = "pc" }, GUI = { @@ -357,8 +350,7 @@ local plane100ly = { LabelFile = speck .. "/100ly.label", TextColor = { 0.0, 0.2, 0.5 }, TextSize = 15.0, - TextMinSize = 0.5, - TextMaxSize = 30.0, + TextMinMaxSize = { 0, 30 }, Unit = "pc" }, GUI = { @@ -385,8 +377,7 @@ local plane1kly = { LabelFile = speck .. "/1kly.label", TextColor = { 0.0, 0.2, 0.5 }, TextSize = 16.0, - TextMinSize = 0.5, - TextMaxSize = 30.0, + TextMinMaxSize = { 0, 30 }, Unit = "pc" }, GUI = { @@ -413,8 +404,7 @@ local plane10kly = { LabelFile = speck .. "/10kly.label", TextColor = { 0.0, 0.2, 0.5 }, TextSize = 17.25, - TextMinSize = 0.5, - TextMaxSize = 30.0, + TextMinMaxSize = { 0, 30 }, Unit = "pc" }, GUI = { @@ -434,8 +424,7 @@ local plane100kly = { LabelFile = speck .. "/100kly.label", TextColor = { 0.0, 0.2, 0.5 }, TextSize = 18.6, - TextMinSize = 0.5, - TextMaxSize = 30.0, + TextMinMaxSize = { 0, 30 }, Unit = "Mpc" }, GUI = { @@ -455,8 +444,7 @@ local plane1Mly = { LabelFile = speck .. "/1Mly.label", TextColor = { 0.0, 0.2, 0.5 }, TextSize = 19.6, - TextMinSize = 0.5, - TextMaxSize = 30.0, + TextMinMaxSize = { 0, 30 }, Unit = "Mpc" }, GUI = { @@ -476,8 +464,7 @@ local plane10Mly = { LabelFile = speck .. "/10Mly.label", TextColor = { 0.0, 0.2, 0.5 }, TextSize = 20.6, - TextMinSize = 0.5, - TextMaxSize = 30.0, + TextMinMaxSize = { 0, 30 }, Unit = "Mpc" }, GUI = { @@ -497,8 +484,7 @@ local plane100Mly = { LabelFile = speck .. "/100Mly.label", TextColor = { 0.0, 0.2, 0.5 }, TextSize = 21.6, - TextMinSize = 0.5, - TextMaxSize = 30.0, + TextMinMaxSize = { 0, 30 }, Unit = "Mpc" }, GUI = { @@ -518,8 +504,7 @@ local plane20Gly = { LabelFile = speck .. "/20Gly.label", TextColor = { 0.0, 0.2, 0.5 }, TextSize = 23.6, - TextMinSize = 0.5, - TextMaxSize = 30.0, + TextMinMaxSize = { 0, 30 }, Unit = "Mpc" }, GUI = { diff --git a/data/assets/scene/digitaluniverse/groups.asset b/data/assets/scene/digitaluniverse/groups.asset index 3653225819..ed426cbdd2 100644 --- a/data/assets/scene/digitaluniverse/groups.asset +++ b/data/assets/scene/digitaluniverse/groups.asset @@ -18,10 +18,10 @@ local object = { Opacity = 0.65, --ScaleFactor = 10.0, LabelFile = speck .. "/groups.label", + Unit = "Mpc", TextColor = { 0.1, 0.6, 0.2 }, TextSize = 21.5, - TextMinSize = 8.0, - Unit = "Mpc", + TextMinMaxSize = { 8, 20 }, DrawLabels = true, TransformationMatrix = { -0.7357425748, 0.67726129641, 0.0, 0.0, diff --git a/data/assets/scene/digitaluniverse/h2regions.asset b/data/assets/scene/digitaluniverse/h2regions.asset index 946c1fb9ca..9648f7d088 100644 --- a/data/assets/scene/digitaluniverse/h2regions.asset +++ b/data/assets/scene/digitaluniverse/h2regions.asset @@ -27,13 +27,12 @@ local object = { Texture = textures .."/point4.png", PolygonSides = 6, LabelFile = speck .. "/h2.label", + Unit = "pc", TextColor = { 0.5, 0.5, 0.5 }, ScaleFactor = 420, TextSize = 16.24, - TextMinSize = 4.0, - TextMaxSize = 20.0, - Unit = "pc", - BillboardMaxSize = 300.0, + TextMinMaxSize = { 4, 20 }, + BillboardMinMaxSize = { 0.0, 300.0 }, EnablePixelSizeControl = false }, GUI = { diff --git a/data/assets/scene/digitaluniverse/hdf.asset b/data/assets/scene/digitaluniverse/hdf.asset new file mode 100644 index 0000000000..51e30e3dfd --- /dev/null +++ b/data/assets/scene/digitaluniverse/hdf.asset @@ -0,0 +1,84 @@ +local assetHelper = asset.require('util/asset_helper') +local circle = asset.require('util/circle').circle + +local HUDFSpeck = asset.syncedResource({ + Name = "HUDF Speck", + Type = "HttpSynchronization", + Identifier = "digitaluniverse_hudf_speck", + Version = 1 +}) + +local ColorMap = asset.syncedResource({ + Name = "HUDF color map", + Type = "HttpSynchronization", + Identifier = "digitaluniverse_hudf_textures", + Version = 1 +}) + +local object = { + Identifier = "HubbleDeepField", + Renderable = { + Type = "RenderableBillboardsCloud", + Enabled = false, + Color = { 1.0, 1.0, 1.0 }, + Opacity = 1.0, + File = HUDFSpeck .. "/hudf.speck", + Texture = circle .. "/circle.png", + ColorMap = ColorMap .. "/hudf.cmap", + ColorOption = { "redshift", "proximity" }, + ColorRange = { { 0.0, 0.075 }, { 1.0, 25.0 } }, + Unit = "Mpc", + ScaleFactor = 520.0, + BillboardMaxSize = 4.7, + EnablePixelSizeControl = true + }, + GUI = { + Name = "Hubble Deep Field", + Path = "/Universe/Galaxies", + Description = [[ + Hubble Ultra Deep Field galaxy survey

+ Data Reference: Hubble Ultra Deep Field 2012 program (Ellis+, Koekemoer+, 2013) + ]], + } +} + +assetHelper.registerSceneGraphNodesAndExport(asset, { object }) + +asset.meta = { + Name = "Hubble Ultra Deep Field", + Version = "1.1", + Description = "Hubble Ultra Deep Field galaxy survey", + Author = "Frank Summers (STScI), Brian Abbott (AMNH)", + Identifiers = {"HubbleDeepField"}, + URL = "http://www.haydenplanetarium.org/universe", + License = [[ + Copyright (c) American Museum of Natural History. All rights reserved.

+ + Downloading the Atlas:
+ AMNH offers the Atlas free of charge via our website, http://www.haydenplanetarium.org/. + The User is free to download and/or duplicate verbatim copies of the Atlas provided this + license and copyright information accompany the Atlas.

+ + Modifying the Atlas:
+ The user is free to modify the Atlas by either adding data or altering existing data, + provided it is for personal use only. Once the user modifies the Atlas, it is no longer + part of AMNH's Atlas and cannot be used publicly alongside or within the Atlas without + written permission from AMNH.

+ + Distributing the Atlas:
+ The user is forbidden to distribute and use the Atlas for profit, as part of a software + and/or production system that will subsequently be redistributed, or for public consumption + (via print, electronic media, or broadcast/produced pieces) without written permission + from AMNH.

+ + Neither the names of American Museum of Natural History and Hayden Planetarium nor the names + of their contributors may be used to endorse or promote products derived from this Atlas + without specific, prior written permission.

+ + The Atlas is free but is offered WITHOUT ANY WARRANTY of any kind. We provide the Atlas as + is and take no responsibility for any damage resulting from the use of this Atlas. The entire + risk as to the quality and performance of this product is with the user.

+ + For more information, please visit http://www.haydenplanetarium.org/universe + ]] +} diff --git a/data/assets/scene/digitaluniverse/kepler.asset b/data/assets/scene/digitaluniverse/kepler.asset index 38ce9309a9..d07868db17 100644 --- a/data/assets/scene/digitaluniverse/kepler.asset +++ b/data/assets/scene/digitaluniverse/kepler.asset @@ -25,11 +25,11 @@ local object = { Opacity = 0.99, ScaleFactor = 410.0, File = speck .. "/kepler.speck", + Unit = "pc", Texture = textures .. "/halo.png", CorrectionSizeEndDistance = 15.86, CorrectionSizeFactor = 8.59, - Unit = "pc", - BillboardMaxSize = 30.0, + BillboardMinMaxSize = { 0.0, 30.0 }, EnablePixelSizeControl = true }, GUI = { diff --git a/data/assets/scene/digitaluniverse/localdwarfs.asset b/data/assets/scene/digitaluniverse/localdwarfs.asset index 8bd7fddce6..ac23ad0dc6 100644 --- a/data/assets/scene/digitaluniverse/localdwarfs.asset +++ b/data/assets/scene/digitaluniverse/localdwarfs.asset @@ -29,12 +29,12 @@ local object = { Texture = textures .. "/point4.png", PolygonSides = 12, LabelFile = speck .. "/localgroup.label", + Unit = "Mpc", TextColor = { 0.3, 0.3, 1.0 }, ScaleFactor = 465, TextSize = 18.3, - TextMinSize = 7.3, - Unit = "Mpc", - BillboardMaxSize = 20.0, + TextMinMaxSize = { 7, 20 }, + BillboardMinMaxSize = { 0.0, 20.0 }, EnablePixelSizeControl = true }, GUI = { diff --git a/data/assets/scene/digitaluniverse/milkyway_label.asset b/data/assets/scene/digitaluniverse/milkyway_label.asset index 20fb25276e..60908e0a35 100644 --- a/data/assets/scene/digitaluniverse/milkyway_label.asset +++ b/data/assets/scene/digitaluniverse/milkyway_label.asset @@ -20,19 +20,18 @@ local homeLabel = { ScaleFactor = 500.0, DrawLabels = true, LabelFile = homespeck .. "/home.label", + Unit = "Mpc", TextColor = { 0.8, 0.8, 0.8 }, TextSize = 20.50, - TextMinSize = 16.0, + TextMinMaxSize = { 16, 20 }, TransformationMatrix = { -0.7357425748, 0.67726129641, 0.0, 0.0, -0.074553778365, -0.080991471307, 0.9939225904, 0.0, 0.67314530211, 0.73127116582, 0.11008126223, 0.0, 0.0, 0.0, 0.0, 1.0 }, - Unit = "Mpc", FadeInDistances = { 0.05, 1.0 }, - BillboardMaxSize = 8.22, - BillboardMinSize = 0.0, + BillboardMinMaxSize = { 0.0, 8.22 }, EnablePixelSizeControl = true }, GUI = { diff --git a/data/assets/scene/digitaluniverse/obassociations.asset b/data/assets/scene/digitaluniverse/obassociations.asset index 3814638db9..1339706042 100644 --- a/data/assets/scene/digitaluniverse/obassociations.asset +++ b/data/assets/scene/digitaluniverse/obassociations.asset @@ -24,20 +24,19 @@ local object = { Color = { 1.0, 1.0, 1.0 }, ColorMap = speck .. "/ob.cmap", ColorOption = { "arm" }, - SizeOption = {"diameter"}, + SizeOption = { "diameter" }, ExactColorMap = true, Opacity = 0.7, File = speck .. "/ob.speck", + Unit = "pc", Texture = textures .. "/point4.png", PolygonSides = 7, LabelFile = speck .. "/ob.label", TextColor = { 0.4, 0.5, 1.0 }, ScaleFactor = 390.0, TextSize = 16.24, - TextMinSize = 4.50, - TextMaxSize = 25, - Unit = "pc", - BillboardMaxSize = 450.0, + TextMinMaxSize = { 4, 25 }, + BillboardMinMaxSize = { 0.0, 450.0 }, EnablePixelSizeControl = true }, GUI = { diff --git a/data/assets/scene/digitaluniverse/openclusters.asset b/data/assets/scene/digitaluniverse/openclusters.asset index 86bbc5b5c9..bb4ae711e5 100644 --- a/data/assets/scene/digitaluniverse/openclusters.asset +++ b/data/assets/scene/digitaluniverse/openclusters.asset @@ -24,16 +24,15 @@ local object = { Color = { 0.1, 0.8, 0.4 }, Opacity = 0.5, File = speck .. "/oc.speck", + Unit = "pc", Texture = textures .. "/point4.png", PolygonSides = 12, TextColor = { 0.05, 0.4, 0.2 }, LabelFile = speck .. "/oc.label", ScaleFactor = 405.75, TextSize = 15.5, - TextMinSize = 4.5, - TextMaxSize = 30.0, - Unit = "pc", - BillboardMaxSize = 604, + TextMinMaxSize = { 4, 30 }, + BillboardMinMaxSize = { 0.0, 604.0 }, EnablePixelSizeControl = true }, GUI = { diff --git a/data/assets/scene/digitaluniverse/planetarynebulae.asset b/data/assets/scene/digitaluniverse/planetarynebulae.asset index 7fb7d217ad..c2a0c107d2 100644 --- a/data/assets/scene/digitaluniverse/planetarynebulae.asset +++ b/data/assets/scene/digitaluniverse/planetarynebulae.asset @@ -27,13 +27,12 @@ local object = { Texture = textures .. "/point4.png", PolygonSides = 3, LabelFile = speck .. "/pn.label", + Unit = "pc", TextColor = { 0.25, 0.25, 0.65 }, ScaleFactor = 425.0, TextSize = 16.24, - TextMinSize = 4.5, - TextMaxSize = 25.0, - Unit = "pc", - BillboardMaxSize = 500, + TextMinMaxSize = { 4, 25 }, + BillboardMinMaxSize = { 0.0, 500.0 }, EnablePixelSizeControl = true }, GUI = { diff --git a/data/assets/scene/digitaluniverse/pulsars.asset b/data/assets/scene/digitaluniverse/pulsars.asset index 8defe08274..6e122a3336 100644 --- a/data/assets/scene/digitaluniverse/pulsars.asset +++ b/data/assets/scene/digitaluniverse/pulsars.asset @@ -27,13 +27,12 @@ local object = { Texture = textures .. "/point4.png", PolygonSides = 4, LabelFile = speck .. "/pulsar.label", + Unit = "pc", TextColor = { 0.7, 0.2, 0.2 }, ScaleFactor = 424, TextSize = 15.77, - TextMinSize = 4, - TextMaxSize = 20.0, - Unit = "pc", - BillboardMaxSize = 500, + TextMinMaxSize = { 4, 20 }, + BillboardMinMaxSize = { 0.0, 500.0 }, EnablePixelSizeControl = false }, GUI = { diff --git a/data/assets/scene/digitaluniverse/quasars.asset b/data/assets/scene/digitaluniverse/quasars.asset index 69336ed468..3ec14ef05b 100644 --- a/data/assets/scene/digitaluniverse/quasars.asset +++ b/data/assets/scene/digitaluniverse/quasars.asset @@ -27,11 +27,8 @@ local object = { Texture = textures .. "/point3A.png", Unit = "Mpc", ScaleFactor = 540.9, - -- Fade in value in the same unit as "Unit" - FadeInDistances = { 1000.0, 10000.0 }, - BillboardMaxSize = 30.0, - BillboardMinSize = 0.0, - BillboardMaxSize = 11.1, + FadeInDistances = { 1000.0, 10000.0 }, -- Fade in value in the same unit as "Unit" + BillboardMinMaxSize = { 0.0, 11.1 }, EnablePixelSizeControl = true }, GUI = { diff --git a/data/assets/scene/digitaluniverse/sdss.asset b/data/assets/scene/digitaluniverse/sdss.asset index 61914b1951..de7391eba0 100644 --- a/data/assets/scene/digitaluniverse/sdss.asset +++ b/data/assets/scene/digitaluniverse/sdss.asset @@ -30,16 +30,12 @@ local object = { ColorRange = { { 0.0, 0.075 }, { 1.0, 50.0 } }, Texture = textures .. "/point3A.png", Unit = "Mpc", - -- Fade in value in the same unit as "Unit" - FadeInDistances = { 220.0, 650.0 }, - BillboardMaxSize = 50.0, - BillboardMinSize = 0.0, + FadeInDistances = { 220.0, 650.0 }, -- Fade in value in the same unit as "Unit" + BillboardMinMaxSize = { 0.0, 5.5 }, CorrectionSizeEndDistance = 20.65, CorrectionSizeFactor = 10.41, TextSize = 14.8, - TextMinSize = 10.0, - TextMaxSize = 50.0, - BillboardMaxSize = 5.5, + TextMinMaxSize = { 10, 50 }, EnablePixelSizeControl = true }, GUI = { diff --git a/data/assets/scene/digitaluniverse/starlabels.asset b/data/assets/scene/digitaluniverse/starlabels.asset index 8a8c99105f..387975abbd 100644 --- a/data/assets/scene/digitaluniverse/starlabels.asset +++ b/data/assets/scene/digitaluniverse/starlabels.asset @@ -17,12 +17,11 @@ local object = { Color = { 1.0, 1.0, 1.0 }, Opacity = 0.65, LabelFile = speck .. "/stars.label", + Unit = "pc", TextColor = { 0.4, 0.4, 0.4 }, DrawLabels = true, TextSize = 14.7, - TextMinSize = 6.0, - TextMaxSize = 50.0, - Unit = "pc" + TextMinMaxSize = { 6, 50 } }, GUI = { Name = "Stars Labels", diff --git a/data/assets/scene/digitaluniverse/starorbits.asset b/data/assets/scene/digitaluniverse/starorbits.asset index 4287107301..d79d96d2fa 100644 --- a/data/assets/scene/digitaluniverse/starorbits.asset +++ b/data/assets/scene/digitaluniverse/starorbits.asset @@ -20,10 +20,8 @@ local sunOrbit = { File = speck .. "/starorbits-Sun.speck", MeshColor = {{ 1.0, 0.65, 0.0 }}, --LabelFile = speck .. "/1ld.label", - TextColor = { 0.0, 0.2, 0.5 }, - TextSize = 10.3, - TextMinSize = 0.5, - TextMaxSize = 30.0, + -- TextColor = { 0.0, 0.2, 0.5 }, + -- TextMinMaxSize = { 0, 30 }, Unit = "pc" }, GUI = { @@ -43,10 +41,9 @@ local barnardsOrbit = { File = speck .. "/starorbits-BarnardsStar.speck", MeshColor = {{0.39, 0.58, 0.93}}, --LabelFile = speck .. "/1ld.label", - TextColor = { 0.0, 0.2, 0.5 }, - TextSize = 10.3, - TextMinSize = 0.5, - TextMaxSize = 30.0, + -- TextColor = { 0.0, 0.2, 0.5 }, + -- TextSize = 10.3, + -- TextMinMaxSize = { 0, 30 }, Unit = "pc" }, GUI = { @@ -66,10 +63,9 @@ local kapteynsOrbit = { File = speck .. "/starorbits-KapteynsStar.speck", MeshColor = {{0.6, 0.6, 0.6}}, --LabelFile = speck .. "/1ld.label", - TextColor = { 0.0, 0.2, 0.5 }, - TextSize = 10.3, - TextMinSize = 0.5, - TextMaxSize = 30.0, + -- TextColor = { 0.0, 0.2, 0.5 }, + -- TextSize = 10.3, + -- TextMinMaxSize = { 0, 30 }, Unit = "pc" }, GUI = { @@ -89,10 +85,9 @@ local lacaille9352Orbit = { File = speck .. "/starorbits-Lacaille9352.speck", MeshColor = {{0.58, 0.0, 0.83}}, --LabelFile = speck .. "/1ld.label", - TextColor = { 0.0, 0.2, 0.5 }, - TextSize = 10.3, - TextMinSize = 0.5, - TextMaxSize = 30.0, + -- TextColor = { 0.0, 0.2, 0.5 }, + -- TextSize = 10.3, + -- TextMinMaxSize = { 0, 30 }, Unit = "pc" }, GUI = { @@ -112,10 +107,9 @@ local lSR1826Orbit = { File = speck .. "/starorbits-LSR1826+3014.speck", MeshColor = {{0.0, 0.39, 0.0}}, --LabelFile = speck .. "/1ld.label", - TextColor = { 0.0, 0.2, 0.5 }, - TextSize = 10.3, - TextMinSize = 0.5, - TextMaxSize = 30.0, + -- TextColor = { 0.0, 0.2, 0.5 }, + -- TextSize = 10.3, + -- TextMinMaxSize = { 0, 30 }, Unit = "pc" }, GUI = { @@ -135,10 +129,9 @@ local lSRJ0822Orbit = { File = speck .. "/starorbits-LSRJ0822+1700.speck", MeshColor = {{0.5, 1.0, 0.0}}, --LabelFile = speck .. "/1ld.label", - TextColor = { 0.0, 0.2, 0.5 }, - TextSize = 10.3, - TextMinSize = 0.5, - TextMaxSize = 30.0, + -- TextColor = { 0.0, 0.2, 0.5 }, + -- TextSize = 10.3, + -- TextMinMaxSize = { 0, 30 }, Unit = "pc" }, GUI = { @@ -158,10 +151,9 @@ local pM_J13420Orbit = { File = speck .. "/starorbits-PM_J13420-3415.speck", MeshColor = {{0.70, 0.13, 0.13}}, --LabelFile = speck .. "/1ld.label", - TextColor = { 0.0, 0.2, 0.5 }, - TextSize = 10.3, - TextMinSize = 0.5, - TextMaxSize = 30.0, + -- TextColor = { 0.0, 0.2, 0.5 }, + -- TextSize = 10.3, + -- TextMinMaxSize = { 0, 30 }, Unit = "pc" }, GUI = { diff --git a/data/assets/scene/digitaluniverse/stars.asset b/data/assets/scene/digitaluniverse/stars.asset index 3103cd6c9a..db0ac4adb7 100644 --- a/data/assets/scene/digitaluniverse/stars.asset +++ b/data/assets/scene/digitaluniverse/stars.asset @@ -1,13 +1,7 @@ local assetHelper = asset.require('util/asset_helper') -local colorLUT = asset.require('./stars_colormap').BvColorLUT - -local textures = asset.syncedResource({ - Name = "Stars Textures", - Type = "HttpSynchronization", - Identifier = "stars_textures", - Version = 1 -}) +local colormaps = asset.require('./stars_colormap').ColorMaps +local textures = asset.require('./stars_textures').textures local speck = asset.syncedResource({ Name = "Stars Speck Files", @@ -30,10 +24,21 @@ local stars = { File = speck .. "/stars.speck", Texture = textures .. "/halo.png", --ShapeTexture = textures .. "/disc.png", - ColorMap = colorLUT .. "/colorbv.cmap", + ColorMap = colormaps .. "/colorbv.cmap", + OtherDataColorMap = colormaps .. "/viridis.cmap", MagnitudeExponent = 6.2, SizeComposition = "Distance Modulus", - RenderMethod = "Texture Based" -- or PSF + RenderMethod = "Texture Based", -- or PSF + DataMapping = { + Bv = "colorb_v", + Luminance = "lum", + AbsoluteMagnitude = "absmag", + ApparentMagnitude = "appmag", + Vx = "vx", + Vy = "vy", + Vz = "vz", + Speed = "speed" + } }, GUI = { Name = "Stars", @@ -55,12 +60,22 @@ local sunstar = { File = sunspeck .. "/sunstar.speck", Texture = textures .. "/halo.png", --ShapeTexture = textures .. "/disc.png", - ColorMap = colorLUT .. "/colorbv.cmap", + ColorMap = colormaps .. "/colorbv.cmap", MagnitudeExponent = 6.2, SizeComposition = "Distance Modulus", RenderMethod = "Texture Based", -- or PSF FadeInDistances = { 0.0001, 0.1 }, - RenderableType = "PostDeferredTransparent" + RenderableType = "PostDeferredTransparent", + DataMapping = { + Bv = "colorb_v", + Luminance = "lum", + AbsoluteMagnitude = "absmag", + ApparentMagnitude = "appmag", + Vx = "vx", + Vy = "vy", + Vz = "vz", + Speed = "speed", + } }, GUI = { Name = "Sun", diff --git a/data/assets/scene/digitaluniverse/stars_colormap.asset b/data/assets/scene/digitaluniverse/stars_colormap.asset index eb4cbc22e3..d8aaa83f1d 100644 --- a/data/assets/scene/digitaluniverse/stars_colormap.asset +++ b/data/assets/scene/digitaluniverse/stars_colormap.asset @@ -1,20 +1,20 @@ local assetHelper = asset.require('util/asset_helper') -local BvColorLUT = asset.syncedResource({ +local colormaps = asset.syncedResource({ Name = "Stars Color Table", Type = "HttpSynchronization", Identifier = "stars_colormap", Version = 2 }) -asset.export("BvColorLUT", BvColorLUT) +asset.export("ColorMaps", colormaps) asset.meta = { - Name = "Stars B-V Colormap", + Name = "Star Colormaps", Version = "2.0", - Description = [[A lookup table that maps a B-V color index to an RGB color. - The B-V values are in the range (-0.4, 2.0) and each line maps a value - in that range to a color]], + Description = [[Lookup tables used for star datasets, one of the tables map a B-V color + index to an RGB color. The B-V values are in the range (-0.4, 2.0) and each line maps + a value in that range to a color. The other table is the commonly used viridis map]], Author = "OpenSpace Team", URL = "https://www.amnh.org/research/hayden-planetarium/digital-universe", License = "AMNH Digital Universe" diff --git a/data/assets/scene/digitaluniverse/stars_textures.asset b/data/assets/scene/digitaluniverse/stars_textures.asset new file mode 100644 index 0000000000..d57f6d0907 --- /dev/null +++ b/data/assets/scene/digitaluniverse/stars_textures.asset @@ -0,0 +1,20 @@ +local assetHelper = asset.require('util/asset_helper') + +local textures = asset.syncedResource({ + Name = "Stars Textures", + Type = "HttpSynchronization", + Identifier = "stars_textures", + Version = 1 +}) + +asset.export("textures", textures) + +asset.meta = { + Name = "Star Textures", + Version = "1.0", + Description = [[Square textures used to represent stars when applied to camera-facing bil;board]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT License" +} + diff --git a/data/assets/scene/digitaluniverse/superclusters.asset b/data/assets/scene/digitaluniverse/superclusters.asset index 85546e608e..facc29d313 100644 --- a/data/assets/scene/digitaluniverse/superclusters.asset +++ b/data/assets/scene/digitaluniverse/superclusters.asset @@ -27,13 +27,13 @@ local object = { File = speck .. "/superclust.speck", Texture = textures .. "/point3A.png", LabelFile = speck .. "/superclust.label", + Unit = "Mpc", TextColor = { 0.9, 0.9, 0.9 }, ScaleFactor = 531.0, TextSize = 22.44, - TextMinSize = 8.0, - Unit = "Mpc", + TextMinMaxSize = { 8, 20 }, DrawLabels = true, - --BillboardMaxSize = 7.2, + --BillboardMinMaxSize = { 0.0, 7.2 }, EnablePixelSizeControl = true }, GUI = { diff --git a/data/assets/scene/digitaluniverse/supernovaremnants.asset b/data/assets/scene/digitaluniverse/supernovaremnants.asset index 20a4f8f557..efa2c2844f 100644 --- a/data/assets/scene/digitaluniverse/supernovaremnants.asset +++ b/data/assets/scene/digitaluniverse/supernovaremnants.asset @@ -27,15 +27,14 @@ local object = { Texture = textures .. "/point4.png", PolygonSides = 7, LabelFile = speck .. "/snr.label", + Unit = "pc", TextColor = { 0.6, 0.46, 0.0 }, ScaleFactor = 424, TextSize = 16.44, - TextMinSize = 4.0, - TextMaxSize = 200.0, + TextMinMaxSize = { 4, 100 }, --CorrectionSizeEndDistance = 17.5, --CorrectionSizeFactor = 13.96, - Unit = "pc", - BillboardMaxSize = 500, + BillboardMinMaxSize = { 0.0, 500.0 }, EnablePixelSizeControl = true }, GUI = { diff --git a/data/assets/scene/digitaluniverse/tully.asset b/data/assets/scene/digitaluniverse/tully.asset index 21e65f5ed5..d06deb8a4c 100644 --- a/data/assets/scene/digitaluniverse/tully.asset +++ b/data/assets/scene/digitaluniverse/tully.asset @@ -33,21 +33,18 @@ local tullyPoints = { ColorRange = { { 1.0, 30.0 } }, LabelFile = speck .. "/tully.label", DrawLabels = false, + Unit = "Mpc", TextColor = { 0.7, 0.7, 0.7 }, TextSize = 19.36, - TextMinSize = 8.2, + TextMinMaxSize = { 8, 20 }, TransformationMatrix = { -0.7357425748, 0.67726129641, 0.0, 0.0, -0.074553778365, -0.080991471307, 0.9939225904, 0.0, 0.67314530211, 0.73127116582, 0.11008126223, 0.0, 0.0, 0.0, 0.0, 1.0 }, - Unit = "Mpc", - -- Fade in value in the same unit as "Unit" - FadeInDistances = { 0.001, 1.0 }, - -- Max size in pixels - BillboardMaxSize = 7, - BillboardMinSize = 0, + FadeInDistances = { 0.001, 1.0 }, -- Fade in value in the same unit as "Unit" + BillboardMinMaxSize = { 0.0, 7.0 }, -- in pixels --CorrectionSizeEndDistance = 22.0, --CorrectionSizeFactor = 10.45 EnablePixelSizeControl = true diff --git a/data/assets/scene/digitaluniverse/voids.asset b/data/assets/scene/digitaluniverse/voids.asset index 20538ee161..269ae7c7e7 100644 --- a/data/assets/scene/digitaluniverse/voids.asset +++ b/data/assets/scene/digitaluniverse/voids.asset @@ -19,10 +19,10 @@ local object = { Color = { 1.0, 1.0, 1.0 }, Opacity = 0.65, LabelFile = speck .. "/voids.label", + Unit = "Mpc", TextColor = { 0.296, 0.629, 1.0 }, TextSize = 20.9, - TextMinSize = 8.0, - Unit = "Mpc" + TextMinMaxSize = { 8, 20 } }, GUI = { Name = "Voids", diff --git a/data/assets/scene/milkyway/exoplanets/exoplanets_data.asset b/data/assets/scene/milkyway/exoplanets/exoplanets_data.asset index 73d4f033a5..45597c4302 100644 --- a/data/assets/scene/milkyway/exoplanets/exoplanets_data.asset +++ b/data/assets/scene/milkyway/exoplanets/exoplanets_data.asset @@ -1,4 +1,4 @@ -local bvColorLUT = asset.require('scene/digitaluniverse/stars_colormap').BvColorLUT +local colormaps = asset.require('scene/digitaluniverse/stars_colormap').ColorMaps local DataPath = asset.syncedResource({ Name = "Exoplanet Data Files", @@ -15,7 +15,7 @@ asset.onInitialize(function () p = "Modules.Exoplanets.BvColormap"; if (openspace.getPropertyValue(p) == "") then - openspace.setPropertyValueSingle(p, bvColorLUT .. "/colorbv.cmap") + openspace.setPropertyValueSingle(p, colormaps .. "/colorbv.cmap") end end) diff --git a/data/assets/scene/milkyway/gaia/apogee.asset b/data/assets/scene/milkyway/gaia/apogee.asset index efa58038ff..b6abe3159a 100644 --- a/data/assets/scene/milkyway/gaia/apogee.asset +++ b/data/assets/scene/milkyway/gaia/apogee.asset @@ -1,14 +1,9 @@ local assetHelper = asset.require('util/asset_helper') +local colorLUT = asset.require('scene/digitaluniverse/stars_colormap').ColorMaps +local textures = asset.require('scene/digitaluniverse/stars_textures').textures -local textures = asset.syncedResource({ - Name = "Stars Textures", - Type = "HttpSynchronization", - Identifier = "stars_textures", - Version = 1 -}) - local speck = asset.syncedResource({ Name = "Apogee Speck Files", Type = "HttpSynchronization", @@ -16,13 +11,6 @@ local speck = asset.syncedResource({ Version = 1 }) -local colorLUT = asset.syncedResource({ - Name = "Stars Color Table", - Type = "HttpSynchronization", - Identifier = "stars_colormap", - Version = 2 -}) - local gaia_abundance_apogee = { Identifier = "Gaia Abundance Apogee", Renderable = { @@ -39,7 +27,17 @@ local gaia_abundance_apogee = { ColorMap = colorLUT .. "/colorbv.cmap", OtherDataColorMap = colorLUT .. "/viridis.cmap", StaticFilter = -9999, - StaticFilterReplacement = 0.0 + StaticFilterReplacement = 0.0, + DataMapping = { + Bv = "colorb_v", + Luminance = "lum", + AbsoluteMagnitude = "absmag", + ApparentMagnitude = "appmag", + Vx = "vx", + Vy = "vy", + Vz = "vz", + Speed = "speed" + } }, GUI = { Path = "/Milky Way/Gaia" diff --git a/data/assets/scene/milkyway/gaia/gaiastars.asset b/data/assets/scene/milkyway/gaia/gaiastars.asset index 997eaa55e5..5eeeb15162 100644 --- a/data/assets/scene/milkyway/gaia/gaiastars.asset +++ b/data/assets/scene/milkyway/gaia/gaiastars.asset @@ -1,18 +1,7 @@ local assetHelper = asset.require("util/asset_helper") -local textures = asset.syncedResource({ - Name = "Stars Textures", - Type = "HttpSynchronization", - Identifier = "stars_textures", - Version = 1 -}) - -local colorLUT = asset.syncedResource({ - Name = "Stars Color Table", - Type = "HttpSynchronization", - Identifier = "stars_colormap", - Version = 1 -}) +local colorLUT = asset.require('scene/digitaluniverse/stars_colormap').ColorMaps +local textures = asset.require('scene/digitaluniverse/stars_textures').textures -- Download a preprocessed binary octree of Radial Velocity subset values per star (preprocessed into 8 binary files). local starsFolder = asset.syncedResource({ diff --git a/data/assets/scene/milkyway/gaia/galah.asset b/data/assets/scene/milkyway/gaia/galah.asset index c9163b2ff3..f4c814c20a 100644 --- a/data/assets/scene/milkyway/gaia/galah.asset +++ b/data/assets/scene/milkyway/gaia/galah.asset @@ -1,13 +1,7 @@ local assetHelper = asset.require('util/asset_helper') - - -local textures = asset.syncedResource({ - Name = "Stars Textures", - Type = "HttpSynchronization", - Identifier = "stars_textures", - Version = 1 -}) +local colorLUT = asset.require('scene/digitaluniverse/stars_colormap').ColorMaps +local textures = asset.require('scene/digitaluniverse/stars_textures').textures local speck = asset.syncedResource({ Name = "Galah Speck Files", @@ -16,12 +10,6 @@ local speck = asset.syncedResource({ Version = 1 }) -local colorLUT = asset.syncedResource({ - Name = "Stars Color Table", - Type = "HttpSynchronization", - Identifier = "stars_colormap", - Version = 2 -}) local gaia_abundance_galah = { Identifier = "Gaia Abundance Galah", @@ -39,7 +27,17 @@ local gaia_abundance_galah = { ColorMap = colorLUT .. "/colorbv.cmap", OtherDataColorMap = colorLUT .. "/viridis.cmap", StaticFilter = -9999, - StaticFilterReplacement = 0.0 + StaticFilterReplacement = 0.0, + DataMapping = { + Bv = "colorb_v", + Luminance = "lum", + AbsoluteMagnitude = "absmag", + ApparentMagnitude = "appmag", + Vx = "vx", + Vy = "vy", + Vz = "vz", + Speed = "speed" + } }, GUI = { Path = "/Milky Way/Gaia" diff --git a/data/assets/scene/milkyway/milkyway/volume.asset b/data/assets/scene/milkyway/milkyway/volume.asset index 76103612b3..0e54bd1535 100644 --- a/data/assets/scene/milkyway/milkyway/volume.asset +++ b/data/assets/scene/milkyway/milkyway/volume.asset @@ -32,16 +32,16 @@ local MilkyWayVolumeGalaxy = { Rotation = { 3.1415926, 3.1248, 4.45741 }, Volume = { Type = "Volume", - Filename = data .. "/MilkyWayRGBAVolume1024x1024x128.raw", + Filename = openspace.absPath(data .. "/MilkyWayRGBAVolume1024x1024x128.raw"), Dimensions = { 1024, 1024, 128 }, Size = { 1.2E21, 1.2E21, 0.15E21 }, Downscale = 0.4, }, Points = { Type = "Points", - Filename = data .. "/MilkyWayPoints.off", + Filename = openspace.absPath(data .. "/MilkyWayPoints.off"), EnabledPointsRatio = 0.3, - Texture = data .. "/halo.png" + Texture = openspace.absPath(data .. "/halo.png") } }, GUI = { diff --git a/data/assets/scene/milkyway/objects/orionnebula/cluster.asset b/data/assets/scene/milkyway/objects/orionnebula/cluster.asset index 2325788c80..0abd320818 100644 --- a/data/assets/scene/milkyway/objects/orionnebula/cluster.asset +++ b/data/assets/scene/milkyway/objects/orionnebula/cluster.asset @@ -19,7 +19,17 @@ local OrionClusterStars = { ColorMap = sync .. "/colorbv.cmap", MagnitudeExponent = 5.02, SizeComposition = "Distance Modulus", - RenderMethod = "Texture Based" + RenderMethod = "Texture Based", + DataMapping = { + Bv = "colorb_v", + Luminance = "lum", + AbsoluteMagnitude = "absmag", + ApparentMagnitude = "appmag", + Vx = "vx", + Vy = "vy", + Vz = "vz", + Speed = "speed" + } }, GUI = { Name = "Orion Nebula Star Cluster", diff --git a/data/assets/scene/milkyway/stars/denver.asset b/data/assets/scene/milkyway/stars/denver.asset index a1c2fbef55..4dc1621909 100644 --- a/data/assets/scene/milkyway/stars/denver.asset +++ b/data/assets/scene/milkyway/stars/denver.asset @@ -32,7 +32,17 @@ local object = { ColorMap = colorLUT .. "/denver_colorbv.cmap", MagnitudeExponent = 6.2, SizeComposition = "Distance Modulus", - RenderMethod = "Texture Based" -- or PSF + RenderMethod = "Texture Based", -- or PSF + DataMapping = { + Bv = "colorb_v", + Luminance = "lum", + AbsoluteMagnitude = "absmag", + ApparentMagnitude = "appmag", + Vx = "vx", + Vy = "vy", + Vz = "vz", + Speed = "speed" + } }, GUI = { Name = "Stars (Denver)", diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/charon/charon.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/charon/charon.asset index fdf60a27e6..e2411ef264 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/charon/charon.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/charon/charon.asset @@ -27,21 +27,16 @@ local Charon = { SegmentsPerPatch = 64, Layers = {}, Labels = { - Enable = false, + Enabled = false, FileName = labelsPath .. "/charon.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 40.0, - LabelsSize = 8.0, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - LabelsFadeOutEnabled = true, - FadeInStartingDistance = 2000000.0, - FadeOutStartingDistance = 800000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 250000.0, - LabelsColor = { 1.0, 1.0, 0.0 } + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 9.0, + FadeInEnabled = true, + FadeOutEnabled = true, + Distances = { 800000.0, 2000000.0 }, + DistanceEPS = 250000.0, + Color = { 1.0, 1.0, 0.0 } } }, Tag = { "planet_solarSystem", "planet_terrestrial" }, diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset index ee44ed93de..947b762858 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset @@ -27,21 +27,16 @@ local Pluto = { SegmentsPerPatch = 64, Layers = {}, Labels = { - Enable = false, + Enabled = false, FileName = labelsPath .. "/pluto.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 28.0, - LabelsSize = 8.0, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - LabelsFadeOutEnabled = true, - FadeInStartingDistance = 4000000.0, - FadeOutStartingDistance = 650000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 500000.0, - LabelsColor = { 1.0, 1.0, 0.0 } + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 8.5, + FadeInEnabled = true, + FadeOutEnabled = true, + FadeDistances = { 650000.0, 4000000.0 }, + DistanceEPS = 500000.0, + Color = { 1.0, 1.0, 0.0 } } }, Tag = { "planet_solarSystem", "planet_terrestrial" }, @@ -56,13 +51,12 @@ local PlutoLabel = { Renderable = { Enabled = false, Type = "RenderableLabels", - LabelText = "Pluto", - FontSize = 100.0, - LabelSize = 8.9, - LabelMaxSize = 100.0, - LabelMinSize = 1.0, + Text = "Pluto", + FontSize = 70.0, + Size = 9.05, + MinMaxSize = { 1, 100 }, BlendMode = "Additive", - LabelOrientationOption = "Camera View Direction" + OrientationOption = "Camera View Direction" }, Tag = { "solarsystem_labels" }, GUI = { diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto_trail.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto_trail.asset index fc9f456e51..42e1e9dfd2 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto_trail.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto_trail.asset @@ -20,7 +20,8 @@ local PlutoTrailBarycentric = { Tag = { "planetTrail_solarSystem", "planetTrail_dwarf" }, GUI = { Name = "Pluto Barycentric Trail", - Path = "/Solar System/Dwarf Planets/Pluto" + Path = "/Solar System/Dwarf Planets/Pluto", + Description = [[Orbit of Pluto around it's Barycenter.]] } } @@ -34,5 +35,6 @@ asset.meta = { NASA Spice (see base spice asset)]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", - License = "MIT license" + License = "MIT license", + Identifiers = {"PlutoBarycentricTrail"} } diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto_trail_kepler.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto_trail_kepler.asset new file mode 100644 index 0000000000..95cc754503 --- /dev/null +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto_trail_kepler.asset @@ -0,0 +1,62 @@ +local assetHelper = asset.require('util/asset_helper') +local transforms = asset.require('scene/solarsystem/sun/transforms') +asset.require("spice/base") +local kernels = asset.require('./kernels').PlutoKernels +local OneAU = 1.496e+8 +local PlutoKeplerianTrail = { + Identifier = "PlutoKeplerianTrail", + Parent = transforms.SunECLIPJ2000.Identifier, + Renderable = { + Type = "RenderableTrailOrbit", + Translation = { + Type = "KeplerTranslation", + Eccentricity = 2.543033082909471E-01, + SemiMajorAxis = 3.974407237841206E+01 * OneAU, + Inclination = 1.736609481151430E+01, + AscendingNode = 1.102099981996057E+02, + ArgumentOfPeriapsis = 1.142248569189779E+02, + MeanAnomaly = 14.53, + Epoch = '2000 01 01 00:00', + Period = 7.82438e+9 + }, + Color = { 0.2, 0.8, 0.3 }, + Period = 90487.27692706819, + Resolution = 1000, + Enabled = false + }, + Tag = { "planetTrail_dwarf" }, + GUI = { + Name = "Pluto Keplerian Trail", + Path = "/Solar System/Dwarf Planets/Pluto", + Description = "Keplerian trail of Pluto. Contains full orbit." + } +} +assetHelper.registerSceneGraphNodesAndExport(asset, { PlutoKeplerianTrail }) + + +asset.meta = { + Name = "Pluto Keplerian Trail", + Version = "1.0", + Description = [[ Full Keplerian trail of Pluto as observed by the Sun. Data from + JPL Horizons.]], + Author = "OpenSpace Team", + URL = "https://ssd.jpl.nasa.gov/sbdb.cgi?sstr=pluto", + License = "JPL/NASA", + Identifiers = {"PlutoKeplerianTrail"} +} + + + +-- Double AscendingNode +-- In range: ( 0.000000,360.000000 ) +-- This value determines the right ascension of the ascending node in degrees, that is the location of position along the orbit where the inclined plane and the horizonal reference plane intersect. +-- Double ArgumentOfPeriapsis +-- In range: ( 0.000000,360.000000 ) +-- This value determines the argument of periapsis in degrees, that is the position on the orbit that is closest to the orbiting body. +-- Double MeanAnomaly +-- In range: ( 0.000000,360.000000 ) +-- This value determines the mean anomaly at the epoch in degrees, which determines the initial location of the object along the orbit at epoch. +-- EPOCH= 2457217.500000000 ! 2015-Jul-14 00:00 (TDB) +-- EC= 2.543033082909471E-01 QR= 2.963702328762702E+01 IN= 1.736609481151430E+01 +-- OM= 1.102099981996057E+02 W = 1.142248569189779E+02 Tp= 2447885.610187903512 +-- A = 3.974407237841206E+01 AD= 4.985112146919710E+01 PR= 9.151809533192721E+04 diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/system.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/system.asset index 0a99b94527..0df3c771b8 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/system.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/system.asset @@ -1,6 +1,7 @@ asset.require('./trail') asset.require('./pluto') asset.require('./pluto_trail') +asset.require('./pluto_trail_kepler') asset.require('./charon/charon') asset.require('./charon/charon_trail') asset.require('./minor/hydra') diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/trail.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/trail.asset index 689500df90..c309dce11b 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/trail.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/trail.asset @@ -23,7 +23,9 @@ local PlutoBarycenterTrail = { Tag = { "planetTrail_solarSystem", "planetTrail_dwarf" }, GUI = { Name = "Pluto Barycenter Trail", - Path = "/Solar System/Dwarf Planets/Pluto" + Path = "/Solar System/Dwarf Planets/Pluto", + Description = [[Precise trail of Pluto from NASA SPICE data. Not + containing full orbit.]] } } diff --git a/data/assets/scene/solarsystem/missions/apollo/15/apollo15.asset b/data/assets/scene/solarsystem/missions/apollo/15/apollo15.asset index 01e7a4183f..349ad80572 100644 --- a/data/assets/scene/solarsystem/missions/apollo/15/apollo15.asset +++ b/data/assets/scene/solarsystem/missions/apollo/15/apollo15.asset @@ -49,7 +49,7 @@ local Apollo15 = { }, Renderable = { Type = "RenderableModel", - GeometryFile = models .. "/ApolloCSM.fbx", + GeometryFile = models .. "/ApolloCSM.osmodel", LightSources = { { Type = "SceneGraphLightSource", diff --git a/data/assets/scene/solarsystem/missions/apollo/8/launch_model.asset b/data/assets/scene/solarsystem/missions/apollo/8/launch_model.asset index f1f8660e8e..19a8084f4e 100644 --- a/data/assets/scene/solarsystem/missions/apollo/8/launch_model.asset +++ b/data/assets/scene/solarsystem/missions/apollo/8/launch_model.asset @@ -50,7 +50,7 @@ local Apollo8LaunchModel = { }, Renderable = { Type = "RenderableModel", - GeometryFile = models .. "/ApolloCSM.fbx", + GeometryFile = models .. "/ApolloCSM.osmodel", LightSources = { { Type = "SceneGraphLightSource", diff --git a/data/assets/scene/solarsystem/missions/apollo/8/model.asset b/data/assets/scene/solarsystem/missions/apollo/8/model.asset index ee208139d8..4399deb973 100644 --- a/data/assets/scene/solarsystem/missions/apollo/8/model.asset +++ b/data/assets/scene/solarsystem/missions/apollo/8/model.asset @@ -62,7 +62,7 @@ local Apollo8Model = { }, Renderable = { Type = "RenderableModel", - GeometryFile = models .. "/ApolloCSM.fbx", + GeometryFile = models .. "/ApolloCSM.osmodel", LightSources = { { Type = "SceneGraphLightSource", diff --git a/data/assets/scene/solarsystem/missions/apollo/csm_model.asset b/data/assets/scene/solarsystem/missions/apollo/csm_model.asset index 048332b7d7..fb8c6b2165 100644 --- a/data/assets/scene/solarsystem/missions/apollo/csm_model.asset +++ b/data/assets/scene/solarsystem/missions/apollo/csm_model.asset @@ -2,7 +2,7 @@ local models = asset.syncedResource({ Name = "Apollo Models", Type = "HttpSynchronization", Identifier = "apollo_models", - Version = 2 + Version = 3 }) asset.export('models', models) diff --git a/data/assets/scene/solarsystem/missions/insight/edl.asset b/data/assets/scene/solarsystem/missions/insight/edl.asset index 6a2b046a66..8231084142 100644 --- a/data/assets/scene/solarsystem/missions/insight/edl.asset +++ b/data/assets/scene/solarsystem/missions/insight/edl.asset @@ -60,33 +60,118 @@ local legDeployTime = "2018 NOV 26 19:43:06.68" -- entry + 243s local landerSeperationTime = "2018 NOV 26 19:44:51.68" -- entry + 348s local touchdownTime = "2018 NOV 26 19:45:32.68" -- entry + 389s local panelDeployTime = "2018 NOV 26 19:45:33.68" -- entry + 390s -local foreverTime = "2018 NOV 26 20:17:50.68" -- entry + 2327s local kernelTouchdownTime = "2018 NOV 26 19:45:32.3" local spiceRotationEndTime = "2018 NOV 26 19:51:39" -local InsightParent = { - Identifier = "InsightParent", - Parent = "MarsBarycenter", - Transform = { - Translation = { +local TranslationKeyframes = { + ['1850 JAN 01 00:00:00'] = { Type = "SpiceTranslation", Target = "INSIGHT", Observer = "MARS", - Frame = "GALACTIC", - Kernels = iKernels + Frame = "IAU_MARS", + Kernels = iKernels, + FixedDate = '2018 NOV 26 19:39:03' + }, + ['2018 NOV 26 19:39:02'] = { + Type = "SpiceTranslation", + Target = "INSIGHT", + Observer = "MARS", + Frame = "IAU_MARS", + Kernels = iKernels, + FixedDate = '2018 NOV 26 19:39:03' + }, + ['2018 NOV 26 19:39:03'] = { + Type = "SpiceTranslation", + Target = "INSIGHT", + Observer = "MARS", + Frame = "IAU_MARS", + Kernels = iKernels + }, + ['2018 NOV 26 19:39:04'] = { + Type = "SpiceTranslation", + Target = "INSIGHT", + Observer = "MARS", + Frame = "IAU_MARS", + Kernels = iKernels + }, + ['2018 NOV 26 19:45:34'] = { + Type = "SpiceTranslation", + Target = "INSIGHT", + Observer = "MARS", + Frame = "IAU_MARS", + Kernels = iKernels + }, + ['2018 NOV 26 19:45:35'] = { + Type = "SpiceTranslation", + Target = "INSIGHT", + Observer = "MARS", + Frame = "IAU_MARS", + Kernels = iKernels, + FixedDate = '2018 NOV 26 19:45:34' + }, +} + +local RotationKeyframes = { + ['1850 JAN 01 00:00:00'] = { + Type = "SpiceRotation", + SourceFrame = "INSIGHT_LANDER_CRUISE", + DestinationFrame = "IAU_MARS", + FixedDate = '2018 NOV 26 19:39:02', + Kernels = iKernels + }, + ['2018 NOV 26 19:39:02'] = { + Type = "SpiceRotation", + SourceFrame = "INSIGHT_LANDER_CRUISE", + DestinationFrame = "IAU_MARS", + FixedDate = '2018 NOV 26 19:39:02', + Kernels = iKernels + }, + ['2018 NOV 26 19:39:03'] = { + Type = "SpiceRotation", + SourceFrame = "INSIGHT_LANDER_CRUISE", + DestinationFrame = "IAU_MARS", + Kernels = iKernels + }, + ['2018 NOV 26 19:39:04'] = { + Type = "SpiceRotation", + SourceFrame = "INSIGHT_LANDER_CRUISE", + DestinationFrame = "IAU_MARS", + Kernels = iKernels + }, + ['2018 NOV 26 19:45:34'] = { + Type = "SpiceRotation", + SourceFrame = "INSIGHT_LANDER_CRUISE", + DestinationFrame = "IAU_MARS", + Kernels = iKernels + }, + ['2018 NOV 26 19:45:35'] = { + Type = "SpiceRotation", + SourceFrame = "INSIGHT_LANDER_CRUISE", + DestinationFrame = "IAU_MARS", + FixedDate = '2018 NOV 26 19:45:34' + }, +} + + +local InsightParent = { + Identifier = "InsightParent", + Parent = "Mars", + Transform = { + Translation ={ + Type = "TimelineTranslation", + Keyframes = TranslationKeyframes, }, Rotation = { - Type = "SpiceRotation", - SourceFrame = "INSIGHT_LANDER_CRUISE", - DestinationFrame = "GALACTIC" + Type = "TimelineRotation", + Keyframes = RotationKeyframes, } }, - TimeFrame = { - Type = "TimeFrameInterval", - Start = entryTimeStart, - End = spiceRotationEndTime - }, + -- TimeFrame = { + -- Type = "TimeFrameInterval", + -- Start = entryTimeStart, + -- End = spiceRotationEndTime + -- }, GUI = { Hidden = true, Name = "InsightParent", @@ -121,7 +206,6 @@ local Insight_Entry_CapsuleA = { }, TimeFrame = { Type = "TimeFrameInterval", - Start = entryTimeStart, End = landerSeperationTime }, GUI = { @@ -142,7 +226,6 @@ local Insight_Entry_Capsule_Ring = { }, TimeFrame = { Type = "TimeFrameInterval", - Start = entryTimeStart, End = landerSeperationTime }, GUI = { @@ -163,7 +246,6 @@ local Insight_Entry_Capsule_Plugs = { }, TimeFrame = { Type = "TimeFrameInterval", - Start = entryTimeStart, End = landerSeperationTime }, GUI = { @@ -184,7 +266,6 @@ local Insight_Entry_Heatshield = { }, TimeFrame = { Type = "TimeFrameInterval", - Start = entryTimeStart, End = heatShieldSeperationTime }, GUI = { @@ -329,11 +410,6 @@ local Insight_Lander_A001 = { ModelTransform = RotationMatrix, LightSources = LightSources, }, - TimeFrame = { - Type = "TimeFrameInterval", - Start = entryTimeStart, - End = foreverTime - }, GUI = { Hidden = true, Name = "Insight Lander A001", @@ -350,11 +426,6 @@ local Insight_Lander_A002 = { ModelTransform = RotationMatrix, LightSources = LightSources, }, - TimeFrame = { - Type = "TimeFrameInterval", - Start = entryTimeStart, - End = foreverTime - }, GUI = { Hidden = true, Name = "Insight Lander A002", @@ -371,11 +442,6 @@ local Insight_Lander_A003 = { ModelTransform = RotationMatrix, LightSources = LightSources, }, - TimeFrame = { - Type = "TimeFrameInterval", - Start = entryTimeStart, - End = foreverTime - }, GUI = { Hidden = true, Name = "Insight Lander A003", @@ -392,11 +458,6 @@ local Insight_Lander_A004 = { ModelTransform = RotationMatrix, LightSources = LightSources, }, - TimeFrame = { - Type = "TimeFrameInterval", - Start = entryTimeStart, - End = foreverTime - }, GUI = { Hidden = true, Name = "Insight Lander A004", @@ -413,11 +474,6 @@ local Insight_Lander_A005 = { ModelTransform = RotationMatrix, LightSources = LightSources, }, - TimeFrame = { - Type = "TimeFrameInterval", - Start = entryTimeStart, - End = foreverTime - }, GUI = { Hidden = true, Name = "Insight Lander A005", @@ -434,11 +490,6 @@ local Insight_Lander_A006 = { ModelTransform = RotationMatrix, LightSources = LightSources, }, - TimeFrame = { - Type = "TimeFrameInterval", - Start = entryTimeStart, - End = foreverTime - }, GUI = { Hidden = true, Name = "Insight Lander A006", @@ -455,11 +506,6 @@ local Insight_Lander_A007 = { ModelTransform = RotationMatrix, LightSources = LightSources, }, - TimeFrame = { - Type = "TimeFrameInterval", - Start = entryTimeStart, - End = foreverTime - }, GUI = { Hidden = true, Name = "Insight Lander A007", @@ -476,11 +522,6 @@ local Insight_Lander_A008 = { ModelTransform = RotationMatrix, LightSources = LightSources, }, - TimeFrame = { - Type = "TimeFrameInterval", - Start = entryTimeStart, - End = foreverTime - }, GUI = { Hidden = true, Name = "Insight Lander A008", @@ -497,11 +538,6 @@ local Insight_Lander_foil1 = { ModelTransform = RotationMatrix, LightSources = LightSources, }, - TimeFrame = { - Type = "TimeFrameInterval", - Start = entryTimeStart, - End = foreverTime - }, GUI = { Hidden = true, Name = "Insight Lander foil", @@ -518,11 +554,6 @@ local Insight_Lander_Tex01 = { ModelTransform = RotationMatrix, LightSources = LightSources, }, - TimeFrame = { - Type = "TimeFrameInterval", - Start = entryTimeStart, - End = foreverTime - }, GUI = { Hidden = true, Name = "Insight Lander Tex01", @@ -539,11 +570,6 @@ local Insight_Lander_Tex02 = { ModelTransform = RotationMatrix, LightSources = LightSources, }, - TimeFrame = { - Type = "TimeFrameInterval", - Start = entryTimeStart, - End = foreverTime - }, GUI = { Hidden = true, Name = "Insight Lander Tex02", @@ -605,7 +631,6 @@ local Insight_Legs_Deployed_tex = { TimeFrame = { Type = "TimeFrameInterval", Start = legDeployTime, - End = foreverTime }, GUI = { Hidden = true, @@ -626,7 +651,6 @@ local Insight_Legs_Deployed_AO06 = { TimeFrame = { Type = "TimeFrameInterval", Start = legDeployTime, - End = foreverTime }, GUI = { Hidden = true, @@ -644,11 +668,6 @@ local Insight_Panels_Stowed_tex = { ModelTransform = RotationMatrix, LightSources = LightSources }, - TimeFrame = { - Type = "TimeFrameInterval", - Start = entryTimeStart, - End = foreverTime - }, GUI = { Hidden = true, Name = "Insight panels_stow_tex", @@ -665,11 +684,6 @@ local Insight_Panels_Stowed_tex2 = { ModelTransform = RotationMatrix, LightSources = LightSources }, - TimeFrame = { - Type = "TimeFrameInterval", - Start = entryTimeStart, - End = foreverTime - }, GUI = { Hidden = true, Name = "Insight panels_stow_tex2", @@ -686,11 +700,6 @@ local Insight_Panels_Stowed_AO01 = { ModelTransform = RotationMatrix, LightSources = LightSources }, - TimeFrame = { - Type = "TimeFrameInterval", - Start = entryTimeStart, - End = foreverTime - }, GUI = { Hidden = true, Name = "Insight panels_stow_AO", @@ -710,7 +719,6 @@ local Insight_Panels_Deployed_tex = { TimeFrame = { Type = "TimeFrameInterval", Start = panelDeployTime, - End = foreverTime }, GUI = { Hidden = true, @@ -731,7 +739,6 @@ local Insight_Panels_Deployed_tex2 = { TimeFrame = { Type = "TimeFrameInterval", Start = panelDeployTime, - End = foreverTime }, GUI = { Hidden = true, @@ -752,7 +759,6 @@ local Insight_Panels_Deployed_AO06 = { TimeFrame = { Type = "TimeFrameInterval", Start = panelDeployTime, - End = foreverTime }, GUI = { Hidden = true, diff --git a/data/assets/scene/solarsystem/missions/jwst/HUDFImage.asset b/data/assets/scene/solarsystem/missions/jwst/HUDFImage.asset new file mode 100644 index 0000000000..7f45814a94 --- /dev/null +++ b/data/assets/scene/solarsystem/missions/jwst/HUDFImage.asset @@ -0,0 +1,77 @@ +local assetHelper = asset.require('util/asset_helper') +local transforms = asset.require('scene/solarsystem/planets/earth/transforms') +local jwstTransforms = asset.require('scene/solarsystem/missions/jwst/jwst') +local sunTransforms = asset.require('scene/solarsystem/sun/transforms') + +local image = asset.syncedResource({ + Name = "HUDF image", + Type = "HttpSynchronization", + Identifier = "hudf_image", + Version = 1 +}) + +local DISTANCE = 9.2E15; + +-- ra = 3h32m38.92s +-- dec = -27d47m29.37s +-- distance = 9.2E15 m (set to size of view sphere) +local HUDFPosition = { + Identifier = "HUDFPosition", + Parent = transforms.EarthInertial.Identifier, + Transform = { + Translation = { + Type = "StaticTranslation", + Position = { + 0.53039024 * DISTANCE, + 0.70802069 * DISTANCE, + -0.46625412 * DISTANCE + } + } + }, + GUI = { + Name = "Hubble Ultra Deep field", + Path = "/Solar System/Missions/JWST", + Hidden = true + } +} + +local HUDFImage = { + Identifier = "HUDFImage", + Enabled = false, + Type = "ScreenSpaceImageLocal", + Name = "Hubble Ultra Deep field", + UseRadiusAzimuthElevation = true, + FaceCamera = false, + RadiusAzimuthElevation = { 200.0, 0.5, 0.15 }, + UsePerspectiveProjection = false, + Opacity = 1.0, + TexturePath = image .. "/Hubble_ultra_deep_field.jpg", + Tag = { "mission_jwst_hudf" }, +} + +local HUDFJWSTLine = { + Identifier = "HUDFJWSTLine", + Parent = sunTransforms.SolarSystemBarycenter.Identifier, + Renderable = { + Enabled = false, + Type = "RenderableNodeLine", + StartNode = HUDFPosition.Identifier, + EndNode = jwstTransforms.JWSTPosition.Identifier, + Color = { 0.5, 0.5, 0.5 }, + LineWidth = 2 + }, + Tag = { "mission_jwst_hudf" }, + GUI = { + Name = "JWST to HUDF Line", + Path = "/Solar System/Missions/JWST", + } +} + +assetHelper.registerSceneGraphNodesAndExport(asset, { HUDFPosition, HUDFImage, HUDFJWSTLine }) + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(HUDFImage) +end) +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(HUDFImage.Identifier) +end) diff --git a/data/assets/scene/solarsystem/missions/jwst/jwst.asset b/data/assets/scene/solarsystem/missions/jwst/jwst.asset new file mode 100644 index 0000000000..a0c86521e4 --- /dev/null +++ b/data/assets/scene/solarsystem/missions/jwst/jwst.asset @@ -0,0 +1,304 @@ +local assetHelper = asset.require('util/asset_helper') +local sunTransforms = asset.require('scene/solarsystem/sun/transforms') + +asset.require('spice/base') +asset.require('scene/solarsystem/planets/earth/lagrange_points/lagrange_points') +local transforms = asset.require('scene/solarsystem/planets/earth/lagrange_points/L2') + +local JWSTKernel = asset.syncedResource({ + Name = "JWST Kernel", + Type = "HttpSynchronization", + Identifier = "jwst_kernels", + Version = 1 +}) + +--[[local JWSTHorizons = asset.syncedResource({ + Name = "JWST Horizons", + Type = "HttpSynchronization", + Identifier = "jwst_horizons", + Version = 1 +})]]-- + +local model = asset.syncedResource({ + Name = "JWST Model", + Type = "HttpSynchronization", + Identifier = "jwst_model", + Version = 1 +}) + +local band = asset.syncedResource({ + Name = "JWST band texture", + Type = "HttpSynchronization", + Identifier = "jwst_band_texture", + Version = 1 +}) + +local JWSTPosition = { + Identifier = "JWSTPosition", + Parent = transforms.L2.Identifier, + Transform = { + Translation = { + Type = "SpiceTranslation", + Target = "JWST", + Observer = "392", -- L2 + Kernels = JWSTKernel .. "/jwst_horizons_20200101_20240101_v01.bsp" + }, + }, + GUI = { + Name = "JWST Position", + Path = "/Solar System/Missions/JWST", + Hidden = true, + } +} + +local JWSTRotation = { + Identifier = "JWSTRotation", + Parent = JWSTPosition.Identifier, + Transform = { + Rotation = { + Type = "FixedRotation", + Attached = "JWSTRotation", + XAxis = { 1, 0, 0 }, + XAxisOrthogonal = true, + YAxisInvert = true, + YAxis = sunTransforms.SolarSystemBarycenter.Identifier + } + }, + GUI = { + Name = "JWST Rotation", + Path = "/Solar System/Missions/JWST", + Hidden = true, + } +} + +local JWSTBand = { + Identifier = "JWSTBand", + Parent = JWSTPosition.Identifier, + Transform = { + Rotation = { + Type = "FixedRotation", + Attached = "JWSTBand", + XAxis = { 1, 0, 0 }, + XAxisOrthogonal = true, + ZAxis = sunTransforms.SolarSystemBarycenter.Identifier + } + }, + Renderable = { + Enabled = false, + Type = "RenderableSphere", + Texture = band .. "/JWST-band.png", + Size = 9.2E15, + Segments = 50, + DisableFadeInOut = true, + Orientation = "Inside", + Opacity = 0.05, + UseAdditiveBlending = true, + }, + Tag = { "mission_jwst_fov" }, + GUI = { + Name = "JWST Safe Viewing Band", + Path = "/Solar System/Missions/JWST" + } +} + +local JWSTModel = { + Identifier = "JWSTModel", + Parent = JWSTRotation.Identifier, + TimeFrame = { + Type = "TimeFrameInterval", + Start = "2020 JAN 01", + End = "2024 JAN 01" + }, + Renderable = { + Type = "RenderableModel", + GeometryFile = model .. "/JWSTFBX.osmodel", + ModelScale = "Foot", + InvertModelScale = true, + EnableAnimation = true, + --TODO: Update theese when the new animation is finished + AnimationStartTime = "2018 10 01 15:00:00", + AnimationMode = "Once", + LightSources = { + { + Type = "SceneGraphLightSource", + Identifier = "Sun", + Node = sunTransforms.SolarSystemBarycenter.Identifier, + Intensity = 1.0 + } + }, + PerformShading = true, + DisableFaceCulling = true + }, + GUI = { + Name = "James Webb Space Telescope", + Path = "/Solar System/Missions/JWST", + } +} + +local JWSTTrail = { + Identifier = "JWSTTrail", + Parent = transforms.L2.Identifier, + Renderable = { + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Target = "JWST", + Observer = "392", -- L2 + Kernels = JWSTKernel .. "/jwst_horizons_20200101_20240101_v01.bsp" + }, + Color = { 0.9, 0.9, 0.0 }, + Period = 91.3105, + Resolution = 100 + }, + GUI = { + Name = "JWST Trail", + Path = "/Solar System/Missions/JWST" + } +} + +local JWSTSunTrail = { + Identifier = "JWSTSunTrail", + Parent = sunTransforms.SolarSystemBarycenter.Identifier, + Renderable = { + Enabled = false, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Target = "JWST", + Observer = "SUN", + Kernels = JWSTKernel .. "/jwst_horizons_20200101_20240101_v01.bsp" + }, + Color = { 0.0, 0.9, 0.9 }, + Period = 365.242, + Resolution = 1000 + }, + GUI = { + Name = "JWST Sun Trail", + Path = "/Solar System/Missions/JWST" + } +} + +local JWSTFov = { + Identifier = "JWSTFov", + Parent = JWSTModel.Identifier, + Renderable = { + Enabled = false, + Type = "RenderablePrism", + Segments = 6, + Lines = 3, + Radius = 3.25, + LineWidth = 1.0, + Color = { 1.0, 1.0, 1.0 }, + Length = 9.2E15 + }, + Transform = { + Rotation = { + Type = "StaticRotation", + Rotation = { 0, 0, math.rad(30) } + }, + }, + Tag = { "mission_jwst_fov" }, + GUI = { + Name = "JWST Field of View", + Path = "/Solar System/Missions/JWST", + } +} + +-- Launch, coming soon +--[[local JWSTLaunchPosition = { + Identifier = "JWSTLaunchPosition", + Parent = transforms.L2.Identifier, + Transform = { + Translation = { + Type = "HorizonsTranslation", + HorizonsTextFile = JWSTHorizons .. "/horizons_jwst_launch.dat", + }, + }, + GUI = { + Name = "JWST Launch Position", + Path = "/Solar System/Missions/JWST", + Hidden = true, + } +} + +local JWSTLaunchModel = { + Identifier = "JWSTLaunchModel", + Parent = JWSTLaunchPosition.Identifier, + TimeFrame = { + Type = "TimeFrameInterval", + Start = "2018 OCT 01 13:18:00", + End = "2019 OCT 01" + }, + Transform = { + Rotation = { + Type = "FixedRotation", + Attached = "JWSTRotation", + XAxis = { 1, 0, 0 }, + XAxisOrthogonal = true, + YAxisInvert = true, + YAxis = sunTransforms.SolarSystemBarycenter.Identifier + } + }, + Renderable = { + Type = "RenderableModel", + GeometryFile = model .. "/JWSTFBX.osmodel", + ModelScale = "Foot", + InvertModelScale = true, + EnableAnimation = true, + --TODO: Update theese when the new animation is finished + AnimationStartTime = "2018 10 01 15:00:00", + AnimationMode = "Once", + LightSources = { + { + Type = "SceneGraphLightSource", + Identifier = "Sun", + Node = sunTransforms.SolarSystemBarycenter.Identifier, + Intensity = 1.0 + } + }, + PerformShading = true, + DisableFaceCulling = true + }, + GUI = { + Name = "JWST Launch Model", + Path = "/Solar System/Missions/JWST", + } +} + +local JWSTLaunchTrail = { + Identifier = "JWSTLaunchTrail", + Parent = transforms.L2.Identifier, + TimeFrame = { + Type = "TimeFrameInterval", + Start = "2018 OCT 01 13:18:00", + End = "2019 OCT 01" + }, + Renderable = { + Type = "RenderableTrailTrajectory", + Translation = { + Type = "HorizonsTranslation", + HorizonsTextFile = JWSTHorizons .. "/horizons_jwst_launch.dat", + }, + Color = { 0.9, 0.9, 0.0 }, + StartTime = "2018 OCT 01 13:18:00", + EndTime = "2019 OCT 01", + SampleInterval = 600 + }, + GUI = { + Name = "JWST Launch Trail", + Path = "/Solar System/Missions/JWST" + } +}]]-- + +assetHelper.registerSceneGraphNodesAndExport(asset, { + JWSTTrail, + JWSTSunTrail, + --JWSTLaunchTrail, + JWSTPosition, + --JWSTLaunchPosition, + JWSTRotation, + JWSTBand, + JWSTModel, + --JWSTLaunchModel, + JWSTFov +}) diff --git a/data/assets/scene/solarsystem/missions/osirisrex/bennu.asset b/data/assets/scene/solarsystem/missions/osirisrex/bennu.asset index ea0377a3a9..ba0442a4eb 100644 --- a/data/assets/scene/solarsystem/missions/osirisrex/bennu.asset +++ b/data/assets/scene/solarsystem/missions/osirisrex/bennu.asset @@ -1,17 +1,10 @@ local assetHelper = asset.require('util/asset_helper') local transforms = asset.require('./transforms') local sunTransforms = asset.require('scene/solarsystem/sun/transforms') - -local models = asset.syncedResource({ - Name = "Bennu Models", - Type = "HttpSynchronization", - Identifier = "bennu_models", - Version = 1 -}) +local models = asset.require('./models').models local BENNU_BODY = "2101955" - local Bennu = { Identifier = "Bennu", Parent = transforms.BennuBarycenter.Identifier, @@ -20,56 +13,17 @@ local Bennu = { Type = "SpiceRotation", SourceFrame = "IAU_BENNU", DestinationFrame = "GALACTIC" + }, + Scale = { + Type = "StaticScale", + Scale = 1000.0 } }, Renderable = { - Type = "RenderableModelProjection", + Enabled = false, + Type = "RenderableModel", Body = BENNU_BODY, - GeometryFile = models .. "/BennuUntextured.obj", - Projection = { - Sequence = asset.localResource('InstrumentTimes'), - SequenceType = "instrument-times", - Observer = "OSIRIS-REX", - Target = BENNU_BODY, - Aberration = "NONE", - AspectRatio = 2, - - DataInputTranslation = { - Instruments = { - ORX_OCAMS_POLYCAM = { - DetectorType = "Camera", - Spice = { "ORX_OCAMS_POLYCAM" }, - Files = { - "BaseballDiamond_PolyCam.txt", - --"OrbitalB_Site08_PolyCamImages.txt", - "Recon_225m_Equatorial_PolyCam.txt" - } - }, - ORX_REXIS = { - DetectorType = "Camera", - Spice = { "ORX_REXIS" }, - Files = { - "DetailedSurvey_EquatorialStations_Spectrometers.txt", - "Recon_225m_Equatorial_spectrometers.txt", - "Recon_525m_Equatorial_spectrometers.txt" - } - } - }, - Target = { - Body = BENNU_BODY - }, - }, - - Instrument = { -- INVALID DATA - JUST FOR TESTING - Name = "ORX_OCAMS_POLYCAM", - Method = "ELLIPSOID", - Aberration = "NONE", - Fovy = 0.792, - Aspect = 1, - Near = 0.01, - Far = 1000000 - } - } + GeometryFile = models .. "/Bennu_v20_200k.stl", }, GUI = { Path = "/Solar System/Asteroid" diff --git a/data/assets/scene/solarsystem/missions/osirisrex/bennu_projection.asset b/data/assets/scene/solarsystem/missions/osirisrex/bennu_projection.asset new file mode 100644 index 0000000000..ae2b0add47 --- /dev/null +++ b/data/assets/scene/solarsystem/missions/osirisrex/bennu_projection.asset @@ -0,0 +1,104 @@ +local assetHelper = asset.require('util/asset_helper') +local transforms = asset.require('./transforms') +local sunTransforms = asset.require('scene/solarsystem/sun/transforms') + +local models = asset.require('./models').models + +local BENNU_BODY = "2101955" + +local images = asset.syncedResource({ + Name = "Bennu Images Approach", + Type = "HttpSynchronization", + Identifier = "osirisrex_bennu_images_approach", + Version = 1 +}) + +local imagesA = asset.syncedResource({ + Name = "Bennu Images A", + Type = "HttpSynchronization", + Identifier = "osirisrex_bennu_images_orbit_a", + Version = 1 +}) + +local BennuProjection = { + Identifier = "BennuProjection", + Parent = transforms.BennuBarycenter.Identifier, + Transform = { + Rotation = { + Type = "SpiceRotation", + SourceFrame = "IAU_BENNU", + DestinationFrame = "GALACTIC" + }, + }, + Renderable = { + Enabled = true, + Type = "RenderableModelProjection", + Body = BENNU_BODY, + GeometryFile = models .. "/BennuTextured.obj", + Projection = { + Sequence = { images, imagesA }, + SequenceType = "image-sequence", + Observer = "OSIRIS-REX", + Target = BENNU_BODY, + Aberration = "NONE", + TextureMap = true, + DataInputTranslation = { + Instruments = { + ORX_OCAMS_POLYCAM = { + DetectorType = "Camera", + Spice = { "ORX_OCAMS_POLYCAM" }, + }, + }, + Target = { + Read = { + "TARGET_NAME", + "INSTRUMENT_HOST_NAME", + "INSTRUMENT_ID", + "START_TIME", + "STOP_TIME" + }, + Convert = { + ["2101955"] = { "2101955" }, + ["OSIRIS-REX"] = { "OSIRIS-REX" }, + ["ORX_OCAMS_POLYCAM"] = { "ORX_OCAMS_POLYCAM" }, + } + } + }, + Instrument = { -- INVALID DATA - JUST FOR TESTING + Name = "ORX_OCAMS_POLYCAM", + Method = "ELLIPSOID", + Aberration = "NONE", + Fovy = 0.792, + Aspect = 1, + Near = 0.01, + Far = 1000000 + } + } + }, + GUI = { + Path = "/Solar System/Asteroid" + } +} + +local BennuTrail = { + Identifier = "BennuTrail", + Parent = sunTransforms.SolarSystemBarycenter.Identifier, + Renderable = { + Type = "RenderableTrailTrajectory", + Translation = { + Type = "SpiceTranslation", + Target = BENNU_BODY, + Observer = "SUN" + }, + Color = { 0.4, 0.0, 0.7 }, + StartTime = "2015 JAN 01 00:00:00.000", + EndTime = "2023 MAY 31 00:00:00.000", + SampleInterval = 3600 + }, + GUI = { + Name = "Bennu Trail", + Path = "/Solar System/Asteroid" + } +} + +assetHelper.registerSceneGraphNodesAndExport(asset, { BennuProjection, BennuTrail }) diff --git a/data/assets/scene/solarsystem/missions/osirisrex/imageplane.asset b/data/assets/scene/solarsystem/missions/osirisrex/imageplane.asset new file mode 100644 index 0000000000..bb4f1ffca2 --- /dev/null +++ b/data/assets/scene/solarsystem/missions/osirisrex/imageplane.asset @@ -0,0 +1,43 @@ +local assetHelper = asset.require('util/asset_helper') +local transforms = asset.require('./transforms') + +local textures = asset.syncedResource({ + Name = "Bennu Textures", + Type = "HttpSynchronization", + Identifier = "bennu_textures", + Version = 1 +}) + +local BENNU_BODY = "2101955" + +local ImagePlane = { + Identifier = "ImagePlaneBennu", + Parent = transforms.BennuBarycenter.Identifier, + Transform = { + -- Translation = { + -- Type = "StaticTranslation", + -- Position = { -0.2476, 0.2710, 0.3364 } + -- }, + -- Rotation = { + -- Type = "SpiceRotation", + -- SourceFrame = "ORX_OCAMS_POLYCAM", + -- DestinationFrame = "ORX_SPACECRAFT" + -- } + }, + Renderable = { + Type = "RenderablePlaneProjection", + Frame = "IAU_BENNU", + DefaultTarget = BENNU_BODY, + Spacecraft = "OSIRIS-REX", + Instrument = "ORX_OCAMS_POLYCAM", + Moving = false, + Texture = textures .. "/defaultProj.png" + }, + GUI = { + Name = "OsirisREx Image Plane", + Path = "/Solar System/Missions/OSIRIS REx" + } +} + + +assetHelper.registerSceneGraphNodesAndExport(asset, { ImagePlane }) diff --git a/data/assets/scene/solarsystem/missions/osirisrex/kernels.asset b/data/assets/scene/solarsystem/missions/osirisrex/kernels.asset new file mode 100644 index 0000000000..85e56d5fa1 --- /dev/null +++ b/data/assets/scene/solarsystem/missions/osirisrex/kernels.asset @@ -0,0 +1,91 @@ +local kernels = asset.syncedResource({ + Name = "Osiris Rex Kernels", + Type = "HttpSynchronization", + Identifier = "osirisrex_kernels", + Version = 2 +}) + +local OsirisRexKernels = { + kernels .. "/orx_v14.tf", + kernels .. "/orx_ocams_v07.ti", + kernels .. "/orx_rexis_v01.ti", + kernels .. "/ORX_SCLKSCET.00061.tsc", + kernels .. "/bennu_v17.tpc", + kernels .. "/orx_struct_v04.bsp", + kernels .. "/orx_sa_red_200106_v02.bc", + kernels .. "/orx_sa_red_200107_v02.bc", + kernels .. "/orx_sa_red_200108_v02.bc", + kernels .. "/orx_sa_red_200109_v02.bc", + kernels .. "/orx_sa_red_200110_v02.bc", + kernels .. "/orx_sa_rel_200106_200112_v01.bc", + kernels .. "/orx_sc_rel_160909_160911_v01.bc", + kernels .. "/orx_sc_rel_160912_160918_v01.bc", + kernels .. "/orx_sc_rel_160919_160925_v01.bc", + kernels .. "/orx_sc_rel_160926_161002_v01.bc", + kernels .. "/orx_sc_rel_181029_181104_v02.bc", + kernels .. "/orx_sc_rel_190218_190224_v02.bc", + kernels .. "/orx_sc_rel_200106_200112_v01.bc", + kernels .. "/orx_sc_rel_201019_201025_v01.bc", + kernels .. "/orx_sc_rel_201012_201018_v01.bc", + kernels .. "/orx_sc_red_200106_v02.bc", + kernels .. "/orx_sc_red_200107_v02.bc", + kernels .. "/orx_sc_red_200108_v02.bc", + kernels .. "/orx_sc_red_200109_v02.bc", + kernels .. "/orx_sc_red_201020_v02.bc", + kernels .. "/orx_sc_red_201017_v03.bc", + kernels .. "/orx_sc_red_201018_v02.bc", + kernels .. "/orx_sc_red_201019_v02.bc", + kernels .. "/orx_r_160909_160910_v01.bc", + kernels .. "/orx_r_160910_160913_v01.bc", + kernels .. "/orx_r_160913_160915_v01.bc", + kernels .. "/orx_r_160915_160919_v01.bc", + kernels .. "/orx_r_160918_160922_v01.bc", + kernels .. "/orx_r_160919_160922_v01.bc", + kernels .. "/orx_r_200105_200107_v02.bc", + kernels .. "/orx_r_200106_200108_v02.bc", + kernels .. "/orx_r_200107_200109_v02.bc", + kernels .. "/orx_r_200107_200112_v01.bc", + kernels .. "/orx_r_200108_200110_v02.bc", + kernels .. "/orx_r_200109_200111_v02.bc", + kernels .. "/orx_r_201019_201021_v06.bc", + kernels .. "/orx_r_201018_201021_v02.bc", + kernels .. "/orx_r_201018_201020_v03.bc", + kernels .. "/orx_r_201017_201019_v03.bc", + kernels .. "/orx_p_160910_161005_xc001b_v01.bc", + kernels .. "/orx_p_200106_200113_2002_od205_v01.bc", + kernels .. "/orx_p_200106_200113_2002_od209_v01.bc", + kernels .. "/orx_p_200106_200113_2002_od210_v01.bc", + kernels .. "/orx_p_201019_201026_2043tag_od293_v03.bc", + kernels .. "/orx_p_201012_201019_2042_od291_v04.bc", + kernels .. "/orx_p_210411_210510_xq006_od297_v05.bc", + kernels .. "/orx_p_210509_210513_xr001_adm_final_mod_od311_v01.bc", + kernels .. "/orx_p_210509_210607_xr001_od298_v00.bc", + kernels .. "/orx_p_230824_231008_src_release_od298_v00.bc", + kernels .. "/OREX_20160904_M45_complete.bsp", + kernels .. "/OREX_20160908_M60_complete.bsp", + kernels .. "/orx_struct_polycam_v01.bc", + kernels .. "/de424.bsp", + kernels .. "/bennu_refdrmc_v1.bsp", + kernels .. "/orx_160908_231024_pgaa2_day06m60.bsp", + kernels .. "/orx_160908_231024_pgaa3_day06m60_v1.bsp", + kernels .. "/orx_160909_161228_160919_od005_tcm1_v2.bsp", + kernels .. "/orx_160909_161228_160930_od006_tcm1_v1.bsp", + kernels .. "/orx_160909_170101_160912_od004_v1.bsp", + kernels .. "/orx_160909_170101_161010_od008_v1.bsp", + kernels .. "/spk_orx_160908_231024_pgaa2_day06m60_v3.bsp", + kernels .. "/orx_160909_231024_refod009_v2.bsp", + kernels .. "/orx_171006_231024_171005_refod027_v1.bsp", + kernels .. "/orx_180301_200101_180711_od037-R-AM1-P-M17B_v2.bsp", + kernels .. "/orx_180801_181219_181128_od066-N-M0P-L-VC1_v1.bsp", + kernels .. "/orx_191101_200407_191202_od204-R-R1P1-P-R3R_v1.bsp", + kernels .. "/orx_201020_210524_210103_od297-N-PTO1-F_v1.bsp", + kernels .. "/orx_201020_210601_201109_od295-R_v1.bsp", + kernels .. "/orx_201020_201110_201021_od293-N_v1.bsp", + kernels .. "/orx_201005_201201_200615_od258-R-T1P1-P-T1R1_v1.bsp", + kernels .. "/orx_201005_201201_200615_od258-C-T1P1-P-T1R5_v2.bsp", + kernels .. "/orx_210115_210701_210426_od310-N-ADM-P_v1.bsp", + kernels .. "/orx_210408_210701_210503_od311-N-ADM-F_v1.bsp", + kernels .. "/orx_210509_231025_210119_od298-R-ADM1-P-DB1_v1.bsp" +} + +asset.export('kernels', OsirisRexKernels) diff --git a/data/assets/scene/solarsystem/missions/osirisrex/model.asset b/data/assets/scene/solarsystem/missions/osirisrex/model.asset index 454d4462e3..0af62025e7 100644 --- a/data/assets/scene/solarsystem/missions/osirisrex/model.asset +++ b/data/assets/scene/solarsystem/missions/osirisrex/model.asset @@ -3,173 +3,17 @@ local transforms = asset.require('./transforms') local sunTransforms = asset.require('scene/solarsystem/sun/transforms') local earthTransforms = asset.require('scene/solarsystem/planets/earth/transforms') - - -local kernels = asset.syncedResource({ - Name = "Osiris Rex Kernels", - Type = "HttpSynchronization", - Identifier = "osirisrex_kernels", - Version = 1 -}) +local OsirisRexKernels = asset.require('./kernels').kernels local models = asset.syncedResource({ Name = "Osiris Rex Models", Type = "HttpSynchronization", Identifier = "osirisrex_models", - Version = 2 + Version = 3 }) local BENNU_BODY = "2101955" -KernelCase = 2 -- Right now we only have the image times for case 2 - -local CaseDependentKernels -if KernelCase == 2 then - CaseDependentKernels = { - kernels .. "/ORX_Recon_525mSortie_Case02.bsp", - kernels .. "/Recon_525mSortie_Case02_0Latitude.bc", - kernels .. "/Recon_525mSortie_Case02_atl_19145_04.atf", - - kernels .. "/ORX_Recon_225mSortie_Case02.bsp", - kernels .. "/Recon_225mSortie_Case02_0Latitude.bc" - } -elseif KernelCase == 5 then - CaseDependentKernels = { - kernels .. "/ORX_Recon_525mSortie_Case05.bsp", - kernels .. "/Recon_525mSortie_Case05_20negLatitude.bc", - kernels .. "/Recon_525mSortie_Case05_atl_19145_04.atf", - kernels .. "/Recon_525mSortie_Case05_NominalProfile.bc", - - kernels .. "/ORX_Recon_225mSortie_Case05.bsp", - kernels .. "/Recon_225mSortie_Case05_20negLatitude.bc" - } -elseif KernelCase == 8 then - CaseDependentKernels = { - kernels .. "/Recon_525mSortie_Case08_NominalProfile.bc", - kernels .. "/ORX_Recon_225mSortie_Case08.bsp", - kernels .. "/Recon_225mSortie_Case08_40negLatitude.bc" - } -elseif KernelCase == 11 then - CaseDependentKernels = { - kernels .. "/ORX_Recon_225mSortie_Case11.bsp", - kernels .. "/Recon_225mSortie_Case11_60negLatitude.bc" - } -end - -local OsirisRexKernels = { - -- background - -- SCLK kernels needs to be loaded before CK kernels (and generally first) - kernels .. "/ORX_SCLKSCET.00000.tsc", - - -- This cannot be loaded correctly for some reason! - --openspace.spice.loadKernel(kernels .. "/OsirisRexKernels/background/dsk/RQ36mod.oct12_CCv0001.bds") - - kernels .. "/orx_v04.tf", - kernels .. "/orx_lidar_v00.ti", - kernels .. "/orx_ocams_v03.ti", - kernels .. "/orx_otes_v00.ti", - kernels .. "/orx_rexis_v00.ti", - kernels .. "/orx_struct_v00.ti", - kernels .. "/orx_navcam_v00.ti", - kernels .. "/orx_ola_v00.ti", - kernels .. "/orx_ovirs_v00.ti", - kernels .. "/orx_stowcam_v00.ti", - -- kernels .. "/naif0011.tls", - kernels .. "/bennu_SPH250m.tpc", - kernels .. "/bennu_v10.tpc", - - -- Low res SPK - kernels .. "/orx_160917_231024_pgaa3_day15m60_v1.bsp", - kernels .. "/orx_160914_231024_pgaa3_day12m60_v1.bsp", - - kernels .. "/orx_160908_231024_pgaa3_day06m60_v1.bsp", - kernels .. "/spk_orx_160908_231024_pgaa2_day06m60_v3.bsp", - kernels .. "/orx_160908_231024_pgaa2_day06m60.bsp", - - kernels .. "/OREX_20160908_M60_complete.bsp", - kernels .. "/OREX_20160904_M45_complete.bsp", - - -- SPK - kernels .. "/de421.bsp", - kernels .. "/sb-101955-76.bsp", - - -- Nominal_Profile_LowRes - kernels .. "/Approach_600s_20180816T230000_20181119T010000.bsp", - kernels .. "/Approach_NominalProfile_600s_20180816T230000_20181119T010000.bc", - kernels .. "/DetailedSurvey_600s_20190108T000000_20190317T000000.bsp", - kernels .. "/OrbitalA_600s_20181203T230000_20190109T000000.bsp", - kernels .. "/OrbitalA_NominalProfile_600s_20181203T230000_20190109T000000.bc", - kernels .. "/OrbitalB_600s_20190316T000000_20190521T000000.bsp", - kernels .. "/DetailedSurvey_NominalProfile_600s_20190108T000000_20190317T000000.bc", - kernels .. "/OrbitalB_NominalProfile600s_20190316T000000_20190521T000000.bc", - kernels .. "/PrelimSurvey_600s_20181119T230000_20181204T010000.bsp", - kernels .. "/PrelimSurvey_NominalProfile_600s_20181119T230000_20181204T010000.bc", - kernels .. "/Recon_600s_20190519T000000_20190830T000000.bsp", - kernels .. "/Recon_NominalProfile_600s_20190519T000000_20190830T000000.bc", - - -- Nominal_Observations_Science - kernels .. "/Phase03_AP_DustSearch_1.bc", - kernels .. "/Phase03_AP_LightCurve_1.bc", - kernels .. "/Phase03_AP_LightCurve_2.bc", - kernels .. "/Phase03_AP_SatSearch_1.bc", - kernels .. "/Phase03_AP_SatSearch_2.bc", - kernels .. "/Phase03_AP_PhaseFunction_1.bc", - kernels .. "/Phase03_AP_ShapeModel_1.bc", - kernels .. "/Phase03_AP_ShapeModel_2.bc", - kernels .. "/Phase03_AP_ShapeModel_3.bc", - kernels .. "/Phase03_AP_ShapeModel_4.bc", - kernels .. "/Phase03_AP_ShapeModel_5.bc", - kernels .. "/Phase03_AP_ShapeModel_6.bc", - kernels .. "/Phase03_AP_ShapeModel_7.bc", - kernels .. "/Phase03_AP_ShapeModel_8.bc", - kernels .. "/Phase03_AP_ShapeModel_9_Forced4x4.bc", - kernels .. "/Phase03_AP_SpectraMap_1.bc", - kernels .. "/Phase04_PS_MC_1_v1_1a.bc", - kernels .. "/Phase04_PS_MC_2_v1_1a.bc", - kernels .. "/Phase04_PS_OLA_Nominal_1.bc", - kernels .. "/Phase04_PS_OLA_Nominal_2.bc", - kernels .. "/Phase04_PS_OLA_Nominal_3.bc", - kernels .. "/Phase04_PS_OLA_Nominal_4.bc", - kernels .. "/Phase04_PS_PolyCam_1.bc", - kernels .. "/Phase04_PS_PolyCam_2.bc", - kernels .. "/Phase04_PS_PolyCam_3.bc", - kernels .. "/Phase04_PS_PolyCam_4.bc", - kernels .. "/Phase04_PS_PolyCam_5.bc", - kernels .. "/Phase04_PS_PolyCam_6.bc", - - --openspace.spice.loadKernel(kernels .. "/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19013_18_BBD1_info.TXT") - --openspace.spice.loadKernel(kernels .. "/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19014_16_BBD2_info.TXT") - --openspace.spice.loadKernel(kernels .. "/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19020_18_BBD3_info.TXT") - --openspace.spice.loadKernel(kernels .. "/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19021_19_BBD4_info.TXT") - --openspace.spice.loadKernel(kernels .. "/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/README.txt") - - kernels .. "/atl_19013_18_BBD1_v2.bc", - kernels .. "/atl_19014_16_BBD2_v2.bc", - kernels .. "/atl_19020_18_BBD3_v2.bc", - kernels .. "/atl_19021_19_BBD4_v2.bc", - - - kernels .. "/Phase06_DS_Equatorial_Stations_1.bc", - kernels .. "/Phase06_DS_Equatorial_Stations_2.bc", - kernels .. "/Phase06_DS_Equatorial_Stations_3.bc", - kernels .. "/Phase06_DS_Equatorial_Stations_4.bc", - kernels .. "/Phase06_DS_Equatorial_Stations_5.bc", - kernels .. "/Phase06_DS_Equatorial_Stations_6.bc", - kernels .. "/Phase06_DS_Equatorial_Stations_7.bc", - kernels .. "/Phase06_DS_Plume_Search_1.bc", - kernels .. "/Phase06_DS_Plume_Search_2.bc", - kernels .. "/Phase07_OB_CSS_Mapping_1.bc", - kernels .. "/Phase07_OB_CSS_Mapping_2.bc", - kernels .. "/Phase07_OB_CSS_Mapping_3.bc", - kernels .. "/CSS_Mapping_1.a", - kernels .. "/CSS_Mapping_2.a", - kernels .. "/CSS_Mapping_3.a", - - --openspace.spice.loadKernel(kernels .. "/Case02_0Latitude.wmv") - --openspace.spice.loadKernel(kernels .. "/Case05_20negLatitude.wmv") - --openspace.spice.loadKernel(kernels .. "/Case08_40negLatitude.wmv") - --openspace.spice.loadKernel(kernels .. "/Case11_60negLatitude.wmv") -} local LightSources = { { @@ -185,11 +29,6 @@ local LightSources = { } } --- Append the CaseDependentKernels at the end of the OsirisRexKernels set -for i = 0, #CaseDependentKernels do - OsirisRexKernels[#OsirisRexKernels + 1] = CaseDependentKernels[i] -end - local OsirisRex = { Identifier = "OsirisRex", Parent = sunTransforms.SolarSystemBarycenter.Identifier, @@ -204,7 +43,7 @@ local OsirisRex = { Type = "SpiceRotation", SourceFrame = "ORX_SPACECRAFT", DestinationFrame = "GALACTIC" - } + }, }, Renderable = { Type = "RenderableModel", @@ -262,7 +101,7 @@ local Rexis = { Type = "SpiceRotation", SourceFrame = "ORX_REXIS", DestinationFrame = "ORX_SPACECRAFT" - } + }, }, GUI = { Name = "REXIS", @@ -274,13 +113,13 @@ local PolyCamFov = { Identifier = "POLYCAM FOV", Parent = PolyCam.Identifier, Renderable = { - Type = "RenderableFov", - Body = "OSIRIS-REX", + Type = "RenderableFov", + Body = "OSIRIS-REX", Frame = "ORX_OCAMS_POLYCAM", - RGB = { 0.8, 0.7, 0.7 }, + RGB = { 0.8, 0.7, 0.7 }, Instrument = { - Name = "ORX_OCAMS_POLYCAM", - Method = "ELLIPSOID", + Name = "ORX_OCAMS_POLYCAM", + Method = "ELLIPSOID", Aberration = "NONE" }, PotentialTargets = { BENNU_BODY } @@ -295,13 +134,13 @@ local RexisFov = { Identifier = "REXIS FOV", Parent = Rexis.Identifier, Renderable = { - Type = "RenderableFov", - Body = "OSIRIS-REX", + Type = "RenderableFov", + Body = "OSIRIS-REX", Frame = "ORX_REXIS", - RGB = { 0.8, 0.7, 0.7 }, + RGB = { 0.8, 0.7, 0.7 }, Instrument = { - Name = "ORX_REXIS", - Method = "ELLIPSOID", + Name = "ORX_REXIS", + Method = "ELLIPSOID", Aberration = "NONE" }, PotentialTargets = { BENNU_BODY }, @@ -316,5 +155,9 @@ local RexisFov = { } assetHelper.registerSceneGraphNodesAndExport(asset, { - OsirisRex, PolyCam, Rexis, PolyCamFov, RexisFov + OsirisRex, + PolyCam, + Rexis, + PolyCamFov, + RexisFov }) diff --git a/data/assets/scene/solarsystem/missions/osirisrex/models.asset b/data/assets/scene/solarsystem/missions/osirisrex/models.asset new file mode 100644 index 0000000000..cdd95678ff --- /dev/null +++ b/data/assets/scene/solarsystem/missions/osirisrex/models.asset @@ -0,0 +1,8 @@ +local models = asset.syncedResource({ + Name = "Bennu Models", + Type = "HttpSynchronization", + Identifier = "bennu_models", + Version = 2 +}) + +asset.export('models', models) diff --git a/data/assets/scene/solarsystem/missions/osirisrex/osirisrex.asset b/data/assets/scene/solarsystem/missions/osirisrex/osirisrex.asset index ff5d7658b6..8428875ce3 100644 --- a/data/assets/scene/solarsystem/missions/osirisrex/osirisrex.asset +++ b/data/assets/scene/solarsystem/missions/osirisrex/osirisrex.asset @@ -1,4 +1,4 @@ -asset.require('./bennu') +asset.require('./bennu_projection') asset.require('./model') asset.require('./trail') asset.require('scene/solarsystem/sun/marker') diff --git a/data/assets/scene/solarsystem/missions/perseverance/model.asset b/data/assets/scene/solarsystem/missions/perseverance/model.asset index f11c247d21..cbe8099d9f 100644 --- a/data/assets/scene/solarsystem/missions/perseverance/model.asset +++ b/data/assets/scene/solarsystem/missions/perseverance/model.asset @@ -1,6 +1,6 @@ --perseverance/model.asset local assetHelper = asset.require('util/asset_helper') -local transforms = asset.require('./transforms') +local trail = asset.require('./trail') local marsTransforms = asset.require('scene/solarsystem/planets/mars/transforms') local sunTransforms = asset.require('scene/solarsystem/sun/transforms') -- asset.require('./fov') @@ -29,7 +29,7 @@ local models = asset.syncedResource({ -- Perseverance Model -- local Perseverance = { Identifier = "Perseverance", - Parent = transforms.MSL_Body.Identifier, + Parent = trail.PerseveranceNode.Identifier, GUI = { Name = "Perseverance", Path = "/Solar System/Missions/Perseverance" @@ -56,7 +56,8 @@ local Body = { Body = "MARS SCIENCE LABORATORY", GeometryFile = models .. "/Perseverance.obj", LightSources = LightSources, - PerformShading = false + PerformShading = false, + RotationVector = {65.940000,201.389999,263.980011} }, GUI = { Name = "Perseverance Model Body", diff --git a/data/assets/scene/solarsystem/missions/perseverance/trail.asset b/data/assets/scene/solarsystem/missions/perseverance/trail.asset index 79ccffb602..10c76a45eb 100644 --- a/data/assets/scene/solarsystem/missions/perseverance/trail.asset +++ b/data/assets/scene/solarsystem/missions/perseverance/trail.asset @@ -60,10 +60,11 @@ local PerseveranceTrailSun = { Color = { 0.2, 0.7, 0.1 }, StartTime = startTime, EndTime = endTime, - SampleInterval = 100 + SampleInterval = 100, + Enabled = false }, GUI = { - Name = "Perseverance Trail", + Name = "Perseverance Trail (Sun)", Path = "/Solar System/Missions/Perseverance" } } @@ -82,7 +83,8 @@ local PerseveranceTrailMars = { Color = { 0.7, 0.9, 0.6 }, StartTime = approachMars, EndTime = endTime, - SampleInterval = 100 + SampleInterval = 100, + Enabled = false }, GUI = { Name = "Perseverance Trail (Mars)", diff --git a/data/assets/scene/solarsystem/missions/perseverance/transforms.asset b/data/assets/scene/solarsystem/missions/perseverance/transforms.asset deleted file mode 100644 index c4caed35ac..0000000000 --- a/data/assets/scene/solarsystem/missions/perseverance/transforms.asset +++ /dev/null @@ -1,503 +0,0 @@ -local assetHelper = asset.require('util/asset_helper') -local marsTransforms = asset.require('scene/solarsystem/planets/mars/transforms') -local marsAsset = asset.require('scene/solarsystem/planets/mars/mars') -local trailAsset = asset.require('./trail') - - -local MSL_Body = { - Identifier = "MSL_Body", - Parent = trailAsset.PerseveranceNode.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0, 0.0, 2.8 } - }, - Rotation = { - Type = "StaticRotation", - Rotation = { -0.521593,0.648407,2.888407 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - ----- ROBOTIC ARM RA ---- -local RA_Base_Location = { - Identifier = "RA_Base_Location", - Parent = MSL_Body.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 1.111, -0.4525, -0.106 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - ---AZ -local RA_Shoulder_AZ_Location = { - Identifier = "RA_Shoulder_AZ_Location", - Parent = RA_Base_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0.0, 0.0, -0.08 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -----EL -local RA_Shoulder_EL_Location = { - Identifier = "RA_Shoulder_EL_Location", - Parent = RA_Shoulder_AZ_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0.17, 0.2, -0.005 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - ---ELBOW -local RA_Elbow_Location = { - Identifier = "RA_Elbow_Location", - Parent = RA_Shoulder_EL_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0.83, -0.2, 0.0 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - ---WRIST -local RA_Wrist_Location = { - Identifier = "RA_Wrist_Location", - Parent = RA_Elbow_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0.77, 0.13, 0.035 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - ---TURRET -local RA_Turret_Location = { - Identifier = "RA_Turret_Location", - Parent = RA_Wrist_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0.0, 0.04, -0.15 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - ---MAHLI -local RA_Mahli_Location = { - Identifier = "RA_Mahli_Location", - Parent = RA_Turret_Location.Identifier -} - ----- MASTCAM RSM ---- -local RSM_ROOT_Location = { - Identifier = "RSM_ROOT_Location", - Parent = MSL_Body.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0.7039, 0.5769, -0.563 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -local RSM_AZ_Location = { - Identifier = "RSM_AZ_Location", - Parent = RSM_ROOT_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0.0, 0.008, 0.0 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -local RSM_ZERO_EL_Location = { - Identifier = "RSM_ZERO_EL_Location", - Parent = RSM_AZ_Location.Identifier, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -local RSM_EL_Location = { - Identifier = "RSM_EL_Location", - Parent = RSM_AZ_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - --Position = {0.0, 0.0, -0.664} - Position = { 0.002, 0.007, -0.688 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - ----- HIGH GAIN ANTENNA HGA ---- -local HGA_AZ_Location = { - Identifier = "HGA_AZ_Location", - Parent = MSL_Body.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { -0.46, -0.47, -0.55 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -local HGA_EL_Location = { - Identifier = "HGA_EL_Location", - Parent = HGA_AZ_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0.0, 0.0, -0.17 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - ----- SAM & HEMIN ---- -local SAM_Cover_1_Location = { - Identifier = "SAM_Cover_1_Location", - Parent = MSL_Body.Identifier, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -local SAM_Cover_2_Location = { - Identifier = "SAM_Cover_2_Location", - Parent = MSL_Body.Identifier, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -local CHEMIN_Location = { - Identifier = "CHEMIN_Location", - Parent = MSL_Body.Identifier, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - ----- Wheels ---- -local Wheel_base_Location = { - Identifier = "Wheel_base_Location", - Parent = MSL_Body.Identifier, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - --- Left side -- -local Leg_1_L_Location = { - Identifier = "Leg_1_L_Location", - Parent = Wheel_base_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0.217, -0.812, -0.215 } --for the right side - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -local Leg_2_L_Location = { - Identifier = "Leg_2_L_Location", - Parent = Leg_1_L_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { -0.74, -0.00380, 0.223 } --CORRECT, DONT CHANGE - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -local Wrist_F_L_Location = { - Identifier = "Wrist_F_L_Location", - Parent = Leg_1_L_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0.8839, -0.2659, 0.2 } --CORRECT, DONT TOUCH - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -local Wheel_F_L_Location = { - Identifier = "Wheel_F_L_Location", - Parent = Wrist_F_L_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0.0, 0.0, 0.426 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -local Wheel_C_L_Location = { - Identifier = "Wheel_C_L_Location", - Parent = Leg_2_L_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0.45, -0.4, 0.403 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -local Wrist_B_L_Location = { - Identifier = "Wrist_B_L_Location", - Parent = Leg_2_L_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { -0.627, -0.2635, -0.022 } --CORRECT, DONT CHANGE - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -local Wheel_B_L_Location = { - Identifier = "Wheel_B_L_Location", - Parent = Wrist_B_L_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0.0, -0.0, 0.426 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - --- wheels, Right Side -- -local Leg_1_R_Location = { - Identifier = "Leg_1_R_Location", - Parent = Wheel_base_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0.217, 0.812, -0.215 } --Check with caroline!!! - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -local Leg_2_R_Location = { - Identifier = "Leg_2_R_Location", - Parent = Leg_1_R_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - --Position = {-0.74, 0.0, 0.24} - Position = { -0.74, 0.00380, 0.223 } --want to use this one, once the center point is changed in maya - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -local Wrist_F_R_Location = { - Identifier = "Wrist_F_R_Location", - Parent = Leg_1_R_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0.882, 0.259, 0.215 } - --Position = {0.8839, 0.2659, 0.2} --position for the Wrist_F_L - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -local Wheel_F_R_Location = { - Identifier = "Wheel_F_R_Location", - Parent = Wrist_F_R_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0.0, 0.0, 0.426 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -local Wheel_C_R_Location = { - Identifier = "Wheel_C_R_Location", - Parent = Leg_2_R_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0.45, 0.4, 0.403 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -local Wrist_B_R_Location = { - Identifier = "Wrist_B_R_Location", - Parent = Leg_2_R_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { -0.6208, 0.2759, -0.025 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -local Wheel_B_R_Location = { - Identifier = "Wheel_B_R_Location", - Parent = Wrist_B_R_Location.Identifier, - Transform = { - Translation = { - Type = "StaticTranslation", - Position = { 0.0, -0.0005, 0.426 } - } - }, - GUI = { - Path = "/Solar System/Missions/Perseverance/Transforms", - Hidden = true - } -} - -assetHelper.registerSceneGraphNodesAndExport(asset, { - MSL_Body, - RA_Base_Location, - RA_Shoulder_AZ_Location, - RA_Shoulder_EL_Location, - RA_Elbow_Location, - RA_Wrist_Location, - RA_Turret_Location, - RA_Mahli_Location, - RSM_ROOT_Location, - RSM_AZ_Location, - RSM_ZERO_EL_Location, - RSM_EL_Location, - - HGA_AZ_Location, - HGA_EL_Location, - SAM_Cover_1_Location, - SAM_Cover_2_Location, - CHEMIN_Location, - - Wheel_base_Location, - Leg_1_L_Location, - Leg_2_L_Location, - Wrist_F_L_Location, - Wheel_F_L_Location, - Wheel_C_L_Location, - Wrist_B_L_Location, - Wheel_B_L_Location, - - Leg_1_R_Location, - Leg_2_R_Location, - Wrist_F_R_Location, - Wheel_F_R_Location, - Wheel_C_R_Location, - Wrist_B_R_Location, - Wheel_B_R_Location -}) diff --git a/data/assets/scene/solarsystem/missions/voyager/voyager1.asset b/data/assets/scene/solarsystem/missions/voyager/voyager1.asset index 922dfa6c03..85d6b3bf30 100644 --- a/data/assets/scene/solarsystem/missions/voyager/voyager1.asset +++ b/data/assets/scene/solarsystem/missions/voyager/voyager1.asset @@ -83,7 +83,7 @@ local Voyager1Main = { } local Voyager1Antenna = { - Identifier = "Voyager_1_Antanna", + Identifier = "Voyager_1_Antenna", Parent = Voyager1.Identifier, Renderable = { Type = "RenderableModel", @@ -92,7 +92,7 @@ local Voyager1Antenna = { LightSources = LightSources }, GUI = { - Name = "Voyager 1 Antanna", + Name = "Voyager 1 Antenna", Path = "/Solar System/Missions/Voyager 1" } } diff --git a/data/assets/scene/solarsystem/missions/voyager/voyager2.asset b/data/assets/scene/solarsystem/missions/voyager/voyager2.asset index 8cbe9dcbac..812c3d29a2 100644 --- a/data/assets/scene/solarsystem/missions/voyager/voyager2.asset +++ b/data/assets/scene/solarsystem/missions/voyager/voyager2.asset @@ -87,7 +87,7 @@ local Voyager2Main = { } local Voyager2Antenna = { - Identifier = "Voyager_2_Antanna", + Identifier = "Voyager_2_Antenna", Parent = Voyager2.Identifier, Renderable = { Type = "RenderableModel", @@ -96,7 +96,7 @@ local Voyager2Antenna = { LightSources = LightSources }, GUI = { - Name = "Voyager 2 Antanna", + Name = "Voyager 2 Antenna", Path = "/Solar System/Missions/Voyager 2" } } @@ -116,7 +116,7 @@ local VoyagerTrailCruiseEarthJupiter = { Kernels = Kernels }, Color = { 0.70, 0.50, 0.20 }, - StartTime = "1977 SEP 05", + StartTime = "1977-AUG-20 16:07:06.535", EndTime = "1979 JUL 06", SampleInterval = 669 * 2 -- 669 is the number of days between the Start and End time }, diff --git a/data/assets/scene/solarsystem/planets/earth/earth.asset b/data/assets/scene/solarsystem/planets/earth/earth.asset index fb34cd82d1..ef29f8c1f3 100644 --- a/data/assets/scene/solarsystem/planets/earth/earth.asset +++ b/data/assets/scene/solarsystem/planets/earth/earth.asset @@ -23,21 +23,16 @@ local Earth = { } }, Labels = { - Enable = false, + Enabled = false, FileName = labelsPath .. "/Earth.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 40.0, - LabelsSize = 4.0, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - LabelsFadeOutEnabled = true, - FadeInStartingDistance = 300000.0, - FadeOutStartingDistance = 10000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 1500000.0, - LabelsColor = { 1.0, 0.0, 0.0 } + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 5.0, + FadeInEnabled = true, + FadeOutEnabled = true, + FadeDistances = { 10000.0, 300000.0 }, + DistanceEPS = 1500000.0, + Color = { 1.0, 0.0, 0.0 } } }, Tag = { "planet_solarSystem", "planet_terrestrial" }, @@ -54,20 +49,16 @@ local EarthLabel = { Renderable = { Enabled = false, Type = "RenderableLabels", - LabelText = "Earth", - FontSize = 100.0, - LabelSize = 8.6, - LabelMaxSize = 100.0, - LabelMinSize = 1.0, - LabelOrientationOption = "Camera View Direction", + Text = "Earth", + FontSize = 70.0, + Size = 8.77, + MinMaxSize = { 1, 100 }, + OrientationOption = "Camera View Direction", BlendMode = "Additive", EnableFading = true, - FadeStartUnit = "au", - FadeStartDistance = 1.5, - FadeStartSpeed = 1.0, - FadeEndUnit = "au", - FadeEndDistance = 15.0, - FadeEndSpeed = 25.0 + FadeUnit = "au", + FadeDistances = { 1.5, 15.0 }, + FadeWidths = { 1.0, 25.0 } }, Tag = { "solarsystem_labels" }, GUI = { diff --git a/data/assets/scene/solarsystem/planets/earth/lagrange_points/L1.asset b/data/assets/scene/solarsystem/planets/earth/lagrange_points/L1.asset new file mode 100644 index 0000000000..420ff19185 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/earth/lagrange_points/L1.asset @@ -0,0 +1,59 @@ +local assetHelper = asset.require('util/asset_helper') +local transforms = asset.require('scene/solarsystem/sun/transforms') +local circle = asset.require('util/circle').circle +local kernels = asset.require('scene/solarsystem/planets/earth/lagrange_points/lagrange_kernels').kernels +asset.require('spice/base') + +local L1 = { + Identifier = "L1", + Parent = transforms.SolarSystemBarycenter.Identifier, + Renderable = { + Enabled = false, + Type = "RenderablePlaneImageLocal", + RenderableType = "Opaque", + Billboard = true, + Size = 700E5, + Texture = circle .. "/circle.png", + BlendMode = "Additive" + }, + Transform = { + Translation = { + Type = "SpiceTranslation", + Target = "391", -- L1 + Observer = "SUN", + Kernels = kernels .. "/L1_de431.bsp" + } + }, + Tag = { "lagrange_points_earth" , "lagrange_points_earth_l1" }, + GUI = { + Name = "L1", + Path = "/Solar System/Planets/Earth/Lagrange points", + } +} + +local L1Label = { + Identifier = "L1Label", + Parent = L1.Identifier, + Renderable = { + Enabled = false, + Type = "RenderableLabels", + Text = "L1", + FontSize = 20, + Size = 7.5, + MinMaxSize = { 1.0, 100.0}, + OrientationOption = "Camera View Direction", + BlendMode = "Normal", + EnableFading = false + }, + Tag = { "lagrange_points_earth", "lagrange_points_earth_l1" }, + GUI = { + Name = "L1 Label", + Path = "/Solar System/Planets/Earth/Lagrange points", + Description = "Main label for L1" + } +} + +assetHelper.registerSceneGraphNodesAndExport(asset, { + L1, + L1Label +}) diff --git a/data/assets/scene/solarsystem/planets/earth/lagrange_points/L2.asset b/data/assets/scene/solarsystem/planets/earth/lagrange_points/L2.asset new file mode 100644 index 0000000000..0f84519837 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/earth/lagrange_points/L2.asset @@ -0,0 +1,127 @@ +local assetHelper = asset.require('util/asset_helper') +local transforms = asset.require('scene/solarsystem/sun/transforms') +local circle = asset.require('util/circle').circle +local kernels = asset.require('scene/solarsystem/planets/earth/lagrange_points/lagrange_kernels').kernels +asset.require('spice/base') + +local L2Small = { + Identifier = "L2Small", + Parent = transforms.SolarSystemBarycenter.Identifier, + Renderable = { + Type = "RenderablePlaneImageLocal", + RenderableType = "Opaque", + Billboard = true, + Size = 400E4, + Texture = circle .. "/circle.png", + BlendMode = "Additive" + }, + Transform = { + Translation = { + Type = "SpiceTranslation", + Target = "392", -- L2 + Observer = "SUN", + Kernels = kernels .. "/L2_de431.bsp" + } + }, + Tag = { "lagrange_points_earth_l2_small" }, + GUI = { + Name = "Small L2", + Path = "/Solar System/Planets/Earth/Lagrange points", + } +} + +local L2 = { + Identifier = "L2", + Parent = transforms.SolarSystemBarycenter.Identifier, + Renderable = { + Enabled = false, + Type = "RenderablePlaneImageLocal", + RenderableType = "Opaque", + Billboard = true, + Size = 700E5, + Texture = circle .. "/circle.png", + BlendMode = "Additive" + }, + Transform = { + Translation = { + Type = "SpiceTranslation", + Target = "392", -- L2 + Observer = "SUN", + Kernels = kernels .. "/L2_de431.bsp" + } + }, + Tag = { "lagrange_points_earth", "lagrange_points_earth_l2" }, + GUI = { + Name = "L2", + Path = "/Solar System/Planets/Earth/Lagrange points", + } +} + +local L2SmallLabel = { + Identifier = "L2SmallLabel", + Parent = L2.Identifier, + Renderable = { + Enabled = true, + Type = "RenderableLabels", + Text = "L2", + FontSize = 20.0, + Size = 6.0, + MinMaxSize = { 1.0, 100.0 }, + OrientationOption = "Camera View Direction", + BlendMode = "Normal", + EnableFading = false + }, + Tag = { "lagrange_points_earth_l2_small" }, + GUI = { + Name = "Small L2 Label", + Path = "/Solar System/Planets/Earth/Lagrange points", + Description = "Small label for L2" + } +} + +local L2Label = { + Identifier = "L2Label", + Parent = L2.Identifier, + Renderable = { + Enabled = false, + Type = "RenderableLabels", + Text = "L2", + FontSize = 20, + Size = 7.5, + MinMaxSize = { 1.0, 100.0}, + OrientationOption = "Camera View Direction", + BlendMode = "Normal", + EnableFading = false + }, + Tag = { "lagrange_points_earth", "lagrange_points_earth_l2" }, + GUI = { + Name = "L2 Label", + Path = "/Solar System/Planets/Earth/Lagrange points", + Description = "Main label for L2" + } +} + +local L2SunLine = { + Identifier = "L2SunLine", + Parent = transforms.SolarSystemBarycenter.Identifier, + Renderable = { + Type = "RenderableNodeLine", + StartNode = "Sun", + EndNode = "L2Small", + Color = { 0.5, 0.5, 0.5 }, + LineWidth = 2 + }, + Tag = { "lagrange_points_earth_l2_small" }, + GUI = { + Name = "Sun to L2 Line", + Path = "/Solar System/Planets/Earth/Lagrange points", + } +} + +assetHelper.registerSceneGraphNodesAndExport(asset, { + L2Small, + L2, + L2SunLine, + L2SmallLabel, + L2Label +}) diff --git a/data/assets/scene/solarsystem/planets/earth/lagrange_points/L4.asset b/data/assets/scene/solarsystem/planets/earth/lagrange_points/L4.asset new file mode 100644 index 0000000000..05ca2a57b5 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/earth/lagrange_points/L4.asset @@ -0,0 +1,59 @@ +local assetHelper = asset.require('util/asset_helper') +local transforms = asset.require('scene/solarsystem/sun/transforms') +local circle = asset.require('util/circle').circle +local kernels = asset.require('scene/solarsystem/planets/earth/lagrange_points/lagrange_kernels').kernels +asset.require('spice/base') + +local L4 = { + Identifier = "L4", + Parent = transforms.SolarSystemBarycenter.Identifier, + Renderable = { + Enabled = false, + Type = "RenderablePlaneImageLocal", + RenderableType = "Opaque", + Billboard = true, + Size = 800E6, + Texture = circle .. "/circle.png", + BlendMode = "Additive" + }, + Transform = { + Translation = { + Type = "SpiceTranslation", + Target = "394", -- L4 + Observer = "SUN", + Kernels = kernels .. "/L4_de431.bsp" + } + }, + Tag = { "lagrange_points_earth", "lagrange_points_earth_l4" }, + GUI = { + Name = "L4", + Path = "/Solar System/Planets/Earth/Lagrange points", + } +} + +local L4Label = { + Identifier = "L4Label", + Parent = L4.Identifier, + Renderable = { + Enabled = false, + Type = "RenderableLabels", + Text = "L4", + FontSize = 20, + Size = 8.5, + MinMaxSize = { 1.0, 100.0 }, + OrientationOption = "Camera View Direction", + BlendMode = "Normal", + EnableFading = false + }, + Tag = { "lagrange_points_earth", "lagrange_points_earth_l4" }, + GUI = { + Name = "L4 Label", + Path = "/Solar System/Planets/Earth/Lagrange points", + Description = "Main label for L4" + } +} + +assetHelper.registerSceneGraphNodesAndExport(asset, { + L4, + L4Label +}) diff --git a/data/assets/scene/solarsystem/planets/earth/lagrange_points/L5.asset b/data/assets/scene/solarsystem/planets/earth/lagrange_points/L5.asset new file mode 100644 index 0000000000..dcaabb12b7 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/earth/lagrange_points/L5.asset @@ -0,0 +1,59 @@ +local assetHelper = asset.require('util/asset_helper') +local transforms = asset.require('scene/solarsystem/sun/transforms') +local circle = asset.require('util/circle').circle +local kernels = asset.require('scene/solarsystem/planets/earth/lagrange_points/lagrange_kernels').kernels +asset.require('spice/base') + +local L5 = { + Identifier = "L5", + Parent = transforms.SolarSystemBarycenter.Identifier, + Renderable = { + Enabled = false, + Type = "RenderablePlaneImageLocal", + RenderableType = "Opaque", + Billboard = true, + Size = 800E6, + Texture = circle .. "/circle.png", + BlendMode = "Additive" + }, + Transform = { + Translation = { + Type = "SpiceTranslation", + Target = "395", -- L5 + Observer = "SUN", + Kernels = kernels .. "/L5_de431.bsp" + } + }, + Tag = { "lagrange_points_earth", "lagrange_points_earth_l5" }, + GUI = { + Name = "L5", + Path = "/Solar System/Planets/Earth/Lagrange points", + } +} + +local L5Label = { + Identifier = "L5Label", + Parent = L5.Identifier, + Renderable = { + Enabled = false, + Type = "RenderableLabels", + Text = "L5", + FontSize = 20, + Size = 8.5, + MinMaxSize = { 1.0, 100.0 }, + OrientationOption = "Camera View Direction", + BlendMode = "Normal", + EnableFading = false + }, + Tag = { "lagrange_points_earth", "lagrange_points_earth_l5" }, + GUI = { + Name = "L5 Label", + Path = "/Solar System/Planets/Earth/Lagrange points", + Description = "Main label for L5" + } +} + +assetHelper.registerSceneGraphNodesAndExport(asset, { + L5, + L5Label +}) diff --git a/data/assets/scene/solarsystem/planets/earth/lagrange_points/lagrange_kernels.asset b/data/assets/scene/solarsystem/planets/earth/lagrange_points/lagrange_kernels.asset new file mode 100644 index 0000000000..b78370a3a8 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/earth/lagrange_points/lagrange_kernels.asset @@ -0,0 +1,8 @@ +local kernels = asset.syncedResource({ + Name = "Lagrange Kernels", + Type = "HttpSynchronization", + Identifier = "earth_lagrange_kernels", + Version = 1 +}) + +asset.export('kernels', kernels) diff --git a/data/assets/scene/solarsystem/planets/earth/lagrange_points/lagrange_points.asset b/data/assets/scene/solarsystem/planets/earth/lagrange_points/lagrange_points.asset new file mode 100644 index 0000000000..8c4d507ca0 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/earth/lagrange_points/lagrange_points.asset @@ -0,0 +1,4 @@ +asset.require('scene/solarsystem/planets/earth/lagrange_points/L1') +asset.require('scene/solarsystem/planets/earth/lagrange_points/L2') +asset.require('scene/solarsystem/planets/earth/lagrange_points/L4') +asset.require('scene/solarsystem/planets/earth/lagrange_points/L5') diff --git a/data/assets/scene/solarsystem/planets/earth/moon/moon.asset b/data/assets/scene/solarsystem/planets/earth/moon/moon.asset index f24995d8bd..f3cd2cea9a 100644 --- a/data/assets/scene/solarsystem/planets/earth/moon/moon.asset +++ b/data/assets/scene/solarsystem/planets/earth/moon/moon.asset @@ -34,21 +34,16 @@ local Moon = { } }, Labels = { - Enable = false, + Enabled = false, FileName = labelsPath .. "/moon.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 14.0, - LabelsSize = 8.0, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - LabelsFadeOutEnabled = true, - FadeInStartingDistance = 500000.0, - FadeOutStartingDistance = 100000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 1350000.0, - LabelsColor = { 1.0, 1.0, 0.0 } + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 7.6, + FadeInEnabled = true, + FadeOutEnabled = true, + FadeDistances = { 100000.0, 500000.0 }, + DistanceEPS = 1350000.0, + Color = { 1.0, 1.0, 0.0 } } }, GUI = { diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset b/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset index 54defe6c21..3c12782da0 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset @@ -46,12 +46,12 @@ local initializeAndAddNodes = function() } local parentNode = { - Identifier = "ISSparentNode", + Identifier = "ISSModel", Parent = iss.Identifier, Transform = { Rotation = { Type = "FixedRotation", - Attached = "ISSparentNode", + Attached = "ISSModel", XAxis = { 0.01, -1.0, 0.56 }, XAxisOrthogonal = true, YAxis = transforms.EarthInertial.Identifier @@ -73,9 +73,8 @@ local initializeAndAddNodes = function() DisableFaceCulling = true }, GUI = { - Name = "ISSparentNode", - Path = "/Solar System/Planets/Earth/Satellites/ISS", - Hidden = true, + Name = "ISS Model", + Path = "/Solar System/Planets/Earth/Satellites/ISS" } } @@ -104,34 +103,29 @@ local initializeAndAddNodes = function() } } + -- @TODO (emmbr, 2021-05-27) add to scene when label rendering issues have been fixed local IssLabel = { Identifier = "IssLabel", Parent = iss.Identifier, - Renderable = { Enabled = false, Type = "RenderableLabels", - LabelText = "ISS", - FontSize = 100.0, - LabelSize = 3.4, - LabelMaxSize = 100.0, - LabelMinSize = 1.0, - LabelOrientationOption = "Camera View Direction", + Text = "ISS", + FontSize = 70.0, + Size = 3.4, + MinMaxSize = { 1, 100 }, + OrientationOption = "Camera View Direction", BlendMode = "Additive", EnableFading = true, - FadeStartUnit = "au", - FadeStartDistance = 0.15, - FadeStartSpeed = 1.0, - FadeEndUnit = "au", - FadeEndDistance = 15.0, - FadeEndSpeed = 25.0 + FadeDistances = { 0.15, 15.0 }, + FadeWidths = { 1.0, 25.0 } }, Tag = { "solarsystem_labels" }, GUI = { Name = "ISS Label", Path = "/Solar System/Planets/Earth/Satellites" } -} + } return { iss, parentNode, issTrail } end @@ -141,7 +135,7 @@ asset.onInitialize(function () for _, node in ipairs(nodes) do openspace.addSceneGraphNode(node) end - openspace.setPropertyValueSingle("Scene.ISSparentNode.Rotation.yAxis-InvertObject", true) + openspace.setPropertyValueSingle("Scene.ISSModel.Rotation.yAxisInvertObject", true) end) diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/weather/aqua.asset b/data/assets/scene/solarsystem/planets/earth/satellites/weather/aqua.asset index 96c6e5561b..0713514a18 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/aqua.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/aqua.asset @@ -59,38 +59,35 @@ asset.onInitialize(function () }, Tag = { "earth_satellite", "Aqua" }, GUI = { - Name = "Terra Trail", + Name = "Aqua Trail", Path = "/Solar System/Planets/Earth/Satellites/Aqua" } } + -- @TODO (emmbr, 2021-05-27) this label is not visible. Too large fade distances? + -- Might also be affected by the rendering issues for labels local AquaLabel = { - Identifier = "AquaLabel", - Parent = Aqua.Identifier, - - Renderable = { - Enabled = false, - Type = "RenderableLabels", - LabelText = "SNPP", - FontSize = 100.0, - LabelSize = 4.0, - LabelMaxSize = 100.0, - LabelMinSize = 1.0, - LabelOrientationOption = "Camera View Direction", - BlendMode = "Additive", - EnableFading = true, - FadeStartUnit = "au", - FadeStartDistance = 0.15, - FadeStartSpeed = 1.0, - FadeEndUnit = "au", - FadeEndDistance = 15.0, - FadeEndSpeed = 25.0 - }, - Tag = { "solarsystem_labels" }, - GUI = { - Name = "Aqua Label", - Path = "/Solar System/Planets/Earth" - } + Identifier = "AquaLabel", + Parent = Aqua.Identifier, + Renderable = { + Enabled = false, + Type = "RenderableLabels", + Text = "Aqua", + FontSize = 70.0, + Size = 4.0, + MinMaxSize = { 1, 100 }, + OrientationOption = "Camera View Direction", + BlendMode = "Additive", + EnableFading = true, + FadeUnit = "au", + FadeDistances = { 1.5, 15.0 }, + FadeWidths = { 1.0, 25.0 } + }, + Tag = { "solarsystem_labels" }, + GUI = { + Name = "Aqua Label", + Path = "/Solar System/Planets/Earth" + } } table.insert(nodes, Aqua) diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/weather/snpp.asset b/data/assets/scene/solarsystem/planets/earth/satellites/weather/snpp.asset index 9564cd31d6..56a3146324 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/snpp.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/snpp.asset @@ -67,32 +67,28 @@ asset.onInitialize(function () } local SNPPLabel = { - Identifier = "SNPPLabel", - Parent = SNPP.Identifier, + Identifier = "SNPPLabel", + Parent = SNPP.Identifier, - Renderable = { - Enabled = false, - Type = "RenderableLabels", - LabelText = "SNPP", - FontSize = 100.0, - LabelSize = 4.0, - LabelMaxSize = 100.0, - LabelMinSize = 1.0, - LabelOrientationOption = "Camera View Direction", - BlendMode = "Additive", - EnableFading = true, - FadeStartUnit = "au", - FadeStartDistance = 0.15, - FadeStartSpeed = 1.0, - FadeEndUnit = "au", - FadeEndDistance = 15.0, - FadeEndSpeed = 25.0 - }, - Tag = { "solarsystem_labels" }, - GUI = { - Name = "SNPP Label", - Path = "/Solar System/Planets/Earth" - } + Renderable = { + Enabled = false, + Type = "RenderableLabels", + Text = "SNPP", + FontSize = 70.0, + Size = 4.0, + MinMaxSize = { 1, 100 }, + OrientationOption = "Camera View Direction", + BlendMode = "Additive", + EnableFading = true, + FadeUnit = "au", + FadeDistances = { 1.5, 15.0 }, + FadeWidths = { 1.0, 25.0 } + }, + Tag = { "solarsystem_labels" }, + GUI = { + Name = "SNPP Label", + Path = "/Solar System/Planets/Earth" + } } table.insert(nodes, SNPP) diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/weather/terra.asset b/data/assets/scene/solarsystem/planets/earth/satellites/weather/terra.asset index 9065e44536..49c0fc93d1 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/terra.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/terra.asset @@ -66,33 +66,30 @@ asset.onInitialize(function () } } + -- @TODO (emmbr, 2021-05-27) this label is not visible. Too large fade distances? + -- Might also be affected by the rendering issues for labels local TerraLabel = { - Identifier = "TerraLabel", - Parent = Terra.Identifier, - - Renderable = { - Enabled = false, - Type = "RenderableLabels", - LabelText = "SNPP", - FontSize = 100.0, - LabelSize = 4.0, - LabelMaxSize = 100.0, - LabelMinSize = 1.0, - LabelOrientationOption = "Camera View Direction", - BlendMode = "Additive", - EnableFading = true, - FadeStartUnit = "au", - FadeStartDistance = 0.15, - FadeStartSpeed = 1.0, - FadeEndUnit = "au", - FadeEndDistance = 15.0, - FadeEndSpeed = 25.0 - }, - Tag = { "solarsystem_labels" }, - GUI = { - Name = "Terra Label", - Path = "/Solar System/Planets/Earth" - } + Identifier = "TerraLabel", + Parent = Terra.Identifier, + Renderable = { + Enabled = false, + Type = "RenderableLabels", + Text = "Terra", + FontSize = 70.0, + Size = 4.0, + MinMaxSize = { 1, 100 }, + OrientationOption = "Camera View Direction", + BlendMode = "Additive", + EnableFading = true, + FadeUnit = "au", + FadeDistances = { 1.5, 15.0 }, + FadeWidths = { 1.0, 25.0 } + }, + Tag = { "solarsystem_labels" }, + GUI = { + Name = "Terra Label", + Path = "/Solar System/Planets/Earth" + } } table.insert(nodes, Terra) diff --git a/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto.asset b/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto.asset index f62b20513d..c4503abea0 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto.asset @@ -28,21 +28,17 @@ local Callisto = { SegmentsPerPatch = 64, Layers = {}, Labels = { - Enable = false, + Enabled = false, FileName = labelsPath .. "/callisto.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 40.0, - LabelsSize = 10.5, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - LabelsFadeOutEnabled = true, - FadeInStartingDistance = 15000000.0, - FadeOutStartingDistance = 5000000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 1350000.0, - LabelsColor = { 1.0, 1.0, 0.0 } + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 11.5, + MinMaxSize = { 1, 100 }, + FadeInEnabled = true, + FadeOutEnabled = true, + FadeDistances = { 5000000.0, 15000000.0 }, + DistanceEPS = 1350000.0, + Color = { 1.0, 1.0, 0.0 } } }, Tag = { "moon_solarSystem", "moon_giants", "moon_jupiter" }, diff --git a/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto_textures.asset b/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto_textures.asset index 80621e6bee..c6cc74bb68 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto_textures.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto_textures.asset @@ -2,6 +2,6 @@ local TexturesPath = asset.syncedResource({ Name = "Callisto Textures", Type = "HttpSynchronization", Identifier = "callisto_textures", - Version = 1 + Version = 2 }) asset.export("TexturesPath", TexturesPath) diff --git a/data/assets/scene/solarsystem/planets/jupiter/callisto/layers/colorlayers/callisto_texture.asset b/data/assets/scene/solarsystem/planets/jupiter/callisto/layers/colorlayers/callisto_texture.asset index 9cd2d1cf52..21653cde87 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/callisto/layers/colorlayers/callisto_texture.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/callisto/layers/colorlayers/callisto_texture.asset @@ -3,7 +3,7 @@ local globeIdentifier = asset.require("./../../callisto").Callisto.Identifier local layer = { Identifier = "Texture", - FilePath = texturesPath .. "/callisto.jpg", + FilePath = texturesPath .. "/callisto_os.tif", } asset.onInitialize(function () @@ -15,8 +15,8 @@ asset.export("layer", layer) asset.meta = { Name = "Callisto Texutre", - Version = "1.0", - Description = [[ Default jpg texture for Callisto]], + Version = "2.0", + Description = [[ Default texture for Callisto]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license", diff --git a/data/assets/scene/solarsystem/planets/jupiter/europa/default_layers.asset b/data/assets/scene/solarsystem/planets/jupiter/europa/default_layers.asset index 926c4cc1fa..efb6a7510b 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/europa/default_layers.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/europa/default_layers.asset @@ -1,7 +1,7 @@ local colorLayersPath = "./layers/colorlayers" asset.require(colorLayersPath .. "/europa_texture") -local colorLayer = asset.require(colorLayersPath .. "/voyager_global_mosaic") +local colorLayer = asset.require(colorLayersPath .. "/voyager_global_mosaic_local") -- Set enabled layers (temporary solution) -- @TODO: do this using a boolean that's passed to the 'asset.require' instead diff --git a/data/assets/scene/solarsystem/planets/jupiter/europa/europa.asset b/data/assets/scene/solarsystem/planets/jupiter/europa/europa.asset index 670ee9c7c8..1ecfb93b34 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/europa/europa.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/europa/europa.asset @@ -28,21 +28,16 @@ local Europa = { SegmentsPerPatch = 64, Layers = {}, Labels = { - Enable = false, + Enabled = false, FileName = labelsPath .. "/europa.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 40.0, - LabelsSize = 10.0, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - LabelsFadeOutEnabled = true, - FadeInStartingDistance = 8000000.0, - FadeOutStartingDistance = 5000000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 700000.0, - LabelsColor = { 1.0, 1.0, 0.0 } + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 11.0, + FadeInEnabled = true, + FadeOutEnabled = true, + FadeDistances = { 500000.0, 8000000.0 }, + DistanceEPS = 700000.0, + Color = { 1.0, 1.0, 0.0 } } }, Tag = { "moon_solarSystem", "moon_giants", "moon_jupiter" }, diff --git a/data/assets/scene/solarsystem/planets/jupiter/europa/europa_textures.asset b/data/assets/scene/solarsystem/planets/jupiter/europa/europa_textures.asset index a1eb48b59e..259bec7da5 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/europa/europa_textures.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/europa/europa_textures.asset @@ -2,6 +2,6 @@ local TexturesPath = asset.syncedResource({ Name = "Europa Textures", Type = "HttpSynchronization", Identifier = "europa_textures", - Version = 1 + Version = 2 }) asset.export("TexturesPath", TexturesPath) diff --git a/data/assets/scene/solarsystem/planets/jupiter/europa/layers/colorlayers/europa_texture.asset b/data/assets/scene/solarsystem/planets/jupiter/europa/layers/colorlayers/europa_texture.asset index ed5e691509..1e690211b2 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/europa/layers/colorlayers/europa_texture.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/europa/layers/colorlayers/europa_texture.asset @@ -3,7 +3,8 @@ local globeIdentifier = asset.require("./../../europa").Europa.Identifier local layer = { Identifier = "Texture", - FilePath = texturesPath .. "/europa.jpg", + FilePath = texturesPath .. "/europa_os.tif", + Enabled = true } asset.onInitialize(function () @@ -15,8 +16,8 @@ asset.export("layer", layer) asset.meta = { Name = "Europa Texutre", - Version = "1.0", - Description = [[ Default jpg texture for Europa]], + Version = "2.0", + Description = [[ Default texture for Europa]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/jupiter/europa/layers/colorlayers/voyager_global_mosaic_local.asset b/data/assets/scene/solarsystem/planets/jupiter/europa/layers/colorlayers/voyager_global_mosaic_local.asset new file mode 100644 index 0000000000..36e08d3c16 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/jupiter/europa/layers/colorlayers/voyager_global_mosaic_local.asset @@ -0,0 +1,36 @@ +local texturesPath = asset.require("./../../europa_textures").TexturesPath +local globeIdentifier = asset.require("./../../europa").Europa.Identifier + +local layer = { + Identifier = "Voyager_Global_Mosaic_Local", + Name = "Voyager Global Mosaic [Local]", + FilePath = texturesPath .. "/evgos.vrt", + BlendMode = "Color" +} + +asset.onInitialize(function () + openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer) +end) + +asset.export("layer", layer) + + +asset.meta = { + Name = "Voyager Global Mosaic", + Version = "1.0", + 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", + Identifiers = {"Voyager_Global_Mosaic_Local"} +} + diff --git a/data/assets/scene/solarsystem/planets/jupiter/ganymede/ganymede.asset b/data/assets/scene/solarsystem/planets/jupiter/ganymede/ganymede.asset index 182b8751e9..ccda9c129a 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/ganymede/ganymede.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/ganymede/ganymede.asset @@ -28,21 +28,16 @@ local Ganymede = { SegmentsPerPatch = 64, Layers = {}, Labels = { - Enable = false, + Enabled = false, FileName = labelsPath .. "/ganymede.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 40.0, - LabelsSize = 10.5, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - LabelsFadeOutEnabled = true, - FadeInStartingDistance = 8000000.0, - FadeOutStartingDistance = 2250000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 1750000.0, - LabelsColor = {1.0, 1.0, 0.0} + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 11.5, + FadeInEnabled = true, + FadeOutEnabled = true, + FadeDistances = { 2250000.0, 8000000.0 }, + DistanceEPS = 1750000.0, + Color = {1.0, 1.0, 0.0} } }, Tag = { "moon_solarSystem", "moon_giants", "moon_jupiter" }, diff --git a/data/assets/scene/solarsystem/planets/jupiter/io/io.asset b/data/assets/scene/solarsystem/planets/jupiter/io/io.asset index 50e84eaa6a..641cf411f6 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/io/io.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/io/io.asset @@ -28,21 +28,16 @@ local Io = { SegmentsPerPatch = 64, Layers = {}, Labels = { - Enable = false, + Enabled = false, FileName = labelsPath .. "/io.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 40.0, - LabelsSize = 10.0, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - LabelsFadeOutEnabled = true, - FadeInStartingDistance = 8500000.0, - FadeOutStartingDistance = 4000000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 1000000.0, - LabelsColor = { 1.0, 1.0, 0.0 } + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 11.0, + FadeInEnabled = true, + FadeOutEnabled = true, + FadeDistances = { 4000000.0, 8500000.0 }, + DistanceEPS = 1000000.0, + Color = { 1.0, 1.0, 0.0 } } }, Tag = { "moon_solarSystem", "moon_giants", "moon_jupiter" }, diff --git a/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset b/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset index c24a8d9789..29a7d0495e 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset @@ -42,12 +42,11 @@ local JupiterLabel = { Renderable = { Enabled = false, Type = "RenderableLabels", - LabelText = "Jupiter", - FontSize = 100.0, - LabelSize = 8.6, - LabelMaxSize = 100.0, - LabelMinSize = 1.0, - LabelOrientationOption = "Camera View Direction", + Text = "Jupiter", + FontSize = 70.0, + Size = 8.77, + MinMaxSize = { 1, 100 }, + OrientationOption = "Camera View Direction", BlendMode = "Additive" }, Tag = { "solarsystem_labels" }, diff --git a/data/assets/scene/solarsystem/planets/jupiter/jupiter_textures.asset b/data/assets/scene/solarsystem/planets/jupiter/jupiter_textures.asset index c82f34e5a6..c310a1906b 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/jupiter_textures.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/jupiter_textures.asset @@ -2,6 +2,6 @@ local TexturesPath = asset.syncedResource({ Name = "Jupiter Textures", Type = "HttpSynchronization", Identifier = "jupiter_textures", - Version = 1 + Version = 2 }) asset.export("TexturesPath", TexturesPath) diff --git a/data/assets/scene/solarsystem/planets/jupiter/layers/colorlayers/jupiter_texture.asset b/data/assets/scene/solarsystem/planets/jupiter/layers/colorlayers/jupiter_texture.asset index 0a9de27073..98b2d1543d 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/layers/colorlayers/jupiter_texture.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/layers/colorlayers/jupiter_texture.asset @@ -3,7 +3,7 @@ local globeIdentifier = asset.require("./../../jupiter").Jupiter.Identifier local layer = { Identifier = "Texture", - FilePath = texturesPath .. "/jupiter.jpg", + FilePath = texturesPath .. "/jupiter_os.tif", } asset.onInitialize(function () @@ -15,8 +15,8 @@ asset.export("layer", layer) asset.meta = { Name = "Jupiter Texutre", - Version = "1.0", - Description = [[ Default jpg texture for Jupiter]], + Version = "2.0", + Description = [[ Default texture for Jupiter]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/mars/default_layers.asset b/data/assets/scene/solarsystem/planets/mars/default_layers.asset index db06a922b2..54354cbafd 100644 --- a/data/assets/scene/solarsystem/planets/mars/default_layers.asset +++ b/data/assets/scene/solarsystem/planets/mars/default_layers.asset @@ -23,7 +23,8 @@ asset.require(colorLayersPath .. "/hirisels") -- Height layers asset.require(heightLayersPath .. "/mola_europe") -local heightLayer = asset.require(heightLayersPath .. "/mola_utah") +asset.require(heightLayersPath .. "/mola_utah") +local heightLayer = asset.require(heightLayersPath .. "/MDEM200M") asset.require(heightLayersPath .. "/hirisels") -- Overlays diff --git a/data/assets/scene/solarsystem/planets/mars/layers/heightlayers/MDEM200M.asset b/data/assets/scene/solarsystem/planets/mars/layers/heightlayers/MDEM200M.asset new file mode 100644 index 0000000000..fefc177186 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/mars/layers/heightlayers/MDEM200M.asset @@ -0,0 +1,35 @@ +local mapServiceConfigs = asset.localResource("./../../map_service_configs") +local globeIdentifier = asset.require("./../../mars").Mars.Identifier + +local layer = { + Identifier = "MDEM200M", + Name = "HRSC MOLA Blended DEM Global 200m v2", + FilePath = mapServiceConfigs .. "/ESRI/MDEM200M.tif", + Description = [[ Blend of data derived from the Mars Orbiter Laser Altimeter + (MOLA, an instrument aboard NASA’s + Mars Global Surveyor spacecraft), and data derived from the High-Resolution + Stereo Camera (HRSC, an instrument aboard the European Space Agency’s Mars + Express spacecraft). The average accuracy is ~100 meters in horizontal + position and the elevation uncertainty is at least ±3 m. This + tiled elevation layer, hosted by Esri, is made available using + lossless LERC compression.(Description from URL).]], +} + +asset.onInitialize(function () + openspace.globebrowsing.addLayer(globeIdentifier, "HeightLayers", layer) +end) + +asset.export("layer", layer) + + +asset.meta = { + Name = "Mars HRSC MOLA Blended DEM Global 200m v2", + Version = "1.0", + Description = [[ESRI Hosted ars HRSC MOLA Blended DEM.]], + Author = "esri_astro", + URL = "https://www.arcgis.com/home/item.html?id=225adad86379474ebc3d51a74573c99b", + License = "Esri Master License Agreement", + Identifiers = {"MDEM200M"} +} + + diff --git a/data/assets/scene/solarsystem/planets/mars/map_service_configs/ESRI/MDEM200M.tif b/data/assets/scene/solarsystem/planets/mars/map_service_configs/ESRI/MDEM200M.tif new file mode 100644 index 0000000000..11e11e6d3e --- /dev/null +++ b/data/assets/scene/solarsystem/planets/mars/map_service_configs/ESRI/MDEM200M.tif @@ -0,0 +1,17 @@ + + + http://astro.arcgis.com/arcgis/rest/services/OnMars/MDEM200M/ImageServer/tile/${z}/${y}/${x} + + + -180.0 90.0 + 180.0 -90.0 + 131328 65664 + 7 top + + 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]] + 513 513 + 1 Int16 + + 5 + 404,400 + diff --git a/data/assets/scene/solarsystem/planets/mars/mars.asset b/data/assets/scene/solarsystem/planets/mars/mars.asset index c169c8a568..977d986e99 100644 --- a/data/assets/scene/solarsystem/planets/mars/mars.asset +++ b/data/assets/scene/solarsystem/planets/mars/mars.asset @@ -23,21 +23,16 @@ local Mars = { SegmentsPerPatch = 90, Layers = {}, Labels = { - Enable = false, + Enabled = false, FileName = labelsPath .. "/mars.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 14.0, - LabelsSize = 9.0, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - LabelsFadeOutEnabled = true, - FadeInStartingDistance = 2000000.0, - FadeOutStartingDistance = 750000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 2500000.0, - LabelsColor = { 1.0, 1.0, 0.0 } + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 8.7, + FadeInEnabled = true, + FadeOutEnabled = true, + FadeDistances = { 750000.0, 2000000.0 }, + DistanceEPS = 2500000.0, + Color = { 1.0, 1.0, 0.0 } } }, Tag = { "planet_solarSystem", "planet_terrestrial" }, @@ -54,12 +49,11 @@ local MarsLabel = { Renderable = { Enabled = false, Type = "RenderableLabels", - LabelText = "Mars", - FontSize = 100.0, - LabelSize = 8.5, - LabelMaxSize = 100.0, - LabelMinSize = 1.0, - LabelOrientationOption = "Camera View Direction", + Text = "Mars", + FontSize = 70.0, + Size = 8.66, + MinMaxSize = { 1, 100 }, + OrientationOption = "Camera View Direction", BlendMode = "Additive", TransformationMatrix = { 1.0, 0.0, 0.0, -8.0E6, diff --git a/data/assets/scene/solarsystem/planets/mercury/mercury.asset b/data/assets/scene/solarsystem/planets/mercury/mercury.asset index f1ea2d6c06..ceb774f5ac 100644 --- a/data/assets/scene/solarsystem/planets/mercury/mercury.asset +++ b/data/assets/scene/solarsystem/planets/mercury/mercury.asset @@ -24,21 +24,16 @@ local Mercury = { SegmentsPerPatch = 64, Layers = {}, Labels = { - Enable = false, + Enabled = false, FileName = labelsPath .. "/Mercury.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 22.0, - LabelsSize = 10.0, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - LabelsFadeOutEnabled = true, - FadeInStartingDistance = 5000000.0, - FadeOutStartingDistance = 1800000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 1500000.0, - LabelsColor = { 1.0, 1.0, 0.0 } + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 10.1, + FadeInEnabled = true, + FadeOutEnabled = true, + FadeDistances = { 1800000.0, 5000000.0 }, + DistanceEPS = 1500000.0, + Color = { 1.0, 1.0, 0.0 } } }, Tag = { "planet_solarSystem", "planet_terrestrial" }, @@ -53,12 +48,11 @@ local MercuryLabel = { Renderable = { Enabled = false, Type = "RenderableLabels", - LabelText = "Mercury", - FontSize = 100.0, - LabelSize = 8.3, - LabelMaxSize = 100.0, - LabelMinSize = 1.0, - LabelOrientationOption = "Camera View Direction", + Text = "Mercury", + FontSize = 70.0, + Size = 8.46, + MinMaxSize = { 1, 100 }, + OrientationOption = "Camera View Direction", BlendMode = "Additive" }, Tag = { "solarsystem_labels" }, diff --git a/data/assets/scene/solarsystem/planets/neptune/neptune.asset b/data/assets/scene/solarsystem/planets/neptune/neptune.asset index 1b53920d46..5700797e14 100644 --- a/data/assets/scene/solarsystem/planets/neptune/neptune.asset +++ b/data/assets/scene/solarsystem/planets/neptune/neptune.asset @@ -33,12 +33,11 @@ local NeptuneLabel = { Renderable = { Enabled = false, Type = "RenderableLabels", - LabelText = "Neptune", - FontSize = 100.0, - LabelSize = 8.8, - LabelMaxSize = 100.0, - LabelMinSize = 1.0, - LabelOrientationOption = "Camera View Direction", + Text = "Neptune", + FontSize = 70.0, + Size = 8.96, + MinMaxSize = { 1, 100 }, + OrientationOption = "Camera View Direction", BlendMode = "Additive" }, Tag = { "solarsystem_labels" }, diff --git a/data/assets/scene/solarsystem/planets/saturn/dione/dione.asset b/data/assets/scene/solarsystem/planets/saturn/dione/dione.asset index 1cce3d7e20..f91edea8ed 100644 --- a/data/assets/scene/solarsystem/planets/saturn/dione/dione.asset +++ b/data/assets/scene/solarsystem/planets/saturn/dione/dione.asset @@ -26,21 +26,16 @@ local Dione = { SegmentsPerPatch = 64, Layers = {}, Labels = { - Enable = false, + Enabled = false, FileName = labelsPath .. "/dione.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 32.0, - LabelsSize = 8.0, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - LabelsFadeOutEnabled = true, - FadeInStartingDistance = 3500000.0, - FadeOutStartingDistance = 1000000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 200000.0, - LabelsColor = { 1.0, 1.0, 0.0 } + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 8.7, + FadeInEnabled = true, + FadeOutEnabled = true, + FadeDistances = { 500000.0, 3500000.0 }, + DistanceEPS = 200000.0, + Color = { 1.0, 1.0, 0.0 } } }, Tag = { "moon_solarSystem", "moon_giants", "moon_saturn" }, diff --git a/data/assets/scene/solarsystem/planets/saturn/enceladus/enceladus.asset b/data/assets/scene/solarsystem/planets/saturn/enceladus/enceladus.asset index 1f16f3f0bb..87d416faea 100644 --- a/data/assets/scene/solarsystem/planets/saturn/enceladus/enceladus.asset +++ b/data/assets/scene/solarsystem/planets/saturn/enceladus/enceladus.asset @@ -26,21 +26,16 @@ local Enceladus = { SegmentsPerPatch = 64, Layers = {}, Labels = { - Enable = false, + Enabled = false, FileName = labelsPath .. "/enceladus.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 22.0, - LabelsSize = 8.0, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - LabelsFadeOutEnabled = true, - FadeInStartingDistance = 1000000.0, - FadeOutStartingDistance = 500000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 100000.0, - LabelsColor = { 1.0, 1.0, 0.0 } + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 8.1, + FadeInEnabled = true, + FadeOutEnabled = true, + FadeDistances = { 300000.0, 1000000.0 }, + DistanceEPS = 100000.0, + Color = { 1.0, 1.0, 0.0 } } }, Tag = { "moon_solarSystem", "moon_giants", "moon_saturn" }, diff --git a/data/assets/scene/solarsystem/planets/saturn/hyperion/hyperion.asset b/data/assets/scene/solarsystem/planets/saturn/hyperion/hyperion.asset index 77fe207be1..763123733a 100644 --- a/data/assets/scene/solarsystem/planets/saturn/hyperion/hyperion.asset +++ b/data/assets/scene/solarsystem/planets/saturn/hyperion/hyperion.asset @@ -26,20 +26,16 @@ local Hyperion = { SegmentsPerPatch = 64, Layers = {}, Labels = { - Enable = false, + -- @TODO (2021-05-21, emmbr26) These labels do not seem to be visible + Enabled = false, FileName = labelsPath .. "/hyperion.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 14.0, - LabelsSize = 8.0, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - FadeInStartingDistance = 500000.0, - FadeOutStartingDistance = 1000000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 1350000.0, - LabelsColor = { 1.0, 1.0, 0.0 } + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 8.6, + FadeInEnabled = true, + FadeDistances = { 500000.0, 1000000.0 }, + DistanceEPS = 1350000.0, + Color = { 1.0, 1.0, 0.0 } } }, Tag = { "moon_solarSystem", "moon_giants", "moon_saturn" }, diff --git a/data/assets/scene/solarsystem/planets/saturn/iapetus/iapetus.asset b/data/assets/scene/solarsystem/planets/saturn/iapetus/iapetus.asset index 5a33262237..17c3c89c4b 100644 --- a/data/assets/scene/solarsystem/planets/saturn/iapetus/iapetus.asset +++ b/data/assets/scene/solarsystem/planets/saturn/iapetus/iapetus.asset @@ -26,21 +26,16 @@ local Iapetus = { SegmentsPerPatch = 64, Layers = {}, Labels = { - Enable = false, + Enabled = false, FileName = labelsPath .. "/iapetus.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 30.0, - LabelsSize = 8.0, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - LabelsFadeOutEnabled = true, - FadeInStartingDistance = 3500000.0, - FadeOutStartingDistance = 600000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 250000.0, - LabelsColor = { 1.0, 1.0, 0.0 } + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 8.7, + FadeInEnabled = true, + FadeOutEnabled = true, + FadeDistances = { 600000.0, 3500000.0 }, + DistanceEPS = 250000.0, + Color = { 1.0, 1.0, 0.0 } } }, Tag = { "moon_solarSystem", "moon_giants", "moon_saturn" }, diff --git a/data/assets/scene/solarsystem/planets/saturn/mimas/mimas.asset b/data/assets/scene/solarsystem/planets/saturn/mimas/mimas.asset index 0b9e83521a..a54c8bc981 100644 --- a/data/assets/scene/solarsystem/planets/saturn/mimas/mimas.asset +++ b/data/assets/scene/solarsystem/planets/saturn/mimas/mimas.asset @@ -26,21 +26,16 @@ local Mimas = { SegmentsPerPatch = 64, Layers = { }, Labels = { - Enable = false, + Enabled = false, FileName = labelsPath .. "/mimas.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 14.0, - LabelsSize = 8.0, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - LabelsFadeOutEnabled = true, - FadeInStartingDistance = 1000000.0, - FadeOutStartingDistance = 400000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 25000.0, - LabelsColor = { 1.0, 1.0, 0.0 } + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 7.7, + FadeInEnabled = true, + FadeOutEnabled = true, + FadeDistances = { 400000.0, 1000000.0 }, + DistanceEPS = 25000.0, + Color = { 1.0, 1.0, 0.0 } } }, Tag = { "moon_solarSystem", "moon_giants", "moon_saturn" }, diff --git a/data/assets/scene/solarsystem/planets/saturn/rhea/rhea.asset b/data/assets/scene/solarsystem/planets/saturn/rhea/rhea.asset index 0c2d323efe..48926b0140 100644 --- a/data/assets/scene/solarsystem/planets/saturn/rhea/rhea.asset +++ b/data/assets/scene/solarsystem/planets/saturn/rhea/rhea.asset @@ -26,21 +26,16 @@ local Rhea = { SegmentsPerPatch = 64, Layers = {}, Labels = { - Enable = false, + Enabled = false, FileName = labelsPath .. "/rhea.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 40.0, - LabelsSize = 8.0, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - LabelsFadeOutEnabled = true, - FadeInStartingDistance = 2500000.0, - FadeOutStartingDistance = 1000000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 250000.0, - LabelsColor = { 1.0, 1.0, 0.0 } + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 9.0, + FadeInEnabled = true, + FadeOutEnabled = true, + FadeDistances = { 500000.0, 2500000.0 }, + DistanceEPS = 250000.0, + Color = { 1.0, 1.0, 0.0 } } }, Tag = { "moon_solarSystem", "moon_giants", "moon_saturn" }, diff --git a/data/assets/scene/solarsystem/planets/saturn/saturn.asset b/data/assets/scene/solarsystem/planets/saturn/saturn.asset index 555ac5fc63..8a92299d59 100644 --- a/data/assets/scene/solarsystem/planets/saturn/saturn.asset +++ b/data/assets/scene/solarsystem/planets/saturn/saturn.asset @@ -56,13 +56,12 @@ local SaturnLabel = { Renderable = { Enabled = false, Type = "RenderableLabels", - LabelText = "Saturn", - FontSize = 100.0, - LabelSize = 8.7, - LabelMaxSize = 100.0, - LabelMinSize = 1.0, + Text = "Saturn", + FontSize = 70.0, + Size = 8.85, + MinMaxSize = { 1, 100 }, BlendMode = "Additive", - LabelOrientationOption = "Camera View Direction" + OrientationOption = "Camera View Direction" }, Tag = { "solarsystem_labels" }, GUI = { diff --git a/data/assets/scene/solarsystem/planets/saturn/tethys/tethys.asset b/data/assets/scene/solarsystem/planets/saturn/tethys/tethys.asset index 636081f8af..a87015d37d 100644 --- a/data/assets/scene/solarsystem/planets/saturn/tethys/tethys.asset +++ b/data/assets/scene/solarsystem/planets/saturn/tethys/tethys.asset @@ -26,21 +26,16 @@ local Tethys = { SegmentsPerPatch = 64, Layers = {}, Labels = { - Enable = false, + Enabled = false, FileName = labelsPath .. "/tethys.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 24.0, - LabelsSize = 8.0, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - LabelsFadeOutEnabled = true, - FadeInStartingDistance = 1500000.0, - FadeOutStartingDistance = 500000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 200000.0, - LabelsColor = { 1.0, 1.0, 0.0 } + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 8.3, + FadeInEnabled = true, + FadeOutEnabled = true, + FadeDistances = { 500000.0, 1500000.0 }, + DistanceEPS = 200000.0, + Color = { 1.0, 1.0, 0.0 } } }, Tag = { "moon_solarSystem", "moon_giants", "moon_saturn" }, diff --git a/data/assets/scene/solarsystem/planets/saturn/titan/default_layers.asset b/data/assets/scene/solarsystem/planets/saturn/titan/default_layers.asset index 9159115f6a..faae518b07 100644 --- a/data/assets/scene/solarsystem/planets/saturn/titan/default_layers.asset +++ b/data/assets/scene/solarsystem/planets/saturn/titan/default_layers.asset @@ -1,7 +1,6 @@ local colorLayersPath = "./layers/colorlayers" -colorLayer = asset.require(colorLayersPath .. "/titan_texture") -local colorLayer = asset.require(colorLayersPath .. "/cassini_iss_global_mosaic_4km_liu") +local colorLayer = asset.require(colorLayersPath .. "/cassini_iss_global_mosaic_4km_local") -- Set enabled layers (temporary solution) -- @TODO: do this using a boolean that's passed to the 'asset.require' instead @@ -14,7 +13,7 @@ end) asset.meta = { Name = "Default Titan Layers", Version = "1.0", - Description = [[ Default Titan layers are: Titan Texture and Cassini ISS Global + Description = [[ Default Titan layers are: Cassini ISS Global Mosaic]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", diff --git a/data/assets/scene/solarsystem/planets/saturn/titan/layers/colorlayers/cassini_iss_global_mosaic_4km_local.asset b/data/assets/scene/solarsystem/planets/saturn/titan/layers/colorlayers/cassini_iss_global_mosaic_4km_local.asset new file mode 100644 index 0000000000..0356317b58 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/saturn/titan/layers/colorlayers/cassini_iss_global_mosaic_4km_local.asset @@ -0,0 +1,34 @@ +local texturesPath = asset.require("./../../titan_textures").TexturesPath +local globeIdentifier = asset.require("./../../titan").Titan.Identifier + +local layer = { + Identifier = "Cassini_ISS_Global_Mosaic_4km_Local", + Name = "Cassini ISS Global Mosaic 4km", + FilePath = texturesPath .. "/Titan_ISS_P19658_Mosaic_Global_4km_os.tif", + Description = [[ This global digital map of Saturn's moon Titan was created using + images taken by the Cassini spacecraft's Imaging Science Subsystem (ISS). The map + was produced in June 2015 using data collected through Cassini's flyby on April 7, + 2014, known as "T100". The mean radius of Titan used for projection of this map is + 1,600 miles (2,575 kilometers). Pixel resolution is 4005 meters per pixel (m). + Titan is assumed to be spherical until a control network -- a model of the moon's + shape based on multiple images tied together at defined points on the surface -- + is created at some point in the future. (Description from URL)]] +} + +asset.onInitialize(function () + openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer) +end) + +asset.export("layer", layer) + + +asset.meta = { + Name = "Cassini ISS Global Mosaic", + Version = "1.0", + Description = [[ Cassini global image layer for Titan]], + Author = "USGS", + URL = "https://astrogeology.usgs.gov/search/map/Titan/Cassini/Global-Mosaic/" .. + "Titan_ISS_P19658_Mosaic_Global_4km", + License = "NASA/PDS", + Identifiers = {"Cassini_ISS_Global_Mosaic_4km_Local"} +} diff --git a/data/assets/scene/solarsystem/planets/saturn/titan/layers/colorlayers/titan_texture.asset b/data/assets/scene/solarsystem/planets/saturn/titan/layers/colorlayers/titan_texture.asset deleted file mode 100644 index b9730b43eb..0000000000 --- a/data/assets/scene/solarsystem/planets/saturn/titan/layers/colorlayers/titan_texture.asset +++ /dev/null @@ -1,23 +0,0 @@ -local texturesPath = asset.require("./../../titan_textures").TexturesPath -local globeIdentifier = asset.require("./../../titan").Titan.Identifier - -local layer = { - Identifier = "Texture", - FilePath = texturesPath .. "/titan.jpg", -} - -asset.onInitialize(function () - openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer) -end) - -asset.export("layer", layer) - - -asset.meta = { - Name = "Titan Texutre", - Version = "1.0", - Description = [[ Default jpg texture for Titan]], - Author = "OpenSpace Team", - URL = "http://openspaceproject.com", - License = "MIT license" -} diff --git a/data/assets/scene/solarsystem/planets/saturn/titan/titan.asset b/data/assets/scene/solarsystem/planets/saturn/titan/titan.asset index fb52863ec2..25e701052e 100644 --- a/data/assets/scene/solarsystem/planets/saturn/titan/titan.asset +++ b/data/assets/scene/solarsystem/planets/saturn/titan/titan.asset @@ -26,21 +26,16 @@ local Titan = { SegmentsPerPatch = 64, Layers = {}, Labels = { - Enable = false, + Enabled = false, FileName = labelsPath .. "/titan.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 14.0, - LabelsSize = 10.0, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - LabelsFadeOutEnabled = true, - FadeInStartingDistance = 7500000.0, - FadeOutStartingDistance = 6000000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 1350000.0, - LabelsColor = { 1.0, 1.0, 0.0 } + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 9.6, + FadeInEnabled = true, + FadeOutEnabled = true, + FadeDistances = { 5000000.0, 7500000.0 }, + DistanceEPS = 1350000.0, + Color = { 1.0, 1.0, 0.0 } } }, Tag = { "moon_solarSystem", "moon_giants", "moon_saturn" }, diff --git a/data/assets/scene/solarsystem/planets/saturn/titan/titan_textures.asset b/data/assets/scene/solarsystem/planets/saturn/titan/titan_textures.asset index 6083943b65..d64bdd04f3 100644 --- a/data/assets/scene/solarsystem/planets/saturn/titan/titan_textures.asset +++ b/data/assets/scene/solarsystem/planets/saturn/titan/titan_textures.asset @@ -2,6 +2,6 @@ local TexturesPath = asset.syncedResource({ Type = "HttpSynchronization", Name = "Titan textures", Identifier = "titan_textures", - Version = 1 + Version = 2 }) asset.export("TexturesPath", TexturesPath) diff --git a/data/assets/scene/solarsystem/planets/uranus/uranus.asset b/data/assets/scene/solarsystem/planets/uranus/uranus.asset index c08924fd96..80d6add8f7 100644 --- a/data/assets/scene/solarsystem/planets/uranus/uranus.asset +++ b/data/assets/scene/solarsystem/planets/uranus/uranus.asset @@ -33,12 +33,11 @@ local UranusLabel = { Renderable = { Enabled = false, Type = "RenderableLabels", - LabelText = "Uranus", - FontSize = 100.0, - LabelSize = 8.7, - LabelMaxSize = 100.0, - LabelMinSize = 1.0, - LabelOrientationOption = "Camera View Direction", + Text = "Uranus", + FontSize = 70.0, + Size = 8.86, + MinMaxSize = { 1, 100 }, + OrientationOption = "Camera View Direction", BlendMode = "Additive" }, Tag = { "solarsystem_labels" }, diff --git a/data/assets/scene/solarsystem/planets/venus/venus.asset b/data/assets/scene/solarsystem/planets/venus/venus.asset index b07ce04f0c..2e1c74df2a 100644 --- a/data/assets/scene/solarsystem/planets/venus/venus.asset +++ b/data/assets/scene/solarsystem/planets/venus/venus.asset @@ -26,22 +26,16 @@ local Venus = { SegmentsPerPatch = 64, Layers = {}, Labels = { - Enable = false, + Enabled = false, FileName = labelsPath .. "/venus.labels", - LabelAlignmentOption = "Horizontally", -- or Circularly - LabelsFontSize = 40.0, - LabelsSize = 10.0, - LabelsMinSize = 1.0, - LabelsMaxSize = 1500.0, - ProximityEnabled = false, - LabelsFadeInEnabled = true, - LabelsFadeInEnabled = true, - LabelsFadeOutEnabled = true, - FadeInStartingDistance = 7000000.0, - FadeOutStartingDistance = 2000000.0, - LabelsForceDomeRendering = true, - LabelsDistanceEPS = 4000000.0, - LabelsColor = { 1.0, 1.0, 0.0 } + AlignmentOption = "Horizontally", -- or Circularly + FontSize = 20.0, + Size = 11.0, + FadeInEnabled = true, + FadeOutEnabled = true, + FadeDistances = { 2000000.0, 7000000.0 }, + DistanceEPS = 4000000.0, + Color = { 1.0, 1.0, 0.0 } } }, Tag = { "planet_solarSystem", "planet_terrestrial" }, @@ -53,25 +47,24 @@ local Venus = { } local VenusLabel = { - Identifier = "VenusLabel", - Parent = Venus.Identifier, - Renderable = { - Enabled = false, - Type = "RenderableLabels", - LabelText = "Venus", - FontSize = 100.0, - LabelSize = 8.4, - LabelMaxSize = 100.0, - LabelMinSize = 1.0, - LabelOrientationOption = "Camera View Direction", - BlendMode = "Additive" - }, - Tag = { "solarsystem_labels" }, - GUI = { - Name = "Venus Label", - Path = "/Solar System/Planets/Venus", - Description = "Label for Venus, viewable within the solar system." - } + Identifier = "VenusLabel", + Parent = Venus.Identifier, + Renderable = { + Enabled = false, + Type = "RenderableLabels", + Text = "Venus", + FontSize = 70.0, + Size = 8.54, + MinMaxSize = { 1, 100 }, + OrientationOption = "Camera View Direction", + BlendMode = "Additive" + }, + Tag = { "solarsystem_labels" }, + GUI = { + Name = "Venus Label", + Path = "/Solar System/Planets/Venus", + Description = "Label for Venus, viewable within the solar system." + } } assetHelper.registerSceneGraphNodesAndExport(asset, { Venus, VenusLabel }) diff --git a/data/assets/scene/solarsystem/sun/sun.asset b/data/assets/scene/solarsystem/sun/sun.asset index 7eae833e2d..de53d4aa1b 100644 --- a/data/assets/scene/solarsystem/sun/sun.asset +++ b/data/assets/scene/solarsystem/sun/sun.asset @@ -26,20 +26,16 @@ local SunLabel = { Renderable = { Enabled = false, Type = "RenderableLabels", - LabelText = "Sun", - FontSize = 100.0, - LabelSize = 13.127, - LabelMaxSize = 100.0, - LabelMinSize = 1.0, - LabelOrientationOption = "Camera View Direction", + Text = "Sun", + FontSize = 70.0, + Size = 14.17, + MinMaxSize = { 1, 50 }, + OrientationOption = "Camera View Direction", BlendMode = "Additive", EnableFading = true, - FadeStartUnit = "Pm", - FadeStartDistance = 2.841, - FadeStartSpeed = 1.375, - FadeEndUnit = "pc", - FadeEndDistance = 1.326, - FadeEndSpeed = 1.0 + FadeUnit = "pc", + FadeDistances = { 1.33, 15.0 }, + FadeWidths = { 1.0, 20.0 } }, Tag = { "solarsystem_labels" }, GUI = { diff --git a/data/assets/util/add_marker.asset b/data/assets/util/add_marker.asset new file mode 100644 index 0000000000..1d62a2f00c --- /dev/null +++ b/data/assets/util/add_marker.asset @@ -0,0 +1,19 @@ +local icons = asset.syncedResource({ + Name = "Icons", + Type = "HttpSynchronization", + Identifier = "icons", + Version = 1 +}) + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable({ + Identifier = "target-marker", + Name = "Target Marker", + Type = "ScreenSpaceImageLocal", + TexturePath = icons .. '/target.png' + }) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable('target-marker'); +end) diff --git a/data/assets/util/circle.asset b/data/assets/util/circle.asset new file mode 100644 index 0000000000..4717b87883 --- /dev/null +++ b/data/assets/util/circle.asset @@ -0,0 +1,8 @@ +local circle = asset.syncedResource({ + Name = "Circle", + Type = "HttpSynchronization", + Identifier = "circle_image", + Version = 1 +}) + +asset.export('circle', circle) diff --git a/data/assets/util/default_joystick.asset b/data/assets/util/default_joystick.asset index e511364fff..8ecce48410 100644 --- a/data/assets/util/default_joystick.asset +++ b/data/assets/util/default_joystick.asset @@ -4,6 +4,7 @@ local propertyHelper = asset.require('./property_helper') -- "None" -- "Orbit X" -- "Orbit Y" +-- "Zoom" -- both in and out -- "Zoom In" -- "Zoom Out" -- "LocalRoll X" @@ -44,10 +45,10 @@ local PS4Controller = { RightThumbStick = { 2, 5 }, LeftTrigger = 3, RightTrigger = 4, - A = 3, -- Triangle - B = 0, -- Square - X = 2, -- Circle - Y = 1, -- Cross + A = 1, -- Cross + B = 2, -- Circle + X = 0, -- Square + Y = 3, -- Triangle LB = 4, RB = 5, Select = 9, -- options @@ -62,6 +63,14 @@ local PS4Controller = { } } +local SpaceMouse = { + Push = {0, 1, 2}, -- left/right, back/forth, up/down + Twist = {5}, -- left/right + Tilt = {4, 3}, -- left/right, back/forth + LeftButton = 0, + RightButton = 1 +} + -- Variables to store the state of the joystick between frames Joystick = {} Joystick.State = {} @@ -73,11 +82,11 @@ local bindLocalRoll = function(axis) -- We only want to store the current state in the first mode that is enabled, otherwise we will overwrite the backup if not Joystick.State.IsInRollMode then -- Save current axis state - Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized = openspace.navigation.joystickAxis(]] .. axis .. [[) + Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity = openspace.navigation.joystickAxis(]] .. axis .. [[) end -- Set new axis state - openspace.navigation.bindJoystickAxis(]] .. axis .. [[, "LocalRoll X", true); + openspace.navigation.bindJoystickAxis(]] .. axis .. [[, "LocalRoll X", Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity); Joystick.State.IsInRollMode = true ]] end @@ -87,88 +96,133 @@ local bindGlobalRoll = function(axis) -- We only want to store the current state in the first mode that is enabled, otherwise we will overwrite the backup if not Joystick.State.IsInRollMode then -- Save current axis state - Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized = openspace.navigation.joystickAxis(]] .. axis .. [[) + Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity = openspace.navigation.joystickAxis(]] .. axis .. [[) end -- Set new axis state - openspace.navigation.bindJoystickAxis(]] .. axis .. [[, "GlobalRoll X", true); + openspace.navigation.bindJoystickAxis(]] .. axis .. [[, "GlobalRoll X", Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity); Joystick.State.IsInRollMode = true ]] end +local permaBindLocalRoll = function(axis) + return [[ + -- Save current axis state + Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity = openspace.navigation.joystickAxis(]] .. axis .. [[) + + -- Set new axis state + openspace.navigation.bindJoystickAxis(]] .. axis .. [[, "LocalRoll X", Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity); + ]] +end + +local permaBindGlobalRoll = function(axis) + return [[ + -- Save current axis state + Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity = openspace.navigation.joystickAxis(]] .. axis .. [[) + + -- Set new axis state + openspace.navigation.bindJoystickAxis(]] .. axis .. [[, "GlobalRoll X", Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity); + ]] +end + local unbindRoll = function(axis) return [[ -- Reset previous state - openspace.navigation.bindJoystickAxis(]] .. axis .. [[, Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized); + openspace.navigation.bindJoystickAxis(]] .. axis .. [[, Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity); ]] end asset.onInitialize(function() -- Set the controller to the connected controller - -- Currently: XBoxController or PS4Controller + -- Currently: XBoxController, PS4Controller or SpaceMouse local controller = XBoxController; - openspace.navigation.setAxisDeadZone(controller.LeftThumbStick[1], 0.15) - openspace.navigation.setAxisDeadZone(controller.LeftThumbStick[2], 0.15) - openspace.navigation.setAxisDeadZone(controller.RightThumbStick[1], 0.15) - openspace.navigation.setAxisDeadZone(controller.RightThumbStick[2], 0.15) - openspace.navigation.setAxisDeadZone(controller.LeftTrigger, 0.15) - openspace.navigation.setAxisDeadZone(controller.RightTrigger, 0.15) + -- Case of XBoxController or PS4Controller + if(controller.A ~= nil) then + openspace.navigation.setAxisDeadZone(controller.LeftThumbStick[1], 0.15) + openspace.navigation.setAxisDeadZone(controller.LeftThumbStick[2], 0.15) + openspace.navigation.setAxisDeadZone(controller.RightThumbStick[1], 0.15) + openspace.navigation.setAxisDeadZone(controller.RightThumbStick[2], 0.15) - openspace.navigation.bindJoystickAxis(controller.LeftThumbStick[1], "Orbit X"); - openspace.navigation.bindJoystickAxis(controller.LeftThumbStick[2], "Orbit Y", true); - openspace.navigation.bindJoystickAxis(controller.RightThumbStick[1], "Pan X", true); - openspace.navigation.bindJoystickAxis(controller.RightThumbStick[2], "Pan Y", true); - openspace.navigation.bindJoystickAxis(controller.LeftTrigger, "Zoom Out", false, true); - openspace.navigation.bindJoystickAxis(controller.RightTrigger, "Zoom In", false, true); + openspace.navigation.bindJoystickAxis(controller.LeftThumbStick[1], "Orbit X"); + openspace.navigation.bindJoystickAxis(controller.LeftThumbStick[2], "Orbit Y", true); + openspace.navigation.bindJoystickAxis(controller.RightThumbStick[1], "Pan X", true); + openspace.navigation.bindJoystickAxis(controller.RightThumbStick[2], "Pan Y", true); + openspace.navigation.bindJoystickAxis(controller.LeftTrigger, "Zoom Out", false, true); + openspace.navigation.bindJoystickAxis(controller.RightTrigger, "Zoom In", false, true); - openspace.navigation.bindJoystickButton( - controller.LB, - bindLocalRoll(controller.RightThumbStick[1]), - "Switch to local roll mode" - ) - openspace.navigation.bindJoystickButton( - controller.LB, - unbindRoll(controller.RightThumbStick[1]), - "Switch back to normal mode", - "Release" - ) - openspace.navigation.bindJoystickButton( - controller.RB, - bindGlobalRoll(controller.RightThumbStick[1]), - "Switch to global roll mode" - ) - openspace.navigation.bindJoystickButton( - controller.RB, - unbindRoll(controller.RightThumbStick[1]), - "Switch back to normal mode", - "Release" - ) + openspace.navigation.bindJoystickButton( + controller.LB, + bindLocalRoll(controller.RightThumbStick[1]), + "Switch to local roll mode" + ) + openspace.navigation.bindJoystickButton( + controller.LB, + unbindRoll(controller.RightThumbStick[1]), + "Switch back to normal mode", + "Release" + ) + openspace.navigation.bindJoystickButton( + controller.RB, + bindGlobalRoll(controller.RightThumbStick[1]), + "Switch to global roll mode" + ) + openspace.navigation.bindJoystickButton( + controller.RB, + unbindRoll(controller.RightThumbStick[1]), + "Switch back to normal mode", + "Release" + ) - openspace.navigation.bindJoystickButton( - controller.A, - propertyHelper.invert('NavigationHandler.OrbitalNavigator.Friction.ZoomFriction'), - "Toggle zoom friction" - ) - openspace.navigation.bindJoystickButton( - controller.B, - propertyHelper.invert('NavigationHandler.OrbitalNavigator.Friction.RotationalFriction'), - "Toggle rotational friction" - ) - openspace.navigation.bindJoystickButton( - controller.DPad.Left, - propertyHelper.invert('NavigationHandler.OrbitalNavigator.Friction.RollFriction'), - "Toggle roll friction" - ) + openspace.navigation.bindJoystickButton( + controller.A, + propertyHelper.invert('NavigationHandler.OrbitalNavigator.Friction.ZoomFriction'), + "Toggle zoom friction" + ) + openspace.navigation.bindJoystickButton( + controller.B, + propertyHelper.invert('NavigationHandler.OrbitalNavigator.Friction.RotationalFriction'), + "Toggle rotational friction" + ) + openspace.navigation.bindJoystickButton( + controller.DPad.Left, + propertyHelper.invert('NavigationHandler.OrbitalNavigator.Friction.RollFriction'), + "Toggle roll friction" + ) - openspace.navigation.bindJoystickButton( - controller.X, - "openspace.setPropertyValue('NavigationHandler.Origin', 'Earth')", - "Switch target to Earth" - ) - openspace.navigation.bindJoystickButton( - controller.Y, - "openspace.setPropertyValue('NavigationHandler.Origin', 'Mars')", - "Switch target to Mars" - ) + openspace.navigation.bindJoystickButton( + controller.X, + "openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Aim', '');" .. + "openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Anchor', 'Earth');" .. + "openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil);", + "Switch target to Earth" + ) + openspace.navigation.bindJoystickButton( + controller.Y, + "openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Aim', '');" .. + "openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Anchor', 'Mars');" .. + "openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil);", + "Switch target to Mars" + ) + -- Case of SpaceMouse + elseif (controller.LeftButton ~= nil) then + openspace.navigation.bindJoystickAxis(controller.Push[1], "Orbit X", false, false, true, 40.0); + openspace.navigation.bindJoystickAxis(controller.Push[2], "Orbit Y", false, false, true, 40.0); + openspace.navigation.bindJoystickAxis(controller.Twist[1], "Pan X", true, false, true, 40.0); + openspace.navigation.bindJoystickAxis(controller.Tilt[2], "Pan Y", false, false, true, 35.0); + openspace.navigation.bindJoystickAxis(controller.Push[3], "Zoom", false, false, true, 40.0); + openspace.navigation.bindJoystickAxis(controller.Tilt[1], "LocalRoll X", false, false, true, 35.0); + + openspace.navigation.bindJoystickButton( + controller.LeftButton, + permaBindLocalRoll(controller.Tilt[1]), + "Switch to local roll mode" + ) + + openspace.navigation.bindJoystickButton( + controller.RightButton, + permaBindGlobalRoll(controller.Tilt[1]), + "Switch to global roll mode" + ) + end end) diff --git a/data/assets/util/default_keybindings.asset b/data/assets/util/default_keybindings.asset index d178200ed0..05a5cdcc10 100644 --- a/data/assets/util/default_keybindings.asset +++ b/data/assets/util/default_keybindings.asset @@ -36,7 +36,7 @@ local Keybindings = { { Key = "SPACE", Name = "Toggle Pause (Interpolated)", - Command = "openspace.time.interpolateTogglePause()", + Command = "openspace.time.pauseToggleViaKeyboard()", Documentation = "Smoothly starts and stops the simulation time.", GuiPath = "/Simulation Speed", Local = true diff --git a/data/assets/util/webgui.asset b/data/assets/util/webgui.asset index 9be28c5d6f..85263c7e8b 100644 --- a/data/assets/util/webgui.asset +++ b/data/assets/util/webgui.asset @@ -3,7 +3,7 @@ asset.require('./static_server') local guiCustomization = asset.require('customization/gui') -- Select which commit hashes to use for the frontend and backend -local frontendHash = "391f8d3ed74e598a0e8a1b16016324d8f747e18d" +local frontendHash = "7fed95043e967c632b446ae1c98c6390f3fb7edc" local dataProvider = "data.openspaceproject.com/files/webgui" local frontend = asset.syncedResource({ diff --git a/data/profiles/jwst.profile b/data/profiles/jwst.profile new file mode 100644 index 0000000000..d273706c84 --- /dev/null +++ b/data/profiles/jwst.profile @@ -0,0 +1,112 @@ +{ + "assets": [ + "base", + "scene/solarsystem/planets/earth/earth", + "scene/solarsystem/planets/earth/satellites/satellites", + "scene/solarsystem/missions/jwst/jwst", + "scene/solarsystem/missions/jwst/HUDFImage", + "scene/digitaluniverse/hdf" + ], + "camera": { + "altitude": 17000000.0, + "anchor": "Earth", + "latitude": 3.5559, + "longitude": -53.0515, + "type": "goToGeo" + }, + "delta_times": [ + 1.0, + 5.0, + 30.0, + 60.0, + 300.0, + 1800.0, + 3600.0, + 43200.0, + 86400.0, + 604800.0, + 1209600.0, + 2592000.0, + 5184000.0, + 7776000.0, + 15552000.0, + 31536000.0, + 63072000.0, + 157680000.0, + 315360000.0, + 630720000.0 + ], + "keybindings": [ + { + "documentation": "Toggle trails on or off for satellites around Earth", + "gui_path": "/Earth", + "is_local": false, + "key": "S", + "name": "Toggle satellite trails", + "script": "local list = openspace.getProperty('{earth_satellites}.Renderable.Enabled'); for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end" + }, + { + "documentation": "Toggle points and labels for the Lagrangian points for Earth Sun system", + "gui_path": "/JWST", + "is_local": false, + "key": "P", + "name": "Toggle Lagrangian points", + "script": "local list = openspace.getProperty('{lagrange_points_earth}.Renderable.Enabled'); for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end" + }, + { + "documentation": "Toggle Hubble Ultra Deep Field image and line towards its coordinate", + "gui_path": "/JWST", + "is_local": false, + "key": "U", + "name": "Toggle Hubble Ultra Deep Field", + "script": "local list = openspace.getProperty('{mission_jwst_hudf}.*.Enabled'); for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end" + }, + { + "documentation": "Toggle L2 label, point and line", + "gui_path": "/JWST", + "is_local": false, + "key": "O", + "name": "Toggle L2", + "script": "local list = openspace.getProperty('{lagrange_points_earth_l2_small}.*.Enabled'); for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end" + }, + { + "documentation": "Toggle James Webb Space Telecope field of view and view band", + "gui_path": "/JWST", + "is_local": false, + "key": "V", + "name": "Toggle JWST field of view and view band", + "script": "local list = openspace.getProperty('{mission_jwst_fov}.*.Enabled'); for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end" + } + ], + "mark_nodes": [ + "JWSTModel", + "JWSTTrail", + "L2", + "Earth", + "Moon", + "Sun" + ], + "meta": { + "author": "OpenSpace Team", + "description": "James Webb Space Telescope Profile. Adds the James Webb Space Telescope model with an estimated trajectery.", + "license": "MIT License", + "name": "James Webb Space Telescope", + "url": "https://www.openspaceproject.com", + "version": "1.0" + }, + "properties": [ + { + "name": "{earth_satellites}.Renderable.Enabled", + "type": "setPropertyValue", + "value": "false" + } + ], + "time": { + "type": "absolute", + "value": "2021-10-31T00:00:00" + }, + "version": { + "major": 1, + "minor": 0 + } +} diff --git a/data/profiles/mars.profile b/data/profiles/mars.profile index 87493a7562..eb730ff151 100644 --- a/data/profiles/mars.profile +++ b/data/profiles/mars.profile @@ -39,7 +39,7 @@ "is_local": false, "key": "I", "name": "Setup scene for insight EDL", - "script": "openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.HeightLayers.Mola_Utah.Settings.Offset', -469.300000);openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.HeightLayers.HiRISE-LS-DEM.Settings.Offset', -470.800006);openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.HeightLayers.HiRISE-LS-DEM.Enabled', true);openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.ColorLayers.HiRISE-LS.Enabled', true);openspace.time.setPause(true);openspace.time.setTime('2018 NOV 26 19:39:03.68');openspace.navigation.setNavigationState({Anchor = 'Insight',Pitch = 0.567457E-4,Position = { 1.240506E1,-1.369270E1,-2.423553E0 },ReferenceFrame = 'Root',Up = { 0.441211E0,0.247019E0,0.862737E0 },Yaw = -0.446853E-4});" + "script": "openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.HeightLayers.Mola_Utah.Settings.Offset', -469.300000);openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.HeightLayers.HiRISE-LS-DEM.Settings.Offset', -470.800006);openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.HeightLayers.HiRISE-LS-DEM.Enabled', true);openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.ColorLayers.HiRISE-LS.Enabled', true);openspace.time.setPause(true);openspace.time.setTime('2018 NOV 26 19:39:01.68');openspace.navigation.setNavigationState({Anchor = 'Insight',Pitch = 0.567457E-4,Position = { 1.240506E1,-1.369270E1,-2.423553E0 },ReferenceFrame = 'Root',Up = { 0.441211E0,0.247019E0,0.862737E0 },Yaw = -0.446853E-4});" }, { "documentation": "Disable Mars layer settings used for insight EDL", @@ -55,7 +55,7 @@ "is_local": false, "key": "P", "name": "Setup and Goto Perseverance", - "script": "openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.HeightLayers.Mola_Utah.Settings.Offset', -1677.088867);openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.HeightLayers.HiRISE-LS-DEM.Settings.Offset', -1677.088867);openspace.time.setPause(true);openspace.time.setTime('2021 FEB 18 20:32:16');openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.HeightLayers.HiRISE-LS-DEM.Enabled', true);openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.ColorLayers.HiRISE-LS.Enabled', true);openspace.navigation.setNavigationState({Anchor = 'Perseverance',Pitch = 0.567457E-4,Position = { 1.240506E1,-1.369270E1,-2.423553E0 },ReferenceFrame = 'Root',Up = { 0.441211E0,0.247019E0,0.862737E0 },Yaw = -0.446853E-4});" + "script": "openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.HeightLayers.Mola_Utah.Settings.Offset', -1674.0);openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.HeightLayers.HiRISE-LS-DEM.Settings.Offset', -1674.0);openspace.time.setPause(true);openspace.time.setTime('2021 FEB 18 20:32:16');openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.HeightLayers.HiRISE-LS-DEM.Enabled', true);openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.ColorLayers.HiRISE-LS.Enabled', true);openspace.navigation.setNavigationState({Anchor = 'Perseverance',Pitch = 0.567457E-4,Position = { 1.240506E1,-1.369270E1,-2.423553E0 },ReferenceFrame = 'Root',Up = { 0.441211E0,0.247019E0,0.862737E0 },Yaw = -0.446853E-4});" } ], "mark_nodes": [ @@ -77,6 +77,6 @@ }, "version": { "major": 1, - "minor": 1 + "minor": 2 } } \ No newline at end of file diff --git a/data/profiles/newhorizons.profile b/data/profiles/newhorizons.profile index 7f30857769..f66c34681d 100644 --- a/data/profiles/newhorizons.profile +++ b/data/profiles/newhorizons.profile @@ -216,7 +216,7 @@ "license": "MIT License", "name": "New Horizons", "url": "https://www.openspaceproject.com", - "version": "1.0" + "version": "1.1" }, "properties": [ { @@ -233,6 +233,11 @@ "name": "Scene.PlutoBarycenterTrail.Renderable.Enabled", "type": "setPropertyValue", "value": "false" + }, + { + "name": "Scene.PlutoProjection.Renderable.ColorTexturePaths", + "type": "setPropertyValue", + "value": "1.000000" } ], "time": { diff --git a/data/profiles/osirisrex.profile b/data/profiles/osirisrex.profile index 94aebc6939..a6b9399bcb 100644 --- a/data/profiles/osirisrex.profile +++ b/data/profiles/osirisrex.profile @@ -3,7 +3,8 @@ "base", "scene/solarsystem/missions/osirisrex/dashboard", "scene/solarsystem/missions/osirisrex/model", - "scene/solarsystem/missions/osirisrex/osirisrex" + "scene/solarsystem/missions/osirisrex/osirisrex", + "scene/solarsystem/missions/osirisrex/imageplane" ], "camera": { "aim": "", diff --git a/data/web/documentation/toplevel.hbs b/data/web/documentation/toplevel.hbs index 3701dd057a..2fe96f3313 100644 --- a/data/web/documentation/toplevel.hbs +++ b/data/web/documentation/toplevel.hbs @@ -22,7 +22,7 @@ {{/with}} {{#if reference}} {{#if reference.found}} -

An object of type '{{reference.name}}'

+

An object of type '{{reference.name}}'

{{else}}

Missing reference

{{/if}} diff --git a/ext/ghoul b/ext/ghoul index 8f17cc57d9..fcb8e8b964 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 8f17cc57d95cb5682aed07e087feb47d06824503 +Subproject commit fcb8e8b964c9c176733f4fdc22d117cac8d3f8b2 diff --git a/include/openspace/documentation/documentation.h b/include/openspace/documentation/documentation.h index 39ed62320e..a5c17c8622 100644 --- a/include/openspace/documentation/documentation.h +++ b/include/openspace/documentation/documentation.h @@ -93,7 +93,7 @@ struct TestResult { /// Is \c true if the TestResult is positive, \c false otherwise - bool success; + bool success = false; /// Contains a list of offenses that were found in the test. Is empty if /// TestResult::Success is \c true std::vector offenses; diff --git a/include/openspace/documentation/documentationgenerator.h b/include/openspace/documentation/documentationgenerator.h index 103187675f..248fa4ea22 100644 --- a/include/openspace/documentation/documentationgenerator.h +++ b/include/openspace/documentation/documentationgenerator.h @@ -94,24 +94,6 @@ private: const std::vector _handlebarTemplates; }; -/** - * This function takes a \p text and escapes all necessary characters () that JSON - * does not want in its strings. - * \param text The text that is to be escaped - * \return The same text will all required characteres escaped - */ -std::string escapedJson(const std::string& text); - - -/** - * This function takes a \p list of text and escapes all necessary characters () that JSON - * does not want in its strings. - * \param text The list text that is to be escaped - * \return The same text will all required characteres escaped - */ -std::string escapedJson(const std::vector& list); - - } // namespace openspace #endif // __OPENSPACE_CORE___DOCUMENTATIONGENERATOR___H__ diff --git a/include/openspace/engine/configuration.h b/include/openspace/engine/configuration.h index 98fbb8518c..83970d9fdf 100644 --- a/include/openspace/engine/configuration.h +++ b/include/openspace/engine/configuration.h @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -85,7 +86,7 @@ struct Configuration { bool shouldUseScreenshotDate = false; std::string onScreenTextScaling = "window"; - bool usePerSceneCache = false; + bool usePerProfileCache = false; bool isRenderingOnMasterDisabled = false; glm::dvec3 globalRotation = glm::dvec3(0.0); @@ -129,9 +130,9 @@ struct Configuration { ghoul::lua::LuaState state; }; -std::string findConfiguration(const std::string& filename = "openspace.cfg"); +std::filesystem::path findConfiguration(const std::string& filename = "openspace.cfg"); -Configuration loadConfigurationFromFile(const std::string& filename, +Configuration loadConfigurationFromFile(const std::filesystem::path& filename, const std::string& overrideScript); } // namespace openspace::configuration diff --git a/include/openspace/engine/downloadmanager.h b/include/openspace/engine/downloadmanager.h index 26b0fa21f6..1bfb97a229 100644 --- a/include/openspace/engine/downloadmanager.h +++ b/include/openspace/engine/downloadmanager.h @@ -26,6 +26,7 @@ #define __OPENSPACE_CORE___DOWNLOADMANAGER___H__ #include +#include #include #include #include @@ -99,7 +100,7 @@ public: // finishedCallback - callback when download finished (happens on different thread) // progressCallback - callback for status during (happens on different thread) std::shared_ptr downloadFile(const std::string& url, - const ghoul::filesystem::File& file, + const std::filesystem::path& file, OverrideFile overrideFile = OverrideFile::Yes, FailOnError failOnError = FailOnError::No, unsigned int timeout_secs = 0, DownloadFinishedCallback finishedCallback = DownloadFinishedCallback(), diff --git a/include/openspace/interaction/joystickcamerastates.h b/include/openspace/interaction/joystickcamerastates.h index fd0098e933..15188faf26 100644 --- a/include/openspace/interaction/joystickcamerastates.h +++ b/include/openspace/interaction/joystickcamerastates.h @@ -43,6 +43,7 @@ public: OrbitY, ZoomIn, ZoomOut, + Zoom, LocalRollX, LocalRollY, GlobalRollX, @@ -60,7 +61,15 @@ public: AxisInvert invert = AxisInvert::No; AxisNormalize normalize = AxisNormalize::No; + // The axis values can either go back to 0 when the joystick is released or it can + // stay at the value it was before the joystick was released. + // The latter is called a sticky axis, when the values don't go back to 0. + bool isSticky = false; + float deadzone = 0.f; + + // Every axis can have their own sensitivity + double sensitivity = 0.0; }; JoystickCameraStates(double sensitivity, double velocityScaleFactor); @@ -69,7 +78,8 @@ public: void setAxisMapping(int axis, AxisType mapping, AxisInvert shouldInvert = AxisInvert::No, - AxisNormalize shouldNormalize = AxisNormalize::No + AxisNormalize shouldNormalize = AxisNormalize::No, + bool isSticky = false, double sensitivity = 0.0 ); AxisInformation axisMapping(int axis) const; @@ -91,6 +101,10 @@ private: std::array _axisMapping; + // This array is used to store the old axis values from the previous frame, + // it is used to calculate the difference in the values in the case of a sticky axis + std::array _prevAxisValues; + struct ButtonInformation { std::string command; JoystickAction action; @@ -135,6 +149,7 @@ from_string(std::string_view string) if (string == "None") { return T::None; } if (string == "Orbit X") { return T::OrbitX; } if (string == "Orbit Y") { return T::OrbitY; } + if (string == "Zoom") { return T::Zoom; } if (string == "Zoom In") { return T::ZoomIn; } if (string == "Zoom Out") { return T::ZoomOut; } if (string == "LocalRoll X") { return T::LocalRollX; } diff --git a/include/openspace/interaction/joystickinputstate.h b/include/openspace/interaction/joystickinputstate.h index ced81f4013..c5d320c7b8 100644 --- a/include/openspace/interaction/joystickinputstate.h +++ b/include/openspace/interaction/joystickinputstate.h @@ -71,6 +71,11 @@ struct JoystickInputState { /// \c nAxes values are defined values, the rest are undefined std::array axes; + /// The axis values can either go back to 0 when the joystick is released or it can + /// stay at the value it was before the joystick was released. + /// The latter is called a sticky axis, when the values don't go back to 0. + bool isSticky = false; + /// The number of buttons that this joystick possesses int nButtons = 0; /// The status of each button. Only the first \c nButtons values are defined, the rest diff --git a/include/openspace/interaction/navigationhandler.h b/include/openspace/interaction/navigationhandler.h index 68d34498b2..15d080330b 100644 --- a/include/openspace/interaction/navigationhandler.h +++ b/include/openspace/interaction/navigationhandler.h @@ -115,7 +115,8 @@ public: JoystickCameraStates::AxisInvert shouldInvert = JoystickCameraStates::AxisInvert::No, JoystickCameraStates::AxisNormalize shouldNormalize = - JoystickCameraStates::AxisNormalize::No + JoystickCameraStates::AxisNormalize::No, + bool isSticky = false, double sensitivity = 0.0 ); JoystickCameraStates::AxisInformation joystickAxisMapping(int axis) const; diff --git a/include/openspace/interaction/sessionrecording.h b/include/openspace/interaction/sessionrecording.h index 51aaaf6686..749f7badfe 100644 --- a/include/openspace/interaction/sessionrecording.h +++ b/include/openspace/interaction/sessionrecording.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace openspace::interaction { @@ -60,7 +61,8 @@ public: enum class SessionState { Idle = 0, Recording, - Playback + Playback, + PlaybackPaused }; struct Timestamps { @@ -69,6 +71,18 @@ public: double timeSim; }; + /* + * Struct for storing a script substring that, if found in a saved script, + * will be replaced by its substringReplacement counterpart. + */ + struct ScriptSubstringReplace { + std::string substringFound; + std::string substringReplacement; + ScriptSubstringReplace(std::string found, std::string replace) + : substringFound(found) + , substringReplacement(replace) {}; + }; + static const size_t FileHeaderVersionLength = 5; char FileHeaderVersion[FileHeaderVersionLength+1] = "01.00"; char TargetConvertVersion[FileHeaderVersionLength+1] = "01.00"; @@ -117,6 +131,20 @@ public: */ double fixedDeltaTimeDuringFrameOutput() const; + /** + * Returns the number of microseconds that have elapsed since playback started, if + * playback is set to be in the mode where a screenshot is captured with every + * rendered frame (enableTakeScreenShotDuringPlayback() is used to enable this mode). + * At the start of playback, this timer is set to the current steady_clock value. + * However, during playback it is incremented by the fixed framerate of the playback + * rather than the actual clock value (as in normal operation). + * + * \returns number of microseconds elapsed since playback started in terms of the + * number of rendered frames multiplied by the fixed time increment per + * frame + */ + std::chrono::steady_clock::time_point currentPlaybackInterpolationTime() const; + /** * Starts a recording session, which will save data to the provided filename * according to the data format specified, and will continue until recording is @@ -154,16 +182,20 @@ public: /** * Starts a playback session, which can run in one of three different time modes. * - * \param filename file containing recorded keyframes to play back + * \param filename file containing recorded keyframes to play back. The file path + * is relative to the base recordings directory specified in the + * config file by the RECORDINGS variable * \param timeMode which of the 3 time modes to use for time reference during * \param forceSimTimeAtStart if true simulation time is forced to that of playback * playback: recorded time, application time, or simulation time. See the * LuaLibrary entry for SessionRecording for details on these time modes + * \param loop if true then the file will playback in loop mode, continuously + * looping back to the beginning until it is manually stopped * * \return \c true if recording to file starts without errors */ bool startPlayback(std::string& filename, KeyframeTimeRef timeMode, - bool forceSimTimeAtStart); + bool forceSimTimeAtStart, bool loop); /** * Used to stop a playback in progress. If open, the playback file will be closed, @@ -171,6 +203,22 @@ public: */ void stopPlayback(); + /** + * Returns playback pause status. + * + * \return \c true if playback is paused + */ + bool isPlaybackPaused(); + + /** + * Pauses a playback session. This does both the normal pause functionality of + * setting simulation delta time to zero, and pausing the progression through the + * timeline. + * + * \param pause if true, then will set playback timeline progression to zero + */ + void setPlaybackPause(bool pause); + /** * Enables that rendered frames should be saved during playback * \param fps Number of frames per second. @@ -205,13 +253,13 @@ public: * whether it is following the rotation of a node, and timestamp). The data will be * saved to the recording file only if a recording is currently in progress. */ - void saveCameraKeyframe(); + void saveCameraKeyframeToTimeline(); /** * Used to trigger a save of the current timing states. The data will be saved to the * recording file only if a recording is currently in progress. */ - void saveTimeKeyframe(); + void saveTimeKeyframeToTimeline(); /** * Used to trigger a save of a script to the recording file, but only if a recording @@ -219,7 +267,7 @@ public: * * \param scriptToSave String of the Lua command to be saved */ - void saveScriptKeyframe(std::string scriptToSave); + void saveScriptKeyframeToTimeline(std::string scriptToSave); /** * \return The Lua library that contains all Lua functions available to affect the @@ -405,6 +453,19 @@ public: void saveScriptKeyframeAscii(Timestamps& times, datamessagestructures::ScriptMessage& sm, std::ofstream& file); + /** + * Since session recordings only record changes, the initial conditions aren't + * preserved when a playback starts. This function is called whenever a property + * value is set and a recording is in progress. Before the set happens, this + * function will read the current value of the property and store it so that when + * the recording is finished, the initial state will be added as a set property + * command at the beginning of the recording file, to be applied when playback + * starts. + * + * \param prop The property being set + */ + void savePropertyBaseline(properties::Property& prop); + /** * Reads header information from a session recording file * @@ -524,17 +585,20 @@ protected: struct timelineEntry { RecordedType keyframeType; unsigned int idxIntoKeyframeTypeArray; - double timestamp; + Timestamps t3stamps; }; ExternInteraction _externInteract; double _timestampRecordStarted = 0.0; + Timestamps _timestamps3RecordStarted; double _timestampPlaybackStarted_application = 0.0; double _timestampPlaybackStarted_simulation = 0.0; double _timestampApplicationStarted_simulation = 0.0; bool hasCameraChangedFromPrev(datamessagestructures::CameraKeyframe kfNew); - double appropriateTimestamp(double timeOs, double timeRec, double timeSim); + double appropriateTimestamp(Timestamps t3stamps); double equivalentSimulationTime(double timeOs, double timeRec, double timeSim); double equivalentApplicationTime(double timeOs, double timeRec, double timeSim); + void recordCurrentTimePauseState(); + void recordCurrentTimeRate(); bool handleRecordingFile(std::string filenameIn); static bool isPath(std::string& filename); void removeTrailingPathSlashes(std::string& filename); @@ -544,19 +608,26 @@ protected: bool playbackScript(); bool playbackAddEntriesToTimeline(); void signalPlaybackFinishedForComponent(RecordedType type); - void findFirstCameraKeyframeInTimeline(); + bool findFirstCameraKeyframeInTimeline(); + Timestamps generateCurrentTimestamp3(double keyframeTime); static void saveStringToFile(const std::string& s, unsigned char* kfBuffer, size_t& idx, std::ofstream& file); static void saveKeyframeToFileBinary(unsigned char* bufferSource, size_t size, std::ofstream& file); - bool addKeyframe(double timestamp, + bool addKeyframe(Timestamps t3stamps, interaction::KeyframeNavigator::CameraPose keyframe, int lineNum); - bool addKeyframe(double timestamp, datamessagestructures::TimeKeyframe keyframe, - int lineNum); - bool addKeyframe(double timestamp, std::string scriptToQueue, int lineNum); - bool addKeyframeToTimeline(RecordedType type, size_t indexIntoTypeKeyframes, - double timestamp, int lineNum); + bool addKeyframe(Timestamps t3stamps, + datamessagestructures::TimeKeyframe keyframe, int lineNum); + bool addKeyframe(Timestamps t3stamps, + std::string scriptToQueue, int lineNum); + bool addKeyframeToTimeline(std::vector& timeline, RecordedType type, + size_t indexIntoTypeKeyframes, Timestamps t3stamps, int lineNum); + + void initializePlayback_time(double now); + void initializePlayback_modeFlags(); + bool initializePlayback_timeline(); + void initializePlayback_triggerStart(); void moveAheadInTime(); void lookForNonCameraKeyframesThatHaveComeDue(double currTime); void updateCameraWithOrWithoutNewKeyframes(double currTime); @@ -580,9 +651,14 @@ protected: const int lineNum); void saveSingleKeyframeScript(datamessagestructures::ScriptMessage& kf, Timestamps& times, DataMode mode, std::ofstream& file, unsigned char* buffer); + void saveScriptKeyframeToPropertiesBaseline(std::string script); + bool isPropertyAllowedForBaseline(const std::string& propString); unsigned int findIndexOfLastCameraKeyframeInTimeline(); bool doesTimelineEntryContainCamera(unsigned int index) const; std::vector> _stateChangeCallbacks; + bool doesStartWithSubstring(const std::string& s, const std::string& matchSubstr); + void trimCommandsFromScriptIfFound(std::string& script); + void replaceCommandsFromScriptIfFound(std::string& script); RecordedType getNextKeyframeType(); RecordedType getPrevKeyframeType(); @@ -600,6 +676,14 @@ protected: DataMode readModeFromHeader(std::string filename); void readPlaybackHeader_stream(std::stringstream& conversionInStream, std::string& version, DataMode& mode); + void populateListofLoadedSceneGraphNodes(); + + bool checkIfScriptUsesScenegraphNode(std::string s); + void checkForScenegraphNodeAccess_Scene(std::string& s, std::string& result); + void checkForScenegraphNodeAccess_Nav(std::string& s, std::string& result); + bool checkIfInitialFocusNodeIsLoaded(unsigned int firstCamIndex); + void eraseSpacesFromString(std::string& s); + std::string getNameFromSurroundingQuotes(std::string& s); static void writeToFileBuffer(unsigned char* buf, size_t& idx, double src); static void writeToFileBuffer(unsigned char* buf, size_t& idx, std::vector& cv); @@ -616,27 +700,78 @@ protected: std::string _playbackLineParsing; std::ofstream _recordFile; int _playbackLineNum = 1; + int _recordingEntryNum = 1; KeyframeTimeRef _playbackTimeReferenceMode; datamessagestructures::CameraKeyframe _prevRecordedCameraKeyframe; bool _playbackActive_camera = false; bool _playbackActive_time = false; bool _playbackActive_script = false; bool _hasHitEndOfCameraKeyframes = false; - bool _setSimulationTimeWithNextCameraKeyframe = false; + bool _playbackPausedWithinDeltaTimePause = false; + bool _playbackLoopMode = false; + bool _playbackForceSimTimeAtStart = false; + double _playbackPauseOffset = 0.0; + double _previousTime = 0.0; bool _saveRenderingDuringPlayback = false; double _saveRenderingDeltaTime = 1.0 / 30.0; double _saveRenderingCurrentRecordedTime; + std::chrono::steady_clock::duration _saveRenderingDeltaTime_interpolation_usec; + std::chrono::steady_clock::time_point _saveRenderingCurrentRecordedTime_interpolation; + long long _saveRenderingClockInterpolation_countsPerSec; + bool _saveRendering_isFirstFrame = true; unsigned char _keyframeBuffer[_saveBufferMaxSize_bytes]; bool _cleanupNeeded = false; + const std::string scriptReturnPrefix = "return "; std::vector _keyframesCamera; std::vector _keyframesTime; std::vector _keyframesScript; std::vector _timeline; + std::vector _keyframesSavePropertiesBaseline_scripts; + std::vector _keyframesSavePropertiesBaseline_timeline; + std::vector _propertyBaselinesSaved; + const std::vector _propertyBaselineRejects = { + "NavigationHandler.OrbitalNavigator.Anchor", + "NavigationHandler.OrbitalNavigator.Aim", + "NavigationHandler.OrbitalNavigator.RetargetAnchor", + "NavigationHandler.OrbitalNavigator.RetargetAim" + }; + //A script that begins with an exact match of any of the strings contained in + // _scriptRejects will not be recorded + const std::vector _scriptRejects = { + "openspace.sessionRecording.enableTakeScreenShotDuringPlayback", + "openspace.sessionRecording.startPlayback", + "openspace.sessionRecording.stopPlayback", + "openspace.sessionRecording.startRecording", + "openspace.sessionRecording.stopRecording", + "openspace.scriptScheduler.clear" + }; + const std::vector _navScriptsUsingNodes = { + "RetargetAnchor", + "Anchor", + "Aim" + }; + //Any script snippet included in this vector will be trimmed from any script + // from the script manager, before it is recorded in the session recording file. + // The remainder of the script will be retained. + const std::vector _scriptsToBeTrimmed = { + "openspace.sessionRecording.togglePlaybackPause" + }; + //Any script snippet included in this vector will be trimmed from any script + // from the script manager, before it is recorded in the session recording file. + // The remainder of the script will be retained. + const std::vector _scriptsToBeReplaced = { + { + "openspace.time.pauseToggleViaKeyboard", + "openspace.time.interpolateTogglePause" + } + }; + std::vector _loadedNodes; + unsigned int _idxTimeline_nonCamera = 0; unsigned int _idxTime = 0; unsigned int _idxScript = 0; diff --git a/include/openspace/interaction/tasks/convertrecfileversiontask.h b/include/openspace/interaction/tasks/convertrecfileversiontask.h index a707146095..8c25c18990 100644 --- a/include/openspace/interaction/tasks/convertrecfileversiontask.h +++ b/include/openspace/interaction/tasks/convertrecfileversiontask.h @@ -29,11 +29,9 @@ #include #include - +#include #include - - namespace openspace::interaction { class ConvertRecFileVersionTask : public Task { @@ -48,7 +46,7 @@ public: private: std::string _inFilename; - std::string _inFilePath; + std::filesystem::path _inFilePath; std::string _valueFunctionLua; }; diff --git a/include/openspace/interaction/tasks/convertrecformattask.h b/include/openspace/interaction/tasks/convertrecformattask.h index 9258d70406..989dd0bd6c 100644 --- a/include/openspace/interaction/tasks/convertrecformattask.h +++ b/include/openspace/interaction/tasks/convertrecformattask.h @@ -29,7 +29,7 @@ #include #include - +#include #include namespace openspace::interaction { @@ -52,8 +52,8 @@ private: void convertToBinary(); void determineFormatType(); std::string addFileSuffix(const std::string& filePath, const std::string& suffix); - std::string _inFilePath; - std::string _outFilePath; + std::filesystem::path _inFilePath; + std::filesystem::path _outFilePath; std::ifstream _iFile; std::ofstream _oFile; SessionRecording::DataMode _fileFormatType; diff --git a/include/openspace/network/messagestructures.h b/include/openspace/network/messagestructures.h index f9e7492ebf..effe727cbe 100644 --- a/include/openspace/network/messagestructures.h +++ b/include/openspace/network/messagestructures.h @@ -49,6 +49,14 @@ struct CameraKeyframe { CameraKeyframe(const std::vector& buffer) { deserialize(buffer); } + CameraKeyframe(glm::dvec3&& pos, glm::dquat&& rot, std::string&& focusNode, + bool&& followNodeRot, float&& scale) + : _position(pos) + , _rotation(rot) + , _followNodeRotation(followNodeRot) + , _focusNode(focusNode) + , _scale(scale) + {} glm::dvec3 _position = glm::dvec3(0.0); glm::dquat _rotation = glm::dquat(1.0, 0.0, 0.0, 0.0); diff --git a/include/openspace/properties/list/doublelistproperty.h b/include/openspace/properties/list/doublelistproperty.h index b857dbc144..2d5bbdf40a 100644 --- a/include/openspace/properties/list/doublelistproperty.h +++ b/include/openspace/properties/list/doublelistproperty.h @@ -31,35 +31,21 @@ namespace openspace::properties { class DoubleListProperty : public ListProperty { public: - DoubleListProperty(Property::PropertyInfo info); - DoubleListProperty(Property::PropertyInfo info, std::vector values); + DoubleListProperty(Property::PropertyInfo info, + std::vector values = std::vector()); + + std::string className() const override; + int typeLua() const override; using TemplateProperty>::operator std::vector; using TemplateProperty>::operator=; + +protected: + std::vector fromLuaConversion(lua_State* state, bool& success) const override; + void toLuaConversion(lua_State* state) const override; + std::string toStringConversion() const override; }; -template <> -std::string PropertyDelegate>>::className(); - -template <> -template <> -std::vector -PropertyDelegate>>::fromLuaValue( - lua_State* state, bool& success); - -template <> -template <> -bool PropertyDelegate>>::toLuaValue( - lua_State* state, const std::vector& value); - -template <> -int PropertyDelegate>>::typeLua(); - -template <> -template <> -bool PropertyDelegate>>::toString( - std::string& outValue, const std::vector& inValue); - } // namespace openspace::properties #endif // __OPENSPACE_CORE___DOUBLELISTPROPERTY___H__ diff --git a/include/openspace/properties/list/intlistproperty.h b/include/openspace/properties/list/intlistproperty.h index 2213968d0d..0157b4d6af 100644 --- a/include/openspace/properties/list/intlistproperty.h +++ b/include/openspace/properties/list/intlistproperty.h @@ -31,34 +31,21 @@ namespace openspace::properties { class IntListProperty : public ListProperty { public: - IntListProperty(Property::PropertyInfo info); - IntListProperty(Property::PropertyInfo info, std::vector values); + IntListProperty(Property::PropertyInfo info, + std::vector values = std::vector()); + + std::string className() const override; + int typeLua() const override; using TemplateProperty>::operator std::vector; using TemplateProperty>::operator=; + +protected: + std::vector fromLuaConversion(lua_State* state, bool& success) const override; + void toLuaConversion(lua_State* state) const override; + std::string toStringConversion() const override; }; -template <> -std::string PropertyDelegate>>::className(); - -template <> -template <> -std::vector PropertyDelegate>>::fromLuaValue( - lua_State* state, bool& success); - -template <> -template <> -bool PropertyDelegate>>::toLuaValue( - lua_State* state, const std::vector& value); - -template <> -int PropertyDelegate>>::typeLua(); - -template <> -template <> -bool PropertyDelegate>>::toString( - std::string& outValue, const std::vector& inValue); - } // namespace openspace::properties #endif // __OPENSPACE_CORE___INTLISTPROPERTY___H__ diff --git a/include/openspace/properties/list/stringlistproperty.h b/include/openspace/properties/list/stringlistproperty.h index 8ed0259332..1d8dfc25ac 100644 --- a/include/openspace/properties/list/stringlistproperty.h +++ b/include/openspace/properties/list/stringlistproperty.h @@ -32,35 +32,22 @@ namespace openspace::properties { class StringListProperty : public ListProperty { public: - StringListProperty(Property::PropertyInfo info); - StringListProperty(Property::PropertyInfo info, std::vector values); + StringListProperty(Property::PropertyInfo info, + std::vector values = std::vector()); + + std::string className() const override; + int typeLua() const override; using TemplateProperty>::operator std::vector; using TemplateProperty>::operator=; + +protected: + std::vector fromLuaConversion(lua_State* state, + bool& success) const override; + void toLuaConversion(lua_State* state) const override; + std::string toStringConversion() const override; }; -template <> -std::string PropertyDelegate>>::className(); - -template <> -template <> -std::vector -PropertyDelegate>>::fromLuaValue( - lua_State* state, bool& success); - -template <> -template <> -bool PropertyDelegate>>::toLuaValue( - lua_State* state, const std::vector& value); - -template <> -int PropertyDelegate>>::typeLua(); - -template <> -template <> -bool PropertyDelegate>>::toString( - std::string& outValue, const std::vector& inValue); - } // namespace openspace::properties #endif // __OPENSPACE_CORE___STRINGLISTPROPERTY___H__ diff --git a/include/openspace/properties/listproperty.h b/include/openspace/properties/listproperty.h index 9d7ef0f820..2e40db8f05 100644 --- a/include/openspace/properties/listproperty.h +++ b/include/openspace/properties/listproperty.h @@ -33,7 +33,6 @@ namespace openspace::properties { template class ListProperty : public TemplateProperty> { public: - ListProperty(Property::PropertyInfo info); ListProperty(Property::PropertyInfo info, std::vector values); virtual ~ListProperty() = 0; diff --git a/include/openspace/properties/listproperty.inl b/include/openspace/properties/listproperty.inl index 6bad6b2c09..72158233bb 100644 --- a/include/openspace/properties/listproperty.inl +++ b/include/openspace/properties/listproperty.inl @@ -24,11 +24,6 @@ namespace openspace::properties { -template -ListProperty::ListProperty(Property::PropertyInfo info) - : TemplateProperty>(std::move(info)) -{} - template ListProperty::ListProperty(Property::PropertyInfo info, std::vector values) : TemplateProperty>(std::move(info), std::move(values)) diff --git a/include/openspace/properties/matrix/dmat2property.h b/include/openspace/properties/matrix/dmat2property.h index 617e56d186..659c2e98b6 100644 --- a/include/openspace/properties/matrix/dmat2property.h +++ b/include/openspace/properties/matrix/dmat2property.h @@ -28,10 +28,27 @@ #include #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(DMat2Property, glm::dmat2x2) +class DMat2Property : public NumericalProperty { +public: + DMat2Property(Property::PropertyInfo info, glm::dmat2x2 value = glm::dmat2x2(0.0), + glm::dmat2x2 minValue = + ghoul::createFillMat2x2(std::numeric_limits::lowest()), + glm::dmat2x2 maxValue = + ghoul::createFillMat2x2(std::numeric_limits::max()), + glm::dmat2x2 stepValue = ghoul::createFillMat2x2(0.01)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + glm::dmat2x2 fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/matrix/dmat2x3property.h b/include/openspace/properties/matrix/dmat2x3property.h deleted file mode 100644 index 825d639204..0000000000 --- a/include/openspace/properties/matrix/dmat2x3property.h +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___DMAT2X3PROPERTY___H__ -#define __OPENSPACE_CORE___DMAT2X3PROPERTY___H__ - -#include - -#include - -namespace openspace::properties { - -REGISTER_NUMERICALPROPERTY_HEADER(DMat2x3Property, glm::dmat2x3) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___DMAT2X3PROPERTY___H__ diff --git a/include/openspace/properties/matrix/dmat2x4property.h b/include/openspace/properties/matrix/dmat2x4property.h deleted file mode 100644 index ba3898edad..0000000000 --- a/include/openspace/properties/matrix/dmat2x4property.h +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___DMAT2X4PROPERTY___H__ -#define __OPENSPACE_CORE___DMAT2X4PROPERTY___H__ - -#include - -#include - -namespace openspace::properties { - -REGISTER_NUMERICALPROPERTY_HEADER(DMat2x4Property, glm::dmat2x4) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___DMAT2X4PROPERTY___H__ diff --git a/include/openspace/properties/matrix/dmat3property.h b/include/openspace/properties/matrix/dmat3property.h index 486e2ad9c3..24bb05e2c9 100644 --- a/include/openspace/properties/matrix/dmat3property.h +++ b/include/openspace/properties/matrix/dmat3property.h @@ -28,10 +28,27 @@ #include #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(DMat3Property, glm::dmat3x3) +class DMat3Property : public NumericalProperty { +public: + DMat3Property(Property::PropertyInfo info, glm::dmat3x3 value = glm::dmat3x3(0.0), + glm::dmat3x3 minValue = + ghoul::createFillMat3x3(std::numeric_limits::lowest()), + glm::dmat3x3 maxValue = + ghoul::createFillMat3x3(std::numeric_limits::max()), + glm::dmat3x3 stepValue = ghoul::createFillMat3x3(0.01)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + glm::dmat3x3 fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/matrix/dmat3x4property.h b/include/openspace/properties/matrix/dmat3x4property.h deleted file mode 100644 index 87521b8724..0000000000 --- a/include/openspace/properties/matrix/dmat3x4property.h +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___DMAT3X4PROPERTY___H__ -#define __OPENSPACE_CORE___DMAT3X4PROPERTY___H__ - -#include - -#include - -namespace openspace::properties { - -REGISTER_NUMERICALPROPERTY_HEADER(DMat3x4Property, glm::dmat3x4) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___DMAT3X4PROPERTY___H__ diff --git a/include/openspace/properties/matrix/dmat4property.h b/include/openspace/properties/matrix/dmat4property.h index 3788742621..a1d1204289 100644 --- a/include/openspace/properties/matrix/dmat4property.h +++ b/include/openspace/properties/matrix/dmat4property.h @@ -28,10 +28,27 @@ #include #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(DMat4Property, glm::dmat4x4) +class DMat4Property : public NumericalProperty { +public: + DMat4Property(Property::PropertyInfo info, glm::dmat4x4 value = glm::dmat4x4(0.0), + glm::dmat4x4 minValue = + ghoul::createFillMat4x4(std::numeric_limits::lowest()), + glm::dmat4x4 maxValue = + ghoul::createFillMat4x4(std::numeric_limits::max()), + glm::dmat4x4 stepValue = ghoul::createFillMat4x4(0.01)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + glm::dmat4x4 fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/matrix/dmat4x2property.h b/include/openspace/properties/matrix/dmat4x2property.h deleted file mode 100644 index 7205415c08..0000000000 --- a/include/openspace/properties/matrix/dmat4x2property.h +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___DMAT4X2PROPERTY___H__ -#define __OPENSPACE_CORE___DMAT4X2PROPERTY___H__ - -#include - -#include - -namespace openspace::properties { - -REGISTER_NUMERICALPROPERTY_HEADER(DMat4x2Property, glm::dmat4x2) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___DMAT4X2PROPERTY___H__ diff --git a/include/openspace/properties/matrix/dmat4x3property.h b/include/openspace/properties/matrix/dmat4x3property.h deleted file mode 100644 index 0e028317b8..0000000000 --- a/include/openspace/properties/matrix/dmat4x3property.h +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___DMAT4X3PROPERTY___H__ -#define __OPENSPACE_CORE___DMAT4X3PROPERTY___H__ - -#include - -#include - -namespace openspace::properties { - -REGISTER_NUMERICALPROPERTY_HEADER(DMat4x3Property, glm::dmat4x3) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___DMAT4X3PROPERTY___H__ diff --git a/include/openspace/properties/matrix/mat2property.h b/include/openspace/properties/matrix/mat2property.h index 42fea778cb..1b610b2e61 100644 --- a/include/openspace/properties/matrix/mat2property.h +++ b/include/openspace/properties/matrix/mat2property.h @@ -28,10 +28,27 @@ #include #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(Mat2Property, glm::mat2x2) +class Mat2Property : public NumericalProperty { +public: + Mat2Property(Property::PropertyInfo info, glm::mat2x2 value = glm::mat2x2(0.f), + glm::mat2x2 minValue = + ghoul::createFillMat2x2(std::numeric_limits::lowest()), + glm::mat2x2 maxValue = + ghoul::createFillMat2x2(std::numeric_limits::max()), + glm::mat2x2 stepValue = ghoul::createFillMat2x2(0.01f)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + glm::mat2x2 fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/matrix/mat2x3property.h b/include/openspace/properties/matrix/mat2x3property.h deleted file mode 100644 index 4ad90b4c51..0000000000 --- a/include/openspace/properties/matrix/mat2x3property.h +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___MAT2X3PROPERTY___H__ -#define __OPENSPACE_CORE___MAT2X3PROPERTY___H__ - -#include - -#include - -namespace openspace::properties { - -REGISTER_NUMERICALPROPERTY_HEADER(Mat2x3Property, glm::mat2x3) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___MAT2X3PROPERTY___H__ diff --git a/include/openspace/properties/matrix/mat2x4property.h b/include/openspace/properties/matrix/mat2x4property.h deleted file mode 100644 index 54508d5535..0000000000 --- a/include/openspace/properties/matrix/mat2x4property.h +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___MAT2X4PROPERTY___H__ -#define __OPENSPACE_CORE___MAT2X4PROPERTY___H__ - -#include - -#include - -namespace openspace::properties { - -REGISTER_NUMERICALPROPERTY_HEADER(Mat2x4Property, glm::mat2x4) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___MAT2X4PROPERTY___H__ diff --git a/include/openspace/properties/matrix/mat3property.h b/include/openspace/properties/matrix/mat3property.h index fbbd272390..ee0c2357c9 100644 --- a/include/openspace/properties/matrix/mat3property.h +++ b/include/openspace/properties/matrix/mat3property.h @@ -28,10 +28,27 @@ #include #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(Mat3Property, glm::mat3x3) +class Mat3Property : public NumericalProperty { +public: + Mat3Property(Property::PropertyInfo info, glm::mat3x3 value = glm::mat3x3(), + glm::mat3x3 minValue = + ghoul::createFillMat3x3(std::numeric_limits::lowest()), + glm::mat3x3 maxValue = + ghoul::createFillMat3x3(std::numeric_limits::max()), + glm::mat3x3 stepValue = ghoul::createFillMat3x3(0.01f)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + glm::mat3x3 fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/matrix/mat3x2property.h b/include/openspace/properties/matrix/mat3x2property.h deleted file mode 100644 index 42290b8fbd..0000000000 --- a/include/openspace/properties/matrix/mat3x2property.h +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___MAT3X2PROPERTY___H__ -#define __OPENSPACE_CORE___MAT3X2PROPERTY___H__ - -#include - -#include - -namespace openspace::properties { - -REGISTER_NUMERICALPROPERTY_HEADER(Mat3x2Property, glm::mat3x2) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___MAT3X2PROPERTY___H__ diff --git a/include/openspace/properties/matrix/mat3x4property.h b/include/openspace/properties/matrix/mat3x4property.h deleted file mode 100644 index ee26c13adf..0000000000 --- a/include/openspace/properties/matrix/mat3x4property.h +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___MAT3X4PROPERTY___H__ -#define __OPENSPACE_CORE___MAT3X4PROPERTY___H__ - -#include - -#include - -namespace openspace::properties { - -REGISTER_NUMERICALPROPERTY_HEADER(Mat3x4Property, glm::mat3x4) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___MAT3X4PROPERTY___H__ diff --git a/include/openspace/properties/matrix/mat4property.h b/include/openspace/properties/matrix/mat4property.h index 50ddd70c40..3c64405aa7 100644 --- a/include/openspace/properties/matrix/mat4property.h +++ b/include/openspace/properties/matrix/mat4property.h @@ -28,10 +28,27 @@ #include #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(Mat4Property, glm::mat4x4) +class Mat4Property : public NumericalProperty { +public: + Mat4Property(Property::PropertyInfo info, glm::mat4x4 value = glm::mat4x4(), + glm::mat4x4 minValue = + ghoul::createFillMat4x4(std::numeric_limits::lowest()), + glm::mat4x4 maxValue = + ghoul::createFillMat4x4(std::numeric_limits::max()), + glm::mat4x4 stepValue = ghoul::createFillMat4x4(0.01f)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + glm::mat4x4 fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/matrix/mat4x2property.h b/include/openspace/properties/matrix/mat4x2property.h deleted file mode 100644 index a30aec4c13..0000000000 --- a/include/openspace/properties/matrix/mat4x2property.h +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___MAT4X2PROPERTY___H__ -#define __OPENSPACE_CORE___MAT4X2PROPERTY___H__ - -#include - -#include - -namespace openspace::properties { - -REGISTER_NUMERICALPROPERTY_HEADER(Mat4x2Property, glm::mat4x2) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___MAT4X2PROPERTY___H__ diff --git a/include/openspace/properties/matrix/mat4x3property.h b/include/openspace/properties/matrix/mat4x3property.h deleted file mode 100644 index fa63aa6c9e..0000000000 --- a/include/openspace/properties/matrix/mat4x3property.h +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___MAT4X3PROPERTY___H__ -#define __OPENSPACE_CORE___MAT4X3PROPERTY___H__ - -#include - -#include - -namespace openspace::properties { - -REGISTER_NUMERICALPROPERTY_HEADER(Mat4x3Property, glm::mat4x3) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___MAT4X3PROPERTY___H__ diff --git a/include/openspace/properties/numericalproperty.h b/include/openspace/properties/numericalproperty.h index 05a88a48fb..1a23ca1370 100644 --- a/include/openspace/properties/numericalproperty.h +++ b/include/openspace/properties/numericalproperty.h @@ -32,20 +32,11 @@ namespace openspace::properties { template class NumericalProperty : public TemplateProperty { public: - NumericalProperty(Property::PropertyInfo info); - NumericalProperty(Property::PropertyInfo info, T value); NumericalProperty(Property::PropertyInfo info, T value, T minimumValue, - T maximumValue); - NumericalProperty(Property::PropertyInfo info, T value, T minimumValue, - T maximumValue, T steppingValue); - NumericalProperty(Property::PropertyInfo info, T value, T minimumValue, - T maximumValue, T steppingValue, float exponent); + T maximumValue, T steppingValue, float exponent = 1.f); - bool getLuaValue(lua_State* state) const override; - bool setLuaValue(lua_State* state) override; - int typeLua() const override; - - bool getStringValue(std::string& value) const override; + virtual std::string className() const override = 0; + virtual int typeLua() const override = 0; T minValue() const; void setMinValue(T value); @@ -59,8 +50,6 @@ public: float exponent() const; void setExponent(float exponent); - virtual std::string className() const override; - std::string jsonValue() const override; using TemplateProperty::operator=; @@ -71,13 +60,16 @@ public: void interpolateValue(float t, ghoul::EasingFunc easingFunc = nullptr) override; - protected: static const std::string MinimumValueKey; static const std::string MaximumValueKey; static const std::string SteppingValueKey; static const std::string ExponentValueKey; + virtual T fromLuaConversion(lua_State* state, bool& success) const override = 0; + virtual void toLuaConversion(lua_State* state) const override; + virtual std::string toStringConversion() const override; + std::string generateAdditionalJsonDescription() const override; /** diff --git a/include/openspace/properties/numericalproperty.inl b/include/openspace/properties/numericalproperty.inl index 57913c30de..3f5696f17a 100644 --- a/include/openspace/properties/numericalproperty.inl +++ b/include/openspace/properties/numericalproperty.inl @@ -22,175 +22,13 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#include #include #include +#include namespace openspace::properties { -#define REGISTER_NUMERICALPROPERTY_HEADER(CLASS_NAME, TYPE) \ - using CLASS_NAME = NumericalProperty; \ - \ - template <> \ - std::string PropertyDelegate>::className(); \ - \ - template <> \ - std::string PropertyDelegate>::className(); \ - \ - template <> \ - template <> \ - TYPE PropertyDelegate>::defaultValue(); \ - \ - template <> \ - template <> \ - TYPE PropertyDelegate>::defaultMinimumValue(); \ - \ - template <> \ - template <> \ - TYPE PropertyDelegate>::defaultMaximumValue(); \ - \ - template <> \ - template <> \ - TYPE PropertyDelegate>::defaultSteppingValue(); \ - \ - template <> \ - template <> \ - TYPE PropertyDelegate>::fromLuaValue(lua_State* state, \ - bool& success); \ - template <> \ - template <> \ - TYPE PropertyDelegate>::fromLuaValue(lua_State* state, \ - bool& success); \ - template <> \ - template <> \ - bool PropertyDelegate>::toLuaValue(lua_State* state, \ - const TYPE& value); \ - template <> \ - template <> \ - bool PropertyDelegate>::toLuaValue(lua_State* state, \ - const TYPE& value); \ - template <> \ - int PropertyDelegate>::typeLua(); \ - template <> \ - int PropertyDelegate>::typeLua(); \ - \ - template <> \ - template <> \ - bool PropertyDelegate>::toString(std::string& outValue, \ - const TYPE& inValue); \ - \ - template <> \ - template <> \ - bool PropertyDelegate>::toString(std::string& outValue, \ - const TYPE& inValue); - - -#define REGISTER_NUMERICALPROPERTY_SOURCE(CLASS_NAME, TYPE, DEFAULT_VALUE, \ - DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, \ - DEFAULT_STEPPING, FROM_LUA_LAMBDA_EXPRESSION, \ - TO_LUA_LAMBDA_EXPRESSION, \ - TO_STRING_LAMBDA_EXPRESSION, LUA_TYPE) \ - template <> \ - std::string PropertyDelegate>::className() \ - { \ - return #CLASS_NAME; \ - } \ - \ - template <> \ - std::string PropertyDelegate>::className() \ - { \ - return PropertyDelegate>::className(); \ - } \ - \ - template <> \ - template <> \ - TYPE PropertyDelegate>::defaultValue() \ - { \ - return DEFAULT_VALUE; \ - } \ - \ - template <> \ - template <> \ - TYPE PropertyDelegate>::defaultMinimumValue() \ - { \ - return DEFAULT_MIN_VALUE; \ - } \ - \ - template <> \ - template <> \ - TYPE PropertyDelegate>::defaultMaximumValue() \ - { \ - return DEFAULT_MAX_VALUE; \ - } \ - \ - template <> \ - template <> \ - TYPE PropertyDelegate>::defaultSteppingValue() \ - { \ - return DEFAULT_STEPPING; \ - } \ - \ - template <> \ - template <> \ - TYPE PropertyDelegate>::fromLuaValue(lua_State* state, \ - bool& success) \ - { \ - return FROM_LUA_LAMBDA_EXPRESSION(state, success); \ - } \ - \ - template <> \ - template <> \ - TYPE PropertyDelegate>::fromLuaValue(lua_State* state, \ - bool& success) \ - { \ - return PropertyDelegate>::fromLuaValue( \ - state, success); \ - } \ - \ - template <> \ - template <> \ - bool PropertyDelegate>::toLuaValue(lua_State* state, \ - const TYPE& value) \ - { \ - return TO_LUA_LAMBDA_EXPRESSION(state, value); \ - } \ - \ - template <> \ - template <> \ - bool PropertyDelegate>::toLuaValue(lua_State* state, \ - const TYPE& value) \ - { \ - return PropertyDelegate>::toLuaValue(state, value); \ - } \ - \ - template <> \ - int PropertyDelegate>::typeLua() \ - { \ - return LUA_TYPE; \ - } \ - \ - template <> \ - int PropertyDelegate>::typeLua() \ - { \ - return PropertyDelegate>::typeLua(); \ - } \ - \ - template <> \ - template <> \ - bool PropertyDelegate>::toString(std::string& outValue, \ - const TYPE& inValue) \ - { \ - return TO_STRING_LAMBDA_EXPRESSION(outValue, inValue); \ - } \ - \ - template <> \ - template <> \ - bool PropertyDelegate>::toString(std::string& outValue, \ - const TYPE& inValue) \ - { \ - return PropertyDelegate>::toString(outValue, inValue); \ - } - - template const std::string NumericalProperty::MinimumValueKey = "MinimumValue"; @@ -203,60 +41,6 @@ const std::string NumericalProperty::SteppingValueKey = "SteppingValue"; template const std::string NumericalProperty::ExponentValueKey = "Exponent"; -// Delegating constructors are necessary; automatic template deduction cannot -// deduce template argument for 'U' if 'default' methods are used as default values in -// a single constructor - -template -NumericalProperty::NumericalProperty(Property::PropertyInfo info) - : NumericalProperty( - std::move(info), - PropertyDelegate>::template defaultValue(), - PropertyDelegate>::template defaultMinimumValue(), - PropertyDelegate>::template defaultMaximumValue(), - PropertyDelegate>::template defaultSteppingValue(), - 1.f - ) -{} - -template -NumericalProperty::NumericalProperty(Property::PropertyInfo info, T value) - : NumericalProperty( - std::move(info), - std::move(value), - PropertyDelegate>::template defaultMinimumValue(), - PropertyDelegate>::template defaultMaximumValue(), - PropertyDelegate>::template defaultSteppingValue(), - 1.f - ) -{} - -template -NumericalProperty::NumericalProperty(Property::PropertyInfo info, T value, - T minimumValue, T maximumValue) - : NumericalProperty( - std::move(info), - std::move(value), - std::move(minimumValue), - std::move(maximumValue), - PropertyDelegate>::template defaultSteppingValue(), - 1.f - ) -{} - -template -NumericalProperty::NumericalProperty(Property::PropertyInfo info, T value, - T minimumValue, T maximumValue, T steppingValue) - : NumericalProperty( - std::move(info), - std::move(value), - std::move(minimumValue), - std::move(maximumValue), - std::move(steppingValue), - 1.f - ) -{} - template NumericalProperty::NumericalProperty(Property::PropertyInfo info, T value, T minimumValue, T maximumValue, T steppingValue, @@ -268,44 +52,6 @@ NumericalProperty::NumericalProperty(Property::PropertyInfo info, T value, , _exponent(exponent) {} -template -std::string NumericalProperty::className() const { - return PropertyDelegate>::className(); -} - -template -bool NumericalProperty::setLuaValue(lua_State* state) { - bool success = false; - T value = PropertyDelegate>::template fromLuaValue( - state, success - ); - if (success) { - TemplateProperty::setValue(std::move(value)); - } - return success; -} - -template -bool NumericalProperty::getLuaValue(lua_State* state) const { - bool success = PropertyDelegate>::template toLuaValue( - state, TemplateProperty::_value - ); - return success; -} - -template -int NumericalProperty::typeLua() const { - return PropertyDelegate>::typeLua(); -} - -template -bool NumericalProperty::getStringValue(std::string& value) const { - bool success = PropertyDelegate>::template toString( - value, TemplateProperty::_value - ); - return success; -} - template T NumericalProperty::minValue() const { return _minimumValue; @@ -343,6 +89,7 @@ float NumericalProperty::exponent() const { template void NumericalProperty::setExponent(float exponent) { + ghoul_assert(std::abs(exponent) > 0.f, "Exponent for property input cannot be zero"); _exponent = exponent; } @@ -374,8 +121,7 @@ std::string NumericalProperty::luaToJson(std::string luaValue) const { template std::string NumericalProperty::jsonValue() const { - std::string value; - getStringValue(value); + std::string value = toStringConversion(); return luaToJson(value); } @@ -390,13 +136,10 @@ void NumericalProperty::setInterpolationTarget(std::any value) { template void NumericalProperty::setLuaInterpolationTarget(lua_State* state) { bool success = false; - T thisValue = PropertyDelegate>::template fromLuaValue( - state, - success - ); + T targetValue = fromLuaConversion(state, success); if (success) { _interpolationStart = TemplateProperty::_value; - _interpolationEnd = std::move(thisValue); + _interpolationEnd = std::move(targetValue); } } @@ -412,4 +155,14 @@ void NumericalProperty::interpolateValue(float t, )); } +template +void NumericalProperty::toLuaConversion(lua_State* state) const { + ghoul::lua::push(state, TemplateProperty::_value); +} + +template +std::string NumericalProperty::toStringConversion() const { + return formatJson(TemplateProperty::_value); +} + } // namespace openspace::properties diff --git a/include/openspace/properties/property.h b/include/openspace/properties/property.h index b900cf8335..52de1629f9 100644 --- a/include/openspace/properties/property.h +++ b/include/openspace/properties/property.h @@ -381,12 +381,13 @@ public: /** * Default view options that can be used in the Property::setViewOption method. The - * values are: Property::ViewOptions::Color = \c Color, - * Property::ViewOptions::Logarithmic = \c Logarithmic + * values are: + * - Property::ViewOptions::Color = \c Color (Intended for Vec3 and Vec4), + * - Property::ViewOptions::MinMaxRange = \c MinMaxRange (Intended for Vec2) */ struct ViewOptions { static const char* Color; - static const char* Logarithmic; + static const char* MinMaxRange; }; /** diff --git a/include/openspace/properties/propertydelegate.h b/include/openspace/properties/propertydelegate.h deleted file mode 100644 index 1a871d7b96..0000000000 --- a/include/openspace/properties/propertydelegate.h +++ /dev/null @@ -1,161 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___PROPERTYDELEGATE___H__ -#define __OPENSPACE_CORE___PROPERTYDELEGATE___H__ - -#include - -struct lua_State; - -namespace openspace::properties { - -/** - * The PropertyDelegate class is used by (among others) the TemplateProperty and the - * NumericalProperty classes to outsource the definitions of class names, default values, - * etc. Using the PropertyDelegate, it is possible to create new TemplateProperty types - * without subclassing the TemplateProperty, but rather creating a specialized instance - * of PropertyDelegate. See - * (https://github.com/OpenSpace/OpenSpace/wiki/Concepts-Properties) for more detailed - * information. - * \see TemplateProperty - * \see NumericalProperty - * \tparam T The full class for which this specialized instance of PropertyDelegate is - * responsible. For example T = TemplateProperty. - */ -template -class PropertyDelegate { -public: - /** - * This method returns the class name for the class T. The default - * implementation will lead to a compile-time error if the class method is not - * specialized. - * \return The class name for the class T - */ - static std::string className(); - - /** - * This method will return the preferred default value for the class T. - * The default implementation will lead to a compile-time error if the class method is - * not specialized. - * \return The default value that the class T should use - * \tparam U The type by which the class T is specialized. If - * T = TemplateProperty, then U = std::string - */ - template - static U defaultValue(); - - /** - * This method will return the preferred default minimum value for the class - * T. The default implementation will lead to a compile-time error if the - * class method is not specialized. This method is not used in TemplateProperty, but - * only NumericalProperty, so the TemplateProperty does not require this method to be - * specialized. - * \return The default minimum value that the class T should use - * \tparam U The type by which the class T is specialized. If - * T = NumericalProperty, then U = int - */ - template - static U defaultMinimumValue(); - - /** - * This method will return the preferred default maximum value for the class - * T. The default implementation will lead to a compile-time error if the - * class method is not specialized. This method is not used in TemplateProperty, but - * only NumericalProperty, so the TemplateProperty does not require this method to be - * specialized. - * \return The default maximum value that the class T should use - * \tparam U The type by which the class T is specialized. If - * T = NumericalProperty, then U = int - */ - template - static U defaultMaximumValue(); - - /** - * The method returns the default stepping value for the class T used in - * GUI elements. The default implementation will lead to a compile-time error if the - * class method is not specialized. This method is not used in TemplateProperty, but - * only NumericalProperty, so the TemplateProperty does not require this method to be - * specialized. - * \return The default stepping that the class T should use - * \tparam U The type by which the class T is specialized. If - * T = NumericalProperty, then U = int - */ - template - static U defaultSteppingValue(); - - /** - * This method converts the top value from the Lua stack into a value of type - * U and reports the success back to the caller. The default - * implementation will lead to a compile-time error if the class method is not - * specialized. - * \param state The Lua state from which the value is retrieved - * \param success Will be true if the conversion succeeded; - * false otherwise - * \return The value that was created by converting the top value from the stack - * \tparam U The type by which the class T is specialized. If - * T = TemplateProperty, then U = std::string - */ - template - static U fromLuaValue(lua_State* state, bool& success); - - /** - * This method converts the passed value, encodes it and places it on the - * top value of the Lua stack and returns the success back to the caller. The default - * implementation will lead to a compile-time error if the class method is not - * specialized. - * \param state The Lua state from which the value is retrieved - * \param value The value that will be converted into a Lua object - * \return true if the conversion succeeded; false otherwise - * \tparam U The type by which the class T is specialized. If - * T = TemplateProperty, then U = std::string - */ - template - static bool toLuaValue(lua_State* state, const U& value); - - /** - * Returns the Lua type that will be put onto the stack in the - * PropertyDelegate::toLuaValue method and which will be consumed by the - * PropertyDelegate::fromLuaValue method. The returned value can belong to the set of - * Lua types: LUA_TNONE, LUA_TNIL, - * LUA_TBOOLEAN, LUA_TLIGHTUSERDATA, - * LUA_TNUMBER, LUA_TSTRING, LUA_TTABLE, - * LUA_TFUNCTION, LUA_TUSERDATA, or - * LUA_TTHREAD. The default implementation will return - * LUA_TNONE. The default implementation will lead to a compile-time - * error if the class method is not specialized. - * \return The Lua type that will be consumed or produced by the - * PropertyDelegate::toLuaValue and PropertyDelegate::fromLuaValue methods. - */ - static int typeLua(); - - template - static bool toString(std::string& outValue, const U& inValue); -}; - -} // namespace openspace::properties - -#include - -#endif // __OPENSPACE_CORE___PROPERTYDELEGATE___H__ diff --git a/include/openspace/properties/scalar/boolproperty.h b/include/openspace/properties/scalar/boolproperty.h index 71932957a0..56f08af1d3 100644 --- a/include/openspace/properties/scalar/boolproperty.h +++ b/include/openspace/properties/scalar/boolproperty.h @@ -44,7 +44,20 @@ namespace openspace::properties { -REGISTER_TEMPLATEPROPERTY_HEADER(BoolProperty, bool) +class BoolProperty : public TemplateProperty { +public: + BoolProperty(Property::PropertyInfo info, bool value = false); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + bool fromLuaConversion(lua_State* state, bool& success) const override; + void toLuaConversion(lua_State* state) const override; + std::string toStringConversion() const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/scalar/charproperty.h b/include/openspace/properties/scalar/charproperty.h deleted file mode 100644 index bce7e2b672..0000000000 --- a/include/openspace/properties/scalar/charproperty.h +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___CHARPROPERTY___H__ -#define __OPENSPACE_CORE___CHARPROPERTY___H__ - - /** - * \file charproperty.h - * - * \addtogroup openspace - * @{ - * \addtogroup properties - * @{ - - * \class CharProperty - * This class is a concrete implementation of openspace::properties::TemplateProperty with - * the type char. - - * @} @} - */ - -#include - -namespace openspace::properties { - -REGISTER_NUMERICALPROPERTY_HEADER(CharProperty, char) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___CHARPROPERTY___H__ diff --git a/include/openspace/properties/scalar/doubleproperty.h b/include/openspace/properties/scalar/doubleproperty.h index f0ad097207..fce130ad3d 100644 --- a/include/openspace/properties/scalar/doubleproperty.h +++ b/include/openspace/properties/scalar/doubleproperty.h @@ -41,10 +41,24 @@ */ #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(DoubleProperty, double) +class DoubleProperty : public NumericalProperty { +public: + DoubleProperty(Property::PropertyInfo info, double value = 0.0, + double minValue = std::numeric_limits::lowest(), + double maxValue = std::numeric_limits::max(), double stepValue = 0.01); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + double fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/scalar/floatproperty.h b/include/openspace/properties/scalar/floatproperty.h index 5812c05179..2b965fd3a8 100644 --- a/include/openspace/properties/scalar/floatproperty.h +++ b/include/openspace/properties/scalar/floatproperty.h @@ -41,10 +41,24 @@ */ #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(FloatProperty, float) +class FloatProperty : public NumericalProperty { +public: + FloatProperty(Property::PropertyInfo info, float value = 0.f, + float minValue = std::numeric_limits::lowest(), + float maxValue = std::numeric_limits::max(), float stepValue = 0.01f); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + float fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/scalar/intproperty.h b/include/openspace/properties/scalar/intproperty.h index 06ea74f47d..33d9a66532 100644 --- a/include/openspace/properties/scalar/intproperty.h +++ b/include/openspace/properties/scalar/intproperty.h @@ -41,10 +41,24 @@ */ #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(IntProperty, int) +class IntProperty : public NumericalProperty { +public: + IntProperty(Property::PropertyInfo info, int value = 0, + int minValue = std::numeric_limits::lowest(), + int maxValue = std::numeric_limits::max(), int stepValue = 1); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + int fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/scalar/longdoubleproperty.h b/include/openspace/properties/scalar/longdoubleproperty.h deleted file mode 100644 index 065c80aff1..0000000000 --- a/include/openspace/properties/scalar/longdoubleproperty.h +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___LONGDOUBLEPROPERTY___H__ -#define __OPENSPACE_CORE___LONGDOUBLEPROPERTY___H__ - - /** - * \file longdoubleproperty.h - * - * \addtogroup openspace - * @{ - * \addtogroup properties - * @{ - - * \class LongDoubleProperty - * This class is a concrete implementation of openspace::properties::TemplateProperty with - * the type long double. - - * @} @} - */ - -#include - -namespace openspace::properties { - -REGISTER_NUMERICALPROPERTY_HEADER(LongDoubleProperty, long double) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___LONGDOUBLEPROPERTY___H__ diff --git a/include/openspace/properties/scalar/longlongproperty.h b/include/openspace/properties/scalar/longlongproperty.h deleted file mode 100644 index f754ee2a33..0000000000 --- a/include/openspace/properties/scalar/longlongproperty.h +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___LONGLONGPROPERTY___H__ -#define __OPENSPACE_CORE___LONGLONGPROPERTY___H__ - - /** - * \file longlongproperty.h - * - * \addtogroup openspace - * @{ - * \addtogroup properties - * @{ - - * \class LongLongProperty - * This class is a concrete implementation of openspace::properties::TemplateProperty with - * the type long long. - - * @} @} - */ - -#include - -namespace openspace::properties { - -REGISTER_NUMERICALPROPERTY_HEADER(LongLongProperty, long long) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___LONGLONGPROPERTY___H__ diff --git a/include/openspace/properties/scalar/longproperty.h b/include/openspace/properties/scalar/longproperty.h index b77efc39ea..80d8b3cfec 100644 --- a/include/openspace/properties/scalar/longproperty.h +++ b/include/openspace/properties/scalar/longproperty.h @@ -41,10 +41,25 @@ */ #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(LongProperty, long) +class LongProperty : public NumericalProperty { +public: + LongProperty(Property::PropertyInfo info, long value = long(0), + long minValue = std::numeric_limits::lowest(), + long maxValue = std::numeric_limits::max(), + long stepValue = long(1)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + long fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/scalar/shortproperty.h b/include/openspace/properties/scalar/shortproperty.h index 3bd3c5af9b..1848ad23fe 100644 --- a/include/openspace/properties/scalar/shortproperty.h +++ b/include/openspace/properties/scalar/shortproperty.h @@ -41,10 +41,25 @@ */ #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(ShortProperty, short) +class ShortProperty : public NumericalProperty { +public: + ShortProperty(Property::PropertyInfo info, short value = short(0), + short minValue = std::numeric_limits::lowest(), + short maxValue = std::numeric_limits::max(), + short stepValue = short(1)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + short fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/scalar/signedcharproperty.h b/include/openspace/properties/scalar/signedcharproperty.h deleted file mode 100644 index 6f177f1219..0000000000 --- a/include/openspace/properties/scalar/signedcharproperty.h +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___SIGNEDCHARPROPERTY___H__ -#define __OPENSPACE_CORE___SIGNEDCHARPROPERTY___H__ - - /** - * \file signedcharproperty.h - * - * \addtogroup openspace - * @{ - * \addtogroup properties - * @{ - - * \class SignedCharProperty - * This class is a concrete implementation of openspace::properties::TemplateProperty with - * the type signed char. - - * @} @} - */ - -#include - -namespace openspace::properties { - -REGISTER_NUMERICALPROPERTY_HEADER(SignedCharProperty, signed char) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___SIGNEDCHARPROPERTY___H__ diff --git a/include/openspace/properties/scalar/ucharproperty.h b/include/openspace/properties/scalar/ucharproperty.h deleted file mode 100644 index 0e35a5c482..0000000000 --- a/include/openspace/properties/scalar/ucharproperty.h +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___UCHARPROPERTY___H__ -#define __OPENSPACE_CORE___UCHARPROPERTY___H__ - - /** - * \file ucharproperty.h - * - * \addtogroup openspace - * @{ - * \addtogroup properties - * @{ - - * \class UCharProperty - * This class is a concrete implementation of openspace::properties::TemplateProperty with - * the type unsigned char. - - * @} @} - */ - -#include - -namespace openspace::properties { - -REGISTER_NUMERICALPROPERTY_HEADER(UCharProperty, unsigned char) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___UCHARPROPERTY___H__ diff --git a/include/openspace/properties/scalar/uintproperty.h b/include/openspace/properties/scalar/uintproperty.h index dcbc60ee57..e3fe6fefdb 100644 --- a/include/openspace/properties/scalar/uintproperty.h +++ b/include/openspace/properties/scalar/uintproperty.h @@ -41,10 +41,25 @@ */ #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(UIntProperty, unsigned int) +class UIntProperty : public NumericalProperty { +public: + UIntProperty(Property::PropertyInfo info, unsigned int value = 0, + unsigned int minValue = std::numeric_limits::lowest(), + unsigned int maxValue = std::numeric_limits::max(), + unsigned int stepValue = 1); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + unsigned int fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/scalar/ulonglongproperty.h b/include/openspace/properties/scalar/ulonglongproperty.h deleted file mode 100644 index 2adc241bd4..0000000000 --- a/include/openspace/properties/scalar/ulonglongproperty.h +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___ULONGLONGPROPERTY___H__ -#define __OPENSPACE_CORE___ULONGLONGPROPERTY___H__ - - /** - * \file ulonglongproperty.h - * - * \addtogroup openspace - * @{ - * \addtogroup properties - * @{ - - * \class ULongLongProperty - * This class is a concrete implementation of openspace::properties::TemplateProperty with - * the type unsigned long long. - - * @} @} - */ - -#include - -namespace openspace::properties { - -REGISTER_NUMERICALPROPERTY_HEADER(ULongLongProperty, unsigned long long) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___ULONGLONGPROPERTY___H__ diff --git a/include/openspace/properties/scalar/ulongproperty.h b/include/openspace/properties/scalar/ulongproperty.h index 862cce3e69..8df652485c 100644 --- a/include/openspace/properties/scalar/ulongproperty.h +++ b/include/openspace/properties/scalar/ulongproperty.h @@ -41,10 +41,25 @@ */ #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(ULongProperty, unsigned long) +class ULongProperty : public NumericalProperty { +public: + ULongProperty(Property::PropertyInfo info, unsigned long value = 0ul, + unsigned long minValue = std::numeric_limits::lowest(), + unsigned long maxValue = std::numeric_limits::max(), + unsigned long stepValue = 1ul); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + unsigned long fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/scalar/ushortproperty.h b/include/openspace/properties/scalar/ushortproperty.h index 5a166ddd98..700b1be5ab 100644 --- a/include/openspace/properties/scalar/ushortproperty.h +++ b/include/openspace/properties/scalar/ushortproperty.h @@ -41,10 +41,25 @@ */ #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(UShortProperty, unsigned short) +class UShortProperty : public NumericalProperty { +public: + UShortProperty(Property::PropertyInfo info, unsigned short value = 0, + unsigned short minValue = std::numeric_limits::lowest(), + unsigned short maxValue = std::numeric_limits::max(), + unsigned short stepValue = 1); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + unsigned short fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/scalar/wcharproperty.h b/include/openspace/properties/scalar/wcharproperty.h deleted file mode 100644 index 321067bd84..0000000000 --- a/include/openspace/properties/scalar/wcharproperty.h +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___WCHARPROPERTY___H__ -#define __OPENSPACE_CORE___WCHARPROPERTY___H__ - - /** - * \file wcharproperty.h - * - * \addtogroup openspace - * @{ - * \addtogroup properties - * @{ - - * \class WCharProperty - * This class is a concrete implementation of openspace::properties::TemplateProperty with - * the type wchar_t. - - * @} @} - */ - -#include - -namespace openspace::properties { - -//REGISTER_NUMERICALPROPERTY_HEADER(WCharProperty, wchar_t) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___WCHARPROPERTY___H__ diff --git a/include/openspace/properties/selectionproperty.h b/include/openspace/properties/selectionproperty.h index 9006ecc630..b17f580a52 100644 --- a/include/openspace/properties/selectionproperty.h +++ b/include/openspace/properties/selectionproperty.h @@ -37,6 +37,9 @@ class SelectionProperty : public TemplateProperty> { public: SelectionProperty(Property::PropertyInfo info); + std::string className() const override; + int typeLua() const override; + /** * This method sets the stored value to the provided value val. * If the value is different, the listeners are notified. It also removes any @@ -110,6 +113,13 @@ public: using TemplateProperty>::operator=; +protected: + std::set fromLuaConversion(lua_State* state, bool& success) const override; + + void toLuaConversion(lua_State* state) const override; + + std::string toStringConversion() const override; + private: void sortOptions(); bool removeInvalidKeys(std::set& keys); @@ -120,28 +130,6 @@ private: std::vector _options; }; -template <> -std::string PropertyDelegate>>::className(); - -template <> -template <> -std::set -PropertyDelegate>>::fromLuaValue(lua_State* state, - bool& success); - -template <> -template <> -bool PropertyDelegate>>::toLuaValue( - lua_State* state, const std::set& value); - -template <> -int PropertyDelegate>>::typeLua(); - -template <> -template <> -bool PropertyDelegate>>::toString( - std::string& outValue, const std::set& inValue); - } // namespace openspace::properties #endif // __OPENSPACE_CORE___SELECTIONPROPERTY___H__ diff --git a/include/openspace/properties/stringproperty.h b/include/openspace/properties/stringproperty.h index e869528c5b..d1a7b8dd7b 100644 --- a/include/openspace/properties/stringproperty.h +++ b/include/openspace/properties/stringproperty.h @@ -29,7 +29,20 @@ namespace openspace::properties { -REGISTER_TEMPLATEPROPERTY_HEADER(StringProperty, std::string) +class StringProperty : public TemplateProperty { +public: + StringProperty(Property::PropertyInfo info, std::string value = ""); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + std::string fromLuaConversion(lua_State* state, bool& success) const override; + void toLuaConversion(lua_State* state) const override; + std::string toStringConversion() const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/templateproperty.h b/include/openspace/properties/templateproperty.h index 81db5f3bff..a9ccd7a8b7 100644 --- a/include/openspace/properties/templateproperty.h +++ b/include/openspace/properties/templateproperty.h @@ -27,12 +27,10 @@ #include -#include - namespace openspace::properties { /** - * This concrete subclass of Property handles a single parameter value that is of type + * This subclass of Property handles a single parameter value that is of type * T. It provides all the necessary methods to automatically access the * value. One notable instantiation of this class is StringProperty, using * T = std::string while NumericalProperty is a templated subclass dealing @@ -40,16 +38,14 @@ namespace openspace::properties { * The accessor operator and assignment operators are overloaded, so that the * TemplateProperty can be used just in the same way as a regular member variable. In the * case that these cannot not be used inline, the Property::get method will work. - * The default value for the stored value of this TemplateProperty is retrieved via a call - * to the PropertyDelegate::defaultValue method, providing the template parameter - * T as argument. When a new TemplateProperty is required, that method needs - * to be specialized for the new type or a compile-time error will occur - * (See https://github.com/OpenSpace/OpenSpace/wiki/Concepts-Properties). + * + * Each instantiation of this class should provide a constructor that deals with the + * default value for that specific type T, so that a property can be + * created from just a Property::PropertyInfo object. * * \tparam T The type of value that is stored in this TemplateProperty * \see Property * \see NumericalProperty - * \see PropertyDelegate */ template class TemplateProperty : public Property { @@ -67,19 +63,15 @@ public: * \pre \p info.identifier must not be empty * \pre \p info.guiName must not be empty */ - TemplateProperty(Property::PropertyInfo info, - T value = PropertyDelegate>::template defaultValue()); + TemplateProperty(Property::PropertyInfo info, T value); /** - * Returns the class name for this TemplateProperty. The default implementation makes - * a call to the PropertyDelegate::className method with the template parameter - * T as argument. For this to work, that method needs to be specialized - * to return the correct class name for the new template parameter T, or a - * compile-time error will occur. + * Returns the class name for this TemplateProperty. This method has to be + * specialized for each new type. * * \return The class name for the TemplateProperty */ - virtual std::string className() const override; + virtual std::string className() const override = 0; /** * Returns the stored value packed into a ghoul::any object. @@ -108,41 +100,34 @@ public: /** * This method encodes the stored value into a Lua object and pushes that object onto - * the stack. The encoding is performed by calling PropertyDelegate::toLuaValue with - * the template parameter T as an argument. This method has to be - * specialized for each new type, or a compile-time error will occur. + * the stack. * * \param state The Lua state onto which the encoded object will be pushed * \return \c true if the encoding succeeded; \c false otherwise */ - bool getLuaValue(lua_State* state) const override; + virtual bool getLuaValue(lua_State* state) const override; /** - * Sets the value of this TemplateProperty by decoding the object at the top of the Lua - * stack and, if successful, assigning it using the Property::set method. The decoding - * is performed by calling the PropertyDelegate::fromLuaValue with the template - * parameter T as argument. If the decoding is successful, the new value - * is set, otherwise it remains unchanged. + * Sets the value of this TemplateProperty by decoding the object at the top of the + * stack and, if successful, assigning it using the Property::set method. If the + * decoding is successful, the new value is set, otherwise it remains unchanged. * * \param state The Lua state from which the value will be decoded * \return \c true if the decoding succeeded; \c false otherwise */ - bool setLuaValue(lua_State* state) override; + virtual bool setLuaValue(lua_State* state) override; /// \see Property::typeLua - int typeLua() const override; + virtual int typeLua() const override = 0; /** - * This method encodes the stored value into a std::string object. The encoding is - * performed by calling PropertyDelegate::toStringValue with the template parameter - * T as an argument. This method has to be specialized for each new - * type, or a compile-time error will occur. The resulting encoding must also be a - * valid JSON representation fo the property. + * This method encodes the stored value into a std::string object. The resulting + * encoding must also be a valid JSON representation fo the property. * * \param value The string object in which to store the resulting encoding * \return \c true if the encoding succeeded; \c false otherwise */ - bool getStringValue(std::string& value) const override; + virtual bool getStringValue(std::string& value) const override; /** * Returns the description for this TemplateProperty as a Lua script that returns a @@ -199,6 +184,33 @@ public: T value() const; protected: + /** + * Decodes the object at the top of the stack to a value of the type T + * and returns it. This method has to be specialized for each new type. + * + * \param state The Lua state from which the value will be decoded + * \param success Set to true \c true if the decoding succeeded; \c false otherwise + * \return the decoded value + */ + virtual T fromLuaConversion(lua_State* state, bool& success) const = 0; + + /** + * Encodes the stored value into a Lua object and pushes that object onto + * the stack. This method has to be specialized for each new type. + * + * \param state The Lua state onto which the encoded object will be pushed + */ + virtual void toLuaConversion(lua_State* state) const = 0; + + /** + * Encodes the stored value into a std::string object, in a format that is a valid + * JSON representation of the property. This method has to be specialized for each + * new type. + * + * \return The resulting encoding + */ + virtual std::string toStringConversion() const = 0; + /// The value that this TemplateProperty currently stores T _value; }; diff --git a/include/openspace/properties/templateproperty.inl b/include/openspace/properties/templateproperty.inl index 2dc21e7b30..f4508183ea 100644 --- a/include/openspace/properties/templateproperty.inl +++ b/include/openspace/properties/templateproperty.inl @@ -24,118 +24,12 @@ namespace openspace::properties { - // The following macros can be used to quickly generate the necessary PropertyDelegate - // specializations required by the TemplateProperty class. Use the - // REGISTER_TEMPLATEPROPERTY_HEADER macro in the header file and the - // REGISTER_TEMPLATEPROPERTY_SOURCE macro in the source file of your new - // specialization of a TemplateProperty - - - // CLASS_NAME = The string that the Property::className() should return as well as the - // C++ class name for which a typedef will be created - // TYPE = The template parameter T for which the TemplateProperty is specialized -#define REGISTER_TEMPLATEPROPERTY_HEADER(CLASS_NAME, TYPE) \ - using CLASS_NAME = TemplateProperty; \ - \ - template <> \ - std::string PropertyDelegate>::className(); \ - \ - template <> \ - template <> \ - TYPE PropertyDelegate>::defaultValue(); \ - \ - template <> \ - template <> \ - TYPE PropertyDelegate>::fromLuaValue(lua_State* state, \ - bool& success); \ - \ - template <> \ - template <> \ - bool PropertyDelegate>::toLuaValue(lua_State* state, \ - const TYPE& value); \ - \ - template <> \ - int PropertyDelegate>::typeLua(); \ - \ - template <> \ - template <> \ - bool PropertyDelegate>::toString(std::string& outValue, \ - const TYPE& inValue); - - -// CLASS_NAME = The string that the Property::className() should return as well as the -// C++ class name for which a typedef will be created -// TYPE = The template parameter T for which the TemplateProperty is specialized -// DEFAULT_VALUE = The value (as type T) which should be used as a default value -// FROM_LUA_LAMBDA_EXPRESSION = A lambda expression receiving a lua_State* as the first -// parameter, a bool& as the second parameter and returning -// a value T. It is used by the fromLua method of -// TemplateProperty. The lambda expression must extract the -// stored value from the lua_State, return the value and -// report success in the second argument -// TO_LUA_LAMBDA_EXPRESSION = A lambda expression receiving a lua_State*, a value T and -// returning a bool. The lambda expression must encode the -// value T onto the lua_State stack and return the success -// LUA_TYPE = The Lua type that will be produced/consumed by the previous -// Lambda expressions -#define REGISTER_TEMPLATEPROPERTY_SOURCE(CLASS_NAME, TYPE, DEFAULT_VALUE, \ - FROM_LUA_LAMBDA_EXPRESSION, \ - TO_LUA_LAMBDA_EXPRESSION, \ - TO_STRING_LAMBDA_EXPRESSION, LUA_TYPE) \ - template <> \ - std::string PropertyDelegate>::className() \ - { \ - return #CLASS_NAME; \ - } \ - \ - template <> \ - template <> \ - TYPE PropertyDelegate>::defaultValue() \ - { \ - return DEFAULT_VALUE; \ - } \ - \ - template <> \ - template <> \ - TYPE PropertyDelegate>::fromLuaValue(lua_State* state, \ - bool& success) \ - { \ - return FROM_LUA_LAMBDA_EXPRESSION(state, success); \ - } \ - \ - template <> \ - template <> \ - bool PropertyDelegate>::toLuaValue(lua_State* state, \ - const TYPE& value) \ - { \ - return TO_LUA_LAMBDA_EXPRESSION(state, value); \ - } \ - \ - template <> \ - int PropertyDelegate>::typeLua() { \ - return LUA_TYPE; \ - } \ - \ - template <> \ - template <> \ - bool PropertyDelegate>::toString(std::string& outValue, \ - const TYPE& inValue) \ - { \ - return TO_STRING_LAMBDA_EXPRESSION(outValue, inValue); \ - } \ - - template TemplateProperty::TemplateProperty(Property::PropertyInfo info, T value) : Property(std::move(info)) , _value(std::move(value)) {} -template -std::string TemplateProperty::className() const { - return PropertyDelegate>::className(); -} - template TemplateProperty::operator T() { return _value; @@ -190,20 +84,14 @@ const std::type_info& TemplateProperty::type() const { template bool TemplateProperty::getLuaValue(lua_State* state) const { - bool success = PropertyDelegate>::template toLuaValue( - state, - _value - ); - return success; + toLuaConversion(state); + return true; } template bool TemplateProperty::setLuaValue(lua_State* state) { bool success = false; - T thisValue = PropertyDelegate>::template fromLuaValue( - state, - success - ); + T thisValue = fromLuaConversion(state, success); if (success) { set(std::any(thisValue)); } @@ -211,17 +99,9 @@ bool TemplateProperty::setLuaValue(lua_State* state) { } template -int TemplateProperty::typeLua() const { - return PropertyDelegate>::typeLua(); -} - -template -bool TemplateProperty::getStringValue(std::string& value) const { - bool success = PropertyDelegate>::template toString( - value, - _value - ); - return success; +bool TemplateProperty::getStringValue(std::string& outValue) const { + outValue = toStringConversion(); + return true; } } // namespace openspace::properties diff --git a/include/openspace/properties/vector/bvec2property.h b/include/openspace/properties/vector/bvec2property.h deleted file mode 100644 index d830934a8d..0000000000 --- a/include/openspace/properties/vector/bvec2property.h +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___BVEC2PROPERTY___H__ -#define __OPENSPACE_CORE___BVEC2PROPERTY___H__ - -#include - -#include - -namespace openspace::properties { - -REGISTER_TEMPLATEPROPERTY_HEADER(BVec2Property, glm::bvec2) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___BVEC2PROPERTY___H__ diff --git a/include/openspace/properties/vector/bvec3property.h b/include/openspace/properties/vector/bvec3property.h deleted file mode 100644 index e800cd040e..0000000000 --- a/include/openspace/properties/vector/bvec3property.h +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___BVEC3PROPERTY___H__ -#define __OPENSPACE_CORE___BVEC3PROPERTY___H__ - -#include - -#include - -namespace openspace::properties { - -REGISTER_TEMPLATEPROPERTY_HEADER(BVec3Property, glm::bvec3) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___BVEC3PROPERTY___H__ diff --git a/include/openspace/properties/vector/bvec4property.h b/include/openspace/properties/vector/bvec4property.h deleted file mode 100644 index 9c007f8f42..0000000000 --- a/include/openspace/properties/vector/bvec4property.h +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___BVEC4PROPERTY___H__ -#define __OPENSPACE_CORE___BVEC4PROPERTY___H__ - -#include - -#include - -namespace openspace::properties { - -REGISTER_TEMPLATEPROPERTY_HEADER(BVec4Property, glm::bvec4) - -} // namespace openspace::properties - -#endif // __OPENSPACE_CORE___BVEC4PROPERTY___H__ diff --git a/include/openspace/properties/vector/dvec2property.h b/include/openspace/properties/vector/dvec2property.h index a6d72d8e48..3234fead9e 100644 --- a/include/openspace/properties/vector/dvec2property.h +++ b/include/openspace/properties/vector/dvec2property.h @@ -28,10 +28,25 @@ #include #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(DVec2Property, glm::dvec2) +class DVec2Property : public NumericalProperty { +public: + DVec2Property(Property::PropertyInfo info, glm::dvec2 value = glm::dvec2(0.0), + glm::dvec2 minValue = glm::dvec2(std::numeric_limits::lowest()), + glm::dvec2 maxValue = glm::dvec2(std::numeric_limits::max()), + glm::dvec2 stepValue = glm::dvec2(0.01)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + glm::dvec2 fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/vector/dvec3property.h b/include/openspace/properties/vector/dvec3property.h index 782f1c63d2..0def50c6e1 100644 --- a/include/openspace/properties/vector/dvec3property.h +++ b/include/openspace/properties/vector/dvec3property.h @@ -28,10 +28,25 @@ #include #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(DVec3Property, glm::dvec3) +class DVec3Property : public NumericalProperty { +public: + DVec3Property(Property::PropertyInfo info, glm::dvec3 value = glm::dvec3(0.0), + glm::dvec3 minValue = glm::dvec3(std::numeric_limits::lowest()), + glm::dvec3 maxValue = glm::dvec3(std::numeric_limits::max()), + glm::dvec3 stepValue = glm::dvec3(0.01)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + glm::dvec3 fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/vector/dvec4property.h b/include/openspace/properties/vector/dvec4property.h index e4e85dc79d..42cd570e9e 100644 --- a/include/openspace/properties/vector/dvec4property.h +++ b/include/openspace/properties/vector/dvec4property.h @@ -28,10 +28,25 @@ #include #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(DVec4Property, glm::dvec4) +class DVec4Property : public NumericalProperty { +public: + DVec4Property(Property::PropertyInfo info, glm::dvec4 value = glm::dvec4(0.0), + glm::dvec4 minValue = glm::dvec4(std::numeric_limits::lowest()), + glm::dvec4 maxValue = glm::dvec4(std::numeric_limits::max()), + glm::dvec4 stepValue = glm::dvec4(0.01)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + glm::dvec4 fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/vector/ivec2property.h b/include/openspace/properties/vector/ivec2property.h index 720afa62e8..b2060baa22 100644 --- a/include/openspace/properties/vector/ivec2property.h +++ b/include/openspace/properties/vector/ivec2property.h @@ -28,10 +28,25 @@ #include #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(IVec2Property, glm::ivec2) +class IVec2Property : public NumericalProperty { +public: + IVec2Property(Property::PropertyInfo info, glm::ivec2 value = glm::ivec2(0), + glm::ivec2 minValue = glm::ivec2(std::numeric_limits::lowest()), + glm::ivec2 maxValue = glm::ivec2(std::numeric_limits::max()), + glm::ivec2 stepValue = glm::ivec2(1)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + glm::ivec2 fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/vector/ivec3property.h b/include/openspace/properties/vector/ivec3property.h index 0a68a8e7dd..3585592ac0 100644 --- a/include/openspace/properties/vector/ivec3property.h +++ b/include/openspace/properties/vector/ivec3property.h @@ -28,10 +28,25 @@ #include #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(IVec3Property, glm::ivec3) +class IVec3Property : public NumericalProperty { +public: + IVec3Property(Property::PropertyInfo info, glm::ivec3 value = glm::ivec3(0), + glm::ivec3 minValue = glm::ivec3(std::numeric_limits::lowest()), + glm::ivec3 maxValue = glm::ivec3(std::numeric_limits::max()), + glm::ivec3 stepValue = glm::ivec3(1)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + glm::ivec3 fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/vector/ivec4property.h b/include/openspace/properties/vector/ivec4property.h index 9e076f009d..392c456032 100644 --- a/include/openspace/properties/vector/ivec4property.h +++ b/include/openspace/properties/vector/ivec4property.h @@ -28,10 +28,25 @@ #include #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(IVec4Property, glm::ivec4) +class IVec4Property : public NumericalProperty { +public: + IVec4Property(Property::PropertyInfo info, glm::ivec4 value = glm::ivec4(0), + glm::ivec4 minValue = glm::ivec4(std::numeric_limits::lowest()), + glm::ivec4 maxValue = glm::ivec4(std::numeric_limits::max()), + glm::ivec4 stepValue = glm::ivec4(1)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + glm::ivec4 fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/vector/uvec2property.h b/include/openspace/properties/vector/uvec2property.h index cd8ee273e6..abcc240a7c 100644 --- a/include/openspace/properties/vector/uvec2property.h +++ b/include/openspace/properties/vector/uvec2property.h @@ -28,10 +28,25 @@ #include #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(UVec2Property, glm::uvec2) +class UVec2Property : public NumericalProperty { +public: + UVec2Property(Property::PropertyInfo info, glm::uvec2 value = glm::uvec2(0), + glm::uvec2 minValue = glm::uvec2(std::numeric_limits::lowest()), + glm::uvec2 maxValue = glm::uvec2(std::numeric_limits::max()), + glm::uvec2 stepValue = glm::uvec2(1)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + glm::uvec2 fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/vector/uvec3property.h b/include/openspace/properties/vector/uvec3property.h index a0cae39791..3f9037d39b 100644 --- a/include/openspace/properties/vector/uvec3property.h +++ b/include/openspace/properties/vector/uvec3property.h @@ -28,10 +28,25 @@ #include #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(UVec3Property, glm::uvec3) +class UVec3Property : public NumericalProperty { +public: + UVec3Property(Property::PropertyInfo info, glm::uvec3 value = glm::uvec3(0), + glm::uvec3 minValue = glm::uvec3(std::numeric_limits::lowest()), + glm::uvec3 maxValue = glm::uvec3(std::numeric_limits::max()), + glm::uvec3 stepValue = glm::uvec3(1)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + glm::uvec3 fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/vector/uvec4property.h b/include/openspace/properties/vector/uvec4property.h index 57111530a4..a83d5e1e4e 100644 --- a/include/openspace/properties/vector/uvec4property.h +++ b/include/openspace/properties/vector/uvec4property.h @@ -28,10 +28,25 @@ #include #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(UVec4Property, glm::uvec4) +class UVec4Property : public NumericalProperty { +public: + UVec4Property(Property::PropertyInfo info, glm::uvec4 value = glm::uvec4(0), + glm::uvec4 minValue = glm::uvec4(std::numeric_limits::lowest()), + glm::uvec4 maxValue = glm::uvec4(std::numeric_limits::max()), + glm::uvec4 stepValue = glm::uvec4(1)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + glm::uvec4 fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/vector/vec2property.h b/include/openspace/properties/vector/vec2property.h index e17bf88f99..f58647c4de 100644 --- a/include/openspace/properties/vector/vec2property.h +++ b/include/openspace/properties/vector/vec2property.h @@ -28,10 +28,25 @@ #include #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(Vec2Property, glm::vec2) +class Vec2Property : public NumericalProperty { +public: + Vec2Property(Property::PropertyInfo info, glm::vec2 value = glm::vec2(0.f), + glm::vec2 minValue = glm::vec2(std::numeric_limits::lowest()), + glm::vec2 maxValue = glm::vec2(std::numeric_limits::max()), + glm::vec2 stepValue = glm::vec2(0.01f)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + glm::vec2 fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/vector/vec3property.h b/include/openspace/properties/vector/vec3property.h index 902226eed3..663f61cd86 100644 --- a/include/openspace/properties/vector/vec3property.h +++ b/include/openspace/properties/vector/vec3property.h @@ -28,10 +28,25 @@ #include #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(Vec3Property, glm::vec3) +class Vec3Property : public NumericalProperty { +public: + Vec3Property(Property::PropertyInfo info, glm::vec3 value = glm::vec3(0.f), + glm::vec3 minValue = glm::vec3(std::numeric_limits::lowest()), + glm::vec3 maxValue = glm::vec3(std::numeric_limits::max()), + glm::vec3 stepValue = glm::vec3(0.01f)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + glm::vec3 fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/properties/vector/vec4property.h b/include/openspace/properties/vector/vec4property.h index 35b5b4c6a6..ae8e467cfd 100644 --- a/include/openspace/properties/vector/vec4property.h +++ b/include/openspace/properties/vector/vec4property.h @@ -28,10 +28,25 @@ #include #include +#include namespace openspace::properties { -REGISTER_NUMERICALPROPERTY_HEADER(Vec4Property, glm::vec4) +class Vec4Property : public NumericalProperty { +public: + Vec4Property(Property::PropertyInfo info, glm::vec4 value = glm::vec4(0.f), + glm::vec4 minValue = glm::vec4(std::numeric_limits::lowest()), + glm::vec4 maxValue = glm::vec4(std::numeric_limits::max()), + glm::vec4 stepValue = glm::vec4(0.01f)); + + std::string className() const override; + int typeLua() const override; + + using TemplateProperty::operator=; + +protected: + glm::vec4 fromLuaConversion(lua_State* state, bool& success) const override; +}; } // namespace openspace::properties diff --git a/include/openspace/rendering/deferredcaster.h b/include/openspace/rendering/deferredcaster.h index 0f33e1894e..3d9f476848 100644 --- a/include/openspace/rendering/deferredcaster.h +++ b/include/openspace/rendering/deferredcaster.h @@ -25,6 +25,7 @@ #ifndef __OPENSPACE_CORE___DEFERREDCASTER___H #define __OPENSPACE_CORE___DEFERREDCASTER___H +#include #include namespace ghoul::opengl { @@ -46,31 +47,30 @@ public: const DeferredcastData& /*deferredData*/, ghoul::opengl::ProgramObject& /*program*/) {}; - virtual void postRaycast(const RenderData & /*renderData*/, + virtual void postRaycast(const RenderData& /*renderData*/, const DeferredcastData& /*deferredData*/, ghoul::opengl::ProgramObject& /*program*/) {}; - virtual std::string deferredcastPath() const = 0; + virtual std::filesystem::path deferredcastPath() const = 0; - virtual std::string deferredcastVSPath() const = 0; + virtual std::filesystem::path deferredcastVSPath() const = 0; - virtual std::string deferredcastFSPath() const = 0; + virtual std::filesystem::path deferredcastFSPath() const = 0; virtual void initializeCachedVariables(ghoul::opengl::ProgramObject&) = 0; virtual void update(const UpdateData&) = 0; /** - * Return a path to a glsl file with helper functions required for the - * transformation and raycast steps. - * This file will be included once per shader program generated, - * regardless of how many volumes say they require the file. - * Ideal to avoid redefinitions of helper functions. + * Return a path to a GLSL file with helper functions required for the transformation + * and raycast steps. This file will be included once per shader program generated, + * regardless of how many volumes say they require the file. Ideal to avoid + * redefinitions of helper functions. * * The shader preprocessor will have access to the #{namespace} variable (unique per * helper file) which should be a prefix to all symbols defined by the helper */ - virtual std::string helperPath() const = 0; + virtual std::filesystem::path helperPath() const = 0; }; } // namespace openspace diff --git a/include/openspace/rendering/framebufferrenderer.h b/include/openspace/rendering/framebufferrenderer.h index ce4c00fb86..d76c2c5d88 100644 --- a/include/openspace/rendering/framebufferrenderer.h +++ b/include/openspace/rendering/framebufferrenderer.h @@ -83,8 +83,10 @@ public: void setDisableHDR(bool disable) override; void update() override; - void performRaycasterTasks(const std::vector& tasks); - void performDeferredTasks(const std::vector& tasks); + void performRaycasterTasks(const std::vector& tasks, + const glm::ivec4& viewport); + void performDeferredTasks(const std::vector& tasks, + const glm::ivec4& viewport); void render(Scene* scene, Camera* camera, float blackoutFactor) override; /** @@ -109,11 +111,11 @@ private: >; void resolveMSAA(float blackoutFactor); - void applyTMO(float blackoutFactor); - void applyFXAA(); + void applyTMO(float blackoutFactor, const glm::ivec4& viewport); + void applyFXAA(const glm::ivec4& viewport); void updateDownscaleTextures(); void updateExitVolumeTextures(); - void writeDownscaledVolume(); + void writeDownscaledVolume(const glm::ivec4& viewport); std::map _raycastData; RaycasterProgObjMap _exitPrograms; @@ -129,10 +131,11 @@ private: std::unique_ptr _downscaledVolumeProgram; UniformCache(hdrFeedingTexture, blackoutFactor, hdrExposure, gamma, - Hue, Saturation, Value) _hdrUniformCache; - UniformCache(renderedTexture, inverseScreenSize) _fxaaUniformCache; - UniformCache(downscaledRenderedVolume, downscaledRenderedVolumeDepth) - _writeDownscaledVolumeUniformCache; + Hue, Saturation, Value, Viewport, Resolution) _hdrUniformCache; + UniformCache(renderedTexture, inverseScreenSize, Viewport, + Resolution) _fxaaUniformCache; + UniformCache(downscaledRenderedVolume, downscaledRenderedVolumeDepth, viewport, + resolution) _writeDownscaledVolumeUniformCache; GLint _defaultFBO; GLuint _screenQuad; diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index f698af2248..cc6698f165 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -34,6 +34,7 @@ #include #include #include +#include namespace ghoul { namespace fontrendering { class Font; } @@ -109,12 +110,13 @@ public: std::vector screenSpaceRenderables() const; std::unique_ptr buildRenderProgram( - const std::string& name, const std::string& vsPath, std::string fsPath, - ghoul::Dictionary data = ghoul::Dictionary()); + const std::string& name, const std::filesystem::path& vsPath, + std::filesystem::path fsPath, ghoul::Dictionary data = ghoul::Dictionary()); std::unique_ptr buildRenderProgram( - const std::string& name, const std::string& vsPath, std::string fsPath, - const std::string& csPath, ghoul::Dictionary data = ghoul::Dictionary()); + const std::string& name, const std::filesystem::path& vsPath, + std::filesystem::path fsPath, const std::filesystem::path& csPath, + ghoul::Dictionary data = ghoul::Dictionary()); void removeRenderProgram(ghoul::opengl::ProgramObject* program); diff --git a/include/openspace/rendering/screenspacerenderable.h b/include/openspace/rendering/screenspacerenderable.h index 189ae16d12..87154bd7b8 100644 --- a/include/openspace/rendering/screenspacerenderable.h +++ b/include/openspace/rendering/screenspacerenderable.h @@ -104,11 +104,12 @@ protected: properties::Vec3Property _localRotation; properties::FloatProperty _scale; + properties::Vec3Property _multiplyColor; properties::FloatProperty _opacity; properties::TriggerProperty _delete; glm::ivec2 _objectSize = glm::ivec2(0); - UniformCache(alpha, modelTransform, viewProj, texture) _uniformCache; + UniformCache(color, opacity, mvp, texture) _uniformCache; std::unique_ptr _shader; }; diff --git a/include/openspace/rendering/texturecomponent.h b/include/openspace/rendering/texturecomponent.h index 5c4d905a7c..1940e05fac 100644 --- a/include/openspace/rendering/texturecomponent.h +++ b/include/openspace/rendering/texturecomponent.h @@ -26,6 +26,7 @@ #define __OPENSPACE_CORE___TEXTURECOMPONENT___H__ #include +#include namespace ghoul::filesystem { class File; } namespace ghoul::opengl {class Texture; } @@ -48,7 +49,7 @@ public: void uploadToGpu(); // Loads a texture from a file on disk - void loadFromFile(const std::string& path); + void loadFromFile(const std::filesystem::path& path); // Function to call in a renderable's update function to make sure // the texture is kept up to date diff --git a/include/openspace/rendering/transferfunction.h b/include/openspace/rendering/transferfunction.h index cdad470af7..cca8ef5dc0 100644 --- a/include/openspace/rendering/transferfunction.h +++ b/include/openspace/rendering/transferfunction.h @@ -26,6 +26,7 @@ #define __OPENSPACE_CORE___TRANSFERFUNCTION___H__ #include +#include #include #include #include @@ -58,7 +59,7 @@ private: void setTextureFromImage(); void uploadTexture(); - std::string _filepath; + std::filesystem::path _filepath; std::unique_ptr _file; std::shared_ptr _texture; bool _needsUpdate = false; diff --git a/include/openspace/scene/assetloader.h b/include/openspace/scene/assetloader.h index 779e98e892..141dc5aa2c 100644 --- a/include/openspace/scene/assetloader.h +++ b/include/openspace/scene/assetloader.h @@ -26,6 +26,7 @@ #define __OPENSPACE_CORE___ASSETLOADER___H__ #include +#include #include #include #include @@ -169,7 +170,7 @@ private: void tearDownAssetLuaTable(Asset* asset); std::shared_ptr getAsset(const std::string& name); - ghoul::filesystem::Directory currentDirectory() const; + std::filesystem::path currentDirectory() const; void setCurrentAsset(Asset* asset); void addLuaDependencyTable(Asset* dependant, Asset* dependency); diff --git a/include/openspace/scripting/lualibrary.h b/include/openspace/scripting/lualibrary.h index 1c123f6014..698da1ca6a 100644 --- a/include/openspace/scripting/lualibrary.h +++ b/include/openspace/scripting/lualibrary.h @@ -26,6 +26,7 @@ #define __OPENSPACE_CORE___LUALIBRARY___H__ #include +#include #include #include @@ -58,7 +59,7 @@ struct LuaLibrary { /// The list of all C-based callback functions for this library std::vector functions; /// A list of script files that are executed for each Lua state - std::vector scripts = std::vector(); + std::vector scripts = std::vector(); /// This struct contains information about a function or constant that is defined in /// a Lua script diff --git a/modules/digitaluniverse/shaders/pointssprite_fs.glsl b/include/openspace/util/json_helper.h similarity index 62% rename from modules/digitaluniverse/shaders/pointssprite_fs.glsl rename to include/openspace/util/json_helper.h index 6a6cfdb647..f5dafffdbc 100644 --- a/modules/digitaluniverse/shaders/pointssprite_fs.glsl +++ b/include/openspace/util/json_helper.h @@ -22,32 +22,47 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include "fragment.glsl" +#ifndef __OPENSPACE_CORE___JSON_HELPER___H__ +#define __OPENSPACE_CORE___JSON_HELPER___H__ -in float vs_screenSpaceDepth; -in vec2 vs_st; +#include -uniform sampler2D texture1; -uniform bool additiveBlending; +namespace openspace { +/** + * This function takes a \p text and escapes all necessary characters () that JSON + * does not want in its strings. + * \param text The text that is to be escaped + * \return The same text with all required characteres escaped + */ +std::string escapedJson(const std::string& text); -Fragment getFragment() { - Fragment frag; - if (gl_FrontFacing) { - frag.color = texture(texture1, vs_st); - } - else { - frag.color = texture(texture1, vec2(1 - vs_st.s, vs_st.t)); - } +/** + * This function takes a \p list of text and escapes all necessary characters () that + * JSON does not want in its strings. + * \param text The list of text that is to be escaped + * \return The same text with all required characteres escaped + */ +std::string escapedJson(const std::vector& list); - if (frag.color.a == 0.0) { - discard; - } +/** + * Convert the input value to a valid JSON formatted string. Nan and Inf values + * are not vald JSON and will be represented by 'null' + * \param d The value to format + * \return The resulting JSON formatted string + */ +std::string formatJsonNumber(double d); - frag.depth = vs_screenSpaceDepth; +/** + * Convert the input value to a valid JSON formatted string + * \param value The value to be converted + * \return The resulting JSON formatted string + */ +template +std::string formatJson(T value); - if (additiveBlending) { - frag.blend = BLEND_MODE_ADDITIVE; - } - return frag; -} +} // namespace openspace + +#include "json_helper.inl" + +#endif // __OPENSPACE_CORE___JSON_HELPER___H__ diff --git a/include/openspace/properties/propertydelegate.inl b/include/openspace/util/json_helper.inl similarity index 50% rename from include/openspace/properties/propertydelegate.inl rename to include/openspace/util/json_helper.inl index be419421cf..ce0fafec86 100644 --- a/include/openspace/properties/propertydelegate.inl +++ b/include/openspace/util/json_helper.inl @@ -22,73 +22,75 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include +#include +#include +#include +#include -namespace openspace::properties { +namespace openspace { + +namespace internal { + +template +struct is_any : std::disjunction...> {}; template -std::string PropertyDelegate::className() { - static_assert(sizeof(T) == 0, - "Unimplemented PropertyDelegate::className specialization"); - return ""; +constexpr bool isGlmMatrix() { + return is_any::value; } template -template -U PropertyDelegate::defaultValue() { - static_assert(sizeof(T) == 0, - "Unimplemented PropertyDelegate::defaultValue specialization"); +constexpr bool isGlmVector() { + return is_any::value; } +} // namespace internal + template -template -U PropertyDelegate::defaultMinimumValue() { - static_assert(sizeof(T) == 0, - "Unimplemented PropertyDelegate::defaultMinimumValue specialization"); +std::string formatJson(T value) { + if constexpr (std::is_same_v) { + return value ? "true" : "false"; + } + else if constexpr (std::is_arithmetic_v) { + return formatJsonNumber(static_cast(value)); + } + else if constexpr (std::is_same_v) { + return escapedJson(value); + } + else if constexpr (std::is_same_v) { + return ghoul::formatJson(value); + } + else if constexpr (internal::isGlmVector()) { + std::string values; + for (glm::length_t i = 0; i < ghoul::glm_components::value; ++i) { + values += std::to_string(value[i]) + ','; + } + values.pop_back(); + return fmt::format("[{}]", values); + } + else if constexpr (internal::isGlmMatrix()) { + std::string values; + for (glm::length_t i = 0; i < T::type::row_type::length(); ++i) { + for (glm::length_t j = 0; j < T::type::col_type::length(); ++j) { + values += std::to_string(value[i][j]) + ','; + } + } + values.pop_back(); + return fmt::format("[{}]", values); + } + else { + static_assert(sizeof(T) == 0, "JSON formatting of type T not implemented"); + } } -template -template -U PropertyDelegate::defaultMaximumValue() { - static_assert(sizeof(T) == 0, - "Unimplemented PropertyDelegate::defaultMaximumValue specialization"); -} - -template -template -U PropertyDelegate::defaultSteppingValue() { - static_assert(sizeof(T) == 0, - "Unimplemented PropertyDelegate::defaultSteppingValue specialization"); -} - -template -template -U PropertyDelegate::fromLuaValue(lua_State*, bool&) { - static_assert(sizeof(T) == 0, - "Unimplemented PropertyDelegate::fromLuaValue specialization"); -} - -template -template -bool PropertyDelegate::toLuaValue(lua_State*, const U&) { - static_assert(sizeof(T) == 0, - "Unimplemented PropertyDelegate::toLuaValue specialization"); - return false; -} - -template -int PropertyDelegate::typeLua() { - static_assert(sizeof(T) == 0, - "Unimplemented PropertyDelegate::luaType specialization"); - return 0; -} - -template -template -bool PropertyDelegate::toString(std::string&, const U&) { - static_assert(sizeof(T) == 0, - "Unimplemented PropertyDelegate::toString specialization"); - return false; -} - -} // namespace openspace::properties +} // namespace openspace diff --git a/include/openspace/util/timeline.h b/include/openspace/util/timeline.h index 1f2936cf40..60e71f25cc 100644 --- a/include/openspace/util/timeline.h +++ b/include/openspace/util/timeline.h @@ -47,8 +47,8 @@ struct Keyframe : public KeyframeBase { Keyframe(size_t i, double t, T d); Keyframe(Keyframe const&) = default; - Keyframe(Keyframe&&) = default; - Keyframe& operator=(Keyframe&&) = default; + Keyframe(Keyframe&&) noexcept = default; + Keyframe& operator=(Keyframe&&) noexcept = default; Keyframe& operator=(Keyframe const&) = default; T data; }; diff --git a/include/openspace/util/timemanager.h b/include/openspace/util/timemanager.h index 1e213abb0a..d7500939c6 100644 --- a/include/openspace/util/timemanager.h +++ b/include/openspace/util/timemanager.h @@ -40,7 +40,7 @@ namespace openspace { struct TimeKeyframeData { Time time; - double delta; + double delta = 0.0; bool pause = false; bool jump = false; }; diff --git a/modules/atmosphere/CMakeLists.txt b/modules/atmosphere/CMakeLists.txt index 475810d9fb..72cd611aa6 100644 --- a/modules/atmosphere/CMakeLists.txt +++ b/modules/atmosphere/CMakeLists.txt @@ -40,30 +40,17 @@ set(SHADER_FILES shaders/atmosphere_common.glsl shaders/atmosphere_deferred_vs.glsl shaders/atmosphere_deferred_fs.glsl - shaders/deltaE_calc_vs.glsl + shaders/calculation_gs.glsl + shaders/calculation_vs.glsl shaders/deltaE_calc_fs.glsl - shaders/deltaJ_calc_vs.glsl shaders/deltaJ_calc_fs.glsl - shaders/deltaJ_calc_gs.glsl - shaders/deltaS_calc_vs.glsl - shaders/deltaS_calc_gs.glsl shaders/deltaS_calc_fs.glsl - shaders/deltaS_sup_calc_vs.glsl - shaders/deltaS_sup_calc_gs.glsl shaders/deltaS_sup_calc_fs.glsl - shaders/inScattering_calc_vs.glsl - shaders/inScattering_calc_gs.glsl shaders/inScattering_calc_fs.glsl - shaders/inScattering_sup_calc_vs.glsl - shaders/inScattering_sup_calc_gs.glsl shaders/inScattering_sup_calc_fs.glsl - shaders/irradiance_calc_vs.glsl shaders/irradiance_calc_fs.glsl - shaders/irradiance_final_vs.glsl shaders/irradiance_final_fs.glsl - shaders/irradiance_sup_calc_vs.glsl shaders/irradiance_sup_calc_fs.glsl - shaders/transmittance_calc_vs.glsl shaders/transmittance_calc_fs.glsl ) source_group("Shader Files" FILES ${SHADER_FILES}) diff --git a/modules/atmosphere/rendering/atmospheredeferredcaster.cpp b/modules/atmosphere/rendering/atmospheredeferredcaster.cpp index 0a27be4596..b26103a2fd 100644 --- a/modules/atmosphere/rendering/atmospheredeferredcaster.cpp +++ b/modules/atmosphere/rendering/atmospheredeferredcaster.cpp @@ -32,118 +32,185 @@ * Copyright (c) 2008 INRIA * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include -#include +#include #include -#include -#include #include -#include #include -#include #include #include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef WIN32 -#define _USE_MATH_DEFINES -#endif // WIN32 #include - +#include namespace { constexpr const char* _loggerCat = "AtmosphereDeferredcaster"; - constexpr const std::array UniformNames1 = { - "cullAtmosphere", "Rg", "Rt", "groundRadianceEmittion", "HR", "betaRayleigh", + constexpr const std::array UniformNames = { + "cullAtmosphere", "Rg", "Rt", "groundRadianceEmission", "HR", "betaRayleigh", "HM", "betaMieExtinction", "mieG", "sunRadiance", "ozoneLayerEnabled", "HO", - "betaOzoneExtinction", "SAMPLES_R", "SAMPLES_MU", "SAMPLES_MU_S", "SAMPLES_NU" - }; - - constexpr const std::array UniformNames2 = { + "betaOzoneExtinction", "SAMPLES_R", "SAMPLES_MU", "SAMPLES_MU_S", "SAMPLES_NU", "dInverseModelTransformMatrix", "dModelTransformMatrix", "dSgctProjectionToModelTransformMatrix", "dSGCTViewToWorldMatrix", "dCamPosObj", "sunDirectionObj", "hardShadows", "transmittanceTexture", "irradianceTexture", "inscatterTexture" }; - constexpr const char* GlslDeferredcastPath = - "${MODULES}/atmosphere/shaders/atmosphere_deferred_fs.glsl"; - constexpr const char* GlslDeferredcastFSPath = - "${MODULES}/atmosphere/shaders/atmosphere_deferred_fs.glsl"; - constexpr const char* GlslDeferredcastVsPath = - "${MODULES}/atmosphere/shaders/atmosphere_deferred_vs.glsl"; - - constexpr const float ATM_EPS = 2.f; + constexpr const float ATM_EPS = 2000.f; constexpr const float KM_TO_M = 1000.f; - void createRenderQuad(GLuint* vao, GLuint* vbo, GLfloat size) { glGenVertexArrays(1, vao); glGenBuffers(1, vbo); glBindVertexArray(*vao); glBindBuffer(GL_ARRAY_BUFFER, *vbo); - const GLfloat vertex_data[] = { - // x y z w + const GLfloat VertexData[] = { + // x y z w -size, -size, 0.f, 1.f, - size, size, 0.f, 1.f, + size, size, 0.f, 1.f, -size, size, 0.f, 1.f, -size, -size, 0.f, 1.f, - size, -size, 0.f, 1.f, - size, size, 0.f, 1.f + size, -size, 0.f, 1.f, + size, size, 0.f, 1.f }; - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); - glVertexAttribPointer( - 0, - 4, - GL_FLOAT, - GL_FALSE, - sizeof(GLfloat) * 4, - nullptr - ); + glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData), VertexData, GL_STATIC_DRAW); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), nullptr); glEnableVertexAttribArray(0); + glBindVertexArray(0); + } + void saveTextureFile(GLenum colorBufferAttachment, + const std::filesystem::path& fileName, const glm::ivec2& size) + { + std::fstream ppmFile; + ppmFile.open(fileName, std::fstream::out); + if (!ppmFile.is_open()) { + return; + } + + std::vector px( + size.x * size.y * 3, + static_cast(255) + ); + + if (colorBufferAttachment != GL_DEPTH_ATTACHMENT) { + glReadBuffer(colorBufferAttachment); + glReadPixels(0, 0, size.x, size.y, GL_RGB, GL_UNSIGNED_BYTE, px.data()); + } + else { + glReadPixels( + 0, + 0, + size.x, + size.y, + GL_DEPTH_COMPONENT, + GL_UNSIGNED_BYTE, + px.data() + ); + } + + ppmFile << "P3" << '\n' << size.x << " " << size.y << '\n' << "255" << '\n'; + + int k = 0; + for (int i = 0; i < size.x; i++) { + for (int j = 0; j < size.y; j++) { + ppmFile << static_cast(px[k]) << ' ' + << static_cast(px[k + 1]) << ' ' + << static_cast(px[k + 2]) << ' '; + k += 3; + } + ppmFile << '\n'; + } + } + + bool isAtmosphereInFrustum(const glm::dmat4& MVMatrix, const glm::dvec3& position, + double radius) + { + // Frustum Planes + glm::dvec3 col1 = glm::dvec3(MVMatrix[0][0], MVMatrix[1][0], MVMatrix[2][0]); + glm::dvec3 col2 = glm::dvec3(MVMatrix[0][1], MVMatrix[1][1], MVMatrix[2][1]); + glm::dvec3 col3 = glm::dvec3(MVMatrix[0][2], MVMatrix[1][2], MVMatrix[2][2]); + glm::dvec3 col4 = glm::dvec3(MVMatrix[0][3], MVMatrix[1][3], MVMatrix[2][3]); + + glm::dvec3 leftNormal = col4 + col1; + glm::dvec3 rightNormal = col4 - col1; + glm::dvec3 bottomNormal = col4 + col2; + glm::dvec3 topNormal = col4 - col2; + glm::dvec3 nearNormal = col3 + col4; + glm::dvec3 farNormal = col4 - col3; + + // Plane Distances + double leftDistance = MVMatrix[3][3] + MVMatrix[3][0]; + double rightDistance = MVMatrix[3][3] - MVMatrix[3][0]; + double bottomDistance = MVMatrix[3][3] + MVMatrix[3][1]; + double topDistance = MVMatrix[3][3] - MVMatrix[3][1]; + double nearDistance = MVMatrix[3][3] + MVMatrix[3][2]; + + // Normalize Planes + const double invLeftMag = 1.0 / glm::length(leftNormal); + leftNormal *= invLeftMag; + leftDistance *= invLeftMag; + + const double invRightMag = 1.0 / glm::length(rightNormal); + rightNormal *= invRightMag; + rightDistance *= invRightMag; + + const double invBottomMag = 1.0 / glm::length(bottomNormal); + bottomNormal *= invBottomMag; + bottomDistance *= invBottomMag; + + const double invTopMag = 1.0 / glm::length(topNormal); + topNormal *= invTopMag; + topDistance *= invTopMag; + + const double invNearMag = 1.0 / glm::length(nearNormal); + nearNormal *= invNearMag; + nearDistance *= invNearMag; + + const double invFarMag = 1.0 / glm::length(farNormal); + farNormal *= invFarMag; + + if (((glm::dot(leftNormal, position) + leftDistance) < -radius) || + ((glm::dot(rightNormal, position) + rightDistance) < -radius) || + ((glm::dot(bottomNormal, position) + bottomDistance) < -radius) || + ((glm::dot(topNormal, position) + topDistance) < -radius) || + ((glm::dot(nearNormal, position) + nearDistance) < -radius)) + // The far plane testing is disabled because the atm has no depth. + { + return false; + } + return true; + } + + void renderQuadForCalc(GLuint vao, GLsizei numberOfVertices) { + glBindVertexArray(vao); + glDrawArrays(GL_TRIANGLES, 0, numberOfVertices); glBindVertexArray(0); } } // namespace @@ -181,7 +248,6 @@ void AtmosphereDeferredcaster::deinitialize() { glDeleteTextures(1, &_deltaSRayleighTableTexture); glDeleteTextures(1, &_deltaSMieTableTexture); glDeleteTextures(1, &_deltaJTableTexture); - glDeleteTextures(1, &_atmosphereTexture); } void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData, @@ -202,18 +268,19 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData, // Radius is in KM const double scaledRadius = glm::length( - glm::dmat3(_modelTransform) * glm::dvec3(1000.0 * _atmosphereRadius, 0.0, 0.0) + glm::dmat3(_modelTransform) * glm::dvec3(KM_TO_M * _atmosphereRadius, 0.0, 0.0) ); + // Number of planet radii to use as distance threshold for culling + const double DISTANCE_CULLING_RADII = 5000; if (distance > scaledRadius * DISTANCE_CULLING_RADII) { program.setUniform(_uniformCache.cullAtmosphere, 1); } else { - glm::dmat4 MV = glm::dmat4( - renderData.camera.sgctInternal.projectionMatrix() - ) * renderData.camera.combinedViewMatrix(); + glm::dmat4 MV = glm::dmat4(renderData.camera.sgctInternal.projectionMatrix()) * + renderData.camera.combinedViewMatrix(); - const float totalAtmosphere = (_atmosphereRadius + ATM_EPS)* KM_TO_M; + const double totalAtmosphere = (scaledRadius + ATM_EPS); if (!isAtmosphereInFrustum(MV, tPlanetPosWorld, totalAtmosphere)) { program.setUniform(_uniformCache.cullAtmosphere, 1); } @@ -222,8 +289,8 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData, program.setUniform(_uniformCache.Rg, _atmospherePlanetRadius); program.setUniform(_uniformCache.Rt, _atmosphereRadius); program.setUniform( - _uniformCache.groundRadianceEmittion, - _planetGroundRadianceEmittion + _uniformCache.groundRadianceEmission, + _planetGroundRadianceEmission ); program.setUniform(_uniformCache.HR, _rayleighHeightScale); program.setUniform(_uniformCache.betaRayleigh, _rayleighScatteringCoeff); @@ -242,10 +309,10 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData, // Object Space glm::dmat4 inverseModelMatrix = glm::inverse(_modelTransform); program.setUniform( - _uniformCache2.dInverseModelTransformMatrix, + _uniformCache.dInverseModelTransformMatrix, inverseModelMatrix ); - program.setUniform(_uniformCache2.dModelTransformMatrix, _modelTransform); + program.setUniform(_uniformCache.dModelTransformMatrix, _modelTransform); // Eye Space in SGCT to Eye Space in OS (SGCT View to OS Camera Rig) // glm::dmat4 dSgctEye2OSEye = glm::inverse( @@ -256,24 +323,27 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData, ); // Eye Space in SGCT to OS World Space - program.setUniform(_uniformCache2.dSGCTViewToWorldMatrix, - dSGCTViewToWorldMatrix); + program.setUniform( + _uniformCache.dSGCTViewToWorldMatrix, + dSGCTViewToWorldMatrix + ); // SGCT Projection to SGCT Eye Space glm::dmat4 dInverseProjection = glm::inverse( - glm::dmat4(renderData.camera.projectionMatrix())); + glm::dmat4(renderData.camera.projectionMatrix()) + ); glm::dmat4 inverseWholeMatrixPipeline = - inverseModelMatrix * - dSGCTViewToWorldMatrix * - dInverseProjection; + inverseModelMatrix * dSGCTViewToWorldMatrix * dInverseProjection; - program.setUniform(_uniformCache2.dSgctProjectionToModelTransformMatrix, - inverseWholeMatrixPipeline); + program.setUniform( + _uniformCache.dSgctProjectionToModelTransformMatrix, + inverseWholeMatrixPipeline + ); - glm::dvec4 camPosObjCoords = inverseModelMatrix * - glm::dvec4(renderData.camera.eyePositionVec3(), 1.0); - program.setUniform(_uniformCache2.dCamPosObj, camPosObjCoords); + glm::dvec4 camPosObjCoords = + inverseModelMatrix * glm::dvec4(renderData.camera.eyePositionVec3(), 1.0); + program.setUniform(_uniformCache.dCamPosObj, camPosObjCoords); double lt; glm::dvec3 sunPosWorld = SpiceManager::ref().targetPosition( @@ -300,7 +370,7 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData, // Sun Position in Object Space program.setUniform( - _uniformCache2.sunDirectionObj, + _uniformCache.sunDirectionObj, glm::normalize(glm::dvec3(sunPosObj)) ); @@ -333,18 +403,14 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData, ); casterPos *= KM_TO_M; // converting to meters - const std::string source = shadowConf.source.first; - SceneGraphNode* sourceNode = - global::renderEngine->scene()->sceneGraphNode(source); - const std::string caster = shadowConf.caster.first; - SceneGraphNode* casterNode = - global::renderEngine->scene()->sceneGraphNode(caster); + SceneGraphNode* sourceNode = sceneGraphNode(shadowConf.source.first); + SceneGraphNode* casterNode = sceneGraphNode(shadowConf.caster.first); if ((sourceNode == nullptr) || (casterNode == nullptr)) { LERRORC( "AtmosphereDeferredcaster", "Invalid scenegraph node for the shadow's caster or shadow's " - "receiver." + "receiver" ); return; } @@ -393,8 +459,8 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData, shadowData.rc = shadowConf.caster.second * casterRadiusScale; shadowData.sourceCasterVec = glm::normalize(sourceCasterVec); shadowData.xp = xp_test; - shadowData.xu = shadowData.rc * sc_length / - (shadowData.rs - shadowData.rc); + shadowData.xu = + shadowData.rc * sc_length / (shadowData.rs - shadowData.rc); shadowData.casterPositionVec = casterPos; } _shadowDataArrayCache.push_back(shadowData); @@ -404,10 +470,7 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData, unsigned int counter = 0; for (const ShadowRenderingStruct& sd : _shadowDataArrayCache) { // Add the counter - char* bf = fmt::format_to( - _uniformNameBuffer + 16, - "{}", counter - ); + char* bf = fmt::format_to(_uniformNameBuffer + 16, "{}", counter); std::strcpy(bf, "].isShadowing\0"); program.setUniform(_uniformNameBuffer, sd.isShadowing); @@ -426,28 +489,27 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData, } counter++; } - program.setUniform(_uniformCache2.hardShadows, _hardShadowsEnabled); + program.setUniform(_uniformCache.hardShadows, _hardShadowsEnabled); } } } _transmittanceTableTextureUnit.activate(); glBindTexture(GL_TEXTURE_2D, _transmittanceTableTexture); program.setUniform( - _uniformCache2.transmittanceTexture, + _uniformCache.transmittanceTexture, _transmittanceTableTextureUnit ); _irradianceTableTextureUnit.activate(); glBindTexture(GL_TEXTURE_2D, _irradianceTableTexture); - program.setUniform(_uniformCache2.irradianceTexture, _irradianceTableTextureUnit); + program.setUniform(_uniformCache.irradianceTexture, _irradianceTableTextureUnit); _inScatteringTableTextureUnit.activate(); glBindTexture(GL_TEXTURE_3D, _inScatteringTableTexture); - program.setUniform(_uniformCache2.inscatterTexture, _inScatteringTableTextureUnit); + program.setUniform(_uniformCache.inscatterTexture, _inScatteringTableTextureUnit); } -void AtmosphereDeferredcaster::postRaycast(const RenderData&, - const DeferredcastData&, +void AtmosphereDeferredcaster::postRaycast(const RenderData&, const DeferredcastData&, ghoul::opengl::ProgramObject&) { ZoneScoped @@ -458,33 +520,32 @@ void AtmosphereDeferredcaster::postRaycast(const RenderData&, _inScatteringTableTextureUnit.deactivate(); } -std::string AtmosphereDeferredcaster::deferredcastPath() const { - return GlslDeferredcastPath; +std::filesystem::path AtmosphereDeferredcaster::deferredcastPath() const { + return absPath("${MODULE_ATMOSPHERE}/shaders/atmosphere_deferred_fs.glsl"); } -std::string AtmosphereDeferredcaster::deferredcastFSPath() const { - return GlslDeferredcastFSPath; +std::filesystem::path AtmosphereDeferredcaster::deferredcastFSPath() const { + return absPath("${MODULE_ATMOSPHERE}/shaders/atmosphere_deferred_fs.glsl"); } -std::string AtmosphereDeferredcaster::deferredcastVSPath() const { - return GlslDeferredcastVsPath; +std::filesystem::path AtmosphereDeferredcaster::deferredcastVSPath() const { + return absPath("${MODULE_ATMOSPHERE}/shaders/atmosphere_deferred_vs.glsl"); } -std::string AtmosphereDeferredcaster::helperPath() const { +std::filesystem::path AtmosphereDeferredcaster::helperPath() const { return ""; // no helper file } void AtmosphereDeferredcaster::initializeCachedVariables( ghoul::opengl::ProgramObject& program) { - ghoul::opengl::updateUniformLocations(program, _uniformCache, UniformNames1); - ghoul::opengl::updateUniformLocations(program, _uniformCache2, UniformNames2); + ghoul::opengl::updateUniformLocations(program, _uniformCache, UniformNames); } void AtmosphereDeferredcaster::update(const UpdateData&) {} -void AtmosphereDeferredcaster::setModelTransform(const glm::dmat4& transform) { - _modelTransform = transform; +void AtmosphereDeferredcaster::setModelTransform(glm::dmat4 transform) { + _modelTransform = std::move(transform); } void AtmosphereDeferredcaster::setTime(double time) { @@ -505,10 +566,10 @@ void AtmosphereDeferredcaster::setPlanetAverageGroundReflectance( _planetAverageGroundReflectance = averageGReflectance; } -void AtmosphereDeferredcaster::setPlanetGroundRadianceEmittion( - float groundRadianceEmittion) +void AtmosphereDeferredcaster::setPlanetGroundRadianceEmission( + float groundRadianceEmission) { - _planetGroundRadianceEmittion = groundRadianceEmittion; + _planetGroundRadianceEmission = groundRadianceEmission; } void AtmosphereDeferredcaster::setRayleighHeightScale(float rayleighHeightScale) { @@ -576,17 +637,13 @@ void AtmosphereDeferredcaster::enableSunFollowing(bool enable) { void AtmosphereDeferredcaster::setPrecalculationTextureScale( float preCalculatedTexturesScale) { - _calculationTextureScale = preCalculatedTexturesScale; - _transmittance_table_width *= static_cast(_calculationTextureScale); - _transmittance_table_height *= static_cast(_calculationTextureScale); - _irradiance_table_width *= static_cast(_calculationTextureScale); - _irradiance_table_height *= static_cast(_calculationTextureScale); - _delta_e_table_width *= static_cast(_calculationTextureScale); - _delta_e_table_height *= static_cast(_calculationTextureScale); - _r_samples *= static_cast(_calculationTextureScale); - _mu_samples *= static_cast(_calculationTextureScale); - _mu_s_samples *= static_cast(_calculationTextureScale); - _nu_samples *= static_cast(_calculationTextureScale); + _transmittanceTableSize *= static_cast(preCalculatedTexturesScale); + _irradianceTableSize *= static_cast(preCalculatedTexturesScale); + _deltaETableSize *= static_cast(preCalculatedTexturesScale); + _r_samples *= static_cast(preCalculatedTexturesScale); + _mu_samples *= static_cast(preCalculatedTexturesScale); + _mu_s_samples *= static_cast(preCalculatedTexturesScale); + _nu_samples *= static_cast(preCalculatedTexturesScale); } void AtmosphereDeferredcaster::enablePrecalculationTexturesSaving() { @@ -594,118 +651,114 @@ void AtmosphereDeferredcaster::enablePrecalculationTexturesSaving() { } void AtmosphereDeferredcaster::loadComputationPrograms() { - //============== Transmittance T ================= + // + // Transmittance T if (!_transmittanceProgramObject) { _transmittanceProgramObject = ghoul::opengl::ProgramObject::Build( "transmittanceCalcProgram", - absPath("${MODULE_ATMOSPHERE}/shaders/transmittance_calc_vs.glsl"), + absPath("${MODULE_ATMOSPHERE}/shaders/calculation_vs.glsl"), absPath("${MODULE_ATMOSPHERE}/shaders/transmittance_calc_fs.glsl") ); } using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError; - _transmittanceProgramObject->setIgnoreSubroutineUniformLocationError( - IgnoreError::Yes - ); _transmittanceProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); - //============== Irradiance E ================= + // + // Irradiance E if (!_irradianceProgramObject) { _irradianceProgramObject = ghoul::opengl::ProgramObject::Build( "irradianceCalcProgram", - absPath("${MODULE_ATMOSPHERE}/shaders/irradiance_calc_vs.glsl"), - absPath("${MODULE_ATMOSPHERE}/shaders/irradiance_calc_fs.glsl")); + absPath("${MODULE_ATMOSPHERE}/shaders/calculation_vs.glsl"), + absPath("${MODULE_ATMOSPHERE}/shaders/irradiance_calc_fs.glsl") + ); } - _irradianceProgramObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); _irradianceProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); if (!_irradianceSupTermsProgramObject) { _irradianceSupTermsProgramObject = ghoul::opengl::ProgramObject::Build( "irradianceSupTermsCalcProgram", - absPath("${MODULE_ATMOSPHERE}/shaders/irradiance_sup_calc_vs.glsl"), - absPath("${MODULE_ATMOSPHERE}/shaders/irradiance_sup_calc_fs.glsl")); + absPath("${MODULE_ATMOSPHERE}/shaders/calculation_vs.glsl"), + absPath("${MODULE_ATMOSPHERE}/shaders/irradiance_sup_calc_fs.glsl") + ); } - _irradianceSupTermsProgramObject->setIgnoreSubroutineUniformLocationError( - IgnoreError::Yes - ); _irradianceSupTermsProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); - - //============== InScattering S ================= + + // + // InScattering S if (!_inScatteringProgramObject) { _inScatteringProgramObject = ghoul::opengl::ProgramObject::Build( "inScatteringCalcProgram", - absPath("${MODULE_ATMOSPHERE}/shaders/inScattering_calc_vs.glsl"), + absPath("${MODULE_ATMOSPHERE}/shaders/calculation_vs.glsl"), absPath("${MODULE_ATMOSPHERE}/shaders/inScattering_calc_fs.glsl"), - absPath("${MODULE_ATMOSPHERE}/shaders/inScattering_calc_gs.glsl")); + absPath("${MODULE_ATMOSPHERE}/shaders/calculation_gs.glsl") + ); } - _inScatteringProgramObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); _inScatteringProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); if (!_inScatteringSupTermsProgramObject) { _inScatteringSupTermsProgramObject = ghoul::opengl::ProgramObject::Build( "inScatteringSupTermsCalcProgram", - absPath("${MODULE_ATMOSPHERE}/shaders/inScattering_sup_calc_vs.glsl"), + absPath("${MODULE_ATMOSPHERE}/shaders/calculation_vs.glsl"), absPath("${MODULE_ATMOSPHERE}/shaders/inScattering_sup_calc_fs.glsl"), - absPath("${MODULE_ATMOSPHERE}/shaders/inScattering_sup_calc_gs.glsl")); + absPath("${MODULE_ATMOSPHERE}/shaders/calculation_gs.glsl") + ); } - _inScatteringSupTermsProgramObject->setIgnoreSubroutineUniformLocationError( - IgnoreError::Yes - ); _inScatteringSupTermsProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); - //============== Delta E ================= + // + // Delta E if (!_deltaEProgramObject) { _deltaEProgramObject = ghoul::opengl::ProgramObject::Build( "deltaECalcProgram", - absPath("${MODULE_ATMOSPHERE}/shaders/deltaE_calc_vs.glsl"), - absPath("${MODULE_ATMOSPHERE}/shaders/deltaE_calc_fs.glsl")); + absPath("${MODULE_ATMOSPHERE}/shaders/calculation_vs.glsl"), + absPath("${MODULE_ATMOSPHERE}/shaders/deltaE_calc_fs.glsl") + ); } - _deltaEProgramObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); _deltaEProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); - //============== Irradiance finel E ================= + // + // Irradiance finel E if (!_irradianceFinalProgramObject) { _irradianceFinalProgramObject = ghoul::opengl::ProgramObject::Build( "irradianceEFinalProgram", - absPath("${MODULE_ATMOSPHERE}/shaders/irradiance_final_vs.glsl"), - absPath("${MODULE_ATMOSPHERE}/shaders/irradiance_final_fs.glsl")); + absPath("${MODULE_ATMOSPHERE}/shaders/calculation_vs.glsl"), + absPath("${MODULE_ATMOSPHERE}/shaders/irradiance_final_fs.glsl") + ); } - _irradianceFinalProgramObject->setIgnoreSubroutineUniformLocationError( - IgnoreError::Yes - ); _irradianceFinalProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); - //============== Delta S ================= + // + // Delta S if (!_deltaSProgramObject) { _deltaSProgramObject = ghoul::opengl::ProgramObject::Build( "deltaSCalcProgram", - absPath("${MODULE_ATMOSPHERE}/shaders/deltaS_calc_vs.glsl"), + absPath("${MODULE_ATMOSPHERE}/shaders/calculation_vs.glsl"), absPath("${MODULE_ATMOSPHERE}/shaders/deltaS_calc_fs.glsl"), - absPath("${MODULE_ATMOSPHERE}/shaders/deltaS_calc_gs.glsl")); + absPath("${MODULE_ATMOSPHERE}/shaders/calculation_gs.glsl") + ); } - _deltaSProgramObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); _deltaSProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); if (!_deltaSSupTermsProgramObject) { _deltaSSupTermsProgramObject = ghoul::opengl::ProgramObject::Build( "deltaSSUPTermsCalcProgram", - absPath("${MODULE_ATMOSPHERE}/shaders/deltaS_sup_calc_vs.glsl"), + absPath("${MODULE_ATMOSPHERE}/shaders/calculation_vs.glsl"), absPath("${MODULE_ATMOSPHERE}/shaders/deltaS_sup_calc_fs.glsl"), - absPath("${MODULE_ATMOSPHERE}/shaders/deltaS_sup_calc_gs.glsl")); + absPath("${MODULE_ATMOSPHERE}/shaders/calculation_gs.glsl") + ); } - _deltaSSupTermsProgramObject->setIgnoreSubroutineUniformLocationError( - IgnoreError::Yes - ); _deltaSSupTermsProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); - //============== Delta J (Radiance Scattered) ================= + // + // Delta J (Radiance Scattered) if (!_deltaJProgramObject) { _deltaJProgramObject = ghoul::opengl::ProgramObject::Build( "deltaJCalcProgram", - absPath("${MODULE_ATMOSPHERE}/shaders/deltaJ_calc_vs.glsl"), + absPath("${MODULE_ATMOSPHERE}/shaders/calculation_vs.glsl"), absPath("${MODULE_ATMOSPHERE}/shaders/deltaJ_calc_fs.glsl"), - absPath("${MODULE_ATMOSPHERE}/shaders/deltaJ_calc_gs.glsl")); + absPath("${MODULE_ATMOSPHERE}/shaders/calculation_gs.glsl") + ); } - _deltaJProgramObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); _deltaJProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); } @@ -724,7 +777,8 @@ void AtmosphereDeferredcaster::unloadComputationPrograms() { void AtmosphereDeferredcaster::createComputationTextures() { if (!_atmosphereCalculated) { - //============== Transmittance ================= + // + // Transmittance ghoul::opengl::TextureUnit transmittanceTableTextureUnit; transmittanceTableTextureUnit.activate(); glGenTextures(1, &_transmittanceTableTexture); @@ -735,10 +789,20 @@ void AtmosphereDeferredcaster::createComputationTextures() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Stopped using a buffer object for GL_PIXEL_UNPACK_BUFFER glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, _transmittance_table_width, - _transmittance_table_height, 0, GL_RGB, GL_FLOAT, nullptr); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RGB32F, + _transmittanceTableSize.x, + _transmittanceTableSize.y, + 0, + GL_RGB, + GL_FLOAT, + nullptr + ); - //============== Irradiance ================= + // + // Irradiance ghoul::opengl::TextureUnit irradianceTableTextureUnit; irradianceTableTextureUnit.activate(); glGenTextures(1, &_irradianceTableTexture); @@ -748,10 +812,20 @@ void AtmosphereDeferredcaster::createComputationTextures() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, _irradiance_table_width, - _irradiance_table_height, 0, GL_RGB, GL_FLOAT, nullptr); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RGB32F, + _irradianceTableSize.x, + _irradianceTableSize.y, + 0, + GL_RGB, + GL_FLOAT, + nullptr + ); - //============== InScattering ================= + // + // InScattering ghoul::opengl::TextureUnit inScatteringTableTextureUnit; inScatteringTableTextureUnit.activate(); glGenTextures(1, &_inScatteringTableTexture); @@ -762,11 +836,22 @@ void AtmosphereDeferredcaster::createComputationTextures() { glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA32F, _mu_s_samples * _nu_samples, - _mu_samples, _r_samples, 0, GL_RGB, GL_FLOAT, nullptr); + glTexImage3D( + GL_TEXTURE_3D, + 0, + GL_RGBA32F, + _mu_s_samples * _nu_samples, + _mu_samples, + _r_samples, + 0, + GL_RGB, + GL_FLOAT, + nullptr + ); } - //============== Delta E ================= + // + // Delta E ghoul::opengl::TextureUnit deltaETableTextureUnit; deltaETableTextureUnit.activate(); glGenTextures(1, &_deltaETableTexture); @@ -776,10 +861,20 @@ void AtmosphereDeferredcaster::createComputationTextures() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, _delta_e_table_width, - _delta_e_table_height, 0, GL_RGB, GL_FLOAT, nullptr); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RGB32F, + _deltaETableSize.x, + _deltaETableSize.y, + 0, + GL_RGB, + GL_FLOAT, + nullptr + ); - //============== Delta S ================= + // + // Delta S ghoul::opengl::TextureUnit deltaSRayleighTableTextureUnit; deltaSRayleighTableTextureUnit.activate(); glGenTextures(1, &_deltaSRayleighTableTexture); @@ -790,8 +885,17 @@ void AtmosphereDeferredcaster::createComputationTextures() { glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB32F, _mu_s_samples * _nu_samples, - _mu_samples, _r_samples, 0, GL_RGB, GL_FLOAT, nullptr); + glTexImage3D( + GL_TEXTURE_3D, + 0, + GL_RGB32F, + _mu_s_samples * _nu_samples, + _mu_samples, + _r_samples, + 0, GL_RGB, + GL_FLOAT, + nullptr + ); ghoul::opengl::TextureUnit deltaSMieTableTextureUnit; deltaSMieTableTextureUnit.activate(); @@ -803,10 +907,21 @@ void AtmosphereDeferredcaster::createComputationTextures() { glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB32F, _mu_s_samples * _nu_samples, - _mu_samples, _r_samples, 0, GL_RGB, GL_FLOAT, nullptr); + glTexImage3D( + GL_TEXTURE_3D, + 0, + GL_RGB32F, + _mu_s_samples * _nu_samples, + _mu_samples, + _r_samples, + 0, + GL_RGB, + GL_FLOAT, + nullptr + ); - //============== Delta J (Radiance Scattered) ================= + // + // Delta J (Radiance Scattered) ghoul::opengl::TextureUnit deltaJTableTextureUnit; deltaJTableTextureUnit.activate(); glGenTextures(1, &_deltaJTableTexture); @@ -817,27 +932,46 @@ void AtmosphereDeferredcaster::createComputationTextures() { glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB32F, _mu_s_samples * _nu_samples, - _mu_samples, _r_samples, 0, GL_RGB, GL_FLOAT, nullptr); - + glTexImage3D( + GL_TEXTURE_3D, + 0, + GL_RGB32F, + _mu_s_samples * _nu_samples, + _mu_samples, + _r_samples, + 0, + GL_RGB, + GL_FLOAT, + nullptr + ); } void AtmosphereDeferredcaster::deleteComputationTextures() { - // Cleaning up glDeleteTextures(1, &_transmittanceTableTexture); + _transmittanceTableTexture = 0; glDeleteTextures(1, &_irradianceTableTexture); + _irradianceTableTexture = 0; glDeleteTextures(1, &_inScatteringTableTexture); + _inScatteringTableTexture = 0; glDeleteTextures(1, &_deltaETableTexture); + _deltaETableTexture = 0; glDeleteTextures(1, &_deltaSRayleighTableTexture); + _deltaSRayleighTableTexture = 0; glDeleteTextures(1, &_deltaSMieTableTexture); + _deltaSMieTableTexture = 0; glDeleteTextures(1, &_deltaJTableTexture); + _deltaJTableTexture = 0; } void AtmosphereDeferredcaster::deleteUnusedComputationTextures() { glDeleteTextures(1, &_deltaETableTexture); + _deltaETableTexture = 0; glDeleteTextures(1, &_deltaSRayleighTableTexture); + _deltaSRayleighTableTexture = 0; glDeleteTextures(1, &_deltaSMieTableTexture); + _deltaSMieTableTexture = 0; glDeleteTextures(1, &_deltaJTableTexture); + _deltaJTableTexture = 0; } void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, @@ -854,37 +988,32 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, glDisable(GL_BLEND); - // =========================================================== // See Precomputed Atmosphere Scattering from Bruneton et al. paper, algorithm 4.1: - // =========================================================== glFramebufferTexture( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _transmittanceTableTexture, 0 ); - checkFrameBufferState("_transmittanceTableTexture"); - glViewport(0, 0, _transmittance_table_width, _transmittance_table_height); + glViewport(0, 0, _transmittanceTableSize.x, _transmittanceTableSize.y); _transmittanceProgramObject->activate(); - loadAtmosphereDataIntoShaderProgram(_transmittanceProgramObject); - //glClear(GL_COLOR_BUFFER_BIT); - static const float black[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - glClearBufferfv(GL_COLOR, 0, black); + loadAtmosphereDataIntoShaderProgram(*_transmittanceProgramObject); + + static const float Black[] = { 0.f, 0.f, 0.f, 0.f }; + glClearBufferfv(GL_COLOR, 0, Black); renderQuadForCalc(quadCalcVAO, vertexSize); if (_saveCalculationTextures) { - saveTextureToPPMFile( + saveTextureFile( GL_COLOR_ATTACHMENT0, - std::string("transmittance_texture.ppm"), - _transmittance_table_width, - _transmittance_table_height + "transmittance_texture.ppm", + _transmittanceTableSize ); } _transmittanceProgramObject->deactivate(); // line 2 in algorithm 4.1 glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _deltaETableTexture, 0); - checkFrameBufferState("_deltaETableTexture"); - glViewport(0, 0, _delta_e_table_width, _delta_e_table_height); + glViewport(0, 0, _deltaETableSize.x, _deltaETableSize.y); _irradianceProgramObject->activate(); transmittanceTableTextureUnit.activate(); glBindTexture(GL_TEXTURE_2D, _transmittanceTableTexture); @@ -892,15 +1021,14 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, "transmittanceTexture", transmittanceTableTextureUnit ); - loadAtmosphereDataIntoShaderProgram(_irradianceProgramObject); + loadAtmosphereDataIntoShaderProgram(*_irradianceProgramObject); glClear(GL_COLOR_BUFFER_BIT); renderQuadForCalc(quadCalcVAO, vertexSize); if (_saveCalculationTextures) { - saveTextureToPPMFile( + saveTextureFile( GL_COLOR_ATTACHMENT0, - std::string("deltaE_table_texture.ppm"), - _delta_e_table_width, - _delta_e_table_height + "deltaE_table_texture.ppm", + _deltaETableSize ); } _irradianceProgramObject->deactivate(); @@ -920,7 +1048,6 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, ); GLenum colorBuffers[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; glDrawBuffers(2, colorBuffers); - checkFrameBufferState("_deltaSRay and _deltaSMie TableTexture"); glViewport(0, 0, _mu_s_samples * _nu_samples, _mu_samples); _inScatteringProgramObject->activate(); transmittanceTableTextureUnit.activate(); @@ -929,24 +1056,22 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, "transmittanceTexture", transmittanceTableTextureUnit ); - loadAtmosphereDataIntoShaderProgram(_inScatteringProgramObject); + loadAtmosphereDataIntoShaderProgram(*_inScatteringProgramObject); glClear(GL_COLOR_BUFFER_BIT); for (int layer = 0; layer < _r_samples; ++layer) { - step3DTexture(_inScatteringProgramObject, layer); + step3DTexture(*_inScatteringProgramObject, layer, true); renderQuadForCalc(quadCalcVAO, vertexSize); } if (_saveCalculationTextures) { - saveTextureToPPMFile( + saveTextureFile( GL_COLOR_ATTACHMENT0, - std::string("deltaS_rayleigh_texture.ppm"), - _mu_s_samples * _nu_samples, - _mu_samples + "deltaS_rayleigh_texture.ppm", + glm::ivec2(_mu_s_samples * _nu_samples, _mu_samples) ); - saveTextureToPPMFile( + saveTextureFile( GL_COLOR_ATTACHMENT1, - std::string("deltaS_mie_texture.ppm"), - _mu_s_samples * _nu_samples, - _mu_samples + "deltaS_mie_texture.ppm", + glm::ivec2(_mu_s_samples * _nu_samples, _mu_samples) ); } glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, 0, 0); @@ -961,21 +1086,22 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, _irradianceTableTexture, 0 ); - checkFrameBufferState("_irradianceTableTexture"); glDrawBuffer(GL_COLOR_ATTACHMENT0); - glViewport(0, 0, _delta_e_table_width, _delta_e_table_height); + glViewport(0, 0, _deltaETableSize.x, _deltaETableSize.y); _deltaEProgramObject->activate(); - //_deltaEProgramObject->setUniform("line", 4); deltaETableTextureUnit.activate(); glBindTexture(GL_TEXTURE_2D, _deltaETableTexture); _deltaEProgramObject->setUniform("deltaETexture", deltaETableTextureUnit); - loadAtmosphereDataIntoShaderProgram(_deltaEProgramObject); + loadAtmosphereDataIntoShaderProgram(*_deltaEProgramObject); glClear(GL_COLOR_BUFFER_BIT); renderQuadForCalc(quadCalcVAO, vertexSize); if (_saveCalculationTextures) { - saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, std::string("irradiance_texture.ppm"), - _delta_e_table_width, _delta_e_table_height); + saveTextureFile( + GL_COLOR_ATTACHMENT0, + "irradiance_texture.ppm", + _deltaETableSize + ); } _deltaEProgramObject->deactivate(); @@ -986,7 +1112,6 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, _inScatteringTableTexture, 0 ); - checkFrameBufferState("_inScatteringTableTexture"); glViewport(0, 0, _mu_s_samples * _nu_samples, _mu_samples); _deltaSProgramObject->activate(); deltaSRayleighTableTextureUnit.activate(); @@ -995,15 +1120,18 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, glBindTexture(GL_TEXTURE_3D, _deltaSMieTableTexture); _deltaSProgramObject->setUniform("deltaSRTexture", deltaSRayleighTableTextureUnit); _deltaSProgramObject->setUniform("deltaSMTexture", deltaSMieTableTextureUnit); - loadAtmosphereDataIntoShaderProgram(_deltaSProgramObject); + loadAtmosphereDataIntoShaderProgram(*_deltaSProgramObject); glClear(GL_COLOR_BUFFER_BIT); for (int layer = 0; layer < _r_samples; ++layer) { - step3DTexture(_deltaSProgramObject, layer, false); + step3DTexture(*_deltaSProgramObject, layer, false); renderQuadForCalc(quadCalcVAO, vertexSize); } if (_saveCalculationTextures) { - saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, std::string("S_texture.ppm"), - _mu_s_samples * _nu_samples, _mu_samples); + saveTextureFile( + GL_COLOR_ATTACHMENT0, + "S_texture.ppm", + glm::ivec2(_mu_s_samples * _nu_samples, _mu_samples) + ); } _deltaSProgramObject->deactivate(); @@ -1016,7 +1144,6 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, _deltaJTableTexture, 0 ); - checkFrameBufferState("_deltaJTableTexture"); glViewport(0, 0, _mu_s_samples * _nu_samples, _mu_samples); _deltaJProgramObject->activate(); if (scatteringOrder == 2) { @@ -1043,15 +1170,17 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, deltaSMieTableTextureUnit.activate(); glBindTexture(GL_TEXTURE_3D, _deltaSMieTableTexture); _deltaJProgramObject->setUniform("deltaSMTexture", deltaSMieTableTextureUnit); - loadAtmosphereDataIntoShaderProgram(_deltaJProgramObject); + loadAtmosphereDataIntoShaderProgram(*_deltaJProgramObject); for (int layer = 0; layer < _r_samples; ++layer) { - step3DTexture(_deltaJProgramObject, layer); + step3DTexture(*_deltaJProgramObject, layer, true); renderQuadForCalc(quadCalcVAO, vertexSize); } if (_saveCalculationTextures) { - saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, + saveTextureFile( + GL_COLOR_ATTACHMENT0, fmt::format("deltaJ_texture-scattering_order-{}.ppm", scatteringOrder), - _mu_s_samples * _nu_samples, _mu_samples); + glm::ivec2(_mu_s_samples * _nu_samples, _mu_samples) + ); } _deltaJProgramObject->deactivate(); @@ -1062,8 +1191,7 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, _deltaETableTexture, 0 ); - checkFrameBufferState("_deltaETableTexture"); - glViewport(0, 0, _delta_e_table_width, _delta_e_table_height); + glViewport(0, 0, _deltaETableSize.x, _deltaETableSize.y); _irradianceSupTermsProgramObject->activate(); if (scatteringOrder == 2) { _irradianceSupTermsProgramObject->setUniform("firstIteraction", 1); @@ -1089,12 +1217,14 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, "deltaSMTexture", deltaSMieTableTextureUnit ); - loadAtmosphereDataIntoShaderProgram(_irradianceSupTermsProgramObject); + loadAtmosphereDataIntoShaderProgram(*_irradianceSupTermsProgramObject); renderQuadForCalc(quadCalcVAO, vertexSize); if (_saveCalculationTextures) { - saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, + saveTextureFile( + GL_COLOR_ATTACHMENT0, fmt::format("deltaE_texture-scattering_order-{}.ppm", scatteringOrder), - _delta_e_table_width, _delta_e_table_height); + _deltaETableSize + ); } _irradianceSupTermsProgramObject->deactivate(); @@ -1105,7 +1235,6 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, _deltaSRayleighTableTexture, 0 ); - checkFrameBufferState("_deltaSRayleighTableTexture"); glViewport(0, 0, _mu_s_samples * _nu_samples, _mu_samples); _inScatteringSupTermsProgramObject->activate(); transmittanceTableTextureUnit.activate(); @@ -1120,17 +1249,16 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, "deltaJTexture", deltaJTableTextureUnit ); - loadAtmosphereDataIntoShaderProgram(_inScatteringSupTermsProgramObject); + loadAtmosphereDataIntoShaderProgram(*_inScatteringSupTermsProgramObject); for (int layer = 0; layer < _r_samples; ++layer) { - step3DTexture(_inScatteringSupTermsProgramObject, layer); + step3DTexture(*_inScatteringSupTermsProgramObject, layer, true); renderQuadForCalc(quadCalcVAO, vertexSize); } if (_saveCalculationTextures) { - saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, - fmt::format("deltaS_texture-scattering_order-{}.ppm", - scatteringOrder), - _mu_s_samples * _nu_samples, - _mu_samples + saveTextureFile( + GL_COLOR_ATTACHMENT0, + fmt::format("deltaS_texture-scattering_order-{}.ppm", scatteringOrder), + glm::ivec2(_mu_s_samples * _nu_samples, _mu_samples) ); } _inScatteringSupTermsProgramObject->deactivate(); @@ -1146,8 +1274,7 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, _irradianceTableTexture, 0 ); - checkFrameBufferState("_irradianceTableTexture"); - glViewport(0, 0, _delta_e_table_width, _delta_e_table_height); + glViewport(0, 0, _deltaETableSize.x, _deltaETableSize.y); _irradianceFinalProgramObject->activate(); deltaETableTextureUnit.activate(); glBindTexture(GL_TEXTURE_2D, _deltaETableTexture); @@ -1155,13 +1282,14 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, "deltaETexture", deltaETableTextureUnit ); - loadAtmosphereDataIntoShaderProgram(_irradianceFinalProgramObject); + loadAtmosphereDataIntoShaderProgram(*_irradianceFinalProgramObject); renderQuadForCalc(quadCalcVAO, vertexSize); if (_saveCalculationTextures) { - saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, - fmt::format("irradianceTable_order-{}.ppm", - scatteringOrder), - _delta_e_table_width, _delta_e_table_height); + saveTextureFile( + GL_COLOR_ATTACHMENT0, + fmt::format("irradianceTable_order-{}.ppm", scatteringOrder), + _deltaETableSize + ); } _irradianceFinalProgramObject->deactivate(); @@ -1172,7 +1300,6 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, _inScatteringTableTexture, 0 ); - checkFrameBufferState("_inScatteringTableTexture"); glViewport(0, 0, _mu_s_samples * _nu_samples, _mu_samples); _deltaSSupTermsProgramObject->activate(); deltaSRayleighTableTextureUnit.activate(); @@ -1181,16 +1308,16 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, "deltaSTexture", deltaSRayleighTableTextureUnit ); - loadAtmosphereDataIntoShaderProgram(_deltaSSupTermsProgramObject); + loadAtmosphereDataIntoShaderProgram(*_deltaSSupTermsProgramObject); for (int layer = 0; layer < _r_samples; ++layer) { - step3DTexture(_deltaSSupTermsProgramObject, layer, false); + step3DTexture(*_deltaSSupTermsProgramObject, layer, false); renderQuadForCalc(quadCalcVAO, vertexSize); } if (_saveCalculationTextures) { - saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, - fmt::format("inscatteringTable_order-{}.ppm", - scatteringOrder), - _mu_s_samples * _nu_samples, _mu_samples); + saveTextureFile(GL_COLOR_ATTACHMENT0, + fmt::format("inscatteringTable_order-{}.ppm", scatteringOrder), + glm::ivec2(_mu_s_samples * _nu_samples, _mu_samples) + ); } _deltaSSupTermsProgramObject->deactivate(); @@ -1202,22 +1329,18 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO, } void AtmosphereDeferredcaster::preCalculateAtmosphereParam() { - //========================================================== - //========= Load Shader Programs for Calculations ========== - //========================================================== + // Load Shader Programs for Calculations loadComputationPrograms(); - //========================================================== - //============ Create Textures for Calculations ============ - //========================================================== + // Create Textures for Calculations createComputationTextures(); // Saves current FBO first GLint defaultFBO; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); - GLint m_viewport[4]; - global::renderEngine->openglStateCache().viewport(m_viewport); + GLint viewport[4]; + global::renderEngine->openglStateCache().viewport(viewport); // Creates the FBO for the calculations GLuint calcFBO; @@ -1232,288 +1355,81 @@ void AtmosphereDeferredcaster::preCalculateAtmosphereParam() { createRenderQuad(&quadCalcVAO, &quadCalcVBO, 1.0f); // Starting Calculations... - LDEBUG("Starting precalculations for scattering effects..."); + LDEBUG("Starting precalculations for scattering effects"); - //========================================================== - //=================== Execute Calculations ================= - //========================================================== + // Execute Calculations executeCalculations(quadCalcVAO, drawBuffers, 6); deleteUnusedComputationTextures(); // Restores system state glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); - global::renderEngine->openglStateCache().setViewportState(m_viewport); + global::renderEngine->openglStateCache().setViewportState(viewport); glDeleteBuffers(1, &quadCalcVBO); glDeleteVertexArrays(1, &quadCalcVAO); glDeleteFramebuffers(1, &calcFBO); - LDEBUG("Ended precalculations for Atmosphere effects..."); + LDEBUG("Ended precalculations for Atmosphere effects"); } void AtmosphereDeferredcaster::loadAtmosphereDataIntoShaderProgram( - std::unique_ptr& shaderProg) + ghoul::opengl::ProgramObject& shaderProg) { - shaderProg->setUniform("Rg", _atmospherePlanetRadius); - shaderProg->setUniform("Rt", _atmosphereRadius); - shaderProg->setUniform("AverageGroundReflectance", _planetAverageGroundReflectance); - shaderProg->setUniform("groundRadianceEmittion", _planetGroundRadianceEmittion); - shaderProg->setUniform("HR", _rayleighHeightScale); - shaderProg->setUniform("betaRayleigh", _rayleighScatteringCoeff); - shaderProg->setUniform("HM", _mieHeightScale); - shaderProg->setUniform("betaMieScattering", _mieScatteringCoeff); - shaderProg->setUniform("betaMieExtinction", _mieExtinctionCoeff); - shaderProg->setUniform("mieG", _miePhaseConstant); - shaderProg->setUniform("sunRadiance", _sunRadianceIntensity); - shaderProg->setUniform("TRANSMITTANCE_W", _transmittance_table_width); - shaderProg->setUniform("TRANSMITTANCE_H", _transmittance_table_height); - shaderProg->setUniform("SKY_W", _irradiance_table_width); - shaderProg->setUniform("SKY_H", _irradiance_table_height); - shaderProg->setUniform("OTHER_TEXTURES_W", _delta_e_table_width); - shaderProg->setUniform("OTHER_TEXTURES_H", _delta_e_table_height); - shaderProg->setUniform("SAMPLES_R", _r_samples); - shaderProg->setUniform("SAMPLES_MU", _mu_samples); - shaderProg->setUniform("SAMPLES_MU_S", _mu_s_samples); - shaderProg->setUniform("SAMPLES_NU", _nu_samples); - shaderProg->setUniform("ozoneLayerEnabled", _ozoneEnabled); - shaderProg->setUniform("HO", _ozoneHeightScale); - shaderProg->setUniform("betaOzoneExtinction", _ozoneExtinctionCoeff); + shaderProg.setUniform("Rg", _atmospherePlanetRadius); + shaderProg.setUniform("Rt", _atmosphereRadius); + shaderProg.setUniform("AverageGroundReflectance", _planetAverageGroundReflectance); + shaderProg.setUniform("groundRadianceEmission", _planetGroundRadianceEmission); + shaderProg.setUniform("HR", _rayleighHeightScale); + shaderProg.setUniform("betaRayleigh", _rayleighScatteringCoeff); + shaderProg.setUniform("HM", _mieHeightScale); + shaderProg.setUniform("betaMieScattering", _mieScatteringCoeff); + shaderProg.setUniform("betaMieExtinction", _mieExtinctionCoeff); + shaderProg.setUniform("mieG", _miePhaseConstant); + shaderProg.setUniform("sunRadiance", _sunRadianceIntensity); + shaderProg.setUniform("TRANSMITTANCE", _transmittanceTableSize); + shaderProg.setUniform("SKY", _irradianceTableSize); + shaderProg.setUniform("OTHER_TEXTURES", _deltaETableSize); + shaderProg.setUniform("SAMPLES_R", _r_samples); + shaderProg.setUniform("SAMPLES_MU", _mu_samples); + shaderProg.setUniform("SAMPLES_MU_S", _mu_s_samples); + shaderProg.setUniform("SAMPLES_NU", _nu_samples); + shaderProg.setUniform("ozoneLayerEnabled", _ozoneEnabled); + shaderProg.setUniform("HO", _ozoneHeightScale); + shaderProg.setUniform("betaOzoneExtinction", _ozoneExtinctionCoeff); } -void AtmosphereDeferredcaster::checkFrameBufferState( - const std::string& codePosition) const -{ - if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - LERROR("Framework not built. " + codePosition); - GLenum fbErr = glCheckFramebufferStatus(GL_FRAMEBUFFER); - switch (fbErr) { - case GL_FRAMEBUFFER_UNDEFINED: - LERROR("Indefined framebuffer."); - break; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - LERROR("Incomplete, missing attachement."); - break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - LERROR("Framebuffer doesn't have at least one image attached to it."); - break; - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: - LERROR( - "Returned if the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is " - "GL_NONE for any color attachment point(s) named by GL_DRAW_BUFFERi." - ); - break; - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: - LERROR( - "Returned if GL_READ_BUFFER is not GL_NONE and the value of " - "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE for the color " - "attachment point named by GL_READ_BUFFER."); - break; - case GL_FRAMEBUFFER_UNSUPPORTED: - LERROR( - "Returned if the combination of internal formats of the attached " - "images violates an implementation - dependent set of restrictions." - ); - break; - case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: - LERROR( - "Returned if the value of GL_RENDERBUFFE_r_samples is not the same " - "for all attached renderbuffers; if the value of GL_TEXTURE_SAMPLES " - "is the not same for all attached textures; or , if the attached " - "images are a mix of renderbuffers and textures, the value of " - "GL_RENDERBUFFE_r_samples does not match the value of " - "GL_TEXTURE_SAMPLES." - ); - LERROR( - "Returned if the value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not " - "the same for all attached textures; or , if the attached images are " - "a mix of renderbuffers and textures, the value of " - "GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not GL_TRUE for all attached " - "textures." - ); - break; - case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: - LERROR( - "Returned if any framebuffer attachment is layered, and any " - "populated attachment is not layered, or if all populated color " - "attachments are not from textures of the same target." - ); - break; - default: - LDEBUG("No error found checking framebuffer: " + codePosition); - break; - } - } -} - -void AtmosphereDeferredcaster::renderQuadForCalc(GLuint vao, GLsizei numberOfVertices) { - glBindVertexArray(vao); - glDrawArrays(GL_TRIANGLES, 0, numberOfVertices); - glBindVertexArray(0); -} - -void AtmosphereDeferredcaster::step3DTexture( - std::unique_ptr& shaderProg, - int layer, - bool doCalculation) +void AtmosphereDeferredcaster::step3DTexture(ghoul::opengl::ProgramObject& shaderProg, + int layer, bool doCalculation) { // See OpenGL redbook 8th Edition page 556 for Layered Rendering if (doCalculation) { - float earth2 = _atmospherePlanetRadius * _atmospherePlanetRadius; - float atm2 = _atmosphereRadius * _atmosphereRadius; - float diff = atm2 - earth2; - float ri = static_cast(layer) / static_cast(_r_samples - 1); - float ri_2 = ri * ri; - float epsilon = - (layer == 0) ? - 0.01f : - (layer == (_r_samples - 1)) ? -0.001f : 0.0f; - float r = sqrtf(earth2 + ri_2 * diff) + epsilon; - float dminG = r - _atmospherePlanetRadius; - float dminT = _atmosphereRadius - r; - float dh = sqrtf(r * r - earth2); - float dH = dh + sqrtf(diff); - - shaderProg->setUniform("r", r); - shaderProg->setUniform("dhdH", dminT, dH, dminG, dh); - } - - shaderProg->setUniform("layer", layer); -} - -void AtmosphereDeferredcaster::saveTextureToPPMFile(GLenum color_buffer_attachment, - const std::string& fileName, - int width, int height) const -{ - std::fstream ppmFile; - - ppmFile.open(fileName.c_str(), std::fstream::out); - if (ppmFile.is_open()) { - unsigned char * pixels = new unsigned char[width*height * 3]; - for (int t = 0; t < width*height * 3; ++t) - pixels[t] = 255; - - if (color_buffer_attachment != GL_DEPTH_ATTACHMENT) { - glReadBuffer(color_buffer_attachment); - glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); - - } - else { - glReadPixels( - 0, - 0, - width, - height, - GL_DEPTH_COMPONENT, - GL_UNSIGNED_BYTE, - pixels - ); - } - - ppmFile << "P3" << std::endl; - ppmFile << width << " " << height << std::endl; - ppmFile << "255" << std::endl; - - std::cout << "\n\nFILE\n\n"; - int k = 0; - for (int i = 0; i < width; i++) { - for (int j = 0; j < height; j++) { - ppmFile << static_cast(pixels[k]) << " " - << static_cast(pixels[k + 1]) << " " - << static_cast(pixels[k + 2]) << " "; - k += 3; + const float earth2 = _atmospherePlanetRadius * _atmospherePlanetRadius; + const float diff = _atmosphereRadius * _atmosphereRadius - earth2; + const float ri = static_cast(layer) / static_cast(_r_samples - 1); + const float eps = [&]() { + if (layer == 0) { + return 0.01f; } - ppmFile << std::endl; - } - delete[] pixels; + else { + if (layer == (_r_samples - 1)) { + return -0.001f; + } + else { + return 0.f; + } + } + }(); + const float r = std::sqrt(earth2 + ri * ri * diff) + eps; + const float dminG = r - _atmospherePlanetRadius; + const float dminT = _atmosphereRadius - r; + const float dh = std::sqrt(r * r - earth2); + const float dH = dh + std::sqrt(diff); - ppmFile.close(); + shaderProg.setUniform("r", r); + shaderProg.setUniform("dhdH", dminT, dH, dminG, dh); } -} -bool AtmosphereDeferredcaster::isAtmosphereInFrustum(const glm::dmat4& MVMatrix, - const glm::dvec3& position, - double radius) const -{ - - // Frustum Planes - //glm::dvec3 col1(MVMatrix[0], MVMatrix[4], MVMatrix[8]); - //glm::dvec3 col2(MVMatrix[1], MVMatrix[5], MVMatrix[9]); - //glm::dvec3 col3(MVMatrix[2], MVMatrix[6], MVMatrix[10]); - //glm::dvec3 col4(MVMatrix[3], MVMatrix[7], MVMatrix[11]); - - glm::dvec3 col1(MVMatrix[0][0], MVMatrix[1][0], MVMatrix[2][0]); - glm::dvec3 col2(MVMatrix[0][1], MVMatrix[1][1], MVMatrix[2][1]); - glm::dvec3 col3(MVMatrix[0][2], MVMatrix[1][2], MVMatrix[2][2]); - glm::dvec3 col4(MVMatrix[0][3], MVMatrix[1][3], MVMatrix[2][3]); - - glm::dvec3 leftNormal = col4 + col1; - glm::dvec3 rightNormal = col4 - col1; - glm::dvec3 bottomNormal = col4 + col2; - glm::dvec3 topNormal = col4 - col2; - glm::dvec3 nearNormal = col3 + col4; - glm::dvec3 farNormal = col4 - col3; - - // Plane Distances - //double leftDistance = MVMatrix[15] + MVMatrix[12]; - //double rightDistance = MVMatrix[15] - MVMatrix[12]; - //double bottomDistance = MVMatrix[15] + MVMatrix[13]; - //double topDistance = MVMatrix[15] - MVMatrix[13]; - //double nearDistance = MVMatrix[15] + MVMatrix[14]; - //double farDistance = MVMatrix[15] - MVMatrix[14]; - - double leftDistance = MVMatrix[3][3] + MVMatrix[3][0]; - double rightDistance = MVMatrix[3][3] - MVMatrix[3][0]; - double bottomDistance = MVMatrix[3][3] + MVMatrix[3][1]; - double topDistance = MVMatrix[3][3] - MVMatrix[3][1]; - double nearDistance = MVMatrix[3][3] + MVMatrix[3][2]; -// double farDistance = MVMatrix[3][3] - MVMatrix[3][2]; - - // Normalize Planes - double invMag = 1.0 / glm::length(leftNormal); - leftNormal *= invMag; - leftDistance *= invMag; - - invMag = 1.0 / glm::length(rightNormal); - rightNormal *= invMag; - rightDistance *= invMag; - - invMag = 1.0 / glm::length(bottomNormal); - bottomNormal *= invMag; - bottomDistance *= invMag; - - invMag = 1.0 / glm::length(topNormal); - topNormal *= invMag; - topDistance *= invMag; - - invMag = 1.0 / glm::length(nearNormal); - nearNormal *= invMag; - nearDistance *= invMag; - - invMag = 1.0 / glm::length(farNormal); - farNormal *= invMag; -// farDistance *= invMag; - - if ((glm::dot(leftNormal, position) + leftDistance) < -radius) { - return false; - } - else if ((glm::dot(rightNormal, position) + rightDistance) < -radius) { - return false; - } - else if ((glm::dot(bottomNormal, position) + bottomDistance) < -radius) { - return false; - } - else if ((glm::dot(topNormal, position) + topDistance) < -radius) { - return false; - } - else if ((glm::dot(nearNormal, position) + nearDistance) < -radius) { - return false; - } - // The far plane testing is disabled because the atm has no depth. - /*else if ((glm::dot(farNormal, position) + farDistance) < -radius) { - return false; - }*/ - - return true; + shaderProg.setUniform("layer", layer); } } // namespace openspace diff --git a/modules/atmosphere/rendering/atmospheredeferredcaster.h b/modules/atmosphere/rendering/atmospheredeferredcaster.h index f0f142824a..608c5d47b4 100644 --- a/modules/atmosphere/rendering/atmospheredeferredcaster.h +++ b/modules/atmosphere/rendering/atmospheredeferredcaster.h @@ -31,7 +31,6 @@ #include #include #include - #include #include @@ -46,6 +45,16 @@ struct RenderData; struct DeferredcastData; struct ShadowConfiguration; +struct ShadowRenderingStruct { + double xu = 0.0; + double xp = 0.0; + double rs = 0.0; + double rc = 0.0; + glm::dvec3 sourceCasterVec = glm::dvec3(0.0); + glm::dvec3 casterPositionVec = glm::dvec3(0.0); + bool isShadowing = false; +}; + class AtmosphereDeferredcaster : public Deferredcaster { public: virtual ~AtmosphereDeferredcaster() = default; @@ -53,27 +62,27 @@ public: void initialize(); void deinitialize(); void preRaycast(const RenderData& renderData, const DeferredcastData& deferredData, - ghoul::opengl::ProgramObject& program) override; + ghoul::opengl::ProgramObject& program) override; void postRaycast(const RenderData& renderData, const DeferredcastData& deferredData, - ghoul::opengl::ProgramObject& program) override; + ghoul::opengl::ProgramObject& program) override; - std::string deferredcastPath() const override; - std::string deferredcastVSPath() const override; - std::string deferredcastFSPath() const override; - std::string helperPath() const override; + std::filesystem::path deferredcastPath() const override; + std::filesystem::path deferredcastVSPath() const override; + std::filesystem::path deferredcastFSPath() const override; + std::filesystem::path helperPath() const override; - void initializeCachedVariables(ghoul::opengl::ProgramObject&) override; + void initializeCachedVariables(ghoul::opengl::ProgramObject& program) override; void update(const UpdateData&) override; void preCalculateAtmosphereParam(); - void setModelTransform(const glm::dmat4 &transform); + void setModelTransform(glm::dmat4 transform); void setTime(double time); void setAtmosphereRadius(float atmRadius); void setPlanetRadius(float planetRadius); void setPlanetAverageGroundReflectance(float averageGReflectance); - void setPlanetGroundRadianceEmittion(float groundRadianceEmittion); + void setPlanetGroundRadianceEmission(float groundRadianceEmission); void setRayleighHeightScale(float rayleighHeightScale); void enableOzone(bool enable); void setOzoneHeightScale(float ozoneHeightScale); @@ -100,20 +109,9 @@ private: void deleteUnusedComputationTextures(); void executeCalculations(GLuint quadCalcVAO, GLenum drawBuffers[1], GLsizei vertexSize); - void step3DTexture(std::unique_ptr& shaderProg, - int layer, bool doCalculation = true); - void checkFrameBufferState(const std::string& codePosition) const; - void loadAtmosphereDataIntoShaderProgram( - std::unique_ptr & shaderProg - ); - void renderQuadForCalc(GLuint vao, GLsizei numberOfVertices); - void saveTextureToPPMFile(GLenum color_buffer_attachment, const std::string& fileName, - int width, int height) const; - bool isAtmosphereInFrustum(const glm::dmat4& MVMatrix, const glm::dvec3& position, - double radius) const; - - // Number of planet radii to use as distance threshold for culling - const double DISTANCE_CULLING_RADII = 5000; + void step3DTexture(ghoul::opengl::ProgramObject& shaderProg, int layer, + bool doCalculation); + void loadAtmosphereDataIntoShaderProgram(ghoul::opengl::ProgramObject& shaderProg); std::unique_ptr _transmittanceProgramObject; std::unique_ptr _irradianceProgramObject; @@ -125,19 +123,13 @@ private: std::unique_ptr _deltaSProgramObject; std::unique_ptr _deltaSSupTermsProgramObject; std::unique_ptr _deltaJProgramObject; - std::unique_ptr _atmosphereProgramObject; - std::unique_ptr _deferredAtmosphereProgramObject; - UniformCache(cullAtmosphere, Rg, Rt, - groundRadianceEmittion, HR, betaRayleigh, HM, - betaMieExtinction, mieG, sunRadiance, ozoneLayerEnabled, - HO, betaOzoneExtinction, SAMPLES_R, - SAMPLES_MU, SAMPLES_MU_S, SAMPLES_NU) _uniformCache; - UniformCache(dInverseModelTransformMatrix, dModelTransformMatrix, - dSgctProjectionToModelTransformMatrix, - dSGCTViewToWorldMatrix, dCamPosObj, sunDirectionObj, - hardShadows, transmittanceTexture, irradianceTexture, - inscatterTexture) _uniformCache2; + UniformCache(cullAtmosphere, Rg, Rt, groundRadianceEmission, HR, betaRayleigh, HM, + betaMieExtinction, mieG, sunRadiance, ozoneLayerEnabled, HO, betaOzoneExtinction, + SAMPLES_R, SAMPLES_MU, SAMPLES_MU_S, SAMPLES_NU, dInverseModelTransformMatrix, + dModelTransformMatrix, dSgctProjectionToModelTransformMatrix, + dSGCTViewToWorldMatrix, dCamPosObj, sunDirectionObj, hardShadows, + transmittanceTexture, irradianceTexture, inscatterTexture) _uniformCache; GLuint _transmittanceTableTexture = 0; GLuint _irradianceTableTexture = 0; @@ -146,7 +138,6 @@ private: GLuint _deltaSRayleighTableTexture = 0; GLuint _deltaSMieTableTexture = 0; GLuint _deltaJTableTexture = 0; - GLuint _atmosphereTexture = 0; ghoul::opengl::TextureUnit _transmittanceTableTextureUnit; ghoul::opengl::TextureUnit _irradianceTableTextureUnit; @@ -159,7 +150,7 @@ private: float _atmosphereRadius = 0.f; float _atmospherePlanetRadius = 0.f; float _planetAverageGroundReflectance = 0.f; - float _planetGroundRadianceEmittion = 0.f; + float _planetGroundRadianceEmission = 0.f; float _rayleighHeightScale = 0.f; float _ozoneHeightScale = 0.f; float _mieHeightScale = 0.f; @@ -173,12 +164,9 @@ private: glm::dvec3 _ellipsoidRadii = glm::vec3(0.f); // Atmosphere Textures Dimmensions - int _transmittance_table_width = 256; - int _transmittance_table_height = 64; - int _irradiance_table_width = 64; - int _irradiance_table_height = 16; - int _delta_e_table_width = 64; - int _delta_e_table_height = 16; + glm::ivec2 _transmittanceTableSize = glm::ivec2(256, 64); + glm::ivec2 _irradianceTableSize = glm::ivec2(64, 16); + glm::ivec2 _deltaETableSize = glm::ivec2(64, 16); int _r_samples = 32; int _mu_samples = 128; int _mu_s_samples = 32; @@ -192,7 +180,6 @@ private: bool _hardShadowsEnabled = false; // Atmosphere Debugging - float _calculationTextureScale = 1.f; bool _saveCalculationTextures = false; std::vector _shadowDataArrayCache; diff --git a/modules/atmosphere/rendering/renderableatmosphere.cpp b/modules/atmosphere/rendering/renderableatmosphere.cpp index ec8550a43d..e14ff893a7 100644 --- a/modules/atmosphere/rendering/renderableatmosphere.cpp +++ b/modules/atmosphere/rendering/renderableatmosphere.cpp @@ -25,33 +25,10 @@ #include #include -#include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef WIN32 -#define _USE_MATH_DEFINES -#endif // WIN32 #include namespace { @@ -69,7 +46,7 @@ namespace { "phase" }; - constexpr openspace::properties::Property::PropertyInfo GroundRadianceEmittioninfo = { + constexpr openspace::properties::Property::PropertyInfo GroundRadianceEmissionInfo = { "GroundRadianceEmission", "Percentage of initial radiance emitted from ground", "Multiplier of the ground radiance color during the rendering phase" @@ -197,7 +174,7 @@ namespace { // [[codegen::verbatim(MieScatteringExtinctionPropCoeffInfo.description)]] std::optional mieScatteringExtinctionPropCoefficient; - // [[codegen::verbatim(GroundRadianceEmittioninfo.description)]] + // [[codegen::verbatim(GroundRadianceEmissionInfo.description)]] float groundRadianceEmission; struct Rayleigh { @@ -243,16 +220,14 @@ namespace { namespace openspace { documentation::Documentation RenderableAtmosphere::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "atmosphere_renderable_atmosphere"; - return doc; + return codegen::doc("atmosphere_renderable_atmosphere"); } RenderableAtmosphere::RenderableAtmosphere(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _atmosphereHeight(AtmosphereHeightInfo, 60.f, 0.1f, 99.0f) , _groundAverageReflectance(AverageGroundReflectanceInfo, 0.f, 0.f, 1.f) - , _groundRadianceEmission(GroundRadianceEmittioninfo, 0.f, 0.f, 1.f) + , _groundRadianceEmission(GroundRadianceEmissionInfo, 0.f, 0.f, 1.f) , _rayleighHeightScale(RayleighHeightScaleInfo, 0.f, 0.1f, 50.f) , _rayleighScatteringCoeff( RayleighScatteringCoeffInfo, @@ -282,9 +257,7 @@ RenderableAtmosphere::RenderableAtmosphere(const ghoul::Dictionary& dictionary) _deferredCasterNeedsUpdate = true; _deferredCasterNeedsCalculation = true; }; - auto updateWithoutCalculation = [this]() { - _deferredCasterNeedsUpdate = true; - }; + auto updateWithoutCalculation = [this]() { _deferredCasterNeedsUpdate = true; }; const Parameters p = codegen::bake(dictionary); @@ -413,8 +386,8 @@ glm::dmat4 RenderableAtmosphere::computeModelTransformMatrix( const TransformData& transformData) { // scale the planet to appropriate size since the planet is a unit sphere - return glm::translate(glm::dmat4(1.0), transformData.translation) * // Translation - glm::dmat4(transformData.rotation) * // Spice rotation + return glm::translate(glm::dmat4(1.0), transformData.translation) * + glm::dmat4(transformData.rotation) * glm::scale(glm::dmat4(1.0), glm::dvec3(transformData.scale)); } @@ -448,7 +421,7 @@ void RenderableAtmosphere::updateAtmosphereParameters() { _deferredcaster->setAtmosphereRadius(_planetRadius + _atmosphereHeight); _deferredcaster->setPlanetRadius(_planetRadius); _deferredcaster->setPlanetAverageGroundReflectance(_groundAverageReflectance); - _deferredcaster->setPlanetGroundRadianceEmittion(_groundRadianceEmission); + _deferredcaster->setPlanetGroundRadianceEmission(_groundRadianceEmission); _deferredcaster->setRayleighHeightScale(_rayleighHeightScale); _deferredcaster->enableOzone(_ozoneEnabled); _deferredcaster->setOzoneHeightScale(_ozoneHeightScale); diff --git a/modules/atmosphere/rendering/renderableatmosphere.h b/modules/atmosphere/rendering/renderableatmosphere.h index 7fe0cbb477..63ec3afeab 100644 --- a/modules/atmosphere/rendering/renderableatmosphere.h +++ b/modules/atmosphere/rendering/renderableatmosphere.h @@ -33,9 +33,7 @@ #include #include #include - #include - #include #include #include @@ -57,16 +55,6 @@ struct ShadowConfiguration { std::pair caster; }; -struct ShadowRenderingStruct { - double xu = 0.0; - double xp = 0.0; - double rs = 0.0; - double rc = 0.0; - glm::dvec3 sourceCasterVec = glm::dvec3(0.0); - glm::dvec3 casterPositionVec = glm::dvec3(0.0); - bool isShadowing = false; -}; - namespace documentation { struct Documentation; } namespace planetgeometry { class PlanetGeometry; } diff --git a/modules/atmosphere/shaders/atmosphere_common.glsl b/modules/atmosphere/shaders/atmosphere_common.glsl index fd0ca1eb2f..6a0884f861 100644 --- a/modules/atmosphere/shaders/atmosphere_common.glsl +++ b/modules/atmosphere/shaders/atmosphere_common.glsl @@ -27,42 +27,38 @@ * from Eric Bruneton is used in the following code. * ****************************************************************************************/ - /** +/** * Precomputed Atmospheric Scattering * Copyright (c) 2008 INRIA * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - // Atmosphere Rendering Parameters uniform float Rg; uniform float Rt; uniform float AverageGroundReflectance; -uniform float groundRadianceEmittion; +uniform float groundRadianceEmission; uniform float HR; uniform vec3 betaRayleigh; uniform float HO; @@ -75,12 +71,9 @@ uniform float sunRadiance; uniform bool ozoneLayerEnabled; -uniform int TRANSMITTANCE_W; -uniform int TRANSMITTANCE_H; -uniform int SKY_W; -uniform int SKY_H; -uniform int OTHER_TEXTURES_W; -uniform int OTHER_TEXTURES_H; +uniform ivec2 TRANSMITTANCE; +uniform ivec2 SKY; +uniform ivec2 OTHER_TEXTURES; uniform int SAMPLES_R; uniform int SAMPLES_MU; uniform int SAMPLES_MU_S; @@ -95,46 +88,44 @@ const int IRRADIANCE_INTEGRAL_SAMPLES = 32; const int INSCATTER_SPHERICAL_INTEGRAL_SAMPLES = 16; const float M_PI = 3.141592657; +const float M_2PI = 2.0 * M_PI; uniform sampler2D transmittanceTexture; -float Rg2 = Rg * Rg; -float Rt2 = Rt * Rt; -float H = sqrt(Rt2 - Rg2); -float H2 = Rt2 - Rg2; -float invSamplesMu = 1.0f / float(SAMPLES_MU); -float invSamplesR = 1.0f / float(SAMPLES_R); -float invSamplesMuS = 1.0f / float(SAMPLES_MU_S); -float invSamplesNu = 1.0f / float(SAMPLES_NU); +float Rg2 = Rg * Rg; +float Rt2 = Rt * Rt; +float H = sqrt(Rt2 - Rg2); +float H2 = Rt2 - Rg2; +float invSamplesMu = 1.0 / float(SAMPLES_MU); +float invSamplesR = 1.0 / float(SAMPLES_R); +float invSamplesMuS = 1.0 / float(SAMPLES_MU_S); +float invSamplesNu = 1.0 / float(SAMPLES_NU); float RtMinusRg = float(Rt - Rg); -float invRtMinusRg = 1.0f / RtMinusRg; +float invRtMinusRg = 1.0 / RtMinusRg; float opticalDepth(float localH, float r, float mu, float d) { - float invH = 1.0/localH; - float a = sqrt((0.5 * invH)*r); - vec2 a01 = a*vec2(mu, mu + d / r); - vec2 a01s = sign(a01); - vec2 a01sq = a01*a01; - float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0; - vec2 y = a01s / (2.3193*abs(a01) + sqrt(1.52*a01sq + 4.0)) * vec2(1.0, exp(-d*invH*(d/(2.0*r)+mu))); - return sqrt((6.2831*H)*r) * exp((Rg-r)*invH) * (x + dot(y, vec2(1.0, -1.0))); + float invH = 1.0 / localH; + float a = sqrt(0.5 * invH * r); + vec2 a01 = a * vec2(mu, mu + d / r); + vec2 a01s = sign(a01); + vec2 a01sq = a01 * a01; + float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0; + vec2 y = a01s / (2.3193 * abs(a01) + sqrt(1.52 * a01sq + 4.0)) * vec2(1.0, exp(-d * invH * (d / (2.0 * r) + mu))); + return sqrt(M_2PI * H * r) * exp((Rg-r)*invH) * (x + dot(y, vec2(1.0, -1.0))); } vec3 analyticTransmittance(float r, float mu, float d) { + vec3 ozone = vec3(0.0); if (ozoneLayerEnabled) { - return exp(-betaRayleigh * opticalDepth(HR, r, mu, d) - - betaOzoneExtinction * (0.0000006) * opticalDepth(HO, r, mu, d) - - betaMieExtinction * opticalDepth(HM, r, mu, d)); - } - else { - return exp(-betaRayleigh * opticalDepth(HR, r, mu, d) - - betaMieExtinction * opticalDepth(HM, r, mu, d)); + ozone = betaOzoneExtinction * (0.0000006) * opticalDepth(HO, r, mu, d); } + return exp(-betaRayleigh * opticalDepth(HR, r, mu, d) - ozone - + betaMieExtinction * opticalDepth(HM, r, mu, d)); } vec3 irradiance(sampler2D sampler, float r, float muSun) { - float u_r = (r - Rg) * invRtMinusRg; - float u_muSun = (muSun + 0.2) / (1.0 + 0.2); + float u_r = (r - Rg) * invRtMinusRg; + float u_muSun = (muSun + 0.2) / 1.2; return texture(sampler, vec2(u_muSun, u_r)).rgb; } @@ -143,160 +134,104 @@ vec3 irradiance(sampler2D sampler, float r, float muSun) { //=============== General Functions ==============// //================================================// // In the following shaders r (altitude) is the length of vector/position x in the -// atmosphere (or on the top of it when considering an observer in space), -// where the light is comming from the opposite direction of the view direction, -// here the vector v or viewDirection. -// Rg is the planet radius and Rt the atmosphere radius. +// atmosphere (or on the top of it when considering an observer in space), where the light +// is coming from the opposite direction of the view direction, here the vector v or +// viewDirection. Rg is the planet radius and Rt the atmosphere radius. -//--- Calculate the distance of the ray starting at x (height r) -// until the planet's ground or top of atmosphere. --- +// Calculate the distance of the ray starting at x (height r) until the planet's ground +// or top of atmosphere // r := || vec(x) || e [0, Rt] // mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r float rayDistance(float r, float mu) { - // The light ray starting at the observer in/on the atmosphere can - // have to possible end points: the top of the atmosphere or the - // planet ground. So the shortest path is the one we are looking for, - // otherwise we may be passing through the ground. + // The light ray starting at the observer in/on the atmosphere can have to possible end + // points: the top of the atmosphere or the planet ground. So the shortest path is the + // one we are looking for, otherwise we may be passing through the ground // cosine law - float atmRadiusEps = Rt + ATM_EPSILON; - float rayDistanceAtmosphere = -r * mu + - sqrt(r * r * (mu * mu - 1.0f) + atmRadiusEps * atmRadiusEps); - float delta = r * r * (mu * mu - 1.0f) + Rg * Rg; + float atmRadiusEps2 = (Rt + ATM_EPSILON) * (Rt + ATM_EPSILON); + float mu2 = mu * mu; + float r2 = r * r; + float rg2 = Rg * Rg; + float rayDistanceAtmosphere = -r * mu + sqrt(r2 * (mu2 - 1.0) + atmRadiusEps2); + float delta = r2 * (mu2 - 1.0) + rg2; // Ray may be hitting ground - if (delta >= 0.0f) { + if (delta >= 0.0) { float rayDistanceGround = -r * mu - sqrt(delta); - if (rayDistanceGround >= 0.0f) { + if (rayDistanceGround >= 0.0) { return min(rayDistanceAtmosphere, rayDistanceGround); } } return rayDistanceAtmosphere; } -//-- Given the window's fragment coordinates, for a defined -// viewport, gives back the interpolated r e [Rg, Rt] and -// mu e [-1, 1] -- -// r := height of starting point vect(x) -// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r -void unmappingRAndMu(out float r, out float mu) { - float u_mu = gl_FragCoord.x / float(TRANSMITTANCE_W); - float u_r = gl_FragCoord.y / float(TRANSMITTANCE_H); - - // In the paper u_r^2 = (r^2-Rg^2)/(Rt^2-Rg^2) - // So, extracting r from u_r in the above equation: - //r = sqrt( Rg * Rg + (u_r * u_r) * (Rt * Rt - Rg * Rg) ); - r = Rg + (u_r * u_r) * RtMinusRg; - - // In the paper the Bruneton suggest mu = dot(v,x)/||x|| with ||v|| = 1.0 - // Later he proposes u_mu = (1-exp(-3mu-0.6))/(1-exp(-3.6)) - // But the below one is better. See Colliene. - // One must remember that mu is defined from 0 to PI/2 + epsillon. - mu = -0.15f + tan(1.5f * u_mu) / tan(1.5f) * (1.0f + 0.15f); -} - -//-- Given the windows's fragment coordinates, for a defined view port, -// gives back the interpolated r e [Rg, Rt] and muSun e [-1, 1] -- -// r := height of starting point vect(x) -// muSun := cosine of the zeith angle of vec(s). Or muSun = (vec(s) * vec(v)) -void unmappingRAndMuSun(out float r, out float muSun) { - // See Bruneton and Colliene to understand the mapping. - muSun = -0.2f + (gl_FragCoord.x - 0.5f) / (float(OTHER_TEXTURES_W) - 1.0f) * (1.0f + 0.2f); - //r = Rg + (gl_FragCoord.y - 0.5f) / (float(OTHER_TEXTURES_H) - 1.0f) * (Rt - Rg); - r = Rg + (gl_FragCoord.y - 0.5f) / (float(OTHER_TEXTURES_H) ) * RtMinusRg; -} - -//-- Given the windows's fragment coordinates, for a defined view port, -// gives back the interpolated r e [Rg, Rt] and muSun e [-1, 1] for the -// Irradiance deltaE texture table -- -// r := height of starting point vect(x) -// muSun := cosine of the zeith angle of vec(s). Or muSun = (vec(s) * vec(v)) -void unmappingRAndMuSunIrradiance(out float r, out float muSun) { - // See Bruneton and Colliene to understand the mapping. - muSun = -0.2f + (gl_FragCoord.x - 0.5f) / (float(SKY_W) - 1.0f) * (1.0f + 0.2f); - r = Rg + (gl_FragCoord.y - 0.5f) / (float(SKY_H) - 1.0f) * RtMinusRg; -} - -//-- Given the windows's fragment coordinates, for a defined view port, -// gives back the interpolated r e [Rg, Rt] and mu, muSun amd nu e [-1, 1] -- +// Given the windows's fragment coordinates, for a defined view port, gives back the +// interpolated r e [Rg, Rt] and mu, muSun amd nu e [-1, 1] // r := height of starting point vect(x) // mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r // muSun := cosine of the zeith angle of vec(s). Or muSun = (vec(s) * vec(v)) // nu := cosone of the angle between vec(s) and vec(v) -// dhdH := it is a vec4. dhdH.x stores the dminT := Rt - r, dhdH.y stores the dH value (see paper), -// dhdH.z stores dminG := r - Rg and dhdH.w stores dh (see paper). +// dhdH := it is a vec4. dhdH.x stores the dminT := Rt - r, dhdH.y stores the dH value +// (see paper), dhdH.z stores dminG := r - Rg and dhdH.w stores dh (see paper) void unmappingMuMuSunNu(float r, vec4 dhdH, out float mu, out float muSun, out float nu) { // Window coordinates of pixel (uncentering also) - float fragmentX = gl_FragCoord.x - 0.5f; - float fragmentY = gl_FragCoord.y - 0.5f; + vec2 fragment = gl_FragCoord.xy - vec2(0.5); // Pre-calculations - //float Rg2 = Rg * Rg; - //float Rt2 = Rt * Rt; float r2 = r * r; - float halfSAMPLE_MU = float(SAMPLES_MU) / 2.0f; - // If the (vec(x) dot vec(v))/r is negative, i.e., - // the light ray has great probability to touch - // the ground, we obtain mu considering the geometry - // of the ground - if (fragmentY < halfSAMPLE_MU) { - float ud = 1.0f - (fragmentY / (halfSAMPLE_MU - 1.0f)); + float halfSAMPLE_MU = float(SAMPLES_MU) / 2.0; + // If the (vec(x) dot vec(v))/r is negative, i.e., the light ray has great probability + // to touch the ground, we obtain mu considering the geometry of the ground + if (fragment.y < halfSAMPLE_MU) { + float ud = 1.0 - (fragment.y / (halfSAMPLE_MU - 1.0)); float d = min(max(dhdH.z, ud * dhdH.w), dhdH.w * 0.999); - // cosine law: Rg^2 = r^2 + d^2 - 2rdcos(pi-theta) - // where cosine(theta) = mu + // cosine law: Rg^2 = r^2 + d^2 - 2rdcos(pi-theta) where cosine(theta) = mu mu = (Rg2 - r2 - d * d) / (2.0 * r * d); - // We can't handle a ray inside the planet, i.e., - // when r ~ Rg, so we check against it. - // If that is the case, we approximate to - // a ray touching the ground. + // We can't handle a ray inside the planet, i.e., when r ~ Rg, so we check against it. + // If that is the case, we approximate to a ray touching the ground. // cosine(pi-theta) = dh/r = sqrt(r^2-Rg^2) // cosine(theta) = - sqrt(1 - Rg^2/r^2) mu = min(mu, -sqrt(1.0 - (Rg2 / r2)) - 0.001); } - // The light ray is touching the atmosphere and - // not the ground + // The light ray is touching the atmosphere and not the ground else { - float d = (fragmentY - halfSAMPLE_MU) / (halfSAMPLE_MU - 1.0f); + float d = (fragment.y - halfSAMPLE_MU) / (halfSAMPLE_MU - 1.0); d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999); - // cosine law: Rt^2 = r^2 + d^2 - 2rdcos(pi-theta) - // whre cosine(theta) = mu - mu = (Rt2 - r2 - d * d) / (2.0f * r * d); + // cosine law: Rt^2 = r^2 + d^2 - 2rdcos(pi-theta) where cosine(theta) = mu + mu = (Rt2 - r2 - d * d) / (2.0 * r * d); } - float modValueMuSun = mod(fragmentX, float(SAMPLES_MU_S)) / (float(SAMPLES_MU_S) - 1.0f); + float modValueMuSun = mod(fragment.x, float(SAMPLES_MU_S)) / (float(SAMPLES_MU_S) - 1.0); // The following mapping is different from the paper. See Colliene for an details. - muSun = tan((2.0f * modValueMuSun - 1.0f + 0.26f) * 1.1f) / tan(1.26f * 1.1f); - nu = -1.0f + floor(fragmentX / float(SAMPLES_MU_S)) / (float(SAMPLES_NU) - 1.0f) * 2.0f; + muSun = tan((2.0 * modValueMuSun - 1.0 + 0.26) * 1.1f) / tan(1.26 * 1.1); + nu = -1.0 + floor(fragment.x / float(SAMPLES_MU_S)) / (float(SAMPLES_NU) - 1.0) * 2.0; } - -//-- Function to access the transmittance texture. Given r -// and mu, returns the transmittance of a ray starting at vec(x), -// height r, and direction vec(v), mu, and length until it hits -// the ground or the top of atmosphere. -- +// Function to access the transmittance texture. Given r and mu, returns the transmittance +// of a ray starting at vec(x), height r, and direction vec(v), mu, and length until it +// hits the ground or the top of atmosphere. // r := height of starting point vect(x) // mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r -vec3 transmittanceLUT(float r, float mu) { - // Given the position x (here the altitude r) and the view - // angle v (here the cosine(v)= mu), we map this - float u_r = sqrt((r - Rg) * invRtMinusRg); - //float u_r = sqrt((r*r - Rg*Rg) / (Rt*Rt - Rg*Rg)); - // See Colliene to understand the different mapping. - float u_mu = atan((mu + 0.15f) / (1.0f + 0.15f) * tan(1.5f)) / 1.5f; +vec3 transmittance(float r, float mu) { + // Given the position x (here the altitude r) and the view angle v + // (here the cosine(v)= mu), we map this + float u_r = sqrt((r - Rg) * invRtMinusRg); + // See Colliene to understand the mapping + float u_mu = atan((mu + 0.15) / 1.15 * tan(1.5)) / 1.5; return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb; } -// -- Given a position r and direction mu, calculates de transmittance -// along the ray with length d. This function uses the propriety -// of Transmittance: T(a,b) = TableT(a,v)/TableT(b, v) -- +// Given a position r and direction mu, calculates de transmittance along the ray with +// length d. This function uses the propriety of Transmittance: +// T(a,b) = TableT(a,v)/TableT(b, v) // r := height of starting point vect(x) // mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r vec3 transmittance(float r, float mu, float d) { - // Here we use the transmittance property: T(x,v) = T(x,d)*T(d,v) - // to, given a distance d, calculates that transmittance along - // that distance starting in x (hight r): T(x,d) = T(x,v)/T(d,v). + // Here we use the transmittance property: T(x,v) = T(x,d)*T(d,v) to, given a distance + // d, calculates that transmittance along that distance starting in x (height r): + // T(x,d) = T(x,v)/T(d,v). // // From cosine law: c^2 = a^2 + b^2 - 2*a*b*cos(ab) float ri = sqrt(d * d + r * r + 2.0 * r * d * mu); @@ -305,105 +240,75 @@ vec3 transmittance(float r, float mu, float d) { // = (r*mu + d) / r_i float mui = (d + r * mu) / ri; - // It's important to remember that we calculate the Transmittance - // table only for zenith angles between 0 and pi/2+episilon. - // Then, if mu < 0.0, we just need to invert the view direction - // and the start and end points between them, i.e., if + // It's important to remember that we calculate the Transmittance table only for zenith + // angles between 0 and pi/2+episilon. Then, if mu < 0.0, we just need to invert the + // view direction and the start and end points between them, i.e., if // x --> x0, then x0-->x. // Also, let's use the property: T(a,c) = T(a,b)*T(b,c) - // Because T(a,c) and T(b,c) are already in the table T, - // T(a,b) = T(a,c)/T(b,c). - if (mu > 0.0f) { - return min(transmittanceLUT(r, mu) / - transmittanceLUT(ri, mui), 1.0f); + // Because T(a,c) and T(b,c) are already in the table T, T(a,b) = T(a,c)/T(b,c). + if (mu > 0.0) { + return min(transmittance(r, mu) / transmittance(ri, mui), 1.0); } else { - return min(transmittanceLUT(ri, -mui) / - transmittanceLUT(r, -mu), 1.0f); + return min(transmittance(ri, -mui) / transmittance(r, -mu), 1.0); } } -// -- Calculates Rayleigh phase function given the -// scattering cosine angle mu -- +// Calculates Rayleigh phase function given the scattering cosine angle mu // mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r float rayleighPhaseFunction(float mu) { //return (3.0f / (16.0f * M_PI)) * (1.0f + mu * mu); - return 0.0596831036 * (1.0f + mu * mu); + return 0.0596831036 * (1.0 + mu * mu); } -// -- Calculates Mie phase function given the -// scattering cosine angle mu -- -// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r -float miePhaseFunction(float mu) { - //return (3.0f / (8.0f * M_PI)) * - // ( ( (1.0f - (mieG * mieG) ) * (1.0f + mu * mu) ) / - // ( (2.0f + mieG * mieG) * - // pow(1.0f + mieG * mieG - 2.0f * mieG * mu, 3.0f/2.0f) ) ); - // return 1.5f * 1.0f / (4.0f * M_PI) * (1.0f - mieG * mieG) * - // pow(1.0f + (mieG * mieG) - 2.0f * mieG * mu, -3.0f/2.0f) * (1.0f + mu * mu) / (2.0f + mieG*mieG); - +// Calculates Mie phase function given the scattering cosine angle mu +// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v)) / r +// mieG := mie phase function value +float miePhaseFunction(float mu, float mieG) { float mieG2 = mieG * mieG; - return 0.1193662072 * (1.0f - mieG2) * - pow(1.0f + mieG2 - 2.0f * mieG * mu, -1.5f) * (1.0f + mu * mu) / (2.0f + mieG2); + return 0.1193662072 * (1.0 - mieG2) * + pow(1.0 + mieG2 - 2.0 * mieG * mu, -1.5) * (1.0 + mu * mu) / (2.0 + mieG2); } -// -- Given the height rm view-zenith angle (cosine) mu, -// sun-zenith angle (cosine) muSun and the angle (cosine) -// between the vec(s) and vec(v), nu, we access the 3D textures -// and interpolate between them (r) to find the value for the -// 4D texture. -- +// Given the height rm view-zenith angle (cosine) mu, sun-zenith angle (cosine) muSun and +// the angle (cosine) between the vec(s) and vec(v), nu, we access the 3D textures and +// interpolate between them (r) to find the value for the 4D texture. // r := height of starting point vect(x) // mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r // muSun := cosine of the zeith angle of vec(s). Or muSun = (vec(s) * vec(v)) // nu := cosine of the angle between vec(s) and vec(v) vec4 texture4D(sampler3D table, float r, float mu, float muSun, float nu) { - //float Rg2 = Rg * Rg; - //float Rt2 = Rt * Rt; - float r2 = r * r; - //float H = sqrt(Rt2 - Rg2); - float rho = sqrt(r2 - Rg2); - float rmu = r * mu; - float delta = rmu * rmu - r2 + Rg2; - //float invSamplesMu = 1.0f / float(SAMPLES_MU); - //float invSamplesR = 1.0f / float(SAMPLES_R); - //float invSamplesMuS = 1.0f / float(SAMPLES_MU_S); - //float invSamplesNu = 1.0f / float(SAMPLES_NU); - // vec4 cst = rmu < 0.0f && delta > 0.0f ? - // vec4(1.0f, 0.0f, 0.0f, 0.5f - 0.5f / float(SAMPLES_MU)) : - // vec4(-1.0f, H * H, H, 0.5f + 0.5f / float(SAMPLES_MU)); + float r2 = r * r; + float rho = sqrt(r2 - Rg2); + float rmu = r * mu; + float delta = rmu * rmu - r2 + Rg2; - vec4 cst = rmu < 0.0f && delta > 0.0f ? - vec4(1.0f, 0.0f, 0.0f, 0.5f - 0.5f * invSamplesMu) : - vec4(-1.0f, H2, H, 0.5f + 0.5f * invSamplesMu); + vec4 cst = rmu < 0.0 && delta > 0.0 ? + vec4(1.0, 0.0, 0.0, 0.5 - 0.5 * invSamplesMu) : + vec4(-1.0, H2, H, 0.5 + 0.5 * invSamplesMu); - //float u_r = 0.5f / float(SAMPLES_R) + rho / H * (1.0f - 1.0f / float(SAMPLES_R)); - float u_r = 0.5f * invSamplesR + rho / H * (1.0f - invSamplesR); - //float u_mu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5f - 1.0f / float(SAMPLES_MU)); - float u_mu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5f - invSamplesMu); - // float u_mu_s = 0.5f / float(SAMPLES_MU_S) + - // (atan(max(muSun, -0.1975) * tan(1.26f * 1.1f)) / 1.1f + (1.0f - 0.26f)) * 0.5f * (1.0f - 1.0f / float(SAMPLES_MU_S)); - float u_mu_s = 0.5f * invSamplesMuS + - (atan(max(muSun, -0.1975) * tan(1.386f)) * 0.9090909090909090 + (0.74f)) * 0.5f * (1.0f - invSamplesMuS); - float lerp = (nu + 1.0f) / 2.0f * (float(SAMPLES_NU) - 1.0f); + float u_r = 0.5 * invSamplesR + rho / H * (1.0 - invSamplesR); + float u_mu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - invSamplesMu); + float u_mu_s = 0.5 * invSamplesMuS + + (atan(max(muSun, -0.1975) * tan(1.386)) * 0.9090909090909090 + 0.74) * 0.5 * (1.0 - invSamplesMuS); + float lerp = (nu + 1.0) / 2.0 * (float(SAMPLES_NU) - 1.0); float u_nu = floor(lerp); lerp = lerp - u_nu; - // return texture(table, vec3((u_nu + u_mu_s) / float(SAMPLES_NU), u_mu, u_r)) * (1.0f - lerp) + - // texture(table, vec3((u_nu + u_mu_s + 1.0f) / float(SAMPLES_NU), u_mu, u_r)) * lerp; - - return texture(table, vec3((u_nu + u_mu_s) * invSamplesNu, u_mu, u_r)) * (1.0f - lerp) + - texture(table, vec3((u_nu + u_mu_s + 1.0f) * invSamplesNu, u_mu, u_r)) * lerp; + return texture( + table, vec3((u_nu + u_mu_s) * invSamplesNu, u_mu, u_r)) * (1.0 - lerp) + + texture(table, vec3((u_nu + u_mu_s + 1.0) * invSamplesNu, u_mu, u_r)) * lerp; } -// -- Given the irradiance texture table, the cosine of zenith sun vector -// and the height of the observer (ray's stating point x), calculates the -// mapping for u_r and u_muSun and returns the value in the LUT. -- +// Given the irradiance texture table, the cosine of zenith sun vector and the height of +// the observer (ray's stating point x), calculates the mapping for u_r and u_muSun and +// returns the value in the LUT // lut := OpenGL texture2D sampler (the irradiance texture deltaE) // muSun := cosine of the zeith angle of vec(s). Or muSun = (vec(s) * vec(v)) // r := height of starting point vect(x) vec3 irradianceLUT(sampler2D lut, float muSun, float r) { // See Bruneton paper and Coliene to understand the mapping - float u_muSun = (muSun + 0.2f) / (1.0f + 0.2f); - float u_r = (r - Rg) * invRtMinusRg; + float u_muSun = (muSun + 0.2) / 1.2; + float u_r = (r - Rg) * invRtMinusRg; return texture(lut, vec2(u_muSun, u_r)).rgb; } diff --git a/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl b/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl index 6e7872b129..9be329d940 100644 --- a/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl +++ b/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl @@ -32,40 +32,35 @@ * Copyright (c) 2008 INRIA * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #version __CONTEXT__ #include "floatoperations.glsl" - #include "atmosphere_common.glsl" -out vec4 renderTarget; -in vec3 interpolatedNDCPos; in vec2 texCoord; +out vec4 renderTarget; uniform int nAaSamples; uniform int cullAtmosphere; @@ -81,617 +76,532 @@ uniform dmat4 dModelTransformMatrix; uniform dmat4 dSGCTViewToWorldMatrix; uniform dmat4 dSgctProjectionToModelTransformMatrix; +uniform vec4 viewport; +uniform vec2 resolution; + uniform dvec4 dCamPosObj; uniform dvec3 sunDirectionObj; /******************************************************************************* ***** ALL CALCULATIONS FOR ECLIPSE ARE IN METERS AND IN WORLD SPACE SYSTEM **** *******************************************************************************/ -// JCC: Remove and use dictionary to -// decides the number of shadows +// JCC: Remove and use dictionary to decide the number of shadows const uint numberOfShadows = 1; struct ShadowRenderingStruct { - double xu, xp; - double rs, rc; - dvec3 sourceCasterVec; - dvec3 casterPositionVec; - bool isShadowing; + double xu, xp; + double rs, rc; + dvec3 sourceCasterVec; + dvec3 casterPositionVec; + bool isShadowing; }; // Eclipse shadow data -// JCC: Remove and use dictionary to -// decides the number of shadows +// JCC: Remove and use dictionary to decide the number of shadows uniform ShadowRenderingStruct shadowDataArray[numberOfShadows]; uniform int shadows; uniform bool hardShadows; -vec4 butterworthFunc(float d, float r, float n) { - return vec4(vec3(sqrt(r/(r + pow(d, 2*n)))), 1.0); -} - -vec4 calcShadow(ShadowRenderingStruct shadowInfoArray[numberOfShadows], dvec3 position, - bool ground) +float calcShadow(ShadowRenderingStruct shadowInfoArray[numberOfShadows], dvec3 position, + bool ground) { - if (shadowInfoArray[0].isShadowing) { - dvec3 pc = shadowInfoArray[0].casterPositionVec - position; - dvec3 sc_norm = shadowInfoArray[0].sourceCasterVec; - dvec3 pc_proj = dot(pc, sc_norm) * sc_norm; - dvec3 d = pc - pc_proj; - - float length_d = float(length(d)); - double length_pc_proj = length(pc_proj); - - float r_p_pi = float(shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xp) / shadowInfoArray[0].xp); - float r_u_pi = float(shadowInfoArray[0].rc * (shadowInfoArray[0].xu - length_pc_proj) / shadowInfoArray[0].xu); - - if ( length_d < r_u_pi ) { // umbra - if (ground) { - if (hardShadows) { - return vec4(0.2, 0.2, 0.2, 1.0); - } - else { - return butterworthFunc(length_d, r_u_pi, 2.0); - } - } - else { - if (hardShadows) { - return vec4(0.5, 0.5, 0.5, 1.0); - } - else { - //return vec4(vec3(length_d/r_p_pi), 1.0); - return butterworthFunc(length_d, r_u_pi, 2.0); - } - } - } - else if ( length_d < r_p_pi ) {// penumbra - if (hardShadows) { - return vec4(0.5, 0.5, 0.5, 1.0); - } - else { - return vec4(vec3(length_d/r_p_pi), 1.0); - } - } - } - - return vec4(1.0); -} + if (!shadowInfoArray[0].isShadowing) { + return 1.0; + } -/******************************************************************************* - ******* ALL CALCULATIONS FOR ATMOSPHERE ARE KM AND IN WORLD SPACE SYSTEM ****** - *******************************************************************************/ - -struct dRay { - dvec4 origin; - dvec4 direction; -}; - -/* Function to calculate the initial intersection of the eye (camera) ray - * with the atmosphere. - * In (all parameters in the same coordinate system and same units): - * - planet position - * - ray direction (normalized) - * - eye position - * - atmosphere radius - * Out: true if an intersection happens, false otherwise - * - inside: true if the ray origin is inside atmosphere, false otherwise - * - offset: the initial intersection distance from eye position when - * the eye is outside the atmosphere - * - maxLength : the second intersection distance from eye position when the - * eye is outside the atmosphere or the initial (and only) - * intersection of the ray with atmosphere when the eye position - * is inside atmosphere. - */ -bool dAtmosphereIntersection(dvec3 planetPosition, dRay ray, double atmRadius, - out bool inside, out double offset, out double maxLength ) { - dvec3 l = planetPosition - ray.origin.xyz; - double s = dot(l, ray.direction.xyz); - double l2 = dot(l, l); - double r2 = atmRadius * atmRadius; // avoiding surface acne - - // Ray origin (eye position) is behind sphere - if ((s < 0.0) && (l2 > r2)) { - inside = false; - offset = 0.0; - maxLength = 0.0; - return false; - } - - double m2 = l2 - s*s; - - // Ray misses atmospere - if (m2 > r2) { - inside = false; - offset = 0.0; - maxLength = 0.0; - return false; - } - - // We already now the ray hits the atmosphere - - // If q = 0.0f, there is only one intersection - double q = sqrt(r2 - m2); - - // If l2 < r2, the ray origin is inside the sphere - if (l2 > r2) { - inside = false; - offset = s - q; - maxLength = s + q; + dvec3 pc = shadowInfoArray[0].casterPositionVec - position; + dvec3 sc_norm = shadowInfoArray[0].sourceCasterVec; + dvec3 pc_proj = dot(pc, sc_norm) * sc_norm; + dvec3 d = pc - pc_proj; + + float length_d = float(length(d)); + double length_pc_proj = length(pc_proj); + + float r_p_pi = float(shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xp) / shadowInfoArray[0].xp); + float r_u_pi = float(shadowInfoArray[0].rc * (shadowInfoArray[0].xu - length_pc_proj) / shadowInfoArray[0].xu); + + if (length_d < r_u_pi) { + // umbra + if (hardShadows) { + return ground ? 0.2 : 0.5; } else { - inside = true; - offset = 0.0; - maxLength = s + q; + // butterworth function + return sqrt(r_u_pi / (r_u_pi + pow(length_d, 4.0))); } - - return true; + } + else if (length_d < r_p_pi) { + // penumbra + return hardShadows ? 0.5 : length_d / r_p_pi; + } + else { + return 1.0; + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +// ALL CALCULATIONS FOR ATMOSPHERE ARE KM AND IN WORLD SPACE SYSTEM // +////////////////////////////////////////////////////////////////////////////////////////// + +struct Ray { + dvec3 origin; + dvec3 direction; +}; + +/* + * Function to calculate the initial intersection of the eye (camera) ray with the + * atmosphere. + * In (all parameters in the same coordinate system and same units): + * - ray direction (normalized) + * - atmosphere radius + * Out: true if an intersection happens, false otherwise + * - return: true if the ray origin is inside atmosphere, false otherwise + * - offset: the initial intersection distance from eye position when the eye is outside + * the atmosphere + * - maxLength: the second intersection distance from eye position when the eye is + * outside the atmosphere or the initial (and only) intersection of the ray + * with atmosphere when the eye position is inside atmosphere. + */ +bool atmosphereIntersection(Ray ray, double atmRadius, out double offset, + out double maxLength) +{ + dvec3 l = -ray.origin; + double s = dot(l, ray.direction); + double l2 = dot(l, l); + double r2 = atmRadius * atmRadius; // avoiding surface acne + + // Ray origin (eye position) is behind sphere + if ((s < 0.0) && (l2 > r2)) { + offset = 0.0; + maxLength = 0.0; + return false; + } + + double m2 = l2 - s * s; + + // Ray misses atmosphere + if (m2 > r2) { + offset = 0.0; + maxLength = 0.0; + return false; + } + + // We already now the ray hits the atmosphere + + // If q = 0.0, there is only one intersection + double q = sqrt(r2 - m2); + + // If l2 < r2, the ray origin is inside the sphere + if (l2 > r2) { + offset = s - q; + maxLength = s + q; + } + else { + offset = 0.0; + maxLength = s + q; + } + + return true; } /* - * Calculates Intersection Ray by walking through - * all the graphic pipile transformations in the - * opposite direction. - * Instead of passing through all the pipeline, - * it starts at NDC from the interpolated - * positions from the screen quad. - * This method avoids matrices multiplications - * wherever is possible. + * Calculates Intersection Ray by walking through all the graphic pipeline transformations + * in the opposite direction. Instead of passing through all the pipeline, it starts at + * NDC from the interpolated positions from the screen quad. This method avoids matrices + * multiplications wherever is possible. */ -void dCalculateRayRenderableGlobe(out dRay ray, - out dvec4 planetPositionObjectCoords, - out dvec4 cameraPositionInObject) { - dvec4 clipCoords = dvec4(interpolatedNDCPos.xy, 1.0, 1.0); +Ray calculateRayRenderableGlobe(vec2 st) { + vec2 interpolatedNDCPos = (st - 0.5) * 2.0; + dvec4 clipCoords = dvec4(interpolatedNDCPos, 1.0, 1.0); - // Clip to Object Coords - dvec4 objectCoords = dSgctProjectionToModelTransformMatrix * clipCoords; - - objectCoords /= objectCoords.w; - - // Planet Position in Object Space - // JCC: Applying the inverse of the model transformation on the object postion in World - // space results in imprecision. - planetPositionObjectCoords = dvec4(0.0, 0.0, 0.0, 1.0); - - // Camera Position in Object Space (in meters) - cameraPositionInObject = dCamPosObj; - - // ============================ - // ====== Building Ray ======== - // Ray in object space (in KM) - ray.origin = cameraPositionInObject * dvec4(0.001, 0.001, 0.001, 1.0); - //ray.direction = dvec4(normalize(objectCoords.xyz - cameraPositionInObject.xyz), 0.0); - ray.direction = dvec4(normalize((objectCoords.xyz * dvec3(0.001))- ray.origin.xyz), 0.0); + // Clip to Object Coords + dvec4 objectCoords = dSgctProjectionToModelTransformMatrix * clipCoords; + objectCoords /= objectCoords.w; + + // Building Ray + // Ray in object space (in KM) + Ray ray; + ray.origin = dvec3(dCamPosObj * dvec4(0.001, 0.001, 0.001, 1.0)); + ray.direction = normalize(objectCoords.xyz * dvec3(0.001) - ray.origin); + return ray; } /* - * Calculates the light scattering in the view direction comming from other - * light rays scattered in the atmosphere. + * Calculates the light scattering in the view direction comming from other light rays + * scattered in the atmosphere. * Following the paper: S[L]|x - T(x,xs) * S[L]|xs - * The view direction here is the ray: x + tv, s is the sun direction, - * r and mu the position and zenith cosine angle as in the paper. + * The view direction here is the ray: x + tv, s is the sun direction, r and mu the + * position and zenith cosine angle as in the paper. * Arguments: * x := camera position * t := ray displacement variable after calculating the intersection with the - * atmosphere. It is the distance from the camera to the last intersection with - * the atmosphere. If the ray hits the ground, t is updated to the correct value + * atmosphere. It is the distance from the camera to the last intersection with the + * atmosphere. If the ray hits the ground, t is updated to the correct value * v := view direction (ray's direction) (normalized) * s := Sun direction (normalized) * r := out of ||x|| inside atmosphere (or top of atmosphere) * mu := out of cosine of the zenith view angle - * attenuation := out of transmittance T(x,x0). This will be used later when - * calculating the reflectance R[L]. + * attenuation := out of transmittance T(x,x0). This will be used later when calculating + * the reflectance R[L] */ -vec3 inscatterRadiance(inout vec3 x, inout float t, inout float irradianceFactor, - vec3 v, vec3 s, out float r, out float mu, - out vec3 attenuation, vec3 fragPosObj, out bool groundHit, - double maxLength, double pixelDepth, - vec4 spaceColor, float sunIntensity) { +vec3 inscatterRadiance(vec3 x, inout float t, out float irradianceFactor, vec3 v, vec3 s, + out float r, out float mu, out vec3 attenuation, vec3 fragPosObj, + out bool groundHit, double maxLength, double pixelDepth, + vec4 spaceColor, float sunIntensity) +{ + const float INTERPOLATION_EPS = 0.004; // precision const from Brunetton - const float INTERPOLATION_EPS = 0.004f; // precision const from Brunetton + vec3 radiance; + + r = length(x); + mu = dot(x, v) / r; - vec3 radiance; + float r2 = r * r; + float nu = dot(v, s); + float muSun = dot(x, s) / r; + float rayleighPhase = rayleighPhaseFunction(nu); + float miePhase = miePhaseFunction(nu, mieG); - r = length(x); - mu = dot(x, v) / r; + // S[L](x,s,v) + // I.e. the next line has the scattering light for the "infinite" ray passing through + // the atmosphere. If this ray hits something inside the atmosphere, we will subtract + // the attenuated scattering light from that path in the current path + vec4 inscatterRadiance = max(texture4D(inscatterTexture, r, mu, muSun, nu), 0.0); + + // After removing the initial path from camera pos to top of atmosphere (for an + // observer in the space) we test if the light ray is hitting the atmosphere + float r0 = length(fragPosObj); + float invr0 = 1.0 / r0; + float muSun0 = dot(fragPosObj, s) * invr0; + float mu0 = dot(fragPosObj, v) * invr0; - float mu2 = mu * mu; - float r2 = r * r; - float nu = dot(v, s); - float muSun = dot(x, s) / r; - float rayleighPhase = rayleighPhaseFunction(nu); - float miePhase = miePhaseFunction(nu); - - // S[L](x,s,v) - // I.e. the next line has the scattering light for the "infinite" ray passing - // through the atmosphere. If this ray hits something inside the atmosphere, - // we will subtract the attenuated scattering light from that path in the - // current path. - vec4 inscatterRadiance = max(texture4D(inscatterTexture, r, mu, muSun, nu), 0.0); - - // After removing the initial path from camera pos to top of atmosphere (for an - // observer in the space) we test if the light ray is hitting the atmosphere - vec3 x0 = fragPosObj; - float r0 = length(fragPosObj); - float invr0 = 1.0/r0; - float muSun0 = dot(fragPosObj, s) * invr0; - //vec3 x0 = x + float(pixelDepth) * v; - float mu0 = dot(x0, v) * invr0; + if ((pixelDepth > INTERPOLATION_EPS) && (pixelDepth < maxLength)) { + t = float(pixelDepth); + groundHit = true; + + // Transmittance from point r, direction mu, distance t + // By Analytical calculation + // attenuation = analyticTransmittance(r, mu, t); + // JCC: change from analytical to LUT transmittance to avoid + // acme on planet surface when looking from far away. (11/02/2017) + attenuation = transmittance(r, mu, t); + + // Here we use the idea of S[L](a->b) = S[L](b->a), and get the S[L](x0, v, s) + // Then we calculate S[L] = S[L]|x - T(x, x0)*S[L]|x0 + // The "infinite" ray hist something inside the atmosphere, so we need to remove + // the unsused contribution to the final radiance. + vec4 inscatterFromSurface = texture4D(inscatterTexture, r0, mu0, muSun0, nu); + inscatterRadiance = max(inscatterRadiance - attenuation.rgbr * inscatterFromSurface, 0.0); - if ((pixelDepth > INTERPOLATION_EPS) && (pixelDepth < maxLength)) { - t = float(pixelDepth); - groundHit = true; - - // Transmittance from point r, direction mu, distance t - // By Analytical calculation - //attenuation = analyticTransmittance(r, mu, t); - // JCC: change from analytical to LUT transmittance to avoid - // acme on planet surface when looking from far away. (11/02/2017) - attenuation = transmittance(r, mu, t); - - // Here we use the idea of S[L](a->b) = S[L](b->a), and get the S[L](x0, v, s) - // Then we calculate S[L] = S[L]|x - T(x, x0)*S[L]|x0 - // The "infinite" ray hist something inside the atmosphere, so we need to remove - // the unsused contribution to the final radiance. - vec4 inscatterFromSurface = texture4D(inscatterTexture, r0, mu0, muSun0, nu); - inscatterRadiance = max(inscatterRadiance - attenuation.rgbr * inscatterFromSurface, 0.0); + // We set the irradianceFactor to 1.0 so the reflected irradiance will be considered + // when calculating the reflected light on the ground. + irradianceFactor = 1.0; + } + else { + attenuation = analyticTransmittance(r, mu, t); + groundHit = false; + } - // We set the irradianceFactor to 1.0 so the reflected irradiance will be considered - // when calculating the reflected light on the ground. - irradianceFactor = 1.0; - } - else { - attenuation = analyticTransmittance(r, mu, t); - //attenuation = transmittance(r, mu, t); - groundHit = false; - } + // cos(PI-thetaH) = dist/r + // cos(thetaH) = - dist/r + // muHorizon = -sqrt(r^2-Rg^2)/r = -sqrt(1-(Rg/r)^2) + float muHorizon = -sqrt(1.0 - Rg2 / r2); - // cos(PI-thetaH) = dist/r - // cos(thetaH) = - dist/r - // muHorizon = -sqrt(r^2-Rg^2)/r = -sqrt(1-(Rg/r)^2) - float muHorizon = -sqrt(1.0f - (Rg2 / r2)); + // In order to avoid imprecision problems near horizon, we interpolate between two + // points: above and below horizon + if (abs(mu - muHorizon) < INTERPOLATION_EPS) { + // We want an interpolation value close to 1/2, so the contribution of each radiance + // value is almost the same or it has a heavy weight if from above or + // below horizon + float interpolationValue = (mu - muHorizon + INTERPOLATION_EPS) / (2.0 * INTERPOLATION_EPS); - // In order to avoid imprecision problems near horizon, - // we interpolate between two points: above and below horizon - if (abs(mu - muHorizon) < INTERPOLATION_EPS) { - // We want an interpolation value close to 1/2, so the - // contribution of each radiance value is almost the same - // or it has a heavy weight if from above or below horizon - float interpolationValue = ((mu - muHorizon) + INTERPOLATION_EPS) / (2.0f * INTERPOLATION_EPS); + // Above Horizon + mu = muHorizon - INTERPOLATION_EPS; + // r0 = sqrt(r * r + t * t + 2.0f * r * t * mu); + // From cosine law where t = distance between x and x0 + // r0^2 = r^2 + t^2 - 2 * r * t * cos(PI-theta) + // r0 = sqrt(r2 + t2 + 2.0f * r * t * mu); + float halfCossineLaw1 = r2 + (t * t); + float halfCossineLaw2 = 2.0 * r * t; + r0 = sqrt(halfCossineLaw1 + halfCossineLaw2 * mu); + + // From the dot product: cos(theta0) = (x0 dot v)/(||ro||*||v||) + // mu0 = ((x + t) dot v) / r0 + // mu0 = (x dot v + t dot v) / r0 + // mu0 = (r*mu + t) / r0 + mu0 = (r * mu + t) * (1.0 / r0); + + vec4 inScatterAboveX = texture4D(inscatterTexture, r, mu, muSun, nu); + vec4 inScatterAboveXs = texture4D(inscatterTexture, r0, mu0, muSun0, nu); + // Attention for the attenuation.r value applied to the S_Mie + vec4 inScatterAbove = max(inScatterAboveX - attenuation.rgbr * inScatterAboveXs, 0.0); - //float t2 = t * t; - - // Above Horizon - mu = muHorizon - INTERPOLATION_EPS; - //r0 = sqrt(r * r + t * t + 2.0f * r * t * mu); - // From cosine law where t = distance between x and x0 - // r0^2 = r^2 + t^2 - 2 * r * t * cos(PI-theta) - //r0 = sqrt(r2 + t2 + 2.0f * r * t * mu); - float halfCossineLaw1 = r2 + (t * t); - float halfCossineLaw2 = 2.0f * r * t; - r0 = sqrt(halfCossineLaw1 + halfCossineLaw2 * mu); - - float invr0 = 1.0/r0; - // From the dot product: cos(theta0) = (x0 dot v)/(||ro||*||v||) - // mu0 = ((x + t) dot v) / r0 - // mu0 = (x dot v + t dot v) / r0 - // mu0 = (r*mu + t) / r0 - mu0 = (r * mu + t) * invr0; - - vec4 inScatterAboveX = texture4D(inscatterTexture, r, mu, muSun, nu); - vec4 inScatterAboveXs = texture4D(inscatterTexture, r0, mu0, muSun0, nu); - // Attention for the attenuation.r value applied to the S_Mie - vec4 inScatterAbove = max(inScatterAboveX - attenuation.rgbr * inScatterAboveXs, 0.0f); + // Below Horizon + mu = muHorizon + INTERPOLATION_EPS; + //r0 = sqrt(r2 + t2 + 2.0f * r * t * mu); + r0 = sqrt(halfCossineLaw1 + halfCossineLaw2 * mu); + + mu0 = (r * mu + t) * (1.0 / r0); + + vec4 inScatterBelowX = texture4D(inscatterTexture, r, mu, muSun, nu); + vec4 inScatterBelowXs = texture4D(inscatterTexture, r0, mu0, muSun0, nu); + // Attention for the attenuation.r value applied to the S_Mie + vec4 inScatterBelow = max(inScatterBelowX - attenuation.rgbr * inScatterBelowXs, 0.0); - // Below Horizon - mu = muHorizon + INTERPOLATION_EPS; - //r0 = sqrt(r2 + t2 + 2.0f * r * t * mu); - r0 = sqrt(halfCossineLaw1 + halfCossineLaw2 * mu); - invr0 = 1.0/r0; - - mu0 = (r * mu + t) * invr0; - - vec4 inScatterBelowX = texture4D(inscatterTexture, r, mu, muSun, nu); - vec4 inScatterBelowXs = texture4D(inscatterTexture, r0, mu0, muSun0, nu); - // Attention for the attenuation.r value applied to the S_Mie - vec4 inScatterBelow = max(inScatterBelowX - attenuation.rgbr * inScatterBelowXs, 0.0); + // Interpolate between above and below inScattering radiance + inscatterRadiance = mix(inScatterAbove, inScatterBelow, interpolationValue); + } - // Interpolate between above and below inScattering radiance - inscatterRadiance = mix(inScatterAbove, inScatterBelow, interpolationValue); - } - - // The w component of inscatterRadiance has stored the Cm,r value (Cm = Sm[L0]) - // So, we must reintroduce the Mie inscatter by the proximity rule as described in the - // paper by Bruneton and Neyret in "Angular precision" paragraph: - - // Hermite interpolation between two values - // This step is done because imprecision problems happen when the Sun is slightly below - // the horizon. When this happens, we avoid the Mie scattering contribution. - inscatterRadiance.w *= smoothstep(0.0f, 0.02f, muSun); - vec3 inscatterMie = inscatterRadiance.rgb * inscatterRadiance.a / max(inscatterRadiance.r, 1e-4) * + // The w component of inscatterRadiance has stored the Cm,r value (Cm = Sm[L0]) + // So, we must reintroduce the Mie inscatter by the proximity rule as described in the + // paper by Bruneton and Neyret in "Angular precision" paragraph: + + // Hermite interpolation between two values + // This step is done because imprecision problems happen when the Sun is slightly + // below the horizon. When this happens, we avoid the Mie scattering contribution + inscatterRadiance.w *= smoothstep(0.0, 0.02, muSun); + vec3 inscatterMie = + inscatterRadiance.rgb * inscatterRadiance.a / max(inscatterRadiance.r, 1e-4) * (betaRayleigh.r / betaRayleigh); - - radiance = max(inscatterRadiance.rgb * rayleighPhase + inscatterMie * miePhase, 0.0f); - // Finally we add the Lsun (all calculations are done with no Lsun so - // we can change it on the fly with no precomputations) - // return radiance * sunRadiance; - vec3 finalScatteringRadiance = radiance * sunIntensity; - - if (groundHit) { - return finalScatteringRadiance; - } - else { - //return ((r-Rg) * invRtMinusRg)*spaceColor.rgb + finalScatteringRadiance; - return spaceColor.rgb + finalScatteringRadiance; - // return attenuation * spaceColor.rgb + - // (vec3(1.0) - attenuation) * finalScatteringRadiance; - } + radiance = max(inscatterRadiance.rgb * rayleighPhase + inscatterMie * miePhase, 0.0); + + // Finally we add the Lsun (all calculations are done with no Lsun so we can change it + // on the fly with no precomputations) + vec3 finalScatteringRadiance = radiance * sunIntensity; + + if (groundHit) { + return finalScatteringRadiance; + } + else { + return spaceColor.rgb + finalScatteringRadiance; + } } /* - * Calculates the light reflected in the view direction comming from other - * light rays integrated over the hemispehre plus the direct light (L0) from Sun. + * Calculates the light reflected in the view direction comming from other light rays + * integrated over the hemispehre plus the direct light (L0) from Sun. * Following the paper: R[L]= R[L0]+R[L*] - * The the ray is x + tv, v the view direction, s is the sun direction, - * r and mu the position and zenith cosine angle as in the paper. - * As for all calculations in the atmosphere, the center of the coordinate system - * is the planet's center of coordiante system, i.e., the planet's position is (0,0,0). + * The ray is x + tv, v the view direction, s is the sun direction, r and mu the position + * and zenith cosine angle as in the paper. + * As for all calculations in the atmosphere, the center of the coordinate system is the + * planet's center of coordiante system, i.e., the planet's position is (0,0,0). * Arguments: * x := camera position * t := ray displacement variable. Here, differently from the inScatter light calculation, - * the position of the camera is already offset (on top of atmosphere) or inside - * the atmosphere. + * the position of the camera is already offset (on top of atmosphere) or inside + * the atmosphere * v := view direction (ray's direction) (normalized) * s := Sun direction (normalized) - * r := ||x|| inside atmosphere (or top of atmosphere). r <= Rt here. * mu := cosine of the zenith view angle * attenuationXtoX0 := transmittance T(x,x0) */ -vec3 groundColor(vec3 x, float t, vec3 v, vec3 s, float r, - float mu, vec3 attenuationXtoX0, vec4 groundColor, - vec3 normal, float irradianceFactor, - float waterReflectance, float sunIntensity) +vec3 groundColor(vec3 x, float t, vec3 v, vec3 s, vec3 attenuationXtoX0, vec3 groundColor, + vec3 normal, float irradianceFactor, float waterReflectance, + float sunIntensity) { - vec3 reflectedRadiance = vec3(0.0f); + vec3 reflectedRadiance = vec3(0.0); - // First we obtain the ray's end point on the surface - vec3 x0 = x + t * v; - float r0 = length(x0); - // Normal of intersection point. - // Normal must be normalized. - vec3 n = normal; - //vec4 groundReflectance = groundColor * vec4(.37); - vec4 groundReflectance = groundColor * - vec4(groundRadianceEmittion, groundRadianceEmittion, groundRadianceEmittion, 1.0f); + // First we obtain the ray's end point on the surface + float r0 = length(x + t * v); - // L0 is not included in the irradiance texture. - // We first calculate the light attenuation from the top of the atmosphere - // to x0. - float dotNS = dot(n, s); - float muSun = max(dotNS, 0.0f); + vec3 groundReflectance = groundColor * groundRadianceEmission; - // Is direct Sun light arriving at x0? If not, there is no direct light from Sun (shadowed) - vec3 transmittanceL0 = muSun < -sqrt(1.0f - (Rg2 / (r0 * r0))) ? - vec3(0.0f) : transmittanceLUT(r0, muSun); - // E[L*] at x0 - vec3 irradianceReflected = irradiance(irradianceTexture, r0, muSun) * irradianceFactor; + // L0 is not included in the irradiance texture. + // We first calculate the light attenuation from the top of the atmosphere to x0 + float dotNS = dot(normal, s); + float muSun = max(dotNS, 0.0); - // R[L0] + R[L*] - // vec3 groundRadiance = (dotNS < -0.2f ? groundReflectance.rgb * 15 : groundReflectance.rgb) * - // (muSun * transmittanceL0 + irradianceReflected) * sunIntensity / M_PI; + // Is direct Sun light arriving at x0? If not, there is no direct light from Sun (shadowed) + vec3 transmittanceL0 = + muSun < -sqrt(1.0 - (Rg2 / (r0 * r0))) ? vec3(0.0) : transmittance(r0, muSun); - vec3 groundRadiance; - vec3 RLStar = (muSun * transmittanceL0 + irradianceReflected) * sunIntensity / M_PI; - if (dotNS < 0.05f) { - groundRadiance = groundReflectance.rgb * mix(30.0f, 1.0f, smoothstep(-1.0f, 0.05f, dotNS)) * RLStar; - } - else { - groundRadiance = groundReflectance.rgb * RLStar; - } + // E[L*] at x0 + vec3 irradianceReflected = irradiance(irradianceTexture, r0, muSun) * irradianceFactor; - // Specular reflection from sun on oceans and rivers - if ((waterReflectance > 0.1f) && /*(dotNS > -0.2f)*/(muSun > 0.0f)) { - vec3 h = normalize(s - v); - // Fresnell Schlick's approximation - float fresnel = 0.02f + 0.98f * pow(1.0f - dot(-v, h), 5.0f); - // Walter BRDF approximation - float waterBrdf = fresnel * pow(max(dot(h, n), 0.0f), 150.0f); - // Adding Fresnell and Water BRDFs approximation to the final surface color - // (After adding the sunRadiance and the attenuation of the Sun through atmosphere) - groundRadiance += waterReflectance * max(waterBrdf, 0.0f) * transmittanceL0 * sunIntensity; - } - //return groundRadiance; - // Finally, we attenuate the surface Radiance from the the point x0 to the camera location. - reflectedRadiance = attenuationXtoX0 * groundRadiance; - - // Returns reflectedRadiance = 0.0 if the ray doesn't hit the ground. - return reflectedRadiance; + // R[L0] + R[L*] + vec3 RLStar = (muSun * transmittanceL0 + irradianceReflected) * sunIntensity / M_PI; + vec3 groundRadiance = + dotNS < 0.05 ? + groundReflectance * mix(30.0, 1.0, smoothstep(-1.0, 0.05, dotNS)) * RLStar : + groundReflectance * RLStar; + + // Specular reflection from sun on oceans and rivers + if ((waterReflectance > 0.1) && (muSun > 0.0)) { + vec3 h = normalize(s - v); + // Fresnell Schlick's approximation + float fresnel = 0.02 + 0.98 * pow(1.0 - dot(-v, h), 5.0); + // Walter BRDF approximation + float waterBrdf = fresnel * pow(max(dot(h, normal), 0.0), 150.0); + // Adding Fresnell and Water BRDFs approximation to the final surface color + // after adding the sunRadiance and the attenuation of the Sun through atmosphere + groundRadiance += waterReflectance * max(waterBrdf, 0.0) * transmittanceL0 * sunIntensity; + } + + // Finally, we attenuate the surface Radiance from the point x0 to the camera location + reflectedRadiance = attenuationXtoX0 * groundRadiance; + + // Returns reflectedRadiance = 0.0 if the ray doesn't hit the ground. + return reflectedRadiance; } /* - * Calculates the Sun color. - * The the ray is x + tv, v the view direction, s is the sun direction, - * r and mu the position and zenith cosine angle as in the paper. - * As for all calculations in the atmosphere, the center of the coordinate system - * is the planet's center of coordiante system, i.e., the planet's position is (0,0,0). - * Arguments: - * x := camera position - * t := ray displacement variable. Here, differently from the inScatter light calculation, - * the position of the camera is already offset (on top of atmosphere) or inside - * the atmosphere. + * Calculates the Sun color. The ray is x + tv, v the view direction, s is the sun + * direction, r and mu the position and zenith cosine angle as in the paper. As for all + * calculations in the atmosphere, the center of the coordinate system is the planet's + * center of coordiante system, i.e., the planet's position is (0,0,0). Arguments: * v := view direction (ray's direction) (normalized) * s := Sun direction (normalized) * r := ||x|| inside atmosphere (or top of atmosphere). r <= Rt here. * mu := cosine of the zenith view angle * attenuation := transmittance T(x,x0) */ -vec3 sunColor(vec3 x, float t, vec3 v, vec3 s, float r, float mu, float irradianceFactor) -{ - vec3 transmittance = (r <= Rt) ? ( mu < -sqrt(1.0f - Rg2/(r*r)) ? - vec3(0.0f) : transmittanceLUT(r, mu)) : vec3(1.0f); - // JCC: Change this function to a impostor texture with gaussian decay color weighted - // by tge sunRadiance, transmittance and irradianceColor (11/03/2017) - float sunFinalColor = smoothstep(cos(M_PI / 500.0f), cos(M_PI / 900.0f), dot(v, s)) * - sunRadiance * (1.0f - irradianceFactor); +vec3 sunColor(vec3 v, vec3 s, float r, float mu, float irradianceFactor) { + vec3 tm = vec3(1.0); + if (r <= Rt) { + tm = mu < -sqrt(1.0 - Rg2 / (r * r)) ? vec3(0.0) : transmittance(r, mu); + } + // JCC: Change this function to a impostor texture with gaussian decay color weighted + // by the sunRadiance, transmittance and irradianceColor (11/03/2017) + float sunFinalColor = smoothstep(cos(M_PI / 500.0), cos(M_PI / 900.0), dot(v, s)) * + sunRadiance * (1.0 - irradianceFactor); - return transmittance * sunFinalColor; + return tm * sunFinalColor; } void main() { - if (cullAtmosphere == 0) { - vec4 atmosphereFinalColor = vec4(0.0f); - int nSamples = 1; - - // First we determine if the pixel is complex (different fragments on it) - bool complex = false; - vec4 oldColor, currentColor; - vec4 colorTexture; - - colorTexture = texture(mainColorTexture, texCoord); - - // Color from G-Buffer - vec4 color = colorTexture; - // Ray in object space - dRay ray; - dvec4 planetPositionObjectCoords = dvec4(0.0); - dvec4 cameraPositionInObject = dvec4(0.0); - - // Get the ray from camera to atm in object space - dCalculateRayRenderableGlobe(ray, planetPositionObjectCoords, - cameraPositionInObject); - - bool insideATM = false; - double offset = 0.0; // in Km - double maxLength = 0.0; // in Km + // Modify the texCoord based on the Viewport and Resolution. This modification is + // necessary in case of side-by-side stereo as we only want to access the part of the + // feeding texture that we are currently responsible for. Otherwise we would map the + // entire feeding texture into our half of the result texture, leading to a doubling + // of the "missing" half. If you don't believe me, load a configuration file with the + // side_by_side stereo mode enabled, disable FXAA, and remove this modification. + // The same calculation is done in the FXAA shader and the HDR resolving + vec2 st = texCoord; + st.x = st.x / (resolution.x / viewport[2]) + (viewport[0] / resolution.x); + st.y = st.y / (resolution.y / viewport[3]) + (viewport[1] / resolution.y); - bool intersectATM = false; + if (cullAtmosphere == 1) { + renderTarget = texture(mainColorTexture, st); + return; + } - intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, ray, - Rt - (ATM_EPSILON * 0.001), insideATM, offset, maxLength); - - if ( intersectATM ) { - // Now we check is if the atmosphere is occluded, i.e., if the distance to the pixel - // in the G-Buffer positions is less than the distance to the atmosphere then the atmosphere - // is occluded - // Fragments positions into G-Buffer are written in SGCT Eye Space (View plus Camera Rig Coords) - // when using their positions later, one must convert them to the planet's coords - - // ======================= - // Get data from G-Buffer - // ======================= + vec4 atmosphereFinalColor = vec4(0.0); + int nSamples = 1; + + // Color from G-Buffer + vec4 color = texture(mainColorTexture, st); + + // Get the ray from camera to atm in object space + Ray ray = calculateRayRenderableGlobe(texCoord); + + double offset = 0.0; // in KM + double maxLength = 0.0; // in KM + bool intersect = atmosphereIntersection(ray, Rt - (ATM_EPSILON * 0.001), offset, maxLength); + if (!intersect) { + renderTarget = color; + return; + } - // Normal is stored in SGCT View Space and transformed to the current object space - vec4 normalViewSpaceAndWaterReflectance = texture(mainNormalTexture, texCoord); - dvec4 normalViewSpace = vec4(normalViewSpaceAndWaterReflectance.xyz, 0.0); - dvec4 normalWorldSpace = dSGCTViewToWorldMatrix * normalViewSpace; - vec4 normal = vec4(dInverseModelTransformMatrix * normalWorldSpace); - normal.xyz = normalize(normal.xyz); - normal.w = normalViewSpaceAndWaterReflectance.w; + // Now we check is if the atmosphere is occluded, i.e., if the distance to the pixel in + // the G-Buffer positions is less than the distance to the atmosphere then the + // atmosphere is occluded. Fragments positions into G-Buffer are written in SGCT Eye + // Space (View plus Camera Rig Coords) when using their positions later, one must + // convert them to the planet's coords - // Data in the mainPositionTexture are written in view space (view plus camera rig) - vec4 position = texture(mainPositionTexture, texCoord); + // + // Get data from G-Buffer - // OS Eye to World coords - dvec4 positionWorldCoords = dSGCTViewToWorldMatrix * position; + // Normal is stored in SGCT View Space and transformed to the current object space + vec4 normalViewSpaceAndWaterReflectance = texture(mainNormalTexture, st); + dvec4 normalViewSpace = vec4(normalViewSpaceAndWaterReflectance.xyz, 0.0); + dvec4 normalWorldSpace = dSGCTViewToWorldMatrix * normalViewSpace; + vec4 normal = vec4(dInverseModelTransformMatrix * normalWorldSpace); + normal.xyz = normalize(normal.xyz); + normal.w = normalViewSpaceAndWaterReflectance.w; - // World to Object (Normal and Position in meters) - dvec4 positionObjectsCoords = dInverseModelTransformMatrix * positionWorldCoords; + // Data in the mainPositionTexture are written in view space (view plus camera rig) + vec4 position = texture(mainPositionTexture, st); - - // Distance of the pixel in the gBuffer to the observer - // JCC (12/12/2017): AMD distance function is buggy. - //double pixelDepth = distance(cameraPositionInObject.xyz, positionObjectsCoords.xyz); - double pixelDepth = length(cameraPositionInObject.xyz - positionObjectsCoords.xyz); - - // JCC (12/13/2017): Trick to remove floating error in texture. - // We see a squared noise on planet's surface when seeing the planet - // from far away. - float dC = float(length(cameraPositionInObject.xyz)); - float x1 = 1e8; - if (dC > x1) { - pixelDepth += 1000.0; - float alpha = 1000.0; - float beta = 1000000.0; - float x2 = 1e9; - float diffGreek = beta - alpha; - float diffDist = x2 - x1; - float varA = diffGreek/diffDist; - float varB = (alpha - varA * x1); - pixelDepth += double(varA * dC + varB); - } + // OS Eye to World coords + dvec4 positionWorldCoords = dSGCTViewToWorldMatrix * position; - // All calculations are done in Km: - pixelDepth *= 0.001; - positionObjectsCoords.xyz *= 0.001; + // World to Object (Normal and Position in meters) + dvec4 positionObjectsCoords = dInverseModelTransformMatrix * positionWorldCoords; - if (pixelDepth < offset) { - // ATM Occluded - Something in fron of ATM. - atmosphereFinalColor += color; - } - else { - // Following paper nomenclature - double t = offset; - vec3 attenuation; + // Distance of the pixel in the gBuffer to the observer + // JCC (12/12/2017): AMD distance function is buggy. + //double pixelDepth = distance(cameraPositionInObject.xyz, positionObjectsCoords.xyz); + double pixelDepth = length(dCamPosObj.xyz - positionObjectsCoords.xyz); + + // JCC (12/13/2017): Trick to remove floating error in texture. + // We see a squared noise on planet's surface when seeing the planet from far away + float dC = float(length(dCamPosObj.xyz)); + const float x1 = 1e8; + if (dC > x1) { + pixelDepth += 1000.0; + const float alpha = 1000.0; + const float beta = 1000000.0; + const float x2 = 1e9; + const float diffGreek = beta - alpha; + const float diffDist = x2 - x1; + const float varA = diffGreek / diffDist; + const float varB = (alpha - varA * x1); + pixelDepth += double(varA * dC + varB); + } - // Moving observer from camera location to top atmosphere - // If the observer is already inside the atm, offset = 0.0 - // and no changes at all. - vec3 x = vec3(ray.origin.xyz + t*ray.direction.xyz); - float r = 0.0f;//length(x); - vec3 v = vec3(ray.direction.xyz); - float mu = 0.0f;//dot(x, v) / r; - vec3 s = vec3(sunDirectionObj); - float tF = float(maxLength - t); + // All calculations are done in KM: + pixelDepth *= 0.001; + positionObjectsCoords.xyz *= 0.001; - // Because we may move the camera origin to the top of atmosphere - // we also need to adjust the pixelDepth for tdCalculateRayRenderableGlobe' offset so the - // next comparison with the planet's ground make sense: - pixelDepth -= offset; - - dvec4 onATMPos = dModelTransformMatrix * dvec4(x * 1000.0, 1.0); - vec4 eclipseShadowATM = calcShadow(shadowDataArray, onATMPos.xyz, false); - float sunIntensityInscatter = sunRadiance * eclipseShadowATM.x; + if (pixelDepth < offset) { + // ATM Occluded - Something in front of ATM + renderTarget = color; + return; + } - float irradianceFactor = 0.0; + // Following paper nomenclature + double t = offset; + vec3 attenuation; - bool groundHit = false; - vec3 inscatterColor = inscatterRadiance(x, tF, irradianceFactor, v, - s, r, mu, attenuation, - vec3(positionObjectsCoords.xyz), - groundHit, maxLength, pixelDepth, - color, sunIntensityInscatter); - vec3 groundColorV = vec3(0.0); - vec3 sunColorV = vec3(0.0); - if (groundHit) { - vec4 eclipseShadowPlanet = calcShadow(shadowDataArray, positionWorldCoords.xyz, true); - float sunIntensityGround = sunRadiance * eclipseShadowPlanet.x; - groundColorV = groundColor(x, tF, v, s, r, mu, attenuation, - color, normal.xyz, irradianceFactor, - normal.a, sunIntensityGround); - } - else { - // In order to get better performance, we are not tracing - // multiple rays per pixel when the ray doesn't intersect - // the ground. - sunColorV = sunColor(x, tF, v, s, r, mu, irradianceFactor); - } - - // Final Color of ATM plus terrain: - vec4 finalRadiance = vec4(inscatterColor + groundColorV + sunColorV, 1.0); + // Moving observer from camera location to top atmosphere. If the observer is already + // inside the atm, offset = 0.0 and no changes at all + vec3 x = vec3(ray.origin + t * ray.direction); + float r = 0.0; // length(x); + vec3 v = vec3(ray.direction); + float mu = 0.0; // dot(x, v) / r; + vec3 s = vec3(sunDirectionObj); + float tF = float(maxLength - t); - atmosphereFinalColor += finalRadiance; - } - } - else { // no intersection - // Buffer color - atmosphereFinalColor += color; - } - + // Because we may move the camera origin to the top of atmosphere we also need to + // adjust the pixelDepth for tdCalculateRayRenderableGlobe' offset so the next + // comparison with the planet's ground make sense: + pixelDepth -= offset; + + dvec3 onATMPos = (dModelTransformMatrix * dvec4(x * 1000.0, 1.0)).xyz; + float eclipseShadowATM = calcShadow(shadowDataArray, onATMPos, false); + float sunIntensityInscatter = sunRadiance * eclipseShadowATM; - renderTarget = atmosphereFinalColor; - } - else { // culling - vec4 bColor = texture(mainColorTexture, texCoord); - renderTarget = bColor; - } + float irradianceFactor = 0.0; + + bool groundHit = false; + vec3 inscatterColor = inscatterRadiance(x, tF, irradianceFactor, v, s, r, mu, + attenuation, vec3(positionObjectsCoords.xyz), groundHit, maxLength, pixelDepth, + color, sunIntensityInscatter); + vec3 atmColor = vec3(0.0); + if (groundHit) { + float eclipseShadowPlanet = calcShadow(shadowDataArray, positionWorldCoords.xyz, true); + float sunIntensityGround = sunRadiance * eclipseShadowPlanet; + atmColor = groundColor(x, tF, v, s, attenuation, color.rgb, normal.xyz, + irradianceFactor, normal.w, sunIntensityGround); + } + else { + // In order to get better performance, we are not tracing multiple rays per pixel + // when the ray doesn't intersect the ground + atmColor = sunColor(v, s, r, mu, irradianceFactor); + } + + // Final Color of ATM plus terrain: + vec4 finalRadiance = vec4(inscatterColor + atmColor, 1.0); + renderTarget = finalRadiance; } diff --git a/modules/atmosphere/shaders/atmosphere_deferred_vs.glsl b/modules/atmosphere/shaders/atmosphere_deferred_vs.glsl index cbe4d8663f..3e350f6e91 100644 --- a/modules/atmosphere/shaders/atmosphere_deferred_vs.glsl +++ b/modules/atmosphere/shaders/atmosphere_deferred_vs.glsl @@ -26,11 +26,9 @@ layout(location = 0) in vec4 in_position; -out vec3 interpolatedNDCPos; out vec2 texCoord; void main() { - texCoord = 0.5 + in_position.xy * 0.5; - interpolatedNDCPos = in_position.xyz; - gl_Position = in_position; + texCoord = in_position.xy / 2.0 + 0.5; + gl_Position = in_position; } diff --git a/modules/atmosphere/shaders/inScattering_sup_calc_gs.glsl b/modules/atmosphere/shaders/calculation_gs.glsl similarity index 92% rename from modules/atmosphere/shaders/inScattering_sup_calc_gs.glsl rename to modules/atmosphere/shaders/calculation_gs.glsl index 7cccacb76a..36a7459ee7 100644 --- a/modules/atmosphere/shaders/inScattering_sup_calc_gs.glsl +++ b/modules/atmosphere/shaders/calculation_gs.glsl @@ -30,10 +30,10 @@ layout (triangles) in; layout (triangle_strip, max_vertices = 3) out; void main() { - for (int n = 0; n < gl_in.length(); ++n) { - gl_Position = gl_in[n].gl_Position; - gl_Layer = layer; - EmitVertex(); - } - EndPrimitive(); + for (int n = 0; n < gl_in.length(); ++n) { + gl_Position = gl_in[n].gl_Position; + gl_Layer = layer; + EmitVertex(); + } + EndPrimitive(); } diff --git a/modules/atmosphere/shaders/deltaS_calc_vs.glsl b/modules/atmosphere/shaders/calculation_vs.glsl similarity index 98% rename from modules/atmosphere/shaders/deltaS_calc_vs.glsl rename to modules/atmosphere/shaders/calculation_vs.glsl index 1ca953fe3c..be225fa6a6 100644 --- a/modules/atmosphere/shaders/deltaS_calc_vs.glsl +++ b/modules/atmosphere/shaders/calculation_vs.glsl @@ -27,5 +27,5 @@ layout(location = 0) in vec3 in_position; void main() { - gl_Position = vec4(in_position, 1.0); + gl_Position = vec4(in_position, 1.0); } diff --git a/modules/atmosphere/shaders/deltaE_calc_vs.glsl b/modules/atmosphere/shaders/deltaE_calc_vs.glsl deleted file mode 100644 index d5a1e43e38..0000000000 --- a/modules/atmosphere/shaders/deltaE_calc_vs.glsl +++ /dev/null @@ -1,31 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version __CONTEXT__ - -layout(location = 0) in vec3 in_position; - -void main() { - gl_Position = vec4(in_position, 1.0); -} \ No newline at end of file diff --git a/modules/atmosphere/shaders/deltaJ_calc_fs.glsl b/modules/atmosphere/shaders/deltaJ_calc_fs.glsl index badfa8934d..37bacbe3b9 100644 --- a/modules/atmosphere/shaders/deltaJ_calc_fs.glsl +++ b/modules/atmosphere/shaders/deltaJ_calc_fs.glsl @@ -26,7 +26,7 @@ #include "atmosphere_common.glsl" -out vec4 renderTarget1; +out vec4 renderTarget; uniform float r; uniform vec4 dhdH; @@ -38,14 +38,14 @@ uniform sampler3D deltaSMTexture; uniform int firstIteraction; // -- Spherical Coordinates Steps. phi e [0,2PI] and theta e [0, PI] -const float stepPhi = (2.0f * M_PI) / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES); +const float stepPhi = (2.0 * M_PI) / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES); const float stepTheta = M_PI / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES); -void inscatter(float r, float mu, float muSun, float nu, inout vec3 radianceJ) { +vec3 inscatter(float r, float mu, float muSun, float nu) { // Be sure to not get a cosine or height out of bounds - r = clamp(r, Rg, Rt); - mu = clamp(mu, -1.0f, 1.0f); - muSun = clamp(muSun, -1.0f, 1.0f); + r = clamp(r, Rg, Rt); + mu = clamp(mu, -1.0, 1.0); + muSun = clamp(muSun, -1.0, 1.0); // s sigma | theta v // \ | / @@ -55,9 +55,9 @@ void inscatter(float r, float mu, float muSun, float nu, inout vec3 radianceJ) { // \ | / cos(theta) = mu // \ | / cos(sigma) = muSun // \|/ cos(ni) = nu - float mu2 = mu * mu; - float muSun2 = muSun * muSun; - float sinThetaSinSigma = sqrt(1.0f - mu2) * sqrt(1.0f - muSun2); + float mu2 = mu * mu; + float muSun2 = muSun * muSun; + float sinThetaSinSigma = sqrt(1.0 - mu2) * sqrt(1.0 - muSun2); // cos(sigma + theta) = cos(theta)cos(sigma)-sin(theta)sin(sigma) // cos(ni) = nu = mu * muSun - sqrt(1.0f - mu*mu)*sqrt(1.0 - muSun*muSun) // sin(theta) = sqrt(1.0 - mu*mu) // Now we make sure the angle between vec(s) and vec(v) is in the right range: @@ -67,8 +67,8 @@ void inscatter(float r, float mu, float muSun, float nu, inout vec3 radianceJ) { // theta is the angle between vec(v) and x // cos(PI-theta) = d/r // -cos(theta) = sqrt(r*r-Rg*Rg)/r - float Rg2 = Rg * Rg; - float r2 = r * r; + float Rg2 = Rg * Rg; + float r2 = r * r; float cosHorizon = -sqrt(r2 - Rg2)/r; // Now we get vec(v) and vec(s) from mu, muSun and nu: @@ -80,7 +80,7 @@ void inscatter(float r, float mu, float muSun, float nu, inout vec3 radianceJ) { // sin(PI-theta) = x/||v|| => x = sin(theta) =? x = sqrt(1-mu*mu) // cos(PI-theta) = z/||v|| => z = cos(theta) = mu // v.y = 0 because ||v|| = 1 - vec3 v = vec3(sqrt(1.0 - mu2), 0.0, mu); + vec3 v = vec3(sqrt(1.0 - mu2), 0.0, mu); // To obtain vec(s), we use the following properties: // ||vec(s)|| = 1, ||vec(v)|| = 1 @@ -89,7 +89,7 @@ void inscatter(float r, float mu, float muSun, float nu, inout vec3 radianceJ) { // So, from vec(s) dot vec(v) = cos(ni) = nu we have, // s.x*v.x +s.y*v.y + s.z*v.z = nu // s.x = (nu - s.z*v.z)/v.x = (nu - mu*muSun)/v.x - float sx = (v.x == 0.0) ? 0.0 : (nu - muSun * mu) / v.x; + float sx = (v.x == 0.0) ? 0.0 : (nu - muSun * mu) / v.x; // Also, ||vec(s)|| = 1, so: // 1 = sqrt(s.x*s.x + s.y*s.y + s.z*s.z) // s.y = sqrt(1 - s.x*s.x - s.z*s.z) = sqrt(1 - s.x*s.x - muSun*muSun) @@ -97,21 +97,21 @@ void inscatter(float r, float mu, float muSun, float nu, inout vec3 radianceJ) { // In order to integrate over 4PI, we scan the sphere using the spherical coordinates // previously defined - for (int theta_i = 0; theta_i < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++theta_i) { - float theta = (float(theta_i) + 0.5f) * stepTheta; - float cosineTheta = cos(theta); - float cosineTheta2 = cosineTheta * cosineTheta; - float distanceToGround = 0.0f; - float groundReflectance = 0.0f; - vec3 groundTransmittance = vec3(0.0f); + for (int theta_i = 0; theta_i < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; theta_i++) { + float theta = (float(theta_i) + 0.5) * stepTheta; + float cosineTheta = cos(theta); + float cosineTheta2 = cosineTheta * cosineTheta; + float distanceToGround = 0.0; + float groundReflectance = 0.0; + vec3 groundTransmittance = vec3(0.0); // If the ray w can see the ground we must compute the transmittance // effect from the starting point x to the ground point in direction -vec(v): - if ( cosineTheta < cosHorizon ) { // ray hits ground + if (cosineTheta < cosHorizon) { // ray hits ground // AverageGroundReflectance e [0,1] groundReflectance = AverageGroundReflectance / M_PI; // From cosine law: Rg*Rg = r*r + distanceToGround*distanceToGround - 2*r*distanceToGround*cos(PI-theta) - distanceToGround = -r * cosineTheta - sqrt(r2 * (cosineTheta2 - 1.0f) + Rg2); + distanceToGround = -r * cosineTheta - sqrt(r2 * (cosineTheta2 - 1.0) + Rg2); // | // | theta // | @@ -125,86 +125,84 @@ void inscatter(float r, float mu, float muSun, float nu, inout vec3 radianceJ) { // cos(alpha) = (-r*distG*cos(theta) - distG*distG)/(Rg*distG) // muGround = -(r*cos(theta) + distG)/Rg float muGround = -(r * cosineTheta + distanceToGround) / Rg; - // We can use the same triangle in calculate the distanceToGround to calculate the cosine of the - // angle between the ground touching point at height Rg and the zenith angle - //float muGround = (r2 - distanceToGround*distanceToGround - Rg2)/(2*distanceToGround*Rg); - // Acesss the Transmittance LUT in order to calculate the transmittance from the ground point Rg, - // thorugh the atmosphere, at a distance: distanceToGround + // We can use the same triangle in calculate the distanceToGround to calculate the + // cosine of the angle between the ground touching point at height Rg and the zenith + // angle + // float muGround = (r2 - distanceToGround*distanceToGround - Rg2)/(2*distanceToGround*Rg); + // Access the Transmittance LUT in order to calculate the transmittance from the + // ground point Rg, thorugh the atmosphere, at a distance: distanceToGround groundTransmittance = transmittance(Rg, muGround, distanceToGround); } - //for ( int phi_i = 0; phi_i < 2*INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++phi_i ) { + for (int phi_i = 0; phi_i < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++phi_i) { - float phi = (float(phi_i) + 0.5) * stepPhi; + float phi = (float(phi_i) + 0.5) * stepPhi; // spherical coordinates: dw = dtheta*dphi*sin(theta)*rho^2 // rho = 1, we are integrating over a unit sphere - float dw = stepTheta * stepPhi * sin(theta); + float dw = stepTheta * stepPhi * sin(theta); // w = (rho*sin(theta)*cos(phi), rho*sin(theta)*sin(phi), rho*cos(theta)) - float sinPhi = sin(phi); + float sinPhi = sin(phi); float sinTheta = sin(theta); - float cosPhi = cos(phi); - vec3 w = vec3(sinTheta * cosPhi, sinTheta * sinPhi, cosineTheta); + float cosPhi = cos(phi); + vec3 w = vec3(sinTheta * cosPhi, sinTheta * sinPhi, cosineTheta); // We calculate the Rayleigh and Mie phase function for the new scattering angle: // cos(angle between vec(v) and vec(w)), ||v|| = ||w|| = 1 - float nuWV = dot(v, w); + float nuWV = dot(v, w); float phaseRayleighWV = rayleighPhaseFunction(nuWV); - float phaseMieWV = miePhaseFunction(nuWV); + float phaseMieWV = miePhaseFunction(nuWV, mieG); - vec3 groundNormal = (vec3(0.0, 0.0, r) + distanceToGround * w) / Rg; + vec3 groundNormal = (vec3(0.0, 0.0, r) + distanceToGround * w) / Rg; vec3 groundIrradiance = irradianceLUT(deltaETexture, dot(groundNormal, s), Rg); - // We finally calculate the radiance from the reflected ray from ground (0.0 if not reflected) + // We finally calculate the radiance from the reflected ray from ground + // (0.0 if not reflected) vec3 radianceJ1 = groundTransmittance * groundReflectance * groundIrradiance; // We calculate the Rayleigh and Mie phase function for the new scattering angle: // cos(angle between vec(s) and vec(w)), ||s|| = ||w|| = 1 float nuSW = dot(s, w); - // The first iteraction is different from the others, that's because in the first - // iteraction all the light InScattered are coming from the initial pre-computed - // single InScattered light. We stored these values in the deltaS textures (Ray and Mie), - // and in order to avoid problems with the high angle dependency in the phase functions, - // we don't include the phase functions on those tables (that's why we calculate them now). - if ( firstIteraction == 1 ) { + // The first iteraction is different from the others. In the first iteraction all + // the light InScattered is coming from the initial pre-computed single InScattered + // light. We stored these values in the deltaS textures (Ray and Mie), and in order + // to avoid problems with the high angle dependency in the phase functions, we don't + // include the phase functions on those tables (that's why we calculate them now). + if (firstIteraction == 1) { float phaseRaySW = rayleighPhaseFunction(nuSW); - float phaseMieSW = miePhaseFunction(nuSW); + float phaseMieSW = miePhaseFunction(nuSW, mieG); // We can now access the values for the single InScattering in the textures deltaS textures. - vec3 singleRay = texture4D(deltaSRTexture, r, w.z, muSun, nuSW).rgb; - vec3 singleMie = texture4D(deltaSMTexture, r, w.z, muSun, nuSW).rgb; + vec3 singleRay = texture4D(deltaSRTexture, r, w.z, muSun, nuSW).rgb; + vec3 singleMie = texture4D(deltaSMTexture, r, w.z, muSun, nuSW).rgb; // Initial InScattering including the phase functions radianceJ1 += singleRay * phaseRaySW + singleMie * phaseMieSW; } else { - // On line 9 of the algorithm, the texture table deltaSR is updated, so when we are not in the first - // iteraction, we are getting the updated result of deltaSR (not the single inscattered light but the - // accumulated (higher order) inscattered light. + // On line 9 of the algorithm, the texture table deltaSR is updated, so when we + // are not in the first iteraction, we are getting the updated result of deltaSR + // (not the single inscattered light but the accumulated (higher order) + // inscattered light. // w.z is the cosine(theta) = mu for vec(w) radianceJ1 += texture4D(deltaSRTexture, r, w.z, muSun, nuSW).rgb; } - // Finally, we add the atmospheric scale height (See: Radiation Transfer on the Atmosphere and Ocean from - // Thomas and Stamnes, pg 9-10. - radianceJ += radianceJ1 * (betaRayleigh * exp(-(r - Rg) / HR) * phaseRayleighWV + - betaMieScattering * exp(-(r - Rg) / HM) * phaseMieWV) * dw; + // Finally, we add the atmospheric scale height (See: Radiation Transfer on the + // Atmosphere and Ocean from Thomas and Stamnes, pg 9-10. + return radianceJ1 * (betaRayleigh * exp(-(r - Rg) / HR) * phaseRayleighWV + + betaMieScattering * exp(-(r - Rg) / HM) * phaseMieWV) * dw; } } } void main() { - // cosine variables to access deltaS textures + // InScattering Radiance to be calculated at different points in the ray path + // Unmapping the variables from texture texels coordinates to mapped coordinates float mu, muSun, nu; - // InScattering Radiance to be calculated at - // different points in the ray path - vec3 radianceJ = vec3(0.0f); - - // Unmapping the variables from texture texels coordinates - // to mapped coordinates unmappingMuMuSunNu(r, dhdH, mu, muSun, nu); // Calculate the the light inScattered in direction // -vec(v) for the point at height r (vec(y) following Bruneton and Neyret's paper - inscatter(r, mu, muSun, nu, radianceJ); + vec3 radianceJ = inscatter(r, mu, muSun, nu); // Write to texture detaJ - renderTarget1 = vec4(radianceJ, 1.0); + renderTarget = vec4(radianceJ, 1.0); } diff --git a/modules/atmosphere/shaders/deltaJ_calc_gs.glsl b/modules/atmosphere/shaders/deltaJ_calc_gs.glsl deleted file mode 100644 index aea1c7db4d..0000000000 --- a/modules/atmosphere/shaders/deltaJ_calc_gs.glsl +++ /dev/null @@ -1,39 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version __CONTEXT__ - -uniform int layer; - -layout (triangles) in; -layout (triangle_strip, max_vertices = 3) out; - -void main() { - for (int n = 0; n < gl_in.length(); ++n) { - gl_Position = gl_in[n].gl_Position; - gl_Layer = layer; - EmitVertex(); - } - EndPrimitive(); -} diff --git a/modules/atmosphere/shaders/deltaJ_calc_vs.glsl b/modules/atmosphere/shaders/deltaJ_calc_vs.glsl deleted file mode 100644 index d5a1e43e38..0000000000 --- a/modules/atmosphere/shaders/deltaJ_calc_vs.glsl +++ /dev/null @@ -1,31 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version __CONTEXT__ - -layout(location = 0) in vec3 in_position; - -void main() { - gl_Position = vec4(in_position, 1.0); -} \ No newline at end of file diff --git a/modules/atmosphere/shaders/deltaS_calc_fs.glsl b/modules/atmosphere/shaders/deltaS_calc_fs.glsl index d337cb18bf..b5d7de5e79 100644 --- a/modules/atmosphere/shaders/deltaS_calc_fs.glsl +++ b/modules/atmosphere/shaders/deltaS_calc_fs.glsl @@ -26,24 +26,21 @@ #include "atmosphere_common.glsl" -out vec4 renderTarget1; +out vec4 renderTarget; uniform int layer; - uniform sampler3D deltaSRTexture; uniform sampler3D deltaSMTexture; void main() { - // First we convert the window's fragment coordinate to - // texel coordinates - vec3 rst = vec3(gl_FragCoord.xy, float(layer) + 0.5f) / + // First we convert the window's fragment coordinate to texel coordinates + vec3 rst = vec3(gl_FragCoord.xy, float(layer) + 0.5) / vec3(ivec3(SAMPLES_MU_S * SAMPLES_NU, SAMPLES_MU, SAMPLES_R)); - vec4 rayleighInscattering0 = texture(deltaSRTexture, rst); - vec4 mieInscattering0 = texture(deltaSMTexture, rst); + vec3 rayleighInscattering = texture(deltaSRTexture, rst).rgb; + float mieInscattering = texture(deltaSMTexture, rst).r; - // We are using only the red component of the Mie scattering - // See the Precomputed Atmosphere Scattering paper for details about - // the angular precision. - renderTarget1 = vec4(rayleighInscattering0.rgb, mieInscattering0.r); + // We are using only the red component of the Mie scattering. See the Precomputed + // Atmosphere Scattering paper for details about the angular precision + renderTarget = vec4(rayleighInscattering, mieInscattering); } diff --git a/modules/atmosphere/shaders/deltaS_calc_gs.glsl b/modules/atmosphere/shaders/deltaS_calc_gs.glsl deleted file mode 100644 index aea1c7db4d..0000000000 --- a/modules/atmosphere/shaders/deltaS_calc_gs.glsl +++ /dev/null @@ -1,39 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version __CONTEXT__ - -uniform int layer; - -layout (triangles) in; -layout (triangle_strip, max_vertices = 3) out; - -void main() { - for (int n = 0; n < gl_in.length(); ++n) { - gl_Position = gl_in[n].gl_Position; - gl_Layer = layer; - EmitVertex(); - } - EndPrimitive(); -} diff --git a/modules/atmosphere/shaders/deltaS_sup_calc_fs.glsl b/modules/atmosphere/shaders/deltaS_sup_calc_fs.glsl index 31e6b6670f..ebe63b5071 100644 --- a/modules/atmosphere/shaders/deltaS_sup_calc_fs.glsl +++ b/modules/atmosphere/shaders/deltaS_sup_calc_fs.glsl @@ -26,20 +26,21 @@ #include "atmosphere_common.glsl" -out vec4 renderTarget1; +out vec4 renderTarget; uniform int layer; - uniform sampler3D deltaSTexture; void main() { - float x = gl_FragCoord.x - 0.5f; - float y = gl_FragCoord.y - 0.5f; + vec2 p = gl_FragCoord.xy - vec2(0.5); - float nu = -1.0f + floor(x / float(SAMPLES_MU_S)) / (float(SAMPLES_NU) - 1.0f) * 2.0f; - vec3 uvw = vec3(gl_FragCoord.xy, float(layer) + 0.5f) / vec3(ivec3(SAMPLES_MU_S * SAMPLES_NU, SAMPLES_MU, SAMPLES_R)); + float nu = -1.0 + floor(p.x / float(SAMPLES_MU_S)) / (float(SAMPLES_NU) - 1.0) * 2.0; + vec3 uvw = vec3( + gl_FragCoord.xy, + float(layer) + 0.5) / vec3(ivec3(SAMPLES_MU_S * SAMPLES_NU, SAMPLES_MU, SAMPLES_R) + ); - // See Bruneton and Neyret paper, "Angular Precision" paragraph to understanding why we are - // dividing the S[L*] by the Rayleigh phase function. - renderTarget1 = vec4(texture(deltaSTexture, uvw).rgb / rayleighPhaseFunction(nu), 0.0f); + // See Bruneton and Neyret paper, "Angular Precision" paragraph to understanding why we + // are dividing the S[L*] by the Rayleigh phase function. + renderTarget = vec4(texture(deltaSTexture, uvw).rgb / rayleighPhaseFunction(nu), 0.0); } diff --git a/modules/atmosphere/shaders/deltaS_sup_calc_gs.glsl b/modules/atmosphere/shaders/deltaS_sup_calc_gs.glsl deleted file mode 100644 index 7cccacb76a..0000000000 --- a/modules/atmosphere/shaders/deltaS_sup_calc_gs.glsl +++ /dev/null @@ -1,39 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version __CONTEXT__ - -uniform int layer; - -layout (triangles) in; -layout (triangle_strip, max_vertices = 3) out; - -void main() { - for (int n = 0; n < gl_in.length(); ++n) { - gl_Position = gl_in[n].gl_Position; - gl_Layer = layer; - EmitVertex(); - } - EndPrimitive(); -} diff --git a/modules/atmosphere/shaders/deltaS_sup_calc_vs.glsl b/modules/atmosphere/shaders/deltaS_sup_calc_vs.glsl deleted file mode 100644 index deb9073c8f..0000000000 --- a/modules/atmosphere/shaders/deltaS_sup_calc_vs.glsl +++ /dev/null @@ -1,31 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version __CONTEXT__ - -layout(location = 0) in vec3 in_position; - -void main() { - gl_Position = vec4(in_position, 1.0); -} diff --git a/modules/atmosphere/shaders/inScattering_calc_fs.glsl b/modules/atmosphere/shaders/inScattering_calc_fs.glsl index be7281bda3..8443cb1109 100644 --- a/modules/atmosphere/shaders/inScattering_calc_fs.glsl +++ b/modules/atmosphere/shaders/inScattering_calc_fs.glsl @@ -21,6 +21,7 @@ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ + #version __CONTEXT__ #include "atmosphere_common.glsl" @@ -31,64 +32,59 @@ layout(location = 1) out vec4 renderTarget2; uniform float r; uniform vec4 dhdH; -//uniform sampler2D transmittanceTexture; - -void integrand(float r, float mu, float muSun, float nu, - float y, out vec3 S_R, out vec3 S_M) { +void integrand(float r, float mu, float muSun, float nu, float y, out vec3 S_R, + out vec3 S_M) +{ // The integral's integrand is the single inscattering radiance: // S[L0] = P_M*S_M[L0] + P_R*S_R[L0] // where S_M[L0] = T*(betaMScattering * exp(-h/H_M))*L0 and // S_R[L0] = T*(betaRScattering * exp(-h/H_R))*L0. // T = transmittance. - // One must remember that because the occlusion on L0, the integrand - // here will be equal to 0 in that cases. - // Also it is important to remember that the phase function for the - // Rayleigh and Mie scattering are added during the rendering time - // to increase the angular precision + // One must remember that because the occlusion on L0, the integrand here will be equal + // to 0 in that cases. Also it is important to remember that the phase function for the + // Rayleigh and Mie scattering are added during the rendering time to increase the + // angular precision S_R = vec3(0.0); S_M = vec3(0.0); // cosine law float ri = max(sqrt(r * r + y * y + 2.0 * r * mu * y), Rg); - // Considering the Sun as a parallel light source, - // thew vector s_i = s. + // Considering the Sun as a parallel light source, thew vector s_i = s. // So muSun_i = (vec(y_i) dot vec(s))/r_i = ((vec(x) + vec(yi-x)) dot vec(s))/r_i // muSun_i = (vec(x) dot vec(s) + vec(yi-x) dot vec(s))/r_i = (r*muSun + yi*nu)/r_i float muSun_i = (nu * y + muSun * r) / ri; - // If the muSun_i is smaller than the angle to horizon (no sun radiance - // hitting the point y), we return S_R = S_M = 0.0f. + // If the muSun_i is smaller than the angle to horizon (no sun radiance hitting the + // point y), we return S_R = S_M = 0.0. if (muSun_i >= -sqrt(1.0 - Rg * Rg / (ri * ri))) { - // It's the transmittance from the point y (ri) to the top of atmosphere - // in direction of the sun (muSun_i) and the transmittance from the observer - // at x (r) to y (ri). - vec3 transmittanceY = transmittance(r, mu, y) * transmittanceLUT(ri, muSun_i); + // It's the transmittance from the point y (ri) to the top of atmosphere in direction + // of the sun (muSun_i) and the transmittance from the observer at x (r) to y (ri). + vec3 transmittanceY = transmittance(r, mu, y) * transmittance(ri, muSun_i); // exp(-h/H)*T(x,v) if (ozoneLayerEnabled) { - S_R = (exp(-(ri - Rg) / HO) + exp( -(ri - Rg) / HR )) * transmittanceY; - S_M = exp( -(ri - Rg) / HM ) * transmittanceY; + S_R = (exp(-(ri - Rg) / HO) + exp(-(ri - Rg) / HR)) * transmittanceY; + S_M = exp(-(ri - Rg) / HM) * transmittanceY; } else { - S_R = exp( -(ri - Rg) / HR ) * transmittanceY; - S_M = exp( -(ri - Rg) / HM ) * transmittanceY; + S_R = exp(-(ri - Rg) / HR) * transmittanceY; + S_M = exp(-(ri - Rg) / HM) * transmittanceY; } // The L0 (sun radiance) is added in real-time. } } void inscatter(float r, float mu, float muSun, float nu, out vec3 S_R, out vec3 S_M) { - // Let's calculate S_M and S_R by integration along the eye ray path inside - // the atmosphere, given a position r, a view angle (cosine) mu, a sun - // position angle (cosine) muSun, and the angle (cosine) between the sun position - // and the view direction, nu. - // Integrating using the Trapezoidal rule: + // Let's calculate S_M and S_R by integration along the eye ray path inside the + // atmosphere, given a position r, a view angle (cosine) mu, a sun position angle + // (cosine) muSun, and the angle (cosine) between the sun position and the view + // direction, nu. Integrating using the Trapezoidal rule: // Integral(f(y)dy)(from a to b) = (b-a)/2n_steps*(Sum(f(y_i+1)+f(y_i))) - S_R = vec3(0.0f); - S_M = vec3(0.0f); + S_R = vec3(0.0); + S_M = vec3(0.0); + float rayDist = rayDistance(r, mu); - float dy = rayDist / float(INSCATTER_INTEGRAL_SAMPLES); - float yi = 0.0f; + float dy = rayDist / float(INSCATTER_INTEGRAL_SAMPLES); vec3 S_Ri; vec3 S_Mi; integrand(r, mu, muSun, nu, 0.0, S_Ri, S_Mi); @@ -99,38 +95,33 @@ void inscatter(float r, float mu, float muSun, float nu, out vec3 S_R, out vec3 integrand(r, mu, muSun, nu, yj, S_Rj, S_Mj); S_R += (S_Ri + S_Rj); S_M += (S_Mi + S_Mj); - yi = yj; S_Ri = S_Rj; S_Mi = S_Mj; } - S_R *= betaRayleigh * (rayDist / (2.0f * float(INSCATTER_INTEGRAL_SAMPLES))); - S_M *= betaMieScattering * (rayDist / (2.0f * float(INSCATTER_INTEGRAL_SAMPLES))); + S_R *= betaRayleigh * (rayDist / (2.0 * float(INSCATTER_INTEGRAL_SAMPLES))); + S_M *= betaMieScattering * (rayDist / (2.0 * float(INSCATTER_INTEGRAL_SAMPLES))); } void main() { vec3 S_R; // First Order Rayleigh InScattering vec3 S_M; // First Order Mie InScattering - float mu, muSun, nu; // parametrization angles - // From the layer interpolation (see C++ code for layer to r) - // and the textures parameters (uv), we unmapping mu, muSun and nu. + // From the layer interpolation (see C++ code for layer to r) and the textures + // parameters (uv), we unmapping mu, muSun and nu. + float mu, muSun, nu; unmappingMuMuSunNu(r, dhdH, mu, muSun, nu); - // Here we calculate the single inScattered light. - // Because this is a single inscattering, the light - // that arrives at a point y in the path from the - // eye to the infinity (top of atmosphere or planet's - // ground), comes only from the light source, i.e., the - // sun. So, the there is no need to integrate over the - // whole solid angle (4pi), we need only to consider - // the Sun position (cosine of sun pos = muSun). - // Then, following the paper notation: + // Here we calculate the single inScattered light. Because this is a single + // inscattering, the light that arrives at a point y in the path from the eye to the + // infinity (top of atmosphere or planet's ground), comes only from the light source, + // i.e., the sun. So, the there is no need to integrate over the whole solid angle + // (4pi), we need only to consider the Sun position (cosine of sun pos = muSun). Then, + // following the paper notation: // S[L] = P_R*S_R[L0] + P_M*S_M[L0] + S[L*] // For single inscattering only: // S[L0] = P_R*S_R[L0] + P_M*S_M[L0] - // In order to save memory, we just store the red component - // of S_M[L0], and later we use the proportionality rule - // to calcule the other components. + // In order to save memory, we just store the red component of S_M[L0], and later we use + // the proportionality rule to calcule the other components. inscatter(r, mu, muSun, nu, S_R, S_M); renderTarget1 = vec4(S_R, 1.0); renderTarget2 = vec4(S_M, 1.0); diff --git a/modules/atmosphere/shaders/inScattering_sup_calc_fs.glsl b/modules/atmosphere/shaders/inScattering_sup_calc_fs.glsl index 81377100bc..fd128b3b16 100644 --- a/modules/atmosphere/shaders/inScattering_sup_calc_fs.glsl +++ b/modules/atmosphere/shaders/inScattering_sup_calc_fs.glsl @@ -26,23 +26,21 @@ #include "atmosphere_common.glsl" -out vec4 renderTarget1; +out vec4 renderTarget; uniform float r; uniform vec4 dhdH; - -//uniform sampler2D transmittanceTexture; uniform sampler3D deltaJTexture; // The integrand here is the f(y) of the trapezoidal rule: vec3 integrand(float r, float mu, float muSun, float nu, float dist) { // We can calculate r_i by the cosine law: r_i^2=dist^2 + r^2 - 2*r*dist*cos(PI-theta) - float r_i = sqrt(r * r + dist * dist + 2.0f * r * dist * mu); + float r_i = sqrt(r * r + dist * dist + 2.0f * r * dist * mu); // r_i can be found using the dot product: // vec(y_i) dot vec(dist) = cos(theta_i) * ||vec(y_i)|| * ||vec(dist)|| // But vec(y_i) = vec(x) + vec(dist), also: vec(x) dot vec(dist) = cos(theta) = mu // So, cos(theta_i) = mu_i = (r*dist**mu + dist*2)/(r_i*dist) - float mu_i = (r * mu + dist) / r_i; + float mu_i = (r * mu + dist) / r_i; // muSun_i can also be found by the dot product: // cos(sigma_i) = muSun_i = (vec(s) dot vec(y_i))/(||vec(y_i)|| * ||vec(s)||) // But vec(y_i) = vec(x) + vec(dist), and vec(x) dot vec(s) = muSun, cos(sigma_i + theta_i) = nu @@ -52,28 +50,29 @@ vec3 integrand(float r, float mu, float muSun, float nu, float dist) { } vec3 inscatter(float r, float mu, float muSun, float nu) { - vec3 inScatteringRadiance = vec3(0.0f); - float dy = rayDistance(r, mu) / float(INSCATTER_INTEGRAL_SAMPLES); - vec3 inScatteringRadiance_i = integrand(r, mu, muSun, nu, 0.0); + vec3 inScatteringRadiance = vec3(0.0); + float dy = rayDistance(r, mu) / float(INSCATTER_INTEGRAL_SAMPLES); + vec3 inScatteringRadiance_i = integrand(r, mu, muSun, nu, 0.0); - // In order to solve the integral from equation (11) we use the trapezoidal - // rule: Integral(f(y)dy)(from a to b) = ((b-a)/2n_steps)*(Sum(f(y_i+1)+f(y_i))) + // In order to solve the integral from equation (11) we use the trapezoidal rule: + // Integral(f(y)dy)(from a to b) = ((b-a)/2n_steps)*(Sum(f(y_i+1)+f(y_i))) // where y_i+1 = y_j for (int i = 1; i <= INSCATTER_INTEGRAL_SAMPLES; ++i) { float y_j = float(i) * dy; vec3 inScatteringRadiance_j = integrand(r, mu, muSun, nu, y_j); - inScatteringRadiance += (inScatteringRadiance_i + inScatteringRadiance_j) / 2.0 * dy; + inScatteringRadiance += (inScatteringRadiance_i + inScatteringRadiance_j) / 2.0 * dy; inScatteringRadiance_i = inScatteringRadiance_j; } return inScatteringRadiance; } void main() { - float mu = 0.0f, muSunun = 0.0f, nu = 0.0f; - // Unmapping the variables from texture texels coordinates - // to mapped coordinates - unmappingMuMuSunNu(r, dhdH, mu, muSunun, nu); + float mu = 0.0; + float muSun = 0.0; + float nu = 0.0; + // Unmapping the variables from texture texels coordinates to mapped coordinates + unmappingMuMuSunNu(r, dhdH, mu, muSun, nu); // Write to texture deltaSR - renderTarget1 = vec4(inscatter(r, mu, muSunun, nu), 1.0); + renderTarget = vec4(inscatter(r, mu, muSun, nu), 1.0); } diff --git a/modules/atmosphere/shaders/inScattering_sup_calc_vs.glsl b/modules/atmosphere/shaders/inScattering_sup_calc_vs.glsl deleted file mode 100644 index deb9073c8f..0000000000 --- a/modules/atmosphere/shaders/inScattering_sup_calc_vs.glsl +++ /dev/null @@ -1,31 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version __CONTEXT__ - -layout(location = 0) in vec3 in_position; - -void main() { - gl_Position = vec4(in_position, 1.0); -} diff --git a/modules/atmosphere/shaders/irradiance_calc_fs.glsl b/modules/atmosphere/shaders/irradiance_calc_fs.glsl index 94ea44c834..93fca5128e 100644 --- a/modules/atmosphere/shaders/irradiance_calc_fs.glsl +++ b/modules/atmosphere/shaders/irradiance_calc_fs.glsl @@ -21,23 +21,23 @@ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ + #version __CONTEXT__ #include "atmosphere_common.glsl" out vec4 renderTableColor; -//uniform sampler2D transmittanceTexture; - void main() { - float muSun, r; - unmappingRAndMuSun(r, muSun); - // We are calculating the Irradiance for L0, i.e., - // only the radiance comming from sun direction is accounted: + // See Bruneton and Colliene to understand the mapping + float muSun = -0.2 + (gl_FragCoord.x - 0.5) / (float(OTHER_TEXTURES.x) - 1.0) * 1.2; + float r = Rg + (gl_FragCoord.y - 0.5) / (float(OTHER_TEXTURES.y) ) * RtMinusRg; + + // We are calculating the Irradiance for L0, i.e., only the radiance coming from Sun + // direction is accounted: // E[L0](x,s) = L0*dot(w,n) or 0 (if v!=s or the sun is occluded). - // Because we consider the Planet as a perfect sphere and we are - // considering only single scattering here, the - // dot product dot(w,n) is equal to dot(s,n) that is equal to + // Because we consider the Planet as a perfect sphere and we are considering only single + // scattering here, the dot product dot(w,n) is equal to dot(s,n) that is equal to // dot(s, r/||r||) = muSun. - renderTableColor = vec4(transmittanceLUT(r, muSun) * max(muSun, 0.0), 0.0); + renderTableColor = vec4(transmittance(r, muSun) * max(muSun, 0.0), 0.0); } diff --git a/modules/atmosphere/shaders/irradiance_calc_vs.glsl b/modules/atmosphere/shaders/irradiance_calc_vs.glsl deleted file mode 100644 index 1ca953fe3c..0000000000 --- a/modules/atmosphere/shaders/irradiance_calc_vs.glsl +++ /dev/null @@ -1,31 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version __CONTEXT__ - -layout(location = 0) in vec3 in_position; - -void main() { - gl_Position = vec4(in_position, 1.0); -} diff --git a/modules/atmosphere/shaders/irradiance_final_fs.glsl b/modules/atmosphere/shaders/irradiance_final_fs.glsl index f21d74bdba..5f9834ab2c 100644 --- a/modules/atmosphere/shaders/irradiance_final_fs.glsl +++ b/modules/atmosphere/shaders/irradiance_final_fs.glsl @@ -31,7 +31,7 @@ out vec4 renderTableColor; uniform sampler2D deltaETexture; void main() { - vec2 uv = gl_FragCoord.xy / vec2(OTHER_TEXTURES_W, OTHER_TEXTURES_H); + vec2 uv = gl_FragCoord.xy / vec2(OTHER_TEXTURES); // Update texture E with E plus deltaE textures. renderTableColor = texture(deltaETexture, uv); diff --git a/modules/atmosphere/shaders/irradiance_final_vs.glsl b/modules/atmosphere/shaders/irradiance_final_vs.glsl deleted file mode 100644 index 1ca953fe3c..0000000000 --- a/modules/atmosphere/shaders/irradiance_final_vs.glsl +++ /dev/null @@ -1,31 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version __CONTEXT__ - -layout(location = 0) in vec3 in_position; - -void main() { - gl_Position = vec4(in_position, 1.0); -} diff --git a/modules/atmosphere/shaders/irradiance_sup_calc_fs.glsl b/modules/atmosphere/shaders/irradiance_sup_calc_fs.glsl index 5ac81a7406..06b31090b8 100644 --- a/modules/atmosphere/shaders/irradiance_sup_calc_fs.glsl +++ b/modules/atmosphere/shaders/irradiance_sup_calc_fs.glsl @@ -29,60 +29,56 @@ out vec4 renderTableColor; uniform int firstIteraction; -//uniform float firstIteraction; - -// -- Spherical Coordinates Steps. phi e [0,2PI] and theta e [0, PI/2] -const float stepPhi = (2.0f * M_PI) / float(IRRADIANCE_INTEGRAL_SAMPLES); -const float stepTheta = M_PI / (2.0f * float(IRRADIANCE_INTEGRAL_SAMPLES)); - -//uniform sampler2D transmittanceTexture; uniform sampler3D deltaSRTexture; uniform sampler3D deltaSMTexture; +// Spherical Coordinates Steps. phi e [0,2PI] and theta e [0, PI/2] +const float stepPhi = (2.0 * M_PI) / float(IRRADIANCE_INTEGRAL_SAMPLES); +const float stepTheta = M_PI / (2.0 * float(IRRADIANCE_INTEGRAL_SAMPLES)); + void main() { - float r = 0.0f; - float muSun = 0.0f; - // Unmapping the variables from texture texels coordinates - // to mapped coordinates - unmappingRAndMuSunIrradiance(r, muSun); + // See Bruneton and Colliene to understand the mapping. + float muSun = -0.2 + (gl_FragCoord.x - 0.5) / (float(SKY.x) - 1.0) * 1.2; + float r = Rg + (gl_FragCoord.y - 0.5) / (float(SKY.y) - 1.0) * RtMinusRg; // We know that muSun = cos(sigma) = s.z/||s|| // But, ||s|| = 1, so s.z = muSun. Also, // ||s|| = 1, so s.x = sin(sigma) = sqrt(1-muSun^2) and s.y = 0.0f - vec3 s = vec3(max(sqrt(1.0f - muSun * muSun), 0.0f), 0.0f, muSun); + vec3 s = vec3(max(sqrt(1.0 - muSun * muSun), 0.0), 0.0, muSun); - // In order to solve the integral from equation (15) we use the trapezoidal - // rule: Integral(f(y)dy)(from a to b) = ((b-a)/2n_steps)*(Sum(f(y_i+1)+f(y_i))) - vec3 irradianceE = vec3(0.0f); + // In order to solve the integral from equation (15) we use the trapezoidal rule: + // Integral(f(y)dy)(from a to b) = ((b-a)/2n_steps)*(Sum(f(y_i+1)+f(y_i))) + vec3 irradianceE = vec3(0.0); for (int iphi = 0; iphi < IRRADIANCE_INTEGRAL_SAMPLES; ++iphi) { - float phi = (float(iphi) + 0.5f) * stepPhi; + float phi = (float(iphi) + 0.5) * stepPhi; for (int itheta = 0; itheta < IRRADIANCE_INTEGRAL_SAMPLES; ++itheta) { - float theta = (float(itheta) + 0.5f) * stepTheta; + float theta = (float(itheta) + 0.5) * stepTheta; // spherical coordinates: dw = dtheta*dphi*sin(theta)*rho^2 // rho = 1, we are integrating over a unit sphere - float dw = stepTheta * stepPhi * sin(theta); + float dw = stepTheta * stepPhi * sin(theta); // w = (cos(phi) * sin(theta) * rho, sin(phi) * sin(theta) * rho, cos(theta) * rho) - vec3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta)); - float nu = dot(s, w); + vec3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta)); + float nu = dot(s, w); // The first iteraction is different from the others, that's because in the first // iteraction all the light arriving are coming from the initial pre-computed - // single scattered light. We stored these values in the deltaS textures (Ray and Mie), - // and in order to avoid problems with the high angle dependency in the phase functions, - // we don't include the phase functions on those tables (that's why we calculate them now). + // single scattered light. We stored these values in the deltaS textures (Ray and + // Mie), and in order to avoid problems with the high angle dependency in the phase + // functions, we don't include the phase functions on those tables (that's why we + // calculate them now) if (firstIteraction == 1) { float phaseRay = rayleighPhaseFunction(nu); - float phaseMie = miePhaseFunction(nu); + float phaseMie = miePhaseFunction(nu, mieG); vec3 singleRay = texture4D(deltaSRTexture, r, w.z, muSun, nu).rgb; vec3 singleMie = texture4D(deltaSMTexture, r, w.z, muSun, nu).rgb; // w.z is the cosine(theta) = mu for vec(w) and also vec(w) dot vec(n(xo)) irradianceE += (singleRay * phaseRay + singleMie * phaseMie) * w.z * dw; } else { - // On line 10 of the algorithm, the texture table deltaE is updated, so when we are not in the first - // iteraction, we are getting the updated result of deltaE (not the single irradiance light but the - // accumulated (higher order) irradiance light. - // w.z is the cosine(theta) = mu for vec(w) and also vec(w) dot vec(n(xo)) + // On line 10 of the algorithm, the texture table deltaE is updated, so when we + // are not in the first iteraction, we are getting the updated result of deltaE + // (not the single irradiance light but the accumulated (higher order) irradiance + // light. w.z is the cosine(theta) = mu for vec(w) and also vec(w) dot vec(n(xo)) irradianceE += texture4D(deltaSRTexture, r, w.z, muSun, nu).rgb * w.z * dw; } } diff --git a/modules/atmosphere/shaders/irradiance_sup_calc_vs.glsl b/modules/atmosphere/shaders/irradiance_sup_calc_vs.glsl deleted file mode 100644 index 1ca953fe3c..0000000000 --- a/modules/atmosphere/shaders/irradiance_sup_calc_vs.glsl +++ /dev/null @@ -1,31 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version __CONTEXT__ - -layout(location = 0) in vec3 in_position; - -void main() { - gl_Position = vec4(in_position, 1.0); -} diff --git a/modules/atmosphere/shaders/transmittance_calc_fs.glsl b/modules/atmosphere/shaders/transmittance_calc_fs.glsl index 0c1dddd0ff..cf78347f29 100644 --- a/modules/atmosphere/shaders/transmittance_calc_fs.glsl +++ b/modules/atmosphere/shaders/transmittance_calc_fs.glsl @@ -21,33 +21,31 @@ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ + #version __CONTEXT__ #include "atmosphere_common.glsl" -//layout(location = 1) out vec4 renderTableColor; out vec4 renderTableColor; -//-- Optical depth by integration, from ray starting at point vec(x), i.e, -// height r and angle mu (cosine of vec(v)) until top of atmosphere -// or planet's ground. -- +// Optical depth by integration, from ray starting at point vec(x), i.e, height r and +// angle mu (cosine of vec(v)) until top of atmosphere or planet's ground. // r := height of starting point vect(x) // mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r -// H := Thickness of atmosphere if its density were uniform (can be used -// for Rayleigh and Mie. +// H := Thickness of atmosphere if its density were uniform (used for Rayleigh and Mie) float opticalDepth(float r, float mu, float H) { - float r2 = r*r; - // Is ray below horizon? The transmittance table will have only - // the values for transmittance starting at r (x) until the - // light ray touches the atmosphere or the ground and only for - // view angles v between 0 and pi/2 + eps. That's because we - // can calculate the transmittance for angles bigger than pi/2 - // just inverting the ray direction and starting and ending points. + float r2 = r * r; + // Is ray below horizon? The transmittance table will have only the values for + // transmittance starting at r (x) until the light ray touches the atmosphere or the + // ground and only for view angles v between 0 and pi/2 + eps. That's because we can + // calculate the transmittance for angles bigger than pi/2 just inverting the ray + // direction and starting and ending points. // cosine law for triangles: y_i^2 = a^2 + b^2 - 2abcos(alpha) - float cosZenithHorizon = -sqrt( 1.0f - ( ( Rg * Rg ) / r2 ) ); - if (mu < cosZenithHorizon) + float cosZenithHorizon = -sqrt(1.0 - (Rg * Rg / r2)); + if (mu < cosZenithHorizon) { return 1e9; + } // Integrating using the Trapezoidal rule: // Integral(f(y)dy)(from a to b) = ((b-a)/2n_steps)*(Sum(f(y_i+1)+f(y_i))) @@ -56,36 +54,39 @@ float opticalDepth(float r, float mu, float H) { // cosine law float y_i = exp(-(r - Rg) / H); - float x_step = 0.0f; - float accumulation = 0.0f; + float accumulation = 0.0; for (int i = 1; i <= TRANSMITTANCE_STEPS; ++i) { float x_i = float(i) * deltaStep; // cosine law for triangles: y_i^2 = a^2 + b^2 - 2abcos(alpha) // In this case, a = r, b = x_i and cos(alpha) = cos(PI-zenithView) = mu - float y_ii = exp(-(sqrt(r2 + x_i * x_i + 2.0 * x_i * r * mu) - Rg) / H); + float y_ii = exp(-(sqrt(r2 + x_i * x_i + 2.0 * x_i * r * mu) - Rg) / H); accumulation += (y_ii + y_i); - //x_step = x_i; y_i = y_ii; } - return accumulation * ( b_a / ( 2 * TRANSMITTANCE_STEPS ) ); + return accumulation * (b_a / (2.0 * TRANSMITTANCE_STEPS)); } - void main() { - float r, muSun; - unmappingRAndMu(r, muSun); + float u_mu = gl_FragCoord.x / float(TRANSMITTANCE.x); + float u_r = gl_FragCoord.y / float(TRANSMITTANCE.y); - vec3 opDepth = vec3(0.0); + // In the paper u_r^2 = (r^2-Rg^2)/(Rt^2-Rg^2) + // So, extracting r from u_r in the above equation: + float r = Rg + (u_r * u_r) * RtMinusRg; + // In the paper the Bruneton suggest mu = dot(v,x)/||x|| with ||v|| = 1.0 + // Later he proposes u_mu = (1-exp(-3mu-0.6))/(1-exp(-3.6)) + // But the below one is better. See Colliene. + // One must remember that mu is defined from 0 to PI/2 + epsilon + float muSun = -0.15 + tan(1.5 * u_mu) / tan(1.5) * 1.15; + + vec3 ozoneContribution = vec3(0.0); if (ozoneLayerEnabled) { - opDepth = betaOzoneExtinction * (0.0000006) * opticalDepth(r, muSun, HO) + + ozoneContribution = betaOzoneExtinction * 0.0000006 * opticalDepth(r, muSun, HO); + } + vec3 opDepth = ozoneContribution + betaMieExtinction * opticalDepth(r, muSun, HM) + betaRayleigh * opticalDepth(r, muSun, HR); - } - else { - opDepth = betaMieExtinction * opticalDepth(r, muSun, HM) + - betaRayleigh * opticalDepth(r, muSun, HR); - } - renderTableColor = vec4(exp(-opDepth), 0.0f); + renderTableColor = vec4(exp(-opDepth), 0.0); } diff --git a/modules/atmosphere/shaders/transmittance_calc_vs.glsl b/modules/atmosphere/shaders/transmittance_calc_vs.glsl deleted file mode 100644 index aead855d65..0000000000 --- a/modules/atmosphere/shaders/transmittance_calc_vs.glsl +++ /dev/null @@ -1,31 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version __CONTEXT__ - -layout(location = 0) in vec4 in_position; - -void main() { - gl_Position = in_position; -} diff --git a/modules/base/CMakeLists.txt b/modules/base/CMakeLists.txt index 75e8508b89..4a69424b32 100644 --- a/modules/base/CMakeLists.txt +++ b/modules/base/CMakeLists.txt @@ -50,6 +50,7 @@ set(HEADER_FILES rendering/renderableplane.h rendering/renderableplaneimagelocal.h rendering/renderableplaneimageonline.h + rendering/renderableprism.h rendering/renderablesphere.h rendering/renderabletrail.h rendering/renderabletrailorbit.h @@ -101,6 +102,7 @@ set(SOURCE_FILES rendering/renderableplane.cpp rendering/renderableplaneimagelocal.cpp rendering/renderableplaneimageonline.cpp + rendering/renderableprism.cpp rendering/renderablesphere.cpp rendering/renderabletrail.cpp rendering/renderabletrailorbit.cpp @@ -141,6 +143,8 @@ set(SHADER_FILES shaders/model_vs.glsl shaders/plane_fs.glsl shaders/plane_vs.glsl + shaders/prism_fs.glsl + shaders/prism_vs.glsl shaders/renderabletrail_fs.glsl shaders/renderabletrail_vs.glsl shaders/screenspace_fs.glsl diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp index 883e73cc21..67f2332629 100644 --- a/modules/base/basemodule.cpp +++ b/modules/base/basemodule.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -131,6 +132,7 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) { fRenderable->registerClass("RenderableNodeLine"); fRenderable->registerClass("RenderablePlaneImageLocal"); fRenderable->registerClass("RenderablePlaneImageOnline"); + fRenderable->registerClass("RenderablePrism"); fRenderable->registerClass("RenderableRadialGrid"); fRenderable->registerClass("RenderableSphere"); fRenderable->registerClass("RenderableSphericalGrid"); diff --git a/modules/base/dashboard/dashboarditemangle.cpp b/modules/base/dashboard/dashboarditemangle.cpp index 5034b763dc..1e3ed867d8 100644 --- a/modules/base/dashboard/dashboarditemangle.cpp +++ b/modules/base/dashboard/dashboarditemangle.cpp @@ -112,9 +112,7 @@ namespace { namespace openspace { documentation::Documentation DashboardItemAngle::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_dashboarditem_angle"; - return doc; + return codegen::doc("base_dashboarditem_angle"); } DashboardItemAngle::DashboardItemAngle(const ghoul::Dictionary& dictionary) diff --git a/modules/base/dashboard/dashboarditemdate.cpp b/modules/base/dashboard/dashboarditemdate.cpp index 3a1a611f6d..f21b7db78c 100644 --- a/modules/base/dashboard/dashboarditemdate.cpp +++ b/modules/base/dashboard/dashboarditemdate.cpp @@ -65,9 +65,7 @@ namespace { namespace openspace { documentation::Documentation DashboardItemDate::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_dashboarditem_date"; - return doc; + return codegen::doc("base_dashboarditem_date"); } DashboardItemDate::DashboardItemDate(const ghoul::Dictionary& dictionary) diff --git a/modules/base/dashboard/dashboarditemdistance.cpp b/modules/base/dashboard/dashboarditemdistance.cpp index bfb364ad2d..86613fc95c 100644 --- a/modules/base/dashboard/dashboarditemdistance.cpp +++ b/modules/base/dashboard/dashboarditemdistance.cpp @@ -140,9 +140,7 @@ namespace { namespace openspace { documentation::Documentation DashboardItemDistance::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_dashboarditem_distance"; - return doc; + return codegen::doc("base_dashboarditem_distance"); } DashboardItemDistance::DashboardItemDistance(const ghoul::Dictionary& dictionary) diff --git a/modules/base/dashboard/dashboarditemframerate.cpp b/modules/base/dashboard/dashboarditemframerate.cpp index f16db9e6fb..283dcb4a52 100644 --- a/modules/base/dashboard/dashboarditemframerate.cpp +++ b/modules/base/dashboard/dashboarditemframerate.cpp @@ -148,9 +148,7 @@ namespace { namespace openspace { documentation::Documentation DashboardItemFramerate::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_dashboarditem_framerate"; - return doc; + return codegen::doc("base_dashboarditem_framerate"); } DashboardItemFramerate::DashboardItemFramerate(const ghoul::Dictionary& dictionary) diff --git a/modules/base/dashboard/dashboarditempropertyvalue.cpp b/modules/base/dashboard/dashboarditempropertyvalue.cpp index 663ff6d68f..cfec7d6e1f 100644 --- a/modules/base/dashboard/dashboarditempropertyvalue.cpp +++ b/modules/base/dashboard/dashboarditempropertyvalue.cpp @@ -62,9 +62,7 @@ namespace { namespace openspace { documentation::Documentation DashboardItemPropertyValue::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_dashboarditem_propertyvalue"; - return doc; + return codegen::doc("base_dashboarditem_propertyvalue"); } DashboardItemPropertyValue::DashboardItemPropertyValue( diff --git a/modules/base/dashboard/dashboarditemsimulationincrement.cpp b/modules/base/dashboard/dashboarditemsimulationincrement.cpp index 6648503c41..1dbe386066 100644 --- a/modules/base/dashboard/dashboarditemsimulationincrement.cpp +++ b/modules/base/dashboard/dashboarditemsimulationincrement.cpp @@ -101,9 +101,7 @@ namespace { namespace openspace { documentation::Documentation DashboardItemSimulationIncrement::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_dashboarditem_simulationincrement"; - return doc; + return codegen::doc("base_dashboarditem_simulationincrement"); } DashboardItemSimulationIncrement::DashboardItemSimulationIncrement( diff --git a/modules/base/dashboard/dashboarditemspacing.cpp b/modules/base/dashboard/dashboarditemspacing.cpp index 5b615f769b..83d32c5262 100644 --- a/modules/base/dashboard/dashboarditemspacing.cpp +++ b/modules/base/dashboard/dashboarditemspacing.cpp @@ -46,9 +46,7 @@ namespace { namespace openspace { documentation::Documentation DashboardItemSpacing::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_dashboarditem_spacing"; - return doc; + return codegen::doc("base_dashboarditem_spacing"); } DashboardItemSpacing::DashboardItemSpacing(const ghoul::Dictionary& dictionary) diff --git a/modules/base/dashboard/dashboarditemtext.cpp b/modules/base/dashboard/dashboarditemtext.cpp index 690da61c6a..321c746310 100644 --- a/modules/base/dashboard/dashboarditemtext.cpp +++ b/modules/base/dashboard/dashboarditemtext.cpp @@ -50,9 +50,7 @@ namespace { namespace openspace { documentation::Documentation DashboardItemText::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_dashboarditem_text"; - return doc; + return codegen::doc("base_dashboarditem_text"); } DashboardItemText::DashboardItemText(const ghoul::Dictionary& dictionary) diff --git a/modules/base/dashboard/dashboarditemvelocity.cpp b/modules/base/dashboard/dashboarditemvelocity.cpp index 587e83f4f3..c13782c8aa 100644 --- a/modules/base/dashboard/dashboarditemvelocity.cpp +++ b/modules/base/dashboard/dashboarditemvelocity.cpp @@ -83,9 +83,7 @@ namespace { namespace openspace { documentation::Documentation DashboardItemVelocity::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_dashboarditem_velocity"; - return doc; + return codegen::doc("base_dashboarditem_velocity"); } DashboardItemVelocity::DashboardItemVelocity(const ghoul::Dictionary& dictionary) diff --git a/modules/base/lightsource/cameralightsource.cpp b/modules/base/lightsource/cameralightsource.cpp index d878e5cf45..198fa95906 100644 --- a/modules/base/lightsource/cameralightsource.cpp +++ b/modules/base/lightsource/cameralightsource.cpp @@ -46,9 +46,7 @@ namespace { namespace openspace { documentation::Documentation CameraLightSource::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_camera_light_source"; - return doc; + return codegen::doc("base_camera_light_source"); } CameraLightSource::CameraLightSource() diff --git a/modules/base/lightsource/scenegraphlightsource.cpp b/modules/base/lightsource/scenegraphlightsource.cpp index 671f7efd75..5a2d32a39a 100644 --- a/modules/base/lightsource/scenegraphlightsource.cpp +++ b/modules/base/lightsource/scenegraphlightsource.cpp @@ -59,9 +59,7 @@ namespace { namespace openspace { documentation::Documentation SceneGraphLightSource::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_scene_graph_light_source"; - return doc; + return codegen::doc("base_scene_graph_light_source"); } SceneGraphLightSource::SceneGraphLightSource() diff --git a/modules/base/rendering/grids/renderableboxgrid.cpp b/modules/base/rendering/grids/renderableboxgrid.cpp index 9f35f6541b..9f14d86fdc 100644 --- a/modules/base/rendering/grids/renderableboxgrid.cpp +++ b/modules/base/rendering/grids/renderableboxgrid.cpp @@ -72,9 +72,7 @@ namespace { namespace openspace { documentation::Documentation RenderableBoxGrid::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_renderable_boxgrid"; - return doc; + return codegen::doc("base_renderable_boxgrid"); } RenderableBoxGrid::RenderableBoxGrid(const ghoul::Dictionary& dictionary) diff --git a/modules/base/rendering/grids/renderablegrid.cpp b/modules/base/rendering/grids/renderablegrid.cpp index c79f5785dc..a3065666cf 100644 --- a/modules/base/rendering/grids/renderablegrid.cpp +++ b/modules/base/rendering/grids/renderablegrid.cpp @@ -82,9 +82,7 @@ namespace { namespace openspace { documentation::Documentation RenderableGrid::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_renderable_grid"; - return doc; + return codegen::doc("base_renderable_grid"); } RenderableGrid::RenderableGrid(const ghoul::Dictionary& dictionary) @@ -92,7 +90,7 @@ RenderableGrid::RenderableGrid(const ghoul::Dictionary& dictionary) , _color(ColorInfo, glm::vec3(0.5f), glm::vec3(0.f), glm::vec3(1.f)) , _segments(SegmentsInfo, glm::uvec2(10), glm::uvec2(1), glm::uvec2(200)) , _lineWidth(LineWidthInfo, 0.5f, 1.f, 20.f) - , _size(SizeInfo, glm::vec2(1e10f), glm::vec2(1.f), glm::vec2(1e20f)) + , _size(SizeInfo, glm::vec2(1.f), glm::vec2(1.f), glm::vec2(1e11f)) { const Parameters p = codegen::bake(dictionary); @@ -110,7 +108,7 @@ RenderableGrid::RenderableGrid(const ghoul::Dictionary& dictionary) _lineWidth = p.lineWidth.value_or(_lineWidth); addProperty(_lineWidth); - _size.setViewOption(properties::Property::ViewOptions::Logarithmic); + _size.setExponent(10.f); _size = p.size.value_or(_size); _size.onChange([&]() { _gridIsDirty = true; }); addProperty(_size); diff --git a/modules/base/rendering/grids/renderableradialgrid.cpp b/modules/base/rendering/grids/renderableradialgrid.cpp index fd2150e178..eda326d974 100644 --- a/modules/base/rendering/grids/renderableradialgrid.cpp +++ b/modules/base/rendering/grids/renderableradialgrid.cpp @@ -65,17 +65,12 @@ namespace { "This value specifies the line width of the spherical grid." }; - constexpr openspace::properties::Property::PropertyInfo OuterRadiusInfo = { - "OuterRadius", - "Outer Radius", - "The outer radius of the circular grid, i.e. its size." - }; - - constexpr openspace::properties::Property::PropertyInfo InnerRadiusInfo = { - "InnerRadius", - "Inner Radius", - "The inner radius of the circular grid, that is the radius of the inmost ring. " - "Must be smaller than the outer radius." + constexpr openspace::properties::Property::PropertyInfo RadiiInfo = { + "Radii", + "Inner and Outer Radius", + "The radii values that determine the size of the circular grid. The first value " + "is the radius of the inmost ring and the second is the radius of the outmost " + "ring." }; struct [[codegen::Dictionary(RenderableRadialGrid)]] Parameters { @@ -91,11 +86,8 @@ namespace { // [[codegen::verbatim(LineWidthInfo.description)]] std::optional lineWidth; - // [[codegen::verbatim(OuterRadiusInfo.description)]] - std::optional outerRadius; - - // [[codegen::verbatim(InnerRadiusInfo.description)]] - std::optional innerRadius; + // [[codegen::verbatim(RadiiInfo.description)]] + std::optional radii; }; #include "renderableradialgrid_codegen.cpp" } // namespace @@ -103,9 +95,7 @@ namespace { namespace openspace { documentation::Documentation RenderableRadialGrid::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_renderable_radialgrid"; - return doc; + return codegen::doc("base_renderable_radialgrid"); } RenderableRadialGrid::RenderableRadialGrid(const ghoul::Dictionary& dictionary) @@ -114,8 +104,7 @@ RenderableRadialGrid::RenderableRadialGrid(const ghoul::Dictionary& dictionary) , _gridSegments(GridSegmentsInfo, glm::ivec2(1), glm::ivec2(1), glm::ivec2(200)) , _circleSegments(CircleSegmentsInfo, 36, 4, 200) , _lineWidth(LineWidthInfo, 0.5f, 1.f, 20.f) - , _maxRadius(OuterRadiusInfo, 1.f, 0.f, 20.f) - , _minRadius(InnerRadiusInfo, 0.f, 0.f, 20.f) + , _radii(RadiiInfo, glm::vec2(0.f, 1.f), glm::vec2(0.f), glm::vec2(20.f)) { const Parameters p = codegen::bake(dictionary); @@ -142,24 +131,11 @@ RenderableRadialGrid::RenderableRadialGrid(const ghoul::Dictionary& dictionary) _lineWidth = p.lineWidth.value_or(_lineWidth); addProperty(_lineWidth); - _minRadius = p.innerRadius.value_or(_minRadius); - _maxRadius = p.outerRadius.value_or(_maxRadius); + _radii = p.radii.value_or(_radii); + _radii.setViewOption(properties::Property::ViewOptions::MinMaxRange); + _radii.onChange([&]() { _gridIsDirty = true; }); - _maxRadius.setMinValue(_minRadius); - _minRadius.setMaxValue(_maxRadius); - - _maxRadius.onChange([&]() { - _gridIsDirty = true; - _minRadius.setMaxValue(_maxRadius); - }); - - _minRadius.onChange([&]() { - _gridIsDirty = true; - _maxRadius.setMinValue(_minRadius); - }); - - addProperty(_maxRadius); - addProperty(_minRadius); + addProperty(_radii); } bool RenderableRadialGrid::isReady() const { @@ -238,12 +214,15 @@ void RenderableRadialGrid::update(const UpdateData&) { return; } + const float innerRadius = _radii.value().x; + const float outerRadius = _radii.value().y; + // Circles const int nRadialSegments = _gridSegments.value()[0]; const float fnCircles = static_cast(nRadialSegments); - const float deltaRadius = (_maxRadius - _minRadius) / fnCircles; + const float deltaRadius = (outerRadius - innerRadius) / fnCircles; - const bool hasInnerRadius = _minRadius > 0; + const bool hasInnerRadius = innerRadius > 0.f; const int nCircles = hasInnerRadius ? nRadialSegments : nRadialSegments + 1; _circles.clear(); @@ -260,11 +239,11 @@ void RenderableRadialGrid::update(const UpdateData&) { // add an extra inmost circle if (hasInnerRadius) { - addRing(_circleSegments, _minRadius); + addRing(_circleSegments, innerRadius); } for (int i = 0; i < nRadialSegments; ++i) { - const float ri = static_cast(i + 1) * deltaRadius + _minRadius; + const float ri = static_cast(i + 1) * deltaRadius + innerRadius; addRing(_circleSegments, ri); } @@ -277,10 +256,10 @@ void RenderableRadialGrid::update(const UpdateData&) { if (nLines > 1) { std::vector outerVertices = - rendering::helper::createRing(nLines, _maxRadius); + rendering::helper::createRing(nLines, outerRadius); std::vector innerVertices = - rendering::helper::createRing(nLines, _minRadius); + rendering::helper::createRing(nLines, innerRadius); for (int i = 0; i < nLines; ++i) { const rendering::helper::VertexXYZ vOut = diff --git a/modules/base/rendering/grids/renderableradialgrid.h b/modules/base/rendering/grids/renderableradialgrid.h index f719808f3d..0c5b1270e3 100644 --- a/modules/base/rendering/grids/renderableradialgrid.h +++ b/modules/base/rendering/grids/renderableradialgrid.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -78,8 +79,7 @@ protected: properties::IVec2Property _gridSegments; properties::IntProperty _circleSegments; properties::FloatProperty _lineWidth; - properties::FloatProperty _maxRadius; - properties::FloatProperty _minRadius; + properties::Vec2Property _radii; bool _gridIsDirty = true; diff --git a/modules/base/rendering/grids/renderablesphericalgrid.cpp b/modules/base/rendering/grids/renderablesphericalgrid.cpp index 75a2b27fbf..52485c23af 100644 --- a/modules/base/rendering/grids/renderablesphericalgrid.cpp +++ b/modules/base/rendering/grids/renderablesphericalgrid.cpp @@ -73,9 +73,7 @@ namespace { namespace openspace { documentation::Documentation RenderableSphericalGrid::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_renderable_sphericalgrid"; - return doc; + return codegen::doc("base_renderable_sphericalgrid"); } RenderableSphericalGrid::RenderableSphericalGrid(const ghoul::Dictionary& dictionary) diff --git a/modules/base/rendering/renderablecartesianaxes.cpp b/modules/base/rendering/renderablecartesianaxes.cpp index 2a6a985522..9b658ac953 100644 --- a/modules/base/rendering/renderablecartesianaxes.cpp +++ b/modules/base/rendering/renderablecartesianaxes.cpp @@ -75,9 +75,7 @@ namespace { namespace openspace { documentation::Documentation RenderableCartesianAxes::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_renderable_cartesianaxes"; - return doc; + return codegen::doc("base_renderable_cartesianaxes"); } RenderableCartesianAxes::RenderableCartesianAxes(const ghoul::Dictionary& dictionary) diff --git a/modules/base/rendering/renderabledisc.cpp b/modules/base/rendering/renderabledisc.cpp index ca17160453..52a733131c 100644 --- a/modules/base/rendering/renderabledisc.cpp +++ b/modules/base/rendering/renderabledisc.cpp @@ -82,9 +82,7 @@ namespace { namespace openspace { documentation::Documentation RenderableDisc::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_renderable_disc"; - return doc; + return codegen::doc("base_renderable_disc"); } RenderableDisc::RenderableDisc(const ghoul::Dictionary& dictionary) @@ -96,10 +94,10 @@ RenderableDisc::RenderableDisc(const ghoul::Dictionary& dictionary) const Parameters p = codegen::bake(dictionary); _texturePath = p.texture.string(); - _texturePath.onChange([&]() { _texture->loadFromFile(_texturePath); }); + _texturePath.onChange([&]() { _texture->loadFromFile(_texturePath.value()); }); addProperty(_texturePath); - _size.setViewOption(properties::Property::ViewOptions::Logarithmic); + _size.setExponent(13.f); _size = p.size.value_or(_size); setBoundingSphere(_size); _size.onChange([&]() { _planeIsDirty = true; }); @@ -129,7 +127,7 @@ void RenderableDisc::initialize() { void RenderableDisc::initializeGL() { initializeShader(); - _texture->loadFromFile(_texturePath); + _texture->loadFromFile(_texturePath.value()); _texture->uploadToGpu(); _plane->initialize(); diff --git a/modules/base/rendering/renderablelabels.cpp b/modules/base/rendering/renderablelabels.cpp index 42c0ea0ab0..5125e2bed7 100644 --- a/modules/base/rendering/renderablelabels.cpp +++ b/modules/base/rendering/renderablelabels.cpp @@ -75,105 +75,78 @@ namespace { constexpr openspace::properties::Property::PropertyInfo BlendModeInfo = { "BlendMode", "Blending Mode", - "This determines the blending mode that is applied to this plane." + "This determines the blending mode that is applied to the renderable." }; - constexpr openspace::properties::Property::PropertyInfo LabelColorInfo = { - "LabelColor", - "Label Color", - "The label color for the astronomical object." + constexpr openspace::properties::Property::PropertyInfo ColorInfo = { + "Color", + "Color", + "The label text color." }; constexpr openspace::properties::Property::PropertyInfo FontSizeInfo = { "FontSize", "Font Size", - "The font size for the astronomical object labels." + "The font size (in points) for the label." }; - constexpr openspace::properties::Property::PropertyInfo LabelSizeInfo = { - "LabelSize", - "Label Size", - "The label size for the astronomical object labels." + constexpr openspace::properties::Property::PropertyInfo SizeInfo = { + "Size", + "Size", + "This value affects the size scale of the label." }; - constexpr openspace::properties::Property::PropertyInfo LabelTextInfo = { - "LabelText", - "Label Text", + constexpr openspace::properties::Property::PropertyInfo TextInfo = { + "Text", + "Text", "The text that will be displayed on screen." }; - constexpr openspace::properties::Property::PropertyInfo LabelMinSizeInfo = { - "LabelMinSize", - "Label Min Size", - "The minimal size (in pixels) of the labels for the astronomical " - "objects being rendered." - }; - - constexpr openspace::properties::Property::PropertyInfo LabelMaxSizeInfo = { - "LabelMaxSize", - "Label Max Size", - "The maximum size (in pixels) of the labels for the astronomical " - "objects being rendered." + constexpr openspace::properties::Property::PropertyInfo MinMaxSizeInfo = { + "MinMaxSize", + "Min and Max Size", + "The minimum and maximum size (in pixels) of the label." }; constexpr openspace::properties::Property::PropertyInfo TransformationMatrixInfo = { "TransformationMatrix", "Transformation Matrix", - "Transformation matrix to be applied to each astronomical object." + "Transformation matrix to be applied to the label." }; - constexpr openspace::properties::Property::PropertyInfo LabelOrientationOptionInfo = { - "LabelOrientationOption", - "Label Orientation Option", + constexpr openspace::properties::Property::PropertyInfo OrientationOptionInfo = { + "OrientationOption", + "Orientation Option", "Label orientation rendering mode." }; constexpr openspace::properties::Property::PropertyInfo EnableFadingEffectInfo = { "EnableFading", - "Enable/Disable Fade-in effect", + "Enable/Disable Fade-in Effect", "Enable/Disable the Fade-in effect." }; - constexpr openspace::properties::Property::PropertyInfo PixelSizeControlInfo = { - "EnablePixelSizeControl", - "Enable pixel size control.", - "Enable pixel size control for rectangular projections." + constexpr openspace::properties::Property::PropertyInfo FadeWidthsInfo = { + "FadeWidths", + "Fade Widths", + "The distances over which the fading takes place, given in the specified unit. " + "The first value is the distance before the closest distance and the second " + "the one after the furthest distance. For example, with the unit Parsec (pc), " + "a value of {1, 2} will make the label being fully faded out 1 Parsec before " + "the closest distance and 2 Parsec away from the furthest distance." }; - constexpr openspace::properties::Property::PropertyInfo FadeStartUnitOptionInfo = { - "FadeStartUnit", - "Fade-In/-Out Start Unit.", - "Unit for fade-in/-out starting position calculation." + constexpr openspace::properties::Property::PropertyInfo FadeDistancesInfo = { + "FadeDistances", + "Fade Distances", + "The distance range in which the labels should be fully opaque, specified in " + "the chosen unit. The distance from the position of the label to the camera." }; - constexpr openspace::properties::Property::PropertyInfo FadeEndUnitOptionInfo = { - "FadeEndUnit", - "Fade-In/-Out End Unit.", - "Unit for fade-in/-out ending position calculation." - }; - - constexpr openspace::properties::Property::PropertyInfo FadeStartDistInfo = { - "FadeStartDistance", - "Fade-In/-Out starting distance.", - "Fade-In/-Out starting distance." - }; - - constexpr openspace::properties::Property::PropertyInfo FadeEndDistInfo = { - "FadeEndDistance", - "Fade-In/-Out ending distance.", - "Fade-In/-Out ending distance." - }; - - constexpr openspace::properties::Property::PropertyInfo FadeStartSpeedInfo = { - "FadeStartSpeed", - "Fade-In/-Out starting speed.", - "Fade-In/-Out starting speed." - }; - - constexpr openspace::properties::Property::PropertyInfo FadeEndSpeedInfo = { - "FadeEndSpeed", - "Fade-In/-Out ending speed.", - "Fade-In/-Out ending speed." + constexpr openspace::properties::Property::PropertyInfo FadeUnitOptionInfo = { + "FadeUnit", + "Fade Distance Unit", + "Distance unit for fade-in/-out distance calculations. Defaults to \"au\"." }; struct [[codegen::Dictionary(RenderableLabels)]] Parameters { @@ -190,33 +163,27 @@ namespace { PositionNormal [[codegen::key("Camera Position Normal")]] }; - // [[codegen::verbatim(LabelOrientationOptionInfo.description)]] - std::optional labelOrientationOption; + // [[codegen::verbatim(OrientationOptionInfo.description)]] + std::optional orientationOption; - // [[codegen::verbatim(LabelColorInfo.description)]] - std::optional labelColor [[codegen::color()]]; + // [[codegen::verbatim(ColorInfo.description)]] + std::optional color [[codegen::color()]]; - // [[codegen::verbatim(LabelTextInfo.description)]] - std::optional labelText; + // [[codegen::verbatim(TextInfo.description)]] + std::optional text; // [[codegen::verbatim(FontSizeInfo.description)]] std::optional fontSize; - // [[codegen::verbatim(LabelSizeInfo.description)]] - std::optional labelSize; + // [[codegen::verbatim(SizeInfo.description)]] + std::optional size; - // [[codegen::verbatim(LabelMinSizeInfo.description)]] - std::optional labelMinSize; - - // [[codegen::verbatim(LabelMaxSizeInfo.description)]] - std::optional labelMaxSize; + // [[codegen::verbatim(MinMaxSizeInfo.description)]] + std::optional minMaxSize; // [[codegen::verbatim(EnableFadingEffectInfo.description)]] std::optional enableFading; - // [[codegen::verbatim(PixelSizeControlInfo.description)]] - std::optional enablePixelControl; - // [[codegen::verbatim(TransformationMatrixInfo.description)]] std::optional transformationMatrix; @@ -230,28 +197,19 @@ namespace { AstronomicalUnit [[codegen::key("au")]], Parsec [[codegen::key("pc")]], KiloParsec [[codegen::key("Kpc")]], - MegaParsec [[codgen::key("Mpc")]], + MegaParsec [[codegen::key("Mpc")]], GigaParsec [[codegen::key("Gpc")]], GigaLightyear [[codegen::key("Gly")]] }; - // [[codegen::verbatim(FadeStartUnitOptionInfo.description)]] - std::optional fadeStartUnit; + // [[codegen::verbatim(FadeUnitOptionInfo.description)]] + std::optional fadeUnit; - // [[codegen::verbatim(FadeEndUnitOptionInfo.description)]] - std::optional fadeEndUnit; + // [[codegen::verbatim(FadeDistancesInfo.description)]] + std::optional fadeDistances; - // [[codegen::verbatim(FadeStartDistInfo.description)]] - std::optional fadeStartDistance; - - // [[codegen::verbatim(FadeEndDistInfo.description)]] - std::optional fadeEndDistance; - - // [[codegen::verbatim(FadeStartSpeedInfo.description)]] - std::optional fadeStartSpeed; - - // [[codegen::verbatim(FadeEndSpeedInfo.description)]] - std::optional fadeEndSpeed; + // [[codegen::verbatim(FadeWidthsInfo.description)]] + std::optional fadeWidths; }; #include "renderablelabels_codegen.cpp" } // namespace @@ -259,39 +217,26 @@ namespace { namespace openspace { documentation::Documentation RenderableLabels::Documentation() { - return codegen::doc(); + return codegen::doc("base_renderable_labels"); } RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _blendMode(BlendModeInfo, properties::OptionProperty::DisplayType::Dropdown) - , _labelColor( - LabelColorInfo, - glm::vec3(1.f, 1.f, 1.f), - glm::vec3(0.f), - glm::vec3(1.f) - ) - , _labelSize(LabelSizeInfo, 8.f, 0.5f, 30.f) + , _color(ColorInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(1.f)) + , _size(SizeInfo, 8.f, 0.5f, 30.f) , _fontSize(FontSizeInfo, 50.f, 1.f, 100.f) - , _labelMinSize(LabelMinSizeInfo, 8.f, 0.5f, 24.f) - , _labelMaxSize(LabelMaxSizeInfo, 20.f, 0.5f, 100.f) - , _pixelSizeControl(PixelSizeControlInfo, false) + , _minMaxSize(MinMaxSizeInfo, glm::ivec2(8, 20), glm::ivec2(0), glm::ivec2(100)) , _enableFadingEffect(EnableFadingEffectInfo, false) - , _labelText(LabelTextInfo, "") - , _fadeStartDistance(FadeStartDistInfo, 1.f, 0.f, 100.f) - , _fadeEndDistance(FadeEndDistInfo, 1.f, 0.f, 100.f) - , _fadeStartSpeed(FadeStartSpeedInfo, 1.f, 1.f, 100.f) - , _fadeEndSpeed(FadeEndSpeedInfo, 1.f, 1.f, 100.f) - , _labelOrientationOption( - LabelOrientationOptionInfo, + , _text(TextInfo, "") + , _fadeDistances(FadeDistancesInfo, glm::vec2(1.f), glm::vec2(0.f), glm::vec2(100.f)) + , _fadeWidths(FadeWidthsInfo, glm::vec2(1.f), glm::vec2(0.f), glm::vec2(100.f)) + , _orientationOption( + OrientationOptionInfo, properties::OptionProperty::DisplayType::Dropdown ) - , _fadeStartUnitOption( - FadeStartUnitOptionInfo, - properties::OptionProperty::DisplayType::Dropdown - ) - , _fadeEndUnitOption( - FadeEndUnitOptionInfo, + , _fadeUnitOption( + FadeUnitOptionInfo, properties::OptionProperty::DisplayType::Dropdown ) { @@ -330,28 +275,28 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) addProperty(_blendMode); - _labelOrientationOption.addOption(ViewDirection, "Camera View Direction"); - _labelOrientationOption.addOption(NormalDirection, "Camera Position Normal"); + _orientationOption.addOption(ViewDirection, "Camera View Direction"); + _orientationOption.addOption(NormalDirection, "Camera Position Normal"); - _labelOrientationOption = NormalDirection; - if (p.labelOrientationOption.has_value()) { - switch (*p.labelOrientationOption) { + _orientationOption = NormalDirection; + if (p.orientationOption.has_value()) { + switch (*p.orientationOption) { case Parameters::Orientation::ViewDirection: - _labelOrientationOption = ViewDirection; + _orientationOption = ViewDirection; break; case Parameters::Orientation::PositionNormal: - _labelOrientationOption = NormalDirection; + _orientationOption = NormalDirection; break; } } - addProperty(_labelOrientationOption); + addProperty(_orientationOption); - _labelText = p.labelText.value_or(_labelText); - addProperty(_labelText); + _text = p.text.value_or(_text); + addProperty(_text); - _labelColor = p.labelColor.value_or(_labelColor); - _labelColor.setViewOption(properties::Property::ViewOptions::Color); - addProperty(_labelColor); + _color = p.color.value_or(_color); + _color.setViewOption(properties::Property::ViewOptions::Color); + addProperty(_color); _fontSize = p.fontSize.value_or(_fontSize); _fontSize.onChange([&]() { @@ -364,156 +309,86 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) }); addProperty(_fontSize); - _labelSize = p.labelSize.value_or(_labelSize); - addProperty(_labelSize); + // @TODO (emmbr, 2021-05-31): Temporarily set as read only, to avoid errors from font + // rendering/loading + _fontSize.setReadOnly(true); - _labelMinSize = p.labelMinSize.value_or(_labelMinSize); - addProperty(_labelMinSize); + _size = p.size.value_or(_size); + addProperty(_size); - _labelMaxSize = p.labelMaxSize.value_or(_labelMaxSize); - addProperty(_labelMaxSize); + _minMaxSize = p.minMaxSize.value_or(_minMaxSize); + _minMaxSize.setViewOption(properties::Property::ViewOptions::MinMaxRange); + addProperty(_minMaxSize); _transformationMatrix = p.transformationMatrix.value_or(_transformationMatrix); - _pixelSizeControl = p.enablePixelControl.value_or(_pixelSizeControl); - if (_pixelSizeControl) { - // @TODO (abock, 2021-01-28) I don't know why we only add the property if the - // pixel control is enabled, but I think this is an error - addProperty(_pixelSizeControl); - } - _enableFadingEffect = p.enableFading.value_or(_enableFadingEffect); addProperty(_enableFadingEffect); - _fadeStartDistance = p.fadeStartDistance.value_or(_fadeStartDistance); - addProperty(_fadeStartDistance); + _fadeUnitOption.addOption(Meter, MeterUnit); + _fadeUnitOption.addOption(Kilometer, KilometerUnit); + _fadeUnitOption.addOption(Megameter, MegameterUnit); + _fadeUnitOption.addOption(Gigameter, GigameterUnit); + _fadeUnitOption.addOption(AU, AstronomicalUnit); + _fadeUnitOption.addOption(Terameter, TerameterUnit); + _fadeUnitOption.addOption(Petameter, PetameterUnit); + _fadeUnitOption.addOption(Parsec, ParsecUnit); + _fadeUnitOption.addOption(Kiloparsec, KiloparsecUnit); + _fadeUnitOption.addOption(Megaparsec, MegaparsecUnit); + _fadeUnitOption.addOption(Gigaparsec, GigaparsecUnit); + _fadeUnitOption.addOption(GigalightYears, GigalightyearUnit); - _fadeStartUnitOption.addOption(Meter, MeterUnit); - _fadeStartUnitOption.addOption(Kilometer, KilometerUnit); - _fadeStartUnitOption.addOption(Megameter, MegameterUnit); - _fadeStartUnitOption.addOption(Gigameter, GigameterUnit); - _fadeStartUnitOption.addOption(AU, AstronomicalUnit); - _fadeStartUnitOption.addOption(Terameter, TerameterUnit); - _fadeStartUnitOption.addOption(Petameter, PetameterUnit); - _fadeStartUnitOption.addOption(Parsec, ParsecUnit); - _fadeStartUnitOption.addOption(Kiloparsec, KiloparsecUnit); - _fadeStartUnitOption.addOption(Megaparsec, MegaparsecUnit); - _fadeStartUnitOption.addOption(Gigaparsec, GigaparsecUnit); - _fadeStartUnitOption.addOption(GigalightYears, GigalightyearUnit); - - - if (p.fadeStartUnit.has_value()) { - switch (*p.fadeStartUnit) { + if (p.fadeUnit.has_value()) { + switch (*p.fadeUnit) { case Parameters::Unit::Meter: - _fadeStartUnitOption = Meter; + _fadeUnitOption = Meter; break; case Parameters::Unit::Kilometer: - _fadeStartUnitOption = Kilometer; + _fadeUnitOption = Kilometer; break; case Parameters::Unit::Megameter: - _fadeStartUnitOption = Megameter; + _fadeUnitOption = Megameter; break; case Parameters::Unit::Gigameter: - _fadeStartUnitOption = Gigameter; + _fadeUnitOption = Gigameter; break; case Parameters::Unit::Terameter: - _fadeStartUnitOption = Terameter; + _fadeUnitOption = Terameter; break; case Parameters::Unit::Petameter: - _fadeStartUnitOption = Petameter; + _fadeUnitOption = Petameter; break; case Parameters::Unit::AstronomicalUnit: - _fadeStartUnitOption = AU; + _fadeUnitOption = AU; break; case Parameters::Unit::Parsec: - _fadeStartUnitOption = Parsec; + _fadeUnitOption = Parsec; break; case Parameters::Unit::KiloParsec: - _fadeStartUnitOption = Kiloparsec; + _fadeUnitOption = Kiloparsec; break; case Parameters::Unit::MegaParsec: - _fadeStartUnitOption = Megaparsec; + _fadeUnitOption = Megaparsec; break; case Parameters::Unit::GigaParsec: - _fadeStartUnitOption = Gigaparsec; + _fadeUnitOption = Gigaparsec; break; case Parameters::Unit::GigaLightyear: - _fadeStartUnitOption = GigalightYears; + _fadeUnitOption = GigalightYears; break; } } else { - _fadeStartUnitOption = AU; + _fadeUnitOption = AU; } - addProperty(_fadeStartUnitOption); + addProperty(_fadeUnitOption); - _fadeStartSpeed = p.fadeStartSpeed.value_or(_fadeStartSpeed); - addProperty(_fadeStartSpeed); + _fadeDistances = p.fadeDistances.value_or(_fadeDistances); + _fadeDistances.setViewOption(properties::Property::ViewOptions::MinMaxRange); + addProperty(_fadeDistances); - _fadeEndDistance = p.fadeEndDistance.value_or(_fadeEndDistance); - addProperty(_fadeEndDistance); - - _fadeEndUnitOption.addOption(Meter, MeterUnit); - _fadeEndUnitOption.addOption(Kilometer, KilometerUnit); - _fadeEndUnitOption.addOption(Megameter, MegameterUnit); - _fadeEndUnitOption.addOption(Gigameter, GigameterUnit); - _fadeEndUnitOption.addOption(AU, AstronomicalUnit); - _fadeEndUnitOption.addOption(Terameter, TerameterUnit); - _fadeEndUnitOption.addOption(Petameter, PetameterUnit); - _fadeEndUnitOption.addOption(Parsec, ParsecUnit); - _fadeEndUnitOption.addOption(Kiloparsec, KiloparsecUnit); - _fadeEndUnitOption.addOption(Megaparsec, MegaparsecUnit); - _fadeEndUnitOption.addOption(Gigaparsec, GigaparsecUnit); - _fadeEndUnitOption.addOption(GigalightYears, GigalightyearUnit); - - - if (p.fadeEndUnit.has_value()) { - switch (*p.fadeEndUnit) { - case Parameters::Unit::Meter: - _fadeStartUnitOption = Meter; - break; - case Parameters::Unit::Kilometer: - _fadeStartUnitOption = Kilometer; - break; - case Parameters::Unit::Megameter: - _fadeStartUnitOption = Megameter; - break; - case Parameters::Unit::Gigameter: - _fadeStartUnitOption = Gigameter; - break; - case Parameters::Unit::Terameter: - _fadeStartUnitOption = Terameter; - break; - case Parameters::Unit::Petameter: - _fadeStartUnitOption = Petameter; - break; - case Parameters::Unit::AstronomicalUnit: - _fadeStartUnitOption = AU; - break; - case Parameters::Unit::Parsec: - _fadeStartUnitOption = Parsec; - break; - case Parameters::Unit::KiloParsec: - _fadeEndUnitOption = Kiloparsec; - break; - case Parameters::Unit::MegaParsec: - _fadeEndUnitOption = Megaparsec; - break; - case Parameters::Unit::GigaParsec: - _fadeEndUnitOption = Gigaparsec; - break; - case Parameters::Unit::GigaLightyear: - _fadeEndUnitOption = GigalightYears; - break; - } - } - else { - _fadeEndUnitOption = AU; - } - addProperty(_fadeEndUnitOption); - - _fadeEndSpeed = p.fadeEndSpeed.value_or(_fadeEndSpeed); - addProperty(_fadeEndSpeed); + _fadeWidths = p.fadeWidths.value_or(_fadeWidths); + addProperty(_fadeWidths); } bool RenderableLabels::isReady() const { @@ -528,7 +403,6 @@ void RenderableLabels::initialize() { void RenderableLabels::initializeGL() { if (_font == nullptr) { - //size_t _fontSize = 50; _font = global::fontManager->font( "Mono", _fontSize, @@ -554,17 +428,7 @@ void RenderableLabels::render(const RenderData& data, RendererTasks&) { float distanceNodeToCamera = static_cast( glm::distance(data.camera.positionVec3(), data.modelTransform.translation) ); - float sUnit = unit(_fadeStartUnitOption); - float eUnit = unit(_fadeEndUnitOption); - float startX = _fadeStartDistance * sUnit; - float endX = _fadeEndDistance * eUnit; - fadeInVariable = linearSmoothStepFunc( - distanceNodeToCamera, - startX, - endX, - sUnit, - eUnit - ); + fadeInVariable = computeFadeFactor(distanceNodeToCamera); } glm::dmat4 modelMatrix(1.0); @@ -598,7 +462,7 @@ void RenderableLabels::render(const RenderData& data, RendererTasks&) { void RenderableLabels::setLabelText(const std::string & newText) { - _labelText = newText; + _text = newText; } void RenderableLabels::renderLabels(const RenderData& data, @@ -606,23 +470,23 @@ void RenderableLabels::renderLabels(const RenderData& data, const glm::dvec3& orthoRight, const glm::dvec3& orthoUp, float fadeInVariable) { - glm::vec4 textColor = glm::vec4(glm::vec3(_labelColor), 1.f); + glm::vec4 textColor = glm::vec4(glm::vec3(_color), 1.f); textColor.a *= fadeInVariable; textColor.a *= _opacity; ghoul::fontrendering::FontRenderer::ProjectedLabelsInformation labelInfo; - labelInfo.orthoRight = orthoRight; - labelInfo.orthoUp = orthoUp; - labelInfo.minSize = static_cast(_labelMinSize); - labelInfo.maxSize = static_cast(_labelMaxSize); - labelInfo.cameraPos = data.camera.positionVec3(); - labelInfo.cameraLookUp = data.camera.lookUpVectorWorldSpace(); - labelInfo.renderType = _labelOrientationOption; - labelInfo.mvpMatrix = modelViewProjectionMatrix; - labelInfo.scale = powf(10.f, _labelSize); - labelInfo.enableDepth = true; + labelInfo.orthoRight = orthoRight; + labelInfo.orthoUp = orthoUp; + labelInfo.minSize = _minMaxSize.value().x; + labelInfo.maxSize = _minMaxSize.value().y; + labelInfo.cameraPos = data.camera.positionVec3(); + labelInfo.cameraLookUp = data.camera.lookUpVectorWorldSpace(); + labelInfo.renderType = _orientationOption; + labelInfo.mvpMatrix = modelViewProjectionMatrix; + labelInfo.scale = powf(10.f, _size); + labelInfo.enableDepth = true; labelInfo.enableFalseDepth = false; // We don't use spice rotation and scale @@ -633,52 +497,34 @@ void RenderableLabels::renderLabels(const RenderData& data, ghoul::fontrendering::FontRenderer::defaultProjectionRenderer().render( *_font, transformedPos, - _labelText.value(), + _text.value(), textColor, labelInfo ); } -float RenderableLabels::changedPerlinSmoothStepFunc(float x, float startX, - float endX) const -{ - float f1 = 6.f * powf((x - startX), 5.f) - 15.f * powf((x - startX), 4.f) + - 10.f * powf((x - startX), 3.f); - float f2 = -6.f * powf((x - endX), 5.f) + 15.f * powf((x - endX), 4.f) - - 10.f * powf((x - endX), 3.f) + 1.f; - float f3 = 1.f; +float RenderableLabels::computeFadeFactor(float distanceNodeToCamera) const { + float distanceUnit = unit(_fadeUnitOption); + + float x = distanceNodeToCamera; + float startX = _fadeDistances.value().x * distanceUnit; + float endX = _fadeDistances.value().y * distanceUnit; + + // The distances over which the fading should happen + float fadingStartDistance = _fadeWidths.value().x * distanceUnit; + float fadingEndDistance = _fadeWidths.value().y * distanceUnit; if (x <= startX) { + float f1 = 1.f - (startX - x) / fadingStartDistance; return std::clamp(f1, 0.f, 1.f); } else if (x > startX && x < endX) { - return f3; + return 1.f; // not faded } - else if (x >= endX) { + else { // x >= endX + float f2 = 1.f - (x - endX) / fadingEndDistance; return std::clamp(f2, 0.f, 1.f); } - return x; -} - -float RenderableLabels::linearSmoothStepFunc(float x, float startX, float endX, - float sUnit, float eUnit) const -{ - float sdiv = 1.f / (sUnit * _fadeStartSpeed); - float ediv = -1.f / (eUnit * _fadeEndSpeed); - float f1 = sdiv * (x - startX) + 1.f; - float f2 = ediv * (x - endX) + 1.f; - float f3 = 1.f; - - if (x <= startX) { - return std::clamp(f1, 0.f, 1.f); - } - else if (x > startX && x < endX) { - return f3; - } - else if (x >= endX) { - return std::clamp(f2, 0.f, 1.f); - } - return x; } float RenderableLabels::unit(int unit) const { diff --git a/modules/base/rendering/renderablelabels.h b/modules/base/rendering/renderablelabels.h index a1cad2dd6d..d1cff72716 100644 --- a/modules/base/rendering/renderablelabels.h +++ b/modules/base/rendering/renderablelabels.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -77,7 +78,7 @@ protected: std::string toString(int unit) const; // Data may require some type of transformation prior the spice transformation being - // applied. + // applied glm::dmat4 _transformationMatrix = glm::dmat4(1.0); enum Unit { @@ -99,31 +100,24 @@ private: void renderLabels(const RenderData& data, const glm::dmat4& modelViewProjectionMatrix, const glm::dvec3& orthoRight, const glm::dvec3& orthoUp, float fadeInVariable); - float changedPerlinSmoothStepFunc(float x, float startX, float endX) const; + float computeFadeFactor(float distanceNodeToCamera) const; - float linearSmoothStepFunc(float x, float startX, float endX, float sUnit, - float eUnit) const; - - properties::Vec3Property _labelColor; - properties::FloatProperty _labelSize; + properties::Vec3Property _color; properties::FloatProperty _fontSize; - properties::FloatProperty _labelMinSize; - properties::FloatProperty _labelMaxSize; - properties::BoolProperty _pixelSizeControl; - properties::BoolProperty _enableFadingEffect; - properties::StringProperty _labelText; - properties::FloatProperty _fadeStartDistance; - properties::FloatProperty _fadeEndDistance; - properties::FloatProperty _fadeStartSpeed; - properties::FloatProperty _fadeEndSpeed; + properties::FloatProperty _size; + properties::IVec2Property _minMaxSize; - properties::OptionProperty _labelOrientationOption; - properties::OptionProperty _fadeStartUnitOption; - properties::OptionProperty _fadeEndUnitOption; + properties::StringProperty _text; + + properties::BoolProperty _enableFadingEffect; + properties::Vec2Property _fadeWidths; + properties::Vec2Property _fadeDistances; + properties::OptionProperty _fadeUnitOption; + + properties::OptionProperty _orientationOption; std::shared_ptr _font; - std::string _speckFile; std::string _colorMapFile; std::string _labelFile; std::string _colorOptionString; diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index f7003a17cb..892c7d6bd1 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -157,13 +157,27 @@ namespace { Centimeter, Decimeter, Meter, - Kilometer + Kilometer, + + // Weird units + Thou, + Inch, + Foot, + Yard, + Chain, + Furlong, + Mile }; // The scale of the model. For example if the model is in centimeters // then ModelScale = Centimeter or ModelScale = 0.01 std::optional> modelScale; + // By default the given ModelScale is used to scale the model down, + // by setting this setting to true the model is instead scaled up with the + // given ModelScale + std::optional invertModelScale; + // Set if invisible parts (parts with no textures or materials) of the model // should be forced to render or not. std::optional forceRenderInvisible; @@ -203,13 +217,13 @@ namespace { std::optional animationMode; // [[codegen::verbatim(AmbientIntensityInfo.description)]] - std::optional ambientIntensity; + std::optional ambientIntensity; // [[codegen::verbatim(DiffuseIntensityInfo.description)]] - std::optional diffuseIntensity; + std::optional diffuseIntensity; // [[codegen::verbatim(SpecularIntensityInfo.description)]] - std::optional specularIntensity; + std::optional specularIntensity; // [[codegen::verbatim(ShadingInfo.description)]] std::optional performShading; @@ -242,9 +256,7 @@ namespace { namespace openspace { documentation::Documentation RenderableModel::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_renderable_model"; - return doc; + return codegen::doc("base_renderable_model"); } RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) @@ -262,8 +274,8 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) glm::dmat3(1.0) ) , _rotationVec(RotationVecInfo, glm::dvec3(0.0), glm::dvec3(0.0), glm::dvec3(360.0)) - , _enableOpacityBlending(EnableOpacityBlendingInfo, false) , _disableDepthTest(DisableDepthTestInfo, false) + , _enableOpacityBlending(EnableOpacityBlendingInfo, false) , _blendingFuncOption( BlendingOptionInfo, properties::OptionProperty::DisplayType::Dropdown @@ -285,13 +297,15 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) } } - std::string file = absPath(p.geometryFile.string()); + std::string file = absPath(p.geometryFile.string()).string(); _geometry = ghoul::io::ModelReader::ref().loadModel( file, ghoul::io::ModelReader::ForceRenderInvisible(_forceRenderInvisible), ghoul::io::ModelReader::NotifyInvisibleDropped(_notifyInvisibleDropped) ); + _invertModelScale = p.invertModelScale.value_or(_invertModelScale); + if (p.modelScale.has_value()) { if (std::holds_alternative(*p.modelScale)) { Parameters::ScaleUnit scaleUnit = @@ -320,10 +334,33 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) case Parameters::ScaleUnit::Kilometer: distanceUnit = DistanceUnit::Kilometer; break; + + // Weired units + case Parameters::ScaleUnit::Thou: + distanceUnit = DistanceUnit::Thou; + break; + case Parameters::ScaleUnit::Inch: + distanceUnit = DistanceUnit::Inch; + break; + case Parameters::ScaleUnit::Foot: + distanceUnit = DistanceUnit::Foot; + break; + case Parameters::ScaleUnit::Yard: + distanceUnit = DistanceUnit::Yard; + break; + case Parameters::ScaleUnit::Chain: + distanceUnit = DistanceUnit::Chain; + break; + case Parameters::ScaleUnit::Furlong: + distanceUnit = DistanceUnit::Furlong; + break; + case Parameters::ScaleUnit::Mile: + distanceUnit = DistanceUnit::Mile; + break; default: throw ghoul::MissingCaseException(); } - _modelScale = convertUnit(distanceUnit, DistanceUnit::Meter); + _modelScale = toMeter(distanceUnit); } else if (std::holds_alternative(*p.modelScale)) { _modelScale = std::get(*p.modelScale); @@ -331,6 +368,10 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) else { throw ghoul::MissingCaseException(); } + + if (_invertModelScale) { + _modelScale = 1.0 / _modelScale; + } } if (p.animationStartTime.has_value()) { @@ -385,7 +426,9 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) throw ghoul::MissingCaseException(); } - _geometry->setTimeScale(convertTime(1.0, timeUnit, TimeUnit::Second)); + _geometry->setTimeScale(static_cast( + convertTime(1.0, timeUnit, TimeUnit::Second)) + ); } else { throw ghoul::MissingCaseException(); diff --git a/modules/base/rendering/renderablemodel.h b/modules/base/rendering/renderablemodel.h index d1d2cbc9fa..1de33afe5b 100644 --- a/modules/base/rendering/renderablemodel.h +++ b/modules/base/rendering/renderablemodel.h @@ -81,6 +81,7 @@ private: std::unique_ptr _geometry; double _modelScale = 1.0; + bool _invertModelScale = false; bool _forceRenderInvisible = false; bool _notifyInvisibleDropped = true; std::string _animationStart; @@ -88,7 +89,6 @@ private: properties::BoolProperty _enableAnimation; properties::FloatProperty _ambientIntensity; - properties::FloatProperty _diffuseIntensity; properties::FloatProperty _specularIntensity; diff --git a/modules/base/rendering/renderablenodeline.cpp b/modules/base/rendering/renderablenodeline.cpp index 0c6de14407..acb91f056f 100644 --- a/modules/base/rendering/renderablenodeline.cpp +++ b/modules/base/rendering/renderablenodeline.cpp @@ -104,9 +104,7 @@ namespace { namespace openspace { documentation::Documentation RenderableNodeLine::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_renderable_renderablenodeline"; - return doc; + return codegen::doc("base_renderable_renderablenodeline"); } RenderableNodeLine::RenderableNodeLine(const ghoul::Dictionary& dictionary) diff --git a/modules/base/rendering/renderableplane.cpp b/modules/base/rendering/renderableplane.cpp index a029a4f576..86401eb031 100644 --- a/modules/base/rendering/renderableplane.cpp +++ b/modules/base/rendering/renderableplane.cpp @@ -45,9 +45,9 @@ namespace { constexpr const char* ProgramName = "Plane"; - enum BlendMode { - BlendModeNormal = 0, - BlendModeAdditive + enum class BlendMode { + Normal = 0, + Additive }; constexpr openspace::properties::Property::PropertyInfo BillboardInfo = { @@ -91,7 +91,7 @@ namespace { // [[codegen::verbatim(BlendModeInfo.description)]] std::optional blendMode; - // [[codegen::verbatim(BlendModeInfo.description)]] + // [[codegen::verbatim(MultiplyColorInfo.description)]] std::optional multiplyColor [[codegen::color()]]; }; #include "renderableplane_codegen.cpp" @@ -100,9 +100,7 @@ namespace { namespace openspace { documentation::Documentation RenderablePlane::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_renderable_plane"; - return doc; + return codegen::doc("base_renderable_plane"); } RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary) @@ -121,15 +119,15 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary) _billboard = p.billboard.value_or(_billboard); _blendMode.addOptions({ - { BlendModeNormal, "Normal" }, - { BlendModeAdditive, "Additive"} + { static_cast(BlendMode::Normal), "Normal" }, + { static_cast(BlendMode::Additive), "Additive"} }); _blendMode.onChange([&]() { switch (_blendMode) { - case BlendModeNormal: + case static_cast(BlendMode::Normal): setRenderBinFromOpacity(); break; - case BlendModeAdditive: + case static_cast(BlendMode::Additive): setRenderBin(Renderable::RenderBin::PreDeferredTransparent); break; default: @@ -138,17 +136,17 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary) }); _opacity.onChange([&]() { - if (_blendMode == BlendModeNormal) { + if (_blendMode == static_cast(BlendMode::Normal)) { setRenderBinFromOpacity(); } }); if (p.blendMode.has_value()) { if (*p.blendMode == Parameters::BlendMode::Normal) { - _blendMode = BlendModeNormal; + _blendMode = static_cast(BlendMode::Normal); } else if (*p.blendMode == Parameters::BlendMode::Additive) { - _blendMode = BlendModeAdditive; + _blendMode = static_cast(BlendMode::Additive); } } @@ -157,7 +155,7 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary) addProperty(_billboard); - _size.setViewOption(properties::Property::ViewOptions::Logarithmic); + _size.setExponent(15.f); addProperty(_size); _size.onChange([this](){ _planeIsDirty = true; }); @@ -264,10 +262,14 @@ void RenderablePlane::render(const RenderData& data, RendererTasks&) { RenderEngine::RendererImplementation::ABuffer; if (usingABufferRenderer) { - _shader->setUniform("additiveBlending", _blendMode == BlendModeAdditive); + _shader->setUniform( + "additiveBlending", + _blendMode == static_cast(BlendMode::Additive) + ); } - bool additiveBlending = (_blendMode == BlendModeAdditive) && usingFramebufferRenderer; + bool additiveBlending = + (_blendMode == static_cast(BlendMode::Additive)) && usingFramebufferRenderer; if (additiveBlending) { glDepthMask(false); glBlendFunc(GL_SRC_ALPHA, GL_ONE); @@ -275,6 +277,7 @@ void RenderablePlane::render(const RenderData& data, RendererTasks&) { glBindVertexArray(_quad); glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); if (additiveBlending) { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -327,6 +330,7 @@ void RenderablePlane::createPlane() { sizeof(GLfloat) * 6, reinterpret_cast(sizeof(GLfloat) * 4) ); + glBindVertexArray(0); } } // namespace openspace diff --git a/modules/base/rendering/renderableplaneimagelocal.cpp b/modules/base/rendering/renderableplaneimagelocal.cpp index b19206d0c5..7b48b72bb5 100644 --- a/modules/base/rendering/renderableplaneimagelocal.cpp +++ b/modules/base/rendering/renderableplaneimagelocal.cpp @@ -78,8 +78,9 @@ namespace { namespace openspace { documentation::Documentation RenderablePlaneImageLocal::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_renderable_plane_image_local"; + documentation::Documentation doc = codegen::doc( + "base_renderable_plane_image_local" + ); // @TODO cleanup // Insert the parents documentation entries until we have a verifier that can deal @@ -101,14 +102,12 @@ RenderablePlaneImageLocal::RenderablePlaneImageLocal(const ghoul::Dictionary& di addProperty(_blendMode); - _texturePath = absPath(p.texture); - _textureFile = std::make_unique(_texturePath); + _texturePath = absPath(p.texture).string(); + _textureFile = std::make_unique(_texturePath.value()); addProperty(_texturePath); _texturePath.onChange([this]() { loadTexture(); }); - _textureFile->setCallback( - [this](const ghoul::filesystem::File&) { _textureIsDirty = true; } - ); + _textureFile->setCallback([this]() { _textureIsDirty = true; }); if (p.renderType.has_value()) { switch (*p.renderType) { @@ -193,7 +192,7 @@ void RenderablePlaneImageLocal::loadTexture() { std::to_string(hash), [path = _texturePath]() -> std::unique_ptr { std::unique_ptr texture = - ghoul::io::TextureReader::ref().loadTexture(absPath(path)); + ghoul::io::TextureReader::ref().loadTexture(absPath(path).string()); LDEBUGC( "RenderablePlaneImageLocal", @@ -209,10 +208,8 @@ void RenderablePlaneImageLocal::loadTexture() { BaseModule::TextureManager.release(t); - _textureFile = std::make_unique(_texturePath); - _textureFile->setCallback( - [&](const ghoul::filesystem::File&) { _textureIsDirty = true; } - ); + _textureFile = std::make_unique(_texturePath.value()); + _textureFile->setCallback([this]() { _textureIsDirty = true; }); } } diff --git a/modules/base/rendering/renderableplaneimageonline.cpp b/modules/base/rendering/renderableplaneimageonline.cpp index 368aa34439..8ce7be472e 100644 --- a/modules/base/rendering/renderableplaneimageonline.cpp +++ b/modules/base/rendering/renderableplaneimageonline.cpp @@ -52,8 +52,9 @@ namespace { namespace openspace { documentation::Documentation RenderablePlaneImageOnline::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_renderable_plane_image_online"; + documentation::Documentation doc = codegen::doc( + "base_renderable_plane_image_online" + ); // @TODO cleanup // Insert the parents documentation entries until we have a verifier that can deal @@ -75,8 +76,6 @@ RenderablePlaneImageOnline::RenderablePlaneImageOnline( const Parameters p = codegen::bake(dictionary); _texturePath.onChange([this]() { _textureIsDirty = true; }); - addProperty(_texturePath); - _texturePath = p.url; addProperty(_texturePath); } diff --git a/modules/base/rendering/renderableprism.cpp b/modules/base/rendering/renderableprism.cpp new file mode 100644 index 0000000000..a5c9e3702a --- /dev/null +++ b/modules/base/rendering/renderableprism.cpp @@ -0,0 +1,344 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2021 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + constexpr const char _loggerCat[] = "RenderablePrism"; + + constexpr const std::array UniformNames = { + "modelViewProjectionTransform", "vs_color" + }; + + constexpr openspace::properties::Property::PropertyInfo SegmentsInfo = { + "Segments", + "Segments", + "The number of segments the shape of the prism should have." + }; + + constexpr openspace::properties::Property::PropertyInfo LinesInfo = { + "NumLines", + "Number of Lines", + "The number of lines connecting the two shapes of the prism." + }; + + static const openspace::properties::Property::PropertyInfo RadiusInfo = { + "Radius", + "Radius", + "The radius of the prism's shape in meters." + }; + + constexpr openspace::properties::Property::PropertyInfo LineWidthInfo = { + "LineWidth", + "Line Width", + "This value specifies the line width." + }; + + constexpr openspace::properties::Property::PropertyInfo LineColorInfo = { + "Color", + "Color", + "This value determines the RGB color for the line." + }; + + constexpr openspace::properties::Property::PropertyInfo LengthInfo = { + "Length", + "Length", + "The length of the prism in meters." + }; + + // Generate vertices around the unit circle on the XY-plane + std::vector unitCircleVertices(int sectorCount) { + std::vector vertices; + vertices.reserve(2 * sectorCount); + float sectorStep = glm::two_pi() / sectorCount; + + for (int i = 0; i < sectorCount; ++i) { + float sectorAngle = i * sectorStep; + vertices.push_back(cos(sectorAngle)); // x + vertices.push_back(sin(sectorAngle)); // y + } + return vertices; + } + + struct [[codegen::Dictionary(RenderablePrism)]] Parameters { + // [[codegen::verbatim(SegmentsInfo.description)]] + int segments; + + // [[codegen::verbatim(LinesInfo.description)]] + std::optional lines; + + // [[codegen::verbatim(RadiusInfo.description)]] + std::optional radius; + + // [[codegen::verbatim(LineWidthInfo.description)]] + std::optional lineWidth; + + // [[codegen::verbatim(LineColorInfo.description)]] + std::optional color [[codegen::color()]]; + + // [[codegen::verbatim(LengthInfo.description)]] + std::optional length; + }; +#include "renderableprism_codegen.cpp" +} // namespace + +namespace openspace { + +documentation::Documentation RenderablePrism::Documentation() { + documentation::Documentation doc = codegen::doc("base_renderable_prism"); + return doc; +} + +RenderablePrism::RenderablePrism(const ghoul::Dictionary& dictionary) + : Renderable(dictionary) + , _nShapeSegments(SegmentsInfo, 6, 3, 32) + , _nLines(LinesInfo, 6, 0, 32) + , _radius(RadiusInfo, 10.f, 0.f, 3.0e12f) + , _lineWidth(LineWidthInfo, 1.f, 1.f, 20.f) + , _lineColor(LineColorInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(1.f)) + , _length(LengthInfo, 20.f, 1.f, 3.0e12f) +{ + const Parameters p = codegen::bake(dictionary); + + _nShapeSegments.onChange([&]() { _prismIsDirty = true; }); + _nShapeSegments = p.segments; + addProperty(_nShapeSegments); + + _nLines.onChange([&]() { _prismIsDirty = true; }); + _nLines = p.lines.value_or(_nShapeSegments); + addProperty(_nLines); + + _radius.setExponent(10.f); + _radius.onChange([&]() { _prismIsDirty = true; }); + _radius = p.radius.value_or(_radius); + addProperty(_radius); + + _lineWidth = p.lineWidth.value_or(_lineWidth); + addProperty(_lineWidth); + + _lineColor.setViewOption(properties::Property::ViewOptions::Color); + _lineColor = p.color.value_or(_lineColor); + addProperty(_lineColor); + + _length.setExponent(12.f); + _length.onChange([&]() { _prismIsDirty = true; }); + _length = p.length.value_or(_length); + addProperty(_length); + + addProperty(_opacity); +} + +bool RenderablePrism::isReady() const { + return _shader != nullptr; +} + +void RenderablePrism::initialize() { + updateVertexData(); +} + +void RenderablePrism::initializeGL() { + _shader = global::renderEngine->buildRenderProgram( + "PrismProgram", + absPath("${MODULE_BASE}/shaders/prism_vs.glsl"), + absPath("${MODULE_BASE}/shaders/prism_fs.glsl") + ); + ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames); + + glGenVertexArrays(1, &_vaoId); + glGenBuffers(1, &_vboId); + glGenBuffers(1, &_iboId); + + glBindVertexArray(_vaoId); + + updateBufferData(); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr); + glBindVertexArray(0); +} + +void RenderablePrism::deinitializeGL() { + global::renderEngine->removeRenderProgram(_shader.get()); + _shader = nullptr; + + glDeleteVertexArrays(1, &_vaoId); + _vaoId = 0; + + glDeleteBuffers(1, &_vboId); + _vboId = 0; + + glDeleteBuffers(1, &_iboId); + _iboId = 0; +} + +void RenderablePrism::updateVertexData() { + _vertexArray.clear(); + _indexArray.clear(); + + // Get unit circle vertices on the XY-plane + std::vector unitVertices = unitCircleVertices(_nShapeSegments); + std::vector unitVerticesLines = unitCircleVertices(_nLines); + + // Put base and top shape vertices into array + for (int i = 0; i < 2; ++i) { + float h = i * _length; // z value, 0 to _length + + for (int j = 0, k = 0; j < _nShapeSegments && k < unitVertices.size(); ++j, k += 2) { + float ux = unitVertices[k]; + float uy = unitVertices[k + 1]; + + _vertexArray.push_back(ux * _radius); // x + _vertexArray.push_back(uy * _radius); // y + _vertexArray.push_back(h); // z + } + } + + // Put the vertices for the connecting lines into array + if (_nLines == 1) { + // In the case of just one line then connect the center points instead + // Center for base shape + _vertexArray.push_back(0.f); + _vertexArray.push_back(0.f); + _vertexArray.push_back(0.f); + + // Center for top shape + _vertexArray.push_back(0.f); + _vertexArray.push_back(0.f); + _vertexArray.push_back(_length); + } + else { + for (int j = 0, k = 0; j < _nLines && k < unitVerticesLines.size(); ++j, k += 2) { + float ux = unitVerticesLines[k]; + float uy = unitVerticesLines[k + 1]; + + // Base + _vertexArray.push_back(ux * _radius); // x + _vertexArray.push_back(uy * _radius); // y + _vertexArray.push_back(0.f); // z + + // Top + _vertexArray.push_back(ux * _radius); // x + _vertexArray.push_back(uy * _radius); // y + _vertexArray.push_back(_length); // z + } + } + + // Indices for Base shape + ghoul_assert(_nShapeSegments.value <= std::numeric_limit::max(), "Too many shape segments") + for (uint8_t i = 0; i < _nShapeSegments; ++i) { + _indexArray.push_back(i); + } + + // Reset + _indexArray.push_back(255); + + // Indices for Top shape + for (uint8_t i = _nShapeSegments; i < 2 * _nShapeSegments; ++i) { + _indexArray.push_back(i); + } + + // Indices for connecting lines + for (int i = 0, k = 0; i < _nLines; ++i, k += 2) { + // Reset + _indexArray.push_back(255); + + _indexArray.push_back(2 * _nShapeSegments + k); + _indexArray.push_back(2 * _nShapeSegments + k + 1); + } +} + +void RenderablePrism::updateBufferData() { + glBindBuffer(GL_ARRAY_BUFFER, _vboId); + glBufferData( + GL_ARRAY_BUFFER, + _vertexArray.size() * sizeof(float), + _vertexArray.data(), + GL_STREAM_DRAW + ); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iboId); + glBufferData( + GL_ELEMENT_ARRAY_BUFFER, + _indexArray.size() * sizeof(uint8_t), + _indexArray.data(), + GL_STREAM_DRAW + ); +} + +void RenderablePrism::render(const RenderData& data, RendererTasks&) { + _shader->activate(); + + // Model transform and view transform needs to be in double precision + glm::dmat4 modelTransform = + glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * + glm::dmat4(data.modelTransform.rotation) * + glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)); + + glm::mat4 modelViewProjectionTransform = + data.camera.projectionMatrix() * + glm::mat4(data.camera.combinedViewMatrix() * modelTransform); + + // Uniforms + _shader->setUniform(_uniformCache.modelViewProjection, modelViewProjectionTransform); + _shader->setUniform(_uniformCache.color, glm::vec4(_lineColor.value(), _opacity)); + + // Render + glEnable(GL_PRIMITIVE_RESTART); + glPrimitiveRestartIndex(255); + glLineWidth(_lineWidth); + glBindVertexArray(_vaoId); + + glDrawElements(GL_LINE_LOOP, static_cast(_indexArray.size()), GL_UNSIGNED_BYTE, nullptr); + + glBindVertexArray(0); + global::renderEngine->openglStateCache().resetLineState(); + glDisable(GL_PRIMITIVE_RESTART); + + _shader->deactivate(); +} + +void RenderablePrism::update(const UpdateData&) { + if (_shader->isDirty()) { + _shader->rebuildFromFile(); + ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames); + } + if (_prismIsDirty) { + updateVertexData(); + updateBufferData(); + _prismIsDirty = false; + } +} + +} // namespace openspace diff --git a/include/openspace/properties/matrix/dmat3x2property.h b/modules/base/rendering/renderableprism.h similarity index 56% rename from include/openspace/properties/matrix/dmat3x2property.h rename to modules/base/rendering/renderableprism.h index e823466c34..3acfb6953f 100644 --- a/include/openspace/properties/matrix/dmat3x2property.h +++ b/modules/base/rendering/renderableprism.h @@ -22,17 +22,62 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __OPENSPACE_CORE___DMAT3X2PROPERTY___H__ -#define __OPENSPACE_CORE___DMAT3X2PROPERTY___H__ +#ifndef __OPENSPACE_MODULE_BASE___RENDERABLEPRISM___H__ +#define __OPENSPACE_MODULE_BASE___RENDERABLEPRISM___H__ -#include +#include +#include +#include +#include +#include +#include #include -namespace openspace::properties { +namespace ghoul::opengl { class ProgramObject; } -REGISTER_NUMERICALPROPERTY_HEADER(DMat3x2Property, glm::dmat3x2) +namespace openspace { -} // namespace openspace::properties +namespace documentation { struct Documentation; } -#endif // __OPENSPACE_CORE___DMAT3X2PROPERTY___H__ +class RenderablePrism : public Renderable { +public: + RenderablePrism(const ghoul::Dictionary& dictionary); + + void initialize() override; + void initializeGL() override; + void deinitializeGL() override; + + bool isReady() const override; + + void render(const RenderData& data, RendererTasks& rendererTask) override; + void update(const UpdateData& data) override; + + static documentation::Documentation Documentation(); + +private: + void updateVertexData(); + void updateBufferData(); + + // Properties + properties::IntProperty _nShapeSegments; + properties::IntProperty _nLines; + properties::FloatProperty _radius; + properties::FloatProperty _lineWidth; + properties::Vec3Property _lineColor; + properties::FloatProperty _length; + UniformCache(modelViewProjection, color) _uniformCache; + + std::unique_ptr _shader; + GLuint _vaoId = 0; + GLuint _vboId = 0; + GLuint _iboId = 0; + std::vector _vertexArray; + std::vector _indexArray; + + bool _prismIsDirty = false; +}; + +} // namespace openspace + +#endif // __OPENSPACE_MODULE_BASE___RENDERABLEPRISM___H__ diff --git a/modules/base/rendering/renderablesphere.cpp b/modules/base/rendering/renderablesphere.cpp index 0dae86d42c..e6b32389be 100644 --- a/modules/base/rendering/renderablesphere.cpp +++ b/modules/base/rendering/renderablesphere.cpp @@ -162,16 +162,14 @@ namespace { namespace openspace { documentation::Documentation RenderableSphere::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_renderable_sphere"; - return doc; + return codegen::doc("base_renderable_sphere"); } RenderableSphere::RenderableSphere(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _texturePath(TextureInfo) , _orientation(OrientationInfo, properties::OptionProperty::DisplayType::Dropdown) - , _size(SizeInfo, 1.f, 0.f, 1e35f) + , _size(SizeInfo, 1.f, 0.f, 1e25f) , _segments(SegmentsInfo, 8, 4, 1000) , _mirrorTexture(MirrorTextureInfo, false) , _useAdditiveBlending(UseAdditiveBlendingInfo, false) @@ -215,7 +213,7 @@ RenderableSphere::RenderableSphere(const ghoul::Dictionary& dictionary) } addProperty(_orientation); - _size.setViewOption(properties::Property::ViewOptions::Logarithmic); + _size.setExponent(15.f); _size.onChange([this]() { setBoundingSphere(_size); _sphereIsDirty = true; diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index 889772bc58..63e7d99764 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -51,7 +52,7 @@ namespace { constexpr const std::array UniformNames = { "opacity", "modelViewTransform", "projectionTransform", "color", "useLineFade", "lineFade", "vertexSortingMethod", "idOffset", "nVertices", "stride", "pointSize", - "renderPhase", "resolution", "lineWidth" + "renderPhase", "viewport", "lineWidth" }; #endif @@ -181,9 +182,7 @@ namespace { namespace openspace { documentation::Documentation RenderableTrail::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_renderable_renderabletrail"; - return doc; + return codegen::doc("base_renderable_renderabletrail"); } RenderableTrail::Appearance::Appearance() @@ -340,12 +339,20 @@ void RenderableTrail::internalRender(bool renderLines, bool renderPoints, #if !defined(__APPLE__) glm::ivec2 resolution = global::renderEngine->renderingResolution(); - _programObject->setUniform(_uniformCache.resolution, resolution); + GLint viewport[4]; + global::renderEngine->openglStateCache().viewport(viewport); + _programObject->setUniform( + _uniformCache.viewport, + static_cast(viewport[0]), + static_cast(viewport[1]), + static_cast(viewport[2]), + static_cast(viewport[3]) + ); _programObject->setUniform( _uniformCache.lineWidth, std::ceil((2.f * 1.f + _appearance.lineWidth) * std::sqrt(2.f)) ); -#endif +#endif // !defined(__APPLE__) if (renderPoints) { // The stride parameter determines the distance between larger points and @@ -432,10 +439,10 @@ void RenderableTrail::render(const RenderData& data, RendererTasks&) { glBlendFunc(GL_SRC_ALPHA, GL_ONE); } - const bool renderLines = (_appearance.renderingModes == RenderingModeLines) | + const bool renderLines = (_appearance.renderingModes == RenderingModeLines) || (_appearance.renderingModes == RenderingModeLinesPoints); - const bool renderPoints = (_appearance.renderingModes == RenderingModePoints) | + const bool renderPoints = (_appearance.renderingModes == RenderingModePoints) || (_appearance.renderingModes == RenderingModeLinesPoints); if (renderLines) { diff --git a/modules/base/rendering/renderabletrail.h b/modules/base/rendering/renderabletrail.h index a65fc7fa18..6d9a6450c4 100644 --- a/modules/base/rendering/renderabletrail.h +++ b/modules/base/rendering/renderabletrail.h @@ -178,8 +178,8 @@ private: pointSize, renderPhase) _uniformCache; #else UniformCache(opacity, modelView, projection, color, useLineFade, lineFade, - vertexSorting, idOffset, nVertices, stride, pointSize, renderPhase, - resolution, lineWidth) _uniformCache; + vertexSorting, idOffset, nVertices, stride, pointSize, renderPhase, viewport, + lineWidth) _uniformCache; #endif }; diff --git a/modules/base/rendering/renderabletrailorbit.cpp b/modules/base/rendering/renderabletrailorbit.cpp index 681c4e14d0..a80152e3eb 100644 --- a/modules/base/rendering/renderabletrailorbit.cpp +++ b/modules/base/rendering/renderabletrailorbit.cpp @@ -129,8 +129,9 @@ namespace { namespace openspace { documentation::Documentation RenderableTrailOrbit::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_renderable_renderabletrailorbit"; + documentation::Documentation doc = codegen::doc( + "base_renderable_renderabletrailorbit" + ); // Insert the parents documentation entries until we have a verifier that can deal // with class hierarchy diff --git a/modules/base/rendering/renderabletrailtrajectory.cpp b/modules/base/rendering/renderabletrailtrajectory.cpp index ecd770c3ea..061e4de74b 100644 --- a/modules/base/rendering/renderabletrailtrajectory.cpp +++ b/modules/base/rendering/renderabletrailtrajectory.cpp @@ -105,8 +105,9 @@ namespace { namespace openspace { documentation::Documentation RenderableTrailTrajectory::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_renderable_renderabletrailtrajectory"; + documentation::Documentation doc = codegen::doc( + "base_renderable_renderabletrailtrajectory" + ); // @TODO cleanup // Insert the parents documentation entries until we have a verifier that can deal diff --git a/modules/base/rendering/screenspacedashboard.cpp b/modules/base/rendering/screenspacedashboard.cpp index 4cb9cf591b..5c3ebae6eb 100644 --- a/modules/base/rendering/screenspacedashboard.cpp +++ b/modules/base/rendering/screenspacedashboard.cpp @@ -128,9 +128,7 @@ int removeDashboardItemsFromScreenSpace(lua_State* L) { } // namespace luascriptfunctions documentation::Documentation ScreenSpaceDashboard::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_screenspace_dashboard"; - return doc; + return codegen::doc("base_screenspace_dashboard"); } ScreenSpaceDashboard::ScreenSpaceDashboard(const ghoul::Dictionary& dictionary) diff --git a/modules/base/rendering/screenspaceimagelocal.cpp b/modules/base/rendering/screenspaceimagelocal.cpp index 3c74143c2f..d4cf2672c6 100644 --- a/modules/base/rendering/screenspaceimagelocal.cpp +++ b/modules/base/rendering/screenspaceimagelocal.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include namespace { @@ -57,9 +58,7 @@ namespace { namespace openspace { documentation::Documentation ScreenSpaceImageLocal::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_screenspace_image_local"; - return doc; + return codegen::doc("base_screenspace_image_local"); } ScreenSpaceImageLocal::ScreenSpaceImageLocal(const ghoul::Dictionary& dictionary) @@ -81,7 +80,7 @@ ScreenSpaceImageLocal::ScreenSpaceImageLocal(const ghoul::Dictionary& dictionary setIdentifier(identifier); _texturePath.onChange([this]() { - if (!FileSys.fileExists(FileSys.absolutePath(_texturePath))) { + if (!std::filesystem::is_regular_file(absPath(_texturePath))) { LWARNINGC( "ScreenSpaceImageLocal", fmt::format("Image {} did not exist for {}", _texturePath, _identifier) @@ -94,8 +93,8 @@ ScreenSpaceImageLocal::ScreenSpaceImageLocal(const ghoul::Dictionary& dictionary addProperty(_texturePath); if (p.texturePath.has_value()) { - if (FileSys.fileExists(FileSys.absolutePath(*p.texturePath))) { - _texturePath = FileSys.absolutePath(*p.texturePath); + if (std::filesystem::is_regular_file(absPath(*p.texturePath))) { + _texturePath = absPath(*p.texturePath).string(); } else { LWARNINGC( @@ -115,7 +114,7 @@ bool ScreenSpaceImageLocal::deinitializeGL() { void ScreenSpaceImageLocal::update() { if (_textureIsDirty && !_texturePath.value().empty()) { std::unique_ptr texture = - ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath)); + ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath).string()); if (texture) { // Images don't need to start on 4-byte boundaries, for example if the diff --git a/modules/base/rendering/screenspaceimageonline.cpp b/modules/base/rendering/screenspaceimageonline.cpp index ef5c527175..8219965b11 100644 --- a/modules/base/rendering/screenspaceimageonline.cpp +++ b/modules/base/rendering/screenspaceimageonline.cpp @@ -58,9 +58,7 @@ namespace { namespace openspace { documentation::Documentation ScreenSpaceImageOnline::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_screenspace_image_online"; - return doc; + return codegen::doc("base_screenspace_image_online"); } ScreenSpaceImageOnline::ScreenSpaceImageOnline(const ghoul::Dictionary& dictionary) @@ -81,8 +79,8 @@ ScreenSpaceImageOnline::ScreenSpaceImageOnline(const ghoul::Dictionary& dictiona setIdentifier(std::move(identifier)); _texturePath.onChange([this]() { _textureIsDirty = true; }); - addProperty(_texturePath); _texturePath = p.url.value_or(_texturePath); + addProperty(_texturePath); } ScreenSpaceImageOnline::~ScreenSpaceImageOnline() {} // NOLINT diff --git a/modules/base/rotation/constantrotation.cpp b/modules/base/rotation/constantrotation.cpp index d72f524f40..cd14fdddc2 100644 --- a/modules/base/rotation/constantrotation.cpp +++ b/modules/base/rotation/constantrotation.cpp @@ -55,9 +55,7 @@ namespace { namespace openspace { documentation::Documentation ConstantRotation::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_transform_rotation_constant"; - return doc; + return codegen::doc("base_transform_rotation_constant"); } ConstantRotation::ConstantRotation(const ghoul::Dictionary& dictionary) diff --git a/modules/base/rotation/fixedrotation.cpp b/modules/base/rotation/fixedrotation.cpp index c89e4dc489..0182155221 100644 --- a/modules/base/rotation/fixedrotation.cpp +++ b/modules/base/rotation/fixedrotation.cpp @@ -46,7 +46,7 @@ namespace { }; constexpr const openspace::properties::Property::PropertyInfo XAxisTypeInfo = { - "xAxis-Type", + "xAxisType", "xAxis: Specification Type", "This value specifies how this axis is being specified, that is whether it is " "referencing another object, specifying an absolute vector, or whether it is " @@ -55,7 +55,7 @@ namespace { }; constexpr const openspace::properties::Property::PropertyInfo YAxisTypeInfo = { - "yAxis-Type", + "yAxisType", "yAxis: Specification Type", "This value specifies how this axis is being specified, that is whether it is " "referencing another object, specifying an absolute vector, or whether it is " @@ -64,7 +64,7 @@ namespace { }; constexpr const openspace::properties::Property::PropertyInfo ZAxisTypeInfo = { - "zAxis-Type", + "zAxisType", "zAxis: Specification Type", "This value specifies how this axis is being specified, that is whether it is " "referencing another object, specifying an absolute vector, or whether it is " @@ -73,7 +73,7 @@ namespace { }; constexpr const openspace::properties::Property::PropertyInfo XAxisObjectInfo = { - "xAxis-Object", + "xAxisObject", "xAxis: Focus Object", "This is the object that the axis will focus on. This object must name an " "existing scene graph node in the currently loaded scene and the rotation will " @@ -81,7 +81,7 @@ namespace { }; constexpr const openspace::properties::Property::PropertyInfo YAxisObjectInfo = { - "yAxis-Object", + "yAxisObject", "yAxis: Focus Object", "This is the object that the axis will focus on. This object must name an " "existing scene graph node in the currently loaded scene and the rotation will " @@ -89,7 +89,7 @@ namespace { }; constexpr const openspace::properties::Property::PropertyInfo ZAxisObjectInfo = { - "zAxis-Object", + "zAxisObject", "zAxis: Focus Object", "This is the object that the axis will focus on. This object must name an " "existing scene graph node in the currently loaded scene and the rotation will " @@ -98,7 +98,7 @@ namespace { constexpr const openspace::properties::Property::PropertyInfo XAxisInvertObjectInfo = { - "xAxis-InvertObject", + "xAxisInvertObject", "xAxis: Invert Object Point Direction", "If this value is set to 'true', and the type is set to 'Object', the inverse of " "the pointing direction is used, causing the object to point away from the " @@ -107,7 +107,7 @@ namespace { constexpr const openspace::properties::Property::PropertyInfo YAxisInvertObjectInfo = { - "yAxis-InvertObject", + "yAxisInvertObject", "yAxis: Invert Object Point Direction", "If this value is set to 'true', and the type is set to 'Object', the inverse of " "the pointing direction is used, causing the object to point away from the " @@ -116,7 +116,7 @@ namespace { constexpr const openspace::properties::Property::PropertyInfo ZAxisInvertObjectInfo = { - "zAxis-InvertObject", + "zAxisInvertObject", "zAxis: Invert Object Point Direction", "If this value is set to 'true', and the type is set to 'Object', the inverse of " "the pointing direction is used, causing the object to point away from the " @@ -124,21 +124,21 @@ namespace { }; constexpr const openspace::properties::Property::PropertyInfo XAxisVectorInfo = { - "xAxis-Vector", + "xAxisVector", "xAxis: Direction vector", "This value specifies a static direction vector that is used for a fixed " "rotation." }; constexpr const openspace::properties::Property::PropertyInfo YAxisVectorInfo = { - "yAxis-Vector", + "yAxisVector", "yAxis: Direction vector", "This value specifies a static direction vector that is used for a fixed " "rotation." }; constexpr const openspace::properties::Property::PropertyInfo ZAxisVectorInfo = { - "zAxis-Vector", + "zAxisVector", "zAxis: Direction vector", "This value specifies a static direction vector that is used for a fixed " "rotation." @@ -147,7 +147,7 @@ namespace { constexpr const openspace::properties::Property::PropertyInfo XAxisOrthogonalVectorInfo = { - "xAxis-Orthogonal", + "xAxisOrthogonal", "xAxis: Vector is orthogonal", "This value determines whether the vector specified is used directly, or whether " "it is used together with another non-coordinate system completion vector to " @@ -157,7 +157,7 @@ namespace { constexpr const openspace::properties::Property::PropertyInfo YAxisOrthogonalVectorInfo = { - "yAxis-Orthogonal", + "yAxisOrthogonal", "yAxis: Vector is orthogonal", "This value determines whether the vector specified is used directly, or whether " "it is used together with another non-coordinate system completion vector to " @@ -167,7 +167,7 @@ namespace { constexpr const openspace::properties::Property::PropertyInfo ZAxisOrthogonalVectorInfo = { - "zAxis-Orthogonal", + "zAxisOrthogonal", "zAxis: Vector is orthogonal", "This value determines whether the vector specified is used directly, or whether " "it is used together with another non-coordinate system completion vector to " @@ -194,7 +194,7 @@ namespace { std::optional xAxisOrthogonal; // [[codegen::verbatim(XAxisInvertObjectInfo.description)]] - std::optional xAxisInvert [[codegen::key("xAxis - InvertObject")]]; + std::optional xAxisInvert; // This value specifies the direction of the new Y axis. If this value is not // specified, it will be computed by completing a right handed coordinate system @@ -207,7 +207,7 @@ namespace { std::optional yAxisOrthogonal; // [[codegen::verbatim(YAxisInvertObjectInfo.description)]] - std::optional yAxisInvert [[codegen::key("yAxis - InvertObject")]]; + std::optional yAxisInvert; // This value specifies the direction of the new Z axis. If this value is not // specified, it will be computed by completing a right handed coordinate system @@ -220,7 +220,7 @@ namespace { std::optional zAxisOrthogonal; // [[codegen::verbatim(ZAxisInvertObjectInfo.description)]] - std::optional zAxisInvert [[codegen::key("zAxis - InvertObject")]]; + std::optional zAxisInvert; // [[codegen::verbatim(AttachedInfo.description)]] std::optional attached; @@ -231,9 +231,7 @@ namespace { namespace openspace { documentation::Documentation FixedRotation::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_transform_rotation_fixed"; - return doc; + return codegen::doc("base_transform_rotation_fixed"); } FixedRotation::FixedRotation(const ghoul::Dictionary& dictionary) diff --git a/modules/base/rotation/luarotation.cpp b/modules/base/rotation/luarotation.cpp index f6f0f822a5..86d9e8d619 100644 --- a/modules/base/rotation/luarotation.cpp +++ b/modules/base/rotation/luarotation.cpp @@ -56,9 +56,7 @@ namespace { namespace openspace { documentation::Documentation LuaRotation::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_transform_rotation_lua"; - return doc; + return codegen::doc("base_transform_rotation_lua"); } LuaRotation::LuaRotation() @@ -69,17 +67,15 @@ LuaRotation::LuaRotation() _luaScriptFile.onChange([&]() { requireUpdate(); - _fileHandle = std::make_unique(_luaScriptFile); - _fileHandle->setCallback([&](const ghoul::filesystem::File&) { - requireUpdate(); - }); + _fileHandle = std::make_unique(_luaScriptFile.value()); + _fileHandle->setCallback([this]() { requireUpdate(); }); }); } LuaRotation::LuaRotation(const ghoul::Dictionary& dictionary) : LuaRotation() { const Parameters p = codegen::bake(dictionary); - _luaScriptFile = absPath(p.script); + _luaScriptFile = absPath(p.script).string(); } glm::dmat3 LuaRotation::matrix(const UpdateData& data) const { diff --git a/modules/base/rotation/staticrotation.cpp b/modules/base/rotation/staticrotation.cpp index 1da7e72f6f..550453f55e 100644 --- a/modules/base/rotation/staticrotation.cpp +++ b/modules/base/rotation/staticrotation.cpp @@ -67,9 +67,7 @@ namespace { namespace openspace { documentation::Documentation StaticRotation::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_transform_rotation_static"; - return doc; + return codegen::doc("base_transform_rotation_static"); } StaticRotation::StaticRotation() diff --git a/modules/base/rotation/timelinerotation.cpp b/modules/base/rotation/timelinerotation.cpp index 8a60f99c8b..aa96c4b0eb 100644 --- a/modules/base/rotation/timelinerotation.cpp +++ b/modules/base/rotation/timelinerotation.cpp @@ -42,9 +42,7 @@ namespace { namespace openspace { documentation::Documentation TimelineRotation::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_transform_rotation_keyframe"; - return doc; + return codegen::doc("base_transform_rotation_keyframe"); } TimelineRotation::TimelineRotation(const ghoul::Dictionary& dictionary) { diff --git a/modules/base/scale/luascale.cpp b/modules/base/scale/luascale.cpp index 8ea195e15c..f99600595e 100644 --- a/modules/base/scale/luascale.cpp +++ b/modules/base/scale/luascale.cpp @@ -55,9 +55,7 @@ namespace { namespace openspace { documentation::Documentation LuaScale::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_scale_lua"; - return doc; + return codegen::doc("base_scale_lua"); } LuaScale::LuaScale() @@ -68,16 +66,14 @@ LuaScale::LuaScale() _luaScriptFile.onChange([&]() { requireUpdate(); - _fileHandle = std::make_unique(_luaScriptFile); - _fileHandle->setCallback([&](const ghoul::filesystem::File&) { - requireUpdate(); - }); + _fileHandle = std::make_unique(_luaScriptFile.value()); + _fileHandle->setCallback([this]() { requireUpdate(); }); }); } LuaScale::LuaScale(const ghoul::Dictionary& dictionary) : LuaScale() { const Parameters p = codegen::bake(dictionary); - _luaScriptFile = absPath(p.script); + _luaScriptFile = absPath(p.script).string(); } glm::dvec3 LuaScale::scaleValue(const UpdateData& data) const { diff --git a/modules/base/scale/nonuniformstaticscale.cpp b/modules/base/scale/nonuniformstaticscale.cpp index 19bc7ca349..62229c511c 100644 --- a/modules/base/scale/nonuniformstaticscale.cpp +++ b/modules/base/scale/nonuniformstaticscale.cpp @@ -45,9 +45,7 @@ namespace { namespace openspace { documentation::Documentation NonUniformStaticScale::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_scale_nonuniformstatic"; - return doc; + return codegen::doc("base_scale_nonuniformstatic"); } glm::dvec3 NonUniformStaticScale::scaleValue(const UpdateData&) const { diff --git a/modules/base/scale/staticscale.cpp b/modules/base/scale/staticscale.cpp index 59b5a96c57..57f5643e99 100644 --- a/modules/base/scale/staticscale.cpp +++ b/modules/base/scale/staticscale.cpp @@ -45,9 +45,7 @@ namespace { namespace openspace { documentation::Documentation StaticScale::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_scale_static"; - return doc; + return codegen::doc("base_scale_static"); } glm::dvec3 StaticScale::scaleValue(const UpdateData&) const { diff --git a/modules/base/scale/timedependentscale.cpp b/modules/base/scale/timedependentscale.cpp index 168146ef0c..567faef012 100644 --- a/modules/base/scale/timedependentscale.cpp +++ b/modules/base/scale/timedependentscale.cpp @@ -71,9 +71,7 @@ namespace { namespace openspace { documentation::Documentation TimeDependentScale::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_scale_timedependent"; - return doc; + return codegen::doc("base_scale_timedependent"); } TimeDependentScale::TimeDependentScale(const ghoul::Dictionary& dictionary) diff --git a/modules/base/shaders/axes_fs.glsl b/modules/base/shaders/axes_fs.glsl index 6bbcd9b84b..912657481c 100644 --- a/modules/base/shaders/axes_fs.glsl +++ b/modules/base/shaders/axes_fs.glsl @@ -35,7 +35,7 @@ uniform vec3 zColor; Fragment getFragment() { Fragment frag; - vec3 colorComponents = step(0.01f, vs_positionModelSpace); + vec3 colorComponents = step(0.01, vs_positionModelSpace); frag.color.rgb = colorComponents.x * xColor + colorComponents.y * yColor + diff --git a/modules/base/shaders/axes_vs.glsl b/modules/base/shaders/axes_vs.glsl index b7d5caae03..539b4ddd18 100644 --- a/modules/base/shaders/axes_vs.glsl +++ b/modules/base/shaders/axes_vs.glsl @@ -37,7 +37,7 @@ void main() { vec4 positionViewSpace = modelViewTransform * vec4(in_position, 1.0); vec4 positionClipSpace = projectionTransform * positionViewSpace; vec4 positionScreenSpace = positionClipSpace; - positionScreenSpace.z = 0.f; + positionScreenSpace.z = 0.0; vs_positionModelSpace = in_position; vs_screenSpaceDepth = positionScreenSpace.w; vs_positionViewSpace = positionViewSpace; diff --git a/modules/base/shaders/grid_fs.glsl b/modules/base/shaders/grid_fs.glsl index 06d83fa764..0046d605d1 100644 --- a/modules/base/shaders/grid_fs.glsl +++ b/modules/base/shaders/grid_fs.glsl @@ -33,13 +33,12 @@ uniform float opacity; Fragment getFragment() { Fragment frag; frag.color.rgb = gridColor; - frag.color.a = opacity; - frag.depth = vs_depthClipSpace; + frag.color.a = opacity; + frag.depth = vs_depthClipSpace; frag.gPosition = vs_positionViewSpace; // There is no normal here frag.gNormal = vec4(0.0, 0.0, -1.0, 1.0); return frag; - } diff --git a/modules/base/shaders/grid_vs.glsl b/modules/base/shaders/grid_vs.glsl index 30351ea566..755eb91e0a 100644 --- a/modules/base/shaders/grid_vs.glsl +++ b/modules/base/shaders/grid_vs.glsl @@ -33,13 +33,13 @@ uniform dmat4 modelViewTransform; uniform dmat4 MVPTransform; void main() { - dvec4 objPosDouble = dvec4(in_position, 1.0); + dvec4 objPosDouble = dvec4(in_position, 1.0); dvec4 positionViewSpace = modelViewTransform * objPosDouble; dvec4 positionClipSpace = MVPTransform * objPosDouble; positionClipSpace.z = 0.0; - vs_depthClipSpace = float(positionClipSpace.w); + vs_depthClipSpace = float(positionClipSpace.w); vs_positionViewSpace = vec4(positionViewSpace); gl_Position = vec4(positionClipSpace); diff --git a/modules/base/shaders/line_fs.glsl b/modules/base/shaders/line_fs.glsl index 0045d65d15..7d60291b6d 100644 --- a/modules/base/shaders/line_fs.glsl +++ b/modules/base/shaders/line_fs.glsl @@ -23,7 +23,6 @@ ****************************************************************************************/ #include "fragment.glsl" -#include "floatoperations.glsl" in float vs_depth; in vec4 vs_positionViewSpace; diff --git a/modules/base/shaders/plane_fs.glsl b/modules/base/shaders/plane_fs.glsl index b11a3da7bc..b70c9a0ebd 100644 --- a/modules/base/shaders/plane_fs.glsl +++ b/modules/base/shaders/plane_fs.glsl @@ -24,10 +24,10 @@ #include "fragment.glsl" -in float vs_screenSpaceDepth; -in vec2 vs_st; in vec4 vs_gPosition; in vec3 vs_gNormal; +in float vs_screenSpaceDepth; +in vec2 vs_st; uniform sampler2D texture1; uniform bool additiveBlending; @@ -57,8 +57,8 @@ Fragment getFragment() { } // G-Buffer - frag.gPosition = vs_gPosition; - frag.gNormal = vec4(vs_gNormal, 1.0); + frag.gPosition = vs_gPosition; + frag.gNormal = vec4(vs_gNormal, 1.0); return frag; } diff --git a/modules/base/shaders/plane_vs.glsl b/modules/base/shaders/plane_vs.glsl index e93dd95a92..a3af07c14e 100644 --- a/modules/base/shaders/plane_vs.glsl +++ b/modules/base/shaders/plane_vs.glsl @@ -29,12 +29,10 @@ layout(location = 0) in vec4 in_position; layout(location = 1) in vec2 in_st; -out vec2 vs_st; -out float vs_screenSpaceDepth; -out vec4 vs_positionScreenSpace; -// G-Buffer out vec4 vs_gPosition; out vec3 vs_gNormal; +out float vs_screenSpaceDepth; +out vec2 vs_st; uniform mat4 modelViewProjectionTransform; uniform mat4 modelViewTransform; diff --git a/modules/atmosphere/shaders/inScattering_calc_vs.glsl b/modules/base/shaders/prism_fs.glsl similarity index 92% rename from modules/atmosphere/shaders/inScattering_calc_vs.glsl rename to modules/base/shaders/prism_fs.glsl index 1ca953fe3c..e659f56f6a 100644 --- a/modules/atmosphere/shaders/inScattering_calc_vs.glsl +++ b/modules/base/shaders/prism_fs.glsl @@ -22,10 +22,15 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#version __CONTEXT__ +#include "fragment.glsl" -layout(location = 0) in vec3 in_position; +in float vs_depth; -void main() { - gl_Position = vec4(in_position, 1.0); +uniform vec4 vs_color; + +Fragment getFragment() { + Fragment frag; + frag.color = vs_color; + frag.depth = vs_depth; + return frag; } diff --git a/modules/atmosphere/shaders/inScattering_calc_gs.glsl b/modules/base/shaders/prism_vs.glsl similarity index 84% rename from modules/atmosphere/shaders/inScattering_calc_gs.glsl rename to modules/base/shaders/prism_vs.glsl index 823cd6a71e..bb8d4f68b0 100644 --- a/modules/atmosphere/shaders/inScattering_calc_gs.glsl +++ b/modules/base/shaders/prism_vs.glsl @@ -24,16 +24,18 @@ #version __CONTEXT__ -uniform int layer; +#include "PowerScaling/powerScaling_vs.hglsl" -layout (triangles) in; -layout (triangle_strip, max_vertices=3) out; +layout (location = 0) in vec3 in_position; + +out float vs_depth; + +uniform mat4 modelViewProjectionTransform; void main() { - for (int n = 0; n < gl_in.length(); ++n) { - gl_Position = gl_in[n].gl_Position; - gl_Layer = layer; - EmitVertex(); - } - EndPrimitive(); + vec4 position = vec4(in_position, 1.0); + vec4 positionClipSpace = modelViewProjectionTransform * position; + vec4 positionScreenSpace = z_normalization(positionClipSpace); + gl_Position = positionScreenSpace; + vs_depth = positionScreenSpace.w; } diff --git a/modules/base/shaders/renderabletrail_fs.glsl b/modules/base/shaders/renderabletrail_fs.glsl index 27e1402b06..c5c370c108 100644 --- a/modules/base/shaders/renderabletrail_fs.glsl +++ b/modules/base/shaders/renderabletrail_fs.glsl @@ -34,12 +34,13 @@ uniform int renderPhase; uniform float opacity = 1.0; uniform float lineWidth; +uniform vec4 viewport; + // Fragile! Keep in sync with RenderableTrail::render::RenderPhase -#define RenderPhaseLines 0 -#define RenderPhasePoints 1 - -#define Delta 0.25 +const int RenderPhaseLines = 0; +const int RenderPhasePoints = 1; +const float Delta = 0.25; Fragment getFragment() { Fragment frag; @@ -61,18 +62,21 @@ Fragment getFragment() { frag.color.a = transparencyCorrection; } - double distanceCenter = length(mathLine - vec2(gl_FragCoord.xy)); + // We can't expect a viewport of the form (0, 0, res.x, res.y) used to convert the + // window coordinates from gl_FragCoord into [0, 1] coordinates, so we need to use + // this more complicated method that is also used in the FXAA and HDR rendering steps + vec2 xy = vec2(gl_FragCoord.xy); + xy -= viewport.xy; + + double distanceCenter = length(mathLine - xy); double dLW = double(lineWidth); - float blendFactor = 20; + const float blendFactor = 20.0; if (distanceCenter > dLW) { frag.color.a = 0.0; - //discard; } else { frag.color.a *= pow(float((dLW - distanceCenter) / dLW), blendFactor); - // if (frag.color.a < 0.4) - // discard; } frag.gPosition = vs_gPosition; diff --git a/modules/base/shaders/renderabletrail_vs.glsl b/modules/base/shaders/renderabletrail_vs.glsl index 3a6b56ce62..f2615fa74c 100644 --- a/modules/base/shaders/renderabletrail_vs.glsl +++ b/modules/base/shaders/renderabletrail_vs.glsl @@ -43,14 +43,13 @@ uniform int vertexSortingMethod; uniform int pointSize; uniform int stride; -uniform ivec2 resolution; +uniform vec4 viewport; // Fragile! Keep in sync with RenderableTrail::render #define VERTEX_SORTING_NEWESTFIRST 0 #define VERTEX_SORTING_OLDESTFIRST 1 #define VERTEX_SORTING_NOSORTING 2 - void main() { int modId = gl_VertexID; @@ -83,5 +82,5 @@ void main() { float(pointSize) : float(pointSize) / 2; gl_Position = z_normalization(vs_positionClipSpace); - mathLine = 0.5 * (vs_positionNDC.xy + vec2(1.0)) * vec2(resolution); + mathLine = 0.5 * (vs_positionNDC.xy + vec2(1.0)) * viewport.zw; } diff --git a/modules/base/shaders/screenspace_fs.glsl b/modules/base/shaders/screenspace_fs.glsl index 7c0f7e1b57..0d36c6ef4f 100644 --- a/modules/base/shaders/screenspace_fs.glsl +++ b/modules/base/shaders/screenspace_fs.glsl @@ -26,21 +26,20 @@ #include "PowerScaling/powerScaling_fs.hglsl" in vec2 vs_st; -in vec4 vs_position; +in float vs_depth; -uniform sampler2D texture1; -uniform float Alpha; +uniform sampler2D tex; +uniform vec3 color = vec3(1.0, 1.0, 1.0); +uniform float opacity = 1.0; Fragment getFragment() { - Fragment frag; + Fragment frag; - frag.color = texture(texture1, vs_st); - frag.color.a = Alpha * frag.color.a; - if (frag.color.a == 0.0) { - discard; - } + frag.color = texture(tex, vs_st) * vec4(color, opacity); + if (frag.color.a == 0.0) { + discard; + } - frag.depth = vs_position.z; - - return frag; + frag.depth = vs_depth; + return frag; } diff --git a/modules/base/shaders/screenspace_vs.glsl b/modules/base/shaders/screenspace_vs.glsl index 2f057ce33d..4932574f04 100644 --- a/modules/base/shaders/screenspace_vs.glsl +++ b/modules/base/shaders/screenspace_vs.glsl @@ -28,14 +28,13 @@ layout(location = 0) in vec3 in_position; layout(location = 1) in vec2 in_st; out vec2 vs_st; -out vec4 vs_position; - -uniform mat4 ModelTransform; -uniform mat4 ViewProjectionMatrix; +out float vs_depth; +uniform mat4 mvpMatrix; void main() { - vs_st = in_st; - vs_position = ViewProjectionMatrix * ModelTransform * vec4(in_position, 1.0); - gl_Position = vec4(vs_position); + vs_st = in_st; + vec4 p = mvpMatrix * vec4(in_position, 1.0); + vs_depth = p.z; + gl_Position = vec4(p); } diff --git a/modules/base/shaders/sphere_fs.glsl b/modules/base/shaders/sphere_fs.glsl index 0a3a97acec..33b5374993 100644 --- a/modules/base/shaders/sphere_fs.glsl +++ b/modules/base/shaders/sphere_fs.glsl @@ -23,13 +23,11 @@ ****************************************************************************************/ #include "fragment.glsl" -#include "PowerScaling/powerScaling_fs.hglsl" in vec4 vs_position; in vec2 vs_textureCoords; in vec3 vs_normal; -uniform float time; uniform sampler2D colorTexture; uniform float opacity; uniform bool mirrorTexture; diff --git a/modules/base/shaders/sphere_vs.glsl b/modules/base/shaders/sphere_vs.glsl index 873646d23a..99e4a11973 100644 --- a/modules/base/shaders/sphere_vs.glsl +++ b/modules/base/shaders/sphere_vs.glsl @@ -42,5 +42,5 @@ void main() { vs_position = position; // Set z to 0 to disable near/far-plane clipping - gl_Position = vec4(position.xy, 0.0, position.w); + gl_Position = vec4(position.xy, 0.0, position.w); } diff --git a/modules/base/timeframe/timeframeinterval.cpp b/modules/base/timeframe/timeframeinterval.cpp index e0a18079b2..01606bb174 100644 --- a/modules/base/timeframe/timeframeinterval.cpp +++ b/modules/base/timeframe/timeframeinterval.cpp @@ -68,9 +68,7 @@ namespace { namespace openspace { documentation::Documentation TimeFrameInterval::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_time_frame_interval"; - return doc; + return codegen::doc("base_time_frame_interval"); } bool TimeFrameInterval::isActive(const Time& time) const { diff --git a/modules/base/timeframe/timeframeunion.cpp b/modules/base/timeframe/timeframeunion.cpp index b630f940ea..2b6204af04 100644 --- a/modules/base/timeframe/timeframeunion.cpp +++ b/modules/base/timeframe/timeframeunion.cpp @@ -50,13 +50,11 @@ namespace { namespace openspace { documentation::Documentation TimeFrameUnion::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_time_frame_union"; - return doc; + return codegen::doc("base_time_frame_union"); } bool TimeFrameUnion::isActive(const Time& time) const { - for (const auto& tf : _timeFrames) { + for (const ghoul::mm_unique_ptr& tf : _timeFrames) { if (tf->isActive(time)) { return true; } diff --git a/modules/base/translation/luatranslation.cpp b/modules/base/translation/luatranslation.cpp index 8f850d1f28..2f853e8394 100644 --- a/modules/base/translation/luatranslation.cpp +++ b/modules/base/translation/luatranslation.cpp @@ -56,9 +56,7 @@ namespace { namespace openspace { documentation::Documentation LuaTranslation::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_transform_translation_lua"; - return doc; + return codegen::doc("base_transform_translation_lua"); } LuaTranslation::LuaTranslation() @@ -69,8 +67,8 @@ LuaTranslation::LuaTranslation() _luaScriptFile.onChange([&]() { requireUpdate(); - _fileHandle = std::make_unique(_luaScriptFile); - _fileHandle->setCallback([&](const ghoul::filesystem::File&) { + _fileHandle = std::make_unique(_luaScriptFile.value()); + _fileHandle->setCallback([this]() { requireUpdate(); notifyObservers(); }); @@ -79,7 +77,7 @@ LuaTranslation::LuaTranslation() LuaTranslation::LuaTranslation(const ghoul::Dictionary& dictionary) : LuaTranslation() { const Parameters p = codegen::bake(dictionary); - _luaScriptFile = absPath(p.script); + _luaScriptFile = absPath(p.script).string(); } glm::dvec3 LuaTranslation::position(const UpdateData& data) const { diff --git a/modules/base/translation/statictranslation.cpp b/modules/base/translation/statictranslation.cpp index b4987cccf3..228d6a7d62 100644 --- a/modules/base/translation/statictranslation.cpp +++ b/modules/base/translation/statictranslation.cpp @@ -45,9 +45,7 @@ namespace { namespace openspace { documentation::Documentation StaticTranslation::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_transform_translation_static"; - return doc; + return codegen::doc("base_transform_translation_static"); } StaticTranslation::StaticTranslation() @@ -58,7 +56,7 @@ StaticTranslation::StaticTranslation() glm::dvec3(std::numeric_limits::max()) ) { - _position.setViewOption(properties::Property::ViewOptions::Logarithmic); + _position.setExponent(20.f); addProperty(_position); _position.onChange([this]() { diff --git a/modules/base/translation/timelinetranslation.cpp b/modules/base/translation/timelinetranslation.cpp index 6067f91c5b..defe7e9eab 100644 --- a/modules/base/translation/timelinetranslation.cpp +++ b/modules/base/translation/timelinetranslation.cpp @@ -42,9 +42,7 @@ namespace { namespace openspace { documentation::Documentation TimelineTranslation::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "base_transform_translation_keyframe"; - return doc; + return codegen::doc("base_transform_translation_keyframe"); } TimelineTranslation::TimelineTranslation(const ghoul::Dictionary& dictionary) { diff --git a/modules/cefwebgui/shaders/gui_fs.glsl b/modules/cefwebgui/shaders/gui_fs.glsl index 08a149d55a..1a08596b5e 100644 --- a/modules/cefwebgui/shaders/gui_fs.glsl +++ b/modules/cefwebgui/shaders/gui_fs.glsl @@ -24,12 +24,11 @@ #version __CONTEXT__ -in vec2 Texcoord; - +in vec2 vs_st; out vec4 outputColor; uniform sampler2D tex; void main() { - outputColor = texture(tex, Texcoord); + outputColor = texture(tex, vs_st); } diff --git a/modules/cefwebgui/shaders/gui_vs.glsl b/modules/cefwebgui/shaders/gui_vs.glsl index 6044288f45..88ee25ef02 100644 --- a/modules/cefwebgui/shaders/gui_vs.glsl +++ b/modules/cefwebgui/shaders/gui_vs.glsl @@ -25,13 +25,12 @@ #version __CONTEXT__ layout(location = 0) in vec2 position; +out vec2 vs_st; uniform mat4 ortho; -out vec2 Texcoord; - void main() { - Texcoord = vec2(position.x + 1.0f, position.y + 1.0f) * 0.5; + vs_st = vec2(position.x + 1.0, position.y + 1.0) * 0.5; gl_Position = vec4(position, 0.0, 1.0); } diff --git a/modules/debugging/rendering/renderabledebugplane.cpp b/modules/debugging/rendering/renderabledebugplane.cpp index 335e48b3b7..57f6958257 100644 --- a/modules/debugging/rendering/renderabledebugplane.cpp +++ b/modules/debugging/rendering/renderabledebugplane.cpp @@ -100,9 +100,7 @@ namespace { namespace openspace { documentation::Documentation RenderableDebugPlane::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "debugging_renderable_debugplane"; - return doc; + return codegen::doc("debugging_renderable_debugplane"); } RenderableDebugPlane::RenderableDebugPlane(const ghoul::Dictionary& dictionary) @@ -117,7 +115,7 @@ RenderableDebugPlane::RenderableDebugPlane(const ghoul::Dictionary& dictionary) _texture = p.texture.value_or(_texture); addProperty(_texture); - _size.setViewOption(properties::Property::ViewOptions::Logarithmic); + _size.setExponent(15.f); _size.onChange([this](){ _planeIsDirty = true; }); _size = p.size.value_or(_size); setBoundingSphere(_size); diff --git a/modules/digitaluniverse/CMakeLists.txt b/modules/digitaluniverse/CMakeLists.txt index 8eb459ec5e..b8abefa7da 100644 --- a/modules/digitaluniverse/CMakeLists.txt +++ b/modules/digitaluniverse/CMakeLists.txt @@ -41,12 +41,6 @@ set(SOURCE_FILES source_group("Source Files" FILES ${SOURCE_FILES}) set(SHADER_FILES - shaders/pointssprite_fs.glsl - shaders/pointssprite_vs.glsl - shaders/points_sprite_fs.glsl - shaders/points_fs.glsl - shaders/points_gs.glsl - shaders/points_vs.glsl shaders/billboard_fs.glsl shaders/billboard_gs.glsl shaders/billboard_vs.glsl @@ -57,6 +51,8 @@ set(SHADER_FILES shaders/dumesh_fs.glsl shaders/plane_vs.glsl shaders/plane_fs.glsl + shaders/points_sprite_fs.glsl + shaders/points_vs.glsl ) source_group("Shader Files" FILES ${SHADER_FILES}) diff --git a/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp b/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp index 3da6f82553..a0aa0c4f33 100644 --- a/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp +++ b/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp @@ -33,22 +33,23 @@ #include #include #include -#include -#include +#include +#include +#include #include #include +#include +#include #include #include #include #include #include -#include -#include -#include #include #include -#include #include +#include +#include #include #include #include @@ -66,7 +67,6 @@ namespace { "hasColorMap", "enabledRectSizeControl", "hasDvarScaling" }; - constexpr int8_t CurrentCacheVersion = 1; constexpr double PARSEC = 0.308567756E17; constexpr const int RenderOptionViewDirection = 0; @@ -116,18 +116,11 @@ namespace { "The text size for the astronomical object labels." }; - constexpr openspace::properties::Property::PropertyInfo LabelMinSizeInfo = { - "TextMinSize", - "Text Min Size", - "The minimal size (in pixels) of the text for the labels for the astronomical " - "objects being rendered." - }; - - constexpr openspace::properties::Property::PropertyInfo LabelMaxSizeInfo = { - "TextMaxSize", - "Text Max Size", - "The maximum size (in pixels) of the text for the labels for the astronomical " - "objects being rendered." + constexpr openspace::properties::Property::PropertyInfo LabelMinMaxSizeInfo = { + "TextMinMaxSize", + "Text Min/Max Size", + "The minimal and maximal size (in pixels) of the text for the labels for the " + "astronomical objects being rendered." }; constexpr openspace::properties::Property::PropertyInfo DrawElementsInfo = { @@ -178,48 +171,43 @@ namespace { constexpr openspace::properties::Property::PropertyInfo DisableFadeInInfo = { "DisableFadeIn", - "Disable Fade-in effect", + "Disable Fade-in Effect", "Enables/Disables the Fade-in effect." }; - constexpr openspace::properties::Property::PropertyInfo BillboardMaxSizeInfo = { - "BillboardMaxSize", - "Billboard Max Size in Pixels", - "The max size (in pixels) for the billboard representing the astronomical " - "object." + constexpr openspace::properties::Property::PropertyInfo PixelSizeControlInfo = { + "EnablePixelSizeControl", + "Enable Pixel Size Control", + "Enable pixel size control for rectangular projections. If set to true, the " + "billboard size is restricted by the min/max size in pixels property." }; - constexpr openspace::properties::Property::PropertyInfo BillboardMinSizeInfo = { - "BillboardMinSize", - "Billboard Min Size in Pixels", - "The min size (in pixels) for the billboard representing the astronomical " - "object." + constexpr openspace::properties::Property::PropertyInfo BillboardMinMaxSizeInfo = { + "BillboardMinMaxSize", + "Billboard Min/Max Size in Pixels", + "The minimum and maximum size (in pixels) for the billboard representing the " + "astronomical object." }; constexpr openspace::properties::Property::PropertyInfo - CorrectionSizeEndDistanceInfo = { + CorrectionSizeEndDistanceInfo = + { "CorrectionSizeEndDistance", - "Distance in 10^X meters where correction size stops acting.", + "Distance in 10^X meters where correction size stops acting", "Distance in 10^X meters where correction size stops acting." }; constexpr openspace::properties::Property::PropertyInfo CorrectionSizeFactorInfo = { "CorrectionSizeFactor", - "Control variable for distance size.", + "Control variable for distance size", "" }; - constexpr openspace::properties::Property::PropertyInfo PixelSizeControlInfo = { - "EnablePixelSizeControl", - "Enable pixel size control.", - "Enable pixel size control for rectangular projections." - }; - constexpr openspace::properties::Property::PropertyInfo UseLinearFiltering = { "UseLinearFiltering", "Use Linear Filtering", "Determines whether the provided color map should be sampled nearest neighbor " - "(=off) or linearly (=on" + "(=off) or linearly (=on)" }; constexpr openspace::properties::Property::PropertyInfo SetRangeFromData = { @@ -258,6 +246,8 @@ namespace { Gigaparsec [[codegen::key("Gpc")]], GigalightYears [[codegen::key("Gly")]] }; + // The unit used for all distances. Must match the unit of any + // distances/positions in the data files std::optional unit; // [[codegen::verbatim(ScaleFactorInfo.description)]] @@ -289,11 +279,8 @@ namespace { // objects being rendered std::optional labelFile; - // [[codegen::verbatim(LabelMinSizeInfo.description)]] - std::optional textMinSize; - - // [[codegen::verbatim(LabelMaxSizeInfo.description)]] - std::optional textMaxSize; + // [[codegen::verbatim(LabelMinMaxSizeInfo.description)]] + std::optional textMinMaxSize; // [[codegen::verbatim(ColorOptionInfo.description)]] std::optional> colorOption; @@ -314,11 +301,8 @@ namespace { // [[codegen::verbatim(DisableFadeInInfo.description)]] std::optional disableFadeIn; - // [[codegen::verbatim(BillboardMaxSizeInfo.description)]] - std::optional billboardMaxSize; - - // [[codegen::verbatim(BillboardMinSizeInfo.description)]] - std::optional billboardMinSize; + // [[codegen::verbatim(BillboardMinMaxSizeInfo.description)]] + std::optional billboardMinMaxSize; // [[codegen::verbatim(CorrectionSizeEndDistanceInfo.description)]] std::optional correctionSizeEndDistance; @@ -338,9 +322,7 @@ namespace { namespace openspace { documentation::Documentation RenderableBillboardsCloud::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "digitaluniverse_RenderableBillboardsCloud"; - return doc; + return codegen::doc("digitaluniverse_RenderableBillboardsCloud"); } RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& dictionary) @@ -351,27 +333,34 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di , _textColor(TextColorInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(1.f)) , _textOpacity(TextOpacityInfo, 1.f, 0.f, 1.f) , _textSize(TextSizeInfo, 8.f, 0.5f, 24.f) - , _textMinSize(LabelMinSizeInfo, 8.f, 0.5f, 24.f) - , _textMaxSize(LabelMaxSizeInfo, 20.f, 0.5f, 100.f) + , _textMinMaxSize( + LabelMinMaxSizeInfo, + glm::ivec2(8, 20), + glm::ivec2(0), + glm::ivec2(100) + ) , _drawElements(DrawElementsInfo, true) , _drawLabels(DrawLabelInfo, false) , _pixelSizeControl(PixelSizeControlInfo, false) , _colorOption(ColorOptionInfo, properties::OptionProperty::DisplayType::Dropdown) , _optionColorRangeData(OptionColorRangeInfo, glm::vec2(0.f)) - , _datavarSizeOption( SizeOptionInfo, properties::OptionProperty::DisplayType::Dropdown ) - , _fadeInDistance( + , _fadeInDistances( FadeInDistancesInfo, glm::vec2(0.f), glm::vec2(0.f), glm::vec2(100.f) ) , _disableFadeInDistance(DisableFadeInInfo, true) - , _billboardMaxSize(BillboardMaxSizeInfo, 400.f, 0.f, 1000.f) - , _billboardMinSize(BillboardMinSizeInfo, 0.f, 0.f, 100.f) + , _billboardMinMaxSize( + BillboardMinMaxSizeInfo, + glm::vec2(0.f, 400.f), + glm::vec2(0.f), + glm::vec2(1000.f) + ) , _correctionSizeEndDistance(CorrectionSizeEndDistanceInfo, 17.f, 12.f, 25.f) , _correctionSizeFactor(CorrectionSizeFactorInfo, 8.f, 0.f, 20.f) , _useLinearFiltering(UseLinearFiltering, false) @@ -381,7 +370,7 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di const Parameters p = codegen::bake(dictionary); if (p.file.has_value()) { - _speckFile = absPath(*p.file); + _speckFile = absPath(*p.file).string(); } _hasSpeckFile = p.file.has_value(); @@ -433,24 +422,23 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di } } else { - LWARNING("No unit given for RenderableBillboardsCloud. Using meters as units."); + LWARNING("No unit given for RenderableBillboardsCloud. Using meters as units"); _unit = Meter; } if (p.texture.has_value()) { - _spriteTexturePath = absPath(*p.texture); + _spriteTexturePath = absPath(*p.texture).string(); _spriteTexturePath.onChange([&]() { _spriteTextureIsDirty = true; }); // @TODO (abock, 2021-01-31) I don't know why we only add this property if the // texture is given, but I think it's a bug + // @TODO (emmbr, 2021-05-24) This goes for several properties in this renderable addProperty(_spriteTexturePath); - } _hasSpriteTexture = p.texture.has_value(); - if (p.colorMap.has_value()) { - _colorMapFile = absPath(*p.colorMap); + _colorMapFile = absPath(*p.colorMap).string(); _hasColorMapFile = true; if (p.colorOption.has_value()) { @@ -517,7 +505,7 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di _drawLabels = p.drawLabels.value_or(_drawLabels); addProperty(_drawLabels); - _labelFile = absPath(*p.labelFile); + _labelFile = absPath(*p.labelFile).string(); _hasLabel = true; _textColor = p.textColor.value_or(_textColor); @@ -532,28 +520,28 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di _textSize = p.textSize.value_or(_textSize); addProperty(_textSize); - _textMinSize = p.textMinSize.value_or(_textMinSize); - addProperty(_textMinSize); - - _textMaxSize = p.textMaxSize.value_or(_textMaxSize); - addProperty(_textMaxSize); + _textMinMaxSize = p.textMinMaxSize.value_or(_textMinMaxSize); + _textMinMaxSize.setViewOption(properties::Property::ViewOptions::MinMaxRange); + addProperty(_textMinMaxSize); } _transformationMatrix = p.transformationMatrix.value_or(_transformationMatrix); if (p.fadeInDistances.has_value()) { - _fadeInDistance = *p.fadeInDistances; - addProperty(_fadeInDistance); + _fadeInDistances = *p.fadeInDistances; + _fadeInDistances.setViewOption(properties::Property::ViewOptions::MinMaxRange); + addProperty(_fadeInDistances); _disableFadeInDistance = false; addProperty(_disableFadeInDistance); } - _billboardMaxSize = p.billboardMaxSize.value_or(_billboardMaxSize); - addProperty(_billboardMaxSize); + _pixelSizeControl = p.enablePixelSizeControl.value_or(_pixelSizeControl); + addProperty(_pixelSizeControl); - _billboardMinSize = p.billboardMinSize.value_or(_billboardMinSize); - addProperty(_billboardMinSize); + _billboardMinMaxSize = p.billboardMinMaxSize.value_or(_billboardMinMaxSize); + _billboardMinMaxSize.setViewOption(properties::Property::ViewOptions::MinMaxRange); + addProperty(_billboardMinMaxSize); _correctionSizeEndDistance = p.correctionSizeEndDistance.value_or(_correctionSizeEndDistance); @@ -564,21 +552,16 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di addProperty(_correctionSizeFactor); } - _pixelSizeControl = p.enablePixelSizeControl.value_or(_pixelSizeControl); - if (p.enablePixelSizeControl.has_value()) { - addProperty(_pixelSizeControl); - } - _setRangeFromData.onChange([this]() { const int colorMapInUse = - _hasColorMapFile ? _variableDataPositionMap[_colorOptionString] : 0; + _hasColorMapFile ? _dataset.index(_colorOptionString) : 0; float minValue = std::numeric_limits::max(); - float maxValue = std::numeric_limits::min(); - for (size_t i = 0; i < _fullData.size(); i += _nValuesPerAstronomicalObject) { - float colorIdx = _fullData[i + 3 + colorMapInUse]; - maxValue = colorIdx >= maxValue ? colorIdx : maxValue; - minValue = colorIdx < minValue ? colorIdx : minValue; + float maxValue = -std::numeric_limits::max(); + for (const speck::Dataset::Entry& e : _dataset.entries) { + float color = e.data[colorMapInUse]; + minValue = std::min(minValue, color); + maxValue = std::max(maxValue, color); } _optionColorRangeData = glm::vec2(minValue, maxValue); @@ -591,15 +574,25 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di } bool RenderableBillboardsCloud::isReady() const { - return ((_program != nullptr) && (!_fullData.empty())) || (!_labelData.empty()); + return (_program && (!_dataset.entries.empty())) || (!_labelset.entries.empty()); } void RenderableBillboardsCloud::initialize() { ZoneScoped - bool success = loadData(); - if (!success) { - throw ghoul::RuntimeError("Error loading data"); + if (_hasSpeckFile) { + _dataset = speck::data::loadFileWithCache(_speckFile); + } + + if (_hasColorMapFile) { + _colorMap = speck::color::loadFileWithCache(_colorMapFile); + } + + if (!_labelFile.empty()) { + _labelset = speck::label::loadFileWithCache(_labelFile); + for (speck::Labelset::Entry& e : _labelset.entries) { + e.position = glm::vec3(_transformationMatrix * glm::dvec4(e.position, 1.0)); + } } if (!_colorOptionString.empty() && (_colorRangeData.size() > 1)) { @@ -645,7 +638,7 @@ void RenderableBillboardsCloud::initializeGL() { } if (_hasLabel) { - if (_font == nullptr) { + if (!_font) { size_t _fontSize = 50; _font = global::fontManager->font( "Mono", @@ -714,8 +707,11 @@ void RenderableBillboardsCloud::renderBillboards(const RenderData& data, glm::dmat4(data.camera.projectionMatrix()) * data.camera.combinedViewMatrix() ) ); - _program->setUniform(_uniformCache.minBillboardSize, _billboardMinSize); // in pixels - _program->setUniform(_uniformCache.maxBillboardSize, _billboardMaxSize); // in pixels + + const float minBillboardSize = _billboardMinMaxSize.value().x; // in pixels + const float maxBillboardSize = _billboardMinMaxSize.value().y; // in pixels + _program->setUniform(_uniformCache.minBillboardSize, minBillboardSize); + _program->setUniform(_uniformCache.maxBillboardSize, maxBillboardSize); _program->setUniform(_uniformCache.color, _pointColor); _program->setUniform(_uniformCache.alphaValue, _opacity); _program->setUniform(_uniformCache.scaleFactor, _scaleFactor); @@ -749,11 +745,7 @@ void RenderableBillboardsCloud::renderBillboards(const RenderData& data, _program->setUniform(_uniformCache.hasColormap, _hasColorMapFile); glBindVertexArray(_vao); - const GLsizei nAstronomicalObjects = static_cast( - _fullData.size() / _nValuesPerAstronomicalObject - ); - glDrawArrays(GL_POINTS, 0, nAstronomicalObjects); - + glDrawArrays(GL_POINTS, 0, static_cast(_dataset.entries.size())); glBindVertexArray(0); _program->deactivate(); @@ -767,16 +759,13 @@ void RenderableBillboardsCloud::renderLabels(const RenderData& data, const glm::dvec3& orthoUp, float fadeInVariable) { - glm::vec4 textColor = glm::vec4( - glm::vec3(_textColor), - _textOpacity * fadeInVariable - ); + glm::vec4 textColor = glm::vec4(glm::vec3(_textColor), _textOpacity * fadeInVariable); ghoul::fontrendering::FontRenderer::ProjectedLabelsInformation labelInfo; labelInfo.orthoRight = orthoRight; labelInfo.orthoUp = orthoUp; - labelInfo.minSize = static_cast(_textMinSize); - labelInfo.maxSize = static_cast(_textMaxSize); + labelInfo.minSize = _textMinMaxSize.value().x; + labelInfo.maxSize = _textMinMaxSize.value().y; labelInfo.cameraPos = data.camera.positionVec3(); labelInfo.cameraLookUp = data.camera.lookUpVectorWorldSpace(); labelInfo.renderType = _renderOption; @@ -785,14 +774,13 @@ void RenderableBillboardsCloud::renderLabels(const RenderData& data, labelInfo.enableDepth = true; labelInfo.enableFalseDepth = false; - for (const std::pair& pair : _labelData) { - //glm::vec3 scaledPos(_transformationMatrix * glm::dvec4(pair.first, 1.0)); - glm::vec3 scaledPos(pair.first); + for (const speck::Labelset::Entry& e : _labelset.entries) { + glm::vec3 scaledPos(e.position); scaledPos *= unitToMeter(_unit); ghoul::fontrendering::FontRenderer::defaultProjectionRenderer().render( *_font, scaledPos, - pair.second, + e.text, textColor, labelInfo ); @@ -800,14 +788,16 @@ void RenderableBillboardsCloud::renderLabels(const RenderData& data, } void RenderableBillboardsCloud::render(const RenderData& data, RendererTasks&) { - float fadeInVariable = 1.f; + float fadeInVar = 1.f; if (!_disableFadeInDistance) { float distCamera = static_cast(glm::length(data.camera.positionVec3())); - const glm::vec2 fadeRange = _fadeInDistance; - const float a = 1.f / ((fadeRange.y - fadeRange.x) * unitToMeter(_unit)); + const glm::vec2 fadeRange = _fadeInDistances; + const float a = static_cast( + 1.f / ((fadeRange.y - fadeRange.x) * unitToMeter(_unit)) + ); const float b = -(fadeRange.x / (fadeRange.y - fadeRange.x)); const float funcValue = a * distCamera + b; - fadeInVariable *= funcValue > 1.f ? 1.f : funcValue; + fadeInVar *= funcValue > 1.f ? 1.f : funcValue; if (funcValue < 0.01f) { return; @@ -840,23 +830,11 @@ void RenderableBillboardsCloud::render(const RenderData& data, RendererTasks&) { glm::dvec3 orthoUp = glm::normalize(glm::cross(cameraViewDirectionWorld, orthoRight)); if (_hasSpeckFile && _drawElements) { - renderBillboards( - data, - modelMatrix, - orthoRight, - orthoUp, - fadeInVariable - ); + renderBillboards(data, modelMatrix, orthoRight, orthoUp, fadeInVar); } if (_drawLabels && _hasLabel) { - renderLabels( - data, - modelViewProjectionMatrix, - orthoRight, - orthoUp, - fadeInVariable - ); + renderLabels(data, modelViewProjectionMatrix, orthoRight, orthoUp, fadeInVar); } } @@ -868,9 +846,9 @@ void RenderableBillboardsCloud::update(const UpdateData&) { TracyGpuZone("Data dirty") LDEBUG("Regenerating data"); - createDataSlice(); + std::vector slice = createDataSlice(); - int size = static_cast(_slicedData.size()); + int size = static_cast(slice.size()); if (_vao == 0) { glGenVertexArrays(1, &_vao); @@ -883,12 +861,7 @@ void RenderableBillboardsCloud::update(const UpdateData&) { glBindVertexArray(_vao); glBindBuffer(GL_ARRAY_BUFFER, _vbo); - glBufferData( - GL_ARRAY_BUFFER, - size * sizeof(float), - &_slicedData[0], - GL_STATIC_DRAW - ); + glBufferData(GL_ARRAY_BUFFER, size * sizeof(float), slice.data(), GL_STATIC_DRAW); GLint positionAttrib = _program->attributeLocation("in_position"); if (_hasColorMapFile && _hasDatavarSize) { @@ -898,7 +871,7 @@ void RenderableBillboardsCloud::update(const UpdateData&) { 4, GL_FLOAT, GL_FALSE, - sizeof(float) * 9, + 9 * sizeof(float), nullptr ); @@ -909,8 +882,8 @@ void RenderableBillboardsCloud::update(const UpdateData&) { 4, GL_FLOAT, GL_FALSE, - sizeof(float) * 9, - reinterpret_cast(sizeof(float) * 4) + 9 * sizeof(float), + reinterpret_cast(4 * sizeof(float)) ); GLint dvarScalingAttrib = _program->attributeLocation("in_dvarScaling"); @@ -920,8 +893,8 @@ void RenderableBillboardsCloud::update(const UpdateData&) { 1, GL_FLOAT, GL_FALSE, - sizeof(float) * 9, - reinterpret_cast(sizeof(float) * 8) + 9 * sizeof(float), + reinterpret_cast(8 * sizeof(float)) ); } else if (_hasColorMapFile) { @@ -931,7 +904,7 @@ void RenderableBillboardsCloud::update(const UpdateData&) { 4, GL_FLOAT, GL_FALSE, - sizeof(float) * 8, + 8 * sizeof(float), nullptr ); @@ -942,8 +915,8 @@ void RenderableBillboardsCloud::update(const UpdateData&) { 4, GL_FLOAT, GL_FALSE, - sizeof(float) * 8, - reinterpret_cast(sizeof(float) * 4) + 8 * sizeof(float), + reinterpret_cast(4 * sizeof(float)) ); } else if (_hasDatavarSize) { @@ -953,7 +926,7 @@ void RenderableBillboardsCloud::update(const UpdateData&) { 4, GL_FLOAT, GL_FALSE, - sizeof(float) * 8, + 8 * sizeof(float), nullptr ); @@ -964,8 +937,8 @@ void RenderableBillboardsCloud::update(const UpdateData&) { 1, GL_FLOAT, GL_FALSE, - sizeof(float) * 5, - reinterpret_cast(sizeof(float) * 4) + 5 * sizeof(float), + reinterpret_cast(4 * sizeof(float)) ); } else { @@ -999,7 +972,7 @@ void RenderableBillboardsCloud::update(const UpdateData&) { [path = _spriteTexturePath]() -> std::unique_ptr { LINFO(fmt::format("Loaded texture from '{}'", absPath(path))); std::unique_ptr t = - ghoul::io::TextureReader::ref().loadTexture(absPath(path)); + ghoul::io::TextureReader::ref().loadTexture(absPath(path).string()); t->uploadTexture(); t->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); t->purgeFromRAM(); @@ -1012,434 +985,9 @@ void RenderableBillboardsCloud::update(const UpdateData&) { } } -bool RenderableBillboardsCloud::loadData() { - bool success = true; - - success &= loadSpeckData(); - - if (_hasColorMapFile) { - if (!_hasSpeckFile) { - success = true; - } - success &= readColorMapFile(); - } - - success &= loadLabelData(); - - return success; -} - -bool RenderableBillboardsCloud::loadSpeckData() { - if (!_hasSpeckFile) { - return true; - } - bool success = true; - const std::string& cachedFile = FileSys.cacheManager()->cachedFilename( - ghoul::filesystem::File(_speckFile), - "RenderableDUMeshes|" + identifier(), - ghoul::filesystem::CacheManager::Persistent::Yes - ); - - const bool hasCachedFile = FileSys.fileExists(cachedFile); - if (hasCachedFile) { - LINFO(fmt::format( - "Cached file '{}' used for Speck file '{}'", - cachedFile, _speckFile - )); - - success = loadCachedFile(cachedFile); - if (success) { - return true; - } - else { - FileSys.cacheManager()->removeCacheFile(_speckFile); - // Intentional fall-through to the 'else' to generate the cache - // file for the next run - } - } - else { - LINFO(fmt::format("Cache for Speck file '{}' not found", _speckFile)); - } - LINFO(fmt::format("Loading Speck file '{}'", _speckFile)); - - success = readSpeckFile(); - if (!success) { - return false; - } - - success &= saveCachedFile(cachedFile); - return success; -} - -bool RenderableBillboardsCloud::loadLabelData() { - if (_labelFile.empty()) { - return true; - } - bool success = true; - // I disabled the cache as it didn't work on Mac --- abock - const std::string& cachedFile = FileSys.cacheManager()->cachedFilename( - ghoul::filesystem::File(_labelFile), - ghoul::filesystem::CacheManager::Persistent::Yes - ); - if (!_hasSpeckFile && !_hasColorMapFile) { - success = true; - } - const bool hasCachedFile = FileSys.fileExists(cachedFile); - if (hasCachedFile) { - LINFO(fmt::format( - "Cached file '{}' used for Label file '{}'", - cachedFile, _labelFile - )); - - success &= loadCachedFile(cachedFile); - if (!success) { - FileSys.cacheManager()->removeCacheFile(_labelFile); - // Intentional fall-through to the 'else' to generate the cache - // file for the next run - } - } - else { - LINFO(fmt::format("Cache for Label file '{}' not found", _labelFile)); - LINFO(fmt::format("Loading Label file '{}'", _labelFile)); - - success &= readLabelFile(); - if (!success) { - return false; - } - } - - return success; -} - -bool RenderableBillboardsCloud::readSpeckFile() { - std::ifstream file(_speckFile); - if (!file.good()) { - LERROR(fmt::format("Failed to open Speck file '{}'", _speckFile)); - return false; - } - - _nValuesPerAstronomicalObject = 0; - - // The beginning of the speck file has a header that either contains comments - // (signaled by a preceding '#') or information about the structure of the file - // (signaled by the keywords 'datavar', 'texturevar', and 'texture') - std::string line; - while (true) { - std::getline(file, line); - - // Guard against wrong line endings (copying files from Windows to Mac) causes - // lines to have a final \r - if (!line.empty() && line.back() == '\r') { - line = line.substr(0, line.length() - 1); - } - - if (line.empty() || line[0] == '#') { - continue; - } - - if (line.substr(0, 7) != "datavar" && - line.substr(0, 10) != "texturevar" && - line.substr(0, 7) != "texture" && - line.substr(0, 10) != "polyorivar" && - line.substr(0, 10) != "maxcomment") - { - // Started reading data - break; - } - - if (line.substr(0, 7) == "datavar") { - // datavar lines are structured as follows: - // datavar # description - // where # is the index of the data variable; so if we repeatedly overwrite - // the 'nValues' variable with the latest index, we will end up with the total - // number of values (+3 since X Y Z are not counted in the Speck file index) - std::stringstream str(line); - - std::string dummy; - str >> dummy; // command - str >> _nValuesPerAstronomicalObject; // variable index - dummy.clear(); - str >> dummy; // variable name - - _variableDataPositionMap.insert({ dummy, _nValuesPerAstronomicalObject }); - - // We want the number, but the index is 0 based - _nValuesPerAstronomicalObject += 1; - } - } - - _nValuesPerAstronomicalObject += 3; // X Y Z are not counted in the Speck file indices - - - - do { - // Guard against wrong line endings (copying files from Windows to Mac) causes - // lines to have a final \r - if (!line.empty() && line.back() == '\r') { - line = line.substr(0, line.length() - 1); - } - - if (line.empty()) { - std::getline(file, line); - continue; - } - else if (line[0] == '#') { - std::getline(file, line); - continue; - } - - std::stringstream str(line); - std::vector values(_nValuesPerAstronomicalObject); - - for (int i = 0; i < _nValuesPerAstronomicalObject; ++i) { - str >> values[i]; - } - - _fullData.insert(_fullData.end(), values.begin(), values.end()); - - // reads new line - std::getline(file, line); - } while (!file.eof()); - - return true; -} - -bool RenderableBillboardsCloud::readColorMapFile() { - std::string _file = _colorMapFile; - std::ifstream file(_file); - if (!file.good()) { - LERROR(fmt::format("Failed to open Color Map file '{}'", _file)); - return false; - } - - std::size_t numberOfColors = 0; - - // The beginning of the speck file has a header that either contains comments - // (signaled by a preceding '#') or information about the structure of the file - // (signaled by the keywords 'datavar', 'texturevar', and 'texture') - std::string line; - while (true) { - // std::streampos position = file.tellg(); - std::getline(file, line); - - if (line[0] == '#' || line.empty()) { - continue; - } - - // Initial number of colors - std::locale loc; - if (std::isdigit(line[0], loc)) { - std::string::size_type sz; - numberOfColors = std::stoi(line, &sz); - break; - } - else if (file.eof()) { - return false; - } - } - - for (size_t i = 0; i < numberOfColors; ++i) { - std::getline(file, line); - std::stringstream str(line); - - glm::vec4 color; - // Each color in the colormap must be defined as (R,G,B,A) - for (int j = 0; j < 4; ++j) { - str >> color[j]; - } - - _colorMapData.push_back(color); - } - - return true; -} - -bool RenderableBillboardsCloud::readLabelFile() { - std::string _file = _labelFile; - std::ifstream file(_file); - if (!file.good()) { - LERROR(fmt::format("Failed to open Label file '{}'", _file)); - return false; - } - - // The beginning of the speck file has a header that either contains comments - // (signaled by a preceding '#') or information about the structure of the file - // (signaled by the keywords 'datavar', 'texturevar', and 'texture') - std::string line; - while (true) { - std::streampos position = file.tellg(); - std::getline(file, line); - - // Guard against wrong line endings (copying files from Windows to Mac) causes - // lines to have a final \r - if (!line.empty() && line.back() == '\r') { - line = line.substr(0, line.length() - 1); - } - - if (line.empty() || line[0] == '#') { - continue; - } - - if (line.substr(0, 9) != "textcolor") { - // we read a line that doesn't belong to the header, so we have to jump back - // before the beginning of the current line - file.seekg(position); - continue; - } - - if (line.substr(0, 9) == "textcolor") { - // textcolor lines are structured as follows: - // textcolor # description - // where # is color text defined in configuration file - std::stringstream str(line); - - // TODO: handle cases of labels with different colors - break; - } - } - - - do { - std::vector values(_nValuesPerAstronomicalObject); - - std::getline(file, line); - - // Guard against wrong line endings (copying files from Windows to Mac) causes - // lines to have a final \r - if (!line.empty() && line.back() == '\r') { - line = line.substr(0, line.length() - 1); - } - - if (line.empty()) { - continue; - } - - std::stringstream str(line); - - glm::vec3 position = glm::vec3(0.f); - for (int j = 0; j < 3; ++j) { - str >> position[j]; - } - - std::string dummy; - str >> dummy; // text keyword - - std::string label; - str >> label; - dummy.clear(); - - while (str >> dummy) { - if (dummy == "#") { - break; - } - - label += " " + dummy; - dummy.clear(); - } - - glm::vec3 transformedPos = glm::vec3( - _transformationMatrix * glm::dvec4(position, 1.0) - ); - _labelData.emplace_back(std::make_pair(transformedPos, label)); - } while (!file.eof()); - - return true; -} - -bool RenderableBillboardsCloud::loadCachedFile(const std::string& file) { - std::ifstream fileStream(file, std::ifstream::binary); - if (!fileStream.good()) { - LERROR(fmt::format("Error opening file '{}' for loading cache file", file)); - return false; - } - int8_t version = 0; - fileStream.read(reinterpret_cast(&version), sizeof(int8_t)); - if (version != CurrentCacheVersion) { - LINFO("The format of the cached file has changed: deleting old cache"); - fileStream.close(); - FileSys.deleteFile(file); - return false; - } - - int32_t nValues = 0; - fileStream.read(reinterpret_cast(&nValues), sizeof(int32_t)); - fileStream.read( - reinterpret_cast(&_nValuesPerAstronomicalObject), - sizeof(int32_t) - ); - - _fullData.resize(nValues); - fileStream.read( - reinterpret_cast(&_fullData[0]), - nValues * sizeof(_fullData[0]) - ); - - if (_hasColorMapFile) { - int32_t nItems = 0; - fileStream.read(reinterpret_cast(&nItems), sizeof(int32_t)); - - for (int i = 0; i < nItems; ++i) { - int32_t keySize = 0; - fileStream.read(reinterpret_cast(&keySize), sizeof(int32_t)); - std::vector buffer(keySize); - fileStream.read(buffer.data(), keySize); - - std::string key(buffer.begin(), buffer.end()); - int32_t value = 0; - fileStream.read(reinterpret_cast(&value), sizeof(int32_t)); - - _variableDataPositionMap.insert({ key, value }); - } - } - - bool success = fileStream.good(); - return success; -} - -bool RenderableBillboardsCloud::saveCachedFile(const std::string& file) const { - std::ofstream fileStream(file, std::ofstream::binary); - if (!fileStream.good()) { - LERROR(fmt::format("Error opening file '{}' for save cache file", file)); - return false; - } - fileStream.write(reinterpret_cast(&CurrentCacheVersion), sizeof(int8_t)); - - int32_t nValues = static_cast(_fullData.size()); - if (nValues == 0) { - LERROR("Error writing cache: No values were loaded"); - return false; - } - fileStream.write(reinterpret_cast(&nValues), sizeof(int32_t)); - - int32_t nValuesPerAstronomicalObject = static_cast( - _nValuesPerAstronomicalObject - ); - fileStream.write( - reinterpret_cast(&nValuesPerAstronomicalObject), - sizeof(int32_t) - ); - - size_t nBytes = nValues * sizeof(_fullData[0]); - fileStream.write(reinterpret_cast(&_fullData[0]), nBytes); - - if (_hasColorMapFile) { - int32_t nItems = static_cast(_variableDataPositionMap.size()); - fileStream.write(reinterpret_cast(&nItems), sizeof(int32_t)); - - for (const std::pair& pair : _variableDataPositionMap) { - int32_t keySize = static_cast(pair.first.size()); - fileStream.write(reinterpret_cast(&keySize), sizeof(int32_t)); - fileStream.write(pair.first.data(), keySize); - int32_t value = static_cast(pair.second); - fileStream.write(reinterpret_cast(&value), sizeof(int32_t)); - } - } - - return fileStream.good(); -} - double RenderableBillboardsCloud::unitToMeter(Unit unit) const { - switch (_unit) { + // @TODO (abock, 2021-05-10) This should be moved to a centralized conversion code + switch (unit) { case Meter: return 1.0; case Kilometer: return 1e3; case Parsec: return PARSEC; @@ -1451,76 +999,58 @@ double RenderableBillboardsCloud::unitToMeter(Unit unit) const { } } -void RenderableBillboardsCloud::createDataSlice() { +std::vector RenderableBillboardsCloud::createDataSlice() { ZoneScoped - _slicedData.clear(); - - if (_fullData.empty() || _nValuesPerAstronomicalObject == 0) { - return; + if (_dataset.entries.empty()) { + return std::vector(); } + std::vector result; if (_hasColorMapFile) { - _slicedData.reserve(8 * (_fullData.size() / _nValuesPerAstronomicalObject)); + result.reserve(8 * _dataset.entries.size()); } else { - _slicedData.reserve(4 * (_fullData.size() / _nValuesPerAstronomicalObject)); + result.reserve(4 * _dataset.entries.size()); } // what datavar in use for the index color - int colorMapInUse = - _hasColorMapFile ? _variableDataPositionMap[_colorOptionString] : 0; + int colorMapInUse = _hasColorMapFile ? _dataset.index(_colorOptionString) : 0; // what datavar in use for the size scaling (if present) - int sizeScalingInUse = _hasDatavarSize ? - _variableDataPositionMap[_datavarSizeOptionString] : -1; - - auto addDatavarSizeScalling = [&](size_t i, int datavarInUse) { - _slicedData.push_back(_fullData[i + 3 + datavarInUse]); - }; - - auto addPosition = [&](const glm::vec4& pos) { - for (int j = 0; j < 4; ++j) { - _slicedData.push_back(pos[j]); - } - }; + int sizeScalingInUse = + _hasDatavarSize ? _dataset.index(_datavarSizeOptionString) : -1; float minColorIdx = std::numeric_limits::max(); - float maxColorIdx = std::numeric_limits::min(); - - for (size_t i = 0; i < _fullData.size(); i += _nValuesPerAstronomicalObject) { - float colorIdx = _fullData[i + 3 + colorMapInUse]; - maxColorIdx = colorIdx >= maxColorIdx ? colorIdx : maxColorIdx; - minColorIdx = colorIdx < minColorIdx ? colorIdx : minColorIdx; + float maxColorIdx = -std::numeric_limits::max(); + for (const speck::Dataset::Entry& e : _dataset.entries) { + float color = e.data[colorMapInUse]; + minColorIdx = std::min(color, minColorIdx); + maxColorIdx = std::max(color, maxColorIdx); } double maxRadius = 0.0; float biggestCoord = -1.f; - for (size_t i = 0; i < _fullData.size(); i += _nValuesPerAstronomicalObject) { + for (const speck::Dataset::Entry& e : _dataset.entries) { glm::vec3 transformedPos = glm::vec3(_transformationMatrix * glm::vec4( - _fullData[i + 0], - _fullData[i + 1], - _fullData[i + 2], - 1.0 + e.position, 1.0 )); glm::vec4 position(transformedPos, static_cast(_unit)); const double unitMeter = unitToMeter(_unit); glm::dvec3 p = glm::dvec3(position) * unitMeter; const double r = glm::length(p); - if (r > maxRadius) { - maxRadius = r; - } + maxRadius = std::max(maxRadius, r); if (_hasColorMapFile) { for (int j = 0; j < 4; ++j) { - _slicedData.push_back(position[j]); - biggestCoord = biggestCoord < position[j] ? position[j] : biggestCoord; + result.push_back(position[j]); } + biggestCoord = std::max(biggestCoord, glm::compMax(position)); // Note: if exact colormap option is not selected, the first color and the // last color in the colormap file are the outliers colors. - float variableColor = _fullData[i + 3 + colorMapInUse]; + float variableColor = e.data[colorMapInUse]; float cmax, cmin; if (_colorRangeData.empty()) { @@ -1536,39 +1066,37 @@ void RenderableBillboardsCloud::createDataSlice() { if (_isColorMapExact) { int colorIndex = variableColor + cmin; for (int j = 0; j < 4; ++j) { - _slicedData.push_back(_colorMapData[colorIndex][j]); + result.push_back(_colorMap.entries[colorIndex][j]); } } else { if (_useLinearFiltering) { - const float value = variableColor; - - float valueT = (value - cmin) / (cmax - cmin); // in [0, 1) + float valueT = (variableColor - cmin) / (cmax - cmin); // in [0, 1) valueT = std::clamp(valueT, 0.f, 1.f); - const float idx = valueT * (_colorMapData.size() - 1); + const float idx = valueT * (_colorMap.entries.size() - 1); const int floorIdx = static_cast(std::floor(idx)); const int ceilIdx = static_cast(std::ceil(idx)); - const glm::vec4 floorColor = _colorMapData[floorIdx]; - const glm::vec4 ceilColor = _colorMapData[ceilIdx]; + const glm::vec4 floorColor = _colorMap.entries[floorIdx]; + const glm::vec4 ceilColor = _colorMap.entries[ceilIdx]; if (floorColor != ceilColor) { const glm::vec4 c = floorColor + idx * (ceilColor - floorColor); - _slicedData.push_back(c.r); - _slicedData.push_back(c.g); - _slicedData.push_back(c.b); - _slicedData.push_back(c.a); + result.push_back(c.r); + result.push_back(c.g); + result.push_back(c.b); + result.push_back(c.a); } else { - _slicedData.push_back(floorColor.r); - _slicedData.push_back(floorColor.g); - _slicedData.push_back(floorColor.b); - _slicedData.push_back(floorColor.a); + result.push_back(floorColor.r); + result.push_back(floorColor.g); + result.push_back(floorColor.b); + result.push_back(floorColor.a); } } else { - float ncmap = static_cast(_colorMapData.size()); + float ncmap = static_cast(_colorMap.entries.size()); float normalization = ((cmax != cmin) && (ncmap > 2)) ? (ncmap - 2) / (cmax - cmin) : 0; int colorIndex = (variableColor - cmin) * normalization + 1; @@ -1576,25 +1104,30 @@ void RenderableBillboardsCloud::createDataSlice() { colorIndex = colorIndex >= ncmap ? ncmap - 1 : colorIndex; for (int j = 0; j < 4; ++j) { - _slicedData.push_back(_colorMapData[colorIndex][j]); + result.push_back(_colorMap.entries[colorIndex][j]); } } } if (_hasDatavarSize) { - addDatavarSizeScalling(i, sizeScalingInUse); + result.push_back(e.data[sizeScalingInUse]); } } else if (_hasDatavarSize) { - addDatavarSizeScalling(i, sizeScalingInUse); - addPosition(position); + result.push_back(e.data[sizeScalingInUse]); + for (int j = 0; j < 4; ++j) { + result.push_back(position[j]); + } } else { - addPosition(position); + for (int j = 0; j < 4; ++j) { + result.push_back(position[j]); + } } } setBoundingSphere(maxRadius); - _fadeInDistance.setMaxValue(glm::vec2(10.f * biggestCoord)); + _fadeInDistances.setMaxValue(glm::vec2(10.f * biggestCoord)); + return result; } void RenderableBillboardsCloud::createPolygonTexture() { @@ -1654,20 +1187,13 @@ void RenderableBillboardsCloud::loadPolygonGeometryForRendering() { glBindVertexArray(_polygonVao); glBindBuffer(GL_ARRAY_BUFFER, _polygonVbo); - const GLfloat vertex_data[] = { + constexpr const std::array VertexData = { // x y z w 0.f, 0.f, 0.f, 1.f, }; - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); - glVertexAttribPointer( - 0, - 4, - GL_FLOAT, - GL_FALSE, - sizeof(GLfloat) * 4, - nullptr - ); + glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData), VertexData.data(), GL_STATIC_DRAW); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), nullptr); glEnableVertexAttribArray(0); glBindVertexArray(0); } @@ -1682,8 +1208,8 @@ void RenderableBillboardsCloud::renderPolygonGeometry(GLuint vao) { ); program->activate(); - static const float black[] = { 0.f, 0.f, 0.f, 0.f }; - glClearBufferfv(GL_COLOR, 0, black); + constexpr const glm::vec4 Black = glm::vec4(0.f, 0.f, 0.f, 0.f); + glClearBufferfv(GL_COLOR, 0, glm::value_ptr(Black)); program->setUniform("sides", _polygonSides); program->setUniform("polygonColor", _pointColor); diff --git a/modules/digitaluniverse/rendering/renderablebillboardscloud.h b/modules/digitaluniverse/rendering/renderablebillboardscloud.h index 4f8d9a45f0..abc3d5d30f 100644 --- a/modules/digitaluniverse/rendering/renderablebillboardscloud.h +++ b/modules/digitaluniverse/rendering/renderablebillboardscloud.h @@ -27,11 +27,13 @@ #include +#include #include #include #include #include #include +#include #include #include #include @@ -78,7 +80,7 @@ private: }; double unitToMeter(Unit unit) const; - void createDataSlice(); + std::vector createDataSlice(); void createPolygonTexture(); void renderToTexture(GLuint textureToRenderTo, GLuint textureWidth, GLuint textureHeight); @@ -89,15 +91,6 @@ private: void renderLabels(const RenderData& data, const glm::dmat4& modelViewProjectionMatrix, const glm::dvec3& orthoRight, const glm::dvec3& orthoUp, float fadeInVariable); - bool loadData(); - bool loadSpeckData(); - bool loadLabelData(); - bool readSpeckFile(); - bool readColorMapFile(); - bool readLabelFile(); - bool loadCachedFile(const std::string& file); - bool saveCachedFile(const std::string& file) const; - bool _hasSpeckFile = false; bool _dataIsDirty = true; bool _textColorIsDirty = true; @@ -119,24 +112,20 @@ private: properties::Vec3Property _textColor; properties::FloatProperty _textOpacity; properties::FloatProperty _textSize; - properties::FloatProperty _textMinSize; - properties::FloatProperty _textMaxSize; + properties::IVec2Property _textMinMaxSize; properties::BoolProperty _drawElements; properties::BoolProperty _drawLabels; properties::BoolProperty _pixelSizeControl; properties::OptionProperty _colorOption; properties::Vec2Property _optionColorRangeData; properties::OptionProperty _datavarSizeOption; - properties::Vec2Property _fadeInDistance; + properties::Vec2Property _fadeInDistances; properties::BoolProperty _disableFadeInDistance; - properties::FloatProperty _billboardMaxSize; - properties::FloatProperty _billboardMinSize; + properties::Vec2Property _billboardMinMaxSize; properties::FloatProperty _correctionSizeEndDistance; properties::FloatProperty _correctionSizeFactor; properties::BoolProperty _useLinearFiltering; properties::TriggerProperty _setRangeFromData; - - // DEBUG: properties::OptionProperty _renderOption; ghoul::opengl::Texture* _polygonTexture = nullptr; @@ -144,8 +133,9 @@ private: ghoul::opengl::ProgramObject* _program = nullptr; ghoul::opengl::ProgramObject* _renderToPolygonProgram = nullptr; - UniformCache(cameraViewProjectionMatrix, modelMatrix, cameraPos, cameraLookup, - renderOption, minBillboardSize, maxBillboardSize, correctionSizeEndDistance, + UniformCache( + cameraViewProjectionMatrix, modelMatrix, cameraPos, cameraLookup, renderOption, + minBillboardSize, maxBillboardSize, correctionSizeEndDistance, correctionSizeFactor, color, alphaValue, scaleFactor, up, right, fadeInValue, screenSize, spriteTexture, hasColormap, enabledRectSizeControl, hasDvarScaling ) _uniformCache; @@ -160,17 +150,14 @@ private: Unit _unit = Parsec; - std::vector _slicedData; - std::vector _fullData; - std::vector _colorMapData; + speck::Dataset _dataset; + speck::Labelset _labelset; + speck::ColorMap _colorMap; + std::vector _colorRangeData; - std::vector> _labelData; - std::unordered_map _variableDataPositionMap; std::unordered_map _optionConversionMap; std::unordered_map _optionConversionSizeMap; - int _nValuesPerAstronomicalObject = 0; - glm::dmat4 _transformationMatrix = glm::dmat4(1.0); GLuint _vao = 0; diff --git a/modules/digitaluniverse/rendering/renderabledumeshes.cpp b/modules/digitaluniverse/rendering/renderabledumeshes.cpp index d73465cc19..b7e0a708df 100644 --- a/modules/digitaluniverse/rendering/renderabledumeshes.cpp +++ b/modules/digitaluniverse/rendering/renderabledumeshes.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -58,7 +59,6 @@ namespace { constexpr const int RenderOptionViewDirection = 0; constexpr const int RenderOptionPositionNormal = 1; - constexpr const int8_t CurrentCacheVersion = 1; constexpr const double PARSEC = 0.308567756E17; constexpr openspace::properties::Property::PropertyInfo TextColorInfo = { @@ -87,18 +87,11 @@ namespace { "objects being rendered." }; - constexpr openspace::properties::Property::PropertyInfo LabelMinSizeInfo = { - "TextMinSize", - "Text Min Size", - "The minimal size (in pixels) of the text for the labels for the astronomical " - "objects being rendered." - }; - - constexpr openspace::properties::Property::PropertyInfo LabelMaxSizeInfo = { - "TextMaxSize", - "Text Max Size", - "The maximum size (in pixels) of the text for the labels for the astronomical " - "objects being rendered." + constexpr openspace::properties::Property::PropertyInfo LabelMinMaxSizeInfo = { + "TextMinMaxSize", + "Text Min/Max Size", + "The minimum and maximum size (in pixels) of the text for the labels for the " + "astronomical objects being rendered." }; constexpr openspace::properties::Property::PropertyInfo LineWidthInfo = { @@ -162,11 +155,8 @@ namespace { // [[codegen::verbatim(LabelFileInfo.description)]] std::optional labelFile; - // [[codegen::verbatim(LabelMinSizeInfo.description)]] - std::optional textMinSize; - - // [[codegen::verbatim(LabelMaxSizeInfo.description)]] - std::optional textMaxSize; + // [[codegen::verbatim(LabelMinMaxSizeInfo.description)]] + std::optional textMinMaxSize; // [[codegen::verbatim(LineWidthInfo.description)]] std::optional lineWidth; @@ -180,9 +170,7 @@ namespace { namespace openspace { documentation::Documentation RenderableDUMeshes::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "digitaluniverse_renderabledumeshes"; - return doc; + return codegen::doc("digitaluniverse_renderabledumeshes"); } RenderableDUMeshes::RenderableDUMeshes(const ghoul::Dictionary& dictionary) @@ -192,8 +180,12 @@ RenderableDUMeshes::RenderableDUMeshes(const ghoul::Dictionary& dictionary) , _textSize(TextSizeInfo, 8.f, 0.5f, 24.f) , _drawElements(DrawElementsInfo, true) , _drawLabels(DrawLabelInfo, false) - , _textMinSize(LabelMinSizeInfo, 8.f, 0.5f, 24.f) - , _textMaxSize(LabelMaxSizeInfo, 500.f, 0.f, 1000.f) + , _textMinMaxSize( + LabelMinMaxSizeInfo, + glm::ivec2(8, 500), + glm::ivec2(0), + glm::ivec2(1000) + ) , _lineWidth(LineWidthInfo, 2.f, 1.f, 16.f) , _renderOption(RenderOptionInfo, properties::OptionProperty::DisplayType::Dropdown) { @@ -202,7 +194,7 @@ RenderableDUMeshes::RenderableDUMeshes(const ghoul::Dictionary& dictionary) addProperty(_opacity); registerUpdateRenderBinFromOpacity(); - _speckFile = absPath(p.file); + _speckFile = absPath(p.file).string(); _hasSpeckFile = true; _drawElements.onChange([&]() { _hasSpeckFile = !_hasSpeckFile; }); addProperty(_drawElements); @@ -252,13 +244,13 @@ RenderableDUMeshes::RenderableDUMeshes(const ghoul::Dictionary& dictionary) _lineWidth = p.lineWidth.value_or(_lineWidth); addProperty(_lineWidth); - _drawLabels = p.drawLabels.value_or(_drawLabels); - addProperty(_drawLabels); - if (p.labelFile.has_value()) { - _labelFile = absPath(*p.labelFile); + _labelFile = absPath(*p.labelFile).string(); _hasLabel = true; + _drawLabels = p.drawLabels.value_or(_drawLabels); + addProperty(_drawLabels); + _textColor = p.textColor.value_or(_textColor); _hasLabel = p.textColor.has_value(); _textColor.setViewOption(properties::Property::ViewOptions::Color); @@ -271,11 +263,9 @@ RenderableDUMeshes::RenderableDUMeshes(const ghoul::Dictionary& dictionary) _textSize = p.textSize.value_or(_textSize); addProperty(_textSize); - _textMinSize = p.textMinSize.value_or(_textMinSize); - addProperty(_textMinSize); - - _textMaxSize = p.textMaxSize.value_or(_textMaxSize); - addProperty(_textMaxSize); + _textMinMaxSize = p.textMinMaxSize.value_or(_textMinMaxSize); + _textMinMaxSize.setViewOption(properties::Property::ViewOptions::MinMaxRange); + addProperty(_textMinMaxSize); } if (p.meshColor.has_value()) { @@ -288,7 +278,7 @@ RenderableDUMeshes::RenderableDUMeshes(const ghoul::Dictionary& dictionary) bool RenderableDUMeshes::isReady() const { return (_program != nullptr) && - (!_renderingMeshesMap.empty() || (!_labelData.empty())); + (!_renderingMeshesMap.empty() || (!_labelset.entries.empty())); } void RenderableDUMeshes::initializeGL() { @@ -419,8 +409,8 @@ void RenderableDUMeshes::renderLabels(const RenderData& data, ghoul::fontrendering::FontRenderer::ProjectedLabelsInformation labelInfo; labelInfo.orthoRight = orthoRight; labelInfo.orthoUp = orthoUp; - labelInfo.minSize = static_cast(_textMinSize); - labelInfo.maxSize = static_cast(_textMaxSize); + labelInfo.minSize = _textMinMaxSize.value().x; + labelInfo.maxSize = _textMinMaxSize.value().y; labelInfo.cameraPos = data.camera.positionVec3(); labelInfo.cameraLookUp = data.camera.lookUpVectorWorldSpace(); labelInfo.renderType = _renderOption; @@ -431,13 +421,13 @@ void RenderableDUMeshes::renderLabels(const RenderData& data, glm::vec4 textColor = glm::vec4(glm::vec3(_textColor), _textOpacity); - for (const std::pair& pair : _labelData) { - glm::vec3 scaledPos(pair.first); + for (const speck::Labelset::Entry& e : _labelset.entries) { + glm::vec3 scaledPos(e.position); scaledPos *= scale; ghoul::fontrendering::FontRenderer::defaultProjectionRenderer().render( *_font, scaledPos, - pair.second, + e.text, textColor, labelInfo ); @@ -494,31 +484,7 @@ void RenderableDUMeshes::update(const UpdateData&) { bool RenderableDUMeshes::loadData() { bool success = false; if (_hasSpeckFile) { - // I disabled the cache as it didn't work on Mac --- abock - // std::string cachedFile = FileSys.cacheManager()->cachedFilename( - // _speckFile, - // ghoul::filesystem::CacheManager::Persistent::Yes - // ); - - // bool hasCachedFile = FileSys.fileExists(cachedFile); - // if (hasCachedFile) { - // LINFO( - // "Cached file '" << cachedFile << - // "' used for Speck file '" << _speckFile << "'" - // ); - - // success = loadCachedFile(cachedFile); - // if (!success) { - // FileSys.cacheManager()->removeCacheFile(_speckFile); - // // Intentional fall-through to the 'else' to generate the cache - // // file for the next run - // } - // } - // else - // { - // LINFO("Cache for Speck file '" << _speckFile << "' not found"); LINFO(fmt::format("Loading Speck file '{}'", _speckFile)); - success = readSpeckFile(); if (!success) { return false; @@ -527,35 +493,7 @@ bool RenderableDUMeshes::loadData() { std::string labelFile = _labelFile; if (!labelFile.empty()) { - // I disabled the cache as it didn't work on Mac --- abock - // std::string cachedFile = FileSys.cacheManager()->cachedFilename( - // labelFile, - // ghoul::filesystem::CacheManager::Persistent::Yes - // ); - // bool hasCachedFile = FileSys.fileExists(cachedFile); - // if (hasCachedFile) { - // LINFO( - // "Cached file '" << cachedFile << "' used for Label file '" << - // labelFile << "'" - // ); - - // success &= loadCachedFile(cachedFile); - // if (!success) { - // FileSys.cacheManager()->removeCacheFile(labelFile); - // // Intentional fall-through to the 'else' to generate the cache - // // file for the next run - // } - // } - // else { - // LINFO("Cache for Label file '" << labelFile << "' not found"); - LINFO(fmt::format("Loading Label file '{}'", labelFile)); - - success &= readLabelFile(); - if (!success) { - return false; - } - - // } + _labelset = speck::label::loadFileWithCache(_labelFile); } return success; @@ -688,158 +626,6 @@ bool RenderableDUMeshes::readSpeckFile() { return true; } -bool RenderableDUMeshes::readLabelFile() { - std::ifstream file(_labelFile); - if (!file.good()) { - LERROR(fmt::format("Failed to open Label file '{}'", _labelFile)); - return false; - } - - // The beginning of the speck file has a header that either contains comments - // (signaled by a preceding '#') or information about the structure of the file - // (signaled by the keywords 'datavar', 'texturevar', and 'texture') - std::string line; - while (true) { - std::streampos position = file.tellg(); - std::getline(file, line); - - // Guard against wrong line endings (copying files from Windows to Mac) causes - // lines to have a final \r - if (!line.empty() && line.back() == '\r') { - line = line.substr(0, line.length() - 1); - } - - - if (line.empty() || line[0] == '#') { - continue; - } - - if (line.substr(0, 9) != "textcolor") { - // we read a line that doesn't belong to the header, so we have to jump back - // before the beginning of the current line - file.seekg(position); - continue; - } - - if (line.substr(0, 9) == "textcolor") { - // textcolor lines are structured as follows: - // textcolor # description - // where # is color text defined in configuration file - std::stringstream str(line); - - // TODO: handle cases of labels with different colors - break; - } - } - - do { - std::vector values(_nValuesPerAstronomicalObject); - - std::getline(file, line); - - // Guard against wrong line endings (copying files from Windows to Mac) causes - // lines to have a final \r - if (!line.empty() && line.back() == '\r') { - line = line.substr(0, line.length() - 1); - } - - if (line.empty()) { - continue; - } - - std::stringstream str(line); - - glm::vec3 position = glm::vec3(0.f); - for (int j = 0; j < 3; ++j) { - str >> position[j]; - } - - std::string dummy; - str >> dummy; // text keyword - - std::string label; - str >> label; - dummy.clear(); - - while (str >> dummy) { - label += " " + dummy; - dummy.clear(); - } - - _labelData.emplace_back(std::make_pair(position, label)); - - } while (!file.eof()); - - return true; -} - -bool RenderableDUMeshes::loadCachedFile(const std::string& file) { - std::ifstream fileStream(file, std::ifstream::binary); - if (!fileStream.good()) { - LERROR(fmt::format("Error opening file '{}' for loading cache file", file)); - return false; - } - - int8_t version = 0; - fileStream.read(reinterpret_cast(&version), sizeof(int8_t)); - if (version != CurrentCacheVersion) { - LINFO("The format of the cached file has changed: deleting old cache"); - fileStream.close(); - FileSys.deleteFile(file); - return false; - } - - int32_t nValues = 0; - fileStream.read(reinterpret_cast(&nValues), sizeof(int32_t)); - fileStream.read( - reinterpret_cast(&_nValuesPerAstronomicalObject), - sizeof(int32_t) - ); - - _fullData.resize(nValues); - fileStream.read( - reinterpret_cast(&_fullData[0]), - nValues * sizeof(_fullData[0]) - ); - - bool success = fileStream.good(); - return success; -} - -bool RenderableDUMeshes::saveCachedFile(const std::string& file) const { - std::ofstream fileStream(file, std::ofstream::binary); - if (!fileStream.good()) { - LERROR(fmt::format("Error opening file '{}' for save cache file", file)); - return false; - } - - fileStream.write( - reinterpret_cast(&CurrentCacheVersion), - sizeof(int8_t) - ); - - const int32_t nValues = static_cast(_fullData.size()); - if (nValues == 0) { - LERROR("Error writing cache: No values were loaded"); - return false; - } - fileStream.write(reinterpret_cast(&nValues), sizeof(int32_t)); - - const int32_t nValuesPerAstronomicalObject = static_cast( - _nValuesPerAstronomicalObject - ); - fileStream.write( - reinterpret_cast(&nValuesPerAstronomicalObject), - sizeof(int32_t) - ); - - const size_t nBytes = nValues * sizeof(_fullData[0]); - fileStream.write(reinterpret_cast(&_fullData[0]), nBytes); - - const bool success = fileStream.good(); - return success; -} - void RenderableDUMeshes::createMeshes() { if (!(_dataIsDirty && _hasSpeckFile)) { return; diff --git a/modules/digitaluniverse/rendering/renderabledumeshes.h b/modules/digitaluniverse/rendering/renderabledumeshes.h index 04d32ae50f..b397eb3a14 100644 --- a/modules/digitaluniverse/rendering/renderabledumeshes.h +++ b/modules/digitaluniverse/rendering/renderabledumeshes.h @@ -27,10 +27,12 @@ #include +#include #include #include #include #include +#include #include #include #include @@ -108,9 +110,6 @@ private: bool loadData(); bool readSpeckFile(); - bool readLabelFile(); - bool loadCachedFile(const std::string& file); - bool saveCachedFile(const std::string& file) const; bool _hasSpeckFile = false; bool _dataIsDirty = true; @@ -122,8 +121,7 @@ private: properties::FloatProperty _textSize; properties::BoolProperty _drawElements; properties::BoolProperty _drawLabels; - properties::FloatProperty _textMinSize; - properties::FloatProperty _textMaxSize; + properties::IVec2Property _textMinMaxSize; properties::FloatProperty _lineWidth; // DEBUG: @@ -140,8 +138,7 @@ private: Unit _unit = Parsec; std::vector _fullData; - std::vector> _labelData; - int _nValuesPerAstronomicalObject = 0; + speck::Labelset _labelset; std::unordered_map _meshColorMap; std::unordered_map _renderingMeshesMap; diff --git a/modules/digitaluniverse/rendering/renderableplanescloud.cpp b/modules/digitaluniverse/rendering/renderableplanescloud.cpp index 7d754f9308..1e54b6a7c7 100644 --- a/modules/digitaluniverse/rendering/renderableplanescloud.cpp +++ b/modules/digitaluniverse/rendering/renderableplanescloud.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -49,11 +51,12 @@ namespace { constexpr const char* _loggerCat = "RenderablePlanesCloud"; constexpr const char* ProgramObjectName = "RenderablePlanesCloud"; + constexpr const int PlanesVertexDataSize = 36; + constexpr std::array UniformNames = { "modelViewProjectionTransform", "alphaValue", "fadeInValue", "galaxyTexture" }; - constexpr int8_t CurrentCacheVersion = 2; constexpr double PARSEC = 0.308567756E17; enum BlendMode { @@ -243,9 +246,7 @@ namespace { namespace openspace { documentation::Documentation RenderablePlanesCloud::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "digitaluniverse_RenderablePlanesCloud"; - return doc; + return codegen::doc("digitaluniverse_RenderablePlanesCloud"); } RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary) @@ -256,7 +257,7 @@ RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary , _textSize(TextSizeInfo, 8.0, 0.5, 24.0) , _drawElements(DrawElementsInfo, true) , _blendMode(BlendModeInfo, properties::OptionProperty::DisplayType::Dropdown) - , _fadeInDistance( + , _fadeInDistances( FadeInDistancesInfo, glm::vec2(0.f), glm::vec2(0.f), @@ -271,7 +272,7 @@ RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary addProperty(_opacity); if (p.file.has_value()) { - _speckFile = absPath(*p.file); + _speckFile = absPath(*p.file).string(); _hasSpeckFile = true; _drawElements.onChange([&]() { _hasSpeckFile = !_hasSpeckFile; }); addProperty(_drawElements); @@ -319,7 +320,7 @@ RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary _scaleFactor.onChange([&]() { _dataIsDirty = true; }); if (p.labelFile.has_value()) { - _labelFile = absPath(*p.labelFile); + _labelFile = absPath(*p.labelFile).string(); _hasLabel = true; _textColor = p.textColor.value_or(_textColor); @@ -367,16 +368,16 @@ RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary } } - _texturesPath = absPath(p.texturePath); + _texturesPath = absPath(p.texturePath).string(); _luminosityVar = p.luminosity.value_or(_luminosityVar); _sluminosity = p.scaleLuminosity.value_or(_sluminosity); - if (p.fadeInDistances.has_value()) { - _fadeInDistance = *p.fadeInDistances; + _fadeInDistances = *p.fadeInDistances; _disableFadeInDistance = false; - addProperty(_fadeInDistance); + _fadeInDistances.setViewOption(properties::Property::ViewOptions::MinMaxRange); + addProperty(_fadeInDistances); addProperty(_disableFadeInDistance); } @@ -388,15 +389,25 @@ RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary } bool RenderablePlanesCloud::isReady() const { - return ((_program != nullptr) && (!_fullData.empty())) || (!_labelData.empty()); + return (_program && (!_dataset.entries.empty())) || (!_labelset.entries.empty()); } void RenderablePlanesCloud::initialize() { ZoneScoped - const bool success = loadData(); - if (!success) { - throw ghoul::RuntimeError("Error loading data"); + if (_hasSpeckFile && std::filesystem::is_regular_file(_speckFile)) { + _dataset = speck::data::loadFileWithCache(_speckFile); + if (_dataset.entries.empty()) { + throw ghoul::RuntimeError("Error loading data"); + } + } + + if (!_labelFile.empty()) { + LINFO(fmt::format("Loading Label file '{}'", _labelFile)); + _labelset = speck::label::loadFileWithCache(_labelFile); + for (speck::Labelset::Entry& e : _labelset.entries) { + e.position = glm::vec3(_transformationMatrix * glm::dvec4(e.position, 1.0)); + } } } @@ -417,7 +428,6 @@ void RenderablePlanesCloud::initializeGL() { ghoul::opengl::updateUniformLocations(*_program, _uniformCache, UniformNames); createPlanes(); - loadTextures(); if (_hasLabel) { @@ -433,7 +443,6 @@ void RenderablePlanesCloud::initializeGL() { } } - void RenderablePlanesCloud::deleteDataGPUAndCPU() { for (std::unordered_map::reference pAMapItem : _planesMap) { glDeleteBuffers(1, &pAMapItem.second.vbo); @@ -484,8 +493,7 @@ void RenderablePlanesCloud::renderPlanes(const RenderData&, _program->setUniform(_uniformCache.galaxyTexture, unit); int currentTextureIndex = -1; - for (std::unordered_map::reference pAMapItem : _planesMap) - { + for (std::unordered_map::reference pAMapItem : _planesMap) { // For planes with undefined textures references if (pAMapItem.first == 30) { continue; @@ -514,35 +522,8 @@ void RenderablePlanesCloud::renderLabels(const RenderData& data, const glm::dvec3& orthoRight, const glm::dvec3& orthoUp, float fadeInVariable) { - float scale = 0.f; - switch (_unit) { - case Meter: - scale = 1.f; - break; - case Kilometer: - scale = 1e3f; - break; - case Parsec: - scale = static_cast(PARSEC); - break; - case Kiloparsec: - scale = static_cast(1e3 * PARSEC); - break; - case Megaparsec: - scale = static_cast(1e6 * PARSEC); - break; - case Gigaparsec: - scale = static_cast(1e9 * PARSEC); - break; - case GigalightYears: - scale = static_cast(306391534.73091 * PARSEC); - break; - } - - glm::vec4 textColor = glm::vec4( - glm::vec3(_textColor), - _textOpacity * fadeInVariable - ); + double scale = unitToMeter(_unit); + glm::vec4 textColor = glm::vec4(glm::vec3(_textColor), _textOpacity * fadeInVariable); ghoul::fontrendering::FontRenderer::ProjectedLabelsInformation labelInfo; labelInfo.orthoRight = orthoRight; @@ -557,14 +538,12 @@ void RenderablePlanesCloud::renderLabels(const RenderData& data, labelInfo.enableDepth = true; labelInfo.enableFalseDepth = false; - for (const std::pair& pair : _labelData) { - //glm::vec3 scaledPos(_transformationMatrix * glm::dvec4(pair.first, 1.0)); - glm::vec3 scaledPos(pair.first); - scaledPos *= scale; + for (const speck::Labelset::Entry& e : _labelset.entries) { + glm::dvec3 scaledPos = glm::dvec3(e.position) * scale; ghoul::fontrendering::FontRenderer::defaultProjectionRenderer().render( *_font, scaledPos, - pair.second, + e.text, textColor, labelInfo ); @@ -578,7 +557,7 @@ void RenderablePlanesCloud::render(const RenderData& data, RendererTasks&) { if (!_disableFadeInDistance) { float distCamera = static_cast(glm::length(data.camera.positionVec3())); distCamera = static_cast(distCamera / scale); - const glm::vec2 fadeRange = _fadeInDistance; + const glm::vec2 fadeRange = _fadeInDistances; //const float a = 1.f / ((fadeRange.y - fadeRange.x) * scale); const float a = 1.f / ((fadeRange.y - fadeRange.x)); const float b = -(fadeRange.x / (fadeRange.y - fadeRange.x)); @@ -597,8 +576,7 @@ void RenderablePlanesCloud::render(const RenderData& data, RendererTasks&) { const glm::dmat4 modelViewMatrix = data.camera.combinedViewMatrix() * modelMatrix; const glm::mat4 projectionMatrix = data.camera.projectionMatrix(); - const glm::dmat4 modelViewProjectionMatrix = glm::dmat4(projectionMatrix) * - modelViewMatrix; + const glm::dmat4 mvpMatrix = glm::dmat4(projectionMatrix) * modelViewMatrix; const glm::dmat4 invMVPParts = glm::inverse(modelMatrix) * glm::inverse(data.camera.combinedViewMatrix()) * @@ -615,13 +593,7 @@ void RenderablePlanesCloud::render(const RenderData& data, RendererTasks&) { } if (_hasLabel) { - renderLabels( - data, - modelViewProjectionMatrix, - orthoRight, - orthoUp, - fadeInVariable - ); + renderLabels(data, mvpMatrix, orthoRight, orthoUp, fadeInVariable); } } @@ -638,442 +610,48 @@ void RenderablePlanesCloud::update(const UpdateData&) { } } -bool RenderablePlanesCloud::loadData() { - bool success = false; - if (_hasSpeckFile) { - // I disabled the cache as it didn't work on Mac --- abock - // std::string cachedFile = FileSys.cacheManager()->cachedFilename( - // _speckFile, - // ghoul::filesystem::CacheManager::Persistent::Yes - // ); +void RenderablePlanesCloud::loadTextures() { + for (const speck::Dataset::Texture& tex : _dataset.textures) { + std::filesystem::path fullPath = absPath(_texturesPath + '/' + tex.file); + std::filesystem::path pngPath = fullPath; + pngPath.replace_extension(".png"); - // bool hasCachedFile = FileSys.fileExists(cachedFile); - // if (hasCachedFile) { - // LINFO( - // "Cached file '" << cachedFile << - // "' used for Speck file '" << _speckFile << "'" - // ); - - // success = loadCachedFile(cachedFile); - // if (!success) { - // FileSys.cacheManager()->removeCacheFile(_speckFile); - // // Intentional fall-through to the 'else' to generate the cache - // // file for the next run - // } - // } - // else - // { - // LINFO("Cache for Speck file '" << _speckFile << "' not found"); - LINFO(fmt::format("Loading Speck file '{}'", _speckFile)); - - success = readSpeckFile(); - if (!success) { - return false; - } - - // LINFO("Saving cache"); - //success &= saveCachedFile(cachedFile); - // } - } - - if (!_labelFile.empty()) { - // I disabled the cache as it didn't work on Mac --- abock - // std::string cachedFile = FileSys.cacheManager()->cachedFilename( - // _labelFile, - // ghoul::filesystem::CacheManager::Persistent::Yes - // ); - // bool hasCachedFile = FileSys.fileExists(cachedFile); - // if (hasCachedFile) { - // LINFO( - // "Cached file '" << cachedFile << - // "' used for Label file '" << _labelFile << "'" - // ); - // - // success &= loadCachedFile(cachedFile); - // if (!success) { - // FileSys.cacheManager()->removeCacheFile(_labelFile); - // // Intentional fall-through to the 'else' to generate the cache - // // file for the next run - // } - // } - // else - // { - // LINFO("Cache for Label file '" << _labelFile << "' not found"); - LINFO(fmt::format("Loading Label file '{}'", _labelFile)); - - success &= readLabelFile(); - if (!success) { - return false; - } - - // } - } - - return success; -} - -bool RenderablePlanesCloud::loadTextures() { - if (!_textureFileMap.empty()) { - for (const std::pair& pair : _textureFileMap) { - const auto& p = _textureMap.insert(std::make_pair( - pair.first, - ghoul::io::TextureReader::ref().loadTexture(pair.second) + std::filesystem::path path; + if (std::filesystem::is_regular_file(fullPath)) { + path = fullPath; + } + else if (std::filesystem::is_regular_file(pngPath)) { + path = pngPath; + } + else { + // We can't really recover from this as it would crash during rendering anyway + throw ghoul::RuntimeError(fmt::format( + "Could not find image file '{}'", tex.file )); - if (p.second) { - LINFOC( - "RenderablePlanesCloud", - fmt::format("Loaded texture from '{}'", pair.second) - ); - p.first->second->uploadTexture(); - p.first->second->setFilter( - ghoul::opengl::Texture::FilterMode::LinearMipMap - ); - p.first->second->purgeFromRAM(); - } - } - } - else { - return false; - } - return true; -} - -bool RenderablePlanesCloud::readSpeckFile() { - std::ifstream file(_speckFile); - if (!file.good()) { - LERROR(fmt::format("Failed to open Speck file '{}'", _speckFile)); - return false; - } - - _nValuesPerAstronomicalObject = 0; - - // The beginning of the speck file has a header that either contains comments - // (signaled by a preceding '#') or information about the structure of the file - // (signaled by the keywords 'datavar', 'texturevar', and 'texture') - std::string line; - while (true) { - std::getline(file, line); - - // Guard against wrong line endings (copying files from Windows to Mac) causes - // lines to have a final \r - if (!line.empty() && line.back() == '\r') { - line = line.substr(0, line.length() -1); } - if (line.empty() || line[0] == '#') { - continue; + std::unique_ptr t = + ghoul::io::TextureReader::ref().loadTexture(path.string()); + + if (t) { + LINFOC("RenderablePlanesCloud", fmt::format("Loaded texture '{}'", path)); + t->uploadTexture(); + t->setFilter(ghoul::opengl::Texture::FilterMode::LinearMipMap); + t->purgeFromRAM(); + } + else { + // Same here, we won't be able to recover from this nullptr + throw ghoul::RuntimeError(fmt::format( + "Could not find image file '{}'", tex.file + )); } - if (line.substr(0, 7) != "datavar" && - line.substr(0, 10) != "texturevar" && - line.substr(0, 7) != "texture" && - line.substr(0, 10) != "polyorivar" && - line.substr(0, 10) != "maxcomment") - { - // Started reading data - break; - } - - if (line.substr(0, 7) == "datavar") { - // datavar lines are structured as follows: - // datavar # description - // where # is the index of the data variable; so if we repeatedly overwrite - // the 'nValues' variable with the latest index, we will end up with the total - // number of values (+3 since X Y Z are not counted in the Speck file index) - std::stringstream str(line); - - std::string dummy; - str >> dummy; // command - str >> _nValuesPerAstronomicalObject; // variable index - dummy.clear(); - str >> dummy; // variable name - - // +3 because of the x, y and z at the begining of each line. - _variableDataPositionMap.insert({ dummy, _nValuesPerAstronomicalObject + 3}); - - if ((dummy == "orientation") || (dummy == "ori")) { // 3d vectors u and v - // We want the number, but the index is 0 based - _nValuesPerAstronomicalObject += 6; - } - else { - // We want the number, but the index is 0 based - _nValuesPerAstronomicalObject += 1; - } - } - - if (line.substr(0, 10) == "polyorivar") { - _planeStartingIndexPos = 0; - std::stringstream str(line); - - std::string dummy; - str >> dummy; // command - str >> _planeStartingIndexPos; - _planeStartingIndexPos += 3; // 3 for xyz - } - - if (line.substr(0, 10) == "texturevar") { - _textureVariableIndex = 0; - std::stringstream str(line); - - std::string dummy; - str >> dummy; // command - str >> _textureVariableIndex; - _textureVariableIndex += 3; // 3 for xyz - } - - if (line.substr(0, 8) == "texture ") { - std::stringstream str(line); - - std::size_t found = line.find('-'); - - int textureIndex = 0; - - std::string dummy; - str >> dummy; // command - - if (found != std::string::npos) { - std::string option; // Not being used right now. - str >> option; - } - - str >> textureIndex; - std::string fileName; - str >> fileName; // texture file name - - std::string fullPath = absPath(_texturesPath + '/' + fileName); - std::string pngPath = - ghoul::filesystem::File(fullPath).fullBaseName() + ".png"; - - if (FileSys.fileExists(fullPath)) { - _textureFileMap.insert({ textureIndex, fullPath }); - - } - else if (FileSys.fileExists(pngPath)) { - _textureFileMap.insert({ textureIndex, pngPath }); - } - else { - LWARNING(fmt::format("Could not find image file {}", fileName)); - _textureFileMap.insert({ textureIndex, "" }); - } - } - } - - _nValuesPerAstronomicalObject += 3; // X Y Z are not counted in the Speck file indices - - do { - - // Guard against wrong line endings (copying files from Windows to Mac) causes - // lines to have a final \r - if (!line.empty() && line.back() == '\r') { - line = line.substr(0, line.length() -1); - } - - if (line.empty()) { - std::getline(file, line); - continue; - } - else if (line[0] == '#') { - std::getline(file, line); - continue; - } - - std::stringstream str(line); - - glm::vec3 u(0.f); - glm::vec3 v(0.f); - - std::vector values(_nValuesPerAstronomicalObject); - - for (int i = 0; i < _nValuesPerAstronomicalObject; ++i) { - str >> values[i]; - if ((i >= _planeStartingIndexPos) && - (i <= _planeStartingIndexPos + 6)) { // vectors u and v - int index = i - _planeStartingIndexPos; - switch (index) { - case 0: - u.x = values[i]; - break; - case 1: - u.y = values[i]; - break; - case 2: - u.z = values[i]; - break; - case 3: - v.x = values[i]; - break; - case 4: - v.y = values[i]; - break; - case 5: - v.z = values[i]; - break; - } - } - } - _fullData.insert(_fullData.end(), values.begin(), values.end()); - - // reads new line - std::getline(file, line); - } while (!file.eof()); - - return true; -} - -bool RenderablePlanesCloud::readLabelFile() { - std::ifstream file(_labelFile); - if (!file.good()) { - LERROR(fmt::format("Failed to open Label file '{}'", _labelFile)); - return false; - } - - // The beginning of the speck file has a header that either contains comments - // (signaled by a preceding '#') or information about the structure of the file - // (signaled by the keywords 'datavar', 'texturevar', and 'texture') - std::string line; - while (true) { - std::streampos position = file.tellg(); - std::getline(file, line); - - // Guard against wrong line endings (copying files from Windows to Mac) causes - // lines to have a final \r - if (!line.empty() && line.back() == '\r') { - line = line.substr(0, line.length() -1); - } - - if (line.empty() || line[0] == '#') { - continue; - } - - if (line.substr(0, 9) != "textcolor") { - // we read a line that doesn't belong to the header, so we have to jump back - // before the beginning of the current line - file.seekg(position); - continue; - } - - if (line.substr(0, 9) == "textcolor") { - // textcolor lines are structured as follows: - // textcolor # description - // where # is color text defined in configuration file - std::stringstream str(line); - - // TODO: handle cases of labels with different colors - break; - } - } - - do { - std::vector values(_nValuesPerAstronomicalObject); - - std::getline(file, line); - - // Guard against wrong line endings (copying files from Windows to Mac) causes - // lines to have a final \r - if (!line.empty() && line.back() == '\r') { - line = line.substr(0, line.length() -1); - } - - if (line.empty()) { - continue; - } - - std::stringstream str(line); - - glm::vec3 position = glm::vec3(0.f); - for (int j = 0; j < 3; ++j) { - str >> position[j]; - } - - std::string dummy; - str >> dummy; // text keyword - - std::string label; - str >> label; - dummy.clear(); - - while (str >> dummy) { - label += " " + dummy; - dummy.clear(); - } - - glm::vec3 transformedPos = glm::vec3( - _transformationMatrix * glm::dvec4(position, 1.0) - ); - _labelData.emplace_back(std::make_pair(transformedPos, label)); - - } while (!file.eof()); - - return true; -} - -bool RenderablePlanesCloud::loadCachedFile(const std::string& file) { - std::ifstream fileStream(file, std::ifstream::binary); - if (fileStream.good()) { - int8_t version = 0; - fileStream.read(reinterpret_cast(&version), sizeof(int8_t)); - if (version != CurrentCacheVersion) { - LINFO("The format of the cached file has changed: deleting old cache"); - fileStream.close(); - FileSys.deleteFile(file); - return false; - } - - int32_t nValues = 0; - fileStream.read(reinterpret_cast(&nValues), sizeof(int32_t)); - fileStream.read(reinterpret_cast( - &_nValuesPerAstronomicalObject), - sizeof(int32_t) - ); - - _fullData.resize(nValues); - fileStream.read(reinterpret_cast(&_fullData[0]), - nValues * sizeof(_fullData[0])); - - bool success = fileStream.good(); - return success; - } - else { - LERROR(fmt::format("Error opening file '{}' for loading cache file", file)); - return false; - } -} - -bool RenderablePlanesCloud::saveCachedFile(const std::string& file) const { - std::ofstream fileStream(file, std::ofstream::binary); - if (fileStream.good()) { - fileStream.write(reinterpret_cast(&CurrentCacheVersion), - sizeof(int8_t)); - - const int32_t nValues = static_cast(_fullData.size()); - if (nValues == 0) { - LERROR("Error writing cache: No values were loaded"); - return false; - } - fileStream.write(reinterpret_cast(&nValues), sizeof(int32_t)); - - const int32_t nValuesPerAstronomicalObject = static_cast( - _nValuesPerAstronomicalObject - ); - fileStream.write(reinterpret_cast( - &nValuesPerAstronomicalObject), - sizeof(int32_t) - ); - - const size_t nBytes = nValues * sizeof(_fullData[0]); - fileStream.write(reinterpret_cast(&_fullData[0]), nBytes); - - bool success = fileStream.good(); - return success; - } - else { - LERROR(fmt::format("Error opening file '{}' for save cache file", file)); - return false; + _textureMap.insert(std::pair(tex.index, std::move(t))); } } double RenderablePlanesCloud::unitToMeter(Unit unit) const { - switch (_unit) { + switch (unit) { case Meter: return 1.0; case Kilometer: return 1e3; case Parsec: return PARSEC; @@ -1087,29 +665,27 @@ double RenderablePlanesCloud::unitToMeter(Unit unit) const { void RenderablePlanesCloud::createPlanes() { if (_dataIsDirty && _hasSpeckFile) { + const int lumIdx = std::max(_dataset.index(_luminosityVar), 0); const double scale = unitToMeter(_unit); LDEBUG("Creating planes..."); float maxSize = 0.f; double maxRadius = 0.0; - for (size_t p = 0; p < _fullData.size(); p += _nValuesPerAstronomicalObject) { + for (const speck::Dataset::Entry& e : _dataset.entries) { const glm::vec4 transformedPos = glm::vec4( - _transformationMatrix * - glm::dvec4(_fullData[p + 0], _fullData[p + 1], _fullData[p + 2], 1.0) + _transformationMatrix * glm::dvec4(e.position, 1.0) ); const double r = glm::length(glm::dvec3(transformedPos) * scale); - if (r > maxRadius) { - maxRadius = r; - } + maxRadius = std::max(maxRadius, r); // Plane vectors u and v glm::vec4 u = glm::vec4( _transformationMatrix * glm::dvec4( - _fullData[p + _planeStartingIndexPos + 0], - _fullData[p + _planeStartingIndexPos + 1], - _fullData[p + _planeStartingIndexPos + 2], + e.data[_dataset.orientationDataIndex + 0], + e.data[_dataset.orientationDataIndex + 1], + e.data[_dataset.orientationDataIndex + 2], 1.f ) ); @@ -1119,9 +695,9 @@ void RenderablePlanesCloud::createPlanes() { glm::vec4 v = glm::vec4( _transformationMatrix * glm::dvec4( - _fullData[p + _planeStartingIndexPos + 3], - _fullData[p + _planeStartingIndexPos + 4], - _fullData[p + _planeStartingIndexPos + 5], + e.data[_dataset.orientationDataIndex + 3], + e.data[_dataset.orientationDataIndex + 4], + e.data[_dataset.orientationDataIndex + 5], 1.f ) ); @@ -1129,8 +705,7 @@ void RenderablePlanesCloud::createPlanes() { v.w = 0.f; if (!_luminosityVar.empty()) { - float lumS = _fullData[p + _variableDataPositionMap[_luminosityVar]] * - _sluminosity; + float lumS = e.data[lumIdx] * _sluminosity; u *= lumS; v *= lumS; } @@ -1150,12 +725,12 @@ void RenderablePlanesCloud::createPlanes() { maxSize = std::max(maxSize, vertex4[i]); } - vertex0 *= scale; - vertex1 *= scale; - vertex2 *= scale; - vertex4 *= scale; + vertex0 = glm::vec4(glm::dvec4(vertex0) * scale); + vertex1 = glm::vec4(glm::dvec4(vertex1) * scale); + vertex2 = glm::vec4(glm::dvec4(vertex2) * scale); + vertex4 = glm::vec4(glm::dvec4(vertex4) * scale); - GLfloat vertexData[] = { + const std::array VertexData = { // x y z w s t vertex0.x, vertex0.y, vertex0.z, 1.f, 0.f, 0.f, vertex1.x, vertex1.y, vertex1.z, 1.f, 1.f, 1.f, @@ -1165,12 +740,12 @@ void RenderablePlanesCloud::createPlanes() { vertex1.x, vertex1.y, vertex1.z, 1.f, 1.f, 1.f, }; - int textureIndex = static_cast(_fullData[p + _textureVariableIndex]); + int textureIndex = static_cast(e.data[_dataset.textureDataIndex]); std::unordered_map::iterator found = _planesMap.find(textureIndex); if (found != _planesMap.end()) { - for (int i = 0; i < PLANES_VERTEX_DATA_SIZE; ++i) { - found->second.planesCoordinates.push_back(vertexData[i]); + for (int i = 0; i < PlanesVertexDataSize; ++i) { + found->second.planesCoordinates.push_back(VertexData[i]); } found->second.numberOfPlanes++; } @@ -1180,10 +755,10 @@ void RenderablePlanesCloud::createPlanes() { glGenVertexArrays(1, &pA.vao); glGenBuffers(1, &pA.vbo); pA.numberOfPlanes = 1; - for (int i = 0; i < PLANES_VERTEX_DATA_SIZE; ++i) { - pA.planesCoordinates.push_back(vertexData[i]); + for (int i = 0; i < PlanesVertexDataSize; ++i) { + pA.planesCoordinates.push_back(VertexData[i]); } - _planesMap.insert(std::pair(textureIndex, pA)); + _planesMap.insert(std::pair(textureIndex, pA)); } } @@ -1193,21 +768,13 @@ void RenderablePlanesCloud::createPlanes() { glBindBuffer(GL_ARRAY_BUFFER, pAMapItem.second.vbo); glBufferData( GL_ARRAY_BUFFER, - sizeof(GLfloat) * PLANES_VERTEX_DATA_SIZE * - pAMapItem.second.numberOfPlanes, + sizeof(GLfloat) * PlanesVertexDataSize * pAMapItem.second.numberOfPlanes, pAMapItem.second.planesCoordinates.data(), GL_STATIC_DRAW ); // in_position glEnableVertexAttribArray(0); - glVertexAttribPointer( - 0, - 4, - GL_FLOAT, - GL_FALSE, - sizeof(GLfloat) * 6, - nullptr - ); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), nullptr); // texture coords glEnableVertexAttribArray(1); @@ -1216,8 +783,8 @@ void RenderablePlanesCloud::createPlanes() { 2, GL_FLOAT, GL_FALSE, - sizeof(GLfloat) * 6, - reinterpret_cast(sizeof(GLfloat) * 4) + 6 * sizeof(GLfloat), + reinterpret_cast(4 * sizeof(GLfloat)) ); glBindVertexArray(0); @@ -1226,7 +793,7 @@ void RenderablePlanesCloud::createPlanes() { _dataIsDirty = false; setBoundingSphere(maxRadius * _scaleFactor); - _fadeInDistance.setMaxValue(glm::vec2(10.f * maxSize)); + _fadeInDistances.setMaxValue(glm::vec2(10.f * maxSize)); } if (_hasLabel && _labelDataIsDirty) { diff --git a/modules/digitaluniverse/rendering/renderableplanescloud.h b/modules/digitaluniverse/rendering/renderableplanescloud.h index 9123200e5c..de2d2386cd 100644 --- a/modules/digitaluniverse/rendering/renderableplanescloud.h +++ b/modules/digitaluniverse/rendering/renderableplanescloud.h @@ -27,6 +27,7 @@ #include +#include #include #include #include @@ -50,7 +51,6 @@ namespace ghoul::opengl { namespace openspace { // (x, y, z, w, s, t) * 6 = 36 -const int PLANES_VERTEX_DATA_SIZE = 36; namespace documentation { struct Documentation; } @@ -98,12 +98,7 @@ private: const glm::dmat4& modelViewProjectionMatrix, const glm::dvec3& orthoRight, const glm::dvec3& orthoUp, float fadeInVariable); - bool loadData(); - bool loadTextures(); - bool readSpeckFile(); - bool readLabelFile(); - bool loadCachedFile(const std::string& file); - bool saveCachedFile(const std::string& file) const; + void loadTextures(); bool _hasSpeckFile = false; bool _dataIsDirty = true; @@ -113,8 +108,6 @@ private: int _textMinSize = 0; int _textMaxSize = 200; - int _planeStartingIndexPos = 0; - int _textureVariableIndex = 0; properties::FloatProperty _scaleFactor; properties::Vec3Property _textColor; @@ -122,16 +115,15 @@ private: properties::FloatProperty _textSize; properties::BoolProperty _drawElements; properties::OptionProperty _blendMode; - properties::Vec2Property _fadeInDistance; + properties::Vec2Property _fadeInDistances; properties::BoolProperty _disableFadeInDistance; properties::FloatProperty _planeMinSize; - - // DEBUG: properties::OptionProperty _renderOption; ghoul::opengl::ProgramObject* _program = nullptr; - UniformCache(modelViewProjectionTransform, alphaValue, fadeInValue, - galaxyTexture) _uniformCache; + UniformCache( + modelViewProjectionTransform, alphaValue, fadeInValue, galaxyTexture + ) _uniformCache; std::shared_ptr _font = nullptr; std::unordered_map> _textureMap; std::unordered_map _textureFileMap; @@ -144,18 +136,14 @@ private: Unit _unit = Parsec; - std::vector _fullData; - std::vector> _labelData; - std::unordered_map _variableDataPositionMap; - - int _nValuesPerAstronomicalObject = 0; + speck::Dataset _dataset; + speck::Labelset _labelset; float _sluminosity = 1.f; glm::dmat4 _transformationMatrix = glm::dmat4(1.0); }; - } // namespace openspace #endif // __OPENSPACE_MODULE_DIGITALUNIVERSE___RENDERABLEPLANESCLOUD___H__ diff --git a/modules/digitaluniverse/rendering/renderablepoints.cpp b/modules/digitaluniverse/rendering/renderablepoints.cpp index 96c5420b91..286e247d96 100644 --- a/modules/digitaluniverse/rendering/renderablepoints.cpp +++ b/modules/digitaluniverse/rendering/renderablepoints.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -54,7 +55,6 @@ namespace { "spriteTexture", "hasColorMap" }; - constexpr int8_t CurrentCacheVersion = 1; constexpr double PARSEC = 0.308567756E17; constexpr openspace::properties::Property::PropertyInfo SpriteTextureInfo = { @@ -116,9 +116,7 @@ namespace { namespace openspace { documentation::Documentation RenderablePoints::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "digitaluniverse_renderablepoints"; - return doc; + return codegen::doc("digitaluniverse_renderablepoints"); } RenderablePoints::RenderablePoints(const ghoul::Dictionary& dictionary) @@ -137,7 +135,7 @@ RenderablePoints::RenderablePoints(const ghoul::Dictionary& dictionary) addProperty(_opacity); registerUpdateRenderBinFromOpacity(); - _speckFile = absPath(p.file); + _speckFile = absPath(p.file).string(); if (p.unit.has_value()) { switch (*p.unit) { @@ -174,22 +172,20 @@ RenderablePoints::RenderablePoints(const ghoul::Dictionary& dictionary) addProperty(_pointColor); if (p.texture.has_value()) { - _spriteTexturePath = absPath(*p.texture); + _spriteTexturePath = absPath(*p.texture).string(); _spriteTextureFile = std::make_unique( - _spriteTexturePath + _spriteTexturePath.value() ); - _spriteTexturePath.onChange([&] { _spriteTextureIsDirty = true; }); - _spriteTextureFile->setCallback( - [&](const ghoul::filesystem::File&) { _spriteTextureIsDirty = true; } - ); + _spriteTexturePath.onChange([this]() { _spriteTextureIsDirty = true; }); + _spriteTextureFile->setCallback([this]() { _spriteTextureIsDirty = true; }); addProperty(_spriteTexturePath); _hasSpriteTexture = true; } if (p.colorMap.has_value()) { - _colorMapFile = absPath(*p.colorMap); + _colorMapFile = absPath(*p.colorMap).string(); _hasColorMapFile = true; } @@ -198,26 +194,22 @@ RenderablePoints::RenderablePoints(const ghoul::Dictionary& dictionary) } bool RenderablePoints::isReady() const { - return (_program != nullptr) && (!_fullData.empty()); + return _program && (!_dataset.entries.empty()); } void RenderablePoints::initialize() { ZoneScoped - bool success = loadData(); - if (!success) { - throw ghoul::RuntimeError("Error loading data"); + _dataset = speck::data::loadFileWithCache(_speckFile); + + if (_hasColorMapFile) { + readColorMapFile(); } } void RenderablePoints::initializeGL() { ZoneScoped - // OBS: The ProgramObject name is later used to release the program as well, so the - // name parameter to requestProgramObject and the first parameter to - // buildRenderProgram has to be the same or an assertion will be thrown at the - // end of the program. - if (_hasSpriteTexture) { _program = DigitalUniverseModule::ProgramObjectManager.request( "RenderablePoints Sprite", @@ -289,10 +281,7 @@ void RenderablePoints::render(const RenderData& data, RendererTasks&) { glEnable(GL_PROGRAM_POINT_SIZE); glBindVertexArray(_vao); - const GLsizei nAstronomicalObjects = static_cast( - _fullData.size() / _nValuesPerAstronomicalObject - ); - glDrawArrays(GL_POINTS, 0, nAstronomicalObjects); + glDrawArrays(GL_POINTS, 0, static_cast(_dataset.entries.size())); glDisable(GL_PROGRAM_POINT_SIZE); glBindVertexArray(0); @@ -305,7 +294,7 @@ void RenderablePoints::update(const UpdateData&) { if (_dataIsDirty) { LDEBUG("Regenerating data"); - createDataSlice(); + std::vector slice = createDataSlice(); if (_vao == 0) { glGenVertexArrays(1, &_vao); @@ -318,19 +307,13 @@ void RenderablePoints::update(const UpdateData&) { glBindBuffer(GL_ARRAY_BUFFER, _vbo); glBufferData( GL_ARRAY_BUFFER, - _slicedData.size() * sizeof(double), - &_slicedData[0], + slice.size() * sizeof(double), + slice.data(), GL_STATIC_DRAW ); GLint positionAttrib = _program->attributeLocation("in_position"); if (_hasColorMapFile) { - - // const size_t nAstronomicalObjects = _fullData.size() / - // _nValuesPerAstronomicalObject; - // const size_t nValues = _slicedData.size() / nAstronomicalObjects; - // GLsizei stride = static_cast(sizeof(double) * nValues); - glEnableVertexAttribArray(positionAttrib); glVertexAttribLPointer( positionAttrib, 4, GL_DOUBLE, sizeof(double) * 8, nullptr @@ -342,8 +325,8 @@ void RenderablePoints::update(const UpdateData&) { colorMapAttrib, 4, GL_DOUBLE, - sizeof(double) * 8, - reinterpret_cast(sizeof(double) * 4) + 8 * sizeof(double), + reinterpret_cast(4 * sizeof(double)) ); } else { @@ -361,7 +344,7 @@ void RenderablePoints::update(const UpdateData&) { _spriteTexture = nullptr; if (!_spriteTexturePath.value().empty()) { _spriteTexture = ghoul::io::TextureReader::ref().loadTexture( - absPath(_spriteTexturePath) + absPath(_spriteTexturePath).string() ); if (_spriteTexture) { LDEBUG(fmt::format( @@ -374,134 +357,20 @@ void RenderablePoints::update(const UpdateData&) { ); _spriteTextureFile = std::make_unique( - _spriteTexturePath - ); - _spriteTextureFile->setCallback( - [&](const ghoul::filesystem::File&) { _spriteTextureIsDirty = true; } + _spriteTexturePath.value() ); + _spriteTextureFile->setCallback([this]() { _spriteTextureIsDirty = true; }); } _spriteTextureIsDirty = false; } } -bool RenderablePoints::loadData() { - std::string cachedFile = FileSys.cacheManager()->cachedFilename( - _speckFile, - ghoul::filesystem::CacheManager::Persistent::Yes - ); - - bool hasCachedFile = FileSys.fileExists(cachedFile); - if (hasCachedFile) { - LINFO(fmt::format( - "Cached file '{}' used for Speck file '{}'", - cachedFile, _speckFile - )); - - bool success = loadCachedFile(cachedFile); - if (success) { - if (_hasColorMapFile) { - success &= readColorMapFile(); - } - return success; - } - else { - FileSys.cacheManager()->removeCacheFile(_speckFile); - // Intentional fall-through to the 'else' to generate the cache file for - // the next run - } - } - else { - LINFO(fmt::format("Cache for Speck file '{}' not found", _speckFile)); - } - LINFO(fmt::format("Loading Speck file '{}'", _speckFile)); - - bool success = readSpeckFile(); - if (!success) { - return false; - } - - LINFO("Saving cache"); - success = saveCachedFile(cachedFile); - - if (_hasColorMapFile) { - success &= readColorMapFile(); - } - - return success; -} - -bool RenderablePoints::readSpeckFile() { - std::ifstream file(_speckFile); - if (!file.good()) { - LERROR(fmt::format("Failed to open Speck file '{}'", _speckFile)); - return false; - } - - _nValuesPerAstronomicalObject = 0; - - // The beginning of the speck file has a header that either contains comments - // (signaled by a preceding '#') or information about the structure of the file - // (signaled by the keywords 'datavar', 'texturevar', and 'texture') - std::string line; - while (true) { - std::streampos position = file.tellg(); - std::getline(file, line); - - if (line[0] == '#' || line.empty()) { - continue; - } - - if (line.substr(0, 7) != "datavar" && - line.substr(0, 10) != "texturevar" && - line.substr(0, 7) != "texture") - { - // we read a line that doesn't belong to the header, so we have to jump - // back before the beginning of the current line - file.seekg(position); - break; - } - - if (line.substr(0, 7) == "datavar") { - // datavar lines are structured as follows: - // datavar # description - // where # is the index of the data variable; so if we repeatedly - // overwrite the 'nValues' variable with the latest index, we will end up - // with the total number of values (+3 since X Y Z are not counted in the - // Speck file index) - std::stringstream str(line); - - std::string dummy; - str >> dummy; - str >> _nValuesPerAstronomicalObject; - // We want the number, but the index is 0 based - _nValuesPerAstronomicalObject += 1; - } - } - - // X Y Z are not counted in the Speck file indices - _nValuesPerAstronomicalObject += 3; - - do { - std::vector values(_nValuesPerAstronomicalObject); - - std::getline(file, line); - std::stringstream str(line); - - for (int i = 0; i < _nValuesPerAstronomicalObject; ++i) { - str >> values[i]; - } - - _fullData.insert(_fullData.end(), values.begin(), values.end()); - } while (!file.eof()); - - return true; -} - -bool RenderablePoints::readColorMapFile() { +void RenderablePoints::readColorMapFile() { std::ifstream file(_colorMapFile); if (!file.good()) { - LERROR(fmt::format("Failed to open Color Map file '{}'", _colorMapFile)); - return false; + throw ghoul::RuntimeError(fmt::format( + "Failed to open Color Map file '{}'", _colorMapFile + )); } std::size_t numberOfColors = 0; @@ -526,7 +395,9 @@ bool RenderablePoints::readColorMapFile() { break; } else if (file.eof()) { - return false; + throw ghoul::RuntimeError(fmt::format( + "Failed to load colors from Color Map file '{}'", _colorMapFile + )); } } @@ -535,106 +406,26 @@ bool RenderablePoints::readColorMapFile() { std::stringstream str(line); glm::vec4 color; - for (int j = 0; j < 4; ++j) { - str >> color[j]; - } + str >> color.r >> color.g >> color.b >> color.a; _colorMapData.push_back(color); } - - return true; } -bool RenderablePoints::loadCachedFile(const std::string& file) { - std::ifstream fileStream(file, std::ifstream::binary); - if (fileStream.good()) { - int8_t version = 0; - fileStream.read(reinterpret_cast(&version), sizeof(int8_t)); - if (version != CurrentCacheVersion) { - LINFO("The format of the cached file has changed: deleting old cache"); - fileStream.close(); - FileSys.deleteFile(file); - return false; - } - - int32_t nValues = 0; - fileStream.read(reinterpret_cast(&nValues), sizeof(int32_t)); - fileStream.read( - reinterpret_cast(&_nValuesPerAstronomicalObject), - sizeof(int32_t) - ); - - _fullData.resize(nValues); - fileStream.read(reinterpret_cast( - &_fullData[0]), - nValues * sizeof(_fullData[0]) - ); - - const bool success = fileStream.good(); - return success; - } - else { - LERROR(fmt::format( - "Error opening file '{}' for loading cache file", - file - )); - return false; - } -} - -bool RenderablePoints::saveCachedFile(const std::string& file) const { - std::ofstream fileStream(file, std::ofstream::binary); - if (fileStream.good()) { - fileStream.write( - reinterpret_cast(&CurrentCacheVersion), - sizeof(int8_t) - ); - - const int32_t nValues = static_cast(_fullData.size()); - if (nValues == 0) { - LERROR("Error writing cache: No values were loaded"); - return false; - } - fileStream.write(reinterpret_cast(&nValues), sizeof(int32_t)); - - const int32_t nValuesPerAstronomicalObject = static_cast( - _nValuesPerAstronomicalObject - ); - fileStream.write( - reinterpret_cast(&nValuesPerAstronomicalObject), - sizeof(int32_t) - ); - - const size_t nBytes = nValues * sizeof(_fullData[0]); - fileStream.write(reinterpret_cast(&_fullData[0]), nBytes); - - const bool success = fileStream.good(); - return success; - } - else { - LERROR(fmt::format("Error opening file '{}' for save cache file", file)); - return false; - } -} - -void RenderablePoints::createDataSlice() { - _slicedData.clear(); +std::vector RenderablePoints::createDataSlice() { + std::vector slice; if (_hasColorMapFile) { - _slicedData.reserve(8 * (_fullData.size() / _nValuesPerAstronomicalObject)); + slice.reserve(8 * _dataset.entries.size()); } else { - _slicedData.reserve(4 * (_fullData.size()/_nValuesPerAstronomicalObject)); + slice.reserve(4 * _dataset.entries.size()); } int colorIndex = 0; - for (size_t i = 0; i < _fullData.size(); i += _nValuesPerAstronomicalObject) { - glm::dvec3 p = glm::dvec3( - _fullData[i + 0], - _fullData[i + 1], - _fullData[i + 2] - ); + for (const speck::Dataset::Entry& e : _dataset.entries) { + glm::dvec3 p = e.position; - // Converting untis + // Converting units if (_unit == Kilometer) { p *= 1E3; } @@ -658,15 +449,15 @@ void RenderablePoints::createDataSlice() { if (_hasColorMapFile) { for (int j = 0; j < 4; ++j) { - _slicedData.push_back(position[j]); + slice.push_back(position[j]); } for (int j = 0; j < 4; ++j) { - _slicedData.push_back(_colorMapData[colorIndex][j]); + slice.push_back(_colorMapData[colorIndex][j]); } } else { for (int j = 0; j < 4; ++j) { - _slicedData.push_back(position[j]); + slice.push_back(position[j]); } } @@ -674,6 +465,8 @@ void RenderablePoints::createDataSlice() { 0 : colorIndex + 1; } + + return slice; } } // namespace openspace diff --git a/modules/digitaluniverse/rendering/renderablepoints.h b/modules/digitaluniverse/rendering/renderablepoints.h index b842a90deb..0f7c4f1361 100644 --- a/modules/digitaluniverse/rendering/renderablepoints.h +++ b/modules/digitaluniverse/rendering/renderablepoints.h @@ -27,6 +27,7 @@ #include +#include #include #include #include @@ -63,7 +64,6 @@ public: static documentation::Documentation Documentation(); private: - enum Unit { Meter = 0, Kilometer = 1, @@ -74,13 +74,9 @@ private: GigalightYears = 6 }; - void createDataSlice(); + std::vector createDataSlice(); - bool loadData(); - bool readSpeckFile(); - bool readColorMapFile(); - bool loadCachedFile(const std::string& file); - bool saveCachedFile(const std::string& file) const; + void readColorMapFile(); bool _dataIsDirty = true; bool _hasSpriteTexture = false; @@ -94,19 +90,20 @@ private: std::unique_ptr _spriteTexture; std::unique_ptr _spriteTextureFile; ghoul::opengl::ProgramObject* _program = nullptr; - UniformCache(modelViewProjectionTransform, color, sides, alphaValue, scaleFactor, - spriteTexture, hasColorMap) _uniformCache; + UniformCache( + modelViewProjectionTransform, color, sides, alphaValue, scaleFactor, + spriteTexture, hasColorMap + ) _uniformCache; std::string _speckFile; std::string _colorMapFile; Unit _unit = Parsec; - std::vector _slicedData; - std::vector _fullData; + speck::Dataset _dataset; std::vector _colorMapData; - int _nValuesPerAstronomicalObject = 0; + //int _nValuesPerAstronomicalObject = 0; GLuint _vao = 0; GLuint _vbo = 0; diff --git a/modules/digitaluniverse/shaders/billboard_fs.glsl b/modules/digitaluniverse/shaders/billboard_fs.glsl index 678b20592a..203310715a 100644 --- a/modules/digitaluniverse/shaders/billboard_fs.glsl +++ b/modules/digitaluniverse/shaders/billboard_fs.glsl @@ -29,47 +29,44 @@ flat in float vs_screenSpaceDepth; in vec2 texCoord; in float ta; -uniform float alphaValue; // opacity +uniform float alphaValue; uniform vec3 color; uniform sampler2D spriteTexture; uniform bool hasColorMap; uniform float fadeInValue; Fragment getFragment() { - vec4 textureColor = texture(spriteTexture, texCoord); + if (gs_colorMap.a == 0.0 || ta == 0.0 || fadeInValue == 0.0 || alphaValue == 0.0) { + discard; + } + + vec4 textureColor = texture(spriteTexture, texCoord); + if (textureColor.a == 0.0) { + discard; + } + + vec4 fullColor = textureColor; - if (textureColor.a == 0.f || gs_colorMap.a == 0.f || ta == 0.f || fadeInValue == 0.f) - { - discard; - } + if (hasColorMap) { + fullColor *= gs_colorMap; + } + else { + fullColor.rgb *= color; + } - vec4 fullColor = vec4(1.0); - - if (hasColorMap) { - fullColor = vec4( - gs_colorMap.rgb * textureColor.rgb, - gs_colorMap.a * textureColor.a * alphaValue - ); - } - else { - fullColor = vec4(color.rgb * textureColor.rgb, textureColor.a * alphaValue); - } + float textureOpacity = dot(fullColor.rgb, vec3(1.0)); + if (textureOpacity == 0.0) { + discard; + } - fullColor.a *= fadeInValue * ta; - - float textureOpacity = dot(fullColor.rgb, vec3(1.0)); - if (fullColor.a == 0.f || textureOpacity == 0.0) { - discard; - } + fullColor.a *= alphaValue * fadeInValue * ta; - Fragment frag; - frag.color = fullColor; - frag.depth = vs_screenSpaceDepth; - // Setting the position of the billboards to not interact - // with the ATM. - frag.gPosition = vec4(-1e32, -1e32, -1e32, 1.0); - frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); - //frag.disableLDR2HDR = true; + Fragment frag; + frag.color = fullColor; + frag.depth = vs_screenSpaceDepth; + // Setting the position of the billboards to not interact with the ATM + frag.gPosition = vec4(-1e32, -1e32, -1e32, 1.0); + frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); - return frag; + return frag; } diff --git a/modules/digitaluniverse/shaders/billboard_gs.glsl b/modules/digitaluniverse/shaders/billboard_gs.glsl index e2f7fb4fc7..0fa9023e8e 100644 --- a/modules/digitaluniverse/shaders/billboard_gs.glsl +++ b/modules/digitaluniverse/shaders/billboard_gs.glsl @@ -29,117 +29,110 @@ layout(points) in; layout(triangle_strip, max_vertices = 4) out; -uniform float scaleFactor; -uniform vec3 up; -uniform vec3 right; -uniform dvec3 cameraPosition; // in world space (no SGCT View was considered) -uniform vec3 cameraLookUp; // in world space (no SGCT View was considered) -uniform int renderOption; -uniform vec2 screenSize; -uniform float maxBillboardSize; -uniform float minBillboardSize; - -uniform mat4 cameraViewProjectionMatrix; -uniform dmat4 modelMatrix; - -uniform float correctionSizeFactor; -uniform float correctionSizeEndDistance; - -uniform bool enabledRectSizeControl; - -uniform bool hasDvarScaling; - flat in vec4 colorMap[]; flat in float dvarScaling[]; flat out vec4 gs_colorMap; - out vec2 texCoord; flat out float vs_screenSpaceDepth; out float ta; +// General settings +uniform float scaleFactor; +uniform int renderOption; +uniform mat4 cameraViewProjectionMatrix; +uniform dmat4 modelMatrix; +uniform bool enabledRectSizeControl; +uniform bool hasDvarScaling; + +// RenderOption: CameraViewDirection +uniform vec3 up; +uniform vec3 right; + +// RenderOption: CameraPositionNormal +uniform dvec3 cameraPosition; +uniform vec3 cameraLookUp; +uniform float correctionSizeFactor; +uniform float correctionSizeEndDistance; + +// Pixel size control: true +uniform vec2 screenSize; +uniform float maxBillboardSize; +uniform float minBillboardSize; + const double PARSEC = 0.308567756e17LF; const vec2 corners[4] = vec2[4]( - vec2(0.0, 0.0), - vec2(1.0, 0.0), - vec2(1.0, 1.0), - vec2(0.0, 1.0) + vec2(0.0, 0.0), + vec2(1.0, 0.0), + vec2(1.0, 1.0), + vec2(0.0, 1.0) ); +const int RenderOptionCameraViewDirection = 0; +const int RenderOptionCameraPositionNormal = 1; void main() { - ta = 1.0f; - vec4 pos = gl_in[0].gl_Position; // in object space - gs_colorMap = colorMap[0]; + ta = 1.0; + vec4 pos = gl_in[0].gl_Position; + gs_colorMap = colorMap[0]; - double unit = PARSEC; + double unit = PARSEC; // Must be the same as the enum in RenderableBillboardsCloud.h - if (pos.w == 1.f) { - unit = 1E3; - } - else if (pos.w == 2.f) { - unit = PARSEC; - } - else if (pos.w == 3.f) { - unit = 1E3 * PARSEC; - } - else if (pos.w == 4.f) { - unit = 1E6 * PARSEC; - } - else if (pos.w == 5.f) { - unit = 1E9 * PARSEC; - } - else if (pos.w == 6.f) { - // Convertion factor from Parsecs to GigalightYears + if (pos.w == 1.0) { unit = 1E3; } + else if (pos.w == 2.0) { unit = PARSEC; } + else if (pos.w == 3.0) { unit = 1E3 * PARSEC; } + else if (pos.w == 4.0) { unit = 1E6 * PARSEC; } + else if (pos.w == 5.0) { unit = 1E9 * PARSEC; } + else if (pos.w == 6.0) { + // Conversion factor from Parsecs to GigalightYears unit = 306391534.73091 * PARSEC; } - dvec4 dpos = dvec4(dvec3(pos.xyz) * unit, 1.0); - dpos = modelMatrix * dpos; + dvec4 dpos = modelMatrix * dvec4(dvec3(pos.xyz) * unit, 1.0); - float scaleMultiply = exp(scaleFactor * 0.10f); - scaleMultiply = hasDvarScaling ? dvarScaling[0] * scaleMultiply : scaleMultiply; - - vec3 scaledRight = vec3(0.f); - vec3 scaledUp = vec3(0.f); - - vec4 initialPosition, secondPosition, thirdPosition, crossCorner; - - if (renderOption == 0) { // Camera View Direction - scaledRight = scaleMultiply * right * 0.5f; - scaledUp = scaleMultiply * up * 0.5f; + float scaleMultiply = exp(scaleFactor * 0.10); + if (hasDvarScaling) { + scaleMultiply *= dvarScaling[0]; } - else if (renderOption == 1) { // Camera Position Normal - vec3 normal = vec3(normalize(cameraPosition - dpos.xyz)); + + vec3 scaledRight = vec3(0.0); + vec3 scaledUp = vec3(0.0); + + if (renderOption == RenderOptionCameraViewDirection) { + scaledRight = scaleMultiply * right * 0.5; + scaledUp = scaleMultiply * up * 0.5; + } + else if (renderOption == RenderOptionCameraPositionNormal) { + vec3 normal = vec3(normalize(cameraPosition - dpos.xyz)); vec3 newRight = normalize(cross(cameraLookUp, normal)); - vec3 newUp = cross(normal, newRight); + vec3 newUp = cross(normal, newRight); if (!enabledRectSizeControl) { double distCamera = length(cameraPosition - dpos.xyz); - float expVar = float(-distCamera) / pow(10.f, correctionSizeEndDistance); - float factorVar = pow(10.f, correctionSizeFactor); - scaleMultiply *= 1.f / (1.f + factorVar * exp(expVar)); + float expVar = float(-distCamera) / pow(10.0, correctionSizeEndDistance); + float factorVar = pow(10.0, correctionSizeFactor); + scaleMultiply *= 1.0 / (1.0 + factorVar * exp(expVar)); } - scaledRight = scaleMultiply * newRight * 0.5f; - scaledUp = scaleMultiply * newUp * 0.5f; + scaledRight = scaleMultiply * newRight * 0.5; + scaledUp = scaleMultiply * newUp * 0.5; } if (enabledRectSizeControl) { - initialPosition = z_normalization(cameraViewProjectionMatrix * + vec4 initialPosition = z_normalization(cameraViewProjectionMatrix * vec4(vec3(dpos.xyz) - scaledRight - scaledUp, dpos.w)); vs_screenSpaceDepth = initialPosition.w; - crossCorner = z_normalization(cameraViewProjectionMatrix * + vec4 crossCorner = z_normalization(cameraViewProjectionMatrix * vec4(vec3(dpos.xyz) + scaledUp + scaledRight, dpos.w)); // Testing size for rectangular viewport: - vec2 halfViewSize = vec2(screenSize.x, screenSize.y) * 0.5f; - vec2 topRight = crossCorner.xy/crossCorner.w; - vec2 bottomLeft = initialPosition.xy/initialPosition.w; + vec2 halfViewSize = screenSize * 0.5; + vec2 topRight = crossCorner.xy / crossCorner.w; + vec2 bottomLeft = initialPosition.xy / initialPosition.w; // width and height vec2 sizes = abs(halfViewSize * (topRight - bottomLeft)); @@ -148,18 +141,18 @@ void main() { float correctionScale = maxBillboardSize / length(sizes); scaledRight *= correctionScale; - scaledUp *= correctionScale; - + scaledUp *= correctionScale; } else { // linear alpha decay - if (sizes.x < 2.0f * minBillboardSize) { - float maxVar = 2.0f * minBillboardSize; + if (sizes.x < 2.0 * minBillboardSize) { + float maxVar = 2.0 * minBillboardSize; float minVar = minBillboardSize; - float var = (sizes.y + sizes.x); - ta = ( (var - minVar)/(maxVar - minVar) ); - if (ta == 0.0f) + float var = sizes.y + sizes.x; + ta = (var - minVar) / (maxVar - minVar); + if (ta == 0.0) { return; + } } } } @@ -169,27 +162,26 @@ void main() { vec4 scaledRightClip = cameraViewProjectionMatrix * vec4(scaledRight, 0.0); vec4 scaledUpClip = cameraViewProjectionMatrix * vec4(scaledUp, 0.0); - initialPosition = z_normalization(dposClip - scaledRightClip - scaledUpClip); + vec4 initialPosition = z_normalization(dposClip - scaledRightClip - scaledUpClip); vs_screenSpaceDepth = initialPosition.w; - secondPosition = z_normalization(dposClip + scaledRightClip - scaledUpClip); - crossCorner = z_normalization(dposClip + scaledUpClip + scaledRightClip); - thirdPosition = z_normalization(dposClip + scaledUpClip - scaledRightClip); + vec4 secondPosition = z_normalization(dposClip + scaledRightClip - scaledUpClip); + vec4 crossCorner = z_normalization(dposClip + scaledUpClip + scaledRightClip); + vec4 thirdPosition = z_normalization(dposClip + scaledUpClip - scaledRightClip); // Build primitive - - texCoord = corners[0]; + texCoord = corners[0]; gl_Position = initialPosition; EmitVertex(); - texCoord = corners[1]; + texCoord = corners[1]; gl_Position = secondPosition; EmitVertex(); - texCoord = corners[3]; + texCoord = corners[3]; gl_Position = thirdPosition; EmitVertex(); - texCoord = corners[2]; + texCoord = corners[2]; gl_Position = crossCorner; EmitVertex(); diff --git a/modules/digitaluniverse/shaders/billboard_vs.glsl b/modules/digitaluniverse/shaders/billboard_vs.glsl index 98517afeb5..53bd0bd9d8 100644 --- a/modules/digitaluniverse/shaders/billboard_vs.glsl +++ b/modules/digitaluniverse/shaders/billboard_vs.glsl @@ -34,7 +34,7 @@ flat out vec4 colorMap; flat out float dvarScaling; void main() { - colorMap = in_colormap; - dvarScaling = in_dvarScaling; - gl_Position = in_position; + colorMap = in_colormap; + dvarScaling = in_dvarScaling; + gl_Position = in_position; } diff --git a/modules/digitaluniverse/shaders/billboardpolygon_gs.glsl b/modules/digitaluniverse/shaders/billboardpolygon_gs.glsl index 2bd88f5b90..6b6936eca4 100644 --- a/modules/digitaluniverse/shaders/billboardpolygon_gs.glsl +++ b/modules/digitaluniverse/shaders/billboardpolygon_gs.glsl @@ -25,7 +25,6 @@ #version __CONTEXT__ layout(points) in; -//layout(line_strip, max_vertices = 19) out; layout(triangle_strip, max_vertices = 63) out; uniform int sides; @@ -33,41 +32,24 @@ uniform int sides; const float PI = 3.1415926; void main() { - // for (int i = 0; i <= sides; i++) { - // // Angle between each side in radians - // float ang = PI * 2.0 / float(sides) * i; - - // // Offset from center of point (0.3 to accomodate for aspect ratio) - // //vec4 offset = vec4(cos(ang) * 0.003, -sin(ang) * 0.004, 0.0, 0.0); - // vec4 offset = vec4(cos(ang) * 0.8, -sin(ang) * 0.8, 0.0, 0.0); - // gl_Position = gl_in[0].gl_Position + offset; - - // // vec4 offset = vec4(cos(ang) * gl_in[0].gl_Position[0], -sin(ang) * gl_in[0].gl_Position[1], - // // gl_in[0].gl_Position[2] , gl_in[0].gl_Position[3]); - // // gl_Position = offset; - - // EmitVertex(); - // } - // EndPrimitive(); + vec4 v0 = gl_in[0].gl_Position; - vec4 v0 = gl_in[0].gl_Position; - - for (int i = sides; i > 0; --i) { - // Angle between each side in radians - float ang = PI * 2.0 / float(sides) * i; + for (int i = sides; i > 0; --i) { + // Angle between each side in radians + float ang = 2.0 * PI / float(sides) * i; - gl_Position = v0; - EmitVertex(); + gl_Position = v0; + EmitVertex(); - vec4 vi = v0 + vec4(cos(ang) * 0.8, -sin(ang) * 0.8, 0.0, 0.0); - gl_Position = vi; - EmitVertex(); + vec4 vi = v0 + vec4(cos(ang) * 0.8, -sin(ang) * 0.8, 0.0, 0.0); + gl_Position = vi; + EmitVertex(); - ang = PI * 2.0 / float(sides) * (i-1); - vec4 vii = v0 + vec4(cos(ang) * 0.8, -sin(ang) * 0.8, 0.0, 0.0); - gl_Position = vii; - EmitVertex(); + ang = 2.0 * PI / float(sides) * (i - 1); + vec4 vii = v0 + vec4(cos(ang) * 0.8, -sin(ang) * 0.8, 0.0, 0.0); + gl_Position = vii; + EmitVertex(); - EndPrimitive(); - } + EndPrimitive(); + } } diff --git a/modules/digitaluniverse/shaders/billboardpolygon_vs.glsl b/modules/digitaluniverse/shaders/billboardpolygon_vs.glsl index aead855d65..8e814f1955 100644 --- a/modules/digitaluniverse/shaders/billboardpolygon_vs.glsl +++ b/modules/digitaluniverse/shaders/billboardpolygon_vs.glsl @@ -27,5 +27,5 @@ layout(location = 0) in vec4 in_position; void main() { - gl_Position = in_position; + gl_Position = in_position; } diff --git a/modules/digitaluniverse/shaders/dumesh_fs.glsl b/modules/digitaluniverse/shaders/dumesh_fs.glsl index 1e28d7ce69..a9a0507272 100644 --- a/modules/digitaluniverse/shaders/dumesh_fs.glsl +++ b/modules/digitaluniverse/shaders/dumesh_fs.glsl @@ -31,18 +31,18 @@ uniform vec3 color; uniform float alphaValue; Fragment getFragment() { - Fragment frag; + Fragment frag; - if (alphaValue == 0.0) { - discard; - } + if (alphaValue == 0.0) { + discard; + } - frag.color = vec4(color, alphaValue); - frag.depth = vs_screenSpaceDepth; + frag.color = vec4(color, alphaValue); + frag.depth = vs_screenSpaceDepth; - // JCC: Need to change the position to camera space - frag.gPosition = vs_positionViewSpace; - frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); + // JCC: Need to change the position to camera space + frag.gPosition = vs_positionViewSpace; + frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); - return frag; + return frag; } diff --git a/modules/digitaluniverse/shaders/dumesh_vs.glsl b/modules/digitaluniverse/shaders/dumesh_vs.glsl index 281d1d0a64..58f891144d 100644 --- a/modules/digitaluniverse/shaders/dumesh_vs.glsl +++ b/modules/digitaluniverse/shaders/dumesh_vs.glsl @@ -28,19 +28,19 @@ in vec3 in_position; -uniform dmat4 modelViewTransform; -uniform dmat4 projectionTransform; - out float vs_screenSpaceDepth; out vec4 vs_positionViewSpace; +uniform dmat4 modelViewTransform; +uniform dmat4 projectionTransform; + void main() { - dvec4 positionViewSpace = modelViewTransform * dvec4(in_position, 1.0); - vec4 positionClipSpace = vec4(projectionTransform * positionViewSpace); - vec4 positionScreenSpace = vec4(z_normalization(positionClipSpace)); + dvec4 positionViewSpace = modelViewTransform * dvec4(in_position, 1.0); + vec4 positionClipSpace = vec4(projectionTransform * positionViewSpace); + vec4 positionScreenSpace = vec4(z_normalization(positionClipSpace)); - vs_screenSpaceDepth = positionScreenSpace.w; - vs_positionViewSpace = vec4(positionViewSpace); + vs_screenSpaceDepth = positionScreenSpace.w; + vs_positionViewSpace = vec4(positionViewSpace); - gl_Position = positionScreenSpace; + gl_Position = positionScreenSpace; } diff --git a/modules/digitaluniverse/shaders/plane_fs.glsl b/modules/digitaluniverse/shaders/plane_fs.glsl index 5282ce582e..c3a0a39965 100644 --- a/modules/digitaluniverse/shaders/plane_fs.glsl +++ b/modules/digitaluniverse/shaders/plane_fs.glsl @@ -28,37 +28,24 @@ in float vs_screenSpaceDepth; in vec2 vs_st; uniform sampler2D galaxyTexture; -//uniform bool additiveBlending; uniform float alphaValue; uniform float fadeInValue; - Fragment getFragment() { - Fragment frag; - // if (gl_FrontFacing) { - // frag.color = texture(galaxyTexture, vs_st); - // } - // else { - // frag.color = texture(galaxyTexture, vec2(1 - vs_st.s, vs_st.t)); - // } + Fragment frag; - frag.color = texture(galaxyTexture, vs_st); - frag.color *= alphaValue; + frag.color = texture(galaxyTexture, vs_st); + frag.color *= alphaValue; - frag.color *= fadeInValue; + frag.color *= fadeInValue; - if (frag.color.a == 0.0) { - discard; - } + if (frag.color.a == 0.0) { + discard; + } - // if (additiveBlending) { - // frag.blend = BLEND_MODE_ADDITIVE; - // } + frag.depth = vs_screenSpaceDepth; + frag.gPosition = vec4(vs_screenSpaceDepth, vs_screenSpaceDepth, vs_screenSpaceDepth, 1.0); + frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); - //frag.color = texture(galaxyTexture, vs_st); - frag.depth = vs_screenSpaceDepth; - frag.gPosition = vec4(vs_screenSpaceDepth, vs_screenSpaceDepth, vs_screenSpaceDepth, 1.0); - frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); - - return frag; + return frag; } diff --git a/modules/digitaluniverse/shaders/plane_vs.glsl b/modules/digitaluniverse/shaders/plane_vs.glsl index cb84739b05..d373add7ec 100644 --- a/modules/digitaluniverse/shaders/plane_vs.glsl +++ b/modules/digitaluniverse/shaders/plane_vs.glsl @@ -34,12 +34,11 @@ out float vs_screenSpaceDepth; uniform dmat4 modelViewProjectionTransform; - void main() { - vs_st = in_st; - vec4 positionClipSpace = vec4(modelViewProjectionTransform * dvec4(in_position)); - vec4 positionScreenSpace = z_normalization(positionClipSpace); + vs_st = in_st; + vec4 positionClipSpace = vec4(modelViewProjectionTransform * dvec4(in_position)); + vec4 positionScreenSpace = z_normalization(positionClipSpace); - vs_screenSpaceDepth = positionScreenSpace.w; - gl_Position = positionScreenSpace; + vs_screenSpaceDepth = positionScreenSpace.w; + gl_Position = positionScreenSpace; } diff --git a/modules/digitaluniverse/shaders/points_gs.glsl b/modules/digitaluniverse/shaders/points_gs.glsl deleted file mode 100644 index dc074d0484..0000000000 --- a/modules/digitaluniverse/shaders/points_gs.glsl +++ /dev/null @@ -1,63 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version __CONTEXT__ - -layout(points) in; -//layout(points, max_vertices = 13) out; -layout(line_strip, max_vertices = 13) out; - -in float vs_screenSpaceDepth[]; -in float vs_scaleFactor[]; -in vec4 colorMap[] - -uniform int sides; - -out float gs_screenSpaceDepth; - -const float PI = 3.1415926; - -void main() { - gs_screenSpaceDepth = vs_screenSpaceDepth[0]; - - for (int i = 0; i <= sides; i++) { - // Angle between each side in radians - float ang = PI * 2.0 / float(sides) * i; - - // Offset from center of point (0.3 to accomodate for aspect ratio) - //vec4 offset = vec4(cos(ang) * 0.003, -sin(ang) * 0.004, 0.0, 0.0); - //gl_Position = gl_in[0].gl_Position + offset; - - vec4 offset = vec4(cos(ang) * gl_in[0].gl_Position[0], -sin(ang) * gl_in[0].gl_Position[1], - gl_in[0].gl_Position[2] , gl_in[0].gl_Position[3]); - gl_Position = offset; - - EmitVertex(); - } - - //gl_Position = gl_in[0].gl_Position;// + offset; - //EmitVertex(); - - EndPrimitive(); -} diff --git a/modules/digitaluniverse/shaders/points_sprite_fs.glsl b/modules/digitaluniverse/shaders/points_sprite_fs.glsl index 03fdcfd916..1614127071 100644 --- a/modules/digitaluniverse/shaders/points_sprite_fs.glsl +++ b/modules/digitaluniverse/shaders/points_sprite_fs.glsl @@ -24,25 +24,23 @@ #include "fragment.glsl" -//in float gs_screenSpaceDepth; in float vs_screenSpaceDepth; uniform vec3 color; uniform float alphaValue; - uniform sampler2D spriteTexture; Fragment getFragment() { - Fragment frag; + Fragment frag; - if (alphaValue == 0.0) { - discard; - } + if (alphaValue == 0.0) { + discard; + } - frag.color = texture(spriteTexture, gl_PointCoord) * vec4(color, alphaValue); - //frag.depth = gs_screenSpaceDepth; - frag.depth = vs_screenSpaceDepth; - frag.blend = BLEND_MODE_ADDITIVE; + frag.color = texture(spriteTexture, gl_PointCoord) * vec4(color, alphaValue); + //frag.depth = gs_screenSpaceDepth; + frag.depth = vs_screenSpaceDepth; + frag.blend = BLEND_MODE_ADDITIVE; - return frag; + return frag; } diff --git a/modules/digitaluniverse/shaders/points_vs.glsl b/modules/digitaluniverse/shaders/points_vs.glsl index a741bea69e..bf8aea92e4 100644 --- a/modules/digitaluniverse/shaders/points_vs.glsl +++ b/modules/digitaluniverse/shaders/points_vs.glsl @@ -29,23 +29,21 @@ in dvec4 in_position; in dvec4 in_colormap; -uniform dmat4 modelViewProjectionTransform; -uniform float scaleFactor; - out float vs_screenSpaceDepth; out float vs_scaleFactor; out vec4 colorMap; +uniform dmat4 modelViewProjectionTransform; +uniform float scaleFactor; + void main() { - vec4 positionClipSpace = vec4(modelViewProjectionTransform * in_position); - // positionClipSpace = vec4( modelViewProjectionTransform * - // vec4(0,0,0,1)); - vec4 positionScreenSpace = vec4(z_normalization(positionClipSpace)); + vec4 positionClipSpace = vec4(modelViewProjectionTransform * in_position); + vec4 positionScreenSpace = vec4(z_normalization(positionClipSpace)); - vs_screenSpaceDepth = positionScreenSpace.w; - vs_scaleFactor = scaleFactor; - colorMap = vec4(in_colormap); + vs_screenSpaceDepth = positionScreenSpace.w; + vs_scaleFactor = scaleFactor; + colorMap = vec4(in_colormap); - gl_PointSize = scaleFactor; - gl_Position = positionScreenSpace; + gl_PointSize = scaleFactor; + gl_Position = positionScreenSpace; } diff --git a/modules/digitaluniverse/shaders/pointssprite_vs.glsl b/modules/digitaluniverse/shaders/pointssprite_vs.glsl deleted file mode 100644 index 7f06ce0d6a..0000000000 --- a/modules/digitaluniverse/shaders/pointssprite_vs.glsl +++ /dev/null @@ -1,48 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version __CONTEXT__ - -#include "PowerScaling/powerScaling_vs.hglsl" - -layout(location = 0) in vec4 in_position; -layout(location = 1) in vec2 in_st; - -out vec2 vs_st; -out float vs_screenSpaceDepth; -out vec4 vs_positionScreenSpace; - -uniform mat4 modelViewProjectionTransform; - - -void main() { - vec4 position = vec4(in_position.xyz * pow(10, in_position.w), 1); - vec4 positionClipSpace = modelViewProjectionTransform * position; - vec4 positionScreenSpace = z_normalization(positionClipSpace); - - gl_Position = positionScreenSpace; - - vs_st = in_st; - vs_screenSpaceDepth = positionScreenSpace.w; -} diff --git a/modules/exoplanets/exoplanetsmodule.cpp b/modules/exoplanets/exoplanetsmodule.cpp index a918bb6ca1..4658cee9c2 100644 --- a/modules/exoplanets/exoplanetsmodule.cpp +++ b/modules/exoplanets/exoplanetsmodule.cpp @@ -199,14 +199,14 @@ ExoplanetsModule::ExoplanetsModule() std::string ExoplanetsModule::exoplanetsDataPath() const { return absPath( - fmt::format("{}/{}", _exoplanetsDataFolder, ExoplanetsDataFileName) - ); + fmt::format("{}/{}", _exoplanetsDataFolder.value(), ExoplanetsDataFileName) + ).string(); }; std::string ExoplanetsModule::lookUpTablePath() const { return absPath( fmt::format("{}/{}", _exoplanetsDataFolder, LookupTableFileName) - ); + ).string(); }; std::string ExoplanetsModule::bvColormapPath() const { diff --git a/modules/exoplanets/exoplanetsmodule_lua.inl b/modules/exoplanets/exoplanetsmodule_lua.inl index 5843cec267..6ee47f1d7a 100644 --- a/modules/exoplanets/exoplanetsmodule_lua.inl +++ b/modules/exoplanets/exoplanetsmodule_lua.inl @@ -429,7 +429,7 @@ void createExoplanetSystem(const std::string& starName) { "Renderable = {" "Type = 'RenderableRadialGrid'," "Enabled = " + isCircleEnabledString + "," - "OuterRadius = " + std::to_string(AU) + "," + "Radii = { 0.0, 1.0 }," "CircleSegments = 64," "LineWidth = 2.0," "}," @@ -437,6 +437,10 @@ void createExoplanetSystem(const std::string& starName) { "Rotation = {" "Type = 'StaticRotation'," "Rotation = " + ghoul::to_string(meanOrbitPlaneRotationMatrix) + "" + "}," + "Scale = {" + "Type = 'StaticScale'," + "Scale = " + std::to_string(AU) + "" "}" "}," "GUI = {" @@ -512,7 +516,7 @@ void createExoplanetSystem(const std::string& starName) { // the luminosity of a star is proportional to: (radius^2)*(temperature^4) // Maybe a better option would be to compute the size based on the aboslute // magnitude or star luminosity, but for now this looks good enough. - float size = 59.f * radiusInMeter; + double size = 59.0 * radiusInMeter; if (hasTeff) { constexpr const float sunTeff = 5780.f; size *= std::pow(system.starData.teff / sunTeff, 2.0); diff --git a/modules/exoplanets/rendering/renderableorbitdisc.cpp b/modules/exoplanets/rendering/renderableorbitdisc.cpp index 7581788fac..8688d84e22 100644 --- a/modules/exoplanets/rendering/renderableorbitdisc.cpp +++ b/modules/exoplanets/rendering/renderableorbitdisc.cpp @@ -93,9 +93,7 @@ namespace { namespace openspace { documentation::Documentation RenderableOrbitDisc::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "exoplanets_renderableorbitdisc"; - return doc; + return codegen::doc("exoplanets_renderableorbitdisc"); } RenderableOrbitDisc::RenderableOrbitDisc(const ghoul::Dictionary& dictionary) @@ -118,7 +116,7 @@ RenderableOrbitDisc::RenderableOrbitDisc(const ghoul::Dictionary& dictionary) setBoundingSphere(_size + _offset.value().y * _size); _texturePath = p.texture.string(); - _texturePath.onChange([&]() { _texture->loadFromFile(_texturePath); }); + _texturePath.onChange([&]() { _texture->loadFromFile(_texturePath.value()); }); addProperty(_texturePath); _eccentricity = p.eccentricity; @@ -148,7 +146,7 @@ void RenderableOrbitDisc::initializeGL() { ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames); - _texture->loadFromFile(_texturePath); + _texture->loadFromFile(_texturePath.value()); _texture->uploadToGpu(); _plane->initialize(); diff --git a/modules/exoplanets/shaders/orbitdisc_fs.glsl b/modules/exoplanets/shaders/orbitdisc_fs.glsl index 0f56ee08a1..bab75b0556 100644 --- a/modules/exoplanets/shaders/orbitdisc_fs.glsl +++ b/modules/exoplanets/shaders/orbitdisc_fs.glsl @@ -22,11 +22,10 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include "PowerScaling/powerScaling_fs.hglsl" #include "fragment.glsl" in vec2 vs_st; -in vec4 vs_position; +in float vs_depth; uniform sampler1D discTexture; uniform vec2 offset; // relative to semi major axis @@ -38,7 +37,7 @@ const float Epsilon = 0.0000001; // Compute semi minor axis from major axis, a, and eccentricity, e float semiMinorAxis(float a, float e) { - return a * sqrt(1.0 - e * e); + return a * sqrt(1.0 - e * e); } // If returned value <= 1, the point is insdie or on the ellipse specified by the input: @@ -46,84 +45,84 @@ float semiMinorAxis(float a, float e) { // cx is the displacement of the center of the ellipse along the x-axis (for an orbit, // the y-displacement is always zero) float ellipseTest(vec2 point, float a, float b, float cx) { - float x = point.x; - float y = point.y; - return (pow(x - cx, 2.0) / (a*a)) + ((y*y) / (b*b)); + float x = point.x; + float y = point.y; + return (pow(x - cx, 2.0) / (a*a)) + ((y*y) / (b*b)); } Fragment getFragment() { - // Moving the origin to the center - vec2 st = (vs_st - vec2(0.5)) * 2.0; + // Moving the origin to the center + vec2 st = (vs_st - vec2(0.5)) * 2.0; - float offsetLower = offset.x * semiMajorAxis; - float offsetUpper = offset.y * semiMajorAxis; + float offsetLower = offset.x * semiMajorAxis; + float offsetUpper = offset.y * semiMajorAxis; - float AUpper = semiMajorAxis + offsetUpper; - float BUpper = semiMinorAxis(AUpper, eccentricity); - float CUpper = sqrt(AUpper*AUpper - BUpper*BUpper); - float outerApoapsisDistance = AUpper * (1 + eccentricity); + float AUpper = semiMajorAxis + offsetUpper; + float BUpper = semiMinorAxis(AUpper, eccentricity); + float CUpper = sqrt(AUpper*AUpper - BUpper*BUpper); + float outerApoapsisDistance = AUpper * (1.0 + eccentricity); - float ALower = semiMajorAxis - offsetLower; - float BLower = semiMinorAxis(ALower, eccentricity); - float CLower = sqrt(ALower*ALower - BLower*BLower); - float innerApoapsisDistance = ALower * (1 + eccentricity); + float ALower = semiMajorAxis - offsetLower; + float BLower = semiMinorAxis(ALower, eccentricity); + float CLower = sqrt(ALower*ALower - BLower*BLower); + float innerApoapsisDistance = ALower * (1.0 + eccentricity); - // Normalize based on outer apoapsis distance (size of plane) - float AU_n = AUpper / outerApoapsisDistance; - float BU_n = BUpper / outerApoapsisDistance; - float CU_n = CUpper / outerApoapsisDistance; - float AL_n = ALower / outerApoapsisDistance; - float BL_n = BLower / outerApoapsisDistance; - float CL_n = CLower / outerApoapsisDistance; + // Normalize based on outer apoapsis distance (size of plane) + float AU_n = AUpper / outerApoapsisDistance; + float BU_n = BUpper / outerApoapsisDistance; + float CU_n = CUpper / outerApoapsisDistance; + float AL_n = ALower / outerApoapsisDistance; + float BL_n = BLower / outerApoapsisDistance; + float CL_n = CLower / outerApoapsisDistance; - if (eccentricity <= Epsilon) { - CU_n = 0.0; - CL_n = 0.0; - } + if (eccentricity <= Epsilon) { + CU_n = 0.0; + CL_n = 0.0; + } - float outer = ellipseTest(st, AU_n, BU_n, -CU_n); - float inner = ellipseTest(st, AL_n, BL_n, -CL_n); - if (outer > 1.0 || inner < 1.0) { - // point is outside outer ellipse or inside inner eliipse - discard; - } + float outer = ellipseTest(st, AU_n, BU_n, -CU_n); + float inner = ellipseTest(st, AL_n, BL_n, -CL_n); + if (outer > 1.0 || inner < 1.0) { + // Point is outside outer ellipse or inside inner ellipse + discard; + } - // Remapping the texture coordinates - vec2 dir = normalize(st); + // Remapping the texture coordinates + vec2 dir = normalize(st); - // Find outer ellipse: where along the direction does the equation == 1? - float denominator = pow(BU_n * dir.x, 2.0) + pow(AU_n * dir.y, 2.0); - float first = -(BU_n * BU_n * dir.x * CU_n) / denominator; - float second = pow((BU_n * BU_n * dir.x * CU_n) / denominator, 2.0); - float third = (pow(BU_n * CU_n, 2.0) - pow(AU_n * BU_n, 2.0)) / denominator; + // Find outer ellipse: where along the direction does the equation == 1? + float denominator = pow(BU_n * dir.x, 2.0) + pow(AU_n * dir.y, 2.0); + float first = -(BU_n * BU_n * dir.x * CU_n) / denominator; + float second = pow((BU_n * BU_n * dir.x * CU_n) / denominator, 2.0); + float third = (pow(BU_n * CU_n, 2.0) - pow(AU_n * BU_n, 2.0)) / denominator; - float scale = first + sqrt(second - third); + float scale = first + sqrt(second - third); - vec2 outerPoint = dir * scale; - vec2 innerPoint = outerPoint * (innerApoapsisDistance / outerApoapsisDistance); + vec2 outerPoint = dir * scale; + vec2 innerPoint = outerPoint * (innerApoapsisDistance / outerApoapsisDistance); - float discWidth = distance(outerPoint, innerPoint); - float distanceFromOuterEdge = distance(outerPoint, st); - float relativeDistance = distanceFromOuterEdge / discWidth; + float discWidth = distance(outerPoint, innerPoint); + float distanceFromOuterEdge = distance(outerPoint, st); + float relativeDistance = distanceFromOuterEdge / discWidth; - // Compute texture coordinate based on the distance to outer edge - float textureCoord = 0.0; + // Compute texture coordinate based on the distance to outer edge + float textureCoord = 0.0; - // The midpoint (textureCoord = 0.5) depends on the ratio between the offsets - // (Note that the texture goes from outer to inner edge of disc) - float midPoint = offsetUpper / (offsetUpper + offsetLower); - if(relativeDistance > midPoint) { - textureCoord = 0.5 + 0.5 * (relativeDistance - midPoint) / (1.0 - midPoint); - } - else { - textureCoord = 0.5 * (relativeDistance / midPoint); - } + // The midpoint (textureCoord = 0.5) depends on the ratio between the offsets + // (Note that the texture goes from outer to inner edge of disc) + float midPoint = offsetUpper / (offsetUpper + offsetLower); + if (relativeDistance > midPoint) { + textureCoord = 0.5 + 0.5 * (relativeDistance - midPoint) / (1.0 - midPoint); + } + else { + textureCoord = 0.5 * (relativeDistance / midPoint); + } - vec4 diffuse = texture(discTexture, textureCoord); - diffuse.a *= opacity; + vec4 diffuse = texture(discTexture, textureCoord); + diffuse.a *= opacity; - Fragment frag; - frag.color = diffuse; - frag.depth = vs_position.w; - return frag; + Fragment frag; + frag.color = diffuse; + frag.depth = vs_depth; + return frag; } diff --git a/modules/exoplanets/shaders/orbitdisc_vs.glsl b/modules/exoplanets/shaders/orbitdisc_vs.glsl index 80a55c613d..37fda99a3f 100644 --- a/modules/exoplanets/shaders/orbitdisc_vs.glsl +++ b/modules/exoplanets/shaders/orbitdisc_vs.glsl @@ -30,15 +30,16 @@ layout(location = 0) in vec2 in_position; layout(location = 1) in vec2 in_st; out vec2 vs_st; -out vec4 vs_position; +out float vs_depth; uniform mat4 modelViewProjectionTransform; void main() { - vs_st = in_st; - vs_position = z_normalization( - modelViewProjectionTransform * vec4(in_position, 0.0, 1.0) - ); + vs_st = in_st; + vec4 pos = z_normalization( + modelViewProjectionTransform * vec4(in_position, 0.0, 1.0) + ); - gl_Position = vs_position; + vs_depth = pos.w; + gl_Position = pos; } diff --git a/modules/exoplanets/tasks/exoplanetsdatapreparationtask.cpp b/modules/exoplanets/tasks/exoplanetsdatapreparationtask.cpp index 837e9cafa3..d817b86285 100644 --- a/modules/exoplanets/tasks/exoplanetsdatapreparationtask.cpp +++ b/modules/exoplanets/tasks/exoplanetsdatapreparationtask.cpp @@ -34,39 +34,53 @@ #include #include #include +#include #include namespace { - constexpr const char* KeyInputDataFile = "InputDataFile"; - constexpr const char* KeyInputSpeck = "InputSPECK"; - constexpr const char* KeyOutputBin = "OutputBIN"; - constexpr const char* KeyOutputLut = "OutputLUT"; - constexpr const char* KeyTeffToBv = "TeffToBvFile"; - constexpr const char* _loggerCat = "ExoplanetsDataPreparationTask"; + + struct [[codegen::Dictionary(ExoplanetsDataPreparationTask)]] Parameters { + // The csv file to extract data from + std::filesystem::path inputDataFile; + + // The speck file with star locations + std::filesystem::path inputSPECK; + + // The bin file to export data into + std::string outputBIN [[codegen::annotation("A valid filepath")]]; + + // The txt file to write look-up table into + std::string outputLUT [[codegen::annotation("A valid filepath")]]; + + // The path to a teff to bv conversion file. Should be a txt file where each line + // has the format 'teff,bv' + std::filesystem::path teffToBvFile; + }; +#include "exoplanetsdatapreparationtask_codegen.cpp" } // namespace namespace openspace::exoplanets { +documentation::Documentation ExoplanetsDataPreparationTask::documentation() { + return codegen::doc("exoplanets_data_preparation_task"); +} + ExoplanetsDataPreparationTask::ExoplanetsDataPreparationTask( const ghoul::Dictionary& dictionary) { - openspace::documentation::testSpecificationAndThrow( - documentation(), - dictionary, - "ExoplanetsDataPreparationTask" - ); + const Parameters p = codegen::bake(dictionary); - _inputDataPath = absPath(dictionary.value(KeyInputDataFile)); - _inputSpeckPath = absPath(dictionary.value(KeyInputSpeck)); - _outputBinPath = absPath(dictionary.value(KeyOutputBin)); - _outputLutPath = absPath(dictionary.value(KeyOutputLut)); - _teffToBvFilePath = absPath(dictionary.value(KeyTeffToBv)); + _inputDataPath = absPath(p.inputDataFile.string()); + _inputSpeckPath = absPath(p.inputSPECK.string()); + _outputBinPath = absPath(p.outputBIN); + _outputLutPath = absPath(p.outputLUT); + _teffToBvFilePath = absPath(p.teffToBvFile.string()); } std::string ExoplanetsDataPreparationTask::description() { return fmt::format( - "Extract data about exoplanets from file '{}' and write as bin to '{}'. The data " + "Extract data about exoplanets from file {} and write as bin to {}. The data " "file should be a csv version of the Planetary Systems Composite Data from the " "NASA exoplanets archive (https://exoplanetarchive.ipac.caltech.edu/).", _inputDataPath, _outputBinPath @@ -78,7 +92,7 @@ void ExoplanetsDataPreparationTask::perform( { std::ifstream inputDataFile(_inputDataPath); if (!inputDataFile.good()) { - LERROR(fmt::format("Failed to open input file '{}'", _inputDataPath)); + LERROR(fmt::format("Failed to open input file {}", _inputDataPath)); return; } @@ -441,45 +455,4 @@ float ExoplanetsDataPreparationTask::bvFromTeff(float teff) { return bv; } -documentation::Documentation ExoplanetsDataPreparationTask::documentation() { - using namespace documentation; - return { - "ExoplanetsDataPreparationTask", - "exoplanets_data_preparation_task", - { - { - KeyInputDataFile, - new FileVerifier, - Optional::No, - "The csv file to extract data from" - }, - { - KeyInputSpeck, - new FileVerifier, - Optional::No, - "The speck file with star locations" - }, - { - KeyOutputBin, - new StringAnnotationVerifier("A valid filepath"), - Optional::No, - "The bin file to export data into" - }, - { - KeyOutputLut, - new StringAnnotationVerifier("A valid filepath"), - Optional::No, - "The txt file to write look-up table into" - }, - { - KeyTeffToBv, - new FileVerifier, - Optional::No, - "The path to a teff to bv conversion file. Should be a txt file where " - "each line has the format 'teff,bv'" - } - } - }; -} - } // namespace openspace::exoplanets diff --git a/modules/exoplanets/tasks/exoplanetsdatapreparationtask.h b/modules/exoplanets/tasks/exoplanetsdatapreparationtask.h index ec3c7d823e..e5db06d53f 100644 --- a/modules/exoplanets/tasks/exoplanetsdatapreparationtask.h +++ b/modules/exoplanets/tasks/exoplanetsdatapreparationtask.h @@ -25,8 +25,10 @@ #ifndef __OPENSPACE_MODULE_EXOPLANETS___EXOPLANETSDATAPREPARATIONTASK___H__ #define __OPENSPACE_MODULE_EXOPLANETS___EXOPLANETSDATAPREPARATIONTASK___H__ -#include #include + +#include +#include #include namespace openspace::exoplanets { @@ -39,11 +41,11 @@ public: static documentation::Documentation documentation(); private: - std::string _inputDataPath; - std::string _inputSpeckPath; - std::string _outputBinPath; - std::string _outputLutPath; - std::string _teffToBvFilePath; + std::filesystem::path _inputDataPath; + std::filesystem::path _inputSpeckPath; + std::filesystem::path _outputBinPath; + std::filesystem::path _outputLutPath; + std::filesystem::path _teffToBvFilePath; glm::vec3 starPosition(const std::string& starName); diff --git a/modules/fieldlines/rendering/renderablefieldlines.cpp b/modules/fieldlines/rendering/renderablefieldlines.cpp index e71c1e4bb3..d07530d03c 100644 --- a/modules/fieldlines/rendering/renderablefieldlines.cpp +++ b/modules/fieldlines/rendering/renderablefieldlines.cpp @@ -192,7 +192,7 @@ void RenderableFieldlines::initializeDefaultPropertyValues() { std::string seedPointSourceFile = _seedPointsInfo.value( KeySeedPointsFile ); - _seedPointSourceFile = absPath(seedPointSourceFile); + _seedPointSourceFile = absPath(seedPointSourceFile).string(); } } else if (sourceType == SeedPointsSourceTable) { @@ -435,7 +435,7 @@ RenderableFieldlines::generateFieldlinesVolumeKameleon() return {}; } std::string fileName = _vectorFieldInfo.value(KeyVectorFieldFile); - fileName = absPath(fileName); + fileName = absPath(fileName).string(); //KameleonWrapper::Model modelType; if (model != VectorFieldKameleonModelBATSRUS) { diff --git a/modules/fieldlinessequence/fieldlinessequencemodule.cpp b/modules/fieldlinessequence/fieldlinessequencemodule.cpp index 35959eb514..9335c9cf8d 100644 --- a/modules/fieldlinessequence/fieldlinessequencemodule.cpp +++ b/modules/fieldlinessequence/fieldlinessequencemodule.cpp @@ -50,7 +50,9 @@ namespace openspace { std::string FieldlinesSequenceModule::DefaultTransferFunctionFile = ""; FieldlinesSequenceModule::FieldlinesSequenceModule() : OpenSpaceModule(Name) { - DefaultTransferFunctionFile = absPath("${TEMPORARY}/default_transfer_function.txt"); + DefaultTransferFunctionFile = absPath( + "${TEMPORARY}/default_transfer_function.txt" + ).string(); std::ofstream file(DefaultTransferFunctionFile); file << DefaultTransferfunctionSource; diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index b500fe33c6..95e075a9a6 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -294,7 +295,9 @@ void RenderableFieldlinesSequence::initializeGL() { // Set a default color table, just in case the (optional) user defined paths are // corrupt or not provided! _colorTablePaths.push_back(FieldlinesSequenceModule::DefaultTransferFunctionFile); - _transferFunction = std::make_unique(absPath(_colorTablePaths[0])); + _transferFunction = std::make_unique( + absPath(_colorTablePaths[0]).string() + ); // EXTRACT OPTIONAL INFORMATION FROM DICTIONARY std::string outputFolderPath; @@ -417,13 +420,16 @@ bool RenderableFieldlinesSequence::extractMandatoryInfoFromDictionary( // Ensure that the source folder exists and then extract // the files with the same extension as - ghoul::filesystem::Directory sourceFolder(sourceFolderPath); - if (FileSys.directoryExists(sourceFolder)) { + if (std::filesystem::is_directory(sourceFolderPath)) { // Extract all file paths from the provided folder - _sourceFiles = sourceFolder.readFiles( - ghoul::filesystem::Directory::Recursive::No, - ghoul::filesystem::Directory::Sort::Yes - ); + _sourceFiles.clear(); + namespace fs = std::filesystem; + for (const fs::directory_entry& e : fs::directory_iterator(sourceFolderPath)) { + if (e.is_regular_file()) { + _sourceFiles.push_back(e.path().string()); + } + } + std::sort(_sourceFiles.begin(), _sourceFiles.end()); // Remove all files that don't have as extension _sourceFiles.erase( @@ -471,9 +477,8 @@ void RenderableFieldlinesSequence::extractOptionalInfoFromDictionary( // ------------------- EXTRACT OPTIONAL VALUES FROM DICTIONARY ------------------- // if (_dictionary->hasValue(KeyOutputFolder)) { outputFolderPath = _dictionary->value(KeyOutputFolder); - ghoul::filesystem::Directory outputFolder(outputFolderPath); - if (FileSys.directoryExists(outputFolder)) { - outputFolderPath = absPath(outputFolderPath); + if (std::filesystem::is_directory(outputFolderPath)) { + outputFolderPath = absPath(outputFolderPath).string(); } else { LERROR(fmt::format( @@ -605,8 +610,9 @@ void RenderableFieldlinesSequence::loadOsflsStatesIntoRAM(const std::string& out if (newState.loadStateFromOsfls(filePath)) { addStateToSequence(newState); if (!outputFolder.empty()) { - ghoul::filesystem::File tmpFile(filePath); - newState.saveStateToJson(outputFolder + tmpFile.baseName()); + newState.saveStateToJson( + outputFolder + std::filesystem::path(filePath).stem().string() + ); } } else { @@ -916,9 +922,8 @@ bool RenderableFieldlinesSequence::extractCdfInfoFromDictionary(std::string& see { if (_dictionary->hasValue(KeyCdfSeedPointFile)) { seedFilePath = _dictionary->value(KeyCdfSeedPointFile); - ghoul::filesystem::File seedPointFile(seedFilePath); - if (FileSys.fileExists(seedPointFile)) { - seedFilePath = absPath(seedFilePath); + if (std::filesystem::is_regular_file(seedFilePath)) { + seedFilePath = absPath(seedFilePath).string(); } else { LERROR(fmt::format( @@ -962,7 +967,7 @@ bool RenderableFieldlinesSequence::extractSeedPointsFromFile(const std::string& std::vector& outVec) { - std::ifstream seedFile(FileSys.relativePath(path)); + std::ifstream seedFile(path); if (!seedFile.good()) { LERROR(fmt::format("Could not open seed points file '{}'", path)); return false; diff --git a/modules/gaia/rendering/renderablegaiastars.cpp b/modules/gaia/rendering/renderablegaiastars.cpp index e89dc71d06..2971318b53 100644 --- a/modules/gaia/rendering/renderablegaiastars.cpp +++ b/modules/gaia/rendering/renderablegaiastars.cpp @@ -414,9 +414,7 @@ namespace { namespace openspace { documentation::Documentation RenderableGaiaStars::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "gaiamission_renderablegaiastars"; - return doc; + return codegen::doc("gaiamission_renderablegaiastars"); } RenderableGaiaStars::RenderableGaiaStars(const ghoul::Dictionary& dictionary) @@ -462,11 +460,11 @@ RenderableGaiaStars::RenderableGaiaStars(const ghoul::Dictionary& dictionary) const Parameters p = codegen::bake(dictionary); - _filePath = absPath(p.file); - _dataFile = std::make_unique(_filePath); - _dataFile->setCallback([&](const File&) { _dataIsDirty = true; }); + _filePath = absPath(p.file).string(); + _dataFile = std::make_unique(_filePath.value()); + _dataFile->setCallback([this]() { _dataIsDirty = true; }); - _filePath.onChange([&]() { _dataIsDirty = true; }); + _filePath.onChange([this]() { _dataIsDirty = true; }); addProperty(_filePath); _fileReaderOption.addOptions({ @@ -519,7 +517,6 @@ RenderableGaiaStars::RenderableGaiaStars(const ghoul::Dictionary& dictionary) _renderOption.onChange([&]() { _buffersAreDirty = true; }); addProperty(_renderOption); -#ifndef __APPLE__ _shaderOption.addOptions({ { gaia::ShaderOption::Point_SSBO, "Point_SSBO" }, { gaia::ShaderOption::Point_VBO, "Point_VBO" }, @@ -527,35 +524,35 @@ RenderableGaiaStars::RenderableGaiaStars(const ghoul::Dictionary& dictionary) { gaia::ShaderOption::Billboard_VBO, "Billboard_VBO" }, { gaia::ShaderOption::Billboard_SSBO_noFBO, "Billboard_SSBO_noFBO" } }); -#else // __APPLE__ - _shaderOption.addOptions({ - { gaia::ShaderOption::Point_VBO, "Point_VBO" }, - { gaia::ShaderOption::Billboard_VBO, "Billboard_VBO" }, - }); -#endif // __APPLE__ if (p.shaderOption.has_value()) { switch (*p.shaderOption) { case Parameters::ShaderOption::PointSSBO: _shaderOption = gaia::ShaderOption::Point_SSBO; +#ifdef __APPLE__ + LWARNING("Shader option unsupported, changing to Point VBO"); + _shaderOption = gaia::ShaderOption::Point_VBO; +#endif // __APPLE__ break; case Parameters::ShaderOption::PointVBO: -#ifdef __APPLE__ - throw ghoul::RuntimeError("Shader option is not supported on MacOS"); -#endif // __APPLE__ _shaderOption = gaia::ShaderOption::Point_VBO; break; case Parameters::ShaderOption::BillboardSSBO: _shaderOption = gaia::ShaderOption::Billboard_SSBO; +#ifdef __APPLE__ + LWARNING("Shader option unsupported, changing to Point VBO"); + _shaderOption = gaia::ShaderOption::Point_VBO; +#endif // __APPLE__ break; case Parameters::ShaderOption::BillboardVBO: -#ifdef __APPLE__ - throw ghoul::RuntimeError("Shader option is not supported on MacOS"); -#endif // __APPLE__ _shaderOption = gaia::ShaderOption::Billboard_VBO; break; case Parameters::ShaderOption::BillboardSSBONoFBO: _shaderOption = gaia::ShaderOption::Billboard_SSBO_noFBO; +#ifdef __APPLE__ + LWARNING("Shader option unsupported, changing to Point VBO"); + _shaderOption = gaia::ShaderOption::Point_VBO; +#endif // __APPLE__ break; default: throw ghoul::MissingCaseException(); @@ -567,19 +564,21 @@ RenderableGaiaStars::RenderableGaiaStars(const ghoul::Dictionary& dictionary) }); addProperty(_shaderOption); - _pointSpreadFunctionTexturePath = absPath(p.texture); + _pointSpreadFunctionTexturePath = absPath(p.texture).string(); _pointSpreadFunctionTexturePath.onChange( - [&](){ _pointSpreadFunctionTextureIsDirty = true; } + [this](){ _pointSpreadFunctionTextureIsDirty = true; } + ); + _pointSpreadFunctionFile = std::make_unique( + _pointSpreadFunctionTexturePath.value() ); - _pointSpreadFunctionFile = std::make_unique(_pointSpreadFunctionTexturePath); _pointSpreadFunctionFile->setCallback( - [&](const File&) { _pointSpreadFunctionTextureIsDirty = true; } + [this]() { _pointSpreadFunctionTextureIsDirty = true; } ); - _colorTexturePath = absPath(p.colorMap); - _colorTextureFile = std::make_unique(_colorTexturePath); - _colorTexturePath.onChange([&]() { _colorTextureIsDirty = true; }); - _colorTextureFile->setCallback([&](const File&) { _colorTextureIsDirty = true; }); + _colorTexturePath = absPath(p.colorMap).string(); + _colorTextureFile = std::make_unique(_colorTexturePath.value()); + _colorTexturePath.onChange([this]() { _colorTextureIsDirty = true; }); + _colorTextureFile->setCallback([this]() { _colorTextureIsDirty = true; }); _luminosityMultiplier = p.luminosityMultiplier.value_or(_luminosityMultiplier); _magnitudeBoost = p.magnitudeBoost.value_or(_magnitudeBoost); @@ -1701,10 +1700,10 @@ void RenderableGaiaStars::update(const UpdateData&) { } case gaia::ShaderOption::Billboard_SSBO: case gaia::ShaderOption::Billboard_VBO: { - std::string vs = absPath( + std::filesystem::path vs = absPath( "${MODULE_GAIA}/shaders/gaia_tonemapping_vs.glsl" ); - std::string fs = absPath( + std::filesystem::path fs = absPath( "${MODULE_GAIA}/shaders/gaia_tonemapping_billboard_fs.glsl" ); std::unique_ptr programTM = @@ -2101,12 +2100,12 @@ void RenderableGaiaStars::update(const UpdateData&) { _pointSpreadFunctionTexture = nullptr; if (!_pointSpreadFunctionTexturePath.value().empty()) { _pointSpreadFunctionTexture = ghoul::io::TextureReader::ref().loadTexture( - absPath(_pointSpreadFunctionTexturePath) + absPath(_pointSpreadFunctionTexturePath).string() ); if (_pointSpreadFunctionTexture) { LDEBUG(fmt::format( - "Loaded texture from '{}'", absPath(_pointSpreadFunctionTexturePath) + "Loaded texture from {}", absPath(_pointSpreadFunctionTexturePath) )); _pointSpreadFunctionTexture->uploadTexture(); } @@ -2115,12 +2114,10 @@ void RenderableGaiaStars::update(const UpdateData&) { ); _pointSpreadFunctionFile = std::make_unique( - _pointSpreadFunctionTexturePath + _pointSpreadFunctionTexturePath.value() ); _pointSpreadFunctionFile->setCallback( - [&](const ghoul::filesystem::File&) { - _pointSpreadFunctionTextureIsDirty = true; - } + [this]() { _pointSpreadFunctionTextureIsDirty = true; } ); } _pointSpreadFunctionTextureIsDirty = false; @@ -2131,7 +2128,7 @@ void RenderableGaiaStars::update(const UpdateData&) { _colorTexture = nullptr; if (!_colorTexturePath.value().empty()) { _colorTexture = ghoul::io::TextureReader::ref().loadTexture( - absPath(_colorTexturePath) + absPath(_colorTexturePath).string() ); if (_colorTexture) { LDEBUG(fmt::format( @@ -2141,11 +2138,9 @@ void RenderableGaiaStars::update(const UpdateData&) { } _colorTextureFile = std::make_unique( - _colorTexturePath - ); - _colorTextureFile->setCallback( - [&](const ghoul::filesystem::File&) { _colorTextureIsDirty = true; } + _colorTexturePath.value() ); + _colorTextureFile->setCallback([this]() { _colorTextureIsDirty = true; }); } _colorTextureIsDirty = false; } diff --git a/modules/gaia/tasks/constructoctreetask.cpp b/modules/gaia/tasks/constructoctreetask.cpp index 7fefa17517..1239a65960 100644 --- a/modules/gaia/tasks/constructoctreetask.cpp +++ b/modules/gaia/tasks/constructoctreetask.cpp @@ -28,9 +28,9 @@ #include #include #include -#include #include #include +#include #include #include @@ -295,8 +295,10 @@ ConstructOctreeTask::ConstructOctreeTask(const ghoul::Dictionary& dictionary) { } std::string ConstructOctreeTask::description() { - return "Read bin file (or files in folder): " + _inFileOrFolderPath + "\n " - "and write octree data file (or files) into: " + _outFileOrFolderPath + "\n"; + return fmt::format( + "Read bin file (or files in folder): {} and write octree data file (or files) " + "into: {}", _inFileOrFolderPath, _outFileOrFolderPath + ); } void ConstructOctreeTask::perform(const Task::ProgressCallback& onProgress) { @@ -323,7 +325,7 @@ void ConstructOctreeTask::constructOctreeFromSingleFile( _octreeManager->initOctree(0, _maxDist, _maxStarsPerNode); - LINFO("Reading data file: " + _inFileOrFolderPath); + LINFO(fmt::format("Reading data file: {}", _inFileOrFolderPath)); LINFO(fmt::format( "MAX DIST: {} - MAX STARS PER NODE: {}", @@ -404,8 +406,7 @@ void ConstructOctreeTask::constructOctreeFromSingleFile( } else { LERROR(fmt::format( - "Error opening file '{}' for loading preprocessed file!", - _inFileOrFolderPath + "Error opening file {} for loading preprocessed file", _inFileOrFolderPath )); } LINFO(fmt::format("{} of {} read stars were filtered", nFilteredStars, nTotalStars)); @@ -413,7 +414,7 @@ void ConstructOctreeTask::constructOctreeFromSingleFile( // Slice LOD data before writing to files. _octreeManager->sliceLodData(); - LINFO("Writing octree to: " + _outFileOrFolderPath); + LINFO(fmt::format("Writing octree to: {}", _outFileOrFolderPath)); std::ofstream outFileStream(_outFileOrFolderPath, std::ofstream::binary); if (outFileStream.good()) { if (nValues == 0) { @@ -425,7 +426,7 @@ void ConstructOctreeTask::constructOctreeFromSingleFile( } else { LERROR(fmt::format( - "Error opening file: {} as output data file.", _outFileOrFolderPath + "Error opening file: {} as output data file", _outFileOrFolderPath )); } } @@ -452,8 +453,16 @@ void ConstructOctreeTask::constructOctreeFromFolder( //int starsOutside2000 = 0; //int starsOutside5000 = 0; - ghoul::filesystem::Directory currentDir(_inFileOrFolderPath); - std::vector allInputFiles = currentDir.readFiles(); + std::vector allInputFiles; + if (std::filesystem::is_directory(_inFileOrFolderPath)) { + namespace fs = std::filesystem; + for (const fs::directory_entry& e : fs::directory_iterator(_inFileOrFolderPath)) { + if (!e.is_regular_file()) { + allInputFiles.push_back(e.path()); + } + } + } + std::vector filterValues; auto writeThreads = std::vector(8); @@ -467,10 +476,10 @@ void ConstructOctreeTask::constructOctreeFromFolder( )); for (size_t idx = 0; idx < allInputFiles.size(); ++idx) { - std::string inFilePath = allInputFiles[idx]; + std::filesystem::path inFilePath = allInputFiles[idx]; int nStarsInfile = 0; - LINFO("Reading data file: " + inFilePath); + LINFO(fmt::format("Reading data file: {}", inFilePath)); std::ifstream inFileStream(inFilePath, std::ifstream::binary); if (inFileStream.good()) { @@ -528,7 +537,7 @@ void ConstructOctreeTask::constructOctreeFromFolder( } else { LERROR(fmt::format( - "Error opening file '{}' for loading preprocessed file!", inFilePath + "Error opening file {} for loading preprocessed file!", inFilePath )); } @@ -552,7 +561,7 @@ void ConstructOctreeTask::constructOctreeFromFolder( std::thread t( &OctreeManager::writeToMultipleFiles, _indexOctreeManager, - _outFileOrFolderPath, + _outFileOrFolderPath.string(), idx ); writeThreads[idx] = std::move(t); @@ -582,17 +591,19 @@ void ConstructOctreeTask::constructOctreeFromFolder( // " - 5000kPc is " + std::to_string(starsOutside5000)); // Write index file of Octree structure. - std::string indexFileOutPath = _outFileOrFolderPath + "index.bin"; + std::filesystem::path indexFileOutPath = fmt::format( + "{}/index.bin", _outFileOrFolderPath.string() + ); std::ofstream outFileStream(indexFileOutPath, std::ofstream::binary); if (outFileStream.good()) { - LINFO("Writing index file!"); + LINFO("Writing index file"); _indexOctreeManager->writeToFile(outFileStream, false); outFileStream.close(); } else { LERROR(fmt::format( - "Error opening file: {} as index output file.", indexFileOutPath + "Error opening file: {} as index output file", indexFileOutPath )); } @@ -642,9 +653,7 @@ bool ConstructOctreeTask::filterStar(const glm::vec2& range, float filterValue, } documentation::Documentation ConstructOctreeTask::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "gaiamission_constructoctreefrombin"; - return doc; + return codegen::doc("gaiamission_constructoctreefrombin"); } } // namespace openspace diff --git a/modules/gaia/tasks/constructoctreetask.h b/modules/gaia/tasks/constructoctreetask.h index e4be13457d..75701fd2a2 100644 --- a/modules/gaia/tasks/constructoctreetask.h +++ b/modules/gaia/tasks/constructoctreetask.h @@ -29,6 +29,7 @@ #include #include +#include namespace openspace { @@ -78,8 +79,8 @@ private: */ bool filterStar(const glm::vec2& range, float filterValue, float normValue = 0.f); - std::string _inFileOrFolderPath; - std::string _outFileOrFolderPath; + std::filesystem::path _inFileOrFolderPath; + std::filesystem::path _outFileOrFolderPath; int _maxDist = 0; int _maxStarsPerNode = 0; bool _singleFileInput = false; diff --git a/modules/gaia/tasks/readfitstask.cpp b/modules/gaia/tasks/readfitstask.cpp index 865433da6a..a23d128073 100644 --- a/modules/gaia/tasks/readfitstask.cpp +++ b/modules/gaia/tasks/readfitstask.cpp @@ -30,10 +30,9 @@ #include #include -#include #include #include - +#include #include #include #include @@ -132,7 +131,7 @@ void ReadFitsTask::readSingleFitsFile(const Task::ProgressCallback& progressCall FitsFileReader fileReader(false); std::vector fullData = fileReader.readFitsFile( - _inFileOrFolderPath, + _inFileOrFolderPath.string(), nValuesPerStar, _firstRow, _lastRow, @@ -166,7 +165,7 @@ void ReadFitsTask::readSingleFitsFile(const Task::ProgressCallback& progressCall } else { LERROR(fmt::format( - "Error opening file: {} as output data file.", _outFileOrFolderPath + "Error opening file: {} as output data file", _outFileOrFolderPath )); } } @@ -185,8 +184,16 @@ void ReadFitsTask::readAllFitsFilesFromFolder(const Task::ProgressCallback&) { ConcurrentJobManager>> jobManager(threadPool); // Get all files in specified folder. - ghoul::filesystem::Directory currentDir(_inFileOrFolderPath); - std::vector allInputFiles = currentDir.readFiles(); + std::vector allInputFiles; + if (std::filesystem::is_directory(_inFileOrFolderPath)) { + namespace fs = std::filesystem; + for (const fs::directory_entry& e : fs::directory_iterator(_inFileOrFolderPath)) { + if (e.is_regular_file()) { + allInputFiles.push_back(e.path()); + } + } + } + size_t nInputFiles = allInputFiles.size(); LINFO("Files to read: " + std::to_string(nInputFiles)); @@ -238,12 +245,12 @@ void ReadFitsTask::readAllFitsFilesFromFolder(const Task::ProgressCallback&) { // Divide all files into ReadFilejobs and then delegate them onto several threads! while (!allInputFiles.empty()) { - std::string fileToRead = allInputFiles.back(); + std::filesystem::path fileToRead = allInputFiles.back(); allInputFiles.erase(allInputFiles.end() - 1); // Add reading of file to jobmanager, which will distribute it to our threadpool. auto readFileJob = std::make_shared( - fileToRead, + fileToRead.string(), _allColumnNames, _firstRow, _lastRow, @@ -294,7 +301,9 @@ void ReadFitsTask::readAllFitsFilesFromFolder(const Task::ProgressCallback&) { int ReadFitsTask::writeOctantToFile(const std::vector& octantData, int index, std::vector& isFirstWrite, int nValuesPerStar) { - std::string outPath = fmt::format("{}octant_{}.bin", _outFileOrFolderPath, index); + std::string outPath = fmt::format( + "{}octant_{}.bin", _outFileOrFolderPath.string(), index + ); std::ofstream fileStream(outPath, std::ofstream::binary | std::ofstream::app); if (fileStream.good()) { int32_t nValues = static_cast(octantData.size()); @@ -328,9 +337,7 @@ int ReadFitsTask::writeOctantToFile(const std::vector& octantData, int in } documentation::Documentation ReadFitsTask::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "gaiamission_fitsfiletorawdata"; - return doc; + return codegen::doc("gaiamission_fitsfiletorawdata"); } } // namespace openspace diff --git a/modules/gaia/tasks/readfitstask.h b/modules/gaia/tasks/readfitstask.h index ee965cc71c..82568057a1 100644 --- a/modules/gaia/tasks/readfitstask.h +++ b/modules/gaia/tasks/readfitstask.h @@ -26,9 +26,11 @@ #define __OPENSPACE_MODULE_GAIA___READFITSTASK___H__ #include + #include #include #include +#include namespace openspace { @@ -67,8 +69,8 @@ private: int writeOctantToFile(const std::vector& data, int index, std::vector& isFirstWrite, int nValuesPerStar); - std::string _inFileOrFolderPath; - std::string _outFileOrFolderPath; + std::filesystem::path _inFileOrFolderPath; + std::filesystem::path _outFileOrFolderPath; bool _singleFileProcess = false; size_t _threadsToUse = 1; int _firstRow = 0; diff --git a/modules/gaia/tasks/readspecktask.cpp b/modules/gaia/tasks/readspecktask.cpp index 04526a33d9..7a0b45917e 100644 --- a/modules/gaia/tasks/readspecktask.cpp +++ b/modules/gaia/tasks/readspecktask.cpp @@ -49,9 +49,7 @@ namespace { namespace openspace { documentation::Documentation ReadSpeckTask::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "gaiamission_speckfiletorawdata"; - return doc; + return codegen::doc("gaiamission_speckfiletorawdata"); } ReadSpeckTask::ReadSpeckTask(const ghoul::Dictionary& dictionary) { @@ -72,7 +70,10 @@ void ReadSpeckTask::perform(const Task::ProgressCallback& onProgress) { int32_t nRenderValues = 0; FitsFileReader fileReader(false); - std::vector fullData = fileReader.readSpeckFile(_inFilePath, nRenderValues); + std::vector fullData = fileReader.readSpeckFile( + _inFilePath.string(), + nRenderValues + ); onProgress(0.9f); diff --git a/modules/gaia/tasks/readspecktask.h b/modules/gaia/tasks/readspecktask.h index f42b07a81f..ce1a1bb446 100644 --- a/modules/gaia/tasks/readspecktask.h +++ b/modules/gaia/tasks/readspecktask.h @@ -27,6 +27,7 @@ #include +#include #include namespace openspace { @@ -43,8 +44,8 @@ public: static documentation::Documentation Documentation(); private: - std::string _inFilePath; - std::string _outFilePath; + std::filesystem::path _inFilePath; + std::filesystem::path _outFilePath; }; } // namespace openspace diff --git a/modules/galaxy/rendering/galaxyraycaster.cpp b/modules/galaxy/rendering/galaxyraycaster.cpp index 0f11505f9d..a861503af6 100644 --- a/modules/galaxy/rendering/galaxyraycaster.cpp +++ b/modules/galaxy/rendering/galaxyraycaster.cpp @@ -58,7 +58,7 @@ void GalaxyRaycaster::initialize() { void GalaxyRaycaster::renderEntryPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) { - program.setUniform("modelViewTransform", glm::mat4(modelViewTransform(data))); + program.setUniform("modelViewTransform", modelViewTransform(data)); program.setUniform("projectionTransform", data.camera.projectionMatrix()); // Cull back face @@ -73,7 +73,7 @@ void GalaxyRaycaster::renderExitPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) { // Uniforms - program.setUniform("modelViewTransform", glm::mat4(modelViewTransform(data))); + program.setUniform("modelViewTransform", modelViewTransform(data)); program.setUniform("projectionTransform", data.camera.projectionMatrix()); // Cull front face diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp index 5964eff426..6cb9da54ee 100644 --- a/modules/galaxy/rendering/renderablegalaxy.cpp +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -47,7 +48,9 @@ #include #include #include +#include #include +#include namespace { constexpr int8_t CurrentCacheVersion = 1; @@ -55,12 +58,12 @@ namespace { constexpr const char* _loggerCat = "Renderable Galaxy"; constexpr const std::array UniformNamesPoints = { - "modelMatrix", "cameraViewProjectionMatrix", "eyePosition", + "modelMatrix", "viewProjectionMatrix", "eyePosition", "opacityCoefficient" }; constexpr const std::array UniformNamesBillboards = { - "modelMatrix", "cameraViewProjectionMatrix", + "modelMatrix", "viewProjectionMatrix", "cameraUp", "eyePosition", "psfTexture" }; @@ -94,12 +97,6 @@ namespace { "" // @TODO Missing documentation }; - constexpr openspace::properties::Property::PropertyInfo TranslationInfo = { - "Translation", - "Translation", - "" // @TODO Missing documentation - }; - constexpr openspace::properties::Property::PropertyInfo RotationInfo = { "Rotation", "Euler rotation", @@ -134,6 +131,57 @@ namespace { "This value set the number of integration steps during the raycasting procedure." }; + struct [[codegen::Dictionary(RenderableGalaxy)]] Parameters { + // [[codegen::verbatim(VolumeRenderingEnabledInfo.description)]] + std::optional volumeRenderingEnabled; + + // [[codegen::verbatim(StarRenderingEnabledInfo.description)]] + std::optional starRenderingEnabled; + + // [[codegen::verbatim(StepSizeInfo.description)]] + std::optional stepSizeInfo; + + // [[codegen::verbatim(AbsorptionMultiplyInfo.description)]] + std::optional absorptionMultiply; + + // [[codegen::verbatim(EmissionMultiplyInfo.description)]] + std::optional emissionMultiply; + + enum class StarRenderingMethod { + Points, + Billboards + }; + // [[codegen::verbatim(StarRenderingMethodInfo.description)]] + std::optional starRenderingMethod; + + // [[codegen::verbatim(RotationInfo.description)]] + std::optional rotation; + + struct Volume { + std::filesystem::path filename; + glm::ivec3 dimensions; + glm::vec3 size; + + // [[codegen::verbatim(NumberOfRayCastingStepsInfo.description)]] + std::optional steps; + + // [[codegen::verbatim(DownscaleVolumeRenderingInfo.description)]] + std::optional downscale; + }; + Volume volume; + + struct Points { + std::filesystem::path filename; + std::filesystem::path texture; + + // [[codegen::verbatim(EnabledPointsRatioInfo.description)]] + std::optional enabledPointsRatio; + }; + Points points; + }; +#include "renderablegalaxy_codegen.cpp" + + void saveCachedFile(const std::string& file, const std::vector& positions, const std::vector& colors, int64_t nPoints, float pointsRatio) @@ -165,6 +213,12 @@ namespace { ); } + float safeLength(const glm::vec3& vector) { + const float maxComponent = std::max( + std::max(std::abs(vector.x), std::abs(vector.y)), std::abs(vector.z) + ); + return glm::length(vector / maxComponent) * maxComponent; + } } // namespace namespace openspace { @@ -173,7 +227,7 @@ RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _volumeRenderingEnabled(VolumeRenderingEnabledInfo, true) , _starRenderingEnabled(StarRenderingEnabledInfo, true) - , _stepSize(StepSizeInfo, 0.01f, 0.0005f, 0.05f, 0.001f) + , _stepSize(StepSizeInfo, 0.01f, 0.001f, 0.05f, 0.001f) , _absorptionMultiply(AbsorptionMultiplyInfo, 40.f, 0.0f, 200.0f) , _emissionMultiply(EmissionMultiplyInfo, 200.f, 0.0f, 1000.0f) , _starRenderingMethod( @@ -181,7 +235,6 @@ RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary) properties::OptionProperty::DisplayType::Dropdown ) , _enabledPointsRatio(EnabledPointsRatioInfo, 0.5f, 0.01f, 1.0f) - , _translation(TranslationInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(1.f)) , _rotation( RotationInfo, glm::vec3(0.f), @@ -191,138 +244,44 @@ RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary) , _downScaleVolumeRendering(DownscaleVolumeRenderingInfo, 1.f, 0.1f, 1.f) , _numberOfRayCastingSteps(NumberOfRayCastingStepsInfo, 1000.f, 1.f, 1000.f) { - if (dictionary.hasKey("VolumeRenderingEnabled")) { - _volumeRenderingEnabled = dictionary.value("VolumeRenderingEnabled"); - } - if (dictionary.hasKey("StarRenderingEnabled")) { - _starRenderingEnabled = dictionary.value("StarRenderingEnabled"); - } + const Parameters p = codegen::bake(dictionary); - if (dictionary.hasKey("StarRenderingMethod")) { - _starRenderingMethod = dictionary.value("StarRenderingMethod"); - } - - if (dictionary.hasValue(VolumeRenderingEnabledInfo.identifier)) { - _volumeRenderingEnabled = dictionary.value( - VolumeRenderingEnabledInfo.identifier - ); - } - - if (dictionary.hasValue(StarRenderingEnabledInfo.identifier)) { - _starRenderingEnabled = static_cast(StarRenderingEnabledInfo.identifier); - } - - if (dictionary.hasValue(StepSizeInfo.identifier)) { - _stepSize = static_cast(dictionary.value(StepSizeInfo.identifier)); - } - - if (dictionary.hasValue(AbsorptionMultiplyInfo.identifier)) { - _absorptionMultiply = static_cast( - dictionary.value(AbsorptionMultiplyInfo.identifier) - ); - } - - if (dictionary.hasValue(EmissionMultiplyInfo.identifier)) { - _emissionMultiply = static_cast( - dictionary.value(EmissionMultiplyInfo.identifier) - ); - } + _volumeRenderingEnabled = p.volumeRenderingEnabled.value_or(_volumeRenderingEnabled); + _starRenderingEnabled = p.starRenderingEnabled.value_or(_starRenderingEnabled); + _volumeRenderingEnabled = p.volumeRenderingEnabled.value_or(_volumeRenderingEnabled); + _stepSize = p.stepSizeInfo.value_or(_stepSize); + _absorptionMultiply = p.absorptionMultiply.value_or(_absorptionMultiply); + _emissionMultiply = p.emissionMultiply.value_or(_emissionMultiply); _starRenderingMethod.addOptions({ { 0, "Points" }, { 1, "Billboards" } }); - if (dictionary.hasKey(StarRenderingMethodInfo.identifier)) { - const std::string starRenderingMethod = dictionary.value( - StarRenderingMethodInfo.identifier - ); - if (starRenderingMethod == "Points") { - _starRenderingMethod = 0; - } - else if (starRenderingMethod == "Billboards") { - _starRenderingMethod = 1; + if (p.starRenderingMethod.has_value()) { + switch (*p.starRenderingMethod) { + case Parameters::StarRenderingMethod::Points: + _starRenderingMethod = 0; + break; + case Parameters::StarRenderingMethod::Billboards: + _starRenderingMethod = 1; + break; } } - if (dictionary.hasValue(TranslationInfo.identifier)) { - _translation = dictionary.value(TranslationInfo.identifier); - } + _rotation = p.rotation.value_or(_rotation); - if (dictionary.hasValue(RotationInfo.identifier)) { - _rotation = dictionary.value(RotationInfo.identifier); - } + _volumeFilename = p.volume.filename.string(); + _volumeDimensions = p.volume.dimensions; + _volumeSize = p.volume.size; + _numberOfRayCastingSteps = p.volume.steps.value_or(_numberOfRayCastingSteps); + _downScaleVolumeRendering = p.volume.downscale.value_or(_downScaleVolumeRendering); - if (!dictionary.hasValue("Volume")) { - LERROR("No volume dictionary specified."); - } - - ghoul::Dictionary volumeDictionary = dictionary.value("Volume"); - - if (volumeDictionary.hasValue("Filename")) { - _volumeFilename = absPath(volumeDictionary.value("Filename")); - } - else { - LERROR("No volume filename specified"); - } - - if (volumeDictionary.hasValue("Dimensions")) { - _volumeDimensions = volumeDictionary.value("Dimensions"); - } - else { - LERROR("No volume dimensions specifieds"); - } - - if (volumeDictionary.hasValue("Size")) { - _volumeSize = volumeDictionary.value("Size"); - } - else { - LERROR("No volume dimensions specified."); - } - - if (volumeDictionary.hasKey(NumberOfRayCastingStepsInfo.identifier)) { - _numberOfRayCastingSteps = static_cast( - volumeDictionary.value(NumberOfRayCastingStepsInfo.identifier) - ); - } - else { - LINFO("Number of raycasting steps not specified. Using default value."); - } - - _downScaleVolumeRendering.setVisibility(properties::Property::Visibility::Developer); - if (volumeDictionary.hasKey(DownscaleVolumeRenderingInfo.identifier)) { - _downScaleVolumeRendering = static_cast( - volumeDictionary.value(DownscaleVolumeRenderingInfo.identifier) - ); - } - - if (!dictionary.hasValue("Points")) { - LERROR("No points dictionary specified."); - } - - ghoul::Dictionary pointsDictionary = dictionary.value("Points"); - if (pointsDictionary.hasValue("Filename")) { - _pointsFilename = absPath(pointsDictionary.value("Filename")); - } - else { - LERROR("No points filename specified."); - } - - if (pointsDictionary.hasValue(EnabledPointsRatioInfo.identifier)) { - _enabledPointsRatio = static_cast( - pointsDictionary.value(EnabledPointsRatioInfo.identifier) - ); - } - - if (pointsDictionary.hasValue("Texture")) { - _pointSpreadFunctionTexturePath = - absPath(pointsDictionary.value("Texture")); - _pointSpreadFunctionFile = std::make_unique( - _pointSpreadFunctionTexturePath - ); - } - else { - LERROR("No points filename specified."); - } + _pointsFilename = p.points.filename.string(); + _enabledPointsRatio = p.points.enabledPointsRatio.value_or(_enabledPointsRatio); + _pointSpreadFunctionTexturePath = p.points.texture.string(); + _pointSpreadFunctionFile = std::make_unique( + _pointSpreadFunctionTexturePath + ); auto onChange = [&](bool enabled) { if (enabled) { @@ -342,8 +301,8 @@ RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary) addProperty(_emissionMultiply); addProperty(_starRenderingMethod); addProperty(_enabledPointsRatio); - addProperty(_translation); addProperty(_rotation); + _downScaleVolumeRendering.setVisibility(properties::Property::Visibility::Developer); addProperty(_downScaleVolumeRendering); addProperty(_numberOfRayCastingSteps); } @@ -352,8 +311,8 @@ void RenderableGalaxy::initialize() { ZoneScoped // Aspect is currently hardcoded to cubic voxels. - _aspect = static_cast(_volumeDimensions); - _aspect /= std::max(std::max(_aspect.x, _aspect.y), _aspect.z); + glm::vec3 d = _volumeDimensions; + _aspect = d / glm::compMax(d); // The volume volume::RawVolumeReader> reader( @@ -363,10 +322,9 @@ void RenderableGalaxy::initialize() { _volume = reader.read(); std::string cachedPointsFile = FileSys.cacheManager()->cachedFilename( - _pointsFilename, - ghoul::filesystem::CacheManager::Persistent::Yes + _pointsFilename ); - const bool hasCachedFile = FileSys.fileExists(cachedPointsFile); + const bool hasCachedFile = std::filesystem::is_regular_file(cachedPointsFile); if (hasCachedFile) { LINFO(fmt::format("Cached file '{}' used for galaxy point file '{}'", cachedPointsFile, _pointsFilename @@ -379,7 +337,7 @@ void RenderableGalaxy::initialize() { } else { FileSys.cacheManager()->removeCacheFile(_pointsFilename); - Result resPoint = loadPointFile(_pointsFilename); + Result resPoint = loadPointFile(); _pointPositionsCache = std::move(resPoint.positions); _pointColorsCache = std::move(resPoint.color); saveCachedFile( @@ -392,7 +350,7 @@ void RenderableGalaxy::initialize() { } } else { - Result res = loadPointFile(_pointsFilename); + Result res = loadPointFile(); ghoul_assert(res.success, "Point file loading failed"); _pointPositionsCache = std::move(res.positions); _pointColorsCache = std::move(res.color); @@ -455,13 +413,12 @@ void RenderableGalaxy::initializeGL() { if (!_pointSpreadFunctionTexturePath.empty()) { _pointSpreadFunctionTexture = ghoul::io::TextureReader::ref().loadTexture( - absPath(_pointSpreadFunctionTexturePath) + absPath(_pointSpreadFunctionTexturePath).string() ); if (_pointSpreadFunctionTexture) { LDEBUG(fmt::format( - "Loaded texture from '{}'", - absPath(_pointSpreadFunctionTexturePath) + "Loaded texture from {}", absPath(_pointSpreadFunctionTexturePath) )); _pointSpreadFunctionTexture->uploadTexture(); } @@ -485,42 +442,33 @@ void RenderableGalaxy::initializeGL() { UniformNamesBillboards ); - _pointsProgram->setIgnoreUniformLocationError( - ghoul::opengl::ProgramObject::IgnoreError::Yes - ); - - GLint positionAttrib = _pointsProgram->attributeLocation("in_position"); - GLint colorAttrib = _pointsProgram->attributeLocation("in_color"); - glGenVertexArrays(1, &_pointsVao); glGenBuffers(1, &_positionVbo); glGenBuffers(1, &_colorVbo); glBindVertexArray(_pointsVao); glBindBuffer(GL_ARRAY_BUFFER, _positionVbo); - glBufferData(GL_ARRAY_BUFFER, + glBufferData( + GL_ARRAY_BUFFER, _pointPositionsCache.size() * sizeof(glm::vec3), _pointPositionsCache.data(), GL_STATIC_DRAW ); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); _pointPositionsCache.clear(); glBindBuffer(GL_ARRAY_BUFFER, _colorVbo); - glBufferData(GL_ARRAY_BUFFER, + glBufferData( + GL_ARRAY_BUFFER, _pointColorsCache.size() * sizeof(glm::vec3), _pointColorsCache.data(), GL_STATIC_DRAW ); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr); _pointColorsCache.clear(); - glBindBuffer(GL_ARRAY_BUFFER, _positionVbo); - glEnableVertexAttribArray(positionAttrib); - glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, nullptr); - - glBindBuffer(GL_ARRAY_BUFFER, _colorVbo); - glEnableVertexAttribArray(colorAttrib); - glVertexAttribPointer(colorAttrib, 3, GL_FLOAT, GL_FALSE, 0, nullptr); - glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); } @@ -544,7 +492,6 @@ void RenderableGalaxy::update(const UpdateData& data) { if (!_raycaster) { return; } - //glm::mat4 transform = glm::translate(, static_cast(_translation)); const glm::vec3 eulerRotation = static_cast(_rotation); glm::mat4 transform = glm::rotate( glm::mat4(1.f), @@ -556,14 +503,6 @@ void RenderableGalaxy::update(const UpdateData& data) { glm::mat4 volumeTransform = glm::scale(transform, _volumeSize); _pointTransform = transform; - //_pointTransform = glm::scale(transform, _pointScaling); - - const glm::vec4 translation = glm::vec4(_translation.value()*_volumeSize, 0.f); - - // Todo: handle floating point overflow, to actually support translation. - - volumeTransform[3] += translation; - _pointTransform[3] += translation; _raycaster->setDownscaleRender(_downScaleVolumeRendering); _raycaster->setMaxSteps(static_cast(_numberOfRayCastingSteps)); @@ -584,7 +523,7 @@ void RenderableGalaxy::render(const RenderData& data, RendererTasks& tasks) { const float length = safeLength(position); const glm::vec3 galaxySize = _volumeSize; - const float maxDim = std::max(std::max(galaxySize.x, galaxySize.y), galaxySize.z); + const float maxDim = glm::compMax(galaxySize); const float lowerRampStart = maxDim * 0.01f; const float lowerRampEnd = maxDim * 0.1f; @@ -605,7 +544,7 @@ void RenderableGalaxy::render(const RenderData& data, RendererTasks& tasks) { } else if (length < upperRampEnd) { opacityCoefficient = 1.f - (length - upperRampStart) / - (upperRampEnd - upperRampStart); //fade out + (upperRampEnd - upperRampStart); // fade out } else { opacityCoefficient = 0; @@ -622,22 +561,23 @@ void RenderableGalaxy::render(const RenderData& data, RendererTasks& tasks) { } } - // Render the stars - if (_starRenderingEnabled && _opacityCoefficient > 0.f) { - if (_starRenderingMethod == 1) { + if (!(_starRenderingEnabled && _opacityCoefficient > 0.f)) { + return; + } + + if (_starRenderingMethod == 1) { + if (_billboardsProgram) { renderBillboards(data); } - else { + } + else { + if (_pointsProgram) { renderPoints(data); } } } void RenderableGalaxy::renderPoints(const RenderData& data) { - if (!_pointsProgram) { - return; - } - glBlendFunc(GL_SRC_ALPHA, GL_ONE); glDepthMask(false); glDisable(GL_DEPTH_TEST); @@ -680,7 +620,6 @@ void RenderableGalaxy::renderPoints(const RenderData& data) { glBindVertexArray(_pointsVao); glDrawArrays(GL_POINTS, 0, static_cast(_nPoints * _enabledPointsRatio)); - glBindVertexArray(0); _pointsProgram->deactivate(); @@ -691,10 +630,6 @@ void RenderableGalaxy::renderPoints(const RenderData& data) { } void RenderableGalaxy::renderBillboards(const RenderData& data) { - if (!_billboardsProgram) { - return; - } - // Change OpenGL Blending and Depth states glBlendFunc(GL_SRC_ALPHA, GL_ONE); glDepthMask(false); @@ -742,7 +677,6 @@ void RenderableGalaxy::renderBillboards(const RenderData& data) { glBindVertexArray(_pointsVao); glDrawArrays(GL_POINTS, 0, static_cast(_nPoints * _enabledPointsRatio)); - glBindVertexArray(0); _billboardsProgram->deactivate(); @@ -752,14 +686,7 @@ void RenderableGalaxy::renderBillboards(const RenderData& data) { global::renderEngine->openglStateCache().resetDepthState(); } -float RenderableGalaxy::safeLength(const glm::vec3& vector) const { - const float maxComponent = std::max( - std::max(std::abs(vector.x), std::abs(vector.y)), std::abs(vector.z) - ); - return glm::length(vector / maxComponent) * maxComponent; -} - -RenderableGalaxy::Result RenderableGalaxy::loadPointFile(const std::string&) { +RenderableGalaxy::Result RenderableGalaxy::loadPointFile() { std::vector pointPositions; std::vector pointColors; int64_t nPoints; @@ -779,11 +706,11 @@ RenderableGalaxy::Result RenderableGalaxy::loadPointFile(const std::string&) { _nPoints = static_cast(nPoints); // Read points - float x, y, z, r, g, b, a; for (size_t i = 0; i < static_cast(_nPoints * _enabledPointsRatio.maxValue()) + 1; ++i) { + float x, y, z, r, g, b, a; std::getline(pointFile, line); std::istringstream issp(line); issp >> x >> y >> z >> r >> g >> b >> a; @@ -838,10 +765,7 @@ RenderableGalaxy::Result RenderableGalaxy::loadCachedFile(const std::string& fil fileStream.read(reinterpret_cast(&nColors), sizeof(uint64_t)); std::vector colors; colors.resize(nColors); - fileStream.read( - reinterpret_cast(colors.data()), - nColors * sizeof(glm::vec3) - ); + fileStream.read(reinterpret_cast(colors.data()), nColors * sizeof(glm::vec3)); Result result; result.success = true; diff --git a/modules/galaxy/rendering/renderablegalaxy.h b/modules/galaxy/rendering/renderablegalaxy.h index 889f2953a2..45dbcd1df7 100644 --- a/modules/galaxy/rendering/renderablegalaxy.h +++ b/modules/galaxy/rendering/renderablegalaxy.h @@ -57,14 +57,13 @@ public: private: void renderPoints(const RenderData& data); void renderBillboards(const RenderData& data); - float safeLength(const glm::vec3& vector) const; struct Result { bool success; std::vector positions; std::vector color; }; - Result loadPointFile(const std::string& file); + Result loadPointFile(); Result loadCachedFile(const std::string& file); glm::vec3 _volumeSize = glm::vec3(0.f); @@ -76,7 +75,6 @@ private: properties::FloatProperty _emissionMultiply; properties::OptionProperty _starRenderingMethod; properties::FloatProperty _enabledPointsRatio; - properties::Vec3Property _translation; properties::Vec3Property _rotation; properties::FloatProperty _downScaleVolumeRendering; properties::FloatProperty _numberOfRayCastingSteps; diff --git a/modules/galaxy/shaders/billboard_fs.glsl b/modules/galaxy/shaders/billboard_fs.glsl index 69931514a8..30930c7495 100644 --- a/modules/galaxy/shaders/billboard_fs.glsl +++ b/modules/galaxy/shaders/billboard_fs.glsl @@ -23,28 +23,25 @@ ****************************************************************************************/ #include "fragment.glsl" -#include "floatoperations.glsl" - -uniform sampler2D psfTexture; in vec4 vs_position; in vec2 psfCoords; flat in vec3 ge_color; flat in float ge_screenSpaceDepth; +uniform sampler2D psfTexture; + Fragment getFragment() { - Fragment frag; + vec4 textureColor = texture(psfTexture, 0.5 * psfCoords + 0.5); + vec4 fullColor = vec4(ge_color * textureColor.a, textureColor.a); + if (fullColor.a == 0) { + discard; + } - vec4 textureColor = texture(psfTexture, 0.5*psfCoords + 0.5); - vec4 fullColor = vec4(ge_color*textureColor.a, textureColor.a); - if (fullColor.a == 0) { - discard; - } - frag.color = fullColor; - - frag.depth = ge_screenSpaceDepth; - frag.gPosition = vs_position; - frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); - - return frag; + Fragment frag; + frag.color = fullColor; + frag.depth = ge_screenSpaceDepth; + frag.gPosition = vs_position; + frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); + return frag; } diff --git a/modules/galaxy/shaders/billboard_ge.glsl b/modules/galaxy/shaders/billboard_ge.glsl index 0cd652d36f..49a23edbca 100644 --- a/modules/galaxy/shaders/billboard_ge.glsl +++ b/modules/galaxy/shaders/billboard_ge.glsl @@ -27,11 +27,6 @@ #include "floatoperations.glsl" #include "PowerScaling/powerScalingMath.hglsl" -uniform dvec3 eyePosition; -uniform dvec3 cameraUp; -uniform dmat4 cameraViewProjectionMatrix; -uniform dmat4 modelMatrix; - layout(points) in; layout(triangle_strip, max_vertices = 4) out; @@ -43,59 +38,63 @@ out vec2 psfCoords; flat out vec3 ge_color; flat out float ge_screenSpaceDepth; +uniform dvec3 eyePosition; +uniform dvec3 cameraUp; +uniform dmat4 viewProjectionMatrix; +uniform dmat4 modelMatrix; + const double PARSEC = 3.08567756E16; void main() { - vs_position = gl_in[0].gl_Position; // in object space - ge_color = vs_color[0]; + vs_position = gl_in[0].gl_Position; + ge_color = vs_color[0]; - double scaleMultiply = 8.0; + double scaleMultiply = 8.0; - dvec4 dpos = dvec4(vs_position); - dpos.xyz *= scaleMultiply; - dpos = modelMatrix * dpos; - dpos /= PARSEC; - //It lies about 8 kpc from the center on what is known as the Orion Arm of the Milky Way - dpos.x += 8000; + dvec4 dpos = dvec4(vs_position); + dpos.xyz *= scaleMultiply; + dpos = modelMatrix * dpos; + dpos /= PARSEC; + // It lies about 8 kpc from the center on the Orion Arm of the Milky Way + dpos.x += 8000; - scaleMultiply *= 4.0; - dvec3 scaledRight = dvec3(0.0); - dvec3 scaledUp = dvec3(0.0); - vec4 bottomLeftVertex, bottomRightVertex, topLeftVertex, topRightVertex; + scaleMultiply *= 4.0; - dvec3 normal = normalize(eyePosition - dpos.xyz); - dvec3 newRight = normalize(cross(cameraUp, normal)); - dvec3 newUp = cross(normal, newRight); - scaledRight = scaleMultiply * newRight; - scaledUp = scaleMultiply * newUp; + dvec3 normal = normalize(eyePosition - dpos.xyz); + dvec3 newRight = normalize(cross(cameraUp, normal)); + dvec3 newUp = cross(normal, newRight); + dvec3 scaledRight = scaleMultiply * newRight; + dvec3 scaledUp = scaleMultiply * newUp; - bottomLeftVertex = z_normalization(vec4(cameraViewProjectionMatrix * - dvec4(dpos.xyz - scaledRight - scaledUp, dpos.w))); + vec4 bottomLeftVertex = z_normalization( + vec4(viewProjectionMatrix * dvec4(dpos.xyz - scaledRight - scaledUp, dpos.w)) + ); - //dvec4 dposCamera = cameraViewProjectionMatrix * dpos; - //ge_screenSpaceDepth = float(length(eyePosition - dposCamera.xyz)/PARSEC); - ge_screenSpaceDepth = bottomLeftVertex.w; + ge_screenSpaceDepth = bottomLeftVertex.w; - topRightVertex = z_normalization(vec4(cameraViewProjectionMatrix * - dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w))); + vec4 topRightVertex = z_normalization( + vec4(viewProjectionMatrix * dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w)) + ); - bottomRightVertex = z_normalization(vec4(cameraViewProjectionMatrix * - dvec4(dpos.xyz + scaledRight - scaledUp, dpos.w))); - topLeftVertex = z_normalization(vec4(cameraViewProjectionMatrix * - dvec4(dpos.xyz + scaledUp - scaledRight, dpos.w))); + vec4 bottomRightVertex = z_normalization( + vec4(viewProjectionMatrix * dvec4(dpos.xyz + scaledRight - scaledUp, dpos.w)) + ); + vec4 topLeftVertex = z_normalization( + vec4(viewProjectionMatrix * dvec4(dpos.xyz + scaledUp - scaledRight, dpos.w)) + ); - // Build primitive - gl_Position = topLeftVertex; - psfCoords = vec2(-1.0, 1.0); - EmitVertex(); - gl_Position = bottomLeftVertex; - psfCoords = vec2(-1.0, -1.0); - EmitVertex(); - gl_Position = topRightVertex; - psfCoords = vec2(1.0, 1.0); - EmitVertex(); - gl_Position = bottomRightVertex; - psfCoords = vec2(1.0, -1.0); - EmitVertex(); - EndPrimitive(); + // Build primitive + gl_Position = topLeftVertex; + psfCoords = vec2(-1.0, 1.0); + EmitVertex(); + gl_Position = bottomLeftVertex; + psfCoords = vec2(-1.0, -1.0); + EmitVertex(); + gl_Position = topRightVertex; + psfCoords = vec2(1.0, 1.0); + EmitVertex(); + gl_Position = bottomRightVertex; + psfCoords = vec2(1.0, -1.0); + EmitVertex(); + EndPrimitive(); } diff --git a/modules/galaxy/shaders/billboard_vs.glsl b/modules/galaxy/shaders/billboard_vs.glsl index 36e1cb8f56..f466ef2103 100644 --- a/modules/galaxy/shaders/billboard_vs.glsl +++ b/modules/galaxy/shaders/billboard_vs.glsl @@ -30,6 +30,6 @@ layout(location = 1) in vec3 in_color; out vec3 vs_color; void main() { - vs_color = in_color; - gl_Position = vec4(in_position, 1.0); + vs_color = in_color; + gl_Position = vec4(in_position, 1.0); } diff --git a/modules/galaxy/shaders/galaxyraycast.glsl b/modules/galaxy/shaders/galaxyraycast.glsl index 5bc7bcb4c6..a73e31501e 100644 --- a/modules/galaxy/shaders/galaxyraycast.glsl +++ b/modules/galaxy/shaders/galaxyraycast.glsl @@ -29,49 +29,45 @@ uniform float absorptionMultiply#{id} = 50.0; uniform float emissionMultiply#{id} = 1500.0; uniform sampler3D galaxyTexture#{id}; -void sample#{id}( - vec3 samplePos, - vec3 dir, - inout vec3 accumulatedColor, - inout vec3 accumulatedAlpha, - inout float stepSize - ) { - vec3 aspect = aspect#{id}; - stepSize = maxStepSize#{id} / length(dir / aspect); +void sample#{id}(vec3 samplePos, vec3 dir, inout vec3 accumulatedColor, + inout vec3 accumulatedAlpha, inout float stepSize) +{ + vec3 aspect = aspect#{id}; + stepSize = maxStepSize#{id} / length(dir / aspect); - //Early ray termination on black parts of the data - vec3 normalizedPos = samplePos * 2.f - 1.f; - if (normalizedPos.x * normalizedPos.x + normalizedPos.y * normalizedPos.y > 0.7) { - return; - } - - vec4 sampledColor = texture(galaxyTexture#{id}, samplePos.xyz); - - // Source textures currently are square-rooted to avoid dithering in the shadows. - // So square them back - sampledColor = sampledColor*sampledColor; - - // Fudge for the dust "spreading" - sampledColor.a = clamp(sampledColor.a, 0.f, 1.f); - sampledColor.a = pow(sampledColor.a, 0.7f); - - // Absorption probability - float scaledDensity = sampledColor.a * stepSize * absorptionMultiply#{id}; - vec3 alphaTint = vec3(0.3f, 0.54f, 0.85f); - vec3 absorption = alphaTint * scaledDensity; - - // Extinction - vec3 extinction = exp(-absorption); - accumulatedColor.rgb *= extinction; - - // Emission - accumulatedColor.rgb += - sampledColor.rgb * stepSize * emissionMultiply#{id} * opacityCoefficient#{id}; - - vec3 oneMinusFrontAlpha = vec3(1.f) - accumulatedAlpha; - accumulatedAlpha += oneMinusFrontAlpha * sampledColor.rgb * opacityCoefficient#{id}; + // Early ray termination on black parts of the data + vec3 normalizedPos = samplePos * 2.0 - 1.0; + if (normalizedPos.x * normalizedPos.x + normalizedPos.y * normalizedPos.y > 0.7) { + return; } - float stepSize#{id}(vec3 samplePos, vec3 dir) { - return maxStepSize#{id} * length(dir * 1.f / aspect#{id}); - } + vec4 sampledColor = texture(galaxyTexture#{id}, samplePos.xyz); + + // Source textures currently are square-rooted to avoid dithering in the shadows. + // So square them back + sampledColor = sampledColor*sampledColor; + + // Fudge for the dust "spreading" + sampledColor.a = clamp(sampledColor.a, 0.0, 1.0); + sampledColor.a = pow(sampledColor.a, 0.7); + + // Absorption probability + float scaledDensity = sampledColor.a * stepSize * absorptionMultiply#{id}; + vec3 alphaTint = vec3(0.3, 0.54, 0.85); + vec3 absorption = alphaTint * scaledDensity; + + // Extinction + vec3 extinction = exp(-absorption); + accumulatedColor.rgb *= extinction; + + // Emission + accumulatedColor.rgb += + sampledColor.rgb * stepSize * emissionMultiply#{id} * opacityCoefficient#{id}; + + vec3 oneMinusFrontAlpha = vec3(1.0) - accumulatedAlpha; + accumulatedAlpha += oneMinusFrontAlpha * sampledColor.rgb * opacityCoefficient#{id}; +} + +float stepSize#{id}(vec3 samplePos, vec3 dir) { + return maxStepSize#{id} * length(dir * 1.0 / aspect#{id}); +} diff --git a/modules/galaxy/shaders/points_fs.glsl b/modules/galaxy/shaders/points_fs.glsl index 025834723f..d3c2220566 100644 --- a/modules/galaxy/shaders/points_fs.glsl +++ b/modules/galaxy/shaders/points_fs.glsl @@ -33,16 +33,23 @@ in float vs_starBrightness; uniform float opacityCoefficient; Fragment getFragment() { - Fragment frag; + Fragment frag; - float multipliedOpacityCoefficient = opacityCoefficient*opacityCoefficient; - vec3 extinction = exp(vec3(0.6, 0.2, 0.3) - vs_color); - vec4 fullColor = vec4(vs_color*extinction*vs_starBrightness*multipliedOpacityCoefficient, opacityCoefficient); - frag.color = fullColor; + float multipliedOpacityCoefficient = opacityCoefficient * opacityCoefficient; + vec3 extinction = exp(vec3(0.6, 0.2, 0.3) - vs_color); - frag.depth = vs_screenSpaceDepth; - frag.gPosition = vs_position; - frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); + // We use the star brightness as the alpha value here to dim the stars as the camera + // moves further away. Otherwise they would occlude the main milkway image even though + // they themselves nolonger have any color contribution left + vec4 fullColor = vec4( + vs_color * extinction * vs_starBrightness * multipliedOpacityCoefficient, + vs_starBrightness + ); + frag.color = fullColor; - return frag; + frag.depth = vs_screenSpaceDepth; + frag.gPosition = vs_position; + frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); + + return frag; } diff --git a/modules/galaxy/shaders/points_vs.glsl b/modules/galaxy/shaders/points_vs.glsl index 9b7612e4c5..ae1a199dc8 100644 --- a/modules/galaxy/shaders/points_vs.glsl +++ b/modules/galaxy/shaders/points_vs.glsl @@ -34,7 +34,7 @@ out vec3 vs_color; out float vs_screenSpaceDepth; out float vs_starBrightness; -uniform dmat4 cameraViewProjectionMatrix; +uniform dmat4 viewProjectionMatrix; uniform dmat4 modelMatrix; uniform dvec3 eyePosition; @@ -44,14 +44,14 @@ void main() { vs_position = vec4(in_position, 1.0); dvec4 dpos = dvec4(vs_position); - double distanceToStar = length((dpos.xyz - eyePosition)); - vs_starBrightness = clamp(float(8000*PARSEC/distanceToStar), 0.0, 1.0); + double distanceToStar = length(dpos.xyz - eyePosition); + vs_starBrightness = clamp(float(8000.0 * PARSEC / distanceToStar), 0.0, 1.0); dpos.xyz *= 8.0; dpos = modelMatrix * dpos; dpos /= PARSEC; - vec4 positionScreenSpace = z_normalization(vec4(cameraViewProjectionMatrix * dpos)); + vec4 positionScreenSpace = z_normalization(vec4(viewProjectionMatrix * dpos)); vs_color = in_color; vs_screenSpaceDepth = positionScreenSpace.w; gl_Position = positionScreenSpace; diff --git a/modules/galaxy/shaders/raycasterbounds_fs.glsl b/modules/galaxy/shaders/raycasterbounds_fs.glsl index 50013a0642..7cd49070e7 100644 --- a/modules/galaxy/shaders/raycasterbounds_fs.glsl +++ b/modules/galaxy/shaders/raycasterbounds_fs.glsl @@ -29,18 +29,10 @@ in vec3 modelPosition; in vec4 viewPosition; Fragment getFragment() { - Fragment frag; - //Early ray termination on black parts of the data - /*vec3 normalizedPos = (modelPosition*2.0)-1.0; - if (abs(modelPosition.x) > 0.9 || abs(modelPosition.y) > 0.9) { - frag.color = vec4(0.0, 0.0, 0.0, 1.0); - } - else {*/ - vec3 pos = modelPosition + 0.5; - //vec3 posClamp = clamp(pos, vec3(0.0), vec3(1.0)); - frag.color = vec4(pos, 1.0); - //} + Fragment frag; + vec3 pos = modelPosition + 0.5; + frag.color = vec4(pos, 1.0); - frag.depth = safeLength(viewPosition); - return frag; + frag.depth = safeLength(viewPosition); + return frag; } diff --git a/modules/galaxy/shaders/raycasterbounds_vs.glsl b/modules/galaxy/shaders/raycasterbounds_vs.glsl index acd3fb47b2..edcf6acea7 100644 --- a/modules/galaxy/shaders/raycasterbounds_vs.glsl +++ b/modules/galaxy/shaders/raycasterbounds_vs.glsl @@ -24,20 +24,20 @@ #version __CONTEXT__ +#include "PowerScaling/powerScalingMath.hglsl" + layout(location = 0) in vec4 vertPosition; out vec3 modelPosition; out vec4 viewPosition; uniform mat4 projectionTransform; -uniform mat4 modelViewTransform; - +uniform dmat4 modelViewTransform; void main() { - modelPosition = vertPosition.xyz; - viewPosition = modelViewTransform*vertPosition; + modelPosition = vertPosition.xyz; + dvec4 vp = modelViewTransform * vertPosition; + viewPosition = vec4(vp); - // project the position to view space - gl_Position = projectionTransform * viewPosition; - gl_Position.z = 0.0; + gl_Position = z_normalization(vec4(projectionTransform * viewPosition)); } diff --git a/modules/globebrowsing/CMakeLists.txt b/modules/globebrowsing/CMakeLists.txt index 4e2434894b..2b0496967b 100644 --- a/modules/globebrowsing/CMakeLists.txt +++ b/modules/globebrowsing/CMakeLists.txt @@ -94,7 +94,7 @@ source_group("Source Files" FILES ${SOURCE_FILES}) set(SHADER_FILES shaders/advanced_rings_vs.glsl shaders/advanced_rings_fs.glsl - shaders/blending.hglsl + shaders/blending.glsl shaders/globalrenderer_vs.glsl shaders/localrenderer_vs.glsl shaders/renderer_fs.glsl @@ -102,10 +102,10 @@ set(SHADER_FILES shaders/rings_fs.glsl shaders/rings_geom_vs.glsl shaders/rings_geom_fs.glsl - shaders/texturetilemapping.hglsl - shaders/tile.hglsl - shaders/tileheight.hglsl - shaders/tilevertexskirt.hglsl + shaders/texturetilemapping.glsl + shaders/tile.glsl + shaders/tileheight.glsl + shaders/tilevertexskirt.glsl ) source_group("Shader Files" FILES ${SHADER_FILES}) diff --git a/modules/globebrowsing/globebrowsingmodule.cpp b/modules/globebrowsing/globebrowsingmodule.cpp index c8618ad63f..89b7fe275b 100644 --- a/modules/globebrowsing/globebrowsingmodule.cpp +++ b/modules/globebrowsing/globebrowsingmodule.cpp @@ -124,12 +124,16 @@ namespace { int iDataset = -1; std::array IdentifierBuffer; std::fill(IdentifierBuffer.begin(), IdentifierBuffer.end(), '\0'); - sscanf( + int ret = sscanf( subDatasets[i], "SUBDATASET_%i_%256[^=]", &iDataset, IdentifierBuffer.data() ); + if (ret != 2) { + LERROR("Error parsing dataset"); + continue; + } if (iDataset != currentLayerNumber) { @@ -454,6 +458,7 @@ std::vector GlobeBrowsingModule::documentations() globebrowsing::LayerAdjustment::Documentation(), globebrowsing::LayerManager::Documentation(), globebrowsing::GlobeTranslation::Documentation(), + globebrowsing::RenderableGlobe::Documentation(), GlobeLabelsComponent::Documentation(), RingsComponent::Documentation(), ShadowComponent::Documentation() diff --git a/modules/globebrowsing/scripts/layer_support.lua b/modules/globebrowsing/scripts/layer_support.lua index e6153e0d84..82678d901c 100644 --- a/modules/globebrowsing/scripts/layer_support.lua +++ b/modules/globebrowsing/scripts/layer_support.lua @@ -63,13 +63,12 @@ openspace.globebrowsing.documentation = { Name = "parseInfoFile", Arguments = "string", Documentation = - "Parses the passed info file and returns two tables. The first return value " .. - "contains the table for the color layer of a RenderableGlobe. The second " .. - "return value contains the table for the height layer of a RenderableGlobe." .. - "Usage: local color, height = openspace.globebrowsing.parseInfoFile(file)" .. - "openspace.globebrowsing.addLayer(\"Earth\", \"ColorLayers\", color)" .. - "openspace.globebrowsing.addLayer(\"Earth\", \"HeightLayers\", height)" - + "Parses the passed info file and return the table with the information " .. + "provided in the info file. The return table contains the optional keys: " .. + "'Color', 'Height', 'Node', 'Location', 'Identifier'." .. + "Usage: local t = openspace.globebrowsing.parseInfoFile(file)" .. + "openspace.globebrowsing.addLayer(\"Earth\", \"ColorLayers\", t.color)" .. + "openspace.globebrowsing.addLayer(\"Earth\", \"HeightLayers\", t.height)" }, { Name = "addBlendingLayersFromDirectory", @@ -264,7 +263,13 @@ openspace.globebrowsing.parseInfoFile = function (file) location = Location end - return name, color, height, location, identifier + return { + Color = color, + Height = height, + Name = name, + Location = location, + Identifier = identifier + } end openspace.globebrowsing.addBlendingLayersFromDirectory = function (dir, node_name) @@ -290,16 +295,14 @@ openspace.globebrowsing.addBlendingLayersFromDirectory = function (dir, node_nam for _, file in pairs(files) do if file and file:find('.info') and ends_with(file, '.info') then - local c, h - _, c, h, _ = openspace.globebrowsing.parseInfoFile(file) - - if c then - openspace.printInfo("Adding color layer '" .. c["Identifier"] .. "'") - openspace.globebrowsing.addLayer(node_name, "ColorLayers", c) + local t = openspace.globebrowsing.parseInfoFile(file) + if t.Color then + openspace.printInfo("Adding color layer '" .. t.Color["Identifier"] .. "'") + openspace.globebrowsing.addLayer(node_name, "ColorLayers", t.Color) end - if h then - openspace.printInfo("Adding height layer '" .. h["Identifier"] .. "'") - openspace.globebrowsing.addLayer(node_name, "HeightLayers", h) + if t.Height then + openspace.printInfo("Adding height layer '" .. t.Height["Identifier"] .. "'") + openspace.globebrowsing.addLayer(node_name, "HeightLayers", t.Height) end end end @@ -310,19 +313,18 @@ openspace.globebrowsing.addFocusNodesFromDirectory = function (dir, node_name) for _, file in pairs(files) do if file and file:find('.info') then - local n, l - n, _, _, l, i = openspace.globebrowsing.parseInfoFile(file) + local t = openspace.globebrowsing.parseInfoFile(file) - if n and l then + if t.Node and t.Location then openspace.printInfo("Creating focus node for '" .. n .. "'") - local lat = l.Center[2] - local long = l.Center[1] + local lat = t.Location.Center[2] + local long = t.Location.Center[1] local a, b, c = openspace.globebrowsing.getGeoPosition(node_name, lat, long, 0.0) local p = { a, b, c } - local identifier = node_name .. " - " .. i - local name = node_name .. " - " .. n + local identifier = node_name .. " - " .. t.Identifier + local name = node_name .. " - " .. t.Node openspace.addSceneGraphNode({ Identifier = identifier, diff --git a/modules/globebrowsing/shaders/advanced_rings_fs.glsl b/modules/globebrowsing/shaders/advanced_rings_fs.glsl index e6ddd8bd7b..1406127d30 100644 --- a/modules/globebrowsing/shaders/advanced_rings_fs.glsl +++ b/modules/globebrowsing/shaders/advanced_rings_fs.glsl @@ -45,99 +45,88 @@ uniform float colorFilterValue; uniform vec3 sunPosition; uniform vec3 sunPositionObj; uniform vec3 camPositionObj; -uniform float _nightFactor; +uniform float nightFactor; uniform float zFightingPercentage; -// temp -in vec4 fragPosInLightSpace; - - Fragment getFragment() { - // Moving the origin to the center - vec2 st = (vs_st - vec2(0.5)) * 2.0; + // Moving the origin to the center + vec2 st = (vs_st - vec2(0.5)) * 2.0; - // The length of the texture coordinates vector is our distance from the center - float radius = length(st); + // The length of the texture coordinates vector is our distance from the center + float radius = length(st); - // We only want to consider ring-like objects so we need to discard everything else - if (radius > 1.0) { - discard; - } + // We only want to consider ring-like objects so we need to discard everything else + if (radius > 1.0) { + discard; + } - // Remapping the texture coordinates - // Radius \in [0,1], texCoord \in [textureOffset.x, textureOffset.y] - // textureOffset.x -> 0 - // textureOffset.y -> 1 - float texCoord = (radius - textureOffset.x) / (textureOffset.y - textureOffset.x); - if (texCoord < 0.f || texCoord > 1.f) { - discard; - } + // Remapping the texture coordinates + // Radius \in [0,1], texCoord \in [textureOffset.x, textureOffset.y] + // textureOffset.x -> 0 + // textureOffset.y -> 1 + float texCoord = (radius - textureOffset.x) / (textureOffset.y - textureOffset.x); + if (texCoord < 0.0 || texCoord > 1.0) { + discard; + } - vec4 colorBckwrd = texture(ringTextureBckwrd, texCoord); - vec4 colorFwrd = texture(ringTextureFwrd, texCoord); - vec4 colorMult = texture(ringTextureColor, texCoord); - vec4 transparency = texture(ringTextureTransparency, texCoord); + vec4 colorBckwrd = texture(ringTextureBckwrd, texCoord); + vec4 colorFwrd = texture(ringTextureFwrd, texCoord); + vec4 colorMult = texture(ringTextureColor, texCoord); + vec4 transparency = texture(ringTextureTransparency, texCoord); - float lerpFactor = dot(camPositionObj, sunPositionObj); + float lerpFactor = dot(camPositionObj, sunPositionObj); - // Jon Colors: - //vec4 diffuse = mix(colorFwrd * vec4(1, 0.88, 0.82, 1.0), colorBckwrd * vec4(1, 0.88, 0.82, 1.0), lerpFactor); - vec4 diffuse = mix(colorFwrd * colorMult, colorBckwrd * colorMult, lerpFactor); - diffuse.a = colorFilterValue * transparency.a; - float colorValue = length(diffuse.rgb) / 0.57735026919; - if (colorValue < 0.1) { - discard; - } + // Jon Colors: + //vec4 diffuse = mix(colorFwrd * vec4(1, 0.88, 0.82, 1.0), colorBckwrd * vec4(1, 0.88, 0.82, 1.0), lerpFactor); + vec4 diffuse = mix(colorFwrd * colorMult, colorBckwrd * colorMult, lerpFactor); + diffuse.a = colorFilterValue * transparency.a; + float colorValue = length(diffuse.rgb) / 0.57735026919; + if (colorValue < 0.1) { + discard; + } - // shadow == 1.0 means it is not in shadow - float shadow = 1.0; - if (shadowCoords.z >= 0) { - vec4 normalizedShadowCoords = shadowCoords; - normalizedShadowCoords.z = normalizeFloat(zFightingPercentage * normalizedShadowCoords.w); - normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; - normalizedShadowCoords.w = 1.0; - - float sum = 0; - #for i in 0..#{nShadowSamples} - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, -NSSamples + #{i})); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, 0)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, NSSamples - #{i})); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , -NSSamples + #{i})); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , NSSamples - #{i})); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, -NSSamples + #{i})); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, 0)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, NSSamples - #{i})); - #endfor - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0)); - shadow = clamp(sum / (8.0 * NSSamples + 1.f), 0.35, 1.0); - } + // shadow == 1.0 means it is not in shadow + float shadow = 1.0; + if (shadowCoords.z >= 0) { + vec4 normalizedShadowCoords = shadowCoords; + normalizedShadowCoords.z = normalizeFloat(zFightingPercentage * normalizedShadowCoords.w); + normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; + normalizedShadowCoords.w = 1.0; + + float sum = 0; + #for i in 0..#{nShadowSamples} + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, -NSSamples + #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, NSSamples - #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , -NSSamples + #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , NSSamples - #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, -NSSamples + #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, NSSamples - #{i})); + #endfor + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0)); + shadow = clamp(sum / (8.0 * NSSamples + 1.f), 0.35, 1.0); + } - // The normal for the one plane depends on whether we are dealing - // with a front facing or back facing fragment - vec3 normal; - // The plane is oriented on the xz plane - // WARNING: This might not be the case for Uranus - if (gl_FrontFacing) { - normal = vec3(-1.0, 0.0, 0.0); - } - else { - normal = vec3(1.0, 0.0, 0.0); - } + // The normal for the one plane depends on whether we are dealing + // with a front facing or back facing fragment + // The plane is oriented on the xz plane + // WARNING: This might not be the case for Uranus + vec3 normal = gl_FrontFacing ? vec3(-1.0, 0.0, 0.0) : vec3(1.0, 0.0, 0.0); - // Reduce the color of the fragment by the user factor - // if we are facing away from the Sun - if (dot(sunPosition, normal) < 0) { - diffuse.xyz = vec3(1.0, 0.97075, 0.952) * - texture(ringTextureUnlit, texCoord).xyz * - _nightFactor; - } + // Reduce the color of the fragment by the user factor + // if we are facing away from the Sun + if (dot(sunPosition, normal) < 0.0) { + diffuse.xyz = + vec3(1.0, 0.97075, 0.952) * texture(ringTextureUnlit, texCoord).xyz * nightFactor; + } - Fragment frag; + Fragment frag; - frag.color = diffuse * shadow; - frag.depth = vs_screenSpaceDepth; - frag.gPosition = vec4(1e30, 1e30, 1e30, 1.0); - frag.gNormal = vec4(normal, 1.0); + frag.color = diffuse * shadow; + frag.depth = vs_screenSpaceDepth; + frag.gPosition = vec4(1e30, 1e30, 1e30, 1.0); + frag.gNormal = vec4(normal, 1.0); - return frag; + return frag; } diff --git a/modules/globebrowsing/shaders/advanced_rings_vs.glsl b/modules/globebrowsing/shaders/advanced_rings_vs.glsl index 8b43a60571..5d58c668c9 100644 --- a/modules/globebrowsing/shaders/advanced_rings_vs.glsl +++ b/modules/globebrowsing/shaders/advanced_rings_vs.glsl @@ -31,7 +31,6 @@ layout(location = 1) in vec2 in_st; out vec2 vs_st; out float vs_screenSpaceDepth; -out vec4 vs_positionViewSpace; out vec4 shadowCoords; uniform dmat4 modelViewProjectionMatrix; @@ -42,12 +41,12 @@ uniform dmat4 modelViewProjectionMatrix; uniform dmat4 shadowMatrix; void main() { - vs_st = in_st; + vs_st = in_st; - dvec4 positionClipSpace = modelViewProjectionMatrix * dvec4(in_position, 0.0, 1.0); - vec4 positionClipSpaceZNorm = z_normalization(vec4(positionClipSpace)); - - shadowCoords = vec4(shadowMatrix * dvec4(in_position, 0.0, 1.0)); - vs_screenSpaceDepth = positionClipSpaceZNorm.w; - gl_Position = positionClipSpaceZNorm; + dvec4 positionClipSpace = modelViewProjectionMatrix * dvec4(in_position, 0.0, 1.0); + vec4 positionClipSpaceZNorm = z_normalization(vec4(positionClipSpace)); + + shadowCoords = vec4(shadowMatrix * dvec4(in_position, 0.0, 1.0)); + vs_screenSpaceDepth = positionClipSpaceZNorm.w; + gl_Position = positionClipSpaceZNorm; } diff --git a/modules/globebrowsing/shaders/blending.hglsl b/modules/globebrowsing/shaders/blending.glsl similarity index 56% rename from modules/globebrowsing/shaders/blending.hglsl rename to modules/globebrowsing/shaders/blending.glsl index aff6b667d9..2456503c7a 100644 --- a/modules/globebrowsing/shaders/blending.hglsl +++ b/modules/globebrowsing/shaders/blending.glsl @@ -26,92 +26,91 @@ #define BLENDING_HGLSL vec4 blendNormal(vec4 oldColor, vec4 newColor) { - vec4 toReturn; - toReturn.a = mix(oldColor.a, 1.0, newColor.a); - toReturn.rgb = - (newColor.rgb * newColor.a + oldColor.rgb * oldColor.a * (1 - newColor.a)) / - toReturn.a; - return toReturn; + vec4 toReturn; + toReturn.a = mix(oldColor.a, 1.0, newColor.a); + toReturn.rgb = + (newColor.rgb * newColor.a + oldColor.rgb * oldColor.a * (1 - newColor.a)) / toReturn.a; + return toReturn; } vec4 blendMultiply(vec4 oldColor, vec4 newColor) { - return oldColor * newColor; + return oldColor * newColor; } vec4 blendAdd(vec4 oldColor, vec4 newColor) { - return oldColor + newColor; + return oldColor + newColor; } vec4 blendSubtract(vec4 oldColor, vec4 newColor) { - return oldColor - newColor; + return oldColor - newColor; } vec3 hsl2rgb(in vec3 c) { - vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0); + vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0); - return c.z + c.y * (rgb - 0.5) * (1.0 - abs(2.0 * c.z - 1.0)); + return c.z + c.y * (rgb - 0.5) * (1.0 - abs(2.0 * c.z - 1.0)); } vec3 HueShift(in vec3 color, in float shift) { - vec3 P = vec3(0.55735) * dot(vec3(0.55735), color); - vec3 U = color - P; - vec3 V = cross(vec3(0.55735), U); - vec3 c = U * cos(shift*6.2832) + V * sin(shift*6.2832) + P; - return c; + vec3 P = vec3(0.55735) * dot(vec3(0.55735), color); + vec3 U = color - P; + vec3 V = cross(vec3(0.55735), U); + vec3 c = U * cos(shift*6.2832) + V * sin(shift*6.2832) + P; + return c; } vec3 rgb2hsl(in vec3 c) { - float r = c.r; - float g = c.g; - float b = c.b; - float cMin = min(r, min(g, b)); - float cMax = max(r, max(g, b)); + float r = c.r; + float g = c.g; + float b = c.b; + float cMin = min(r, min(g, b)); + float cMax = max(r, max(g, b)); - if (cMax > cMin) { - float l = (cMax + cMin) / 2.0; + if (cMax > cMin) { + float l = (cMax + cMin) / 2.0; - float cDelta = cMax - cMin; + float cDelta = cMax - cMin; - //s = l < .05 ? cDelta / ( cMax + cMin ) : cDelta / ( 2.0 - ( cMax + cMin ) ); Original - float s = (l < 0.0) ? cDelta / (cMax + cMin) : cDelta / (2.0 - (cMax + cMin)); + //s = l < .05 ? cDelta / ( cMax + cMin ) : cDelta / ( 2.0 - ( cMax + cMin ) ); Original + float s = (l < 0.0) ? cDelta / (cMax + cMin) : cDelta / (2.0 - (cMax + cMin)); - float h = 0.0; - if (r == cMax) { - h = (g - b) / cDelta; - } - else if (g == cMax) { - h = 2.0 + (b - r) / cDelta; - } - else { - h = 4.0 + (r - g) / cDelta; - } - - if (h < 0.0) { - h += 6.0; - } - h = h / 6.0; - - return vec3(h, s, l); + float h = 0.0; + if (r == cMax) { + h = (g - b) / cDelta; + } + else if (g == cMax) { + h = 2.0 + (b - r) / cDelta; } else { - return vec3(0.0); + h = 4.0 + (r - g) / cDelta; } + + if (h < 0.0) { + h += 6.0; + } + h = h / 6.0; + + return vec3(h, s, l); + } + else { + return vec3(0.0); + } } vec3 rgb2hsv(vec3 c) { - vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); - vec4 p = (c.g < c.b) ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); - vec4 q = (c.r < p.x) ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + vec4 p = (c.g < c.b) ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = (c.r < p.x) ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); - float d = q.x - min(q.w, q.y); - float e = 1.0e-10; - return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); } vec3 hsv2rgb(vec3 c) { - vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); - vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); - return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); } -#endif +#endif // BLENDING_HGLSL diff --git a/modules/globebrowsing/shaders/globalrenderer_vs.glsl b/modules/globebrowsing/shaders/globalrenderer_vs.glsl index 7f1755f19d..3d59c08d04 100644 --- a/modules/globebrowsing/shaders/globalrenderer_vs.glsl +++ b/modules/globebrowsing/shaders/globalrenderer_vs.glsl @@ -25,10 +25,10 @@ #version __CONTEXT__ #include "PowerScaling/powerScaling_vs.hglsl" -#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl> -#include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.hglsl> -#include <${MODULE_GLOBEBROWSING}/shaders/tileheight.hglsl> -#include <${MODULE_GLOBEBROWSING}/shaders/tilevertexskirt.hglsl> +#include <${MODULE_GLOBEBROWSING}/shaders/tile.glsl> +#include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.glsl> +#include <${MODULE_GLOBEBROWSING}/shaders/tileheight.glsl> +#include <${MODULE_GLOBEBROWSING}/shaders/tilevertexskirt.glsl> layout(location = 1) in vec2 in_uv; @@ -39,22 +39,22 @@ out vec3 levelWeights; out vec3 positionCameraSpace; #if USE_ACCURATE_NORMALS - out vec3 ellipsoidTangentThetaCameraSpace; - out vec3 ellipsoidTangentPhiCameraSpace; + out vec3 ellipsoidTangentThetaCameraSpace; + out vec3 ellipsoidTangentPhiCameraSpace; #endif // USE_ACCURATE_NORMALS #if USE_ECLIPSE_SHADOWS - out vec3 positionWorldSpace; - uniform dmat4 modelTransform; -#endif + out vec3 positionWorldSpace; + uniform dmat4 modelTransform; +#endif // USE_ECLIPSE_SHADOWS #if SHADOW_MAPPING_ENABLED - // ShadowMatrix is the matrix defined by: - // textureCoordsMatrix * projectionMatrix * combinedViewMatrix * modelMatrix - // where textureCoordsMatrix is just a scale and bias computation: [-1,1] to [0,1] - uniform dmat4 shadowMatrix; - out vec4 shadowCoords; -#endif + // ShadowMatrix is the matrix defined by: + // textureCoordsMatrix * projectionMatrix * combinedViewMatrix * modelMatrix + // where textureCoordsMatrix is just a scale and bias computation: [-1,1] to [0,1] + uniform dmat4 shadowMatrix; + out vec4 shadowCoords; +#endif // SHADOW_MAPPING_ENABLED uniform mat4 modelViewProjectionTransform; uniform mat4 modelViewTransform; @@ -68,78 +68,77 @@ uniform float chunkMinHeight; uniform float distanceScaleFactor; uniform int chunkLevel; - struct PositionNormalPair { - vec3 position; - vec3 normal; + vec3 position; + vec3 normal; }; PositionNormalPair globalInterpolation(vec2 uv) { - vec2 lonlat = lonLatScalingFactor * uv + minLatLon; + vec2 lonlat = lonLatScalingFactor * uv + minLatLon; - // geodetic surface normal - float cosLat = cos(lonlat.y); - vec3 normal = vec3(cosLat * cos(lonlat.x), cosLat * sin(lonlat.x), sin(lonlat.y)); - vec3 k = radiiSquared * normal; - float gamma = sqrt(dot(k, normal)); + // geodetic surface normal + float cosLat = cos(lonlat.y); + vec3 normal = vec3(cosLat * cos(lonlat.x), cosLat * sin(lonlat.x), sin(lonlat.y)); + vec3 k = radiiSquared * normal; + float gamma = sqrt(dot(k, normal)); - PositionNormalPair result; - result.position = k / gamma; - result.normal = normal; - return result; + PositionNormalPair result; + result.position = k / gamma; + result.normal = normal; + return result; } vec3 getLevelWeights(float distToVertexOnEllipsoid) { - float projectedScaleFactor = distanceScaleFactor / distToVertexOnEllipsoid; - float desiredLevel = log2(projectedScaleFactor); - float levelInterp = chunkLevel - desiredLevel; + float projectedScaleFactor = distanceScaleFactor / distToVertexOnEllipsoid; + float desiredLevel = log2(projectedScaleFactor); + float levelInterp = chunkLevel - desiredLevel; - return vec3( - clamp(1.0 - levelInterp, 0.0, 1.0), - clamp(levelInterp, 0.0, 1.0) - clamp(levelInterp - 1.0, 0.0, 1.0), - clamp(levelInterp - 1.0, 0.0, 1.0) - ); + return vec3( + clamp(1.0 - levelInterp, 0.0, 1.0), + clamp(levelInterp, 0.0, 1.0) - clamp(levelInterp - 1.0, 0.0, 1.0), + clamp(levelInterp - 1.0, 0.0, 1.0) + ); } void main() { - PositionNormalPair pair = globalInterpolation(in_uv); - float distToVertexOnEllipsoid = length((pair.normal * chunkMinHeight + pair.position) - cameraPosition); + PositionNormalPair pair = globalInterpolation(in_uv); + float distToVertexOnEllipsoid = length((pair.normal * chunkMinHeight + pair.position) - cameraPosition); - // use level weight for height sampling, and output to fragment shader - levelWeights = getLevelWeights(distToVertexOnEllipsoid); + // use level weight for height sampling, and output to fragment shader + levelWeights = getLevelWeights(distToVertexOnEllipsoid); - // Get the height value and apply skirts - float height = getTileHeight(in_uv, levelWeights) - getTileVertexSkirtLength(); + // Get the height value and apply skirts + float height = getTileHeight(in_uv, levelWeights) - getTileVertexSkirtLength(); #if USE_ACCURATE_NORMALS - // Calculate tangents - // tileDelta is a step length (epsilon). Should be small enough for accuracy but not - // Too small for precision. 1 / 512 is good. - const float tileDelta = 1.0 / 512.0; - PositionNormalPair pair10 = globalInterpolation(vec2(1.0, 0.0) * tileDelta + in_uv); - PositionNormalPair pair01 = globalInterpolation(vec2(0.0, 1.0) * tileDelta + in_uv); - vec3 ellipsoidTangentTheta = normalize(pair10.position - pair.position); - vec3 ellipsoidTangentPhi = normalize(pair01.position - pair.position); - ellipsoidTangentThetaCameraSpace = mat3(modelViewTransform) * ellipsoidTangentTheta; - ellipsoidTangentPhiCameraSpace = mat3(modelViewTransform) * ellipsoidTangentPhi; + // Calculate tangents + // tileDelta is a step length (epsilon). Should be small enough for accuracy but not + // Too small for precision. 1 / 512 is good. + const float tileDelta = 1.0 / 512.0; + PositionNormalPair pair10 = globalInterpolation(vec2(1.0, 0.0) * tileDelta + in_uv); + PositionNormalPair pair01 = globalInterpolation(vec2(0.0, 1.0) * tileDelta + in_uv); + vec3 ellipsoidTangentTheta = normalize(pair10.position - pair.position); + vec3 ellipsoidTangentPhi = normalize(pair01.position - pair.position); + ellipsoidTangentThetaCameraSpace = mat3(modelViewTransform) * ellipsoidTangentTheta; + ellipsoidTangentPhiCameraSpace = mat3(modelViewTransform) * ellipsoidTangentPhi; #endif // USE_ACCURATE_NORMALS - // Add the height in the direction of the normal - pair.position = pair.normal * height + pair.position; - vec4 positionClippingSpace = modelViewProjectionTransform * vec4(pair.position, 1.0); + // Add the height in the direction of the normal + pair.position = pair.normal * height + pair.position; + vec4 positionClippingSpace = modelViewProjectionTransform * vec4(pair.position, 1.0); - // Write output - fs_uv = in_uv; - fs_position = z_normalization(positionClippingSpace); - gl_Position = fs_position; - ellipsoidNormalCameraSpace = mat3(modelViewTransform) * pair.normal; - positionCameraSpace = vec3(modelViewTransform * vec4(pair.position, 1.0)); + // Write output + fs_uv = in_uv; + fs_position = z_normalization(positionClippingSpace); + gl_Position = fs_position; + ellipsoidNormalCameraSpace = mat3(modelViewTransform) * pair.normal; + positionCameraSpace = vec3(modelViewTransform * vec4(pair.position, 1.0)); #if USE_ECLIPSE_SHADOWS - positionWorldSpace = vec3(modelTransform * dvec4(pair.position, 1.0)); -#endif + positionWorldSpace = vec3(modelTransform * dvec4(pair.position, 1.0)); +#endif // USE_ECLIPSE_SHADOWS #if SHADOW_MAPPING_ENABLED - shadowCoords = vec4(shadowMatrix * dvec4(pair.position, 1.0)); -#endif + shadowCoords = vec4(shadowMatrix * dvec4(pair.position, 1.0)); +#endif // SHADOW_MAPPING_ENABLED } diff --git a/modules/globebrowsing/shaders/localrenderer_vs.glsl b/modules/globebrowsing/shaders/localrenderer_vs.glsl index 5c1439139d..642a2a2ae4 100644 --- a/modules/globebrowsing/shaders/localrenderer_vs.glsl +++ b/modules/globebrowsing/shaders/localrenderer_vs.glsl @@ -25,10 +25,10 @@ #version __CONTEXT__ #include "PowerScaling/powerScaling_vs.hglsl" -#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl> -#include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.hglsl> -#include <${MODULE_GLOBEBROWSING}/shaders/tileheight.hglsl> -#include <${MODULE_GLOBEBROWSING}/shaders/tilevertexskirt.hglsl> +#include <${MODULE_GLOBEBROWSING}/shaders/tile.glsl> +#include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.glsl> +#include <${MODULE_GLOBEBROWSING}/shaders/tileheight.glsl> +#include <${MODULE_GLOBEBROWSING}/shaders/tilevertexskirt.glsl> layout(location = 1) in vec2 in_uv; @@ -39,22 +39,22 @@ out vec3 levelWeights; out vec3 positionCameraSpace; #if USE_ACCURATE_NORMALS - out vec3 ellipsoidTangentThetaCameraSpace; - out vec3 ellipsoidTangentPhiCameraSpace; + out vec3 ellipsoidTangentThetaCameraSpace; + out vec3 ellipsoidTangentPhiCameraSpace; #endif // USE_ACCURATE_NORMALS #if USE_ECLIPSE_SHADOWS out vec3 positionWorldSpace; uniform dmat4 inverseViewTransform; -#endif +#endif // USE_ECLIPSE_SHADOWS #if SHADOW_MAPPING_ENABLED - // ShadowMatrix is the matrix defined by: - // textureCoordsMatrix * projectionMatrix * combinedViewMatrix * modelMatrix - // where textureCoordsMatrix is just a scale and bias computation: [-1,1] to [0,1] - uniform dmat4 shadowMatrix; - out vec4 shadowCoords; -#endif + // ShadowMatrix is the matrix defined by: + // textureCoordsMatrix * projectionMatrix * combinedViewMatrix * modelMatrix + // where textureCoordsMatrix is just a scale and bias computation: [-1,1] to [0,1] + uniform dmat4 shadowMatrix; + out vec4 shadowCoords; +#endif // SHADOW_MAPPING_ENABLED uniform mat4 projectionTransform; // Input points in camera space @@ -69,60 +69,60 @@ uniform float distanceScaleFactor; uniform int chunkLevel; vec3 bilinearInterpolation(vec2 uv) { - vec3 p0 = mix(p00, p10, uv.x); - vec3 p1 = mix(p01, p11, uv.x); - return mix(p0, p1, uv.y); + vec3 p0 = mix(p00, p10, uv.x); + vec3 p1 = mix(p01, p11, uv.x); + return mix(p0, p1, uv.y); } vec3 getLevelWeights(float distToVertexOnEllipsoid) { - float projectedScaleFactor = distanceScaleFactor / distToVertexOnEllipsoid; - float desiredLevel = log2(projectedScaleFactor); - float levelInterp = chunkLevel - desiredLevel; + float projectedScaleFactor = distanceScaleFactor / distToVertexOnEllipsoid; + float desiredLevel = log2(projectedScaleFactor); + float levelInterp = chunkLevel - desiredLevel; - return vec3( - clamp(1.0 - levelInterp, 0.0, 1.0), - clamp(levelInterp, 0.0, 1.0) - clamp(levelInterp - 1.0, 0.0, 1.0), - clamp(levelInterp - 1.0, 0.0, 1.0) - ); + return vec3( + clamp(1.0 - levelInterp, 0.0, 1.0), + clamp(levelInterp, 0.0, 1.0) - clamp(levelInterp - 1.0, 0.0, 1.0), + clamp(levelInterp - 1.0, 0.0, 1.0) + ); } void main() { - // Position in cameraspace - vec3 p = bilinearInterpolation(in_uv); - - // Calculate desired level based on distance to the vertex on the ellipsoid - // Before any heightmapping is done - float distToVertexOnEllipsoid = length(p + patchNormalCameraSpace * chunkMinHeight); + // Position in cameraspace + vec3 p = bilinearInterpolation(in_uv); + + // Calculate desired level based on distance to the vertex on the ellipsoid + // Before any heightmapping is done + float distToVertexOnEllipsoid = length(p + patchNormalCameraSpace * chunkMinHeight); - // use level weight for height sampling, and output to fragment shader - levelWeights = getLevelWeights(distToVertexOnEllipsoid); + // use level weight for height sampling, and output to fragment shader + levelWeights = getLevelWeights(distToVertexOnEllipsoid); - // Get the height value and apply skirts - float height = getTileHeightScaled(in_uv, levelWeights) - getTileVertexSkirtLength(); - - // Translate the point along normal - p += patchNormalCameraSpace * height; + // Get the height value and apply skirts + float height = getTileHeightScaled(in_uv, levelWeights) - getTileVertexSkirtLength(); + + // Translate the point along normal + p += patchNormalCameraSpace * height; - vec4 positionClippingSpace = projectionTransform * vec4(p, 1); + vec4 positionClippingSpace = projectionTransform * vec4(p, 1); #if USE_ACCURATE_NORMALS - // Calculate tangents - ellipsoidTangentThetaCameraSpace = normalize(p10 - p00); - ellipsoidTangentPhiCameraSpace = normalize(p01 - p00); + // Calculate tangents + ellipsoidTangentThetaCameraSpace = normalize(p10 - p00); + ellipsoidTangentPhiCameraSpace = normalize(p01 - p00); #endif // USE_ACCURATE_NORMALS - // Write output - fs_uv = in_uv; - fs_position = z_normalization(positionClippingSpace); - gl_Position = fs_position; - ellipsoidNormalCameraSpace = patchNormalCameraSpace; - positionCameraSpace = p; + // Write output + fs_uv = in_uv; + fs_position = z_normalization(positionClippingSpace); + gl_Position = fs_position; + ellipsoidNormalCameraSpace = patchNormalCameraSpace; + positionCameraSpace = p; #if USE_ECLIPSE_SHADOWS - positionWorldSpace = vec3(inverseViewTransform * dvec4(p, 1.0)); -#endif + positionWorldSpace = vec3(inverseViewTransform * dvec4(p, 1.0)); +#endif // USE_ECLIPSE_SHADOWS #if SHADOW_MAPPING_ENABLED - shadowCoords = vec4(shadowMatrix * dvec4(p, 1.0)); -#endif + shadowCoords = vec4(shadowMatrix * dvec4(p, 1.0)); +#endif // SHADOW_MAPPING_ENABLED } diff --git a/modules/globebrowsing/shaders/renderer_fs.glsl b/modules/globebrowsing/shaders/renderer_fs.glsl index 07ba765e6c..c02fe78d19 100644 --- a/modules/globebrowsing/shaders/renderer_fs.glsl +++ b/modules/globebrowsing/shaders/renderer_fs.glsl @@ -24,9 +24,9 @@ #include "fragment.glsl" -#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl> -#include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.hglsl> -#include <${MODULE_GLOBEBROWSING}/shaders/tileheight.hglsl> +#include <${MODULE_GLOBEBROWSING}/shaders/tile.glsl> +#include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.glsl> +#include <${MODULE_GLOBEBROWSING}/shaders/tileheight.glsl> #include "PowerScaling/powerScaling_fs.hglsl" // Below are all the tiles that are used for contributing the actual fragment color @@ -49,15 +49,13 @@ uniform Layer WaterMasks[NUMLAYERS_WATERMASK]; #if SHOW_HEIGHT_RESOLUTION uniform vec2 vertexResolution; -#endif +#endif // SHOW_HEIGHT_RESOLUTION -//#if USE_NIGHTTEXTURE || USE_WATERMASK || PERFORM_SHADING uniform vec3 lightDirectionCameraSpace; -//#endif #if PERFORM_SHADING uniform float orenNayarRoughness; -#endif +#endif // PERFORM_SHADING #if SHADOW_MAPPING_ENABLED @@ -67,23 +65,22 @@ uniform float orenNayarRoughness; in vec4 shadowCoords; uniform sampler2DShadow shadowMapTexture; uniform float zFightingPercentage; -#endif +#endif // SHADOW_MAPPING_ENABLED #if USE_ECLIPSE_SHADOWS - #define NSEclipseShadowsMinusOne #{nEclipseShadows} #define NSEclipseShadows (NSEclipseShadowsMinusOne + 1) /******************************************************************************* - ***** ALL CALCULATIONS FOR ECLIPSE ARE IN METERS AND IN WORLD SPACE SYSTEM **** - *******************************************************************************/ + ***** ALL CALCULATIONS FOR ECLIPSE ARE IN METERS AND IN WORLD SPACE SYSTEM **** + *******************************************************************************/ struct ShadowRenderingStruct { - double xu, xp; - double rs, rc; - dvec3 sourceCasterVec; - dvec3 casterPositionVec; - bool isShadowing; + double xu, xp; + double rs, rc; + dvec3 sourceCasterVec; + dvec3 casterPositionVec; + bool isShadowing; }; // Eclipse shadow data @@ -96,48 +93,46 @@ uniform bool hardShadows; vec4 calcShadow(const ShadowRenderingStruct shadowInfoArray[NSEclipseShadows], const dvec3 position, const bool ground) { - #for i in 0..#{nEclipseShadows} - if (shadowInfoArray[#{i}].isShadowing) { - dvec3 pc = shadowInfoArray[#{i}].casterPositionVec - position; - dvec3 sc_norm = shadowInfoArray[#{i}].sourceCasterVec; - dvec3 pc_proj = dot(pc, sc_norm) * sc_norm; - dvec3 d = pc - pc_proj; + #for i in 0..#{nEclipseShadows} + if (shadowInfoArray[#{i}].isShadowing) { + dvec3 pc = shadowInfoArray[#{i}].casterPositionVec - position; + dvec3 sc_norm = shadowInfoArray[#{i}].sourceCasterVec; + dvec3 pc_proj = dot(pc, sc_norm) * sc_norm; + dvec3 d = pc - pc_proj; + float length_d = float(length(d)); + double length_pc_proj = length(pc_proj); - float length_d = float(length(d)); - double length_pc_proj = length(pc_proj); + float r_p_pi = float(shadowInfoArray[#{i}].rc * (length_pc_proj + shadowInfoArray[#{i}].xp) / shadowInfoArray[#{i}].xp); + float r_u_pi = float(shadowInfoArray[#{i}].rc * (shadowInfoArray[#{i}].xu - length_pc_proj) / shadowInfoArray[#{i}].xu); - float r_p_pi = float(shadowInfoArray[#{i}].rc * (length_pc_proj + shadowInfoArray[#{i}].xp) / shadowInfoArray[#{i}].xp); - float r_u_pi = float(shadowInfoArray[#{i}].rc * (shadowInfoArray[#{i}].xu - length_pc_proj) / shadowInfoArray[#{i}].xu); - - if (length_d < r_u_pi) { // umbra - if (ground) { - #if USE_ECLIPSE_HARD_SHADOWS - return vec4(0.2, 0.2, 0.2, 1.0); - #else - // butterworthFunc - return vec4(vec3(sqrt(r_u_pi / (r_u_pi + pow(length_d, 2.0)))), 1.0); - #endif - } - else { - #if USE_ECLIPSE_HARD_SHADOWS - return vec4(0.5, 0.5, 0.5, 1.0); - #else - return vec4(vec3(length_d / r_p_pi), 1.0); - #endif - } - } - else if (length_d < r_p_pi) {// penumbra - #if USE_ECLIPSE_HARD_SHADOWS - return vec4(0.5, 0.5, 0.5, 1.0); - #else - return vec4(vec3(length_d / r_p_pi), 1.0); - #endif - } + if (length_d < r_u_pi) { // umbra + if (ground) { +#if USE_ECLIPSE_HARD_SHADOWS + return vec4(0.2, 0.2, 0.2, 1.0); +#else + // butterworthFunc + return vec4(vec3(sqrt(r_u_pi / (r_u_pi + pow(length_d, 2.0)))), 1.0); +#endif } - - #endfor - return vec4(1.0); + else { +#if USE_ECLIPSE_HARD_SHADOWS + return vec4(0.5, 0.5, 0.5, 1.0); +#else + return vec4(vec3(length_d / r_p_pi), 1.0); +#endif + } + } + else if (length_d < r_p_pi) {// penumbra +#if USE_ECLIPSE_HARD_SHADOWS + return vec4(0.5, 0.5, 0.5, 1.0); +#else + return vec4(vec3(length_d / r_p_pi), 1.0); +#endif + } + } + #endfor + return vec4(1.0); } #endif @@ -148,8 +143,8 @@ in vec3 levelWeights; in vec3 positionCameraSpace; #if USE_ACCURATE_NORMALS - in vec3 ellipsoidTangentThetaCameraSpace; - in vec3 ellipsoidTangentPhiCameraSpace; + in vec3 ellipsoidTangentThetaCameraSpace; + in vec3 ellipsoidTangentPhiCameraSpace; #endif // USE_ACCURATE_NORMALS #if USE_ECLIPSE_SHADOWS @@ -158,146 +153,142 @@ in vec3 positionWorldSpace; uniform float opacity; - Fragment getFragment() { - Fragment frag; - frag.color = vec4(0.3, 0.3, 0.3, 1.0); + Fragment frag; + frag.color = vec4(0.3, 0.3, 0.3, 1.0); - vec3 normal = normalize(ellipsoidNormalCameraSpace); + vec3 normal = normalize(ellipsoidNormalCameraSpace); #if USE_ACCURATE_NORMALS - normal = getTileNormal( - fs_uv, - levelWeights, - normalize(ellipsoidNormalCameraSpace), - normalize(ellipsoidTangentThetaCameraSpace), - normalize(ellipsoidTangentPhiCameraSpace) - ); + normal = getTileNormal( + fs_uv, + levelWeights, + normalize(ellipsoidNormalCameraSpace), + normalize(ellipsoidTangentThetaCameraSpace), + normalize(ellipsoidTangentPhiCameraSpace) + ); #endif /// USE_ACCURATE_NORMALS #if USE_COLORTEXTURE - frag.color = calculateColor(frag.color, fs_uv, levelWeights, ColorLayers); + frag.color = calculateColor(frag.color, fs_uv, levelWeights, ColorLayers); #endif // USE_COLORTEXTURE #if USE_WATERMASK - float waterReflectance = 0.0; - frag.color = calculateWater( - frag.color, - fs_uv, - levelWeights, - WaterMasks, - normal, - lightDirectionCameraSpace, // Should already be normalized - positionCameraSpace, - waterReflectance - ); - + float waterReflectance = 0.0; + frag.color = calculateWater( + frag.color, + fs_uv, + levelWeights, + WaterMasks, + normal, + lightDirectionCameraSpace, // Should already be normalized + positionCameraSpace, + waterReflectance + ); #endif // USE_WATERMASK #if USE_NIGHTTEXTURE - frag.color = calculateNight( - frag.color, - fs_uv, - levelWeights, - NightLayers, - normalize(ellipsoidNormalCameraSpace), - lightDirectionCameraSpace // Should already be normalized - ); - + frag.color = calculateNight( + frag.color, + fs_uv, + levelWeights, + NightLayers, + normalize(ellipsoidNormalCameraSpace), + lightDirectionCameraSpace // Should already be normalized + ); #endif // USE_NIGHTTEXTURE #if PERFORM_SHADING - frag.color = calculateShadedColor( - frag.color, - normal, - lightDirectionCameraSpace, - normalize(positionCameraSpace), - orenNayarRoughness - ); + frag.color = calculateShadedColor( + frag.color, + normal, + lightDirectionCameraSpace, + normalize(positionCameraSpace), + orenNayarRoughness + ); #endif // PERFORM_SHADING #if USE_ECLIPSE_SHADOWS - frag.color *= calcShadow(shadowDataArray, dvec3(positionWorldSpace), true); -#endif + frag.color *= calcShadow(shadowDataArray, dvec3(positionWorldSpace), true); +#endif // USE_ECLIPSE_SHADOWS #if USE_OVERLAY - frag.color = calculateOverlay(frag.color, fs_uv, levelWeights, Overlays); + frag.color = calculateOverlay(frag.color, fs_uv, levelWeights, Overlays); #endif // USE_OVERLAY #if SHOW_HEIGHT_INTENSITIES - frag.color.rgb *= vec3(0.1); + frag.color.rgb *= vec3(0.1); - float untransformedHeight = getUntransformedTileVertexHeight(fs_uv, levelWeights); - float contourLine = fract(10.0 * untransformedHeight) > 0.98 ? 1.0 : 0.0; - frag.color.r += untransformedHeight; - frag.color.b = contourLine; -#endif + float untransformedHeight = getUntransformedTileVertexHeight(fs_uv, levelWeights); + float contourLine = fract(10.0 * untransformedHeight) > 0.98 ? 1.0 : 0.0; + frag.color.r += untransformedHeight; + frag.color.b = contourLine; +#endif // SHOW_HEIGHT_INTENSITIES #if SHOW_HEIGHT_RESOLUTION - frag.color += 0.0001 * calculateDebugColor(fs_uv, fs_position, vertexResolution); - #if USE_HEIGHTMAP - frag.color.r = min(frag.color.r, 0.8); - frag.color.r += tileResolution(fs_uv, HeightLayers[0].pile.chunkTile0) > 0.9 ? 1 : 0; - #endif -#endif + frag.color += 0.0001 * calculateDebugColor(fs_uv, fs_position, vertexResolution); + #if USE_HEIGHTMAP + frag.color.r = min(frag.color.r, 0.8); + frag.color.r += tileResolution(fs_uv, HeightLayers[0].pile.chunkTile0) > 0.9 ? 1 : 0; + #endif // USE_HEIGHTMAP +#endif // SHOW_HEIGHT_RESOLUTION - // Other data + // Other data #if USE_WATERMASK - // Water reflectance is added to the G-Buffer. - frag.gNormal.w = waterReflectance; + // Water reflectance is added to the G-Buffer. + frag.gNormal.w = waterReflectance; #else - frag.gNormal.w = 0.0; + frag.gNormal.w = 0.0; #endif - // Normal is written View Space (Including SGCT View Matrix). - frag.gNormal.xyz = normal; + // Normal is written View Space (Including SGCT View Matrix). + frag.gNormal.xyz = normal; - if (dot(positionCameraSpace, vec3(1.0)) != 0.0) { - frag.gPosition = vec4(positionCameraSpace, 1.0); // in Camera Rig Space - } - else { - frag.gPosition = vec4(1.0); // in Camera Rig Space - } + if (dot(positionCameraSpace, vec3(1.0)) != 0.0) { + frag.gPosition = vec4(positionCameraSpace, 1.0); // in Camera Rig Space + } + else { + frag.gPosition = vec4(1.0); // in Camera Rig Space + } - frag.depth = fs_position.w; + frag.depth = fs_position.w; #if SHOW_CHUNK_EDGES - const float BorderSize = 0.005; - const vec3 BorderColor = vec3(1.0, 0.0, 0.0); + const float BorderSize = 0.005; + const vec3 BorderColor = vec3(1.0, 0.0, 0.0); - vec2 uvOffset = fs_uv - vec2(0.5); - float thres = 0.5 - BorderSize * 0.5; - bool isBorder = abs(uvOffset.x) > thres || abs(uvOffset.y) > thres; - if (isBorder) { - frag.color.rgb += BorderColor; - } + vec2 uvOffset = fs_uv - vec2(0.5); + float thres = 0.5 - BorderSize * 0.5; + bool isBorder = abs(uvOffset.x) > thres || abs(uvOffset.y) > thres; + if (isBorder) { + frag.color.rgb += BorderColor; + } #endif // SHOW_CHUNK_EDGES #if SHADOW_MAPPING_ENABLED - float shadow = 1.0; - if (shadowCoords.w > 1) { - vec4 normalizedShadowCoords = shadowCoords; - normalizedShadowCoords.z = normalizeFloat(zFightingPercentage * normalizedShadowCoords.w); - normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; - normalizedShadowCoords.w = 1.0; + float shadow = 1.0; + if (shadowCoords.w > 1) { + vec4 normalizedShadowCoords = shadowCoords; + normalizedShadowCoords.z = normalizeFloat(zFightingPercentage * normalizedShadowCoords.w); + normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; + normalizedShadowCoords.w = 1.0; - float sum = 0; - #for i in 0..#{nShadowSamples} - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, -NSSamples + #{i})); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, 0)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, NSSamples - #{i})); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , -NSSamples + #{i})); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , NSSamples - #{i})); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, -NSSamples + #{i})); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, 0)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, NSSamples - #{i})); - #endfor - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0)); - shadow = sum / (8.0 * NSSamples + 1.f); - } - frag.color.xyz *= shadow < 0.99 ? clamp(shadow + 0.3, 0.0, 1.0) : shadow; + float sum = 0; + #for i in 0..#{nShadowSamples} + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, -NSSamples + #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, NSSamples - #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , -NSSamples + #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , NSSamples - #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, -NSSamples + #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, NSSamples - #{i})); + #endfor + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0)); + shadow = sum / (8.0 * NSSamples + 1.f); + } + frag.color.xyz *= shadow < 0.99 ? clamp(shadow + 0.3, 0.0, 1.0) : shadow; #endif - frag.color.a *= opacity; - - return frag; + frag.color.a *= opacity; + return frag; } diff --git a/modules/globebrowsing/shaders/rings_fs.glsl b/modules/globebrowsing/shaders/rings_fs.glsl index d3fb2bc9e4..128ac8b687 100644 --- a/modules/globebrowsing/shaders/rings_fs.glsl +++ b/modules/globebrowsing/shaders/rings_fs.glsl @@ -38,91 +38,82 @@ uniform vec2 textureOffset; uniform float colorFilterValue; uniform vec3 sunPosition; -uniform float _nightFactor; +uniform float nightFactor; uniform float zFightingPercentage; -// temp -in vec4 fragPosInLightSpace; - - Fragment getFragment() { - // Moving the origin to the center - vec2 st = (vs_st - vec2(0.5)) * 2.0; + // Moving the origin to the center + vec2 st = (vs_st - vec2(0.5)) * 2.0; - // The length of the texture coordinates vector is our distance from the center - float radius = length(st); + // The length of the texture coordinates vector is our distance from the center + float radius = length(st); - // We only want to consider ring-like objects so we need to discard everything else - if (radius > 1.0) { - discard; + // We only want to consider ring-like objects so we need to discard everything else + if (radius > 1.0) { + discard; + } + + // Remapping the texture coordinates + // Radius \in [0,1], texCoord \in [textureOffset.x, textureOffset.y] + // textureOffset.x -> 0 + // textureOffset.y -> 1 + float texCoord = (radius - textureOffset.x) / (textureOffset.y - textureOffset.x); + if (texCoord < 0.0 || texCoord > 1.0) { + discard; + } + + vec4 diffuse = texture(ringTexture, texCoord); + // divided by 3 as length of vec3(1.0, 1.0, 1.0) will return 3 and we want + // to normalize the alpha value to [0,1] + float colorValue = length(diffuse.rgb) / 3.0; + if (colorValue < colorFilterValue) { + diffuse.a = colorValue * colorFilterValue; + if (diffuse.a < 0.65) { + discard; } - - // Remapping the texture coordinates - // Radius \in [0,1], texCoord \in [textureOffset.x, textureOffset.y] - // textureOffset.x -> 0 - // textureOffset.y -> 1 - float texCoord = (radius - textureOffset.x) / (textureOffset.y - textureOffset.x); - if (texCoord < 0.f || texCoord > 1.f) { - discard; - } - - vec4 diffuse = texture(ringTexture, texCoord); - // divided by 3 as length of vec3(1.0, 1.0, 1.0) will return 3 and we want - // to normalize the alpha value to [0,1] - float colorValue = length(diffuse.rgb) / 3.0; - if (colorValue < colorFilterValue) { - diffuse.a = colorValue * colorFilterValue; - if (diffuse.a < 0.65) - discard; - } - - // shadow == 1.0 means it is not in shadow - float shadow = 1.0; - if (shadowCoords.z >= 0) { - vec4 normalizedShadowCoords = shadowCoords; - normalizedShadowCoords.z = normalizeFloat(zFightingPercentage * normalizedShadowCoords.w); - normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; - normalizedShadowCoords.w = 1.0; - - float sum = 0; - #for i in 0..#{nShadowSamples} - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, -NSSamples + #{i})); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, 0)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, NSSamples - #{i})); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , -NSSamples + #{i})); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , NSSamples - #{i})); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, -NSSamples + #{i})); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, 0)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, NSSamples - #{i})); - #endfor - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0)); - shadow = clamp(sum / (8.0 * NSSamples + 1.f), 0.35, 1.0); - } - - // The normal for the one plane depends on whether we are dealing - // with a front facing or back facing fragment - vec3 normal; - // The plane is oriented on the xz plane - // WARNING: This might not be the case for Uranus - if (gl_FrontFacing) { - normal = vec3(-1.0, 0.0, 0.0); - } - else { - normal = vec3(1.0, 0.0, 0.0); - } - - // Reduce the color of the fragment by the user factor - // if we are facing away from the Sun - if (dot(sunPosition, normal) < 0) { - diffuse.xyz *= _nightFactor; - } - - Fragment frag; - - frag.color = diffuse * shadow; - frag.depth = vs_screenSpaceDepth; - frag.gPosition = vec4(1e30, 1e30, 1e30, 1.0); - frag.gNormal = vec4(normal, 1.0); - - return frag; +} + + // shadow == 1.0 means it is not in shadow + float shadow = 1.0; + if (shadowCoords.z >= 0) { + vec4 normalizedShadowCoords = shadowCoords; + normalizedShadowCoords.z = normalizeFloat(zFightingPercentage * normalizedShadowCoords.w); + normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; + normalizedShadowCoords.w = 1.0; + + float sum = 0; + #for i in 0..#{nShadowSamples} + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, -NSSamples + #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, NSSamples - #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , -NSSamples + #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , NSSamples - #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, -NSSamples + #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, NSSamples - #{i})); + #endfor + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0)); + shadow = clamp(sum / (8.0 * NSSamples + 1.0), 0.35, 1.0); + } + + // The normal for the one plane depends on whether we are dealing + // with a front facing or back facing fragment + // The plane is oriented on the xz plane + // WARNING: This might not be the case for Uranus + vec3 normal = gl_FrontFacing ? vec3(-1.0, 0.0, 0.0) : vec3(1.0, 0.0, 0.0); + + // Reduce the color of the fragment by the user factor + // if we are facing away from the Sun + if (dot(sunPosition, normal) < 0.0) { + diffuse.xyz *= _nightFactor; + } + + Fragment frag; + + frag.color = diffuse * shadow; + frag.depth = vs_screenSpaceDepth; + frag.gPosition = vec4(1e30, 1e30, 1e30, 1.0); + frag.gNormal = vec4(normal, 1.0); + + return frag; } diff --git a/modules/globebrowsing/shaders/rings_geom_fs.glsl b/modules/globebrowsing/shaders/rings_geom_fs.glsl index 6d2126b842..0eaa13a96f 100644 --- a/modules/globebrowsing/shaders/rings_geom_fs.glsl +++ b/modules/globebrowsing/shaders/rings_geom_fs.glsl @@ -32,43 +32,43 @@ uniform sampler1D ringTexture; uniform vec2 textureOffset; Fragment getFragment() { - // Moving the origin to the center - vec2 st = (vs_st - vec2(0.5)) * 2.0; + // Moving the origin to the center + vec2 st = (vs_st - vec2(0.5)) * 2.0; - // The length of the texture coordinates vector is our distance from the center - float radius = length(st); + // The length of the texture coordinates vector is our distance from the center + float radius = length(st); - // We only want to consider ring-like objects so we need to discard everything else - if (radius > 1.0) { - discard; - } + // We only want to consider ring-like objects so we need to discard everything else + if (radius > 1.0) { + discard; + } - // Remapping the texture coordinates - // Radius \in [0,1], texCoord \in [textureOffset.x, textureOffset.y] - // textureOffset.x -> 0 - // textureOffset.y -> 1 - float texCoord = (radius - textureOffset.x) / (textureOffset.y - textureOffset.x); - if (texCoord < 0.f || texCoord > 1.f) { - discard; - } + // Remapping the texture coordinates + // Radius \in [0,1], texCoord \in [textureOffset.x, textureOffset.y] + // textureOffset.x -> 0 + // textureOffset.y -> 1 + float texCoord = (radius - textureOffset.x) / (textureOffset.y - textureOffset.x); + if (texCoord < 0.0 || texCoord > 1.0) { + discard; + } - float diffuse = length(texture(ringTexture, texCoord).rgb); - - // The normal for the one plane depends on whether we are dealing - // with a front facing or back facing fragment - //vec3 normal; - // The plane is oriented on the xz plane - // WARNING: This might not be the case for Uranus - // if (gl_FrontFacing) { - // normal = vec3(-1.0, 0.0, 0.0); - // } - // else { - // normal = vec3(1.0, 0.0, 0.0); - // } + float diffuse = length(texture(ringTexture, texCoord).rgb); + + // The normal for the one plane depends on whether we are dealing + // with a front facing or back facing fragment + //vec3 normal; + // The plane is oriented on the xz plane + // WARNING: This might not be the case for Uranus + // if (gl_FrontFacing) { + // normal = vec3(-1.0, 0.0, 0.0); + // } + // else { + // normal = vec3(1.0, 0.0, 0.0); + // } - Fragment frag; - frag.color = vec4(vec3(vs_screenSpaceDepth), 1.0); - frag.depth = (diffuse < 0.5) ? 1E30 : vs_screenSpaceDepth; - - return frag; + Fragment frag; + frag.color = vec4(vec3(vs_screenSpaceDepth), 1.0); + frag.depth = (diffuse < 0.5) ? 1E30 : vs_screenSpaceDepth; + + return frag; } diff --git a/modules/globebrowsing/shaders/rings_geom_vs.glsl b/modules/globebrowsing/shaders/rings_geom_vs.glsl index 7698109c5b..2c18bd7fe2 100644 --- a/modules/globebrowsing/shaders/rings_geom_vs.glsl +++ b/modules/globebrowsing/shaders/rings_geom_vs.glsl @@ -35,13 +35,10 @@ out float vs_screenSpaceDepth; uniform dmat4 modelViewProjectionMatrix; void main() { - vs_st = in_st; + vs_st = in_st; - dvec4 positionClipSpace = modelViewProjectionMatrix * - dvec4(in_position, 0.0, 1.0); - vec4 positionClipSpaceZNorm = z_normalization(vec4(positionClipSpace)); - - vs_screenSpaceDepth = positionClipSpaceZNorm.w; - - gl_Position = positionClipSpaceZNorm; + dvec4 positionClipSpace = modelViewProjectionMatrix * dvec4(in_position, 0.0, 1.0); + vec4 positionClipSpaceZNorm = z_normalization(vec4(positionClipSpace)); + vs_screenSpaceDepth = positionClipSpaceZNorm.w; + gl_Position = positionClipSpaceZNorm; } diff --git a/modules/globebrowsing/shaders/rings_vs.glsl b/modules/globebrowsing/shaders/rings_vs.glsl index 8b43a60571..5d58c668c9 100644 --- a/modules/globebrowsing/shaders/rings_vs.glsl +++ b/modules/globebrowsing/shaders/rings_vs.glsl @@ -31,7 +31,6 @@ layout(location = 1) in vec2 in_st; out vec2 vs_st; out float vs_screenSpaceDepth; -out vec4 vs_positionViewSpace; out vec4 shadowCoords; uniform dmat4 modelViewProjectionMatrix; @@ -42,12 +41,12 @@ uniform dmat4 modelViewProjectionMatrix; uniform dmat4 shadowMatrix; void main() { - vs_st = in_st; + vs_st = in_st; - dvec4 positionClipSpace = modelViewProjectionMatrix * dvec4(in_position, 0.0, 1.0); - vec4 positionClipSpaceZNorm = z_normalization(vec4(positionClipSpace)); - - shadowCoords = vec4(shadowMatrix * dvec4(in_position, 0.0, 1.0)); - vs_screenSpaceDepth = positionClipSpaceZNorm.w; - gl_Position = positionClipSpaceZNorm; + dvec4 positionClipSpace = modelViewProjectionMatrix * dvec4(in_position, 0.0, 1.0); + vec4 positionClipSpaceZNorm = z_normalization(vec4(positionClipSpace)); + + shadowCoords = vec4(shadowMatrix * dvec4(in_position, 0.0, 1.0)); + vs_screenSpaceDepth = positionClipSpaceZNorm.w; + gl_Position = positionClipSpaceZNorm; } diff --git a/modules/globebrowsing/shaders/smviewer_fs.glsl b/modules/globebrowsing/shaders/smviewer_fs.glsl deleted file mode 100644 index 56d518a85e..0000000000 --- a/modules/globebrowsing/shaders/smviewer_fs.glsl +++ /dev/null @@ -1,40 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#include "PowerScaling/powerScaling_fs.hglsl" -#include "fragment.glsl" - -precision highp float; - -in vec2 texCoord; - -uniform highp sampler2D shadowMapTexture; - -Fragment getFragment() { - Fragment frag; - frag.color = vec4(vec3(1.f) - texture(shadowMapTexture, texCoord).rrr, 1.f); - frag.depth = 0.f; - - return frag; -} diff --git a/modules/globebrowsing/shaders/smviewer_vs.glsl b/modules/globebrowsing/shaders/smviewer_vs.glsl deleted file mode 100644 index 208ce361c4..0000000000 --- a/modules/globebrowsing/shaders/smviewer_vs.glsl +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version __CONTEXT__ - -out vec2 texCoord; - -const vec3 posData[6] = vec3[] ( - vec3(1.0, -0.5, 0.0), - vec3(0.5, -0.5, 0.0), - vec3(0.5, -1.0, 0.0), - vec3(1.0, -1.0, 0.0), - vec3(1.0, -0.5, 0.0), - vec3(0.5, -1.0, 0.0) -); - -const vec2 texData[6] = vec2[] ( - vec2(1.0, 1.0), - vec2(0.0, 1.0), - vec2(0.0, 0.0), - vec2(1.0, 0.0), - vec2(1.0, 1.0), - vec2(0.0, 0.0) - -); - -void main() { - texCoord = texData[gl_VertexID]; - gl_Position = vec4(posData[gl_VertexID], 1.0); -} diff --git a/modules/globebrowsing/shaders/texturetilemapping.glsl b/modules/globebrowsing/shaders/texturetilemapping.glsl new file mode 100644 index 0000000000..5b39d02c42 --- /dev/null +++ b/modules/globebrowsing/shaders/texturetilemapping.glsl @@ -0,0 +1,457 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2021 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef TEXTURETILEMAPPING_HGLSL +#define TEXTURETILEMAPPING_HGLSL + +#include <${MODULE_GLOBEBROWSING}/shaders/tile.glsl> +#include <${MODULE_GLOBEBROWSING}/shaders/blending.glsl> + +// First layer type from LayerShaderManager is height map +#define NUMLAYERS_HEIGHTMAP #{lastLayerIndexHeightLayers} + 1 +#define USE_HEIGHTMAP #{useHeightLayers} +#define HEIGHTMAP_BLENDING_ENABLED #{blendHeightLayers} + +// Second layer type from LayerShaderManager is color texture +#define NUMLAYERS_COLORTEXTURE #{lastLayerIndexColorLayers} + 1 +#define USE_COLORTEXTURE #{useColorLayers} +#define COLORTEXTURE_BLENDING_ENABLED #{blendColorLayers} + + // Third layer type from LayerShaderManager is water mask +#define NUMLAYERS_WATERMASK #{lastLayerIndexWaterMasks} + 1 +#define USE_WATERMASK #{useWaterMasks} +#define WATERMASK_BLENDING_ENABLED #{blendWaterMasks} + +// Fourth layer type from LayerShaderManager is night texture +#define NUMLAYERS_NIGHTTEXTURE #{lastLayerIndexNightLayers} + 1 +#define USE_NIGHTTEXTURE #{useNightLayers} +#define NIGHTTEXTURE_BLENDING_ENABLED #{blendNightLayers} + +// Fifth layer type from LayerShaderManager is overlay +#define NUMLAYERS_OVERLAY #{lastLayerIndexOverlays} + 1 +#define USE_OVERLAY #{useOverlays} +#define OVERLAY_BLENDING_ENABLED #{blendOverlays} + +// Global constants +#define CHUNK_DEFAULT_HEIGHT #{defaultHeight} + +// Other key value pairs used for settings +#define USE_ACCURATE_NORMALS #{useAccurateNormals} +#define PERFORM_SHADING #{performShading} +#define USE_ECLIPSE_SHADOWS #{useEclipseShadows} +#define USE_ECLIPSE_HARD_SHADOWS #{useEclipseHardShadows} +#define SHOW_CHUNK_EDGES #{showChunkEdges} +#define SHOW_HEIGHT_RESOLUTION #{showHeightResolution} +#define SHOW_HEIGHT_INTENSITIES #{showHeightIntensities} +#define SHADOW_MAPPING_ENABLED #{enableShadowMapping} + +const vec3 DefaultLevelWeights = vec3(1.0, 0.0, 0.0); + +float orenNayarDiffuse(vec3 lightDirection, vec3 viewDirection, vec3 surfaceNormal, + float roughness) +{ + // calculate intermediary values + float NdotL = dot(surfaceNormal, lightDirection); + float NdotV = dot(surfaceNormal, viewDirection); + + float angleVN = acos(NdotV); + float angleLN = acos(NdotL); + + float alpha = max(angleVN, angleLN); + float beta = min(angleVN, angleLN); + float gamma = dot( + viewDirection - surfaceNormal * dot(viewDirection, surfaceNormal), + lightDirection - surfaceNormal * dot(lightDirection, surfaceNormal) + ); + + float roughnessSquared = roughness * roughness; + + // calculate A and B + float A = 1.0 - 0.5 * (roughnessSquared / (roughnessSquared + 0.57)); + float B = 0.45 * (roughnessSquared / (roughnessSquared + 0.09)); + float C = sin(alpha) * tan(beta); + + // put it all together + return max(0.0, NdotL) * (A + B * max(0.0, gamma) * C); +} + +float performLayerSettings(float value, LayerSettings settings) { + float v = pow(abs(value), settings.gamma) * settings.multiplier + settings.offset; + return sign(value) * v * settings.opacity; +} + +vec4 performLayerSettings(vec4 currentValue, LayerSettings settings) { + vec3 newValue = sign(currentValue.rgb) * pow(abs(currentValue.rgb), vec3(settings.gamma)) * + settings.multiplier + settings.offset; + return vec4(newValue, currentValue.a * settings.opacity); +} + +vec2 tileUVToTextureSamplePosition(ChunkTile chunkTile, vec2 tileUV, PixelPadding padding) +{ + vec2 uv = chunkTile.uvTransform.uvOffset + chunkTile.uvTransform.uvScale * tileUV; + + // compensateSourceTextureSampling + ivec2 resolution = textureSize(chunkTile.textureSampler, 0); + vec2 sourceSize = vec2(resolution) + padding.sizeDifference; + vec2 currentSize = vec2(resolution); + vec2 sourceToCurrentSize = currentSize / sourceSize; + return sourceToCurrentSize * (uv - padding.startOffset / sourceSize); +} + +vec4 getTexVal(ChunkTilePile chunkTilePile, vec3 w, vec2 uv, PixelPadding padding) { + vec4 v1 = texture( + chunkTilePile.chunkTile0.textureSampler, + tileUVToTextureSamplePosition(chunkTilePile.chunkTile0, uv, padding) + ); + vec4 v2 = texture( + chunkTilePile.chunkTile1.textureSampler, + tileUVToTextureSamplePosition(chunkTilePile.chunkTile1, uv, padding) + ); + vec4 v3 = texture( + chunkTilePile.chunkTile2.textureSampler, + tileUVToTextureSamplePosition(chunkTilePile.chunkTile2, uv, padding) + ); + + return w.x * v1 + w.y * v2 + w.z * v3; +} + +#for id, layerGroup in layerGroups +#for i in 0..#{lastLayerIndex#{layerGroup}} + +vec4 getSample#{layerGroup}#{i}(vec2 uv, vec3 levelWeights, + Layer #{layerGroup}[#{lastLayerIndex#{layerGroup}} + 1]) +{ + vec4 c = vec4(0.0, 0.0, 0.0, 1.0); + + // All tile layers are the same. Sample from texture +#if (#{#{layerGroup}#{i}LayerType} == 0) // DefaultTileLayer + c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding); +#elif (#{#{layerGroup}#{i}LayerType} == 1) // SingleImageTileLayer + c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding); +#elif (#{#{layerGroup}#{i}LayerType} == 2) // SizeReferenceTileLayer + c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding); +#elif (#{#{layerGroup}#{i}LayerType} == 3) // TemporalTileLayer + c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding); +#elif (#{#{layerGroup}#{i}LayerType} == 4) // TileIndexTileLayer + c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding); +#elif (#{#{layerGroup}#{i}LayerType} == 5) // ByIndexTileLayer + c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding); +#elif (#{#{layerGroup}#{i}LayerType} == 6) // ByLevelTileLayer + c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding); +#elif (#{#{layerGroup}#{i}LayerType} == 7) // SolidColor + c.rgb = #{layerGroup}[#{i}].color; +#endif + + return c; +} + +#endfor +#endfor + +#define BlendModeDefault 0 +#define BlendModeMultiply 1 +#define BlendModeAdd 2 +#define BlendModeSubtract 3 +#define BlendModeColor 4 + +#for id, layerGroup in layerGroups +#for i in 0..#{lastLayerIndex#{layerGroup}} + +vec4 blend#{layerGroup}#{i}(vec4 currentColor, vec4 newColor, float blendFactor) { +#if (#{#{layerGroup}#{i}BlendMode} == BlendModeDefault) + return blendNormal(currentColor, vec4(newColor.rgb, newColor.a * blendFactor)); +#elif (#{#{layerGroup}#{i}BlendMode} == BlendModeMultiply) + return blendMultiply(currentColor, newColor * blendFactor); +#elif (#{#{layerGroup}#{i}BlendMode} == BlendModeAdd) + return blendAdd(currentColor, newColor * blendFactor); +#elif (#{#{layerGroup}#{i}BlendMode} == BlendModeSubtract) + return blendSubtract(currentColor, newColor * blendFactor); +#elif (#{#{layerGroup}#{i}BlendMode} == BlendModeColor) + // Convert color to grayscale + float gray = (newColor.r + newColor.g + newColor.b) / 3.0; + + vec3 hsvCurrent = rgb2hsv(currentColor.rgb); + // Use gray from new color as value in hsv + vec3 hsvNew = vec3(hsvCurrent.x, hsvCurrent.y, gray); + vec3 rgbNew = hsv2rgb(hsvNew); + + vec4 color = blendNormal(currentColor, vec4(rgbNew, newColor.a * blendFactor)); + return color; +#endif +} + +#endfor +#endfor + +#define LayerAdjustmentTypeDefault 0 +#define LayerAdjustmentTypeChroma 1 +#define LayerAdjustmentTypeTransferFunction 1 + +#for id, layerGroup in layerGroups +#for i in 0..#{lastLayerIndex#{layerGroup}} + +vec4 performAdjustment#{layerGroup}#{i}(vec4 currentColor, LayerAdjustment adjustment) { +#if (#{#{layerGroup}#{i}LayerAdjustmentType} == LayerAdjustmentTypeDefault) + return currentColor; +#elif (#{#{layerGroup}#{i}LayerAdjustmentType} == LayerAdjustmentTypeChroma) + if (distance(currentColor.rgb, adjustment.chromaKeyColor) <= + adjustment.chromaKeyTolerance) + { + return vec4(0.0); + } + else { + return currentColor; + } +#elif (#{#{layerGroup}#{i}LayerAdjustmentType} == LayerAdjustmentTypeTransferFunction) + return currentColor; +#else + return currentColor; +#endif +} + +#endfor +#endfor + +float calculateUntransformedHeight(vec2 uv, vec3 levelWeights, + Layer HeightLayers[NUMLAYERS_HEIGHTMAP]) +{ + + float height = 0; + + // The shader compiler will remove unused code when variables are multiplied by + // a constant 0 +#if !HEIGHTMAP_BLENDING_ENABLED + levelWeights = DefaultLevelWeights; +#endif // HEIGHTMAP_BLENDING_ENABLED + + #for i in 0..#{lastLayerIndexHeightLayers} + { + vec4 colorSample = getSampleHeightLayers#{i}(uv, levelWeights, HeightLayers); + colorSample = performAdjustmentHeightLayers#{i}(colorSample, HeightLayers[#{i}].adjustment); + height = colorSample.r; + + height = performLayerSettings(height, HeightLayers[#{i}].settings); + } + #endfor + return height; +} + +float calculateHeight(vec2 uv, vec3 levelWeights, Layer HeightLayers[NUMLAYERS_HEIGHTMAP]) +{ + float height = 0; + + // The shader compiler will remove unused code when variables are multiplied by + // a constant 0 +#if !HEIGHTMAP_BLENDING_ENABLED + levelWeights = DefaultLevelWeights; +#endif // HEIGHTMAP_BLENDING_ENABLED + + #for i in 0..#{lastLayerIndexHeightLayers} + { + vec4 colorSample = getSampleHeightLayers#{i}(uv, levelWeights, HeightLayers); + colorSample = performAdjustmentHeightLayers#{i}(colorSample, HeightLayers[#{i}].adjustment); + float untransformedHeight = colorSample.r; + + TileDepthTransform transform = HeightLayers[#{i}].depthTransform; + float heightSample = transform.depthScale * untransformedHeight + transform.depthOffset; + if (heightSample > -100000) { + heightSample = performLayerSettings(heightSample, HeightLayers[#{i}].settings); + height = heightSample; + } + } + #endfor + return height; +} + +vec4 calculateColor(vec4 currentColor, vec2 uv, vec3 levelWeights, + Layer ColorLayers[NUMLAYERS_COLORTEXTURE]) +{ + vec4 color = currentColor; + + // The shader compiler will remove unused code when variables are multiplied by + // a constant 0 +#if !COLORTEXTURE_BLENDING_ENABLED + levelWeights = DefaultLevelWeights; +#endif // COLORTEXTURE_BLENDING_ENABLED + + #for i in 0..#{lastLayerIndexColorLayers} + { + vec4 colorSample = getSampleColorLayers#{i}(uv, levelWeights, ColorLayers); + colorSample = performAdjustmentColorLayers#{i}(colorSample, ColorLayers[#{i}].adjustment); + colorSample = performLayerSettings(colorSample, ColorLayers[#{i}].settings); + + color = blendColorLayers#{i}(color, colorSample, 1.0); + } + #endfor + + return color; +} + +float gridDots(vec2 uv, vec2 gridResolution) { + vec2 uvVertexSpace = fract((gridResolution) * uv) + 0.5; + + vec2 uvDotSpace = abs(2.0 * (uvVertexSpace - 0.5)); + return 1.0 - length(1.0 - uvDotSpace); +} + +vec4 calculateDebugColor(vec2 uv, vec4 fragPos, vec2 vertexResolution) { + vec2 uvVertexSpace = fract(vertexResolution * uv); + vec3 colorUv = vec3(0.3 * uv.x, 0.3 * uv.y, 0); + vec3 colorDistance = vec3(0.0, 0.0, min(0.4 * log(fragPos.w) - 3.9, 1)); + vec3 colorVertex = (1.0 - length(uvVertexSpace)) * vec3(0.5); + vec3 colorSum = colorUv + colorDistance + colorVertex; + return vec4(0.5 * colorSum, 1); +} + +float tileResolution(vec2 tileUV, ChunkTile chunkTile) { + PixelPadding padding; + padding.startOffset = ivec2(0); + padding.sizeDifference = ivec2(0); + + vec2 heightResolution = textureSize(chunkTile.textureSampler, 0); + vec2 uv = tileUVToTextureSamplePosition(chunkTile, tileUV, padding); + return gridDots(uv, heightResolution); +} + +vec4 calculateNight(vec4 currentColor, vec2 uv, vec3 levelWeights, + Layer NightLayers[NUMLAYERS_NIGHTTEXTURE], + vec3 ellipsoidNormalCameraSpace, vec3 lightDirectionCameraSpace) +{ + vec4 nightColor = vec4(0.0); + vec4 color = currentColor; + + // The shader compiler will remove unused code when variables are multiplied by + // a constant 0 +#if !NIGHTTEXTURE_BLENDING_ENABLED + levelWeights = DefaultLevelWeights; +#endif // NIGHTTEXTURE_BLENDING_ENABLED + + vec3 n = normalize(ellipsoidNormalCameraSpace); + vec3 l = lightDirectionCameraSpace; + float cosineFactor = clamp(dot(l, normalize(n + 0.20 * l)) * 3 , 0, 1); + + #for i in 0..#{lastLayerIndexNightLayers} + { + vec4 colorSample = getSampleNightLayers#{i}(uv, levelWeights, NightLayers); + colorSample = performAdjustmentNightLayers#{i}(colorSample, NightLayers[#{i}].adjustment); + colorSample = performLayerSettings(colorSample, NightLayers[#{i}].settings); + + float adjustedAlpha = cosineFactor * colorSample.a; + // Filter to night side + vec4 newColor = vec4(cosineFactor * colorSample.xyz, adjustedAlpha); + + color = blendNightLayers#{i}(color, newColor, adjustedAlpha); + } + #endfor + + return color; +} + +vec4 calculateShadedColor(vec4 currentColor, vec3 ellipsoidNormalCameraSpace, + vec3 lightDirectionCameraSpace, vec3 viewDirectionCameraSpace, + float roughness) +{ + vec3 shadedColor = currentColor.rgb * 0.05; + + vec3 n = normalize(ellipsoidNormalCameraSpace); + + float power = orenNayarDiffuse( + -lightDirectionCameraSpace, + viewDirectionCameraSpace, + ellipsoidNormalCameraSpace, + roughness + ); + + vec3 l = lightDirectionCameraSpace; + power = max(smoothstep(0.0, 0.1, max(dot(-l, n), 0.0)) * power, 0.0); + + vec4 color = vec4(shadedColor + currentColor.rgb * power, currentColor.a); + return color; +} + +vec4 calculateOverlay(vec4 currentColor, vec2 uv, vec3 levelWeights, + Layer Overlays[NUMLAYERS_OVERLAY]) +{ + vec4 color = currentColor; + + // The shader compiler will remove unused code when variables are multiplied by + // a constant 0 +#if !OVERLAY_BLENDING_ENABLED + levelWeights = DefaultLevelWeights; +#endif // OVERLAY_BLENDING_ENABLED + + #for i in 0..#{lastLayerIndexOverlays} + { + vec4 colorSample = getSampleOverlays#{i}(uv, levelWeights, Overlays); + colorSample = performAdjustmentOverlays#{i}(colorSample, Overlays[#{i}].adjustment); + + colorSample = performLayerSettings(colorSample, Overlays[#{i}].settings); + + color = blendNormal(color, colorSample); + color = blendOverlays#{i}(color, colorSample, 1.0); + } + #endfor + + return color; +} + +vec4 calculateWater(vec4 currentColor, vec2 uv, vec3 levelWeights, + Layer WaterMasks[NUMLAYERS_WATERMASK], + vec3 ellipsoidNormalCameraSpace, vec3 lightDirectionCameraSpace, + vec3 positionCameraSpace, out float reflectance) +{ + vec4 waterColor = vec4(0.0); + + // The shader compiler will remove unused code when variables are multiplied by + // a constant 0 +#if !WATERMASK_BLENDING_ENABLED + levelWeights = DefaultLevelWeights; +#endif // WATERMASK_BLENDING_ENABLED + + #for i in 0..#{lastLayerIndexWaterMasks} + { + vec4 colorSample = getSampleWaterMasks#{i}(uv, levelWeights, WaterMasks); + colorSample = performAdjustmentWaterMasks#{i}(colorSample, WaterMasks[#{i}].adjustment); + + colorSample.a = performLayerSettings(colorSample.a, WaterMasks[#{i}].settings); + + waterColor = blendWaterMasks#{i}(waterColor, colorSample, 1.0); + } + #endfor + + vec3 directionToFragmentCameraSpace = normalize(positionCameraSpace - vec3(0, 0, 0)); + vec3 reflectionDirectionCameraSpace = reflect(lightDirectionCameraSpace, ellipsoidNormalCameraSpace); + // float cosineFactor = clamp(dot(-reflectionDirectionCameraSpace, directionToFragmentCameraSpace), 0, 1); + // cosineFactor = pow(cosineFactor, 100); + + // const float specularIntensity = 0.4; + // vec3 specularTotal = cosineFactor * specularIntensity * waterColor.a; + + reflectance = waterColor.a; + //return blendNormal(currentColor, waterColor); + //return currentColor + vec4(specularTotal, 1); + return currentColor; +} + +#endif // TEXTURETILEMAPPING_HGLSL diff --git a/modules/globebrowsing/shaders/texturetilemapping.hglsl b/modules/globebrowsing/shaders/texturetilemapping.hglsl deleted file mode 100644 index 5cf2214291..0000000000 --- a/modules/globebrowsing/shaders/texturetilemapping.hglsl +++ /dev/null @@ -1,461 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2021 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef TEXTURETILEMAPPING_HGLSL -#define TEXTURETILEMAPPING_HGLSL - -#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl> -#include <${MODULE_GLOBEBROWSING}/shaders/blending.hglsl> - -// First layer type from LayerShaderManager is height map -#define NUMLAYERS_HEIGHTMAP #{lastLayerIndexHeightLayers} + 1 -#define USE_HEIGHTMAP #{useHeightLayers} -#define HEIGHTMAP_BLENDING_ENABLED #{blendHeightLayers} - -// Second layer type from LayerShaderManager is color texture -#define NUMLAYERS_COLORTEXTURE #{lastLayerIndexColorLayers} + 1 -#define USE_COLORTEXTURE #{useColorLayers} -#define COLORTEXTURE_BLENDING_ENABLED #{blendColorLayers} - - // Third layer type from LayerShaderManager is water mask -#define NUMLAYERS_WATERMASK #{lastLayerIndexWaterMasks} + 1 -#define USE_WATERMASK #{useWaterMasks} -#define WATERMASK_BLENDING_ENABLED #{blendWaterMasks} - -// Fourth layer type from LayerShaderManager is night texture -#define NUMLAYERS_NIGHTTEXTURE #{lastLayerIndexNightLayers} + 1 -#define USE_NIGHTTEXTURE #{useNightLayers} -#define NIGHTTEXTURE_BLENDING_ENABLED #{blendNightLayers} - -// Fifth layer type from LayerShaderManager is overlay -#define NUMLAYERS_OVERLAY #{lastLayerIndexOverlays} + 1 -#define USE_OVERLAY #{useOverlays} -#define OVERLAY_BLENDING_ENABLED #{blendOverlays} - -// Global constants -#define CHUNK_DEFAULT_HEIGHT #{defaultHeight} - -// Other key value pairs used for settings -#define USE_ACCURATE_NORMALS #{useAccurateNormals} -#define PERFORM_SHADING #{performShading} -#define USE_ECLIPSE_SHADOWS #{useEclipseShadows} -#define USE_ECLIPSE_HARD_SHADOWS #{useEclipseHardShadows} -#define SHOW_CHUNK_EDGES #{showChunkEdges} -#define SHOW_HEIGHT_RESOLUTION #{showHeightResolution} -#define SHOW_HEIGHT_INTENSITIES #{showHeightIntensities} -#define SHADOW_MAPPING_ENABLED #{enableShadowMapping} - -const vec3 DefaultLevelWeights = vec3(1.0, 0.0, 0.0); - -float orenNayarDiffuse(vec3 lightDirection, vec3 viewDirection, vec3 surfaceNormal, - float roughness) -{ - // calculate intermediary values - float NdotL = dot(surfaceNormal, lightDirection); - float NdotV = dot(surfaceNormal, viewDirection); - - float angleVN = acos(NdotV); - float angleLN = acos(NdotL); - - float alpha = max(angleVN, angleLN); - float beta = min(angleVN, angleLN); - float gamma = dot( - viewDirection - surfaceNormal * dot(viewDirection, surfaceNormal), - lightDirection - surfaceNormal * dot(lightDirection, surfaceNormal) - ); - - float roughnessSquared = roughness * roughness; - - // calculate A and B - float A = 1.0 - 0.5 * (roughnessSquared / (roughnessSquared + 0.57)); - float B = 0.45 * (roughnessSquared / (roughnessSquared + 0.09)); - float C = sin(alpha) * tan(beta); - - // put it all together - return max(0.0, NdotL) * (A + B * max(0.0, gamma) * C); -} - -float performLayerSettings(float currentValue, LayerSettings settings) { - float v = sign(currentValue) * pow(abs(currentValue), settings.gamma) * - settings.multiplier + settings.offset; - return v * settings.opacity; -} - -vec4 performLayerSettings(vec4 currentValue, LayerSettings settings) { - vec3 newValue = sign(currentValue.rgb) * pow(abs(currentValue.rgb), vec3(settings.gamma)) * - settings.multiplier + settings.offset; - return vec4(newValue, currentValue.a * settings.opacity); -} - -vec2 tileUVToTextureSamplePosition(ChunkTile chunkTile, vec2 tileUV, - PixelPadding padding) -{ - vec2 uv = chunkTile.uvTransform.uvOffset + chunkTile.uvTransform.uvScale * tileUV; - - // compensateSourceTextureSampling - ivec2 resolution = textureSize(chunkTile.textureSampler, 0); - vec2 sourceSize = vec2(resolution) + padding.sizeDifference; - vec2 currentSize = vec2(resolution); - vec2 sourceToCurrentSize = currentSize / sourceSize; - return sourceToCurrentSize * (uv - padding.startOffset / sourceSize); -} - -vec4 getTexVal(ChunkTilePile chunkTilePile, vec3 w, vec2 uv, - PixelPadding padding) -{ - vec4 v1 = texture( - chunkTilePile.chunkTile0.textureSampler, - tileUVToTextureSamplePosition(chunkTilePile.chunkTile0, uv, padding) - ); - vec4 v2 = texture( - chunkTilePile.chunkTile1.textureSampler, - tileUVToTextureSamplePosition(chunkTilePile.chunkTile1, uv, padding) - ); - vec4 v3 = texture( - chunkTilePile.chunkTile2.textureSampler, - tileUVToTextureSamplePosition(chunkTilePile.chunkTile2, uv, padding) - ); - - return w.x * v1 + w.y * v2 + w.z * v3; -} - -#for id, layerGroup in layerGroups -#for i in 0..#{lastLayerIndex#{layerGroup}} - -vec4 getSample#{layerGroup}#{i}(vec2 uv, vec3 levelWeights, - Layer #{layerGroup}[#{lastLayerIndex#{layerGroup}} + 1]) -{ - vec4 color = vec4(0.0, 0.0, 0.0, 1.0); - - // All tile layers are the same. Sample from texture -#if (#{#{layerGroup}#{i}LayerType} == 0) // DefaultTileLayer - color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding); -#elif (#{#{layerGroup}#{i}LayerType} == 1) // SingleImageTileLayer - color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding); -#elif (#{#{layerGroup}#{i}LayerType} == 2) // SizeReferenceTileLayer - color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding); -#elif (#{#{layerGroup}#{i}LayerType} == 3) // TemporalTileLayer - color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding); -#elif (#{#{layerGroup}#{i}LayerType} == 4) // TileIndexTileLayer - color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding); -#elif (#{#{layerGroup}#{i}LayerType} == 5) // ByIndexTileLayer - color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding); -#elif (#{#{layerGroup}#{i}LayerType} == 6) // ByLevelTileLayer - color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding); -#elif (#{#{layerGroup}#{i}LayerType} == 7) // SolidColor - color.rgb = #{layerGroup}[#{i}].color; -#endif - - return color; -} - -#endfor -#endfor - -#for id, layerGroup in layerGroups -#for i in 0..#{lastLayerIndex#{layerGroup}} - -vec4 blend#{layerGroup}#{i}(vec4 currentColor, vec4 newColor, float blendFactor) { -#if (#{#{layerGroup}#{i}BlendMode} == 0) // Default, Normal - return blendNormal(currentColor, vec4(newColor.rgb, newColor.a * blendFactor)); -#elif (#{#{layerGroup}#{i}BlendMode} == 1) // Multiply - return blendMultiply(currentColor, newColor * blendFactor); -#elif (#{#{layerGroup}#{i}BlendMode} == 2) // Add - return blendAdd(currentColor, newColor * blendFactor); -#elif (#{#{layerGroup}#{i}BlendMode} == 3) // Subtract - return blendSubtract(currentColor, newColor * blendFactor); -#elif (#{#{layerGroup}#{i}BlendMode} == 4) // Color - // Convert color to grayscale - float gray = (newColor.r + newColor.g + newColor.b) / 3.0; - - vec3 hsvCurrent = rgb2hsv(currentColor.rgb); - // Use gray from new color as value in hsv - vec3 hsvNew = vec3(hsvCurrent.x, hsvCurrent.y, gray); - vec3 rgbNew = hsv2rgb(hsvNew); - - vec4 color = blendNormal(currentColor, vec4(rgbNew, newColor.a * blendFactor)); - return color; -#endif -} - -#endfor -#endfor - - -#for id, layerGroup in layerGroups -#for i in 0..#{lastLayerIndex#{layerGroup}} - -vec4 performAdjustment#{layerGroup}#{i}(vec4 currentColor, - LayerAdjustment adjustment) -{ -#if (#{#{layerGroup}#{i}LayerAdjustmentType} == 0) // Default, None - return currentColor; -#elif (#{#{layerGroup}#{i}LayerAdjustmentType} == 1) // ChromaKey - if (distance( - currentColor.rgb, - adjustment.chromaKeyColor - ) <= adjustment.chromaKeyTolerance) - { - return vec4(0.0); - } - else { - return currentColor; - } -#elif (#{#{layerGroup}#{i}LayerAdjustmentType} == 2) // TransferFunction - return currentColor; -#else - return currentColor; -#endif -} - -#endfor -#endfor - -float calculateUntransformedHeight(vec2 uv, vec3 levelWeights, - Layer HeightLayers[NUMLAYERS_HEIGHTMAP]) -{ - - float height = 0; - - // The shader compiler will remove unused code when variables are multiplied by - // a constant 0 -#if !HEIGHTMAP_BLENDING_ENABLED - levelWeights = DefaultLevelWeights; -#endif // HEIGHTMAP_BLENDING_ENABLED - - #for i in 0..#{lastLayerIndexHeightLayers} - { - vec4 colorSample = getSampleHeightLayers#{i}(uv, levelWeights, HeightLayers); - colorSample = performAdjustmentHeightLayers#{i}(colorSample, HeightLayers[#{i}].adjustment); - height = colorSample.r; - - height = performLayerSettings(height, HeightLayers[#{i}].settings); - } - #endfor - return height; -} - -float calculateHeight(vec2 uv, vec3 levelWeights, Layer HeightLayers[NUMLAYERS_HEIGHTMAP]) -{ - float height = 0; - - // The shader compiler will remove unused code when variables are multiplied by - // a constant 0 -#if !HEIGHTMAP_BLENDING_ENABLED - levelWeights = DefaultLevelWeights; -#endif // HEIGHTMAP_BLENDING_ENABLED - - - #for i in 0..#{lastLayerIndexHeightLayers} - { - vec4 colorSample = getSampleHeightLayers#{i}(uv, levelWeights, HeightLayers); - colorSample = performAdjustmentHeightLayers#{i}(colorSample, HeightLayers[#{i}].adjustment); - float untransformedHeight = colorSample.r; - - TileDepthTransform transform = HeightLayers[#{i}].depthTransform; - float heightSample = - transform.depthScale * untransformedHeight + transform.depthOffset; - if (heightSample > -100000) { - heightSample = performLayerSettings(heightSample, HeightLayers[#{i}].settings); - height = heightSample; - } - } - #endfor - return height; -} - -vec4 calculateColor(vec4 currentColor, vec2 uv, vec3 levelWeights, - Layer ColorLayers[NUMLAYERS_COLORTEXTURE]) -{ - vec4 color = currentColor; - - // The shader compiler will remove unused code when variables are multiplied by - // a constant 0 -#if !COLORTEXTURE_BLENDING_ENABLED - levelWeights = DefaultLevelWeights; -#endif // COLORTEXTURE_BLENDING_ENABLED - - #for i in 0..#{lastLayerIndexColorLayers} - { - vec4 colorSample = getSampleColorLayers#{i}(uv, levelWeights, ColorLayers); - colorSample = performAdjustmentColorLayers#{i}(colorSample, ColorLayers[#{i}].adjustment); - colorSample = performLayerSettings(colorSample, ColorLayers[#{i}].settings); - - color = blendColorLayers#{i}(color, colorSample, 1.0); - } - #endfor - - return color; -} - -float gridDots(vec2 uv, vec2 gridResolution) { - vec2 uvVertexSpace = fract((gridResolution) * uv) + 0.5; - - vec2 uvDotSpace = abs(2.0 * (uvVertexSpace - 0.5)); - return 1.0 - length(1.0 - uvDotSpace); -} - -vec4 calculateDebugColor(vec2 uv, vec4 fragPos, vec2 vertexResolution) { - vec2 uvVertexSpace = fract(vertexResolution * uv); - vec3 colorUv = vec3(0.3 * uv.x, 0.3 * uv.y, 0); - vec3 colorDistance = vec3(0.0, 0.0, min(0.4 * log(fragPos.w) - 3.9, 1)); - vec3 colorVertex = (1.0 - length(uvVertexSpace)) * vec3(0.5); - vec3 colorSum = colorUv + colorDistance + colorVertex; - return vec4(0.5 * colorSum, 1); -} - -float tileResolution(vec2 tileUV, ChunkTile chunkTile) { - PixelPadding padding; - padding.startOffset = ivec2(0); - padding.sizeDifference = ivec2(0); - - vec2 heightResolution = textureSize(chunkTile.textureSampler, 0); - vec2 uv = tileUVToTextureSamplePosition(chunkTile, tileUV, padding); - return gridDots(uv, heightResolution); -} - -vec4 calculateNight(vec4 currentColor, vec2 uv, vec3 levelWeights, - Layer NightLayers[NUMLAYERS_NIGHTTEXTURE], - vec3 ellipsoidNormalCameraSpace, - vec3 lightDirectionCameraSpace) -{ - vec4 nightColor = vec4(0.0); - vec4 color = currentColor; - - // The shader compiler will remove unused code when variables are multiplied by - // a constant 0 -#if !NIGHTTEXTURE_BLENDING_ENABLED - levelWeights = DefaultLevelWeights; -#endif // NIGHTTEXTURE_BLENDING_ENABLED - - vec3 n = normalize(ellipsoidNormalCameraSpace); - vec3 l = lightDirectionCameraSpace; - float cosineFactor = clamp(dot(l, normalize(n + 0.20 * l)) * 3 , 0, 1); - - #for i in 0..#{lastLayerIndexNightLayers} - { - vec4 colorSample = getSampleNightLayers#{i}(uv, levelWeights, NightLayers); - colorSample = performAdjustmentNightLayers#{i}(colorSample, NightLayers[#{i}].adjustment); - colorSample = performLayerSettings(colorSample, NightLayers[#{i}].settings); - - float adjustedAlpha = cosineFactor * colorSample.a; - // Filter to night side - vec4 newColor = vec4(cosineFactor * colorSample.xyz, adjustedAlpha); - - color = blendNightLayers#{i}(color, newColor, adjustedAlpha); - } - #endfor - - return color; -} - -vec4 calculateShadedColor(vec4 currentColor, vec3 ellipsoidNormalCameraSpace, - vec3 lightDirectionCameraSpace, vec3 viewDirectionCameraSpace, - float roughness) -{ - vec3 shadedColor = currentColor.rgb * 0.05; - - vec3 n = normalize(ellipsoidNormalCameraSpace); - - float power = orenNayarDiffuse( - -lightDirectionCameraSpace, - viewDirectionCameraSpace, - ellipsoidNormalCameraSpace, - roughness); - - vec3 l = lightDirectionCameraSpace; - power = max(smoothstep(0.0f, 0.1f, max(dot(-l, n), 0.0f)) * power, 0.0f); - - vec4 color = vec4(shadedColor + currentColor.rgb * power, currentColor.a); - return color; -} - -vec4 calculateOverlay(vec4 currentColor, vec2 uv, vec3 levelWeights, - Layer Overlays[NUMLAYERS_OVERLAY]) -{ - vec4 color = currentColor; - - // The shader compiler will remove unused code when variables are multiplied by - // a constant 0 -#if !OVERLAY_BLENDING_ENABLED - levelWeights = DefaultLevelWeights; -#endif // OVERLAY_BLENDING_ENABLED - - #for i in 0..#{lastLayerIndexOverlays} - { - vec4 colorSample = getSampleOverlays#{i}(uv, levelWeights, Overlays); - colorSample = performAdjustmentOverlays#{i}(colorSample, Overlays[#{i}].adjustment); - - colorSample = performLayerSettings(colorSample, Overlays[#{i}].settings); - - color = blendNormal(color, colorSample); - color = blendOverlays#{i}(color, colorSample, 1.0); - } - #endfor - - return color; -} - -vec4 calculateWater(vec4 currentColor, vec2 uv, vec3 levelWeights, - Layer WaterMasks[NUMLAYERS_WATERMASK], - vec3 ellipsoidNormalCameraSpace, - vec3 lightDirectionCameraSpace, vec3 positionCameraSpace, - out float reflectance) -{ - vec4 waterColor = vec4(0.0); - - // The shader compiler will remove unused code when variables are multiplied by - // a constant 0 -#if !WATERMASK_BLENDING_ENABLED - levelWeights = DefaultLevelWeights; -#endif // WATERMASK_BLENDING_ENABLED - - #for i in 0..#{lastLayerIndexWaterMasks} - { - vec4 colorSample = getSampleWaterMasks#{i}(uv, levelWeights, WaterMasks); - colorSample = performAdjustmentWaterMasks#{i}(colorSample, WaterMasks[#{i}].adjustment); - - colorSample.a = performLayerSettings(colorSample.a, WaterMasks[#{i}].settings); - - waterColor = blendWaterMasks#{i}(waterColor, colorSample, 1.0); - } - #endfor - - vec3 directionToFragmentCameraSpace = normalize(positionCameraSpace - vec3(0, 0, 0)); - vec3 reflectionDirectionCameraSpace = reflect(lightDirectionCameraSpace, ellipsoidNormalCameraSpace); - float cosineFactor = clamp(dot(-reflectionDirectionCameraSpace, directionToFragmentCameraSpace), 0, 1); - cosineFactor = pow(cosineFactor, 100); - - const vec3 specularColor = vec3(1.0); - const float specularIntensity = 0.4; - - vec3 specularTotal = specularColor * cosineFactor * specularIntensity * waterColor.a; - - reflectance = waterColor.a; - //return blendNormal(currentColor, waterColor); - //return currentColor + vec4(specularTotal, 1); - return currentColor; -} - -#endif // TEXTURETILEMAPPING_HGLSL diff --git a/modules/globebrowsing/shaders/tile.hglsl b/modules/globebrowsing/shaders/tile.glsl similarity index 78% rename from modules/globebrowsing/shaders/tile.hglsl rename to modules/globebrowsing/shaders/tile.glsl index d074581c8c..7b2ce24ea4 100644 --- a/modules/globebrowsing/shaders/tile.hglsl +++ b/modules/globebrowsing/shaders/tile.glsl @@ -26,53 +26,53 @@ #define TEXTURETILE_HGLSL struct TileDepthTransform { - float depthScale; - float depthOffset; + float depthScale; + float depthOffset; }; struct TileUvTransform { - vec2 uvOffset; - vec2 uvScale; + vec2 uvOffset; + vec2 uvScale; }; struct ChunkTile { - sampler2D textureSampler; - TileUvTransform uvTransform; + sampler2D textureSampler; + TileUvTransform uvTransform; }; struct PixelPadding { - ivec2 startOffset; - ivec2 sizeDifference; + ivec2 startOffset; + ivec2 sizeDifference; }; struct ChunkTilePile { - ChunkTile chunkTile0; - ChunkTile chunkTile1; - ChunkTile chunkTile2; + ChunkTile chunkTile0; + ChunkTile chunkTile1; + ChunkTile chunkTile2; }; struct LayerSettings { - float opacity; - float gamma; - float multiplier; - float offset; - float valueBlending; + float opacity; + float gamma; + float multiplier; + float offset; + float valueBlending; }; struct LayerAdjustment { - vec3 chromaKeyColor; - float chromaKeyTolerance; + vec3 chromaKeyColor; + float chromaKeyTolerance; }; struct Layer { - ChunkTilePile pile; - TileDepthTransform depthTransform; - LayerSettings settings; - LayerAdjustment adjustment; - PixelPadding padding; - - // Other layer type properties stuff - vec3 color; + ChunkTilePile pile; + TileDepthTransform depthTransform; + LayerSettings settings; + LayerAdjustment adjustment; + PixelPadding padding; + + // Other layer type properties stuff + vec3 color; }; #endif // TEXTURETILE_HGLSL diff --git a/modules/globebrowsing/shaders/tileheight.hglsl b/modules/globebrowsing/shaders/tileheight.glsl similarity index 66% rename from modules/globebrowsing/shaders/tileheight.hglsl rename to modules/globebrowsing/shaders/tileheight.glsl index 47865f9bb5..64f026c328 100644 --- a/modules/globebrowsing/shaders/tileheight.hglsl +++ b/modules/globebrowsing/shaders/tileheight.glsl @@ -26,16 +26,15 @@ #define TILE_HEIGHT_HGLSL #include "PowerScaling/powerScaling_vs.hglsl" - -#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl> +#include <${MODULE_GLOBEBROWSING}/shaders/tile.glsl> #ifndef USE_HEIGHTMAP #define USE_HEIGHTMAP #{useAccurateNormals} -#endif //USE_HEIGHTMAP +#endif // USE_HEIGHTMAP #ifndef USE_ACCURATE_NORMALS #define USE_ACCURATE_NORMALS #{useAccurateNormals} -#endif //USE_ACCURATE_NORMALS +#endif // USE_ACCURATE_NORMALS #if USE_HEIGHTMAP uniform Layer HeightLayers[NUMLAYERS_HEIGHTMAP]; @@ -48,42 +47,38 @@ uniform float deltaTheta1; uniform float deltaPhi0; uniform float deltaPhi1; uniform float tileDelta; -#endif //USE_ACCURATE_NORMALS && USE_HEIGHTMAP +#endif // USE_ACCURATE_NORMALS && USE_HEIGHTMAP +// levelWeights := Variable to determine which texture to sample from +// HeightLayers := Three textures to sample from float getUntransformedTileHeight(vec2 uv, vec3 levelWeights) { - float height = CHUNK_DEFAULT_HEIGHT; + float height = CHUNK_DEFAULT_HEIGHT; #if USE_HEIGHTMAP - // Calculate desired level based on distance to the vertex on the ellipsoid - // Before any heightmapping is done - height = calculateUntransformedHeight( - uv, - levelWeights, // Variable to determine which texture to sample from - HeightLayers // Three textures to sample from - ); + // Calculate desired level based on distance to the vertex on the ellipsoid before any + // heightmapping is done. + height = calculateUntransformedHeight(uv, levelWeights, HeightLayers); #endif // USE_HEIGHTMAP return height; } +// levelWeights := Variable to determine which texture to sample from +// HeightLayers := Three textures to sample from float getTileHeight(vec2 uv, vec3 levelWeights) { - float height = CHUNK_DEFAULT_HEIGHT; + float height = CHUNK_DEFAULT_HEIGHT; #if USE_HEIGHTMAP - // Calculate desired level based on distance to the vertex on the ellipsoid - // Before any heightmapping is done - height = calculateHeight( - uv, - levelWeights, // Variable to determine which texture to sample from - HeightLayers // Three textures to sample from - ); + // Calculate desired level based on distance to the vertex on the ellipsoid before any + // heightmapping is done + height = calculateHeight(uv, levelWeights, HeightLayers); #endif // USE_HEIGHTMAP return height; } float getTileHeightScaled(vec2 uv, vec3 levelWeights) { - float height = getTileHeight(uv, levelWeights); + float height = getTileHeight(uv, levelWeights); #if USE_HEIGHTMAP height *= heightScale; @@ -96,25 +91,25 @@ vec3 getTileNormal(vec2 uv, vec3 levelWeights, vec3 ellipsoidNormalCameraSpace, vec3 ellipsoidTangentThetaCameraSpace, vec3 ellipsoidTangentPhiCameraSpace) { - vec3 normal = ellipsoidNormalCameraSpace; + vec3 normal = ellipsoidNormalCameraSpace; #if USE_ACCURATE_NORMALS - float deltaPhi = mix(deltaPhi0, deltaPhi1, uv.x); - float deltaTheta = mix(deltaTheta0, deltaTheta1, uv.y); + float deltaPhi = mix(deltaPhi0, deltaPhi1, uv.x); + float deltaTheta = mix(deltaTheta0, deltaTheta1, uv.y); - vec3 deltaPhiVec = ellipsoidTangentPhiCameraSpace * deltaPhi; - vec3 deltaThetaVec = ellipsoidTangentThetaCameraSpace * deltaTheta; + vec3 deltaPhiVec = ellipsoidTangentPhiCameraSpace * deltaPhi; + vec3 deltaThetaVec = ellipsoidTangentThetaCameraSpace * deltaTheta; - float height00 = getTileHeightScaled(uv, levelWeights); - float height10 = getTileHeightScaled(uv + vec2(tileDelta, 0.0f), levelWeights); - float height01 = getTileHeightScaled(uv + vec2(0.0f, tileDelta), levelWeights); + float height00 = getTileHeightScaled(uv, levelWeights); + float height10 = getTileHeightScaled(uv + vec2(tileDelta, 0.0), levelWeights); + float height01 = getTileHeightScaled(uv + vec2(0.0, tileDelta), levelWeights); - vec3 diffTheta = deltaThetaVec + ellipsoidNormalCameraSpace * (height10 - height00); - vec3 diffPhi = deltaPhiVec + ellipsoidNormalCameraSpace * (height01 - height00); + vec3 diffTheta = deltaThetaVec + ellipsoidNormalCameraSpace * (height10 - height00); + vec3 diffPhi = deltaPhiVec + ellipsoidNormalCameraSpace * (height01 - height00); - normal = normalize(cross(diffTheta, diffPhi)); + normal = normalize(cross(diffTheta, diffPhi)); #endif // USE_ACCURATE_NORMALS - return normal; + return normal; } #endif // TILE_HEIGHT_HGLSL diff --git a/modules/globebrowsing/shaders/tilevertexskirt.hglsl b/modules/globebrowsing/shaders/tilevertexskirt.glsl similarity index 89% rename from modules/globebrowsing/shaders/tilevertexskirt.hglsl rename to modules/globebrowsing/shaders/tilevertexskirt.glsl index 37bcce883c..ac1bcccccc 100644 --- a/modules/globebrowsing/shaders/tilevertexskirt.hglsl +++ b/modules/globebrowsing/shaders/tilevertexskirt.glsl @@ -31,14 +31,14 @@ uniform int xSegments; uniform float skirtLength; bool tileVertexIsSkirtVertex() { - int vertexIDx = gl_VertexID % (xSegments + 3); - int vertexIDy = gl_VertexID / (xSegments + 3); - return vertexIDx == 0 || vertexIDy == 0 || - vertexIDx == (xSegments + 2) || vertexIDy == (xSegments + 2); + int vertexIDx = gl_VertexID % (xSegments + 3); + int vertexIDy = gl_VertexID / (xSegments + 3); + return vertexIDx == 0 || vertexIDy == 0 || + vertexIDx == (xSegments + 2) || vertexIDy == (xSegments + 2); } float getTileVertexSkirtLength() { - return tileVertexIsSkirtVertex() ? skirtLength : 0.0; + return tileVertexIsSkirtVertex() ? skirtLength : 0.0; } #endif // TILE_VERTEX_SKIRT_HGLSL diff --git a/modules/globebrowsing/src/dashboarditemglobelocation.cpp b/modules/globebrowsing/src/dashboarditemglobelocation.cpp index fe51c0fb9f..0369043f4f 100644 --- a/modules/globebrowsing/src/dashboarditemglobelocation.cpp +++ b/modules/globebrowsing/src/dashboarditemglobelocation.cpp @@ -78,9 +78,7 @@ namespace { namespace openspace { documentation::Documentation DashboardItemGlobeLocation::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "globebrowsing_dashboarditem_globelocation"; - return doc; + return codegen::doc("globebrowsing_dashboarditem_globelocation"); } DashboardItemGlobeLocation::DashboardItemGlobeLocation( diff --git a/modules/globebrowsing/src/gdalwrapper.cpp b/modules/globebrowsing/src/gdalwrapper.cpp index 0e845581da..e41d0dbf0f 100644 --- a/modules/globebrowsing/src/gdalwrapper.cpp +++ b/modules/globebrowsing/src/gdalwrapper.cpp @@ -105,8 +105,11 @@ GdalWrapper::GdalWrapper(size_t maximumCacheSize, size_t maximumMaximumCacheSize addProperty(_gdalMaximumCacheSize); GDALAllRegister(); - CPLSetConfigOption("GDAL_DATA", absPath("${MODULE_GLOBEBROWSING}/gdal_data").c_str()); - CPLSetConfigOption("CPL_TMPDIR", absPath("${BASE}").c_str()); + CPLSetConfigOption( + "GDAL_DATA", + absPath("${MODULE_GLOBEBROWSING}/gdal_data").string().c_str() + ); + CPLSetConfigOption("CPL_TMPDIR", absPath("${BASE}").string().c_str()); CPLSetConfigOption("GDAL_HTTP_UNSAFESSL", "YES"); CPLSetConfigOption("GDAL_HTTP_TIMEOUT", "3"); // 3 seconds diff --git a/modules/globebrowsing/src/globelabelscomponent.cpp b/modules/globebrowsing/src/globelabelscomponent.cpp index 185dc0ce6b..7dbb215593 100644 --- a/modules/globebrowsing/src/globelabelscomponent.cpp +++ b/modules/globebrowsing/src/globelabelscomponent.cpp @@ -51,7 +51,6 @@ namespace { constexpr const char* _loggerCat = "GlobeLabels"; constexpr const double LabelFadeOutLimitAltitudeMeters = 25000.0; - constexpr const double RangeAngularCoefConst = 0.8; constexpr const float MinOpacityValueConst = 0.009f; enum LabelRenderingAlignmentType { @@ -61,106 +60,86 @@ namespace { constexpr int8_t CurrentCacheVersion = 1; - constexpr openspace::properties::Property::PropertyInfo LabelsInfo = { - "Labels", - "Labels Enabled", - "Enables and disables the rendering of labels on the globe surface from " - "the csv label file" + constexpr openspace::properties::Property::PropertyInfo EnabledInfo = { + "Enabled", + "Enabled", + "Enables and disables labels' rendering." }; - constexpr openspace::properties::Property::PropertyInfo LabelsEnableInfo = { - "Enable", - "Enable", - "Enables and disables labels' rendering from the asset file." - }; - - constexpr openspace::properties::Property::PropertyInfo LabelsFontSizeInfo = { - "LabelsFontSize", - "Labels Font Size", + constexpr openspace::properties::Property::PropertyInfo FontSizeInfo = { + "FontSize", + "Font Size", "Font size for the rendering labels. This is different fromt text size." }; - constexpr openspace::properties::Property::PropertyInfo LabelsMaxSizeInfo = { - "LabelsMaxSize", - "Labels Maximum Text Size", - "Maximum label size" + constexpr openspace::properties::Property::PropertyInfo MinMaxSizeInfo = { + "MinMaxSize", + "Min/Max Text Size", + "Minimum and maximum label size, in pixels." }; - constexpr openspace::properties::Property::PropertyInfo LabelsMinSizeInfo = { - "LabelsMinSize", - "Labels Minimum Text Size", - "Minimum label size" - }; - - constexpr openspace::properties::Property::PropertyInfo LabelsSizeInfo = { + constexpr openspace::properties::Property::PropertyInfo SizeInfo = { "LabelsSize", "Labels Size", - "Labels Size" + "This value affects the size scale of the labels." }; - constexpr openspace::properties::Property::PropertyInfo LabelsMinHeightInfo = { - "LabelsMinHeight", - "Labels Minimum Height", - "Labels Minimum Height" + constexpr openspace::properties::Property::PropertyInfo HeightOffsetInfo = { + "HeightOffset", + "Height Offset", + "This value moves the label away from the globe surface by the specified " + "distance (in meters)." }; - constexpr openspace::properties::Property::PropertyInfo LabelsColorInfo = { - "LabelsColor", - "Labels Color", - "Labels Color" + constexpr openspace::properties::Property::PropertyInfo ColorInfo = { + "Color", + "Color", + "The text color of the labels." }; - constexpr openspace::properties::Property::PropertyInfo LabelsOpacityInfo = { - "LabelsOpacity", - "Labels Opacity", - "Labels Opacity" + constexpr openspace::properties::Property::PropertyInfo OpacityInfo = { + "Opacity", + "Opacity", + "The opacity of the labels." }; - constexpr openspace::properties::Property::PropertyInfo - LabelsFadeInStartingDistanceInfo = - { - "FadeInStartingDistance", - "Fade In Starting Distance for Labels", - "Fade In Starting Distance for Labels" + constexpr openspace::properties::Property::PropertyInfo FadeDistancesInfo = { + "FadeDistances", + "Fade-In Distances", + "The distances above the globe's surface at which the labels start fading in or " + "out, given in meters. The final distances are also adjusted by the specified " + "height offset." }; - constexpr openspace::properties::Property::PropertyInfo - LabelsFadeOutStartingDistanceInfo = - { - "FadeOutStartingDistance", - "Fade Out Starting Distance for Labels", - "Fade Out Starting Distance for Labels" + constexpr openspace::properties::Property::PropertyInfo FadeInEnabledInfo = { + "FadeInEnabled", + "Fade In Enabled", + "Sets whether the labels fade in when approaching the globe from a distance. If " + "false, no fading happens and the labels immediately has full opacity." }; - constexpr openspace::properties::Property::PropertyInfo LabelsFadeInEnabledInfo = { - "LabelsFadeInEnabled", - "Labels fade In enabled", - "Labels fade In enabled" + constexpr openspace::properties::Property::PropertyInfo FadeOutEnabledInfo = { + "FadeOutEnabled", + "Fade Out Enabled", + "Sets whether the labels fade out when approaching the surface of the globe. If " + "false, no fading happens and the labels stays in full opacity." }; - constexpr openspace::properties::Property::PropertyInfo LabelsFadeOutEnabledInfo = { - "LabelsFadeOutEnabled", - "Labels fade Out enabled", - "Labels fade Out enabled" + constexpr openspace::properties::Property::PropertyInfo DisableCullingInfo = { + "DisableCulling", + "Culling Disabled", + "Labels culling disabled." }; - constexpr openspace::properties::Property::PropertyInfo - LabelsDisableCullingEnabledInfo = - { - "LabelsDisableCullingEnabled", - "Labels culling disabled", - "Labels culling disabled" + constexpr openspace::properties::Property::PropertyInfo DistanceEPSInfo = { + "DistanceEPS", + "Culling Distance", + "Labels culling distance from globe's center." }; - constexpr openspace::properties::Property::PropertyInfo LabelsDistanceEPSInfo = { - "LabelsDistanceEPS", - "Labels culling distance from globe's center", - "Labels culling distance from globe's center" - }; - - constexpr openspace::properties::Property::PropertyInfo LabelAlignmentOptionInfo = { - "LabelAlignmentOption", - "Label Alignment Option", + constexpr openspace::properties::Property::PropertyInfo AlignmentOptionInfo = { + "AlignmentOption", + "Alignment Option", "Labels are aligned horizontally or circularly related to the planet." }; @@ -168,57 +147,48 @@ namespace { // The path to the labels file std::optional fileName; - // [[codegen::verbatim(LabelsInfo.description)]] - std::optional labels; + // [[codegen::verbatim(EnabledInfo.description)]] + std::optional enabled; - // [[codegen::verbatim(LabelsEnableInfo.description)]] - std::optional enable; + // [[codegen::verbatim(FontSizeInfo.description)]] + std::optional fontSize; - // [[codegen::verbatim(LabelsFontSizeInfo.description)]] - std::optional labelsFontSize; + // [[codegen::verbatim(MinMaxSizeInfo.description)]] + std::optional minMaxSize; - // [[codegen::verbatim(LabelsMinSizeInfo.description)]] - std::optional labelsMinSize; + // [[codegen::verbatim(SizeInfo.description)]] + std::optional size; - // [[codegen::verbatim(LabelsMaxSizeInfo.description)]] - std::optional labelsMaxSize; + // [[codegen::verbatim(HeightOffsetInfo.description)]] + std::optional heightOffset; - // [[codegen::verbatim(LabelsSizeInfo.description)]] - std::optional labelsSize; + // [[codegen::verbatim(ColorInfo.description)]] + std::optional color [[codegen::color()]]; - // [[codegen::verbatim(LabelsMinHeightInfo.description)]] - std::optional labelsMinHeight; + // [[codegen::verbatim(OpacityInfo.description)]] + std::optional opacity [[codegen::inrange(0.f, 1.f)]]; - // [[codegen::verbatim(LabelsColorInfo.description)]] - std::optional labelsColor [[codegen::color()]]; + // [[codegen::verbatim(FadeDistancesInfo.description)]] + std::optional fadeDistances; - // [[codegen::verbatim(LabelsOpacityInfo.description)]] - std::optional labelsOpacity [[codegen::inrange(0.f, 1.0)]]; + // [[codegen::verbatim(FadeInEnabledInfo.description)]] + std::optional fadeInEnabled; - // [[codegen::verbatim(LabelsFadeInStartingDistanceInfo.description)]] - std::optional fadeInStartingDistance; + // [[codegen::verbatim(FadeOutEnabledInfo.description)]] + std::optional fadeOutEnabled; - // [[codegen::verbatim(LabelsFadeOutStartingDistanceInfo.description)]] - std::optional fadeOutStartingDistance; + // [[codegen::verbatim(DisableCullingInfo.description)]] + std::optional disableCulling; - // [[codegen::verbatim(LabelsFadeInEnabledInfo.description)]] - std::optional labelsFadeInEnabled; - - // [[codegen::verbatim(LabelsFadeOutEnabledInfo.description)]] - std::optional labelsFadeOutEnabled; - - // [[codegen::verbatim(LabelsDisableCullingEnabledInfo.description)]] - std::optional labelsDisableCullingEnabled; - - // [[codegen::verbatim(LabelsDistanceEPSInfo.description)]] - std::optional labelsDistanceEPS; + // [[codegen::verbatim(DistanceEPSInfo.description)]] + std::optional distanceEPS; enum class Alignment { Horizontally, Circularly }; - // [[codegen::verbatim(LabelAlignmentOptionInfo.description)]] - std::optional labelAlignmentOption; + // [[codegen::verbatim(AlignmentOptionInfo.description)]] + std::optional alignmentOption; }; #include "globelabelscomponent_codegen.cpp" } // namespace @@ -226,56 +196,54 @@ namespace { namespace openspace { documentation::Documentation GlobeLabelsComponent::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "globebrowsing_globelabelscomponent"; - return doc; + return codegen::doc("globebrowsing_globelabelscomponent"); } GlobeLabelsComponent::GlobeLabelsComponent() : properties::PropertyOwner({ "Labels" }) - , _labelsEnabled(LabelsInfo, false) - , _labelsFontSize(LabelsFontSizeInfo, 30, 1, 300) - , _labelsMaxSize(LabelsMaxSizeInfo, 300, 10, 1000) - , _labelsMinSize(LabelsMinSizeInfo, 4, 1, 100) - , _labelsSize(LabelsSizeInfo, 2.5, 0, 30) - , _labelsMinHeight(LabelsMinHeightInfo, 100.0, 0.0, 10000.0) - , _labelsColor( - LabelsColorInfo, - glm::vec3(1.f, 1.f, 0.f), - glm::vec3(0.f), - glm::vec3(1.f) + , _enabled(EnabledInfo, false) + , _fontSize(FontSizeInfo, 30, 1, 300) + , _minMaxSize(MinMaxSizeInfo, glm::ivec2(1, 1000), glm::ivec2(1), glm::ivec2(1000)) + , _size(SizeInfo, 2.5, 0, 30) + , _heightOffset(HeightOffsetInfo, 100.0, 0.0, 10000.0) + , _color(ColorInfo, glm::vec3(1.f, 1.f, 0.f), glm::vec3(0.f), glm::vec3(1.f)) + , _opacity(OpacityInfo, 1.f, 0.f, 1.f) + , _fadeDistances( + FadeDistancesInfo, + glm::vec2(1e4, 1e6), + glm::vec2(1.f), + glm::vec2(1e8) ) - , _labelsOpacity(LabelsOpacityInfo, 1.f, 0.f, 1.f) - , _labelsFadeInDist(LabelsFadeInStartingDistanceInfo, 1e6, 1e3, 1e8) - , _labelsFadeOutDist(LabelsFadeOutStartingDistanceInfo, 1e4, 1, 1e7) - , _labelsFadeInEnabled(LabelsFadeInEnabledInfo, false) - , _labelsFadeOutEnabled(LabelsFadeOutEnabledInfo, false) - , _labelsDisableCullingEnabled(LabelsDisableCullingEnabledInfo, false) - , _labelsDistanceEPS(LabelsDistanceEPSInfo, 100000.f, 1000.f, 10000000.f) - , _labelAlignmentOption( - LabelAlignmentOptionInfo, + , _fadeInEnabled(FadeInEnabledInfo, false) + , _fadeOutEnabled(FadeOutEnabledInfo, false) + , _disableCulling(DisableCullingInfo, false) + , _distanceEPS(DistanceEPSInfo, 100000.f, 1000.f, 10000000.f) + , _alignmentOption( + AlignmentOptionInfo, properties::OptionProperty::DisplayType::Dropdown ) { - addProperty(_labelsEnabled); - addProperty(_labelsFontSize); - addProperty(_labelsSize); - addProperty(_labelsMinHeight); - _labelsColor.setViewOption(properties::Property::ViewOptions::Color); - addProperty(_labelsColor); - addProperty(_labelsOpacity); - addProperty(_labelsFadeInDist); - addProperty(_labelsFadeOutDist); - addProperty(_labelsMinSize); - addProperty(_labelsFadeInEnabled); - addProperty(_labelsFadeOutEnabled); - addProperty(_labelsDisableCullingEnabled); - addProperty(_labelsDistanceEPS); + addProperty(_enabled); + addProperty(_fontSize); + addProperty(_size); + _minMaxSize.setViewOption(properties::Property::ViewOptions::MinMaxRange); + addProperty(_minMaxSize); + addProperty(_color); + addProperty(_opacity); + _fadeDistances.setViewOption(properties::Property::ViewOptions::MinMaxRange); + _fadeDistances.setExponent(3.f); + addProperty(_fadeDistances); + addProperty(_fadeInEnabled); + addProperty(_fadeOutEnabled); + addProperty(_heightOffset); + _color.setViewOption(properties::Property::ViewOptions::Color); + addProperty(_disableCulling); + addProperty(_distanceEPS); - _labelAlignmentOption.addOption(Horizontally, "Horizontally"); - _labelAlignmentOption.addOption(Circularly, "Circularly"); - _labelAlignmentOption = Horizontally; - addProperty(_labelAlignmentOption); + _alignmentOption.addOption(Horizontally, "Horizontally"); + _alignmentOption.addOption(Circularly, "Circularly"); + _alignmentOption = Horizontally; + addProperty(_alignmentOption); } void GlobeLabelsComponent::initialize(const ghoul::Dictionary& dictionary, @@ -289,35 +257,37 @@ void GlobeLabelsComponent::initialize(const ghoul::Dictionary& dictionary, return; } - const bool loadSuccess = loadLabelsData(absPath(p.fileName->string())); + const bool loadSuccess = loadLabelsData(absPath(p.fileName->string()).string()); if (!loadSuccess) { return; } - _labelsEnabled = p.enable.value_or(true); - _labelsFontSize = p.labelsFontSize.value_or(_labelsFontSize); - _labelsFontSize.onChange([this]() { initializeFonts(); }); - _labelsSize = p.labelsSize.value_or(_labelsSize); - _labelsMinHeight = p.labelsMinHeight.value_or(_labelsMinHeight); - _labelsColor = p.labelsColor.value_or(_labelsColor); - _labelsOpacity = p.labelsOpacity.value_or(_labelsOpacity); - _labelsFadeInEnabled = p.labelsFadeInEnabled.value_or(_labelsFadeInEnabled); - _labelsFadeInDist = p.fadeInStartingDistance.value_or(_labelsFadeInDist); - _labelsFadeOutEnabled = p.labelsFadeOutEnabled.value_or(_labelsFadeOutEnabled); - _labelsFadeOutDist = p.fadeOutStartingDistance.value_or(_labelsFadeOutDist); - _labelsMinSize = p.labelsMinSize.value_or(_labelsMinSize); - _labelsMaxSize = p.labelsMaxSize.value_or(_labelsMaxSize); - _labelsDisableCullingEnabled = - p.labelsDisableCullingEnabled.value_or(_labelsDisableCullingEnabled); - _labelsDistanceEPS = p.labelsDistanceEPS.value_or(_labelsDistanceEPS); + _enabled = p.enabled.value_or(_enabled); + _fontSize = p.fontSize.value_or(_fontSize); + _fontSize.onChange([this]() { initializeFonts(); }); - if (p.labelAlignmentOption.has_value()) { - switch (*p.labelAlignmentOption) { + // @TODO (emmbr, 2021-05-31): Temporarily set as read only, to avoid errors from font + // rendering (avoid filling font atlas) + _fontSize.setReadOnly(true); + + _size = p.size.value_or(_size); + _heightOffset = p.heightOffset.value_or(_heightOffset); + _color = p.color.value_or(_color); + _opacity = p.opacity.value_or(_opacity); + _fadeInEnabled = p.fadeInEnabled.value_or(_fadeInEnabled); + _fadeOutEnabled = p.fadeOutEnabled.value_or(_fadeOutEnabled); + _fadeDistances = p.fadeDistances.value_or(_fadeDistances); + _minMaxSize = p.minMaxSize.value_or(_minMaxSize); + _disableCulling = p.disableCulling.value_or(_disableCulling); + _distanceEPS = p.distanceEPS.value_or(_distanceEPS); + + if (p.alignmentOption.has_value()) { + switch (*p.alignmentOption) { case Parameters::Alignment::Horizontally: - _labelAlignmentOption = Horizontally; + _alignmentOption = Horizontally; break; case Parameters::Alignment::Circularly: - _labelAlignmentOption = Circularly; + _alignmentOption = Circularly; break; default: throw ghoul::MissingCaseException(); @@ -330,20 +300,19 @@ void GlobeLabelsComponent::initialize(const ghoul::Dictionary& dictionary, void GlobeLabelsComponent::initializeFonts() { _font = openspace::global::fontManager->font( "Mono", - static_cast(_labelsFontSize), + static_cast(_fontSize), ghoul::fontrendering::FontManager::Outline::Yes, - ghoul::fontrendering::FontManager::LoadGlyphs::No + ghoul::fontrendering::FontManager::LoadGlyphs::Yes ); } bool GlobeLabelsComponent::loadLabelsData(const std::string& file) { std::string cachedFile = FileSys.cacheManager()->cachedFilename( - ghoul::filesystem::File(file), - "GlobeLabelsComponent|" + identifier(), - ghoul::filesystem::CacheManager::Persistent::Yes + file, + "GlobeLabelsComponent|" + identifier() ); - bool hasCachedFile = FileSys.fileExists(cachedFile); + bool hasCachedFile = std::filesystem::is_regular_file(cachedFile); if (hasCachedFile) { LINFO(fmt::format("Cached file '{}' used for labels file: {}", cachedFile, file)); @@ -476,7 +445,9 @@ bool GlobeLabelsComponent::loadCachedFile(const std::string& file) { if (version != CurrentCacheVersion) { LINFO("The format of the cached file has changed: deleting old cache"); fileStream.close(); - FileSys.deleteFile(file); + if (std::filesystem::is_regular_file(file)) { + std::filesystem::remove(file); + } return false; } @@ -498,8 +469,7 @@ bool GlobeLabelsComponent::saveCachedFile(const std::string& file) const { LERROR(fmt::format("Error opening file '{}' for save cache file", file)); return false; } - fileStream.write(reinterpret_cast(&CurrentCacheVersion), - sizeof(int8_t)); + fileStream.write(reinterpret_cast(&CurrentCacheVersion), sizeof(int8_t)); int32_t nValues = static_cast(_labels.labelsArray.size()); if (nValues == 0) { @@ -515,7 +485,7 @@ bool GlobeLabelsComponent::saveCachedFile(const std::string& file) const { } void GlobeLabelsComponent::draw(const RenderData& data) { - if (!_labelsEnabled) { + if (!_enabled) { return; } @@ -525,21 +495,19 @@ void GlobeLabelsComponent::draw(const RenderData& data) { viewTransform; glm::dmat4 mvp = vp * _globe->modelTransform(); - glm::dvec3 globePositionWorld = glm::dvec3(_globe->modelTransform() * - glm::vec4(0.f, 0.f, 0.f, 1.f)); - glm::dvec3 cameraToGlobeDistanceWorld = globePositionWorld - - data.camera.positionVec3(); - double distanceCameraGlobeWorld = glm::length(cameraToGlobeDistanceWorld); + glm::dvec3 globePosWorld = + glm::dvec3(_globe->modelTransform() * glm::vec4(0.f, 0.f, 0.f, 1.f)); + glm::dvec3 cameraToGlobeWorld = globePosWorld - data.camera.positionVec3(); + double distanceCameraGlobeWorld = glm::length(cameraToGlobeWorld); float varyingOpacity = 1.f; - double averageRadius = ( - _globe->ellipsoid().radii().x + _globe->ellipsoid().radii().y + - _globe->ellipsoid().radii().z - ) / 3.0; - if (_labelsFadeInEnabled) { - glm::dvec2 fadeRange = glm::dvec2(averageRadius + _labelsMinHeight); - fadeRange.x += _labelsFadeInDist; + const glm::dvec3 globeRadii = _globe->ellipsoid().radii(); + double averageRadius = (globeRadii.x + globeRadii.y + globeRadii.z) / 3.0; + + if (_fadeInEnabled) { + glm::dvec2 fadeRange = glm::dvec2(averageRadius + _heightOffset); + fadeRange.x += _fadeDistances.value().y; double a = 1.0 / (fadeRange.y - fadeRange.x); double b = -(fadeRange.x / (fadeRange.y - fadeRange.x)); double funcValue = a * distanceCameraGlobeWorld + b; @@ -550,11 +518,11 @@ void GlobeLabelsComponent::draw(const RenderData& data) { } } - if (_labelsFadeOutEnabled) { + if (_fadeOutEnabled) { glm::dvec2 fadeRange = glm::dvec2( - averageRadius + _labelsMinHeight + LabelFadeOutLimitAltitudeMeters + averageRadius + _heightOffset + LabelFadeOutLimitAltitudeMeters ); - fadeRange.x += _labelsFadeOutDist; + fadeRange.x += _fadeDistances.value().x; double a = 1.0 / (fadeRange.x - fadeRange.y); double b = -(fadeRange.y / (fadeRange.x - fadeRange.y)); double funcValue = a * distanceCameraGlobeWorld + b; @@ -570,12 +538,11 @@ void GlobeLabelsComponent::draw(const RenderData& data) { void GlobeLabelsComponent::renderLabels(const RenderData& data, const glm::dmat4& modelViewProjectionMatrix, - float distToCamera, - float fadeInVariable + float distToCamera, float fadeInVariable ) { glm::vec4 textColor = glm::vec4( - glm::vec3(_labelsColor), - _labelsOpacity * fadeInVariable + glm::vec3(_color), + _opacity * fadeInVariable ); glm::dmat4 VP = glm::dmat4(data.camera.sgctInternal.projectionMatrix()) * @@ -609,11 +576,11 @@ void GlobeLabelsComponent::renderLabels(const RenderData& data, double distanceCameraToLabelWorld = glm::length(locationPositionWorld - data.camera.positionVec3()); - if (_labelsDisableCullingEnabled || - ((distToCamera > (distanceCameraToLabelWorld + _labelsDistanceEPS)) && + if (_disableCulling || + ((distToCamera > (distanceCameraToLabelWorld + _distanceEPS)) && isLabelInFrustum(VP, locationPositionWorld))) { - if (_labelAlignmentOption == Circularly) { + if (_alignmentOption == Circularly) { glm::dvec3 labelNormalObj = glm::dvec3( invModelMatrix * glm::dvec4(data.camera.positionVec3(), 1.0) ) - glm::dvec3(position); @@ -634,18 +601,19 @@ void GlobeLabelsComponent::renderLabels(const RenderData& data, orthoUp = glm::normalize(glm::cross(labelNormalObj, orthoRight)); } - position += _labelsMinHeight; + // Move the position along the normal. Note that position is in model space + position += _heightOffset.value() * glm::normalize(position); ghoul::fontrendering::FontRenderer::ProjectedLabelsInformation labelInfo; labelInfo.orthoRight = orthoRight; labelInfo.orthoUp = orthoUp; - labelInfo.minSize = _labelsMinSize; - labelInfo.maxSize = _labelsMaxSize; + labelInfo.minSize = _minMaxSize.value().x; + labelInfo.maxSize = _minMaxSize.value().y; labelInfo.cameraPos = data.camera.positionVec3(); labelInfo.cameraLookUp = data.camera.lookUpVectorWorldSpace(); labelInfo.renderType = 0; labelInfo.mvpMatrix = modelViewProjectionMatrix; - labelInfo.scale = powf(2.f, _labelsSize); + labelInfo.scale = powf(2.f, _size); labelInfo.enableDepth = true; labelInfo.enableFalseDepth = true; labelInfo.disableTransmittance = true; @@ -672,7 +640,6 @@ void GlobeLabelsComponent::renderLabels(const RenderData& data, bool GlobeLabelsComponent::isLabelInFrustum(const glm::dmat4& MVMatrix, const glm::dvec3& position) const { - // Frustum Planes glm::dvec3 col1(MVMatrix[0][0], MVMatrix[1][0], MVMatrix[2][0]); glm::dvec3 col2(MVMatrix[0][1], MVMatrix[1][1], MVMatrix[2][1]); @@ -736,10 +703,6 @@ bool GlobeLabelsComponent::isLabelInFrustum(const glm::dmat4& MVMatrix, else if ((glm::dot(nearNormal, position) + nearDistance) < -Radius) { return false; } - // The far plane testing is disabled because the atm has no depth. - /*else if ((glm::dot(farNormal, position) + farDistance) < -Radius) { - return false; - }*/ return true; } diff --git a/modules/globebrowsing/src/globelabelscomponent.h b/modules/globebrowsing/src/globelabelscomponent.h index ce56c80b0d..a14ede7078 100644 --- a/modules/globebrowsing/src/globelabelscomponent.h +++ b/modules/globebrowsing/src/globelabelscomponent.h @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include #include #include @@ -68,7 +70,6 @@ private: float distToCamera, float fadeInVariable); bool isLabelInFrustum(const glm::dmat4& MVMatrix, const glm::dvec3& position) const; -private: // Labels Structures struct LabelEntry { char feature[256]; @@ -83,30 +84,29 @@ private: std::vector labelsArray; }; - properties::BoolProperty _labelsEnabled; - properties::FloatProperty _labelsFontSize; - properties::IntProperty _labelsMaxSize; - properties::IntProperty _labelsMinSize; - properties::FloatProperty _labelsSize; - properties::FloatProperty _labelsMinHeight; - properties::Vec3Property _labelsColor; - properties::FloatProperty _labelsOpacity; - properties::FloatProperty _labelsFadeInDist; - properties::FloatProperty _labelsFadeOutDist; - properties::BoolProperty _labelsFadeInEnabled; - properties::BoolProperty _labelsFadeOutEnabled; - properties::BoolProperty _labelsDisableCullingEnabled; - properties::FloatProperty _labelsDistanceEPS; - properties::OptionProperty _labelAlignmentOption; + properties::BoolProperty _enabled; + properties::FloatProperty _fontSize; + properties::FloatProperty _size; + properties::IVec2Property _minMaxSize; + properties::FloatProperty _heightOffset; + + properties::Vec3Property _color; + properties::FloatProperty _opacity; + + properties::Vec2Property _fadeDistances; + properties::BoolProperty _fadeInEnabled; + properties::BoolProperty _fadeOutEnabled; + properties::BoolProperty _disableCulling; + properties::FloatProperty _distanceEPS; + properties::OptionProperty _alignmentOption; -private: Labels _labels; // Font std::shared_ptr _font; // Globe - globebrowsing::RenderableGlobe* _globe; + globebrowsing::RenderableGlobe* _globe = nullptr; }; } // namespace openspace diff --git a/modules/globebrowsing/src/globetranslation.cpp b/modules/globebrowsing/src/globetranslation.cpp index 6056b81a52..d1097c35de 100644 --- a/modules/globebrowsing/src/globetranslation.cpp +++ b/modules/globebrowsing/src/globetranslation.cpp @@ -98,9 +98,7 @@ namespace { namespace openspace::globebrowsing { documentation::Documentation GlobeTranslation::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "space_translation_globetranslation"; - return doc; + return codegen::doc("space_translation_globetranslation"); } GlobeTranslation::GlobeTranslation(const ghoul::Dictionary& dictionary) diff --git a/modules/globebrowsing/src/layer.cpp b/modules/globebrowsing/src/layer.cpp index 43039ef251..0d9e4fbb45 100644 --- a/modules/globebrowsing/src/layer.cpp +++ b/modules/globebrowsing/src/layer.cpp @@ -179,9 +179,7 @@ namespace { } // namespace documentation::Documentation Layer::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "globebrowsing_layer"; - return doc; + return codegen::doc("globebrowsing_layer"); } Layer::Layer(layergroupid::GroupID id, const ghoul::Dictionary& layerDict, diff --git a/modules/globebrowsing/src/layeradjustment.cpp b/modules/globebrowsing/src/layeradjustment.cpp index 512fdaf88d..ac9da38447 100644 --- a/modules/globebrowsing/src/layeradjustment.cpp +++ b/modules/globebrowsing/src/layeradjustment.cpp @@ -70,9 +70,7 @@ namespace { namespace openspace::globebrowsing { documentation::Documentation LayerAdjustment::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "globebrowsing_layeradjustment"; - return doc; + return codegen::doc("globebrowsing_layeradjustment"); } LayerAdjustment::LayerAdjustment() diff --git a/modules/globebrowsing/src/rawtiledatareader.cpp b/modules/globebrowsing/src/rawtiledatareader.cpp index 81254ff64d..6b7b56951a 100644 --- a/modules/globebrowsing/src/rawtiledatareader.cpp +++ b/modules/globebrowsing/src/rawtiledatareader.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #ifdef _MSC_VER #pragma warning (push) @@ -450,7 +451,7 @@ void RawTileDataReader::initialize() { if (module.isWMSCachingEnabled()) { ZoneScopedN("WMS Caching") std::string c; - if (FileSys.fileExists(_datasetFilePath)) { + if (std::filesystem::is_regular_file(_datasetFilePath)) { // Only replace the 'content' if the dataset is an XML file and we want to do // caching std::ifstream t(_datasetFilePath); @@ -486,7 +487,7 @@ void RawTileDataReader::initialize() { CPLCreateXMLElementAndValue( cache, "Path", - absPath(module.wmsCacheLocation()).c_str() + absPath(module.wmsCacheLocation()).string().c_str() ); CPLCreateXMLElementAndValue(cache, "Depth", "4"); CPLCreateXMLElementAndValue(cache, "Expires", "315576000"); // 10 years diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index 39c561518f..02ef8d540c 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -107,62 +108,57 @@ namespace { constexpr openspace::properties::Property::PropertyInfo ShowChunkEdgeInfo = { "ShowChunkEdges", "Show chunk edges", - "" // @TODO Missing documentation - }; - - constexpr openspace::properties::Property::PropertyInfo ShowChunkBoundsInfo = { - "ShowChunkBounds", - "Show chunk bounds", - "" // @TODO Missing documentation - }; - - constexpr openspace::properties::Property::PropertyInfo HeightResolutionInfo = { - "ShowHeightResolution", - "Show height resolution", - "" // @TODO Missing documentation - }; - - constexpr openspace::properties::Property::PropertyInfo HeightIntensityInfo = { - "ShowHeightIntensities", - "Show height intensities", - "" // @TODO Missing documentation + "If this value is set to 'true', the borders between chunks are shown using a " + "red highlight" }; constexpr openspace::properties::Property::PropertyInfo LevelProjectedAreaInfo = { "LevelByProjectedAreaElseDistance", "Level by projected area (else distance)", - "" // @TODO Missing documentation + "If this value is set to 'true', the tile level is determined by the area " + "projected on screen. If it is 'false', the distance to the center of the tile " + "is used instead." }; constexpr openspace::properties::Property::PropertyInfo ResetTileProviderInfo = { "ResetTileProviders", "Reset tile providers", - "" // @TODO Missing documentation + "If this property is triggered, all tile provides for the globe are reset and " + "data is reloaded from scratch." }; constexpr openspace::properties::Property::PropertyInfo ModelSpaceRenderingInfo = { "ModelSpaceRenderingCutoffLevel", "Model Space Rendering Cutoff Level", - "" // @TODO Missing documentation + "This value determines the tile level that is used as the cut off between " + "rendering tiles using the globe model rendering vs the flat in-game rendering " + "method. This value is a tradeoff between not having precision errors in the " + "rendering and represting a tile as flat or curved." }; constexpr openspace::properties::Property::PropertyInfo DynamicLodIterationCountInfo = { "DynamicLodIterationCount", "Data availability checks before LOD factor impact", - "" // @TODO Missing documentation + "The number of checks that have to fail/succeed in a row before the dynamic " + "level-of-detail adjusts the actual level-of-detail up or down during a session " + "recording" }; constexpr openspace::properties::Property::PropertyInfo PerformShadingInfo = { "PerformShading", "Perform shading", - "" // @TODO Missing documentation + "This value determines whether there should be lighting applied to the surface " + "of the globe. Note that if there is an atmosphere attached to the planet, there " + "is a separate setting to control the shadowing induced by the atmosphere part." }; constexpr openspace::properties::Property::PropertyInfo AccurateNormalsInfo = { "UseAccurateNormals", "Use Accurate Normals", - "" // @TODO Missing documentation + "This value determines whether higher-accuracy normals should be used in the " + "rendering. These normals are calculated based on the height field information " + "and are thus only available if the planet has a height map" }; constexpr openspace::properties::Property::PropertyInfo EclipseInfo = { @@ -200,25 +196,22 @@ namespace { constexpr openspace::properties::Property::PropertyInfo TargetLodScaleFactorInfo = { "TargetLodScaleFactor", "Target Level of Detail Scale Factor", - "" // @TODO Missing documentation + "Determines the targeted level-of-detail of the tiles for this globe. A higher " + "value means that the tiles rendered are a higher resolution for the same " + "distance of the camera to the planet." }; constexpr openspace::properties::Property::PropertyInfo CurrentLodScaleFactorInfo = { "CurrentLodScaleFactor", "Current Level of Detail Scale Factor (Read Only)", - "" // @TODO Missing documentation - }; - - constexpr openspace::properties::Property::PropertyInfo CameraMinHeightInfo = { - "CameraMinHeight", - "Camera Minimum Height", - "" // @TODO Missing documentation + "The currently used scale factor whose target value is deteremined by " + "'TargetLodScaleFactor'." }; constexpr openspace::properties::Property::PropertyInfo OrenNayarRoughnessInfo = { "OrenNayarRoughness", "orenNayarRoughness", - "" // @TODO Missing documentation + "The roughness factor that is used for the Oren-Nayar lighting mode" }; constexpr openspace::properties::Property::PropertyInfo NActiveLayersInfo = { @@ -497,18 +490,13 @@ Chunk::Chunk(const TileIndex& ti) {} documentation::Documentation RenderableGlobe::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "globebrowsing_renderableglobe"; - return doc; + return codegen::doc("globebrowsing_renderableglobe"); } RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _debugProperties({ BoolProperty(ShowChunkEdgeInfo, false), - BoolProperty(ShowChunkBoundsInfo, false), - BoolProperty(HeightResolutionInfo, false), - BoolProperty(HeightIntensityInfo, false), BoolProperty(LevelProjectedAreaInfo, true), BoolProperty(ResetTileProviderInfo, false), IntProperty(ModelSpaceRenderingInfo, 14, 1, 22), @@ -524,7 +512,6 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) IntProperty(NumberShadowSamplesInfo, 5, 1, 7), FloatProperty(TargetLodScaleFactorInfo, 15.f, 1.f, 50.f), FloatProperty(CurrentLodScaleFactorInfo, 15.f, 1.f, 50.f), - FloatProperty(CameraMinHeightInfo, 100.f, 0.f, 1000.f), FloatProperty(OrenNayarRoughnessInfo, 0.f, 0.f, 1.f), IntProperty(NActiveLayersInfo, 0, 0, OpenGLCap.maxTextureUnits() / 3) }) @@ -605,16 +592,11 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) }); addProperty(_generalProperties.targetLodScaleFactor); addProperty(_generalProperties.currentLodScaleFactor); - addProperty(_generalProperties.cameraMinHeight); addProperty(_generalProperties.orenNayarRoughness); _generalProperties.nActiveLayers.setReadOnly(true); addProperty(_generalProperties.nActiveLayers); _debugPropertyOwner.addProperty(_debugProperties.showChunkEdges); - //_debugPropertyOwner.addProperty(_debugProperties.showChunkBounds); - //_debugPropertyOwner.addProperty(_debugProperties.showChunkAABB); - //_debugPropertyOwner.addProperty(_debugProperties.showHeightResolution); - //_debugPropertyOwner.addProperty(_debugProperties.showHeightIntensities); _debugPropertyOwner.addProperty(_debugProperties.levelByProjectedAreaElseDistance); _debugPropertyOwner.addProperty(_debugProperties.resetTileProviders); _debugPropertyOwner.addProperty(_debugProperties.modelSpaceRenderingCutoffLevel); @@ -628,8 +610,6 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) _generalProperties.eclipseHardShadows.onChange(notifyShaderRecompilation); _generalProperties.performShading.onChange(notifyShaderRecompilation); _debugProperties.showChunkEdges.onChange(notifyShaderRecompilation); - _debugProperties.showHeightResolution.onChange(notifyShaderRecompilation); - _debugProperties.showHeightIntensities.onChange(notifyShaderRecompilation); _layerManager.onChange([&](Layer* l) { _shadersNeedRecompilation = true; @@ -745,13 +725,14 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask // Render from light source point of view renderChunks(lightRenderData, rendererTask, {}, true); if (_hasRings && _ringsComponent.isEnabled()) { - _ringsComponent.draw(lightRenderData, RingsComponent::GeometryOnly); + _ringsComponent.draw( + lightRenderData, + RingsComponent::RenderPass::GeometryOnly + ); } glEnable(GL_BLEND); - _shadowComponent.setViewDepthMap(false); - _shadowComponent.end(); // Render again from original point of view @@ -759,7 +740,7 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask if (_hasRings && _ringsComponent.isEnabled()) { _ringsComponent.draw( data, - RingsComponent::GeometryAndShading, + RingsComponent::RenderPass::GeometryAndShading, _shadowComponent.shadowMapData() ); } @@ -767,7 +748,10 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask else { renderChunks(data, rendererTask); if (_hasRings && _ringsComponent.isEnabled()) { - _ringsComponent.draw(data, RingsComponent::GeometryAndShading); + _ringsComponent.draw( + data, + RingsComponent::RenderPass::GeometryAndShading + ); } } } @@ -808,13 +792,6 @@ void RenderableGlobe::update(const UpdateData& data) { _localRenderer.program->setUniform("xSegments", _grid.xSegments); - if (_debugProperties.showHeightResolution) { - _localRenderer.program->setUniform( - "vertexResolution", - glm::vec2(_grid.xSegments, _grid.ySegments) - ); - } - ghoul::opengl::updateUniformLocations( *_localRenderer.program, _localRenderer.uniformCache, @@ -827,12 +804,6 @@ void RenderableGlobe::update(const UpdateData& data) { _globalRenderer.program->setUniform("xSegments", _grid.xSegments); - if (_debugProperties.showHeightResolution) { - _globalRenderer.program->setUniform( - "vertexResolution", - glm::vec2(_grid.xSegments, _grid.ySegments) - ); - } // Ellipsoid Radius (Model Space) _globalRenderer.program->setUniform( "radiiSquared", @@ -1220,48 +1191,32 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&, } _localRenderer.program->deactivate(); - if (_debugProperties.showChunkBounds) { - for (int i = 0; i < globalCount; ++i) { - debugRenderChunk( - *_globalChunkBuffer[i], - mvp, - _debugProperties.showChunkBounds - ); + if (global::sessionRecording->isSavingFramesDuringPlayback()) { + // If our tile cache is very full, we assume we need to adjust the level of detail + // dynamically to not keep rendering frames with unavailable data + // After certain number of iterations(_debugProperties.dynamicLodIterationCount) of + // unavailable/available data in a row, we assume that a change could be made. + const int iterCount = _debugProperties.dynamicLodIterationCount; + const bool exceededIterations = + static_cast(_iterationsOfUnavailableData) > iterCount; + const float clf = _generalProperties.currentLodScaleFactor; + const float clfMin = _generalProperties.currentLodScaleFactor.minValue(); + const float targetLod = _generalProperties.targetLodScaleFactor; + const bool validLodFactor = clf > clfMin; + if (exceededIterations && validLodFactor) { + _generalProperties.currentLodScaleFactor = + _generalProperties.currentLodScaleFactor - 0.1f; + _iterationsOfUnavailableData = 0; + _lodScaleFactorDirty = true; + } // Make 2 times the iterations with available data to move it up again + else if (static_cast(_iterationsOfAvailableData) > + (iterCount * 2) && clf < targetLod) + { + _generalProperties.currentLodScaleFactor = + _generalProperties.currentLodScaleFactor + 0.1f; + _iterationsOfAvailableData = 0; + _lodScaleFactorDirty = true; } - - for (int i = 0; i < localCount; ++i) { - debugRenderChunk( - *_localChunkBuffer[i], - mvp, - _debugProperties.showChunkBounds - ); - } - } - - // If our tile cache is very full, we assume we need to adjust the level of detail - // dynamically to not keep rendering frames with unavailable data - // After certain number of iterations(_debugProperties.dynamicLodIterationCount) of - // unavailable/available data in a row, we assume that a change could be made. - const int iterCount = _debugProperties.dynamicLodIterationCount; - const bool exceededIterations = - static_cast(_iterationsOfUnavailableData) > iterCount; - const float clf = _generalProperties.currentLodScaleFactor; - const float clfMin = _generalProperties.currentLodScaleFactor.minValue(); - const float targetLod = _generalProperties.targetLodScaleFactor; - const bool validLodFactor = clf > clfMin; - if (exceededIterations && validLodFactor) { - _generalProperties.currentLodScaleFactor = - _generalProperties.currentLodScaleFactor - 0.1f; - _iterationsOfUnavailableData = 0; - _lodScaleFactorDirty = true; - } // Make 2 times the iterations with available data to move it up again - else if (static_cast(_iterationsOfAvailableData) > - (iterCount * 2) && clf < targetLod) - { - _generalProperties.currentLodScaleFactor = - _generalProperties.currentLodScaleFactor + 0.1f; - _iterationsOfAvailableData = 0; - _lodScaleFactorDirty = true; } } @@ -1658,12 +1613,8 @@ void RenderableGlobe::recompileShaders() { std::to_string(_generalProperties.shadowMapping) ); pairs.emplace_back("showChunkEdges", std::to_string(_debugProperties.showChunkEdges)); - pairs.emplace_back("showHeightResolution", - std::to_string(_debugProperties.showHeightResolution) - ); - pairs.emplace_back("showHeightIntensities", - std::to_string(_debugProperties.showHeightIntensities) - ); + pairs.emplace_back("showHeightResolution", "0"); + pairs.emplace_back("showHeightIntensities", "0"); pairs.emplace_back("defaultHeight", std::to_string(DefaultHeight)); @@ -1771,13 +1722,6 @@ void RenderableGlobe::recompileShaders() { _localRenderer.program->setUniform("xSegments", _grid.xSegments); - if (_debugProperties.showHeightResolution) { - _localRenderer.program->setUniform( - "vertexResolution", - glm::vec2(_grid.xSegments, _grid.ySegments) - ); - } - ghoul::opengl::updateUniformLocations( *_localRenderer.program, _localRenderer.uniformCache, @@ -1799,12 +1743,6 @@ void RenderableGlobe::recompileShaders() { _globalRenderer.program->setUniform("xSegments", _grid.xSegments); - if (_debugProperties.showHeightResolution) { - _globalRenderer.program->setUniform( - "vertexResolution", - glm::vec2(_grid.xSegments, _grid.ySegments) - ); - } // Ellipsoid Radius (Model Space) _globalRenderer.program->setUniform( "radiiSquared", diff --git a/modules/globebrowsing/src/renderableglobe.h b/modules/globebrowsing/src/renderableglobe.h index c1ce8d7a98..35247cefe7 100644 --- a/modules/globebrowsing/src/renderableglobe.h +++ b/modules/globebrowsing/src/renderableglobe.h @@ -123,9 +123,6 @@ private: struct { properties::BoolProperty showChunkEdges; - properties::BoolProperty showChunkBounds; - properties::BoolProperty showHeightResolution; - properties::BoolProperty showHeightIntensities; properties::BoolProperty levelByProjectedAreaElseDistance; properties::BoolProperty resetTileProviders; properties::IntProperty modelSpaceRenderingCutoffLevel; @@ -142,7 +139,6 @@ private: properties::IntProperty nShadowSamples; properties::FloatProperty targetLodScaleFactor; properties::FloatProperty currentLodScaleFactor; - properties::FloatProperty cameraMinHeight; properties::FloatProperty orenNayarRoughness; properties::IntProperty nActiveLayers; } _generalProperties; diff --git a/modules/globebrowsing/src/ringscomponent.cpp b/modules/globebrowsing/src/ringscomponent.cpp index e59917235b..c54bb66491 100644 --- a/modules/globebrowsing/src/ringscomponent.cpp +++ b/modules/globebrowsing/src/ringscomponent.cpp @@ -55,13 +55,13 @@ namespace { constexpr const char* _loggerCat = "RingsComponent"; constexpr const std::array UniformNames = { - "modelViewProjectionMatrix", "textureOffset", "colorFilterValue", "_nightFactor", + "modelViewProjectionMatrix", "textureOffset", "colorFilterValue", "nightFactor", "sunPosition", "ringTexture", "shadowMatrix", "shadowMapTexture", "zFightingPercentage" }; constexpr const std::array UniformNamesAdvancedRings = { - "modelViewProjectionMatrix", "textureOffset", "colorFilterValue", "_nightFactor", + "modelViewProjectionMatrix", "textureOffset", "colorFilterValue", "nightFactor", "sunPosition", "sunPositionObj", "camPositionObj", "ringTextureFwrd", "ringTextureBckwrd", "ringTextureUnlit", "ringTextureColor", "ringTextureTransparency", "shadowMatrix", "shadowMapTexture", "zFightingPercentage" @@ -122,10 +122,10 @@ namespace { constexpr openspace::properties::Property::PropertyInfo OffsetInfo = { "Offset", "Offset", - "This value is used to limit the width of the rings.Each of the two values is a " - "value between 0 and 1, where 0 is the center of the ring and 1 is the maximum " - "extent at the radius. If this value is, for example {0.5, 1.0}, the ring is " - "only shown between radius/2 and radius. It defaults to {0.0, 1.0}." + "This value is used to limit the width of the rings. Each of the two values is " + "a value between 0 and 1, where 0 is the center of the ring and 1 is the " + "maximum extent at the radius. For example, if the value is {0.5, 1.0}, the " + "ring is only shown between radius/2 and radius. It defaults to {0.0, 1.0}." }; constexpr openspace::properties::Property::PropertyInfo NightFactorInfo = { @@ -200,9 +200,7 @@ namespace { namespace openspace { documentation::Documentation RingsComponent::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "globebrowsing_rings_component"; - return doc; + return codegen::doc("globebrowsing_rings_component"); } RingsComponent::RingsComponent(const ghoul::Dictionary& dictionary) @@ -251,60 +249,63 @@ void RingsComponent::initialize() { addProperty(_enabled); - _size.setViewOption(properties::Property::ViewOptions::Logarithmic); + _size.setExponent(15.f); _size = p.size.value_or(_size); _size.onChange([&]() { _planeIsDirty = true; }); addProperty(_size); if (p.texture.has_value()) { - _texturePath = absPath(p.texture->string()); - _textureFile = std::make_unique(_texturePath); - _texturePath.onChange([&]() { loadTexture(); }); + _texturePath = absPath(p.texture->string()).string(); + _textureFile = std::make_unique(_texturePath.value()); + _texturePath.onChange([this]() { loadTexture(); }); addProperty(_texturePath); - _textureFile->setCallback([&](const File&) { _textureIsDirty = true; }); + _textureFile->setCallback([this]() { _textureIsDirty = true; }); } if (p.textureFwrd.has_value()) { - _textureFwrdPath = absPath(p.textureFwrd->string()); - _textureFileForwards = std::make_unique(_textureFwrdPath); - _textureFwrdPath.onChange([&]() { loadTexture(); }); + _textureFwrdPath = absPath(p.textureFwrd->string()).string(); + _textureFileForwards = std::make_unique(_textureFwrdPath.value()); + _textureFwrdPath.onChange([this]() { loadTexture(); }); addProperty(_textureFwrdPath); - _textureFileForwards->setCallback([&](const File&) { _textureIsDirty = true; }); + _textureFileForwards->setCallback([this]() { _textureIsDirty = true; }); } if (p.textureBckwrd.has_value()) { - _textureBckwrdPath = absPath(p.textureBckwrd->string()); - _textureFileBackwards = std::make_unique(_textureBckwrdPath); - _textureBckwrdPath.onChange([&]() { loadTexture(); }); + _textureBckwrdPath = absPath(p.textureBckwrd->string()).string(); + _textureFileBackwards = std::make_unique(_textureBckwrdPath.value()); + _textureBckwrdPath.onChange([this]() { loadTexture(); }); addProperty(_textureBckwrdPath); - _textureFileBackwards->setCallback([&](const File&) { _textureIsDirty = true; }); + _textureFileBackwards->setCallback([this]() { _textureIsDirty = true; }); } if (p.textureUnlit.has_value()) { - _textureUnlitPath = absPath(p.textureUnlit->string()); - _textureFileUnlit = std::make_unique(_textureUnlitPath); - _textureUnlitPath.onChange([&]() { loadTexture(); }); + _textureUnlitPath = absPath(p.textureUnlit->string()).string(); + _textureFileUnlit = std::make_unique(_textureUnlitPath.value()); + _textureUnlitPath.onChange([this]() { loadTexture(); }); addProperty(_textureUnlitPath); - _textureFileUnlit->setCallback([&](const File&) { _textureIsDirty = true; }); + _textureFileUnlit->setCallback([this]() { _textureIsDirty = true; }); } if (p.textureColor.has_value()) { - _textureColorPath = absPath(p.textureColor->string()); - _textureFileColor = std::make_unique(_textureColorPath); - _textureColorPath.onChange([&]() { loadTexture(); }); + _textureColorPath = absPath(p.textureColor->string()).string(); + _textureFileColor = std::make_unique(_textureColorPath.value()); + _textureColorPath.onChange([this]() { loadTexture(); }); addProperty(_textureColorPath); - _textureFileColor->setCallback([&](const File&) { _textureIsDirty = true; }); + _textureFileColor->setCallback([this]() { _textureIsDirty = true; }); } if (p.textureTransparency.has_value()) { - _textureTransparencyPath = absPath(p.textureTransparency->string()); - _textureFileTransparency = std::make_unique(_textureTransparencyPath); - _textureTransparencyPath.onChange([&]() { loadTexture(); }); + _textureTransparencyPath = absPath(p.textureTransparency->string()).string(); + _textureFileTransparency = std::make_unique( + _textureTransparencyPath.value() + ); + _textureTransparencyPath.onChange([this]() { loadTexture(); }); addProperty(_textureTransparencyPath); - _textureFileTransparency->setCallback([&](const File&) { _textureIsDirty = true; }); + _textureFileTransparency->setCallback([this]() { _textureIsDirty = true; }); } _offset = p.offset.value_or(_offset); + _offset.setViewOption(properties::Property::ViewOptions::MinMaxRange); addProperty(_offset); _nightFactor = p.nightFactor.value_or(_nightFactor); @@ -380,14 +381,13 @@ void RingsComponent::deinitializeGL() { _geometryOnlyShader = nullptr; } -void RingsComponent::draw(const RenderData& data, - const RingsComponent::RenderPass renderPass, +void RingsComponent::draw(const RenderData& data, RenderPass renderPass, const ShadowComponent::ShadowMapData& shadowData) { - if (renderPass == GeometryAndShading) { + if (renderPass == RenderPass::GeometryAndShading) { _shader->activate(); } - else if (renderPass == GeometryOnly) { + else if (renderPass == RenderPass::GeometryOnly) { _geometryOnlyShader->activate(); } @@ -406,7 +406,7 @@ void RingsComponent::draw(const RenderData& data, ghoul::opengl::TextureUnit ringTextureUnlitUnit; ghoul::opengl::TextureUnit ringTextureColorUnit; ghoul::opengl::TextureUnit ringTextureTransparencyUnit; - if (renderPass == GeometryAndShading) { + if (renderPass == RenderPass::GeometryAndShading) { if (_isAdvancedTextureEnabled) { _shader->setUniform( _uniformCacheAdvancedRings.modelViewProjectionMatrix, @@ -540,7 +540,7 @@ void RingsComponent::draw(const RenderData& data, glEnablei(GL_BLEND, 0); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } - else if (renderPass == GeometryOnly) { + else if (renderPass == RenderPass::GeometryOnly) { _geometryOnlyShader->setUniform( _geomUniformCache.modelViewProjectionMatrix, modelViewProjectionTransform @@ -566,12 +566,11 @@ void RingsComponent::draw(const RenderData& data, glEnable(GL_CULL_FACE); - if (renderPass == GeometryAndShading) { + if (renderPass == RenderPass::GeometryAndShading) { _shader->deactivate(); global::renderEngine->openglStateCache().resetBlendState(); - //global::renderEngine->openglStateCache().resetDepthState(); } - else if (renderPass == GeometryOnly) { + else if (renderPass == RenderPass::GeometryOnly) { _geometryOnlyShader->deactivate(); } } @@ -615,7 +614,7 @@ void RingsComponent::loadTexture() { if (!_texturePath.value().empty()) { std::unique_ptr texture = TextureReader::ref().loadTexture( - absPath(_texturePath) + absPath(_texturePath).string() ); if (texture) { @@ -628,16 +627,16 @@ void RingsComponent::loadTexture() { _texture->uploadTexture(); _texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); - _textureFile = std::make_unique(_texturePath); - _textureFile->setCallback( - [&](const ghoul::filesystem::File&) { _textureIsDirty = true; } + _textureFile = std::make_unique( + _texturePath.value() ); + _textureFile->setCallback([this]() { _textureIsDirty = true; }); } } if (!_textureFwrdPath.value().empty()) { std::unique_ptr textureForwards = TextureReader::ref().loadTexture( - absPath(_textureFwrdPath) + absPath(_textureFwrdPath).string() ); if (textureForwards) { @@ -655,17 +654,15 @@ void RingsComponent::loadTexture() { ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); _textureFileForwards = std::make_unique( - _textureFwrdPath - ); - _textureFileForwards->setCallback( - [&](const ghoul::filesystem::File&) { _textureIsDirty = true; } + _textureFwrdPath.value() ); + _textureFileForwards->setCallback([this]() { _textureIsDirty = true; }); } } if (!_textureBckwrdPath.value().empty()) { std::unique_ptr textureBackwards = TextureReader::ref().loadTexture( - absPath(_textureBckwrdPath) + absPath(_textureBckwrdPath).string() ); if (textureBackwards) { @@ -683,17 +680,15 @@ void RingsComponent::loadTexture() { ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); _textureFileBackwards = std::make_unique( - _textureBckwrdPath - ); - _textureFileBackwards->setCallback( - [&](const ghoul::filesystem::File&) { _textureIsDirty = true; } + _textureBckwrdPath.value() ); + _textureFileBackwards->setCallback([this]() { _textureIsDirty = true; }); } } if (!_textureUnlitPath.value().empty()) { std::unique_ptr textureUnlit = TextureReader::ref().loadTexture( - absPath(_textureUnlitPath) + absPath(_textureUnlitPath).string() ); if (textureUnlit) { @@ -707,18 +702,18 @@ void RingsComponent::loadTexture() { _textureUnlit = std::move(textureUnlit); _textureUnlit->uploadTexture(); - _textureUnlit->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); + _textureUnlit->setFilter(Texture::FilterMode::AnisotropicMipMap); - _textureFileUnlit = std::make_unique(_textureUnlitPath); - _textureFileUnlit->setCallback( - [&](const ghoul::filesystem::File&) { _textureIsDirty = true; } + _textureFileUnlit = std::make_unique( + _textureUnlitPath.value() ); + _textureFileUnlit->setCallback([this]() { _textureIsDirty = true; }); } } if (!_textureColorPath.value().empty()) { std::unique_ptr textureColor = TextureReader::ref().loadTexture( - absPath(_textureColorPath) + absPath(_textureColorPath).string() ); if (textureColor) { @@ -732,18 +727,18 @@ void RingsComponent::loadTexture() { _textureColor = std::move(textureColor); _textureColor->uploadTexture(); - _textureColor->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); + _textureColor->setFilter(Texture::FilterMode::AnisotropicMipMap); - _textureFileColor = std::make_unique(_textureColorPath); - _textureFileColor->setCallback( - [&](const ghoul::filesystem::File&) { _textureIsDirty = true; } + _textureFileColor = std::make_unique( + _textureColorPath.value() ); + _textureFileColor->setCallback([this]() { _textureIsDirty = true; }); } } if (!_textureTransparencyPath.value().empty()) { std::unique_ptr textureTransparency = TextureReader::ref().loadTexture( - absPath(_textureTransparencyPath) + absPath(_textureTransparencyPath).string() ); if (textureTransparency) { @@ -762,11 +757,9 @@ void RingsComponent::loadTexture() { ); _textureFileTransparency = std::make_unique( - _textureTransparencyPath - ); - _textureFileTransparency->setCallback( - [&](const ghoul::filesystem::File&) { _textureIsDirty = true; } + _textureTransparencyPath.value() ); + _textureFileTransparency->setCallback([this]() { _textureIsDirty = true; }); } } diff --git a/modules/globebrowsing/src/ringscomponent.h b/modules/globebrowsing/src/ringscomponent.h index c19a8565b9..6c9acc4fd3 100644 --- a/modules/globebrowsing/src/ringscomponent.h +++ b/modules/globebrowsing/src/ringscomponent.h @@ -50,7 +50,7 @@ namespace documentation { struct Documentation; } class RingsComponent : public properties::PropertyOwner { public: - enum RenderPass { + enum class RenderPass { GeometryOnly, GeometryAndShading }; @@ -63,7 +63,7 @@ public: bool isReady() const; - void draw(const RenderData& data, const RingsComponent::RenderPass renderPass, + void draw(const RenderData& data, RenderPass renderPass, const ShadowComponent::ShadowMapData& shadowData = {} ); void update(const UpdateData& data); diff --git a/modules/globebrowsing/src/shadowcomponent.cpp b/modules/globebrowsing/src/shadowcomponent.cpp index 55a5285480..f7c63a8df0 100644 --- a/modules/globebrowsing/src/shadowcomponent.cpp +++ b/modules/globebrowsing/src/shadowcomponent.cpp @@ -155,9 +155,7 @@ namespace { namespace openspace { documentation::Documentation ShadowComponent::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "globebrowsing_shadows_component"; - return doc; + return codegen::doc("globebrowsing_shadows_component"); } ShadowComponent::ShadowComponent(const ghoul::Dictionary& dictionary) @@ -356,33 +354,6 @@ void ShadowComponent::end() { if (_blendIsEnabled) { glEnable(GL_BLEND); } - - if (_viewDepthMap) { - if (!_renderDMProgram) { - _renderDMProgram = global::renderEngine->buildRenderProgram( - "ShadowMappingDebuggingProgram", - absPath("${MODULE_GLOBEBROWSING}/shaders/smviewer_vs.glsl"), - absPath("${MODULE_GLOBEBROWSING}/shaders/smviewer_fs.glsl") - ); - } - - if (!_quadVAO) { - glGenVertexArrays(1, &_quadVAO); - } - - _renderDMProgram->activate(); - - ghoul::opengl::TextureUnit shadowMapUnit; - shadowMapUnit.activate(); - glBindTexture(GL_TEXTURE_2D, _shadowDepthTexture); - - _renderDMProgram->setUniform("shadowMapTexture", shadowMapUnit); - - glBindVertexArray(_quadVAO); - glDrawArrays(GL_TRIANGLES, 0, 6); - - _renderDMProgram->deactivate(); - } } void ShadowComponent::update(const UpdateData&) { @@ -619,10 +590,6 @@ ShadowComponent::ShadowMapData ShadowComponent::shadowMapData() const { return _shadowData; } -void ShadowComponent::setViewDepthMap(bool enable) { - _viewDepthMap = enable; -} - GLuint ShadowComponent::dDepthTexture() const { return _dDepthTexture; } diff --git a/modules/globebrowsing/src/shadowcomponent.h b/modules/globebrowsing/src/shadowcomponent.h index dddea2fb66..b39c832b2a 100644 --- a/modules/globebrowsing/src/shadowcomponent.h +++ b/modules/globebrowsing/src/shadowcomponent.h @@ -77,8 +77,6 @@ public: ShadowComponent::ShadowMapData shadowMapData() const; - void setViewDepthMap(bool enable); - GLuint dDepthTexture() const; private: @@ -137,9 +135,6 @@ private: // DEBUG bool _executeDepthTextureSave = false; - bool _viewDepthMap = false; - std::unique_ptr _renderDMProgram; - GLuint _quadVAO = 0u; }; } // namespace openspace diff --git a/modules/globebrowsing/src/tileprovider.cpp b/modules/globebrowsing/src/tileprovider.cpp index ddf1200ed9..53d75717f3 100644 --- a/modules/globebrowsing/src/tileprovider.cpp +++ b/modules/globebrowsing/src/tileprovider.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include "cpl_minixml.h" @@ -148,6 +149,21 @@ namespace temporal { "This is the path to the XML configuration file that describes the temporal tile " "information." }; + + constexpr openspace::properties::Property::PropertyInfo UseFixedTimeInfo = { + "UseFixedTime", + "Use Fixed Time", + "If this value is enabled, the time-varying timevarying dataset will always use " + "the time that is specified in the 'FixedTime' property, rather than using the " + "actual time from OpenSpace" + }; + + constexpr openspace::properties::Property::PropertyInfo FixedTimeInfo = { + "FixedTime", + "Fixed Time", + "If the 'UseFixedTime' is enabled, this time will be used instead of the actual " + "time taken from OpenSpace for the displayed tiles." + }; } // namespace temporal @@ -344,12 +360,11 @@ std::unique_ptr initTileProvider(TemporalTileProvider& t, const size_t numChars = strlen(temporal::UrlTimePlaceholder); // @FRAGILE: This will only find the first instance. Dangerous if that instance is // commented out ---abock - const std::string timeSpecifiedXml = xmlTemplate.replace(pos, numChars, timekey); - std::string gdalDatasetXml = timeSpecifiedXml; + std::string xml = xmlTemplate.replace(pos, numChars, timekey); - FileSys.expandPathTokens(gdalDatasetXml, IgnoredTokens); + xml = FileSys.expandPathTokens(std::move(xml), IgnoredTokens).string(); - t.initDict.setValue(KeyFilePath, gdalDatasetXml); + t.initDict.setValue(KeyFilePath, xml); return std::make_unique(t.initDict); } @@ -375,18 +390,29 @@ TileProvider* getTileProvider(TemporalTileProvider& t, std::string_view timekey) TileProvider* getTileProvider(TemporalTileProvider& t, const Time& time) { ZoneScoped - Time tCopy(time); - if (t.timeQuantizer.quantize(tCopy, true)) { - char Buffer[22]; - const int size = timeStringify(t.timeFormat, tCopy, Buffer); + if (t.useFixedTime && !t.fixedTime.value().empty()) { try { - return getTileProvider(t, std::string_view(Buffer, size)); + return getTileProvider(t, t.fixedTime.value()); } catch (const ghoul::RuntimeError& e) { LERRORC("TemporalTileProvider", e.message); return nullptr; } } + else { + Time tCopy(time); + if (t.timeQuantizer.quantize(tCopy, true)) { + char Buffer[22]; + const int size = timeStringify(t.timeFormat, tCopy, Buffer); + try { + return getTileProvider(t, std::string_view(Buffer, size)); + } + catch (const ghoul::RuntimeError& e) { + LERRORC("TemporalTileProvider", e.message); + return nullptr; + } + } + } return nullptr; } @@ -487,9 +513,9 @@ bool readFilePath(TemporalTileProvider& t) { } // File path was not a path to a file but a GDAL config or empty - ghoul::filesystem::File f(t.filePath); - if (FileSys.fileExists(f)) { - t.initDict.setValue(temporal::KeyBasePath, f.directoryName()); + std::filesystem::path f(t.filePath.value()); + if (std::filesystem::is_regular_file(f)) { + t.initDict.setValue(temporal::KeyBasePath, f.parent_path().string()); } t.gdalXmlTemplate = consumeTemporalMetaData(t, xml); @@ -831,6 +857,8 @@ TileProviderByLevel::TileProviderByLevel(const ghoul::Dictionary& dictionary) { TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary) : initDict(dictionary) , filePath(temporal::FilePathInfo) + , useFixedTime(temporal::UseFixedTimeInfo, false) + , fixedTime(temporal::FixedTimeInfo) { ZoneScoped @@ -839,6 +867,16 @@ TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary) filePath = dictionary.value(KeyFilePath); addProperty(filePath); + if (dictionary.hasValue(temporal::UseFixedTimeInfo.identifier)) { + useFixedTime = dictionary.value(temporal::UseFixedTimeInfo.identifier); + } + addProperty(useFixedTime); + + if (dictionary.hasValue(temporal::FixedTimeInfo.identifier)) { + fixedTime = dictionary.value(temporal::FixedTimeInfo.identifier); + } + addProperty(fixedTime); + successfulInitialization = readFilePath(*this); if (!successfulInitialization) { diff --git a/modules/globebrowsing/src/tileprovider.h b/modules/globebrowsing/src/tileprovider.h index 2d70e8dd0c..0641739388 100644 --- a/modules/globebrowsing/src/tileprovider.h +++ b/modules/globebrowsing/src/tileprovider.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -174,6 +175,8 @@ struct TemporalTileProvider : public TileProvider { ghoul::Dictionary initDict; properties::StringProperty filePath; + properties::BoolProperty useFixedTime; + properties::StringProperty fixedTime; std::string gdalXmlTemplate; std::unordered_map> tileProviderMap; diff --git a/modules/globebrowsing/src/tiletextureinitdata.cpp b/modules/globebrowsing/src/tiletextureinitdata.cpp index b47d838548..04137f7d6f 100644 --- a/modules/globebrowsing/src/tiletextureinitdata.cpp +++ b/modules/globebrowsing/src/tiletextureinitdata.cpp @@ -192,7 +192,7 @@ TileTextureInitData TileTextureInitData::operator=(const TileTextureInitData& rh return rhs; } -TileTextureInitData TileTextureInitData::operator=(TileTextureInitData&& rhs) { +TileTextureInitData TileTextureInitData::operator=(TileTextureInitData&& rhs) noexcept { if (this == &rhs) { return *this; } diff --git a/modules/globebrowsing/src/tiletextureinitdata.h b/modules/globebrowsing/src/tiletextureinitdata.h index 2a311a81f5..46d0ea0215 100644 --- a/modules/globebrowsing/src/tiletextureinitdata.h +++ b/modules/globebrowsing/src/tiletextureinitdata.h @@ -49,7 +49,7 @@ public: TileTextureInitData(TileTextureInitData&& original) = default; TileTextureInitData operator=(const TileTextureInitData& rhs); - TileTextureInitData operator=(TileTextureInitData&& rhs); + TileTextureInitData operator=(TileTextureInitData&& rhs) noexcept; ~TileTextureInitData() = default; diff --git a/modules/globebrowsing/src/timequantizer.cpp b/modules/globebrowsing/src/timequantizer.cpp index a931db8a23..5317be039e 100644 --- a/modules/globebrowsing/src/timequantizer.cpp +++ b/modules/globebrowsing/src/timequantizer.cpp @@ -335,8 +335,8 @@ TimeQuantizer::TimeQuantizer(std::string start, std::string end, : _start(start) , _timerange(std::move(start), std::move(end)) { - verifyStartTimeRestrictions(); _resolution = parseTimeResolutionStr(resolution); + verifyStartTimeRestrictions(); } double TimeQuantizer::parseTimeResolutionStr(const std::string& resolutionStr) { @@ -366,18 +366,36 @@ void TimeQuantizer::setStartEndRange(const std::string& start, const std::string void TimeQuantizer::setResolution(const std::string& resolutionString) { _resolution = parseTimeResolutionStr(resolutionString); + verifyStartTimeRestrictions(); } void TimeQuantizer::verifyStartTimeRestrictions() { - if (_start.day() < 1 || _start.day() > 28) { + //If monthly time resolution then restrict to 28 days so every month is consistent + unsigned int dayUpperLimit; + std::string helpfulDescription = "the selected month"; + if (_resolutionUnit == 'M') { + dayUpperLimit = 28; + helpfulDescription = "monthly increment"; + } + else if (_resolutionUnit == 'y') { + //Get month sizes using a fixed non-leap year + dayUpperLimit = monthSize(_start.month(), 2001); + helpfulDescription += " on a yearly increment"; + } + else { + dayUpperLimit = 31; + } + if (_start.day() < 1 || _start.day() > dayUpperLimit) { throw ghoul::RuntimeError(fmt::format( - "Invalid start day value of {} for day of month. Valid days are 1 - 28", - _start.day() + "Invalid start day value of {} for {}, valid days are 1 - {}", + _start.day(), + helpfulDescription, + dayUpperLimit )); } if (_start.hour() != 0 || _start.minute() != 0 || _start.second() != 0) { throw ghoul::RuntimeError(fmt::format( - "Invalid start time value of {}:{}:{}. Time must be 00:00:00", + "Invalid start time value of {}:{}:{}, time must be 00:00:00", _start.hour(), _start.minute(), _start.second() )); } diff --git a/modules/imgui/shaders/gui_fs.glsl b/modules/imgui/shaders/gui_fs.glsl index 55266b7681..159603cd92 100644 --- a/modules/imgui/shaders/gui_fs.glsl +++ b/modules/imgui/shaders/gui_fs.glsl @@ -32,5 +32,5 @@ in vec4 out_color; out vec4 FragColor; void main() { - FragColor = out_color * texture(tex, out_uv); + FragColor = out_color * texture(tex, out_uv); } diff --git a/modules/imgui/shaders/gui_vs.glsl b/modules/imgui/shaders/gui_vs.glsl index aed40bd172..ae30863e23 100644 --- a/modules/imgui/shaders/gui_vs.glsl +++ b/modules/imgui/shaders/gui_vs.glsl @@ -34,7 +34,7 @@ out vec4 out_color; uniform mat4 ortho; void main() { - out_uv = in_uv; - out_color = in_color; - gl_Position = ortho * vec4(in_position.xy, 0.0, 1.0); + out_uv = in_uv; + out_color = in_color; + gl_Position = ortho * vec4(in_position.xy, 0.0, 1.0); } diff --git a/modules/imgui/src/gui.cpp b/modules/imgui/src/gui.cpp index b86622ba16..1329d52063 100644 --- a/modules/imgui/src/gui.cpp +++ b/modules/imgui/src/gui.cpp @@ -38,7 +38,7 @@ #include #include #include - +#include namespace { constexpr const char* _loggerCat = "GUI"; @@ -53,7 +53,7 @@ namespace { constexpr const std::array UniformNames = { "tex", "ortho" }; void addScreenSpaceRenderableLocal(std::string identifier, std::string texturePath) { - if (!FileSys.fileExists(absPath(texturePath))) { + if (!std::filesystem::is_regular_file(absPath(texturePath))) { LWARNING(fmt::format("Could not find image '{}'", texturePath)); return; } @@ -206,8 +206,7 @@ void GUI::deinitialize() { void GUI::initializeGL() { std::string cachedFile = FileSys.cacheManager()->cachedFilename( configurationFile, - "", - ghoul::filesystem::CacheManager::Persistent::Yes + "" ); LDEBUG(fmt::format("Using {} as ImGUI cache location", cachedFile)); @@ -248,9 +247,9 @@ void GUI::initializeGL() { io.KeyMap[ImGuiKey_Y] = static_cast(Key::Y); io.KeyMap[ImGuiKey_Z] = static_cast(Key::Z); - io.Fonts->AddFontFromFileTTF(absPath(GuiFont).c_str(), FontSize); + io.Fonts->AddFontFromFileTTF(absPath(GuiFont).string().c_str(), FontSize); captionFont = io.Fonts->AddFontFromFileTTF( - absPath(GuiFont).c_str(), + absPath(GuiFont).string().c_str(), FontSize * 1.5f ); diff --git a/modules/imgui/src/guiassetcomponent.cpp b/modules/imgui/src/guiassetcomponent.cpp index 92b6eedaa5..d0eedb873f 100644 --- a/modules/imgui/src/guiassetcomponent.cpp +++ b/modules/imgui/src/guiassetcomponent.cpp @@ -30,9 +30,9 @@ #include #include #include - #include #include +#include namespace { std::string assetStateToString(openspace::Asset::State state) { @@ -90,10 +90,10 @@ void GuiAssetComponent::renderTree(const Asset& asset, const std::string& relati using namespace ghoul::filesystem; std::string assetPath = asset.assetFilePath(); - const std::string& assetDirectory = File(assetPath).directoryName(); + std::string assetDirectory = std::filesystem::path(assetPath).parent_path().string(); if (!relativeToPath.empty()) { - assetPath = FileSys.relativePath(assetPath, relativeToPath); + assetPath = std::filesystem::relative(assetPath, relativeToPath).string(); } std::string assetText = assetPath + " " + assetStateToString(asset.state()); diff --git a/modules/imgui/src/guifilepathcomponent.cpp b/modules/imgui/src/guifilepathcomponent.cpp index bfee3703ad..d6f0d97f7e 100644 --- a/modules/imgui/src/guifilepathcomponent.cpp +++ b/modules/imgui/src/guifilepathcomponent.cpp @@ -51,7 +51,7 @@ void GuiFilePathComponent::render() { for (const std::string& t : tokens) { ImGui::Text("%s", t.c_str()); ImGui::NextColumn(); - ImGui::Text("%s", absPath(t).c_str()); + ImGui::Text("%s", absPath(t).string().c_str()); ImGui::NextColumn(); ImGui::Separator(); } diff --git a/modules/imgui/src/renderproperties.cpp b/modules/imgui/src/renderproperties.cpp index 6462e330f4..71f566af29 100644 --- a/modules/imgui/src/renderproperties.cpp +++ b/modules/imgui/src/renderproperties.cpp @@ -390,7 +390,7 @@ void renderDoubleProperty(properties::Property* prop, const std::string& ownerNa min, max, "%.5f", - p->exponent() + ImGuiSliderFlags_Logarithmic ); if (showTooltip) { renderTooltip(prop, tooltipDelay); @@ -545,7 +545,7 @@ void renderFloatProperty(Property* prop, const std::string& ownerName, min, max, "%.5f", - p->exponent() + ImGuiSliderFlags_Logarithmic ); if (showTooltip) { renderTooltip(prop, tooltipDelay); @@ -577,7 +577,7 @@ void renderVec2Property(Property* prop, const std::string& ownerName, min, max, "%.5f", - p->exponent() + ImGuiSliderFlags_Logarithmic ); if (showTooltip) { renderTooltip(prop, tooltipDelay); @@ -621,7 +621,7 @@ void renderVec3Property(Property* prop, const std::string& ownerName, min, max, "%.5f", - p->exponent() + ImGuiSliderFlags_Logarithmic ); } if (showTooltip) { @@ -666,7 +666,7 @@ void renderVec4Property(Property* prop, const std::string& ownerName, min, max, "%.5f", - p->exponent() + ImGuiSliderFlags_Logarithmic ); } if (showTooltip) { @@ -702,7 +702,7 @@ void renderDVec2Property(Property* prop, const std::string& ownerName, min, max, "%.5f", - p->exponent() + ImGuiSliderFlags_Logarithmic ); if (showTooltip) { renderTooltip(prop, tooltipDelay); @@ -738,7 +738,7 @@ void renderDVec3Property(Property* prop, const std::string& ownerName, min, max, "%.5f", - p->exponent() + ImGuiSliderFlags_Logarithmic ); if (showTooltip) { renderTooltip(prop, tooltipDelay); @@ -774,7 +774,7 @@ void renderDVec4Property(Property* prop, const std::string& ownerName, min, max, "%.5f", - p->exponent() + ImGuiSliderFlags_Logarithmic ); if (showTooltip) { renderTooltip(prop, tooltipDelay); @@ -822,7 +822,7 @@ void renderDMat2Property(Property* prop, const std::string& ownerName, min, max, "%.5f", - p->exponent() + ImGuiSliderFlags_Logarithmic ); changed |= ImGui::SliderFloat2( "[1]", @@ -830,7 +830,7 @@ void renderDMat2Property(Property* prop, const std::string& ownerName, min, max, "%.5f", - p->exponent() + ImGuiSliderFlags_Logarithmic ); if (showTooltip) { @@ -881,7 +881,7 @@ void renderDMat3Property(Property* prop, const std::string& ownerName, min, max, "%.5f", - p->exponent() + ImGuiSliderFlags_Logarithmic ); changed |= ImGui::SliderFloat3( "[1]", @@ -889,7 +889,7 @@ void renderDMat3Property(Property* prop, const std::string& ownerName, min, max, "%.5f", - p->exponent() + ImGuiSliderFlags_Logarithmic ); changed |= ImGui::SliderFloat3( "[2]", @@ -897,7 +897,7 @@ void renderDMat3Property(Property* prop, const std::string& ownerName, min, max, "%.5f", - p->exponent() + ImGuiSliderFlags_Logarithmic ); if (showTooltip) { @@ -950,7 +950,7 @@ void renderDMat4Property(Property* prop, const std::string& ownerName, min, max, "%.5f", - p->exponent() + ImGuiSliderFlags_Logarithmic ); changed |= ImGui::SliderFloat4( "[1]", @@ -958,7 +958,7 @@ void renderDMat4Property(Property* prop, const std::string& ownerName, min, max, "%.5f", - p->exponent() + ImGuiSliderFlags_Logarithmic ); changed |= ImGui::SliderFloat4( "[2]", @@ -966,7 +966,7 @@ void renderDMat4Property(Property* prop, const std::string& ownerName, min, max, "%.5f", - p->exponent() + ImGuiSliderFlags_Logarithmic ); changed |= ImGui::SliderFloat4( "[3]", @@ -974,7 +974,7 @@ void renderDMat4Property(Property* prop, const std::string& ownerName, min, max, "%.5f", - p->exponent() + ImGuiSliderFlags_Logarithmic ); if (showTooltip) { diff --git a/modules/iswa/rendering/datacygnet.cpp b/modules/iswa/rendering/datacygnet.cpp index 440be61f3c..6d8e217807 100644 --- a/modules/iswa/rendering/datacygnet.cpp +++ b/modules/iswa/rendering/datacygnet.cpp @@ -276,7 +276,7 @@ void DataCygnet::readTransferFunctions(std::string tfPath) { if (tfFile.is_open()) { std::string line; while (getline(tfFile, line)) { - tfs.emplace_back(absPath(line)); + tfs.emplace_back(absPath(line).string()); } tfFile.close(); diff --git a/modules/iswa/rendering/kameleonplane.cpp b/modules/iswa/rendering/kameleonplane.cpp index 78d718fa5b..82fe6a0145 100644 --- a/modules/iswa/rendering/kameleonplane.cpp +++ b/modules/iswa/rendering/kameleonplane.cpp @@ -131,7 +131,7 @@ void KameleonPlane::initializeGL() { initializeTime(); createGeometry(); - readFieldlinePaths(absPath(_fieldlineIndexFile)); + readFieldlinePaths(absPath(_fieldlineIndexFile).string()); if (_group) { _dataProcessor = _group->dataProcessor(); diff --git a/modules/iswa/util/dataprocessorkameleon.cpp b/modules/iswa/util/dataprocessorkameleon.cpp index 7c0a1b4e1c..37ee4c1381 100644 --- a/modules/iswa/util/dataprocessorkameleon.cpp +++ b/modules/iswa/util/dataprocessorkameleon.cpp @@ -31,6 +31,7 @@ #include #include #include +#include namespace openspace { @@ -158,14 +159,14 @@ void DataProcessorKameleon::setDimensions(glm::size3_t dimensions) { } void DataProcessorKameleon::initializeKameleonWrapper(std::string path) { - const std::string& extension = ghoul::filesystem::File(absPath(path)).fileExtension(); - if (FileSys.fileExists(absPath(path)) && extension == "cdf") { + std::filesystem::path extension = std::filesystem::path(absPath(path)).extension(); + if (std::filesystem::is_regular_file(absPath(path)) && extension == ".cdf") { if (_kw) { _kw->close(); } _kwPath = std::move(path); - _kw = std::make_shared(absPath(_kwPath)); + _kw = std::make_shared(absPath(_kwPath).string()); } } diff --git a/modules/iswa/util/iswamanager.cpp b/modules/iswa/util/iswamanager.cpp index ff0655fdbc..8d1fccebf1 100644 --- a/modules/iswa/util/iswamanager.cpp +++ b/modules/iswa/util/iswamanager.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include "iswamanager_lua.inl" @@ -410,10 +411,9 @@ std::string IswaManager::parseKWToLuaTable(const CdfInfo& info, const std::strin return ""; } - const std::string& extension = - ghoul::filesystem::File(absPath(info.path)).fileExtension(); - if (extension == "cdf") { - KameleonWrapper kw = KameleonWrapper(absPath(info.path)); + std::filesystem::path ext = std::filesystem::path(absPath(info.path)).extension(); + if (ext == ".cdf") { + KameleonWrapper kw = KameleonWrapper(absPath(info.path).string()); std::string parent = kw.parent(); std::string frame = kw.frame(); @@ -587,10 +587,8 @@ void IswaManager::createSphere(MetadataFuture& data) { } void IswaManager::createKameleonPlane(CdfInfo info, std::string cut) { - const std::string& extension = ghoul::filesystem::File( - absPath(info.path) - ).fileExtension(); - if (FileSys.fileExists(absPath(info.path)) && extension == "cdf") { + std::filesystem::path ext = std::filesystem::path(absPath(info.path)).extension(); + if (std::filesystem::is_regular_file(absPath(info.path)) && ext == ".cdf") { if (!info.group.empty()) { std::string type = typeid(KameleonPlane).name(); registerGroup(info.group, type); @@ -621,16 +619,17 @@ void IswaManager::createKameleonPlane(CdfInfo info, std::string cut) { } } else { - LWARNING( absPath(info.path) + " is not a cdf file or can't be found."); + LWARNING( + fmt::format("{} is not a cdf file or can't be found", absPath(info.path)) + ); } } void IswaManager::createFieldline(std::string name, std::string cdfPath, std::string seedPath) { - const std::string& ext = ghoul::filesystem::File(absPath(cdfPath)).fileExtension(); - - if (FileSys.fileExists(absPath(cdfPath)) && ext == "cdf") { + std::filesystem::path ext = std::filesystem::path(absPath(cdfPath)).extension(); + if (std::filesystem::is_regular_file(absPath(cdfPath)) && ext == ".cdf") { std::string luaTable = "{" "Name = '" + name + "'," "Parent = 'Earth'," @@ -700,10 +699,10 @@ ghoul::Event<>& IswaManager::iswaEvent() { } void IswaManager::addCdfFiles(std::string cdfpath) { - cdfpath = absPath(cdfpath); - if (FileSys.fileExists(cdfpath)) { + std::filesystem::path cdf = absPath(cdfpath); + if (std::filesystem::is_regular_file(cdf)) { //std::string basePath = path.substr(0, path.find_last_of("/\\")); - std::ifstream jsonFile(cdfpath); + std::ifstream jsonFile(cdf); if (jsonFile.is_open()) { json cdfGroups = json::parse(jsonFile); @@ -742,7 +741,7 @@ void IswaManager::addCdfFiles(std::string cdfpath) { } } else { - LWARNING(cdfpath + " is not a cdf file or can't be found."); + LWARNING(fmt::format("{} is not a cdf file or can't be found", cdf)); } } diff --git a/modules/kameleon/src/kameleonwrapper.cpp b/modules/kameleon/src/kameleonwrapper.cpp index 5528881746..05927d31d8 100644 --- a/modules/kameleon/src/kameleonwrapper.cpp +++ b/modules/kameleon/src/kameleonwrapper.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #ifdef WIN32 #pragma warning (push) @@ -113,7 +114,7 @@ KameleonWrapper::~KameleonWrapper() { bool KameleonWrapper::open(const std::string& filename) { close(); - if (!FileSys.fileExists(filename)) { + if (!std::filesystem::is_regular_file(filename)) { return false; } diff --git a/modules/kameleonvolume/kameleonvolumereader.cpp b/modules/kameleonvolume/kameleonvolumereader.cpp index 63301ba596..9d4cef1d7c 100644 --- a/modules/kameleonvolume/kameleonvolumereader.cpp +++ b/modules/kameleonvolume/kameleonvolumereader.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #ifdef WIN32 #pragma warning (push) @@ -75,7 +76,7 @@ namespace { namespace openspace::kameleonvolume { KameleonVolumeReader::KameleonVolumeReader(std::string path) : _path(std::move(path)) { - if (!FileSys.fileExists(_path)) { + if (!std::filesystem::is_regular_file(_path)) { throw ghoul::FileNotFoundError(_path); } diff --git a/modules/kameleonvolume/rendering/renderablekameleonvolume.cpp b/modules/kameleonvolume/rendering/renderablekameleonvolume.cpp index b12c28ac9f..2e8ad45922 100644 --- a/modules/kameleonvolume/rendering/renderablekameleonvolume.cpp +++ b/modules/kameleonvolume/rendering/renderablekameleonvolume.cpp @@ -45,6 +45,7 @@ #include #include #include +#include namespace { constexpr const char* _loggerCat = "RenderableKameleonVolume"; @@ -172,7 +173,7 @@ RenderableKameleonVolume::RenderableKameleonVolume(const ghoul::Dictionary& dict } if (dictionary.hasValue(KeySource)) { - _sourcePath = absPath(dictionary.value(KeySource)); + _sourcePath = absPath(dictionary.value(KeySource)).string(); } if (dictionary.hasValue(KeyVariable)) { @@ -323,7 +324,7 @@ bool RenderableKameleonVolume::isCachingEnabled() const { } void RenderableKameleonVolume::load() { - if (!FileSys.fileExists(ghoul::filesystem::File(_sourcePath))) { + if (!std::filesystem::is_regular_file(_sourcePath.value())) { LERROR(fmt::format("File '{}' does not exist", _sourcePath.value())); return; } @@ -331,13 +332,11 @@ void RenderableKameleonVolume::load() { loadFromPath(_sourcePath); return; } - ghoul::filesystem::File sourceFile(_sourcePath); std::string cachePath = FileSys.cacheManager()->cachedFilename( - sourceFile.baseName(), - cacheSuffix(), - ghoul::filesystem::CacheManager::Persistent::Yes + std::filesystem::path(_sourcePath.value()).stem(), + cacheSuffix() ); - if (FileSys.fileExists(cachePath)) { + if (std::filesystem::is_regular_file(cachePath)) { loadRaw(cachePath); } else { @@ -352,15 +351,8 @@ std::string RenderableKameleonVolume::cacheSuffix() const { } void RenderableKameleonVolume::loadFromPath(const std::string& path) { - ghoul::filesystem::File file(path); - std::string extension = file.fileExtension(); - std::transform( - extension.begin(), - extension.end(), - extension.begin(), - [](char v) { return static_cast(tolower(v)); } - ); - if (extension == "cdf") { + std::filesystem::path extension = std::filesystem::path(path).extension(); + if (extension == ".cdf" || extension == ".CDF") { loadCdf(path); } else { diff --git a/modules/kameleonvolume/tasks/kameleondocumentationtask.cpp b/modules/kameleonvolume/tasks/kameleondocumentationtask.cpp index 9e4cac12a5..2d862da6a7 100644 --- a/modules/kameleonvolume/tasks/kameleondocumentationtask.cpp +++ b/modules/kameleonvolume/tasks/kameleondocumentationtask.cpp @@ -29,30 +29,37 @@ #include #include #include +#include #include namespace { - constexpr const char* KeyInput = "Input"; - constexpr const char* KeyOutput = "Output"; constexpr const char* MainTemplateFilename = "${WEB}/kameleondocumentation/main.hbs"; constexpr const char* HandlebarsFilename = "${WEB}/common/handlebars-v4.0.5.js"; constexpr const char* JsFilename = "${WEB}/kameleondocumentation/script.js"; constexpr const char* BootstrapFilename = "${WEB}/common/bootstrap.min.css"; constexpr const char* CssFilename = "${WEB}/common/style.css"; + + struct [[codegen::Dictionary(KameleonDocumentationTask)]] Parameters { + // The CDF file to extract data from + std::filesystem::path input; + + // The HTML file to write documentation to + std::string output [[codegen::annotation("A valid filepath")]]; + }; +#include "kameleondocumentationtask_codegen.cpp" } // namespace namespace openspace::kameleonvolume { +documentation::Documentation KameleonDocumentationTask::documentation() { + return codegen::doc("kameleon_documentation_task"); +} + KameleonDocumentationTask::KameleonDocumentationTask(const ghoul::Dictionary& dictionary) { - openspace::documentation::testSpecificationAndThrow( - documentation(), - dictionary, - "KameleonDocumentationTask" - ); - - _inputPath = absPath(dictionary.value(KeyInput)); - _outputPath = absPath(dictionary.value(KeyOutput)); + const Parameters p = codegen::bake(dictionary); + _inputPath = absPath(p.input.string()); + _outputPath = absPath(p.output); } std::string KameleonDocumentationTask::description() { @@ -63,14 +70,14 @@ std::string KameleonDocumentationTask::description() { } void KameleonDocumentationTask::perform(const Task::ProgressCallback & progressCallback) { - KameleonVolumeReader reader(_inputPath); + KameleonVolumeReader reader(_inputPath.string()); ghoul::Dictionary kameleonDictionary = reader.readMetaData(); progressCallback(0.33f); ghoul::Dictionary dictionary; dictionary.setValue("kameleon", std::move(kameleonDictionary)); dictionary.setValue("version", std::string(OPENSPACE_VERSION_NUMBER)); - dictionary.setValue("input", _inputPath); + dictionary.setValue("input", _inputPath.string()); std::string json = ghoul::formatJson(dictionary); progressCallback(0.66f); @@ -146,26 +153,4 @@ void KameleonDocumentationTask::perform(const Task::ProgressCallback & progressC progressCallback(1.0f); } -documentation::Documentation KameleonDocumentationTask::documentation() { - using namespace documentation; - return { - "KameleonDocumentationTask", - "kameleon_documentation_task", - { - { - KeyInput, - new StringAnnotationVerifier("A file path to a cdf file"), - Optional::No, - "The cdf file to extract data from" - }, - { - KeyOutput, - new StringAnnotationVerifier("A valid filepath"), - Optional::No, - "The html file to write documentation to" - } - } - }; -} - } // namespace openspace::kameleonvolume diff --git a/modules/kameleonvolume/tasks/kameleondocumentationtask.h b/modules/kameleonvolume/tasks/kameleondocumentationtask.h index 566f28b8a5..b321511fac 100644 --- a/modules/kameleonvolume/tasks/kameleondocumentationtask.h +++ b/modules/kameleonvolume/tasks/kameleondocumentationtask.h @@ -27,6 +27,7 @@ #include +#include #include namespace openspace::kameleonvolume { @@ -41,8 +42,8 @@ public: static documentation::Documentation documentation(); private: - std::string _inputPath; - std::string _outputPath; + std::filesystem::path _inputPath; + std::filesystem::path _outputPath; }; } // namespace openspace::kameleonvolume diff --git a/modules/kameleonvolume/tasks/kameleonmetadatatojsontask.cpp b/modules/kameleonvolume/tasks/kameleonmetadatatojsontask.cpp index ecd1bcccf5..af8d22baa8 100644 --- a/modules/kameleonvolume/tasks/kameleonmetadatatojsontask.cpp +++ b/modules/kameleonvolume/tasks/kameleonmetadatatojsontask.cpp @@ -29,26 +29,32 @@ #include #include #include +#include #include namespace { - constexpr const char* KeyInput = "Input"; - constexpr const char* KeyOutput = "Output"; + struct [[codegen::Dictionary(KameleonMetadataToJsonTask)]] Parameters { + // The CDF file to extract data from + std::filesystem::path input; + + // The JSON file to export data into + std::string output [[codegen::annotation("A valid filepath")]]; + }; +#include "kameleonmetadatatojsontask_codegen.cpp" } // namespace namespace openspace::kameleonvolume { +documentation::Documentation KameleonMetadataToJsonTask::documentation() { + return codegen::doc("kameleon_metadata_to_json_task"); +} + KameleonMetadataToJsonTask::KameleonMetadataToJsonTask( const ghoul::Dictionary& dictionary) { - openspace::documentation::testSpecificationAndThrow( - documentation(), - dictionary, - "KameleonMetadataToJsonTask" - ); - - _inputPath = absPath(dictionary.value(KeyInput)); - _outputPath = absPath(dictionary.value(KeyOutput)); + const Parameters p = codegen::bake(dictionary); + _inputPath = absPath(p.input.string()); + _outputPath = absPath(p.output); } std::string KameleonMetadataToJsonTask::description() { @@ -59,7 +65,7 @@ std::string KameleonMetadataToJsonTask::description() { } void KameleonMetadataToJsonTask::perform(const Task::ProgressCallback& progressCallback) { - KameleonVolumeReader reader(_inputPath); + KameleonVolumeReader reader(_inputPath.string()); ghoul::Dictionary dictionary = reader.readMetaData(); progressCallback(0.5f); @@ -69,26 +75,4 @@ void KameleonMetadataToJsonTask::perform(const Task::ProgressCallback& progressC progressCallback(1.0f); } -documentation::Documentation KameleonMetadataToJsonTask::documentation() { - using namespace documentation; - return { - "KameleonMetadataToJsonTask", - "kameleon_metadata_to_json_task", - { - { - KeyInput, - new StringAnnotationVerifier("A file path to a cdf file"), - Optional::No, - "The cdf file to extract data from" - }, - { - KeyOutput, - new StringAnnotationVerifier("A valid filepath"), - Optional::No, - "The JSON file to export data into" - } - } - }; -} - } // namespace openspace::kameleonvolume diff --git a/modules/kameleonvolume/tasks/kameleonmetadatatojsontask.h b/modules/kameleonvolume/tasks/kameleonmetadatatojsontask.h index 2e392116ce..b70385e286 100644 --- a/modules/kameleonvolume/tasks/kameleonmetadatatojsontask.h +++ b/modules/kameleonvolume/tasks/kameleonmetadatatojsontask.h @@ -27,6 +27,7 @@ #include +#include #include namespace openspace::kameleonvolume { @@ -41,8 +42,8 @@ public: static documentation::Documentation documentation(); private: - std::string _inputPath; - std::string _outputPath; + std::filesystem::path _inputPath; + std::filesystem::path _outputPath; }; } // namespace openspace::kameleonvolume diff --git a/modules/kameleonvolume/tasks/kameleonvolumetorawtask.cpp b/modules/kameleonvolume/tasks/kameleonvolumetorawtask.cpp index fd9c342afe..76015be84c 100644 --- a/modules/kameleonvolume/tasks/kameleonvolumetorawtask.cpp +++ b/modules/kameleonvolume/tasks/kameleonvolumetorawtask.cpp @@ -31,13 +31,11 @@ #include #include #include +#include +#include namespace { - constexpr const char* KeyInput = "Input"; - constexpr const char* KeyRawVolumeOutput = "RawVolumeOutput"; - constexpr const char* KeyDictionaryOutput = "DictionaryOutput"; constexpr const char* KeyDimensions = "Dimensions"; - constexpr const char* KeyVariable = "Variable"; constexpr const char* KeyTime = "Time"; constexpr const char* KeyLowerDomainBound = "LowerDomainBound"; constexpr const char* KeyUpperDomainBound = "UpperDomainBound"; @@ -46,92 +44,62 @@ namespace { constexpr const char* KeyMaxValue = "MaxValue"; constexpr const char* KeyVisUnit = "VisUnit"; + + struct [[codegen::Dictionary(KameleonVolumeToRawTask)]] Parameters { + // The cdf file to extract data from + std::filesystem::path input; + + // The raw volume file to export data to + std::string rawVolumeOutput [[codegen::annotation("A valid filepath")]]; + + // The Lua dictionary file to export metadata to + std::string dictionaryOutput [[codegen::annotation("A valid filepath")]]; + + // The variable name to read from the kameleon dataset + std::string variable [[codegen::annotation("A valid kameleon variable")]]; + + // A vector representing the number of cells in each dimension + glm::ivec3 dimensions; + + // A vector representing the lower bound of the domain, in the native kameleon + // grid units + std::optional lowerDomainBound; + + // A vector representing the lower bound of the domain, in the native kameleon + // grid units + std::optional upperDomainBound; + + // The unit of the data + std::optional visUnit + [[codegen::annotation("A valid kameleon unit")]]; + }; +#include "kameleonvolumetorawtask_codegen.cpp" } // namespace namespace openspace::kameleonvolume { documentation::Documentation KameleonVolumeToRawTask::documentation() { - using namespace documentation; - return { - "KameleonVolumeToRawTask", - "kameleon_metadata_to_json_task", - { - { - KeyInput, - new StringAnnotationVerifier("A file path to a cdf file"), - Optional::No, - "The cdf file to extract data from", - }, - { - KeyRawVolumeOutput, - new StringAnnotationVerifier("A valid filepath"), - Optional::No, - "The raw volume file to export data to", - }, - { - KeyDictionaryOutput, - new StringAnnotationVerifier("A valid filepath"), - Optional::No, - "The lua dictionary file to export metadata to", - }, - { - KeyVariable, - new StringAnnotationVerifier("A valid kameleon variable"), - Optional::No, - "The variable name to read from the kameleon dataset", - }, - { - KeyDimensions, - new DoubleVector3Verifier, - Optional::No, - "A vector representing the number of cells in each dimension", - }, - { - KeyLowerDomainBound, - new DoubleVector3Verifier, - Optional::Yes, - "A vector representing the lower bound of the domain, " - "in the native kameleon grid units", - }, - { - KeyUpperDomainBound, - new DoubleVector3Verifier, - Optional::Yes, - "A vector representing the lower bound of the domain, " - "in the native kameleon grid units" - }, - { - KeyVisUnit, - new StringAnnotationVerifier("A valid kameleon unit"), - Optional::Yes, - "The unit of the data", - } - } - }; + return codegen::doc("kameleon_metadata_to_json_task"); } - KameleonVolumeToRawTask::KameleonVolumeToRawTask(const ghoul::Dictionary& dictionary) { - openspace::documentation::testSpecificationAndThrow( - documentation(), - dictionary, - "KameleonVolumeToRawTask" - ); + const Parameters p = codegen::bake(dictionary); - _inputPath = absPath(dictionary.value(KeyInput)); - _rawVolumeOutputPath = absPath(dictionary.value(KeyRawVolumeOutput)); - _dictionaryOutputPath = absPath(dictionary.value(KeyDictionaryOutput)); - _variable = dictionary.value(KeyVariable); - _dimensions = glm::uvec3(dictionary.value(KeyDimensions)); + _inputPath = absPath(p.input.string()); + _rawVolumeOutputPath = absPath(p.rawVolumeOutput); + _dictionaryOutputPath = absPath(p.dictionaryOutput); + _variable = p.variable; + _dimensions = p.dimensions; - if (dictionary.hasKey(KeyLowerDomainBound)) { - _lowerDomainBound = dictionary.value(KeyLowerDomainBound); + if (p.lowerDomainBound.has_value()) { + _lowerDomainBound = *p.lowerDomainBound; } else { _autoDomainBounds = true; } - if (dictionary.hasKey(KeyUpperDomainBound)) { - _upperDomainBound = dictionary.value(KeyUpperDomainBound); + + if (p.upperDomainBound.has_value()) { + _upperDomainBound = *p.upperDomainBound; } else { _autoDomainBounds = true; @@ -147,7 +115,7 @@ std::string KameleonVolumeToRawTask::description() { } void KameleonVolumeToRawTask::perform(const Task::ProgressCallback& progressCallback) { - KameleonVolumeReader reader(_inputPath); + KameleonVolumeReader reader(_inputPath.string()); std::array variables = reader.gridVariableNames(); @@ -174,7 +142,7 @@ void KameleonVolumeToRawTask::perform(const Task::ProgressCallback& progressCall progressCallback(0.5f); - volume::RawVolumeWriter writer(_rawVolumeOutputPath); + volume::RawVolumeWriter writer(_rawVolumeOutputPath.string()); writer.write(*rawVolume); progressCallback(0.9f); diff --git a/modules/kameleonvolume/tasks/kameleonvolumetorawtask.h b/modules/kameleonvolume/tasks/kameleonvolumetorawtask.h index b187bfcc59..040f9c998f 100644 --- a/modules/kameleonvolume/tasks/kameleonvolumetorawtask.h +++ b/modules/kameleonvolume/tasks/kameleonvolumetorawtask.h @@ -28,6 +28,7 @@ #include #include +#include #include namespace openspace::kameleonvolume { @@ -42,9 +43,9 @@ public: static documentation::Documentation documentation(); private: - std::string _inputPath; - std::string _rawVolumeOutputPath; - std::string _dictionaryOutputPath; + std::filesystem::path _inputPath; + std::filesystem::path _rawVolumeOutputPath; + std::filesystem::path _dictionaryOutputPath; std::string _variable; std::string _units; diff --git a/modules/multiresvolume/rendering/renderablemultiresvolume.cpp b/modules/multiresvolume/rendering/renderablemultiresvolume.cpp index 6e75384f79..fef5801605 100644 --- a/modules/multiresvolume/rendering/renderablemultiresvolume.cpp +++ b/modules/multiresvolume/rendering/renderablemultiresvolume.cpp @@ -54,6 +54,7 @@ #include #include #include +#include #include #include @@ -170,7 +171,7 @@ RenderableMultiresVolume::RenderableMultiresVolume(const ghoul::Dictionary& dict , _scaling(ScalingInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(10.f)) { if (dictionary.hasValue(KeyDataSource)) { - _filename = absPath(dictionary.value(KeyDataSource)); + _filename = absPath(dictionary.value(KeyDataSource)).string(); } else { LERROR(fmt::format("Node did not contain a valid '{}'", KeyDataSource)); @@ -222,7 +223,7 @@ RenderableMultiresVolume::RenderableMultiresVolume(const ghoul::Dictionary& dict if (dictionary.hasValue(KeyTransferFunction)) { _transferFunctionPath = absPath( dictionary.value(KeyTransferFunction) - ); + ).string(); _transferFunction = std::make_shared(_transferFunctionPath); } else { @@ -454,14 +455,12 @@ bool RenderableMultiresVolume::initializeSelector() { switch (_selector) { case Selector::TF: if (_errorHistogramManager) { - std::stringstream cacheName; - ghoul::filesystem::File f = _filename; - cacheName << f.baseName() << "_" << nHistograms << "_errorHistograms"; - std::string cacheFilename; - cacheFilename = FileSys.cacheManager()->cachedFilename( - cacheName.str(), - "", - ghoul::filesystem::CacheManager::Persistent::Yes + std::string cacheFilename = FileSys.cacheManager()->cachedFilename( + fmt::format( + "{}_{}_errorHistograms", + std::filesystem::path(_filename).stem().string(), nHistograms + ), + "" ); std::ifstream cacheFile(cacheFilename, std::ios::in | std::ios::binary); if (cacheFile.is_open()) { @@ -472,12 +471,14 @@ bool RenderableMultiresVolume::initializeSelector() { ); success &= _errorHistogramManager->loadFromFile(cacheFilename); } - else if (_errorHistogramsPath != "") { + else if (!_errorHistogramsPath.empty()) { // Read histograms from scene data. LINFO(fmt::format( "Loading histograms from scene data: {}", _errorHistogramsPath )); - success &= _errorHistogramManager->loadFromFile(_errorHistogramsPath); + success &= _errorHistogramManager->loadFromFile( + _errorHistogramsPath.string() + ); } else { // Build histograms from tsp file. @@ -494,14 +495,11 @@ bool RenderableMultiresVolume::initializeSelector() { case Selector::SIMPLE: if (_histogramManager) { - std::stringstream cacheName; - ghoul::filesystem::File f = _filename; - cacheName << f.baseName() << "_" << nHistograms << "_histograms"; - std::string cacheFilename; - cacheFilename = FileSys.cacheManager()->cachedFilename( - cacheName.str(), - "", - ghoul::filesystem::CacheManager::Persistent::Yes + std::string cacheFilename = FileSys.cacheManager()->cachedFilename( + fmt::format("{}_{}_histogram", + std::filesystem::path(_filename).stem().string(), nHistograms + ), + "" ); std::ifstream cacheFile(cacheFilename, std::ios::in | std::ios::binary); if (cacheFile.is_open()) { @@ -528,12 +526,12 @@ bool RenderableMultiresVolume::initializeSelector() { case Selector::LOCAL: if (_localErrorHistogramManager) { - ghoul::filesystem::File f = _filename; - std::string cacheFilename; - cacheFilename = FileSys.cacheManager()->cachedFilename( - fmt::format("{}_{}_localErrorHistograms", f.baseName(), nHistograms), - "", - ghoul::filesystem::CacheManager::Persistent::Yes + std::string cacheFilename = FileSys.cacheManager()->cachedFilename( + fmt::format( + "{}_{}_localErrorHistograms", + std::filesystem::path(_filename).stem().string(), nHistograms + ), + "" ); std::ifstream cacheFile(cacheFilename, std::ios::in | std::ios::binary); if (cacheFile.is_open()) { @@ -628,8 +626,9 @@ void RenderableMultiresVolume::update(const UpdateData& data) { // Make sure that the directory exists ghoul::filesystem::File file(_statsFileName); - ghoul::filesystem::Directory directory(file.directoryName()); - FileSys.createDirectory(directory, ghoul::filesystem::FileSystem::Recursive::Yes); + std::filesystem::path directory = + std::filesystem::path(_statsFileName).parent_path(); + std::filesystem::create_directories(directory); std::ofstream ofs(_statsFileName, std::ofstream::out); diff --git a/modules/multiresvolume/rendering/renderablemultiresvolume.h b/modules/multiresvolume/rendering/renderablemultiresvolume.h index 28a9d56994..1b4c71914d 100644 --- a/modules/multiresvolume/rendering/renderablemultiresvolume.h +++ b/modules/multiresvolume/rendering/renderablemultiresvolume.h @@ -33,6 +33,7 @@ #include #include #include +#include namespace ghoul { class Dictionary; } namespace ghoul::filesystem { class File; } @@ -122,7 +123,7 @@ private: std::string _volumeName; std::string _transferFunctionPath; - std::string _errorHistogramsPath; + std::filesystem::path _errorHistogramsPath; std::shared_ptr _transferFunction; diff --git a/modules/multiresvolume/rendering/tsp.cpp b/modules/multiresvolume/rendering/tsp.cpp index e056dbaeb4..124d1cea24 100644 --- a/modules/multiresvolume/rendering/tsp.cpp +++ b/modules/multiresvolume/rendering/tsp.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -506,11 +507,9 @@ bool TSP::readCache() { if (!FileSys.cacheManager()) return false; - ghoul::filesystem::File f = _filename; std::string cacheFilename = FileSys.cacheManager()->cachedFilename( - f.baseName(), - "", - ghoul::filesystem::CacheManager::Persistent::Yes + std::filesystem::path(_filename).stem(), + "" ); std::ifstream file(cacheFilename, std::ios::in | std::ios::binary); @@ -546,11 +545,9 @@ bool TSP::writeCache() { return false; } - ghoul::filesystem::File f = _filename; std::string cacheFilename = FileSys.cacheManager()->cachedFilename( - f.baseName(), - "", - ghoul::filesystem::CacheManager::Persistent::Yes + std::filesystem::path(_filename).stem(), + "" ); std::ofstream file(cacheFilename, std::ios::out | std::ios::binary); diff --git a/modules/server/include/topics/luascripttopic.h b/modules/server/include/topics/luascripttopic.h index 7ed757e3dd..49b81f37f4 100644 --- a/modules/server/include/topics/luascripttopic.h +++ b/modules/server/include/topics/luascripttopic.h @@ -36,8 +36,9 @@ public: void handleJson(const nlohmann::json& json) override; bool isDone() const override; + private: - void runScript(const std::string& script, bool returnValue); + void runScript(std::string script, bool returnValue); bool _waitingForReturnValue = true; }; diff --git a/modules/server/src/topics/luascripttopic.cpp b/modules/server/src/topics/luascripttopic.cpp index b718ea4838..d2140b6e75 100644 --- a/modules/server/src/topics/luascripttopic.cpp +++ b/modules/server/src/topics/luascripttopic.cpp @@ -176,7 +176,7 @@ void LuaScriptTopic::handleJson(const nlohmann::json& json) { } } -void LuaScriptTopic::runScript(const std::string& script, bool shouldReturn) { +void LuaScriptTopic::runScript(std::string script, bool shouldReturn) { scripting::ScriptEngine::ScriptCallback callback; if (shouldReturn) { callback = [this](ghoul::Dictionary data) { diff --git a/modules/server/src/topics/sessionrecordingtopic.cpp b/modules/server/src/topics/sessionrecordingtopic.cpp index 9b39e739c5..1a724b24fd 100644 --- a/modules/server/src/topics/sessionrecordingtopic.cpp +++ b/modules/server/src/topics/sessionrecordingtopic.cpp @@ -124,6 +124,9 @@ void SessionRecordingTopic::sendJsonData() { case SessionRecording::SessionState::Playback: stateString = "playing"; break; + case SessionRecording::SessionState::PlaybackPaused: + stateString = "playing-paused"; + break; default: stateString = "idle"; break; diff --git a/modules/space/CMakeLists.txt b/modules/space/CMakeLists.txt index 583e3e89ab..09e56ed641 100644 --- a/modules/space/CMakeLists.txt +++ b/modules/space/CMakeLists.txt @@ -25,6 +25,7 @@ include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake) set(HEADER_FILES + speckloader.h rendering/planetgeometry.h rendering/renderableconstellationbounds.h rendering/renderablehabitablezone.h @@ -43,6 +44,7 @@ set(HEADER_FILES source_group("Header Files" FILES ${HEADER_FILES}) set(SOURCE_FILES + speckloader.cpp rendering/planetgeometry.cpp rendering/renderableconstellationbounds.cpp rendering/renderablehabitablezone.cpp diff --git a/modules/space/rendering/planetgeometry.cpp b/modules/space/rendering/planetgeometry.cpp index ec68224b61..8216093752 100644 --- a/modules/space/rendering/planetgeometry.cpp +++ b/modules/space/rendering/planetgeometry.cpp @@ -40,9 +40,7 @@ namespace { namespace openspace::planetgeometry { documentation::Documentation PlanetGeometry::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "space_geometry_planet"; - return doc; + return codegen::doc("space_geometry_planet"); } std::unique_ptr PlanetGeometry::createFromDictionary( diff --git a/modules/space/rendering/renderableconstellationbounds.cpp b/modules/space/rendering/renderableconstellationbounds.cpp index e6f2821592..a9193c6294 100644 --- a/modules/space/rendering/renderableconstellationbounds.cpp +++ b/modules/space/rendering/renderableconstellationbounds.cpp @@ -99,11 +99,8 @@ namespace { namespace openspace { documentation::Documentation RenderableConstellationBounds::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "space_renderable_constellationbounds"; - return doc; -} // namespace - + return codegen::doc("space_renderable_constellationbounds"); +} RenderableConstellationBounds::RenderableConstellationBounds( const ghoul::Dictionary& dictionary) @@ -233,7 +230,7 @@ bool RenderableConstellationBounds::loadVertexFile() { return false; } - std::string fileName = absPath(_vertexFilename); + std::filesystem::path fileName = absPath(_vertexFilename); std::ifstream file; file.open(fileName); if (!file.good()) { @@ -273,7 +270,7 @@ bool RenderableConstellationBounds::loadVertexFile() { LERRORC( "RenderableConstellationBounds", fmt::format( - "Error reading file '{}' at line #{}", fileName, currentLineNumber + "Error reading file {} at line #{}", fileName, currentLineNumber ) ); break; diff --git a/modules/space/rendering/renderableconstellationbounds.h b/modules/space/rendering/renderableconstellationbounds.h index c6ea6e606c..5af808d7c5 100644 --- a/modules/space/rendering/renderableconstellationbounds.h +++ b/modules/space/rendering/renderableconstellationbounds.h @@ -66,7 +66,7 @@ private: struct ConstellationBound { std::string constellationAbbreviation; ///< The abbreviation of the constellation std::string constellationFullName; - bool isEnabled; + bool isEnabled = false; GLsizei startIndex; ///< The index of the first vertex describing the bounds GLsizei nVertices; ///< The number of vertices describing the bounds }; diff --git a/modules/space/rendering/renderablehabitablezone.cpp b/modules/space/rendering/renderablehabitablezone.cpp index d540d75906..fb5a7ca4fc 100644 --- a/modules/space/rendering/renderablehabitablezone.cpp +++ b/modules/space/rendering/renderablehabitablezone.cpp @@ -40,7 +40,7 @@ #include namespace { - constexpr const char _loggerCat[] = "RenderableHabitableZone"; + constexpr const char* _loggerCat = "RenderableHabitableZone"; constexpr const std::array UniformNames = { "modelViewProjectionTransform", "opacity", "width", "transferFunctionTexture", @@ -96,8 +96,9 @@ namespace { namespace openspace { documentation::Documentation RenderableHabitableZone::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "space_renderablehabitablezone"; + documentation::Documentation doc = codegen::doc( + "space_renderablehabitablezone" + ); // @TODO cleanup // Insert the parents documentation entries until we have a verifier that can deal @@ -135,6 +136,7 @@ RenderableHabitableZone::RenderableHabitableZone(const ghoul::Dictionary& dictio // The user should not be able to change this property. It's just used to communicate // the different rendering that happens outside of this interval addProperty(_kopparapuTeffInterval); + _kopparapuTeffInterval.setViewOption(properties::Property::ViewOptions::MinMaxRange); _kopparapuTeffInterval.setReadOnly(true); // Make parent's size related properties read only. We want to set them based on the diff --git a/modules/space/rendering/renderableorbitalkepler.cpp b/modules/space/rendering/renderableorbitalkepler.cpp index 040354458d..e54329e9ab 100644 --- a/modules/space/rendering/renderableorbitalkepler.cpp +++ b/modules/space/rendering/renderableorbitalkepler.cpp @@ -262,9 +262,7 @@ namespace { namespace openspace { documentation::Documentation RenderableOrbitalKepler::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "space_renderableorbitalkepler"; - return doc; + return codegen::doc("space_renderableorbitalkepler"); } double RenderableOrbitalKepler::calculateSemiMajorAxis(double meanMotion) const { diff --git a/modules/space/rendering/renderablerings.cpp b/modules/space/rendering/renderablerings.cpp index 6e45f719b6..e013449b9c 100644 --- a/modules/space/rendering/renderablerings.cpp +++ b/modules/space/rendering/renderablerings.cpp @@ -60,10 +60,10 @@ namespace { constexpr openspace::properties::Property::PropertyInfo OffsetInfo = { "Offset", "Offset", - "This value is used to limit the width of the rings.Each of the two values is a " - "value between 0 and 1, where 0 is the center of the ring and 1 is the maximum " - "extent at the radius. If this value is, for example {0.5, 1.0}, the ring is " - "only shown between radius/2 and radius. It defaults to {0.0, 1.0}." + "This value is used to limit the width of the rings. Each of the two values is " + "a value between 0 and 1, where 0 is the center of the ring and 1 is the " + "maximum extent at the radius. For example, if the value is {0.5, 1.0}, the " + "ring is only shown between radius/2 and radius. It defaults to {0.0, 1.0}." }; constexpr openspace::properties::Property::PropertyInfo NightFactorInfo = { @@ -103,9 +103,7 @@ namespace { namespace openspace { documentation::Documentation RenderableRings::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "space_renderable_rings"; - return doc; + return codegen::doc("space_renderable_rings"); } RenderableRings::RenderableRings(const ghoul::Dictionary& dictionary) @@ -125,16 +123,17 @@ RenderableRings::RenderableRings(const ghoul::Dictionary& dictionary) _size.onChange([&]() { _planeIsDirty = true; }); addProperty(_size); - _texturePath = absPath(p.texture); - _textureFile = std::make_unique(_texturePath); + _texturePath = absPath(p.texture).string(); + _textureFile = std::make_unique(_texturePath.value()); _offset = p.offset.value_or(_offset); + _offset.setViewOption(properties::Property::ViewOptions::MinMaxRange); addProperty(_offset); _texturePath.onChange([&]() { loadTexture(); }); addProperty(_texturePath); - _textureFile->setCallback([&](const File&) { _textureIsDirty = true; }); + _textureFile->setCallback([this]() { _textureIsDirty = true; }); _nightFactor = p.nightFactor.value_or(_nightFactor); addProperty(_nightFactor); @@ -236,23 +235,23 @@ void RenderableRings::loadTexture() { using namespace ghoul::io; using namespace ghoul::opengl; std::unique_ptr texture = TextureReader::ref().loadTexture( - absPath(_texturePath) + absPath(_texturePath).string() ); if (texture) { LDEBUGC( "RenderableRings", - fmt::format("Loaded texture from '{}'", absPath(_texturePath)) + fmt::format("Loaded texture from {}", absPath(_texturePath)) ); _texture = std::move(texture); _texture->uploadTexture(); _texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); - _textureFile = std::make_unique(_texturePath); - _textureFile->setCallback( - [&](const ghoul::filesystem::File&) { _textureIsDirty = true; } + _textureFile = std::make_unique( + _texturePath.value() ); + _textureFile->setCallback([this]() { _textureIsDirty = true; }); } } } diff --git a/modules/space/rendering/renderablesatellites.cpp b/modules/space/rendering/renderablesatellites.cpp index f808be2147..7bd47a3648 100644 --- a/modules/space/rendering/renderablesatellites.cpp +++ b/modules/space/rendering/renderablesatellites.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -63,8 +64,9 @@ namespace { namespace openspace { documentation::Documentation RenderableSatellites::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "space_renderablesatellites"; + documentation::Documentation doc = codegen::doc( + "space_renderablesatellites" + ); // Insert the parents documentation entries until we have a verifier that can deal // with class hierarchy @@ -105,7 +107,7 @@ RenderableSatellites::RenderableSatellites(const ghoul::Dictionary& dictionary) } void RenderableSatellites::readDataFile(const std::string& filename) { - if (!FileSys.fileExists(filename)) { + if (!std::filesystem::is_regular_file(filename)) { throw ghoul::RuntimeError(fmt::format( "Satellite TLE file {} does not exist", filename )); diff --git a/modules/space/rendering/renderablesmallbody.cpp b/modules/space/rendering/renderablesmallbody.cpp index 72414c3453..3236bab79a 100644 --- a/modules/space/rendering/renderablesmallbody.cpp +++ b/modules/space/rendering/renderablesmallbody.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -97,8 +98,9 @@ namespace { namespace openspace { documentation::Documentation RenderableSmallBody::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "space_renderablesmallbody"; + documentation::Documentation doc = codegen::doc( + "space_renderablesmallbody" + ); // Insert the parents documentation entries until we have a verifier that can deal // with class hierarchy @@ -172,7 +174,7 @@ RenderableSmallBody::RenderableSmallBody(const ghoul::Dictionary& dictionary) } void RenderableSmallBody::readDataFile(const std::string& filename) { - if (!FileSys.fileExists(filename)) { + if (!std::filesystem::is_regular_file(filename)) { throw ghoul::RuntimeError(fmt::format( "JPL SBDB file {} does not exist.", filename )); diff --git a/modules/space/rendering/renderablestars.cpp b/modules/space/rendering/renderablestars.cpp index eefa4ba887..89b4fdf9a5 100644 --- a/modules/space/rendering/renderablestars.cpp +++ b/modules/space/rendering/renderablestars.cpp @@ -52,21 +52,21 @@ namespace { constexpr const char* _loggerCat = "RenderableStars"; constexpr const std::array UniformNames = { - "modelMatrix", "cameraUp", "cameraViewProjectionMatrix", - "colorOption", "magnitudeExponent", "eyePosition", "psfParamConf", - "lumCent", "radiusCent", "brightnessCent", "colorTexture", - "alphaValue", "psfTexture", "otherDataTexture", "otherDataRange", - "filterOutOfRange", "fixedColor" + "modelMatrix", "cameraUp", "cameraViewProjectionMatrix", "colorOption", + "magnitudeExponent", "eyePosition", "psfParamConf", "lumCent", "radiusCent", + "brightnessCent", "colorTexture", "alphaValue", "psfTexture", "otherDataTexture", + "otherDataRange", "filterOutOfRange", "fixedColor" }; - constexpr int8_t CurrentCacheVersion = 3; - constexpr const int RenderOptionPointSpreadFunction = 0; constexpr const int RenderOptionTexture = 1; constexpr const int PsfMethodSpencer = 0; constexpr const int PsfMethodMoffat = 1; + constexpr const int PsfTextureSize = 64; + constexpr const int ConvolvedfTextureSize = 257; + constexpr double PARSEC = 0.308567756E17; struct ColorVBOLayout { @@ -120,6 +120,61 @@ namespace { "to its color. The texture is used as a one dimensional lookup function." }; + constexpr openspace::properties::Property::PropertyInfo MappingBvInfo = { + "MappingBV", + "Mapping (bv-color)", + "The name of the variable in the speck file that is used as the b-v color " + "variable" + }; + + constexpr openspace::properties::Property::PropertyInfo MappingLuminanceInfo = { + "MappingLuminance", + "Mapping (luminance)", + "The name of the variable in the speck file that is used as the luminance " + "variable" + }; + + constexpr openspace::properties::Property::PropertyInfo MappingAbsMagnitudeInfo = { + "MappingAbsMagnitude", + "Mapping (absolute magnitude)", + "The name of the variable in the speck file that is used as the absolute " + "magnitude variable" + }; + + constexpr openspace::properties::Property::PropertyInfo MappingAppMagnitudeInfo = { + "MappingAppMagnitude", + "Mapping (apparent magnitude)", + "The name of the variable in the speck file that is used as the apparent " + "magnitude variable" + }; + + constexpr openspace::properties::Property::PropertyInfo MappingVxInfo = { + "MappingVx", + "Mapping (vx)", + "The name of the variable in the speck file that is used as the star velocity " + "along the x-axis" + }; + + constexpr openspace::properties::Property::PropertyInfo MappingVyInfo = { + "MappingVy", + "Mapping (vy)", + "The name of the variable in the speck file that is used as the star velocity " + "along the y-axis" + }; + + constexpr openspace::properties::Property::PropertyInfo MappingVzInfo = { + "MappingVz", + "Mapping (vz)", + "The name of the variable in the speck file that is used as the star velocity " + "along the z-axis" + }; + + constexpr openspace::properties::Property::PropertyInfo MappingSpeedInfo = { + "MappingSpeed", + "Mapping (speed)", + "The name of the variable in the speck file that is used as the speed" + }; + constexpr openspace::properties::Property::PropertyInfo ColorOptionInfo = { "ColorOption", "Color Option", @@ -159,12 +214,6 @@ namespace { "or filtered away" }; - constexpr openspace::properties::Property::PropertyInfo EnableTestGridInfo = { - "EnableTestGrid", - "Enable Test Grid", - "Set it to true for rendering the test grid." - }; - // Old Method constexpr openspace::properties::Property::PropertyInfo PsfTextureInfo = { "Texture", @@ -173,11 +222,11 @@ namespace { "stars." }; - /*constexpr openspace::properties::Property::PropertyInfo ShapeTextureInfo = { - "ShapeTexture", - "Shape Texture to be convolved", - "The path to the texture that should be used as the base shape for the stars." - };*/ + //constexpr openspace::properties::Property::PropertyInfo ShapeTextureInfo = { + // "ShapeTexture", + // "Shape Texture to be convolved", + // "The path to the texture that should be used as the base shape for the stars." + //}; // PSF constexpr openspace::properties::Property::PropertyInfo MagnitudeExponentInfo = { @@ -344,23 +393,56 @@ namespace { // [[codegen::verbatim(MagnitudeExponentInfo.description)]] std::optional magnitudeExponent; - // [[codegen::verbatim(EnableTestGridInfo.description)]] - std::optional enableTestGrid; + enum class RenderMethod { + PSF, + TextureBased [[codegen::key("Texture Based")]] + }; // [[codegen::verbatim(RenderMethodOptionInfo.description)]] - std::string renderMethod; + RenderMethod renderMethod; // [[codegen::verbatim(PsfTextureInfo.description)]] std::filesystem::path texture; + enum class SizeComposition { + AppBrightness [[codegen::key("App Brightness")]], + LumSize [[codegen::key("Lum and Size")]], + LumSizeAppBrightness [[codegen::key("Lum, Size and App Brightness")]], + AbsMagnitude [[codegen::key("Abs Magnitude")]], + AppMagnitude [[codegen::key("App Magnitude")]], + DistanceModulus [[codegen::key("Distance Modulus")]] + }; + // [[codegen::verbatim(SizeCompositionOptionInfo.description)]] - std::optional sizeComposition; + std::optional sizeComposition; + + struct DataMapping { + // [[codegen::verbatim(MappingBvInfo.description)]] + std::optional bv; + // [[codegen::verbatim(MappingLuminanceInfo.description)]] + std::optional luminance; + // [[codegen::verbatim(MappingAbsMagnitudeInfo.description)]] + std::optional absoluteMagnitude; + // [[codegen::verbatim(MappingAppMagnitudeInfo.description)]] + std::optional apparentMagnitude; + // [[codegen::verbatim(MappingVxInfo.description)]] + std::optional vx; + // [[codegen::verbatim(MappingVyInfo.description)]] + std::optional vy; + // [[codegen::verbatim(MappingVzInfo.description)]] + std::optional vz; + // [[codegen::verbatim(MappingSpeedInfo.description)]] + std::optional speed; + }; + // The mappings between data values and the variable names specified in the speck + // file + DataMapping dataMapping; // [[codegen::verbatim(FadeInDistancesInfo.description)]] std::optional fadeInDistances; // [[codegen::verbatim(DisableFadeInInfo.description)]] - std::optional distableFadeIn; + std::optional disableFadeIn; }; #include "renderablestars_codegen.cpp" } // namespace @@ -368,9 +450,7 @@ namespace { namespace openspace { documentation::Documentation RenderableStars::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "space_renderablestars"; - return doc; + return codegen::doc("space_renderablestars"); } RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary) @@ -378,6 +458,17 @@ RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary) , _speckFile(SpeckFileInfo) , _colorTexturePath(ColorTextureInfo) //, _shapeTexturePath(ShapeTextureInfo) + , _dataMappingContainer({ "DataMapping", "Data Mapping" }) + , _dataMapping{ + properties::StringProperty(MappingBvInfo), + properties::StringProperty(MappingLuminanceInfo), + properties::StringProperty(MappingAbsMagnitudeInfo), + properties::StringProperty(MappingAppMagnitudeInfo), + properties::StringProperty(MappingVxInfo), + properties::StringProperty(MappingVyInfo), + properties::StringProperty(MappingVzInfo), + properties::StringProperty(MappingSpeedInfo) + } , _colorOption(ColorOptionInfo, properties::OptionProperty::DisplayType::Dropdown) , _otherDataOption( OtherDataOptionInfo, @@ -411,7 +502,7 @@ RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary) , _p2Param(P2ParamInfo, 0.138f, 0.f, 1.f) , _spencerAlphaConst(AlphaConstInfo, 0.02f, 0.000001f, 5.f) , _moffatPSFParamOwner(MoffatPSFParamOwnerInfo) - , _FWHMConst(FWHMInfo, 10.4f, -100.f, 1000.f) + , _FWHMConst(FWHMInfo, 10.4f, 0.f, 100.f) , _moffatBetaConst(BetaInfo, 4.765f, 0.f, 100.f) , _renderingMethodOption( RenderMethodOptionInfo, @@ -420,7 +511,7 @@ RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary) , _userProvidedTextureOwner(UserProvidedTextureOptionInfo) , _parametersOwner(ParametersOwnerOptionInfo) , _moffatMethodOwner(MoffatMethodOptionInfo) - , _fadeInDistance( + , _fadeInDistances( FadeInDistancesInfo, glm::vec2(0.f), glm::vec2(0.f), @@ -435,20 +526,54 @@ RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary) addProperty(_opacity); registerUpdateRenderBinFromOpacity(); + _dataMapping.bvColor = p.dataMapping.bv.value_or(""); + _dataMapping.bvColor.onChange([this]() { _dataIsDirty = true; }); + _dataMappingContainer.addProperty(_dataMapping.bvColor); + + _dataMapping.luminance = p.dataMapping.luminance.value_or(""); + _dataMapping.luminance.onChange([this]() { _dataIsDirty = true; }); + _dataMappingContainer.addProperty(_dataMapping.luminance); + + _dataMapping.absoluteMagnitude = p.dataMapping.absoluteMagnitude.value_or(""); + _dataMapping.absoluteMagnitude.onChange([this]() { _dataIsDirty = true; }); + _dataMappingContainer.addProperty(_dataMapping.absoluteMagnitude); + + _dataMapping.apparentMagnitude = p.dataMapping.apparentMagnitude.value_or(""); + _dataMapping.apparentMagnitude.onChange([this]() { _dataIsDirty = true; }); + _dataMappingContainer.addProperty(_dataMapping.apparentMagnitude); + + _dataMapping.vx = p.dataMapping.vx.value_or(""); + _dataMapping.vx.onChange([this]() { _dataIsDirty = true; }); + _dataMappingContainer.addProperty(_dataMapping.vx); + + _dataMapping.vy = p.dataMapping.vy.value_or(""); + _dataMapping.vy.onChange([this]() { _dataIsDirty = true; }); + _dataMappingContainer.addProperty(_dataMapping.vy); + + _dataMapping.vz = p.dataMapping.vz.value_or(""); + _dataMapping.vz.onChange([this]() { _dataIsDirty = true; }); + _dataMappingContainer.addProperty(_dataMapping.vz); + + _dataMapping.speed = p.dataMapping.speed.value_or(""); + _dataMapping.speed.onChange([this]() { _dataIsDirty = true; }); + _dataMappingContainer.addProperty(_dataMapping.speed); + + addPropertySubOwner(_dataMappingContainer); + _speckFile = p.speckFile.string(); _speckFile.onChange([&]() { _speckFileIsDirty = true; }); addProperty(_speckFile); _colorTexturePath = p.colorMap.string(); - _colorTextureFile = std::make_unique(_colorTexturePath); + _colorTextureFile = std::make_unique(_colorTexturePath.value()); - /*_shapeTexturePath = absPath(dictionary.value( - ShapeTextureInfo.identifier - )); - _shapeTextureFile = std::make_unique(_shapeTexturePath);*/ + //_shapeTexturePath = absPath(dictionary.value( + // ShapeTextureInfo.identifier + // )); + //_shapeTextureFile = std::make_unique(_shapeTexturePath); if (p.otherDataColorMap.has_value()) { - _otherDataColorMapPath = absPath(*p.otherDataColorMap); + _otherDataColorMapPath = absPath(*p.otherDataColorMap).string(); } _fixedColor.setViewOption(properties::Property::ViewOptions::Color, true); @@ -484,23 +609,15 @@ RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary) addProperty(_colorOption); _colorTexturePath.onChange([&] { _colorTextureIsDirty = true; }); - _colorTextureFile->setCallback([&](const File&) { - _colorTextureIsDirty = true; - }); + _colorTextureFile->setCallback([this]() { _colorTextureIsDirty = true; }); addProperty(_colorTexturePath); - /*_shapeTexturePath.onChange([&] { _shapeTextureIsDirty = true; }); - _shapeTextureFile->setCallback([&](const File&) { - _shapeTextureIsDirty = true; - }); - addProperty(_shapeTexturePath);*/ - - _enableTestGrid = p.enableTestGrid.value_or(_enableTestGrid); _queuedOtherData = p.otherData.value_or(_queuedOtherData); _otherDataOption.onChange([&]() { _dataIsDirty = true; }); addProperty(_otherDataOption); + _otherDataRange.setViewOption(properties::Property::ViewOptions::MinMaxRange); addProperty(_otherDataRange); addProperty(_otherDataColorMapPath); @@ -519,19 +636,21 @@ RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary) _renderingMethodOption.addOption(RenderOptionTexture, "Textured Based"); addProperty(_renderingMethodOption); - if (p.renderMethod == "PSF") { + if (p.renderMethod == Parameters::RenderMethod::PSF) { _renderingMethodOption = RenderOptionPointSpreadFunction; } - else if (p.renderMethod == "Texture Based") { + else { _renderingMethodOption = RenderOptionTexture; } - _pointSpreadFunctionTexturePath = absPath(p.texture.string()); - _pointSpreadFunctionFile = std::make_unique(_pointSpreadFunctionTexturePath); - _pointSpreadFunctionTexturePath.onChange([&]() { + _pointSpreadFunctionTexturePath = absPath(p.texture.string()).string(); + _pointSpreadFunctionFile = std::make_unique( + _pointSpreadFunctionTexturePath.value() + ); + _pointSpreadFunctionTexturePath.onChange([this]() { _pointSpreadFunctionTextureIsDirty = true; }); - _pointSpreadFunctionFile->setCallback([&](const File&) { + _pointSpreadFunctionFile->setCallback([this]() { _pointSpreadFunctionTextureIsDirty = true; }); _userProvidedTextureOwner.addProperty(_pointSpreadFunctionTexturePath); @@ -551,23 +670,25 @@ RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary) if (p.sizeComposition.has_value()) { - if (*p.sizeComposition == "App Brightness") { - _psfMultiplyOption = 0; - } - else if (*p.sizeComposition == "Lum and Size") { - _psfMultiplyOption = 1; - } - else if (*p.sizeComposition == "Lum, Size and App Brightness") { - _psfMultiplyOption = 2; - } - else if (*p.sizeComposition == "Abs Magnitude") { - _psfMultiplyOption = 3; - } - else if (*p.sizeComposition == "App Maginitude") { - _psfMultiplyOption = 4; - } - else if (*p.sizeComposition == "Distance Modulus") { - _psfMultiplyOption = 5; + switch (*p.sizeComposition) { + case Parameters::SizeComposition::AppBrightness: + _psfMultiplyOption = 0; + break; + case Parameters::SizeComposition::LumSize: + _psfMultiplyOption = 1; + break; + case Parameters::SizeComposition::LumSizeAppBrightness: + _psfMultiplyOption = 2; + break; + case Parameters::SizeComposition::AbsMagnitude: + _psfMultiplyOption = 3; + break; + case Parameters::SizeComposition::AppMagnitude: + _psfMultiplyOption = 4; + break; + case Parameters::SizeComposition::DistanceModulus: + _psfMultiplyOption = 5; + break; } } else { @@ -607,9 +728,10 @@ RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary) if (p.fadeInDistances.has_value()) { glm::vec2 v = *p.fadeInDistances; - _fadeInDistance = v; + _fadeInDistances = v; _disableFadeInDistance = false; - addProperty(_fadeInDistance); + _fadeInDistances.setViewOption(properties::Property::ViewOptions::MinMaxRange); + addProperty(_fadeInDistances); addProperty(_disableFadeInDistance); } } @@ -632,13 +754,16 @@ void RenderableStars::initializeGL() { loadData(); + // We need to wait until after loading the data until we can see if the requested + // data value actually exists or not. Once we determine the index, we no longer + // need the value and can clear it if (!_queuedOtherData.empty()) { - auto it = std::find(_dataNames.begin(), _dataNames.end(), _queuedOtherData); - if (it == _dataNames.end()) { + int idx = _dataset.index(_queuedOtherData); + if (idx == -1) { LERROR(fmt::format("Could not find other data column {}", _queuedOtherData)); } else { - _otherDataOption = static_cast(std::distance(_dataNames.begin(), it)); + _otherDataOption = idx; _queuedOtherData.clear(); } } @@ -651,7 +776,7 @@ void RenderableStars::initializeGL() { glBindVertexArray(_psfVao); glBindBuffer(GL_ARRAY_BUFFER, _psfVbo); - const GLfloat vertexData[] = { + constexpr const std::array VertexData = { //x y s t -1.f, -1.f, 0.f, 0.f, 1.f, 1.f, 1.f, 1.f, @@ -661,15 +786,8 @@ void RenderableStars::initializeGL() { 1.f, 1.f, 1.f, 1.f }; - glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW); - glVertexAttribPointer( - 0, - 4, - GL_FLOAT, - GL_FALSE, - sizeof(GLfloat) * 4, - nullptr - ); + glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData), VertexData.data(), GL_STATIC_DRAW); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), nullptr); glEnableVertexAttribArray(0); glBindVertexArray(0); @@ -685,8 +803,8 @@ void RenderableStars::initializeGL() { GL_TEXTURE_2D, 0, GL_RGBA8, - _psfTextureSize, - _psfTextureSize, + PsfTextureSize, + PsfTextureSize, 0, GL_RGBA, GL_BYTE, @@ -708,8 +826,8 @@ void RenderableStars::initializeGL() { GL_TEXTURE_2D, 0, GL_RGBA8, - _convolvedfTextureSize, - _convolvedfTextureSize, + ConvolvedfTextureSize, + ConvolvedfTextureSize, 0, GL_RGBA, GL_BYTE, @@ -742,13 +860,12 @@ void RenderableStars::loadPSFTexture() { std::filesystem::exists(_pointSpreadFunctionTexturePath.value())) { _pointSpreadFunctionTexture = ghoul::io::TextureReader::ref().loadTexture( - absPath(_pointSpreadFunctionTexturePath) + absPath(_pointSpreadFunctionTexturePath).string() ); if (_pointSpreadFunctionTexture) { LDEBUG(fmt::format( - "Loaded texture from '{}'", - absPath(_pointSpreadFunctionTexturePath) + "Loaded texture from '{}'", absPath(_pointSpreadFunctionTexturePath) )); _pointSpreadFunctionTexture->uploadTexture(); } @@ -757,26 +874,16 @@ void RenderableStars::loadPSFTexture() { ); _pointSpreadFunctionFile = std::make_unique( - _pointSpreadFunctionTexturePath - ); + _pointSpreadFunctionTexturePath.value() + ); _pointSpreadFunctionFile->setCallback( - [&](const ghoul::filesystem::File&) { - _pointSpreadFunctionTextureIsDirty = true; - } + [&]() { _pointSpreadFunctionTextureIsDirty = true; } ); } _pointSpreadFunctionTextureIsDirty = false; - } void RenderableStars::renderPSFToTexture() { - // Saves current FBO first - // GLint defaultFBO; - // defaultFBO = global::renderEngine->openglStateCache().defaultFramebuffer(); - -// GLint m_viewport[4]; -// global::renderEngine.openglStateCache().viewPort(m_viewport); - // Creates the FBO for the calculations GLuint psfFBO; glGenFramebuffers(1, &psfFBO); @@ -785,9 +892,7 @@ void RenderableStars::renderPSFToTexture() { glDrawBuffers(1, drawBuffers); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _psfTexture, 0); - - glViewport(0, 0, _psfTextureSize, _psfTextureSize); - + glViewport(0, 0, PsfTextureSize, PsfTextureSize); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); std::unique_ptr program = @@ -798,8 +903,8 @@ void RenderableStars::renderPSFToTexture() { ); program->activate(); - constexpr const float black[] = { 0.f, 0.f, 0.f, 0.f }; - glClearBufferfv(GL_COLOR, 0, black); + constexpr const std::array Black = { 0.f, 0.f, 0.f, 0.f }; + glClearBufferfv(GL_COLOR, 0, Black.data()); program->setUniform("psfMethod", _psfMethodOption.value()); program->setUniform("p0Param", _p0Param); @@ -873,7 +978,7 @@ void RenderableStars::renderPSFToTexture() { // m_viewport[2], // m_viewport[3] //); - //glDeleteFramebuffers(1, &psfFBO); + glDeleteFramebuffers(1, &psfFBO); //glDeleteFramebuffers(1, &convolveFBO); // Restores OpenGL blending state @@ -881,7 +986,7 @@ void RenderableStars::renderPSFToTexture() { } void RenderableStars::render(const RenderData& data, RendererTasks&) { - if (_fullData.empty()) { + if (_dataset.entries.empty()) { return; } @@ -931,7 +1036,7 @@ void RenderableStars::render(const RenderData& data, RendererTasks&) { float fadeInVariable = 1.f; if (!_disableFadeInDistance) { float distCamera = static_cast(glm::length(data.camera.positionVec3())); - const glm::vec2 fadeRange = _fadeInDistance; + const glm::vec2 fadeRange = _fadeInDistances; const double a = 1.f / ((fadeRange.y - fadeRange.x) * PARSEC); const double b = -(fadeRange.x / (fadeRange.y - fadeRange.x)); const double funcValue = a * distCamera + b; @@ -981,7 +1086,7 @@ void RenderableStars::render(const RenderData& data, RendererTasks&) { glBindVertexArray(_vao); - const GLsizei nStars = static_cast(_fullData.size() / _nValuesPerStar); + const GLsizei nStars = static_cast(_dataset.entries.size()); glDrawArrays(GL_POINTS, 0, nStars); glBindVertexArray(0); @@ -999,7 +1104,7 @@ void RenderableStars::update(const UpdateData&) { _dataIsDirty = true; } - if (_fullData.empty()) { + if (_dataset.entries.empty()) { return; } @@ -1007,9 +1112,7 @@ void RenderableStars::update(const UpdateData&) { const int value = _colorOption; LDEBUG("Regenerating data"); - createDataSlice(ColorOption(value)); - - int size = static_cast(_slicedData.size()); + std::vector slice = createDataSlice(ColorOption(value)); if (_vao == 0) { glGenVertexArrays(1, &_vao); @@ -1021,8 +1124,8 @@ void RenderableStars::update(const UpdateData&) { glBindBuffer(GL_ARRAY_BUFFER, _vbo); glBufferData( GL_ARRAY_BUFFER, - size * sizeof(GLfloat), - _slicedData.data(), + slice.size() * sizeof(GLfloat), + slice.data(), GL_STATIC_DRAW ); @@ -1032,8 +1135,8 @@ void RenderableStars::update(const UpdateData&) { "in_bvLumAbsMagAppMag" ); - const size_t nStars = _fullData.size() / _nValuesPerStar; - const size_t nValues = _slicedData.size() / nStars; + const size_t nStars = _dataset.entries.size(); + const size_t nValues = slice.size() / nStars; GLsizei stride = static_cast(sizeof(GLfloat) * nValues); @@ -1161,7 +1264,7 @@ void RenderableStars::update(const UpdateData&) { _colorTexture = nullptr; if (_colorTexturePath.value() != "") { _colorTexture = ghoul::io::TextureReader::ref().loadTexture( - absPath(_colorTexturePath) + absPath(_colorTexturePath).string() ); if (_colorTexture) { LDEBUG(fmt::format( @@ -1172,11 +1275,9 @@ void RenderableStars::update(const UpdateData&) { } _colorTextureFile = std::make_unique( - _colorTexturePath - ); - _colorTextureFile->setCallback( - [&](const ghoul::filesystem::File&) { _colorTextureIsDirty = true; } + _colorTexturePath.value() ); + _colorTextureFile->setCallback([this]() { _colorTextureIsDirty = true; }); } _colorTextureIsDirty = false; } @@ -1188,7 +1289,7 @@ void RenderableStars::update(const UpdateData&) { _otherDataColorMapTexture = nullptr; if (!_otherDataColorMapPath.value().empty()) { _otherDataColorMapTexture = ghoul::io::TextureReader::ref().loadTexture( - absPath(_otherDataColorMapPath) + absPath(_otherDataColorMapPath).string() ); if (_otherDataColorMapTexture) { LDEBUG(fmt::format( @@ -1208,278 +1309,45 @@ void RenderableStars::update(const UpdateData&) { } } -/* -void RenderableStars::loadShapeTexture() { - if (_shapeTextureIsDirty) { - LDEBUG("Reloading Shape Texture"); - _shapeTexture = nullptr; - if (_shapeTexturePath.value() != "") { - _shapeTexture = ghoul::io::TextureReader::ref().loadTexture( - absPath(_shapeTexturePath) - ); - if (_shapeTexture) { - LDEBUG(fmt::format( - "Loaded texture from '{}'", - absPath(_shapeTexturePath) - )); - _shapeTexture->uploadTexture(); - } - - _shapeTextureFile = std::make_unique( - _shapeTexturePath - ); - _shapeTextureFile->setCallback( - [&](const ghoul::filesystem::File&) { _shapeTextureIsDirty = true; } - ); - } - _shapeTextureIsDirty = false; - } -} -*/ - void RenderableStars::loadData() { - std::string file = absPath(_speckFile); - if (!FileSys.fileExists(file)) { + std::filesystem::path file = absPath(_speckFile); + if (!std::filesystem::is_regular_file(file)) { return; } - std::string cachedFile = FileSys.cacheManager()->cachedFilename( - file, - ghoul::filesystem::CacheManager::Persistent::Yes + _dataset = speck::data::loadFileWithCache(file); + if (_dataset.entries.empty()) { + return; + } + + std::vector variableNames; + variableNames.reserve(_dataset.variables.size()); + for (const speck::Dataset::Variable& v : _dataset.variables) { + variableNames.push_back(v.name); + } + _otherDataOption.addOptions(variableNames); + + bool success = _dataset.normalizeVariable("lum"); + if (!success) { + throw ghoul::RuntimeError("Could not find required variable 'luminosity'"); + } +} + +std::vector RenderableStars::createDataSlice(ColorOption option) { + const int bvIdx = std::max(_dataset.index(_dataMapping.bvColor.value()), 0); + const int lumIdx = std::max(_dataset.index(_dataMapping.luminance.value()), 0); + const int absMagIdx = std::max( + _dataset.index(_dataMapping.absoluteMagnitude.value()), + 0 ); - - _nValuesPerStar = 0; - _slicedData.clear(); - _fullData.clear(); - _dataNames.clear(); - - bool hasCachedFile = FileSys.fileExists(cachedFile); - if (hasCachedFile) { - LINFO(fmt::format("Cached file '{}' used for Speck file '{}'", - cachedFile, file - )); - - bool success = loadCachedFile(cachedFile); - if (success) { - return; - } - else { - FileSys.cacheManager()->removeCacheFile(file); - // Intentional fall-through to the 'else' computation to generate the cache - // file for the next run - } - } - else { - LINFO(fmt::format("Cache for Speck file '{}' not found", file)); - } - LINFO(fmt::format("Loading Speck file '{}'", file)); - - readSpeckFile(); - - LINFO("Saving cache"); - saveCachedFile(cachedFile); -} - -void RenderableStars::readSpeckFile() { - std::string _file = _speckFile; - std::ifstream file(_file); - if (!file.good()) { - LERROR(fmt::format("Failed to open Speck file '{}'", _file)); - return; - } - - // The beginning of the speck file has a header that either contains comments - // (signaled by a preceding '#') or information about the structure of the file - // (signaled by the keywords 'datavar', 'texturevar', and 'texture') - std::string line; - while (true) { - std::streampos position = file.tellg(); - std::getline(file, line, '\n'); - - if (line[0] == '#' || line.empty()) { - continue; - } - - if (line.substr(0, 7) != "datavar" && - line.substr(0, 10) != "texturevar" && - line.substr(0, 7) != "texture") - { - // we read a line that doesn't belong to the header, so we have to jump back - // before the beginning of the current line - if (_enableTestGrid) { - file.seekg(position - std::streamoff(8)); - } - break; - } - - if (line.substr(0, 7) == "datavar") { - // datavar lines are structured as follows: - // datavar # description - // where # is the index of the data variable; so if we repeatedly overwrite - // the 'nValues' variable with the latest index, we will end up with the total - // number of values (+3 since X Y Z are not counted in the Speck file index) - std::stringstream str(line); - - std::string dummy; - str >> dummy; - str >> _nValuesPerStar; - - std::string name; - str >> name; - _dataNames.push_back(name); - - // +3 because the position x, y, z - if (name == "lum") { - _lumArrayPos = _nValuesPerStar + 3; - } - else if (name == "absmag") { - _absMagArrayPos = _nValuesPerStar + 3; - } - else if (name == "appmag") { - _appMagArrayPos = _nValuesPerStar + 3; - } - else if (name == "colorb_v") { - _bvColorArrayPos = _nValuesPerStar + 3; - } - else if (name == "vx") { - _velocityArrayPos = _nValuesPerStar + 3; - } - else if (name == "speed") { - _speedArrayPos = _nValuesPerStar + 3; - } - _nValuesPerStar += 1; // We want the number, but the index is 0 based - } - } - - _nValuesPerStar += 3; // X Y Z are not counted in the Speck file indices - _otherDataOption.addOptions(_dataNames); - - float minLumValue = std::numeric_limits::max(); - float maxLumValue = std::numeric_limits::min(); - - do { - std::vector values(_nValuesPerStar); - std::stringstream str(line); - - for (int i = 0; i < _nValuesPerStar; ++i) { - str >> values[i]; - } - - bool nullArray = true; - for (float v : values) { - if (v != 0.0) { - nullArray = false; - break; - } - } - minLumValue = values[_lumArrayPos] < minLumValue ? - values[_lumArrayPos] : minLumValue; - maxLumValue = values[_lumArrayPos] > maxLumValue ? - values[_lumArrayPos] : maxLumValue; - if (!nullArray) { - _fullData.insert(_fullData.end(), values.begin(), values.end()); - } - - std::getline(file, line, '\n'); - - } while (!file.eof()); - - // Normalize Luminosity: - for (size_t i = 0; i < _fullData.size(); i += _nValuesPerStar) { - _fullData[i + _lumArrayPos] = - (_fullData[i + _lumArrayPos] - minLumValue) / (maxLumValue - minLumValue); - } -} - -bool RenderableStars::loadCachedFile(const std::string& file) { - std::ifstream fileStream(file, std::ifstream::binary); - if (fileStream.good()) { - int8_t version = 0; - fileStream.read(reinterpret_cast(&version), sizeof(int8_t)); - if (version != CurrentCacheVersion) { - LINFO("The format of the cached file has changed: deleting old cache"); - fileStream.close(); - FileSys.deleteFile(file); - return false; - } - - int32_t nValues = 0; - fileStream.read(reinterpret_cast(&nValues), sizeof(int32_t)); - fileStream.read(reinterpret_cast(&_nValuesPerStar), sizeof(int32_t)); - - fileStream.read(reinterpret_cast(&_lumArrayPos), sizeof(int32_t)); - fileStream.read(reinterpret_cast(&_absMagArrayPos), sizeof(int32_t)); - fileStream.read(reinterpret_cast(&_appMagArrayPos), sizeof(int32_t)); - fileStream.read(reinterpret_cast(&_bvColorArrayPos), sizeof(int32_t)); - fileStream.read(reinterpret_cast(&_velocityArrayPos), sizeof(int32_t)); - fileStream.read(reinterpret_cast(&_speedArrayPos), sizeof(int32_t)); - - for (int i = 0; i < _nValuesPerStar - 3; ++i) { - uint16_t len; - fileStream.read(reinterpret_cast(&len), sizeof(uint16_t)); - std::vector buffer(len); - fileStream.read(buffer.data(), len); - std::string value(buffer.begin(), buffer.end()); - _dataNames.push_back(value); - } - _otherDataOption.addOptions(_dataNames); - - _fullData.resize(nValues); - fileStream.read(reinterpret_cast( - _fullData.data()), - nValues * sizeof(_fullData[0]) - ); - - bool success = fileStream.good(); - return success; - } - else { - LERROR(fmt::format("Error opening file '{}' for loading cache file", file)); - return false; - } -} - -void RenderableStars::saveCachedFile(const std::string& file) const { - std::ofstream fileStream(file, std::ofstream::binary); - - if (!fileStream.good()) { - LERROR(fmt::format("Error opening file '{}' for save cache file", file)); - return; - } - - fileStream.write( - reinterpret_cast(&CurrentCacheVersion), - sizeof(int8_t) + const int appMagIdx = std::max( + _dataset.index(_dataMapping.apparentMagnitude.value()), + 0 ); - - int32_t nValues = static_cast(_fullData.size()); - if (nValues == 0) { - throw ghoul::RuntimeError("Error writing cache: No values were loaded"); - } - fileStream.write(reinterpret_cast(&nValues), sizeof(int32_t)); - - int32_t nValuesPerStar = static_cast(_nValuesPerStar); - fileStream.write(reinterpret_cast(&nValuesPerStar), sizeof(int32_t)); - fileStream.write(reinterpret_cast(&_lumArrayPos), sizeof(int32_t)); - fileStream.write(reinterpret_cast(&_absMagArrayPos), sizeof(int32_t)); - fileStream.write(reinterpret_cast(&_appMagArrayPos), sizeof(int32_t)); - fileStream.write(reinterpret_cast(&_bvColorArrayPos), sizeof(int32_t)); - fileStream.write(reinterpret_cast(&_velocityArrayPos), sizeof(int32_t)); - fileStream.write(reinterpret_cast(&_speedArrayPos), sizeof(int32_t)); - - // -3 as we don't want to save the xyz values that are in the beginning of the file - for (int i = 0; i < _nValuesPerStar - 3; ++i) { - uint16_t len = static_cast(_dataNames[i].size()); - fileStream.write(reinterpret_cast(&len), sizeof(uint16_t)); - fileStream.write(_dataNames[i].c_str(), len); - } - - size_t nBytes = nValues * sizeof(_fullData[0]); - fileStream.write(reinterpret_cast(_fullData.data()), nBytes); -} - -void RenderableStars::createDataSlice(ColorOption option) { - _slicedData.clear(); + const int vxIdx = std::max(_dataset.index(_dataMapping.vx.value()), 0); + const int vyIdx = std::max(_dataset.index(_dataMapping.vy.value()), 0); + const int vzIdx = std::max(_dataset.index(_dataMapping.vz.value()), 0); + const int speedIdx = std::max(_dataset.index(_dataMapping.speed.value()), 0); _otherDataRange = glm::vec2( std::numeric_limits::max(), @@ -1488,18 +1356,12 @@ void RenderableStars::createDataSlice(ColorOption option) { double maxRadius = 0.0; - for (size_t i = 0; i < _fullData.size(); i += _nValuesPerStar) { - glm::dvec3 position = glm::dvec3( - _fullData[i + 0], - _fullData[i + 1], - _fullData[i + 2] - ); - position *= openspace::distanceconstants::Parsec; - - const double r = glm::length(position); - if (r > maxRadius) { - maxRadius = r; - } + std::vector result; + // 7 for the default Color option of 3 positions + bv + lum + abs + app magnitude + result.reserve(_dataset.entries.size() * 7); + for (const speck::Dataset::Entry& e : _dataset.entries) { + glm::dvec3 position = glm::dvec3(e.position) * distanceconstants::Parsec; + maxRadius = std::max(maxRadius, glm::length(position)); switch (option) { case ColorOption::Color: @@ -1516,23 +1378,12 @@ void RenderableStars::createDataSlice(ColorOption option) { static_cast(position[2]) }}; - if (_enableTestGrid) { - float sunColor = 0.650f; - layout.value.value = sunColor;// _fullData[i + 3]; - } - else { - layout.value.value = _fullData[i + _bvColorArrayPos]; - } - - layout.value.luminance = _fullData[i + _lumArrayPos]; - layout.value.absoluteMagnitude = _fullData[i + _absMagArrayPos]; - layout.value.apparentMagnitude = _fullData[i + _appMagArrayPos]; - - _slicedData.insert( - _slicedData.end(), - layout.data.begin(), - layout.data.end()); + layout.value.value = e.data[bvIdx]; + layout.value.luminance = e.data[lumIdx]; + layout.value.absoluteMagnitude = e.data[absMagIdx]; + layout.value.apparentMagnitude = e.data[appMagIdx]; + result.insert(result.end(), layout.data.begin(), layout.data.end()); break; } case ColorOption::Velocity: @@ -1548,20 +1399,16 @@ void RenderableStars::createDataSlice(ColorOption option) { static_cast(position[2]) }}; - layout.value.value = _fullData[i + _bvColorArrayPos]; - layout.value.luminance = _fullData[i + _lumArrayPos]; - layout.value.absoluteMagnitude = _fullData[i + _absMagArrayPos]; - layout.value.apparentMagnitude = _fullData[i + _appMagArrayPos]; + layout.value.value = e.data[bvIdx]; + layout.value.luminance = e.data[lumIdx]; + layout.value.absoluteMagnitude = e.data[absMagIdx]; + layout.value.apparentMagnitude = e.data[appMagIdx]; - layout.value.vx = _fullData[i + _velocityArrayPos]; - layout.value.vy = _fullData[i + _velocityArrayPos + 1]; - layout.value.vz = _fullData[i + _velocityArrayPos + 2]; + layout.value.vx = e.data[vxIdx]; + layout.value.vy = e.data[vyIdx]; + layout.value.vz = e.data[vzIdx]; - _slicedData.insert( - _slicedData.end(), - layout.data.begin(), - layout.data.end() - ); + result.insert(result.end(), layout.data.begin(), layout.data.end()); break; } case ColorOption::Speed: @@ -1577,18 +1424,13 @@ void RenderableStars::createDataSlice(ColorOption option) { static_cast(position[2]) }}; - layout.value.value = _fullData[i + _bvColorArrayPos]; - layout.value.luminance = _fullData[i + _lumArrayPos]; - layout.value.absoluteMagnitude = _fullData[i + _absMagArrayPos]; - layout.value.apparentMagnitude = _fullData[i + _appMagArrayPos]; + layout.value.value = e.data[bvIdx]; + layout.value.luminance = e.data[lumIdx]; + layout.value.absoluteMagnitude = e.data[absMagIdx]; + layout.value.apparentMagnitude = e.data[appMagIdx]; + layout.value.speed = e.data[speedIdx]; - layout.value.speed = _fullData[i + _speedArrayPos]; - - _slicedData.insert( - _slicedData.end(), - layout.data.begin(), - layout.data.end() - ); + result.insert(result.end(), layout.data.begin(), layout.data.end()); break; } case ColorOption::OtherData: @@ -1606,37 +1448,32 @@ void RenderableStars::createDataSlice(ColorOption option) { int index = _otherDataOption.value(); // plus 3 because of the position - layout.value.value = _fullData[i + index + 3]; + layout.value.value = e.data[index]; - if (_staticFilterValue.has_value() && - layout.value.value == _staticFilterValue) + if (_staticFilterValue.has_value() && e.data[index] == _staticFilterValue) { layout.value.value = _staticFilterReplacementValue; } - glm::vec2 range = _otherDataRange.value(); + glm::vec2 range = _otherDataRange; range.x = std::min(range.x, layout.value.value); range.y = std::max(range.y, layout.value.value); _otherDataRange = range; _otherDataRange.setMinValue(glm::vec2(range.x)); _otherDataRange.setMaxValue(glm::vec2(range.y)); - layout.value.luminance = _fullData[i + _lumArrayPos]; - layout.value.absoluteMagnitude = _fullData[i + _absMagArrayPos]; - layout.value.apparentMagnitude = _fullData[i + _appMagArrayPos]; - - _slicedData.insert( - _slicedData.end(), - layout.data.begin(), - layout.data.end() - ); + layout.value.luminance = e.data[lumIdx]; + layout.value.absoluteMagnitude = e.data[absMagIdx]; + layout.value.apparentMagnitude = e.data[appMagIdx]; + result.insert(result.end(), layout.data.begin(), layout.data.end()); break; } } } setBoundingSphere(maxRadius); + return result; } } // namespace openspace diff --git a/modules/space/rendering/renderablestars.h b/modules/space/rendering/renderablestars.h index 7f1e83eb02..bb2af31f34 100644 --- a/modules/space/rendering/renderablestars.h +++ b/modules/space/rendering/renderablestars.h @@ -27,6 +27,7 @@ #include +#include #include #include #include @@ -74,15 +75,8 @@ private: FixedColor = 4 }; - static const int _psfTextureSize = 64; - static const int _convolvedfTextureSize = 257; - - void createDataSlice(ColorOption option); - void loadData(); - void readSpeckFile(); - bool loadCachedFile(const std::string& file); - void saveCachedFile(const std::string& file) const; + std::vector createDataSlice(ColorOption option); properties::StringProperty _speckFile; @@ -90,9 +84,17 @@ private: std::unique_ptr _colorTexture; std::unique_ptr _colorTextureFile; - //properties::StringProperty _shapeTexturePath; - //std::unique_ptr _shapeTexture; - //std::unique_ptr _shapeTextureFile; + properties::PropertyOwner _dataMappingContainer; + struct { + properties::StringProperty bvColor; + properties::StringProperty luminance; + properties::StringProperty absoluteMagnitude; + properties::StringProperty apparentMagnitude; + properties::StringProperty vx; + properties::StringProperty vy; + properties::StringProperty vz; + properties::StringProperty speed; + } _dataMapping; properties::OptionProperty _colorOption; properties::OptionProperty _otherDataOption; @@ -123,16 +125,15 @@ private: properties::PropertyOwner _userProvidedTextureOwner; properties::PropertyOwner _parametersOwner; properties::PropertyOwner _moffatMethodOwner; - properties::Vec2Property _fadeInDistance; + properties::Vec2Property _fadeInDistances; properties::BoolProperty _disableFadeInDistance; std::unique_ptr _program; UniformCache( - modelMatrix, cameraUp, cameraViewProjectionMatrix, - colorOption, magnitudeExponent, eyePosition, psfParamConf, - lumCent, radiusCent, brightnessCent, colorTexture, - alphaValue, psfTexture, otherDataTexture, otherDataRange, - filterOutOfRange, fixedColor + modelMatrix, cameraUp, cameraViewProjectionMatrix, colorOption, magnitudeExponent, + eyePosition, psfParamConf, lumCent, radiusCent, brightnessCent, colorTexture, + alphaValue, psfTexture, otherDataTexture, otherDataRange, filterOutOfRange, + fixedColor ) _uniformCache; bool _speckFileIsDirty = true; @@ -142,26 +143,13 @@ private: bool _dataIsDirty = true; bool _otherDataColorMapIsDirty = true; - // Test Grid Enabled - bool _enableTestGrid = false; + speck::Dataset _dataset; - std::vector _slicedData; - std::vector _fullData; - - int _nValuesPerStar = 0; std::string _queuedOtherData; - std::vector _dataNames; std::optional _staticFilterValue; float _staticFilterReplacementValue = 0.f; - std::size_t _lumArrayPos = 0; - std::size_t _absMagArrayPos = 0; - std::size_t _appMagArrayPos = 0; - std::size_t _bvColorArrayPos = 0; - std::size_t _velocityArrayPos = 0; - std::size_t _speedArrayPos = 0; - GLuint _vao = 0; GLuint _vbo = 0; GLuint _psfVao = 0; diff --git a/modules/space/rendering/simplespheregeometry.cpp b/modules/space/rendering/simplespheregeometry.cpp index 5c4ed12ef9..eb95f5153c 100644 --- a/modules/space/rendering/simplespheregeometry.cpp +++ b/modules/space/rendering/simplespheregeometry.cpp @@ -55,9 +55,7 @@ namespace { namespace openspace::planetgeometry { documentation::Documentation SimpleSphereGeometry::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "space_geometry_simplesphere"; - return doc; + return codegen::doc("space_geometry_simplesphere"); } SimpleSphereGeometry::SimpleSphereGeometry(const ghoul::Dictionary& dictionary) diff --git a/modules/space/rotation/spicerotation.cpp b/modules/space/rotation/spicerotation.cpp index 927c1c7ceb..dad12653d2 100644 --- a/modules/space/rotation/spicerotation.cpp +++ b/modules/space/rotation/spicerotation.cpp @@ -52,6 +52,13 @@ namespace { "The time frame in which the spice kernels are valid." }; + constexpr openspace::properties::Property::PropertyInfo FixedDateInfo = { + "FixedDate", + "Fixed Date", + "A time to lock the rotation to. Setting this to an empty string will " + "unlock the time and return to rotation based on current simulation time." + }; + struct [[codegen::Dictionary(SpiceRotation)]] Parameters { // [[codegen::verbatim(SourceInfo.description)]] std::string sourceFrame @@ -66,6 +73,10 @@ namespace { // [[codegen::verbatim(TimeFrameInfo.description)]] std::optional timeFrame [[codegen::reference("core_time_frame")]]; + + // [[codegen::verbatim(FixedDateInfo.description)]] + std::optional fixedDate + [[codegen::annotation("A time to lock the rotation to")]]; }; #include "spicerotation_codegen.cpp" } // namespace @@ -73,14 +84,13 @@ namespace { namespace openspace { documentation::Documentation SpiceRotation::Documentation() { - documentation::Documentation doc = codegen::doc(); - doc.id = "space_transform_rotation_spice"; - return doc; + return codegen::doc("space_transform_rotation_spice"); } SpiceRotation::SpiceRotation(const ghoul::Dictionary& dictionary) : _sourceFrame(SourceInfo) , _destinationFrame(DestinationInfo) + , _fixedDate(FixedDateInfo) { const Parameters p = codegen::bake(dictionary); @@ -98,6 +108,17 @@ SpiceRotation::SpiceRotation(const ghoul::Dictionary& dictionary) } } + _fixedDate.onChange([this]() { + if (_fixedDate.value().empty()) { + _fixedEphemerisTime = std::nullopt; + } + else { + _fixedEphemerisTime = SpiceManager::ref().ephemerisTimeFromDate(_fixedDate); + } + }); + _fixedDate = p.fixedDate.value_or(_fixedDate); + addProperty(_fixedDate); + if (dictionary.hasKey(TimeFrameInfo.identifier)) { ghoul::Dictionary timeFrameDictionary = dictionary.value(TimeFrameInfo.identifier); @@ -113,16 +134,21 @@ SpiceRotation::SpiceRotation(const ghoul::Dictionary& dictionary) _sourceFrame.onChange([this]() { requireUpdate(); }); _destinationFrame.onChange([this]() { requireUpdate(); }); + } glm::dmat3 SpiceRotation::matrix(const UpdateData& data) const { if (_timeFrame && !_timeFrame->isActive(data.time)) { return glm::dmat3(1.0); } + double time = data.time.j2000Seconds(); + if (_fixedEphemerisTime.has_value()) { + time = *_fixedEphemerisTime; + } return SpiceManager::ref().positionTransformMatrix( _sourceFrame, _destinationFrame, - data.time.j2000Seconds() + time ); } diff --git a/modules/space/rotation/spicerotation.h b/modules/space/rotation/spicerotation.h index 1cc4043774..af819b9606 100644 --- a/modules/space/rotation/spicerotation.h +++ b/modules/space/rotation/spicerotation.h @@ -29,6 +29,7 @@ #include #include +#include namespace openspace { @@ -46,7 +47,10 @@ public: private: properties::StringProperty _sourceFrame; properties::StringProperty _destinationFrame; + properties::StringProperty _fixedDate; + ghoul::mm_unique_ptr _timeFrame; + std::optional _fixedEphemerisTime; }; } // namespace openspace diff --git a/modules/space/shaders/constellationbounds_fs.glsl b/modules/space/shaders/constellationbounds_fs.glsl index 32ea62a82e..5e0f05b820 100644 --- a/modules/space/shaders/constellationbounds_fs.glsl +++ b/modules/space/shaders/constellationbounds_fs.glsl @@ -27,16 +27,14 @@ in vec4 vs_position; -uniform vec4 campos; -uniform vec4 objpos; uniform vec3 color; Fragment getFragment() { - vec4 position = vs_position; + vec4 position = vs_position; - Fragment frag; - frag.color = vec4(color, 1.0); - frag.depth = pscDepth(position); + Fragment frag; + frag.color = vec4(color, 1.0); + frag.depth = pscDepth(position); - return frag; + return frag; } diff --git a/modules/space/shaders/constellationbounds_vs.glsl b/modules/space/shaders/constellationbounds_vs.glsl index 1f3bc5245e..12c74b2476 100644 --- a/modules/space/shaders/constellationbounds_vs.glsl +++ b/modules/space/shaders/constellationbounds_vs.glsl @@ -33,11 +33,11 @@ uniform mat4 ModelTransform; #include "PowerScaling/powerScaling_vs.hglsl" void main() { - vec4 tmp = vec4(in_position, 0.0); - vs_position = tmp; + vec4 tmp = vec4(in_position, 0.0); + vs_position = tmp; - vec4 position = pscTransform(tmp, ModelTransform); - vs_position = tmp; - position = ViewProjection * position; - gl_Position = z_normalization(position); + vec4 position = pscTransform(tmp, ModelTransform); + vs_position = tmp; + position = ViewProjection * position; + gl_Position = z_normalization(position); } diff --git a/modules/space/shaders/convolution_fs.glsl b/modules/space/shaders/convolution_fs.glsl index c884ce1846..cea22697c0 100644 --- a/modules/space/shaders/convolution_fs.glsl +++ b/modules/space/shaders/convolution_fs.glsl @@ -26,8 +26,7 @@ out vec4 renderTableColor; -in vec2 psfCoords; -in vec2 texturesCoords; +in vec2 vs_uv; uniform int psfTextureSize; uniform int convolvedfTextureSize; @@ -35,42 +34,19 @@ uniform sampler2D psfTexture; uniform sampler2D shapeTexture; void main() { - float fullColor = 0.0; - - // Kernel Center - //vec2 psfTextureCoords = vec2((float(psfTextureSize)/2.0 + 1.0) / float(psfTextureSize)); - // fullColor += texture2D(shapeTexture, texturesCoords) * - // texture2D(psfTexture, psfTextureCoords); - - float maxConvSize = float(psfTextureSize); - float convStep = 1.0 / maxConvSize; - float textureStep = 1.0 / float(convolvedfTextureSize); - for (float i = 0.0, ii = 0.0; i < maxConvSize; i += convStep, ii += textureStep) { - for (float j = 0.0, jj = 0.0; j < maxConvSize; j += convStep, jj += textureStep) { - vec2 newTexCoords = texturesCoords; - newTexCoords.x = i < 0.5 ? texturesCoords.x - ii : texturesCoords.x + ii; - newTexCoords.y = j < 0.5 ? texturesCoords.y - jj : texturesCoords.y + jj; - newTexCoords.x = newTexCoords.x > 1.0 ? 1.0 : newTexCoords.x < 0.0 ? 0.0 : newTexCoords.x; - newTexCoords.y = newTexCoords.y > 1.0 ? 1.0 : newTexCoords.y < 0.0 ? 0.0 : newTexCoords.y; - fullColor += texture2D(shapeTexture, newTexCoords).x * - texture2D(psfTexture, vec2(i, j)).x; - } + float fullColor = 0.0; + + float maxConvSize = float(psfTextureSize); + float convStep = 1.0 / maxConvSize; + float textureStep = 1.0 / float(convolvedfTextureSize); + for (float i = 0.0, ii = 0.0; i < maxConvSize; i += convStep, ii += textureStep) { + for (float j = 0.0, jj = 0.0; j < maxConvSize; j += convStep, jj += textureStep) { + vec2 uv = vs_uv; + uv.x = clamp(i < 0.5 ? vs_uv.x - ii : vs_uv.x + ii, 0.0, 1.0); + uv.y = clamp(j < 0.5 ? vs_uv.y - jj : vs_uv.y + jj, 0.0, 1.0); + fullColor += texture(shapeTexture, uv).x * texture(psfTexture, vec2(i, j)).x; } + } - /* - vec2 onePixel = vec2(1.0, 1.0) / float(psfTextureSize); - vec4 fullColor = - texture2D(shapeTexture, texturesCoords + onePixel * vec2(-1, -1)) * texture2D(psfTexture, vec2(i, j)) + - texture2D(shapeTexture, texturesCoords + onePixel * vec2( 0, -1)) * texture2D(psfTexture, vec2(i, j)) + - texture2D(shapeTexture, texturesCoords + onePixel * vec2( 1, -1)) * texture2D(psfTexture, vec2(i, j)) + - texture2D(shapeTexture, texturesCoords + onePixel * vec2(-1, 0)) * texture2D(psfTexture, vec2(i, j)) + - texture2D(shapeTexture, texturesCoords + onePixel * vec2( 0, 0)) * texture2D(psfTexture, vec2(i, j)) + - texture2D(shapeTexture, texturesCoords + onePixel * vec2( 1, 0)) * texture2D(psfTexture, vec2(i, j)) + - texture2D(shapeTexture, texturesCoords + onePixel * vec2(-1, 1)) * texture2D(psfTexture, vec2(i, j)) + - texture2D(shapeTexture, texturesCoords + onePixel * vec2( 0, 1)) * texture2D(psfTexture, vec2(i, j)) + - texture2D(shapeTexture, texturesCoords + onePixel * vec2( 1, 1)) * texture2D(psfTexture, vec2(i, j)); - */ - - - renderTableColor = vec4(fullColor/40.0); + renderTableColor = vec4(fullColor / 40.0); } diff --git a/modules/space/shaders/convolution_vs.glsl b/modules/space/shaders/convolution_vs.glsl index a92bf82d5d..d3cb844fbe 100644 --- a/modules/space/shaders/convolution_vs.glsl +++ b/modules/space/shaders/convolution_vs.glsl @@ -26,11 +26,9 @@ layout(location = 0) in vec4 in_position; -out vec2 psfCoords; -out vec2 texturesCoords; +out vec2 vs_uv; void main() { - gl_Position = vec4(in_position.xy, 0.f, 1.f); - psfCoords = vec2(in_position); - texturesCoords = vec2(in_position.zw); + gl_Position = vec4(in_position.xy, 0.0, 1.0); + vs_uv = vec2(in_position.zw); } diff --git a/modules/space/shaders/debrisViz_fs.glsl b/modules/space/shaders/debrisViz_fs.glsl index b7a8476e81..239894d9ea 100644 --- a/modules/space/shaders/debrisViz_fs.glsl +++ b/modules/space/shaders/debrisViz_fs.glsl @@ -23,77 +23,52 @@ ****************************************************************************************/ #include "fragment.glsl" -//#include "floatoperations.glsl" + +in vec4 viewSpacePosition; +in float viewSpaceDepth; +in float periodFraction; +in float offsetPeriods; uniform vec3 color; uniform float opacity = 1.0; - uniform float lineFade; -// uniform int numberOfSegments; - -in vec4 viewSpacePosition; -in float vs_position_w; - -in float periodFraction_f; -in float offsetPeriods; -in float vertexID_f; - -// debuggers : -// in float offset; -// in float epoch; -// in float period; -// in flat double tajm; Fragment getFragment() { - // float offsetPeriods = offset / period; - // This is now done in the fragment shader instead - // to make smooth movement between vertecies. - // We want vertexDistance to be double up to this point, I think. - // (hence the unnessesary float to float conversion) - float vertexDistance = periodFraction_f - offsetPeriods; - float vertexDistance_f = float(vertexDistance); - - // This is the alternative way of calculating - // the offsetPeriods: (vertexID_perOrbit/nrOfSegments_f) - // float vertexID_perOrbit = mod(vertexID_f, numberOfSegments); - // float nrOfSegments_f = float(numberOfSegments); - // float vertexDistance = periodFraction_f - (vertexID_perOrbit/nrOfSegments_f); + // float offsetPeriods = offset / period; + // This is now done in the fragment shader instead to make smooth movement between + // vertices. We want vertexDistance to be double up to this point, I think, (hence the + // unnessesary float to float conversion) + float vertexDistance = periodFraction - offsetPeriods; + + // This is the alternative way of calculating + // the offsetPeriods: (vertexID_perOrbit/nrOfSegments_f) + // float vertexID_perOrbit = mod(vertexID_f, numberOfSegments); + // float nrOfSegments_f = float(numberOfSegments); + // float vertexDistance = periodFraction - (vertexID_perOrbit/nrOfSegments_f); - if (vertexDistance_f < 0.0) { - vertexDistance_f += 1.0; - } + if (vertexDistance < 0.0) { + vertexDistance += 1.0; + } - float invert = pow((1.0 - vertexDistance_f), lineFade); - float fade = clamp(invert, 0.0, 1.0); + float invert = pow((1.0 - vertexDistance), lineFade); + float fade = clamp(invert, 0.0, 1.0); - // Currently even fully transparent lines can occlude other lines, thus we discard - // these fragments since debris and satellites are rendered so close to each other - if (fade < 0.05) { - discard; - } - Fragment frag; + // Currently even fully transparent lines can occlude other lines, thus we discard these + // fragments since debris and satellites are rendered so close to each other + if (fade < 0.05) { + discard; + } + Fragment frag; + if (fade < 0.15) { // Use additive blending for some values to make the discarding less abrupt - if (fade < 0.15) { - frag.blend = BLEND_MODE_ADDITIVE; - } + frag.blend = BLEND_MODE_ADDITIVE; + } - frag.color = vec4(color, fade * opacity); - frag.depth = vs_position_w; - frag.gPosition = viewSpacePosition; - frag.gNormal = vec4(1, 1, 1, 0); + frag.color = vec4(color, fade * opacity); + frag.depth = viewSpaceDepth; + frag.gPosition = viewSpacePosition; + frag.gNormal = vec4(1.0, 1.0, 1.0, 0.0); - - // to debug using colors use this if-statment. - // float ep = 0.01; - // if (fract(vertexID_f) < ep) { - // periodFraction < ep - // frag.color = vec4(1, 0, 0, 1); - // } - - return frag; + return frag; } - - - - diff --git a/modules/space/shaders/debrisViz_vs.glsl b/modules/space/shaders/debrisViz_vs.glsl index 7ec4e86faf..460e8f6e87 100644 --- a/modules/space/shaders/debrisViz_vs.glsl +++ b/modules/space/shaders/debrisViz_vs.glsl @@ -26,68 +26,47 @@ #include "PowerScaling/powerScalingMath.hglsl" -layout (location = 0) in vec4 vertex_data; // 1: x, 2: y, 3: z, 4: timeOffset, -layout (location = 1) in vec2 orbit_data; // 1: epoch, 2: period +layout (location = 0) in vec4 vertexData; // 1: x, 2: y, 3: z, 4: timeOffset, +layout (location = 1) in vec2 orbitData; // 1: epoch, 2: period + +out vec4 viewSpacePosition; +out float viewSpaceDepth; +out float periodFraction; +out float offsetPeriods; uniform dmat4 modelViewTransform; uniform mat4 projectionTransform; - -//uniform float lineFade; uniform double inGameTime; -out vec4 viewSpacePosition; -out float vs_position_w; - -out float periodFraction_f; -out float offsetPeriods; -out float vertexID_f; - -// debugers : -// out float offset; -// out float epoch; -// out float period; -// out double tajm; - void main() { - // tajm = inGameTime; - /** The way the position and line fade is calculated is: - * By using inGameTime, epoch and period of this orbit, - * we get how many revolutions it has done since epoch. - * The fract of that, is how far into a revolution it has traveld since epoch. - * Similarly we do the same but for this vertex, but calculating offsetPeriods. - * In the fragment shader the difference between - * periodFraction_f and offsetPeriods is calculated to know how much to fade - * that specific fragment. - */ + /* + * The way the position and line fade is calculated is: + * By using inGameTime, epoch and period of this orbit, we get how many revolutions it + * has done since epoch. The fract of that, is how far into a revolution it has traveled + * since epoch. Similarly we do the same but for this vertex, but calculating + * offsetPeriods. In the fragment shader the difference between periodFraction_f and + * offsetPeriods is calculated to know how much to fade that specific fragment. + */ - // If orbit_data is doubles, cast to float first - float offset = vertex_data.w; - double epoch = orbit_data.x; - double period = orbit_data.y; - - // calculate nr of periods, get fractional part to know where - // the vertex closest to the debris part is right now - double nrOfRevolutions = (inGameTime - epoch) / period; - //double periodFraction = fract(nrOfRevolutions); //mod(nrOfRevolutions, 1.0); - int intfrac = int(nrOfRevolutions); - double doublefrac = double(intfrac); - double periodFraction = nrOfRevolutions - doublefrac; - if (periodFraction < 0.0) { - periodFraction += 1.0; - } - periodFraction_f = float(periodFraction); + // If orbit_data is doubles, cast to float first + float epoch = orbitData.x; + float period = orbitData.y; - // same procedure for the current vertex - float period_f = float(period); - offsetPeriods = offset / period_f; + // calculate nr of periods, get fractional part to know where the vertex closest to the + // debris part is right now + double nrOfRevolutions = (inGameTime - epoch) / period; + double frac = double(int(nrOfRevolutions)); + double periodFractiond = nrOfRevolutions - frac; + if (periodFractiond < 0.0) { + periodFractiond += 1.0; + } + periodFraction = float(periodFractiond); - // offsetPeriods can also be calculated by passing the vertexID as a float - // to the fragment shader and deviding it by nrOfSegments. - vertexID_f = float(gl_VertexID); - dvec3 positions = dvec3(vertex_data.x, vertex_data.y, vertex_data.z); - dvec4 vertexPosition = dvec4(positions, 1); - viewSpacePosition = vec4(modelViewTransform * vertexPosition); - vec4 vs_position = z_normalization( projectionTransform * viewSpacePosition); - gl_Position = vs_position; - vs_position_w = vs_position.w; + // same procedure for the current vertex + offsetPeriods = vertexData.w / float(period); + + viewSpacePosition = vec4(modelViewTransform * dvec4(vertexData.xyz, 1)); + vec4 vs_position = z_normalization(projectionTransform * viewSpacePosition); + gl_Position = vs_position; + viewSpaceDepth = vs_position.w; } diff --git a/modules/space/shaders/habitablezone_fs.glsl b/modules/space/shaders/habitablezone_fs.glsl index 11bcca4f3b..565a0f8379 100644 --- a/modules/space/shaders/habitablezone_fs.glsl +++ b/modules/space/shaders/habitablezone_fs.glsl @@ -40,48 +40,48 @@ uniform bool showOptimistic; float computeTextureCoord(float radius, float innerRadius, float conservativeInner, float conservativeOuter) { - const float t1 = 1.0 / 3.0; - const float t2 = 2.0 / 3.0; + const float t1 = 1.0 / 3.0; + const float t2 = 2.0 / 3.0; - if (radius < conservativeInner) { - float t = (radius - innerRadius) / (conservativeInner - innerRadius); - return mix(0.0, t1, t); - } - else if (radius > conservativeOuter) { - float t = (radius - conservativeOuter) / (1.0 - conservativeOuter); - return mix(t2, 1.0, t); - } - else { - float t = (radius - conservativeInner) / (conservativeOuter - conservativeInner); - return mix(t1, t2, t); - } + if (radius < conservativeInner) { + float t = (radius - innerRadius) / (conservativeInner - innerRadius); + return mix(0.0, t1, t); + } + else if (radius > conservativeOuter) { + float t = (radius - conservativeOuter) / (1.0 - conservativeOuter); + return mix(t2, 1.0, t); + } + else { + float t = (radius - conservativeInner) / (conservativeOuter - conservativeInner); + return mix(t1, t2, t); + } } Fragment getFragment() { - // The length of the texture coordinates vector is our distance from the center - float radius = length(vs_st); - float innerRadius = 1.0 - width; + // The length of the texture coordinates vector is our distance from the center + float radius = length(vs_st); + float innerRadius = 1.0 - width; - // We only want to consider ring-like objects so we need to discard everything else - if (radius > 1.0 || radius < innerRadius) { - discard; - } + // We only want to consider ring-like objects so we need to discard everything else + if (radius > 1.0 || radius < innerRadius) { + discard; + } - float consInner = conservativeBounds.x; - float consOuter = conservativeBounds.y; - bool outsideConservative = (radius < consInner) || (radius > consOuter); + float consInner = conservativeBounds.x; + float consOuter = conservativeBounds.y; + bool outsideConservative = (radius < consInner) || (radius > consOuter); - if (!showOptimistic && outsideConservative) { - discard; - } + if (!showOptimistic && outsideConservative) { + discard; + } - float texCoord = computeTextureCoord(radius, innerRadius, consInner, consOuter); + float texCoord = computeTextureCoord(radius, innerRadius, consInner, consOuter); - vec4 diffuse = texture(transferFunctionTexture, texCoord); - diffuse.a *= opacity; + vec4 diffuse = texture(transferFunctionTexture, texCoord); + diffuse.a *= opacity; - Fragment frag; - frag.color = diffuse; - frag.depth = vs_screenSpaceDepth; - return frag; + Fragment frag; + frag.color = diffuse; + frag.depth = vs_screenSpaceDepth; + return frag; } diff --git a/modules/space/shaders/habitablezone_vs.glsl b/modules/space/shaders/habitablezone_vs.glsl index d5796d62d9..599b4a2a8a 100644 --- a/modules/space/shaders/habitablezone_vs.glsl +++ b/modules/space/shaders/habitablezone_vs.glsl @@ -35,13 +35,13 @@ out float vs_screenSpaceDepth; uniform mat4 modelViewProjectionTransform; void main() { - vec4 position = vec4(in_position.xy, 0.0, 1.0); - vec4 positionScreenSpace = z_normalization(modelViewProjectionTransform * position); + vec4 position = vec4(in_position.xy, 0.0, 1.0); + vec4 positionScreenSpace = z_normalization(modelViewProjectionTransform * position); - // Moving the origin to the center - vs_st = (in_st - vec2(0.5)) * 2.0; + // Moving the origin to the center + vs_st = (in_st - vec2(0.5)) * 2.0; - vs_screenSpaceDepth = positionScreenSpace.w; + vs_screenSpaceDepth = positionScreenSpace.w; - gl_Position = positionScreenSpace; + gl_Position = positionScreenSpace; } diff --git a/modules/space/shaders/psfToTexture_fs.glsl b/modules/space/shaders/psfToTexture_fs.glsl index 288149d9b2..b4cba15cb2 100644 --- a/modules/space/shaders/psfToTexture_fs.glsl +++ b/modules/space/shaders/psfToTexture_fs.glsl @@ -24,7 +24,6 @@ #version __CONTEXT__ -//layout(location = 1) out vec4 renderTableColor; out vec4 renderTableColor; uniform int psfMethod; @@ -39,30 +38,32 @@ uniform float betaConstant; in vec2 psfCoords; +const int PsfMethodSpencer = 0; +const int PsfMethodMoffat = 1; + void main() { - vec4 fullColor = vec4(0.0, 0.0, 0.0, 1.0); - if (psfMethod == 0) { - // PSF Functions from paper: Physically-Based Galre Effects for Digital - // Images - Spencer, Shirley, Zimmerman and Greenberg. - float theta = sqrt((psfCoords.y*psfCoords.y + psfCoords.x*psfCoords.x)) * 90.0; - float f0 = 2.61E6 * exp(-pow(theta/alphaConst, 2.0)); - float f1 = 20.91/pow(theta + alphaConst, 3.0); - float f2 = 72.37/pow(theta + alphaConst, 2.0); - float psf_p = p0Param * f0 + p1Param * f1 + p2Param * f2; - fullColor = vec4(psf_p); - } - else if (psfMethod == 1) { - // Moffat - float r = sqrt((psfCoords.y*psfCoords.y + psfCoords.x*psfCoords.x)) * 90.0; - float alpha = FWHM / (2.f * sqrt(pow(2.f, 1.f/betaConstant) - 1)); - float moffat_psf = pow(1.f + (r/alpha)*(r/alpha), -betaConstant); - - fullColor = vec4(moffat_psf); - } - - if (fullColor.a == 0) { - discard; - } - - renderTableColor = fullColor; + vec4 fullColor = vec4(0.0, 0.0, 0.0, 1.0); + if (psfMethod == PsfMethodSpencer) { + // PSF Functions from paper: Physically-Based Galre Effects for Digital + // Images - Spencer, Shirley, Zimmerman and Greenberg. + float theta = sqrt((psfCoords.y * psfCoords.y + psfCoords.x * psfCoords.x)) * 90.0; + float f0 = 2.61E6 * exp(-pow(theta / alphaConst, 2.0)); + float f1 = 20.91 / pow(theta + alphaConst, 3.0); + float f2 = 72.37 / pow(theta + alphaConst, 2.0); + float spencer = p0Param * f0 + p1Param * f1 + p2Param * f2; + fullColor = vec4(spencer); +} + else if (psfMethod == PsfMethodMoffat) { + // Moffat + float r = sqrt((psfCoords.y * psfCoords.y + psfCoords.x * psfCoords.x)) * 90.0; + float alpha = FWHM / (2.0 * sqrt(pow(2.0, 1.0 / betaConstant) - 1.0)); + float moffat = pow(1.0 + (r/alpha) * (r/alpha), -betaConstant); + fullColor = vec4(moffat); + } + + if (fullColor.a == 0) { + discard; + } + + renderTableColor = fullColor; } diff --git a/modules/space/shaders/psfToTexture_vs.glsl b/modules/space/shaders/psfToTexture_vs.glsl index 03ae1f2ef5..e460cf80b8 100644 --- a/modules/space/shaders/psfToTexture_vs.glsl +++ b/modules/space/shaders/psfToTexture_vs.glsl @@ -29,6 +29,6 @@ layout(location = 0) in vec4 in_position; out vec2 psfCoords; void main() { - gl_Position = vec4(in_position.xy, 0.f, 1.f); - psfCoords = vec2(in_position); + gl_Position = vec4(in_position.xy, 0.0, 1.0); + psfCoords = vec2(in_position); } diff --git a/modules/space/shaders/rings_fs.glsl b/modules/space/shaders/rings_fs.glsl index 76c92cb733..b5fa7f35a2 100644 --- a/modules/space/shaders/rings_fs.glsl +++ b/modules/space/shaders/rings_fs.glsl @@ -38,61 +38,62 @@ uniform bool hasSunPosition; uniform vec3 sunPosition; uniform float _nightFactor; - Fragment getFragment() { - // Moving the origin to the center - vec2 st = (vs_st - vec2(0.5)) * 2.0; + // Moving the origin to the center + vec2 st = (vs_st - vec2(0.5)) * 2.0; - // The length of the texture coordinates vector is our distance from the center - float radius = length(st); + // The length of the texture coordinates vector is our distance from the center + float radius = length(st); - // We only want to consider ring-like objects so we need to discard everything else - if (radius > 1.0) - discard; + // We only want to consider ring-like objects so we need to discard everything else + if (radius > 1.0) { + discard; + } - // Remapping the texture coordinates - // Radius \in [0,1], texCoord \in [textureOffset.x, textureOffset.y] - // textureOffset.x -> 0 - // textureOffset.y -> 1 - float texCoord = (radius - textureOffset.x) / (textureOffset.y - textureOffset.x); - if (texCoord < 0.f || texCoord > 1.f) { - discard; - } - - vec4 diffuse = texture(texture1, texCoord); - // divided by 3 as length of vec3(1.0, 1.0, 1.0) will return 3 and we want - // to normalize the alpha value to [0,1] - float colorValue = length(diffuse.rgb) / 3.0; - if (colorValue < colorFilterValue) { - diffuse.a = colorValue * colorFilterValue; - if (diffuse.a < 0.65) - discard; + // Remapping the texture coordinates + // Radius \in [0,1], texCoord \in [textureOffset.x, textureOffset.y] + // textureOffset.x -> 0 + // textureOffset.y -> 1 + float texCoord = (radius - textureOffset.x) / (textureOffset.y - textureOffset.x); + if (texCoord < 0.0 || texCoord > 1.0) { + discard; + } + + vec4 diffuse = texture(texture1, texCoord); + // divided by 3 as length of vec3(1.0, 1.0, 1.0) will return 3 and we want + // to normalize the alpha value to [0,1] + float colorValue = length(diffuse.rgb) / 3.0; + if (colorValue < colorFilterValue) { + diffuse.a = colorValue * colorFilterValue; + if (diffuse.a < 0.65) { + discard; } + } - // The normal for the one plane depends on whether we are dealing - // with a front facing or back facing fragment - vec3 normal; - // The plane is oriented on the xz plane - // WARNING: This might not be the case for Uranus - if (gl_FrontFacing) { - normal = vec3(-1.0, 0.0, 0.0); - } - else { - normal = vec3(1.0, 0.0, 0.0); - } + // The normal for the one plane depends on whether we are dealing + // with a front facing or back facing fragment + vec3 normal; + // The plane is oriented on the xz plane + // WARNING: This might not be the case for Uranus + if (gl_FrontFacing) { + normal = vec3(-1.0, 0.0, 0.0); + } + else { + normal = vec3(1.0, 0.0, 0.0); + } - // Reduce the color of the fragment by the user factor - // if we are facing away from the Sun - if (dot(sunPosition, normal) < 0) { - diffuse.xyz *= _nightFactor; - } + // Reduce the color of the fragment by the user factor + // if we are facing away from the Sun + if (dot(sunPosition, normal) < 0) { + diffuse.xyz *= _nightFactor; + } - Fragment frag; - frag.color = diffuse; - frag.depth = vs_position.w; + Fragment frag; + frag.color = diffuse; + frag.depth = vs_position.w; - //frag.gPosition = vs_gPosition; - //frag.gNormal = vs_gNormal; + //frag.gPosition = vs_gPosition; + //frag.gNormal = vs_gNormal; - return frag; + return frag; } diff --git a/modules/space/shaders/rings_vs.glsl b/modules/space/shaders/rings_vs.glsl index c81afe6f9d..788298015f 100644 --- a/modules/space/shaders/rings_vs.glsl +++ b/modules/space/shaders/rings_vs.glsl @@ -31,16 +31,14 @@ layout(location = 1) in vec2 in_st; out vec2 vs_st; out vec4 vs_position; -//out vec4 vs_gPosition; -//out vec3 vs_gNormal; uniform mat4 modelViewProjectionTransform; void main() { - vs_st = in_st; + vs_st = in_st; - vs_position = z_normalization( - modelViewProjectionTransform * vec4(in_position.xy, 0.0, 1.0) - ); - gl_Position = vs_position; + vs_position = z_normalization( + modelViewProjectionTransform * vec4(in_position.xy, 0.0, 1.0) + ); + gl_Position = vs_position; } diff --git a/modules/space/shaders/star_fs.glsl b/modules/space/shaders/star_fs.glsl index a38dd238b1..166c2515aa 100644 --- a/modules/space/shaders/star_fs.glsl +++ b/modules/space/shaders/star_fs.glsl @@ -23,14 +23,13 @@ ****************************************************************************************/ #include "fragment.glsl" -#include "floatoperations.glsl" // keep in sync with renderablestars.h:ColorOption enum -const int COLOROPTION_COLOR = 0; -const int COLOROPTION_VELOCITY = 1; -const int COLOROPTION_SPEED = 2; -const int COLOROPTION_OTHERDATA = 3; -const int COLOROPTION_FIXEDCOLOR = 4; +const int ColorOptionColor = 0; +const int ColorOptionVelocity = 1; +const int ColorOptionSpeed = 2; +const int ColorOptionOtherData = 3; +const int ColorOptionFixedColor = 4; uniform sampler1D colorTexture; uniform sampler2D psfTexture; @@ -44,73 +43,68 @@ uniform sampler1D otherDataTexture; uniform vec2 otherDataRange; uniform bool filterOutOfRange; -in vec4 vs_position; -in vec2 psfCoords; -flat in vec4 ge_bvLumAbsMagAppMag; +in vec3 vs_position; +in vec2 texCoords; +flat in float ge_bv; flat in vec3 ge_velocity; flat in float ge_speed; -flat in float ge_observationDistance; flat in float gs_screenSpaceDepth; vec4 bv2rgb(float bv) { - // BV is [-0.4,2.0] - float t = (bv + 0.4) / (2.0 + 0.4); - return texture(colorTexture, t); + // BV is [-0.4,2.0] + float t = (bv + 0.4) / (2.0 + 0.4); + return texture(colorTexture, t); } bool isOtherDataValueInRange() { - float t = (ge_bvLumAbsMagAppMag.x - otherDataRange.x) / (otherDataRange.y - otherDataRange.x); - return t >= 0.0 && t <= 1.0; + float t = (ge_bv - otherDataRange.x) / (otherDataRange.y - otherDataRange.x); + return t >= 0.0 && t <= 1.0; } vec4 otherDataValue() { - float t = (ge_bvLumAbsMagAppMag.x - otherDataRange.x) / (otherDataRange.y - otherDataRange.x); - t = clamp(t, 0.0, 1.0); - return texture(otherDataTexture, t); + float t = (ge_bv - otherDataRange.x) / (otherDataRange.y - otherDataRange.x); + t = clamp(t, 0.0, 1.0); + return texture(otherDataTexture, t); } Fragment getFragment() { - // Something in the color calculations need to be changed because before it was dependent - // on the gl blend functions since the abuffer was not involved - - vec4 color = vec4(0.0); - switch (colorOption) { - case COLOROPTION_COLOR: - color = bv2rgb(ge_bvLumAbsMagAppMag.x); - break; - case COLOROPTION_VELOCITY: - color = vec4(abs(ge_velocity), 0.5); - break; - case COLOROPTION_SPEED: - // @TODO Include a transfer function here ---abock - color = vec4(vec3(ge_speed), 0.5); - break; - case COLOROPTION_OTHERDATA: - if (filterOutOfRange && !isOtherDataValueInRange()) { - discard; - } - else { - color = otherDataValue(); - } - break; - case COLOROPTION_FIXEDCOLOR: - color = vec4(fixedColor, 1.0); - break; - } - - vec4 textureColor = texture(psfTexture, 0.5 * psfCoords + 0.5); - vec4 fullColor = vec4(color.rgb, textureColor.a); - fullColor.a *= alphaValue; - - if (fullColor.a < 0.001) { + vec4 color = vec4(0.0); + switch (colorOption) { + case ColorOptionColor: + color = bv2rgb(ge_bv); + break; + case ColorOptionVelocity: + color = vec4(abs(ge_velocity), 0.5); + break; + case ColorOptionSpeed: + // @TODO Include a transfer function here ---abock + color = vec4(vec3(ge_speed), 0.5); + break; + case ColorOptionOtherData: + if (filterOutOfRange && !isOtherDataValueInRange()) { discard; - } + } + else { + color = otherDataValue(); + } + break; + case ColorOptionFixedColor: + color = vec4(fixedColor, 1.0); + break; + } - Fragment frag; - frag.color = fullColor; - frag.depth = gs_screenSpaceDepth; - frag.gPosition = vs_position; - frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); - frag.disableLDR2HDR = true; - - return frag; + vec4 textureColor = texture(psfTexture, texCoords); + vec4 fullColor = vec4(color.rgb, textureColor.a * alphaValue); + + if (fullColor.a < 0.001) { + discard; + } + + Fragment frag; + frag.color = fullColor; + frag.depth = gs_screenSpaceDepth; + frag.gPosition = vec4(vs_position, 1.0); + frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); + frag.disableLDR2HDR = true; + + return frag; } diff --git a/modules/space/shaders/star_ge.glsl b/modules/space/shaders/star_ge.glsl index 759927b7f1..36c8ad316b 100644 --- a/modules/space/shaders/star_ge.glsl +++ b/modules/space/shaders/star_ge.glsl @@ -24,7 +24,6 @@ #version __CONTEXT__ -#include "floatoperations.glsl" #include "PowerScaling/powerScalingMath.hglsl" layout(points) in; @@ -32,25 +31,20 @@ layout(triangle_strip, max_vertices = 4) out; in vec4 vs_bvLumAbsMagAppMag[]; in vec3 vs_velocity[]; -in vec4 vs_gPosition[]; in float vs_speed[]; -out vec4 vs_position; -out vec2 psfCoords; +out vec3 vs_position; +out vec2 texCoords; -flat out vec4 ge_bvLumAbsMagAppMag; +flat out float ge_bv; flat out vec3 ge_velocity; flat out float ge_speed; -flat out float ge_observationDistance; flat out float gs_screenSpaceDepth; uniform float magnitudeExponent; uniform dvec3 eyePosition; uniform dvec3 cameraUp; -// uniform float FWHM; -// uniform float betaConstant; - uniform int psfParamConf; uniform float lumCent; uniform float radiusCent; @@ -62,128 +56,169 @@ uniform dmat4 modelMatrix; const double PARSEC = 3.08567756E16; //const double PARSEC = 3.08567782E16; -const vec2 corners[4] = vec2[4]( - vec2(0.0, 0.0), - vec2(1.0, 0.0), - vec2(1.0, 1.0), - vec2(0.0, 1.0) -); +// FRAGILE +// All of these values have to be synchronized with the values in the optionproperty +const int SizeCompositionOptionAppBrightness = 0; +const int SizeCompositionOptionLumSize = 1; +const int SizeCompositionOptionLumSizeAppBrightness = 2; +const int SizeCompositionOptionLumSizeAbsMagnitude = 3; +const int SizeCompositionOptionLumSizeAppMagnitude = 4; +const int SizeCompositionOptionLumSizeDistanceModulus = 5; -const float SunTemperature = 5800.0f; -const float SunAbsMagnitude = 4.83f; +const float SunTemperature = 5800.0; +const float SunAbsMagnitude = 4.83; const float SunRadius = 6.957E8; // meters float bvToKelvin(float bv) { - float tmp = 0.92f * bv; - return 4600.f * (1.f/(tmp+1.7f) +1.f/(tmp+0.62f)); + float tmp = 0.92 * bv; + return 4600 * (1.0 / (tmp + 1.7) + 1.0 / (tmp + 0.62)); +} + +double scaleForApparentBrightness(dvec3 dpos, float luminance) { + // Working like Partiview + double pSize = pow(10, 29.0 + magnitudeExponent); + float luminosity = luminance * 10.0; + double distanceToStar = length(dpos - eyePosition); + return (pSize * luminosity) / distanceToStar; +} + +double scaleForLuminositySize(float bv, float luminance, float absMagnitude) { + double adjustedLuminance = luminance + 5E9; + float L_over_Lsun = pow(2.51, SunAbsMagnitude - absMagnitude); + float temperature = bvToKelvin(bv); + float relativeTemperature = SunTemperature / temperature; + double starRadius = SunRadius * pow(relativeTemperature, 2.0) * sqrt(L_over_Lsun); + return (lumCent * adjustedLuminance + (radiusCent * starRadius)) * pow(10.0, magnitudeExponent); +} + +double scaleForLuminositySizeAppBrightness(dvec3 dpos, float bv, float luminance, float absMagnitude) { + double luminosity = double(1.0 - luminance); + double distanceToStarInParsecs = trunc(length(dpos - eyePosition) / PARSEC); + double apparentBrightness = luminosity / distanceToStarInParsecs; + float L_over_Lsun = pow(2.51, SunAbsMagnitude - absMagnitude); + float temperature = bvToKelvin(bv); + float relativeTemperature = SunTemperature / temperature; + double starRadius = SunRadius * pow(relativeTemperature, 2.0) * sqrt(L_over_Lsun); + + double scaledLuminance = lumCent * (luminance + 5E9); + double scaledStarRadius = radiusCent * starRadius; + double scaledBrightness = brightnessCent * apparentBrightness * 5E15; + return (scaledLuminance + scaledStarRadius + scaledBrightness) * pow(10.0, magnitudeExponent); +} + +double scaleForAbsoluteMagnitude(float absMagnitude) { + return (-absMagnitude + 35) * pow(10.0, magnitudeExponent + 8.5); +} + +double scaleForApparentMagnitude(dvec3 dpos, float absMag) { + double distanceToStarInMeters = length(dpos - eyePosition); + double distanceToCenterInMeters = length(eyePosition); + float distanceToStarInParsecs = float(distanceToStarInMeters/PARSEC); + //float appMag = absMag + 5*log(distanceToStarInParsecs) - 5.0; + float appMag = absMag + 5.0 * (log(distanceToStarInParsecs/10.0)/log(2.0)); + //appMag = vs_bvLumAbsMagAppMag[0].w; + + //scaleMultiply = (30.623 - appMag) * pow(10.0, magnitudeExponent + 7.0);// * + //float(distanceToStarInMeters/distanceToCenterInMeters); + + return (-appMag + 50.0) * pow(10.0, magnitudeExponent + 7.5); + // return log(35.f + appMag) * pow(10.0, magnitudeExponent + 6.5f); + // return exp((35.f - appMag) * 0.2) * pow(10.0, magnitudeExponent + 2.5f); + // return appMag * pow(10.0, magnitudeExponent + 8.5f); + // return exp((-30.0 - appMag) * 0.45) * pow(10.0, magnitudeExponent + 8.f); + // return pow(10.0, (appMag - absMag)*(1.0/5.0) + 1.0) * pow(10.0, magnitudeExponent + 3.f); +} + +double scaleForDistanceModulus(float absMag) { + return exp((-30.623 - absMag) * 0.462) * pow(10.0, magnitudeExponent + 12.5) * 2000; } void main() { - vs_position = gl_in[0].gl_Position; // in object space - dvec4 dpos = modelMatrix * dvec4(vs_position); + vec3 pos = gl_in[0].gl_Position.xyz; + vs_position = pos; // in object space + dvec4 dpos = modelMatrix * dvec4(pos, 1.0); - ge_bvLumAbsMagAppMag = vs_bvLumAbsMagAppMag[0]; - ge_velocity = vs_velocity[0]; - ge_speed = vs_speed[0]; - - double scaleMultiply = 1.0; + ge_bv = vs_bvLumAbsMagAppMag[0].x; + ge_velocity = vs_velocity[0]; + ge_speed = vs_speed[0]; - if (psfParamConf == 0) { - // Working like Partiview - double luminosity = double(ge_bvLumAbsMagAppMag.y) * 10.0; - double pSize = pow(10, magnitudeExponent + 29.0); - double distanceToStar = length((dpos.xyz - eyePosition)); - double apparentBrightness = pSize * luminosity / (distanceToStar); - scaleMultiply = apparentBrightness; - } - else if (psfParamConf == 1) { - float L_over_Lsun = pow(2.51f, SunAbsMagnitude - ge_bvLumAbsMagAppMag.z); - float starTemperature = bvToKelvin(ge_bvLumAbsMagAppMag.x); - float starRadius = SunRadius * pow(SunTemperature/starTemperature, 2.f) * sqrt(L_over_Lsun); - scaleMultiply = ((lumCent * (ge_bvLumAbsMagAppMag.y + 5E9)) + - (radiusCent * double(starRadius))) * pow(10.0, magnitudeExponent); - } - else if (psfParamConf == 2) { - double luminosity = double(1.0 - ge_bvLumAbsMagAppMag.y); - double distanceToStarInParsecs = trunc(length(dpos.xyz - eyePosition) / PARSEC); - double apparentBrightness = luminosity / distanceToStarInParsecs; - float L_over_Lsun = pow(2.51f, SunAbsMagnitude - ge_bvLumAbsMagAppMag.z); - float starTemperature = bvToKelvin(ge_bvLumAbsMagAppMag.x); - float starRadius = SunRadius * pow(SunTemperature/starTemperature, 2.f) * - sqrt(L_over_Lsun); - scaleMultiply = ((lumCent * (ge_bvLumAbsMagAppMag.y + 5E9)) + - (radiusCent * double(starRadius)) + - (brightnessCent * apparentBrightness * 5E15)) * - pow(10.0, magnitudeExponent); - } - else if (psfParamConf == 3) { - float absMag = ge_bvLumAbsMagAppMag.z; - scaleMultiply = (-absMag + 35.f) * pow(10.0, magnitudeExponent + 8.5f); - } - else if (psfParamConf == 4) { - float absMag = vs_bvLumAbsMagAppMag[0].z; - double distanceToStarInMeters = length(dpos.xyz - eyePosition); - double distanceToCenterInMeters = length(eyePosition); - float distanceToStarInParsecs = float(distanceToStarInMeters/PARSEC); - //float appMag = absMag + 5*log(distanceToStarInParsecs) - 5.0; - float appMag = absMag + 5.0 * (log(distanceToStarInParsecs/10.0)/log(2.0)); - //appMag = vs_bvLumAbsMagAppMag[0].w; - - //scaleMultiply = (30.623 - appMag) * pow(10.0, magnitudeExponent + 7.0);// * - //float(distanceToStarInMeters/distanceToCenterInMeters); - - //scaleMultiply = (-appMag + 50.f) * pow(10.0, magnitudeExponent + 7.5f); - //scaleMultiply = log(35.f + appMag) * pow(10.0, magnitudeExponent + 6.5f); - //scaleMultiply = exp((35.f - appMag) * 0.2) * pow(10.0, magnitudeExponent + 2.5f); - //scaleMultiply = appMag * pow(10.0, magnitudeExponent + 8.5f); - scaleMultiply = exp((-30.0 - appMag) * 0.45) * pow(10.0, magnitudeExponent + 8.f); - //scaleMultiply = pow(10.0, (appMag - absMag)*(1.0/5.0) + 1.0) * pow(10.0, magnitudeExponent + 3.f); - } - else if (psfParamConf == 5) { - float absMag = ge_bvLumAbsMagAppMag.z; - scaleMultiply = exp((-30.623 - absMag) * 0.462) * pow(10.0, magnitudeExponent + 12.5f) * 2000; - } + double scaleMultiply = 1.0; - dvec3 scaledRight = dvec3(0.0); - dvec3 scaledUp = dvec3(0.0); - vec4 bottomLeftVertex, bottomRightVertex, topLeftVertex, topRightVertex; + if (psfParamConf == SizeCompositionOptionAppBrightness) { + float luminance = vs_bvLumAbsMagAppMag[0].y; + + scaleMultiply = scaleForApparentBrightness(dpos.xyz, luminance); + } + else if (psfParamConf == SizeCompositionOptionLumSize) { + float bv = vs_bvLumAbsMagAppMag[0].x; + float luminance = vs_bvLumAbsMagAppMag[0].y; + float absMagnitude = vs_bvLumAbsMagAppMag[0].z; + + scaleMultiply = scaleForLuminositySize(bv, luminance, absMagnitude); + } + else if (psfParamConf == SizeCompositionOptionLumSizeAppBrightness) { + float bv = vs_bvLumAbsMagAppMag[0].x; + float luminance = vs_bvLumAbsMagAppMag[0].y; + float absMagnitude = vs_bvLumAbsMagAppMag[0].z; + + scaleMultiply = scaleForLuminositySizeAppBrightness(dpos.xyz, bv, luminance, absMagnitude); + } + else if (psfParamConf == SizeCompositionOptionLumSizeAbsMagnitude) { + float absMagnitude = vs_bvLumAbsMagAppMag[0].z; + + scaleMultiply = scaleForAbsoluteMagnitude(absMagnitude); + } + else if (psfParamConf == SizeCompositionOptionLumSizeAppMagnitude) { + float absMagnitude = vs_bvLumAbsMagAppMag[0].z; + + scaleMultiply = scaleForApparentMagnitude(dpos.xyz, absMagnitude); + } + else if (psfParamConf == SizeCompositionOptionLumSizeDistanceModulus) { + float absMagnitude = vs_bvLumAbsMagAppMag[0].z; + + scaleMultiply = scaleForDistanceModulus(absMagnitude); + } + + dvec3 normal = eyePosition - dpos.xyz; + dvec3 newRight = normalize(cross(cameraUp, normal)); + dvec3 newUp = normalize(cross(normal, newRight)); + dvec3 scaledRight = scaleMultiply * newRight; + dvec3 scaledUp = scaleMultiply * newUp; - dvec3 normal = normalize(eyePosition - dpos.xyz); - dvec3 newRight = normalize(cross(cameraUp, normal)); - dvec3 newUp = cross(normal, newRight); - scaledRight = scaleMultiply * newRight; - scaledUp = scaleMultiply * newUp; - - bottomLeftVertex = z_normalization(vec4(cameraViewProjectionMatrix * - dvec4(dpos.xyz - scaledRight - scaledUp, dpos.w))); - gs_screenSpaceDepth = bottomLeftVertex.w; - - topRightVertex = z_normalization(vec4(cameraViewProjectionMatrix * - dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w))); + vec4 lowerLeft = z_normalization( + vec4(cameraViewProjectionMatrix * dvec4(dpos.xyz - scaledRight - scaledUp, dpos.w)) + ); + + vec4 upperRight = z_normalization( + vec4(cameraViewProjectionMatrix * dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w)) + ); - bottomRightVertex = z_normalization(vec4(cameraViewProjectionMatrix * - dvec4(dpos.xyz + scaledRight - scaledUp, dpos.w))); - - topLeftVertex = z_normalization(vec4(cameraViewProjectionMatrix * - dvec4(dpos.xyz + scaledUp - scaledRight, dpos.w))); - - // Build primitive - - gl_Position = bottomLeftVertex; - psfCoords = vec2(-1.0, -1.0); - EmitVertex(); - - gl_Position = bottomRightVertex; - psfCoords = vec2(1.0, -1.0); - EmitVertex(); + vec4 lowerRight = z_normalization( + vec4(cameraViewProjectionMatrix * dvec4(dpos.xyz + scaledRight - scaledUp, dpos.w)) + ); + + vec4 upperLeft = z_normalization( + vec4(cameraViewProjectionMatrix * dvec4(dpos.xyz + scaledUp - scaledRight, dpos.w)) + ); - gl_Position = topLeftVertex; - psfCoords = vec2(-1.0, 1.0); - EmitVertex(); - - gl_Position = topRightVertex; - psfCoords = vec2(1.0, 1.0); - EmitVertex(); - - EndPrimitive(); + gs_screenSpaceDepth = lowerLeft.w; + + // Build primitive + gl_Position = lowerLeft; + texCoords = vec2(0.0, 0.0); + EmitVertex(); + + gl_Position = lowerRight; + texCoords = vec2(1.0,0.0); + EmitVertex(); + + gl_Position = upperLeft; + texCoords = vec2(0.0, 1.0); + EmitVertex(); + + gl_Position = upperRight; + texCoords = vec2(1.0, 1.0); + EmitVertex(); + + EndPrimitive(); } diff --git a/modules/space/shaders/star_vs.glsl b/modules/space/shaders/star_vs.glsl index 754deb5ea5..d03a9be2ad 100644 --- a/modules/space/shaders/star_vs.glsl +++ b/modules/space/shaders/star_vs.glsl @@ -24,8 +24,6 @@ #version __CONTEXT__ -#include "PowerScaling/powerScaling_vs.hglsl" - in vec3 in_position; in vec4 in_bvLumAbsMagAppMag; in vec3 in_velocity; @@ -36,9 +34,9 @@ out vec3 vs_velocity; out float vs_speed; void main() { - vs_bvLumAbsMagAppMag = in_bvLumAbsMagAppMag; - vs_velocity = in_velocity; - vs_speed = in_speed; + vs_bvLumAbsMagAppMag = in_bvLumAbsMagAppMag; + vs_velocity = in_velocity; + vs_speed = in_speed; - gl_Position = vec4(in_position, 1.0); + gl_Position = vec4(in_position, 1.0); } diff --git a/modules/space/speckloader.cpp b/modules/space/speckloader.cpp new file mode 100644 index 0000000000..996ba3ab73 --- /dev/null +++ b/modules/space/speckloader.cpp @@ -0,0 +1,905 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2021 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + constexpr const int8_t DataCacheFileVersion = 10; + constexpr const int8_t LabelCacheFileVersion = 10; + constexpr const int8_t ColorCacheFileVersion = 10; + + constexpr bool startsWith(std::string_view lhs, std::string_view rhs) noexcept { + return (rhs.size() <= lhs.size()) && (lhs.substr(0, rhs.size()) == rhs); + } + + void strip(std::string& line) noexcept { + // 1. Remove all spaces from the beginning + // 2. Remove # + // 3. Remove all spaces from the new beginning + // 4. Remove all spaces from the end + + while (!line.empty() && line[0] == ' ') { + line = line.substr(1); + } + + if (!line.empty() && line[0] == '#') { + line = line.substr(1); + } + + while (!line.empty() && line[0] == ' ') { + line = line.substr(1); + } + + while (!line.empty() && line.back() == ' ') { + line = line.substr(0, line.size() - 1); + } + } + + template + void checkSize(U value, std::string_view message) { + if (value > std::numeric_limits::max()) { + throw ghoul::RuntimeError(fmt::format("Error saving file: {}", message)); + } + } + + template + using LoadCacheFunc = std::function(std::filesystem::path)>; + + template + using SaveCacheFunc = std::function; + + template + using LoadSpeckFunc = std::function; + + + + template + T internalLoadFileWithCache(std::filesystem::path speckPath, + openspace::speck::SkipAllZeroLines skipAllZeroLines, + LoadSpeckFunc loadSpeckFunction, + LoadCacheFunc loadCacheFunction, + SaveCacheFunc saveCacheFunction) + { + static_assert( + std::is_same_v || + std::is_same_v || + std::is_same_v + ); + + std::string cachePath = FileSys.cacheManager()->cachedFilename(speckPath); + + if (std::filesystem::exists(cachePath)) { + LINFOC( + "SpeckLoader", + fmt::format( + "Cached file '{}' used for file {}", cachePath, speckPath + ) + ); + + std::optional dataset = loadCacheFunction(cachePath); + if (dataset.has_value()) { + // We could load the cache file and we are now done with this + return *dataset; + } + else { + FileSys.cacheManager()->removeCacheFile(cachePath); + } + } + LINFOC("SpeckLoader", fmt::format("Loading file {}", speckPath)); + T dataset = loadSpeckFunction(speckPath, skipAllZeroLines); + + if (!dataset.entries.empty()) { + LINFOC("SpeckLoader", "Saving cache"); + saveCacheFunction(dataset, cachePath); + } + return dataset; + } +} // namespace + +namespace openspace::speck { + +namespace data { + +Dataset loadFile(std::filesystem::path path, SkipAllZeroLines skipAllZeroLines) { + ghoul_assert(std::filesystem::exists(path), "File must exist"); + + std::ifstream file(path); + if (!file.good()) { + throw ghoul::RuntimeError(fmt::format("Failed to open speck file {}", path)); + } + + Dataset res; + + int nDataValues = 0; + + std::string line; + // First phase: Loading the header information + while (std::getline(file, line)) { + // Ignore empty line or commented-out lines + if (line.empty() || line[0] == '#') { + continue; + } + + // Guard against wrong line endings (copying files from Windows to Mac) causes + // lines to have a final \r + if (line.back() == '\r') { + line = line.substr(0, line.length() - 1); + } + + strip(line); + + // If the first character is a digit, we have left the preamble and are in the + // data section of the file + if (std::isdigit(line[0]) || line[0] == '-') { + break; + } + + + if (startsWith(line, "datavar")) { + // each datavar line is following the form: + // datavar + // with being the index of the data variable + + std::stringstream str(line); + std::string dummy; + Dataset::Variable v; + str >> dummy >> v.index >> v.name; + + nDataValues += 1; + res.variables.push_back(v); + continue; + } + + if (startsWith(line, "texturevar")) { + // each texturevar line is following the form: + // texturevar + // where is the data value index where the texture index is stored + if (res.textureDataIndex != -1) { + throw ghoul::RuntimeError(fmt::format( + "Error loading speck file {}: Texturevar defined twice", path + )); + } + + std::stringstream str(line); + std::string dummy; + str >> dummy >> res.textureDataIndex; + + continue; + } + + if (startsWith(line, "polyorivar")) { + // each polyorivar line is following the form: + // texturevar + // where is the data value index where the orientation index storage + // starts. There are 6 values stored in total, xyz + uvw + + if (res.orientationDataIndex != -1) { + throw ghoul::RuntimeError(fmt::format( + "Error loading speck file {}: Orientation index defined twice", path + )); + } + + std::stringstream str(line); + std::string dummy; + str >> dummy >> res.orientationDataIndex; + + // Ok.. this is kind of weird. Speck unfortunately doesn't tell us in the + // specification how many values a datavar has. Usually this is 1 value per + // datavar, unless it is a polygon orientation thing. Now, the datavar name + // for these can be anything (have seen 'orientation' and 'ori' before, so we + // can't really check by name for these or we will miss some if they are + // mispelled or whatever. So we have to go the roundabout way of adding the + // 5 remaining values (the 6th nDataValue was already added in the + // corresponding 'datavar' section) here + nDataValues += 5; + + continue; + } + + if (startsWith(line, "texture")) { + // each texture line is following one of two forms: + // 1: texture -M 1 halo.sgi + // 2: texture 1 M1.sgi + // The parameter in #1 is currently being ignored + + std::stringstream str(line); + + std::string dummy; + str >> dummy; + + if (line.find('-') != std::string::npos) { + str >> dummy; + } + + Dataset::Texture texture; + str >> texture.index >> texture.file; + + for (const Dataset::Texture& t : res.textures) { + if (t.index == texture.index) { + throw ghoul::RuntimeError(fmt::format( + "Error loading speck file {}: Texture index '{}' defined twice", + path, texture.index + )); + } + } + + res.textures.push_back(texture); + continue; + } + } + + std::sort( + res.variables.begin(), res.variables.end(), + [](const Dataset::Variable& lhs, const Dataset::Variable& rhs) { + return lhs.index < rhs.index; + } + ); + + std::sort( + res.textures.begin(), res.textures.end(), + [](const Dataset::Texture& lhs, const Dataset::Texture& rhs) { + return lhs.index < rhs.index; + } + ); + + // For the first line, we already loaded it and rejected it above, so if we do another + // std::getline, we'd miss the first data value line + bool isFirst = true; + while (isFirst || std::getline(file, line)) { + isFirst = false; + + // Ignore empty line or commented-out lines + if (line.empty() || line[0] == '#') { + continue; + } + + // Guard against wrong line endings (copying files from Windows to Mac) causes + // lines to have a final \r + if (line.back() == '\r') { + line = line.substr(0, line.length() - 1); + } + + strip(line); + + if (line.empty()) { + continue; + } + + // If the first character is a digit, we have left the preamble and are in the + // data section of the file + if (!std::isdigit(line[0]) && line[0] != '-') { + throw ghoul::RuntimeError(fmt::format( + "Error loading speck file {}: Header information and datasegment " + "intermixed", path + )); + } + + bool allZero = true; + + std::stringstream str(line); + Dataset::Entry entry; + str >> entry.position.x >> entry.position.y >> entry.position.z; + allZero &= (entry.position == glm::vec3(0.0)); + + entry.data.resize(nDataValues); + for (int i = 0; i < nDataValues; i += 1) { + str >> entry.data[i]; + allZero &= (entry.data[i] == 0.0); + } + + if (skipAllZeroLines && allZero) { + continue; + } + + std::string rest; + std::getline(str, rest); + if (!rest.empty()) { + + strip(rest); + entry.comment = rest; + } + + res.entries.push_back(std::move(entry)); + } + +#ifdef _DEBUG + if (!res.entries.empty()) { + size_t nValues = res.entries[0].data.size(); + ghoul_assert(nDataValues == nValues, "nDataValues calculation went wrong"); + for (const Dataset::Entry& e : res.entries) { + ghoul_assert( + e.data.size() == nDataValues, + "Row had different number of data values" + ); + } + } +#endif + + return res; +} + +std::optional loadCachedFile(std::filesystem::path path) { + std::ifstream file(path, std::ios::binary); + if (!file.good()) { + return std::nullopt; + } + + Dataset result; + + int8_t fileVersion; + file.read(reinterpret_cast(&fileVersion), sizeof(int8_t)); + if (fileVersion != DataCacheFileVersion) { + // Incompatible version and we won't be able to read the file + return std::nullopt; + } + + // + // Read variables + uint16_t nVariables; + file.read(reinterpret_cast(&nVariables), sizeof(uint16_t)); + result.variables.resize(nVariables); + for (int i = 0; i < nVariables; i += 1) { + Dataset::Variable var; + + int16_t idx; + file.read(reinterpret_cast(&idx), sizeof(int16_t)); + var.index = idx; + + uint16_t len; + file.read(reinterpret_cast(&len), sizeof(uint16_t)); + var.name.resize(len); + file.read(var.name.data(), len); + + result.variables[i] = std::move(var); + } + + // + // Read textures + uint16_t nTextures; + file.read(reinterpret_cast(&nTextures), sizeof(uint16_t)); + result.textures.resize(nTextures); + for (int i = 0; i < nTextures; i += 1) { + Dataset::Texture tex; + + int16_t idx; + file.read(reinterpret_cast(&idx), sizeof(int16_t)); + tex.index = idx; + + uint16_t len; + file.read(reinterpret_cast(&len), sizeof(uint16_t)); + tex.file.resize(len); + file.read(tex.file.data(), len); + + result.textures[i] = std::move(tex); + } + + // + // Read indices + int16_t texDataIdx; + file.read(reinterpret_cast(&texDataIdx), sizeof(int16_t)); + result.textureDataIndex = texDataIdx; + + int16_t oriDataIdx; + file.read(reinterpret_cast(&oriDataIdx), sizeof(int16_t)); + result.orientationDataIndex = oriDataIdx; + + // + // Read entries + uint64_t nEntries; + file.read(reinterpret_cast(&nEntries), sizeof(uint64_t)); + result.entries.reserve(nEntries); + for (uint64_t i = 0; i < nEntries; i += 1) { + Dataset::Entry e; + file.read(reinterpret_cast(&e.position.x), sizeof(float)); + file.read(reinterpret_cast(&e.position.y), sizeof(float)); + file.read(reinterpret_cast(&e.position.z), sizeof(float)); + + uint16_t nValues; + file.read(reinterpret_cast(&nValues), sizeof(uint16_t)); + e.data.resize(nValues); + file.read(reinterpret_cast(e.data.data()), nValues * sizeof(float)); + + uint16_t len; + file.read(reinterpret_cast(&len), sizeof(uint16_t)); + if (len > 0) { + std::string comment; + comment.resize(len); + file.read(comment.data(), len); + e.comment = std::move(comment); + } + + result.entries.push_back(std::move(e)); + } + + return result; +} + +void saveCachedFile(const Dataset& dataset, std::filesystem::path path) { + std::ofstream file(path, std::ofstream::binary); + + file.write(reinterpret_cast(&DataCacheFileVersion), sizeof(int8_t)); + + // + // Store variables + checkSize(dataset.variables.size(), "Too many variables"); + uint16_t nVariables = static_cast(dataset.variables.size()); + file.write(reinterpret_cast(&nVariables), sizeof(uint16_t)); + for (const Dataset::Variable& var : dataset.variables) { + checkSize(var.index, "Variable index too large"); + int16_t idx = static_cast(var.index); + file.write(reinterpret_cast(&idx), sizeof(int16_t)); + + checkSize(var.name.size(), "Variable name too long"); + uint16_t len = static_cast(var.name.size()); + file.write(reinterpret_cast(&len), sizeof(uint16_t)); + file.write(var.name.data(), len); + } + + // + // Store textures + checkSize(dataset.textures.size(), "Too many textures"); + uint16_t nTextures = static_cast(dataset.textures.size()); + file.write(reinterpret_cast(&nTextures), sizeof(uint16_t)); + for (const Dataset::Texture& tex : dataset.textures) { + checkSize(tex.index, "Texture index too large"); + int16_t idx = static_cast(tex.index); + file.write(reinterpret_cast(&idx), sizeof(int16_t)); + + + checkSize(tex.file.size(), "Texture file too long"); + uint16_t len = static_cast(tex.file.size()); + file.write(reinterpret_cast(&len), sizeof(uint16_t)); + file.write(tex.file.data(), len); + } + + // + // Store indices + checkSize(dataset.textureDataIndex, "Texture index too large"); + int16_t texIdx = static_cast(dataset.textureDataIndex); + file.write(reinterpret_cast(&texIdx), sizeof(int16_t)); + + checkSize(dataset.orientationDataIndex, "Orientation index too large"); + int16_t orientationIdx = static_cast(dataset.orientationDataIndex); + file.write(reinterpret_cast(&orientationIdx), sizeof(int16_t)); + + // + // Store entries + checkSize(dataset.entries.size(), "Too many entries"); + uint64_t nEntries = static_cast(dataset.entries.size()); + file.write(reinterpret_cast(&nEntries), sizeof(uint64_t)); + for (const Dataset::Entry& e : dataset.entries) { + file.write(reinterpret_cast(&e.position.x), sizeof(float)); + file.write(reinterpret_cast(&e.position.y), sizeof(float)); + file.write(reinterpret_cast(&e.position.z), sizeof(float)); + + checkSize(e.data.size(), "Too many data variables"); + uint16_t nValues = static_cast(e.data.size()); + file.write(reinterpret_cast(&nValues), sizeof(uint16_t)); + file.write( + reinterpret_cast(e.data.data()), + e.data.size() * sizeof(float) + ); + + if (e.comment.has_value()) { + checkSize(e.comment->size(), "Comment too long"); + } + uint16_t commentLen = e.comment.has_value() ? + static_cast(e.comment->size()) : + 0; + file.write(reinterpret_cast(&commentLen), sizeof(uint16_t)); + if (e.comment.has_value()) { + file.write(e.comment->data(), e.comment->size()); + } + } +} + +Dataset loadFileWithCache(std::filesystem::path speckPath, + SkipAllZeroLines skipAllZeroLines) +{ + return internalLoadFileWithCache( + speckPath, + skipAllZeroLines, + &loadFile, + &loadCachedFile, + &saveCachedFile + ); +} + +} // namespace data + +namespace label { + +Labelset loadFile(std::filesystem::path path, SkipAllZeroLines) { + ghoul_assert(std::filesystem::exists(path), "File must exist"); + + std::ifstream file(path); + if (!file.good()) { + throw ghoul::RuntimeError(fmt::format("Failed to open speck file '{}'", path)); + } + + Labelset res; + + std::string line; + // First phase: Loading the header information + while (std::getline(file, line)) { + // Ignore empty line or commented-out lines + if (line.empty() || line[0] == '#') { + continue; + } + + // Guard against wrong line endings (copying files from Windows to Mac) causes + // lines to have a final \r + if (line.back() == '\r') { + line = line.substr(0, line.length() - 1); + } + + strip(line); + + // If the first character is a digit, we have left the preamble and are in the + // data section of the file + if (std::isdigit(line[0]) || line[0] == '-') { + break; + } + + if (startsWith(line, "textcolor")) { + // each textcolor line is following the form: + // textcolor + // with being the index of the color into some configuration file (not + // really sure how these configuration files work, but they don't seem to be + // included in the speck file) + if (res.textColorIndex != -1) { + throw ghoul::RuntimeError(fmt::format( + "Error loading label file '{}': Textcolor defined twice", path + )); + } + + + std::stringstream str(line); + std::string dummy; + str >> dummy >> res.textColorIndex; + continue; + } + } + + // For the first line, we already loaded it and rejected it above, so if we do another + // std::getline, we'd miss the first data value line + bool isFirst = true; + while (isFirst || std::getline(file, line)) { + isFirst = false; + + // Ignore empty line or commented-out lines + if (line.empty() || line[0] == '#') { + continue; + } + + // Guard against wrong line endings (copying files from Windows to Mac) causes + // lines to have a final \r + if (line.back() == '\r') { + line = line.substr(0, line.length() - 1); + } + + strip(line); + + if (line.empty()) { + continue; + } + + // If the first character is a digit, we have left the preamble and are in the + // data section of the file + if (!std::isdigit(line[0]) && line[0] != '-') { + throw ghoul::RuntimeError(fmt::format( + "Error loading label file '{}': Header information and datasegment " + "intermixed", path + )); + } + + // Each line looks like this: + // text