diff --git a/Jenkinsfile b/Jenkinsfile index bbb2cf43f6..730909116e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -73,6 +73,7 @@ linux_gcc_make: { deleteDir(); gitHelper.checkoutGit(url, branch); } + stage('linux-gcc-make/build') { def cmakeCompileOptions = moduleCMakeFlags(); cmakeCompileOptions += ' -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS:STRING="-DGLM_ENABLE_EXPERIMENTAL"'; @@ -81,11 +82,31 @@ linux_gcc_make: { compileHelper.build(compileHelper.Make(), compileHelper.Gcc(), cmakeCompileOptions, '', 'build-make'); compileHelper.recordCompileIssues(compileHelper.Gcc()); } - stage('linux-gcc-make/test') { - testHelper.runUnitTests('bin/codegentest'); - testHelper.runUnitTests('bin/SGCTTest'); - testHelper.runUnitTests('bin/GhoulTest'); - testHelper.runUnitTests('bin/OpenSpaceTest'); + + if (env.RUN_UNIT_TESTS == 'true') { + stage('linux-gcc-make/test-codegen') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/codegentest'); + } + } + + stage('linux-gcc-make/test-sgct') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/SGCTTest'); + } + } + + stage('linux-gcc-make/test-ghoul') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/GhoulTest'); + } + } + + stage('linux-gcc-make/test-openspace') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/OpenSpaceTest'); + } + } } cleanWs() } // node('linux') @@ -98,17 +119,38 @@ linux_gcc_ninja: { deleteDir(); gitHelper.checkoutGit(url, branch); } + stage('linux-gcc-ninja/build') { def cmakeCompileOptions = moduleCMakeFlags(); cmakeCompileOptions += '-DMAKE_BUILD_TYPE=Release'; // Not sure why the linking of OpenSpaceTest takes so long compileHelper.build(compileHelper.Ninja(), compileHelper.Gcc(), cmakeCompileOptions, '', 'build-ninja'); } - stage('linux-gcc-ninja/test') { - testHelper.runUnitTests('bin/codegentest'); - testHelper.runUnitTests('bin/SGCTTest'); - testHelper.runUnitTests('bin/GhoulTest'); - testHelper.runUnitTests('bin/OpenSpaceTest'); + + if (env.RUN_UNIT_TESTS == 'true') { + stage('linux-gcc-ninja/test-codegen') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/codegentest'); + } + } + + stage('linux-gcc-ninja/test-sgct') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/SGCTTest'); + } + } + + stage('linux-gcc-ninja/test-ghoul') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/GhoulTest'); + } + } + + stage('linux-gcc-ninja/test-openspace') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/OpenSpaceTest'); + } + } } cleanWs() } // node('linux') @@ -121,6 +163,7 @@ linux_clang_make: { deleteDir() gitHelper.checkoutGit(url, branch); } + stage('linux-clang-make/build') { def cmakeCompileOptions = moduleCMakeFlags() cmakeCompileOptions += ' -DMAKE_BUILD_TYPE=Release' @@ -128,11 +171,31 @@ linux_clang_make: { compileHelper.build(compileHelper.Make(), compileHelper.Clang(), cmakeCompileOptions, '', 'build-make'); compileHelper.recordCompileIssues(compileHelper.Clang()); } - stage('linux-clang-make/test') { - testHelper.runUnitTests('bin/codegentest'); - testHelper.runUnitTests('bin/SGCTTest'); - testHelper.runUnitTests('bin/GhoulTest'); - testHelper.runUnitTests('bin/OpenSpaceTest'); + + if (env.RUN_UNIT_TESTS == 'true') { + stage('linux-clang-make/test-codegen') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/codegentest'); + } + } + + stage('linux-clang-make/test-sgct') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/SGCTTest'); + } + } + + stage('linux-clang-make/test-ghoul') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/GhoulTest'); + } + } + + stage('linux-clang-make/test-openspace') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/OpenSpaceTest'); + } + } } cleanWs() } // node('linux') @@ -145,17 +208,38 @@ linux_clang_ninja: { deleteDir() gitHelper.checkoutGit(url, branch); } + stage('linux-clang-ninja/build') { def cmakeCompileOptions = moduleCMakeFlags() cmakeCompileOptions += '-DMAKE_BUILD_TYPE=Release' // Not sure why the linking of OpenSpaceTest takes so long compileHelper.build(compileHelper.Ninja(), compileHelper.Clang(), cmakeCompileOptions, '', 'build-ninja'); } - stage('linux-clang-ninja/test') { - testHelper.runUnitTests('bin/codegentest'); - testHelper.runUnitTests('bin/SGCTTest'); - testHelper.runUnitTests('bin/GhoulTest'); - testHelper.runUnitTests('bin/OpenSpaceTest'); + + if (env.RUN_UNIT_TESTS == 'true') { + stage('linux-clang-ninja/test-codegen') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/codegentest'); + } + } + + stage('linux-clang-ninja/test-sgct') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/SGCTTest'); + } + } + + stage('linux-clang-ninja/test-ghoul') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/GhoulTest'); + } + } + + stage('linux-clang-ninja/test-openspace') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/OpenSpaceTest'); + } + } } cleanWs() } // node('linux') @@ -168,16 +252,37 @@ windows_msvc: { deleteDir(); gitHelper.checkoutGit(url, branch); } + stage('windows-msvc/build') { compileHelper.build(compileHelper.VisualStudio(), compileHelper.VisualStudio(), moduleCMakeFlags(), '', 'build-msvc'); compileHelper.recordCompileIssues(compileHelper.VisualStudio()); } - stage('windows-msvc/test') { - testHelper.runUnitTests('bin\\Debug\\codegentest'); - testHelper.runUnitTests('bin\\Debug\\SGCTTest'); - testHelper.runUnitTests('bin\\Debug\\GhoulTest'); - testHelper.runUnitTests('bin\\Debug\\OpenSpaceTest'); - } + + if (env.RUN_UNIT_TESTS == 'true') { + stage('windows-msvc/test-codegen') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin\\Debug\\codegentest'); + } + } + + stage('windows-msvc/test-sgct') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin\\Debug\\SGCTTest'); + } + } + + stage('windows-msvc/test-ghoul') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin\\Debug\\GhoulTest'); + } + } + + stage('windows-msvc/test-openspace') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin\\Debug\\OpenSpaceTest'); + } + } + } cleanWs() } // node('windows') } @@ -209,13 +314,36 @@ macos_make: { deleteDir(); gitHelper.checkoutGit(url, branch); } + stage('macos-make/build') { compileHelper.build(compileHelper.Make(), compileHelper.Clang(), moduleCMakeFlags(), '', 'build-make'); } - stage('macos-make/test') { - testHelper.runUnitTests('bin/Debug/OpenSpaceTest') - testHelper.runUnitTests('bin/Debug/codegentest') - } + + if (env.RUN_UNIT_TESTS == 'true') { + stage('macos-make/test-codegen') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/Debug/codegentest');\ + } + } + + stage('macos-make/test-sgct') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/Debug\\SGCTTest'); + } + } + + stage('macos-make/test-ghoul') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/Debug\\GhoulTest'); + } + } + + stage('macos-make/test-openspace') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/Debug/OpenSpaceTest'); + } + } + } cleanWs() } // node('macos') } @@ -227,14 +355,37 @@ macos_xcode: { deleteDir(); gitHelper.checkoutGit(url, branch); } + stage('macos-xcode/build') { compileHelper.build(compileHelper.Xcode(), compileHelper.Xcode(), moduleCMakeFlags(), '', 'build-xcode'); } - stage('macos-xcode/test') { - testHelper.runUnitTests('bin/Debug/OpenSpaceTest') - testHelper.runUnitTests('bin/Debug/codegentest') - } - cleanWs() + + if (env.RUN_UNIT_TESTS == 'true') { + stage('macos-xcode/test-codegen') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/Debug/codegentest'); + } + } + + stage('macos-xcode/test-sgct') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/Debug\\SGCTTest'); + } + } + + stage('macos-xcode/test-ghoul') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/Debug\\GhoulTest'); + } + } + + stage('macos-xcode/test-openspace') { + timeout(time: 2, unit: 'MINUTES') { + testHelper.runUnitTests('bin/Debug/OpenSpaceTest'); + } + } + } + cleanWs() } // node('macos') } } diff --git a/apps/OpenSpace/ext/launcher/src/profile/assetsdialog.cpp b/apps/OpenSpace/ext/launcher/src/profile/assetsdialog.cpp index f38566e8c9..a44c0beadc 100644 --- a/apps/OpenSpace/ext/launcher/src/profile/assetsdialog.cpp +++ b/apps/OpenSpace/ext/launcher/src/profile/assetsdialog.cpp @@ -106,8 +106,8 @@ namespace { for (int r = 0; r < nRows; r++) { QModelIndex idx = model.index(r, 0, parent); std::string assetName = model.name(idx).toStdString(); - - if (path == assetName) { + // Need to check if it actually is an asset to prevent issue #2154 + if (model.isAsset(idx) && path == assetName) { foundFileMatch = true; model.setChecked(idx, true); break; diff --git a/apps/OpenSpace/ext/launcher/src/sgctedit/windowcontrol.cpp b/apps/OpenSpace/ext/launcher/src/sgctedit/windowcontrol.cpp index ba5358246e..3d7938cc19 100644 --- a/apps/OpenSpace/ext/launcher/src/sgctedit/windowcontrol.cpp +++ b/apps/OpenSpace/ext/launcher/src/sgctedit/windowcontrol.cpp @@ -63,6 +63,7 @@ namespace { constexpr float DefaultFovV = 50.534f; constexpr float DefaultHeightOffset = 0.f; constexpr int MaxWindowSizePixels = 10000; + constexpr double FovEpsilon = 0.00001; QList monitorNames(const std::vector& resolutions) { QList monitorNames; @@ -355,8 +356,8 @@ QWidget* WindowControl::createPlanarWidget() { layout->addWidget(fovH, 1, 0); _planar.fovH = new QDoubleSpinBox; - _planar.fovH->setMinimum(0.0); - _planar.fovH->setMaximum(180.0); + _planar.fovH->setMinimum(FovEpsilon); + _planar.fovH->setMaximum(180.0 - FovEpsilon); _planar.fovH->setValue(DefaultFovH); _planar.fovH->setEnabled(false); _planar.fovH->setToolTip(hfovTip); @@ -373,12 +374,12 @@ QWidget* WindowControl::createPlanarWidget() { layout->addWidget(fovV, 2, 0); _planar.fovV = new QDoubleSpinBox; - _planar.fovH->setMinimum(0.0); - _planar.fovH->setMaximum(90.0); - _planar.fovH->setValue(DefaultFovV); + _planar.fovV->setMinimum(FovEpsilon); + _planar.fovV->setMaximum(180.0 - FovEpsilon); + _planar.fovV->setValue(DefaultFovV); _planar.fovV->setEnabled(false); _planar.fovV->setToolTip(vfovTip); - _planar.fovH->setSizePolicy( + _planar.fovV->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ); @@ -685,11 +686,17 @@ sgct::config::Projections WindowControl::generateProjectionInformation() const { } case ProjectionIndices::Planar: { + double fovH = _planar.fovH->text().toFloat(); + fovH = std::clamp(fovH, FovEpsilon, 180.0 - FovEpsilon); + + double fovV = _planar.fovV->text().toFloat(); + fovV = std::clamp(fovV, FovEpsilon, 180.0 - FovEpsilon); + // The negative values for left & down are due to SGCT's convention PlanarProjection projection; - projection.fov.right = _planar.fovH->text().toFloat() / 2.0; + projection.fov.right = fovH / 2.0; projection.fov.left = -projection.fov.right; - projection.fov.up = _planar.fovV->text().toFloat() / 2.0; + projection.fov.up = fovV / 2.0; projection.fov.down = -projection.fov.up; return projection; } diff --git a/data/assets/scene/milkyway/constellations/constellation_art.asset b/data/assets/scene/milkyway/constellations/constellation_art.asset index d0d1b3080e..9e7b2e38e5 100644 --- a/data/assets/scene/milkyway/constellations/constellation_art.asset +++ b/data/assets/scene/milkyway/constellations/constellation_art.asset @@ -5,7 +5,7 @@ local images = asset.syncedResource({ Name = "Constellation Images", Type = "HttpSynchronization", Identifier = "constellation_images", - Version = 3 + Version = 4 }) --function that reads the file diff --git a/data/assets/scene/solarsystem/heliosphere/2012/reset_loop_action.asset b/data/assets/scene/solarsystem/heliosphere/2012/reset_loop_action.asset index f171536437..8c2e4e3637 100644 --- a/data/assets/scene/solarsystem/heliosphere/2012/reset_loop_action.asset +++ b/data/assets/scene/solarsystem/heliosphere/2012/reset_loop_action.asset @@ -14,5 +14,5 @@ asset.onInitialize(function () end) asset.onDeinitialize(function () - openspace.asction.removeAction(resetLoopAction) + openspace.action.removeAction(resetLoopAction) end) diff --git a/data/assets/scene/solarsystem/missions/jwst/deployment.mission b/data/assets/scene/solarsystem/missions/jwst/deployment.mission new file mode 100644 index 0000000000..6b51256d55 --- /dev/null +++ b/data/assets/scene/solarsystem/missions/jwst/deployment.mission @@ -0,0 +1,25 @@ +return +{ + Name = "JWST_Deployment", + Phases = { + { Name = "Solar_Array_Deploy", TimeRange = { Start = "2021-DEC-25 12:50:20", End = "2021-DEC-25 12:50:42" }, + { Name = "Communication_Antenna_Deploy", TimeRange = { Start = "2021-DEC-26 06:20:00", End = "2021-DEC-26 11:59:00" }, + { Name = "Front_Palette_Deploy", TimeRange = { Start = "2021-DEC-28 06:40:35", End = "2021-DEC-28 18:20:00" }, + { Name = "Rear_Palette_Deploy", TimeRange = { Start = "2021-DEC-28 21:11:00", End = "2021-DEC-29 00:20:00" }, + { Name = "Base_Rise_Deploy", TimeRange = { Start = "2021-DEC-29 00:42:00", End = "2021-DEC-30 05:55:00" }, + { Name = "Aft_Flap_Deploy", TimeRange = { Start = "2021-DEC-30 09:20:00", End = "2021-DEC-30 13:57:00" }, + { Name = "Front_Right_Membrane_Restraints_Release", TimeRange = { Start = "2021-DEC-30 14:29:00", End = "2021-DEC-30 15:15:39" }, + { Name = "Front_Left_Membrane_Restraints_Release", TimeRange = { Start = "2021-DEC-30 15:29:13", End = "2021-DEC-30 16:58:20" }, + { Name = "Rear_Membrane_Restraints_Release", TimeRange = { Start = "2021-DEC-30 17:17:00", End = "2021-DEC-30 20:50:56" }, + { Name = "Core_Cover_Release", TimeRange = { Start = "2021-DEC-30 21:35:49", End = "2021-DEC-30 22:20:00" }, + { Name = "Right_Mid_Boom_Extend", TimeRange = { Start = "2021-DEC-30 23:49:43", End = "2021-DEC-31 06:02:05" }, + { Name = "Left_Mid_Boom_Extend", TimeRange = { Start = "2021-DEC-31 06:02:05", End = "2021-DEC-31 10:26:00" }, + { Name = "Sun_Shield_Membrane_Stretching", TimeRange = { Start = "2021-DEC-31 10:29:14", End = "2021-DEC-31 10:40:00" }, + { Name = "Sun_Shield_Layers_Separate", TimeRange = { Start = "2022-JAN-01 00:56:49", End = "2022-JAN-01 03:16:02" }, + { Name = "Bottom_Panel_Deploy", TimeRange = { Start = "2022-JAN-01 04:05:00", End = "2022-JAN-01 05:10:00" }, + { Name = "Secondary_Mirror_Deploy", TimeRange = { Start = "2022-JAN-01 12:20:00", End = "2022-JAN-05 22:53:00" }, + { Name = "Aft_Radiator_Delopy", TimeRange = { Start = "2022-JAN-06 00:40:48", End = "2022-JAN-06 04:25:00" }, + { Name = "Right_Main_Mirror_Deploy", TimeRange = { Start = "2022-JAN-06 21:50:00", End = "2022-JAN-08 01:00:48" }, + { Name = "Left_Main_Mirror_Deploy", TimeRange = { Start = "2022-JAN-08 11:20:00", End = "2022-JAN-09 07:20:00" } + } +} diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/misc/hubble_trail.asset b/data/assets/scene/solarsystem/planets/earth/satellites/misc/hubble_trail.asset index 2181058681..97955c876e 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/misc/hubble_trail.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/misc/hubble_trail.asset @@ -1,7 +1,7 @@ local transforms = asset.require('scene/solarsystem/planets/earth/transforms') local satelliteHelper = asset.require('util/tle_helper') -local url = "https://celestrak.com/satcat/tle.php?CATNR=20580" +local url = "https://celestrak.com/NORAD/elements/gp.php?CATNR=20580" local identifier = "HST" local filename = "HST.txt" local nodes = {} 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 1f302d73e0..e2a84a2714 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset @@ -2,7 +2,7 @@ local satelliteHelper = asset.require("util/tle_helper") local transforms = asset.require("scene/solarsystem/planets/earth/transforms") local sun = asset.require("scene/solarsystem/sun/sun") -local url = "http://celestrak.com/satcat/tle.php?CATNR=25544" +local url = "http://celestrak.com/NORAD/elements/gp.php?CATNR=25544" local identifier = "ISS" local filename = "ISS.txt" local nodes = {} 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 7a994bcd50..4017b449c6 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/aqua.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/aqua.asset @@ -2,7 +2,7 @@ local satelliteHelper = asset.require("util/tle_helper") local transforms = asset.require("scene/solarsystem/planets/earth/transforms") local sunTransforms = asset.require("scene/solarsystem/sun/transforms") -local url = "http://celestrak.com/satcat/tle.php?CATNR=27424" +local url = "http://celestrak.com/NORAD/elements/gp.php?CATNR=27424" local identifier = "Aqua" local filename = "Aqua.txt" local nodes = {} @@ -49,8 +49,8 @@ asset.onInitialize(function () Observer = transforms.EarthInertial.Identifier, File = path, LineNumber = 1, + RenderBinMode = "PostDeferredTransparent" }, - RenderBinMode = "PostDeferredTransparent" Color = { 0.9, 0.6715, 0.0 }, Fade = 1.5, Period = period, 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 96c41cf1f6..db469f6491 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/snpp.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/snpp.asset @@ -2,7 +2,7 @@ local satelliteHelper = asset.require("util/tle_helper") local transforms = asset.require("scene/solarsystem/planets/earth/transforms") local sunTransforms = asset.require("scene/solarsystem/sun/transforms") -local url = "http://celestrak.com/satcat/tle.php?CATNR=37849" +local url = "http://celestrak.com/NORAD/elements/gp.php?CATNR=37849" local identifier = "SNPP" local filename = "SNPP.txt" local nodes = {} @@ -10,7 +10,6 @@ local tle = satelliteHelper.downloadTLEFile(asset, url, identifier, filename) asset.onInitialize(function () - local lineElement = satelliteHelper.makeSingleLineElement(tle, filename) local period = satelliteHelper.getPeriodFromElement(lineElement) local path = tle .. "/" .. filename 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 b2c20027fe..5defc3ab95 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/terra.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/terra.asset @@ -2,7 +2,7 @@ local satelliteHelper = asset.require("util/tle_helper") local transforms = asset.require("scene/solarsystem/planets/earth/transforms") local sunTransforms = asset.require("scene/solarsystem/sun/transforms") -local url = "http://celestrak.com/satcat/tle.php?CATNR=25994" +local url = "http://celestrak.com/NORAD/elements/gp.php?CATNR=25994" local identifier = "Terra" local filename = "Terra.txt" local nodes = {} @@ -10,7 +10,6 @@ local tle = satelliteHelper.downloadTLEFile(asset, url, identifier, filename) asset.onInitialize(function () - local lineElement = satelliteHelper.makeSingleLineElement(tle, filename) local period = satelliteHelper.getPeriodFromElement(lineElement) local path = tle .. "/" .. filename @@ -51,8 +50,8 @@ asset.onInitialize(function () Observer = transforms.EarthInertial.Identifier, File = path, LineNumber = 1, + RenderBinMode = "PostDeferredTransparent" }, - RenderBinMode = "PostDeferredTransparent" Color = { 0.9, 0.6715, 0.0 }, Fade = 1.5, Period = period, diff --git a/ext/ghoul b/ext/ghoul index 3cf276553a..51602b07ea 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 3cf276553a96b432fff6ccc97140c236240f590a +Subproject commit 51602b07ea10579a45b3d2984d88b826b2822468 diff --git a/include/openspace/engine/moduleengine.h b/include/openspace/engine/moduleengine.h index ac1592aca4..d297975f19 100644 --- a/include/openspace/engine/moduleengine.h +++ b/include/openspace/engine/moduleengine.h @@ -27,6 +27,7 @@ #include +#include #include #include #include @@ -123,7 +124,10 @@ public: static scripting::LuaLibrary luaLibrary(); private: - /// The list of all registered OpenSpaceModule%s + /// The list of all names of all registered OpenSpaceModules + properties::StringListProperty _allModules; + + /// The list of all registered OpenSpaceModules std::vector> _modules; }; diff --git a/include/openspace/events/event.h b/include/openspace/events/event.h index 4b02129311..083d65a9fb 100644 --- a/include/openspace/events/event.h +++ b/include/openspace/events/event.h @@ -35,6 +35,7 @@ namespace openspace { class Camera; class Layer; class Profile; + class Renderable; class SceneGraphNode; class ScreenSpaceRenderable; class Time; @@ -74,6 +75,8 @@ struct Event { LayerRemoved, SessionRecordingPlayback, PointSpacecraft, + RenderableEnabled, + RenderableDisabled, Custom }; constexpr explicit Event(Type type_) : type(type_) {} @@ -108,12 +111,17 @@ void logAllEvents(const Event* e); * This event is created whenever a new scene graph node is added to the system. By the * time this event is signalled, the scene graph node has already been created and added * to the scene. - * - * \param Node The identifier of the node that was added */ struct EventSceneGraphNodeAdded : public Event { static const Type Type = Event::Type::SceneGraphNodeAdded; + /** + * Creates an instance of an EventSceneGraphNodeAdded event. + * + * \param Node The identifier of the node that was added + * + * \pre node_ must not be nullptr + */ explicit EventSceneGraphNodeAdded(const SceneGraphNode* node_); const tstring node; }; @@ -121,12 +129,17 @@ struct EventSceneGraphNodeAdded : public Event { /** * This event is created whenever a scene graph node was removed. By the time this event * is signalled, the scene graph node has already been removed. - * - * \param Node The identifier of that node that was removed */ struct EventSceneGraphNodeRemoved : public Event { static const Type Type = Event::Type::SceneGraphNodeRemoved; + /** + * Creates an instance of an EventSceneGraphNodeRemoved event. + * + * \param Node The identifier of the node that was removed + * + * \pre node_ must not be nullptr + */ explicit EventSceneGraphNodeRemoved(const SceneGraphNode* node_); const tstring node; }; @@ -134,9 +147,6 @@ struct EventSceneGraphNodeRemoved : public Event { /** * This event is created whenever something in the parallel connection subsystem changes. * The new state is sent as an argument with this event. - * - * \param State The new state of the parallel connection system; is one of `Established`, - * `Lost`, `HostshipGained`, or `HostshipLost` */ struct EventParallelConnection : public Event { static const Type Type = Event::Type::ParallelConnection; @@ -147,6 +157,13 @@ struct EventParallelConnection : public Event { HostshipGained, HostshipLost }; + + /** + * Creates an instance of an EventParallelConnection event. + * + * \param State The new state of the parallel connection system; is one of + * `Established`, `Lost`, `HostshipGained`, or `HostshipLost` + */ explicit EventParallelConnection(State state_); State state; }; @@ -158,6 +175,9 @@ struct EventParallelConnection : public Event { struct EventProfileLoadingFinished : public Event { static const Type Type = Event::Type::ProfileLoadingFinished; + /** + * Creates an instance of an EventProfileLoadingFinished event. + */ EventProfileLoadingFinished(); }; @@ -165,9 +185,6 @@ struct EventProfileLoadingFinished : public Event { * This event is created whenever some information about the application shutdown sequence * changes. This can either be that the seqeuence started, was aborted, or is finished, * which means that OpenSpace is just about the shutdown. - * - * \param State The next state of the application shutdown sequence; is one of `Started`, - * `Aborted`, or `Finished` */ struct EventApplicationShutdown : public Event { static const Type Type = Event::Type::ApplicationShutdown; @@ -178,6 +195,12 @@ struct EventApplicationShutdown : public Event { Finished }; + /** + * Creates an instance of an EventApplicationShutdown event. + * + * \param State The next state of the application shutdown sequence; is one of + * `Started`, `Aborted`, or `Finished` + */ explicit EventApplicationShutdown(State state_); const State state; }; @@ -185,13 +208,17 @@ struct EventApplicationShutdown : public Event { /** * This event is created when a new screenspace renderable has been created. By the time * this event is craeted, the screenspace renderable is already registered and available. - * - * \param Renderable The identifier of the new screenspace renderable that was just added - * to the system */ struct EventScreenSpaceRenderableAdded : public Event { static const Type Type = Event::Type::ScreenSpaceRenderableAdded; + /** + * Creates an instance of an EventScreenSpaceRenderableAdded event. + * + * \param renderable_ The the new screenspace renderable that was added to the system + * + * \pre renderable_ must not be nullptr + */ explicit EventScreenSpaceRenderableAdded(const ScreenSpaceRenderable* renderable_); const tstring renderable; }; @@ -200,12 +227,15 @@ struct EventScreenSpaceRenderableAdded : public Event { * This event is created when a screenspace renderable has been removed from the system. * When this event is created, the screenspace renderable has already been removed and is * no longer available - * - * \param Renderable The identifier of the screenspace renderable that was removed */ struct EventScreenSpaceRenderableRemoved : public Event { static const Type Type = Event::Type::ScreenSpaceRenderableRemoved; + /** + * Creates an instance of an EventScreenSpaceRenderableRemoved event. + * + * \param renderable_ The the new screenspace renderable that was removed + */ explicit EventScreenSpaceRenderableRemoved(const ScreenSpaceRenderable* renderable_); const tstring renderable; }; @@ -227,11 +257,6 @@ interaction sphere radius are all taken from the current focus node. ^ ^ ^ ^ Exiting Receding Reaching Approaching ``` - * - * \param Node The name of the node the camera is transitioning relative to. Currently is - * always the same as the camera's focus node - * \param Transition The transition type that the camera just finished; is one of - * `Approaching`, `Reaching`, `Receding`, or `Exiting` */ struct EventCameraFocusTransition : public Event { static const Type Type = Event::Type::CameraFocusTransition; @@ -243,6 +268,18 @@ struct EventCameraFocusTransition : public Event { Exiting }; + /** + * Creates an instance of an EventCameraFocusTransition event. + * + * \param camera_ The camera object that caused the transition + * \param node_ The name of the node the camera is transitioning relative to. + * Currently is always the same as the camera's focus node + * \param transition_ The transition type that the camera just finished; is one of + * `Approaching`, `Reaching`, `Receding`, or `Exiting` + * + * \pre camera_ must not be nullptr + * \pre node_ must not be nullptr + */ EventCameraFocusTransition(const Camera* camera_, const SceneGraphNode* node_, Transition transition_); @@ -259,7 +296,14 @@ struct EventCameraFocusTransition : public Event { struct EventTimeOfInterestReached : public Event { static const Type Type = Event::Type::TimeOfInterestReached; + /** + * Creates an instance of an EventTimeOfInterestReached event. + * + * \param time_ The time of interest that has been reached + * \param camera_ Information about the camera for the specific transition + */ EventTimeOfInterestReached(const Time* time_, const Camera* camera_); + const Time* time = nullptr; const Camera* camera = nullptr; }; @@ -279,16 +323,21 @@ struct EventMissionEventReached : public Event { /** * This event is created when a planet is eclipsed by a moon or a different planet. This * event is currently unused. - * - * \param Eclipsee The identifier of the scene graph node that is eclipsed by another - * object - * \param Eclipser The identifier of the scene graph node that is eclipsing the other - * object */ struct EventPlanetEclipsed : public Event { static const Type Type = Event::Type::PlanetEclipsed; + /** + * Creates an instance of an EventPlanetEclipsed event. + * + * \param eclipsee_ The scene graph node that is eclipsed by another object + * \param eclipser_ The scene graph node that is eclipsing the other object + * + * \pre eclipsee_ must not be nullptr + * \pre eclipser_ must not be nullptr + */ EventPlanetEclipsed(const SceneGraphNode* eclipsee_, const SceneGraphNode* eclipser_); + const tstring eclipsee; const tstring eclipser; }; @@ -296,12 +345,17 @@ struct EventPlanetEclipsed : public Event { /** * This event is created when the interpolation of a property value is finished. If the * interpolation time of a property change is 0s, this event is not fired - * - * \param Property The URI of the property whose interpolation has finished */ struct EventInterpolationFinished : public Event { static const Type Type = Event::Type::InterpolationFinished; + /** + * Creates an instance of an EventInterpolationFinished event. + * + * \param Property The property whose interpolation has finished + * + * \pre property_ must not be nullptr + */ EventInterpolationFinished(const properties::Property* property_); const tstring property; }; @@ -310,30 +364,45 @@ struct EventInterpolationFinished : public Event { * This event is created when the camera changes focus nodes. Even if the camera position * is interpolated, the node change happens instantaneously and the event is fired at the * same time. - * - * \param OldNode The identifier of the scene graph node which was the old focus node - * \param NewNode The identifier of the scene graph node that is the new focus node */ struct EventFocusNodeChanged : public Event { static const Type Type = Event::Type::FocusNodeChanged; + /** + * Creates an instance of an EventFocusNodeChanged event. + * + * \param oldNode_ The scene graph node which was the old focus node + * \param newNode_ The scene graph node that is the new focus node + * + * \pre oldNode_ must not be nullptr + * \pre newNode_ must not be nullptr + */ EventFocusNodeChanged(const SceneGraphNode* oldNode_, const SceneGraphNode* newNode_); + const tstring oldNode; const tstring newNode; }; /** * This event is created when a layer is added to to a globe. - * - * \param Globe The identifier of the globe to which the layer is added - * \param Group The identifier of the layer group to which the layer is added - * \param Layer The identifier of the layer that was added */ struct EventLayerAdded : public Event { static const Type Type = Event::Type::LayerAdded; + /** + * Creates an instance of an EventLayerAdded event. + * + * \param node_ The identifier of the globe to which the layer is added + * \param layerGroup_ The identifier of the layer group to which the layer is added + * \param layer_ The identifier of the layer that was added + * + * \pre node_ must not be empty + * \pre layerGroup_ must not be empty + * \pre layer_ must not be empty + */ explicit EventLayerAdded(std::string_view node_, std::string_view layerGroup_, std::string_view layer_); + const tstring node; const tstring layerGroup; const tstring layer; @@ -341,16 +410,24 @@ struct EventLayerAdded : public Event { /** * This event is created when a layer is removed from a globe. - * - * \param Globe The identifier of the globe from which the layer is removed - * \param Group The identifier of the layer group from which the layer is removed - * \param Layer The identifier of the layer that was removed */ struct EventLayerRemoved : public Event { static const Type Type = Event::Type::LayerRemoved; + /** + * Creates an instance of an EventLayerRemoved event. + * + * \param node_ The identifier of the globe to which the layer is removed + * \param layerGroup_ The identifier of the layer group to which the layer is removed + * \param layer_ The identifier of the layer that was removed + * + * \pre node_ must not be empty + * \pre layerGroup_ must not be empty + * \pre layer_ must not be empty + */ explicit EventLayerRemoved(std::string_view node_, std::string_view layerGroup_, std::string_view layer_); + const tstring node; const tstring layerGroup; const tstring layer; @@ -359,9 +436,6 @@ struct EventLayerRemoved : public Event { /** * This event is created when something regarding a session recording playback changes. * The event contains information about the new state of the session recording subsystem. - * - * \param State The new state of the session recording; one of `Started`, `Paused`, - * `Resumed`, `Finished` */ struct EventSessionRecordingPlayback : public Event { static const Type Type = Event::Type::SessionRecordingPlayback; @@ -373,7 +447,14 @@ struct EventSessionRecordingPlayback : public Event { Finished }; + /** + * Creates an instance of an EventSessionRecordingPlayback event. + * + * \param state_ The new state of the session recording; one of `Started`, `Paused`, + * `Resumed`, `Finished` + */ EventSessionRecordingPlayback(State state_); + const State state; }; @@ -382,21 +463,63 @@ struct EventSessionRecordingPlayback : public Event { * coordinate in the sky is issued. The event contains information about the sky * coordinate to point the spacecraft towards, and an optional argument for the duration * it should do the pointing. - * - * \param Ra The Ra part of the sky coordinate in decimal degrees to point towards - * \param Dec The Dec part of the sky coordinate in decimal degrees to point towards - * \param Duration The duration of time in seconds that the spacecraft should redirect - * itself to the coordinate. Default is 3 seconds */ struct EventPointSpacecraft : public Event { static const Type Type = Event::Type::PointSpacecraft; + /** + * Creates an instance of an EventSessionRecordingPlayback event. + * + * \param ra_ The Ra part of the sky coordinate in decimal degrees to point towards + * \param dec_ The Dec part of the sky coordinate in decimal degrees to point towards + * \param duration_ The duration of time in seconds that the spacecraft should + * redirect itself to the coordinate. Default is 3 seconds + */ EventPointSpacecraft(double ra_, double dec_, double duration_ = 3.0); + const double ra; const double dec; const double duration; }; +/** + * This event is created whenever a renderable is enabled. By the time this event is + * signalled, the renderable has already been enabled. + */ +struct EventRenderableEnabled : public Event { + static const Type Type = Event::Type::RenderableEnabled; + + /** + * Creates an instance of an EventRenderableEnabled event. + * + * \param node_ The identifier of the node that contains the renderable + * + * \pre node_ must not be nullptr + */ + explicit EventRenderableEnabled(const SceneGraphNode* node_); + + const tstring node; +}; + +/** + * This event is created whenever a renderable is disabled. By the time this event is + * signalled, the renderable has already been disabled. + */ +struct EventRenderableDisabled : public Event { + static const Type Type = Event::Type::RenderableDisabled; + + /** + * Creates an instance of an EventRenderableDisabled event. + * + * \param node_ The identifier of that node that contains the renderable + * + * \pre node_ must not be nullptr + */ + explicit EventRenderableDisabled(const SceneGraphNode* node_); + + const tstring node; +}; + /** * A custom event type that can be used in a pinch when no explicit event type is * available. This should only be used in special circumstances and it should be @@ -405,6 +528,14 @@ struct EventPointSpacecraft : public Event { struct CustomEvent : public Event { static const Type Type = Event::Type::Custom; + /** + * Creates an instance of a CustomEvent event. + * + * \param subtype_ A textual description of the custom subtype that is emitted + * \param payload_ The payload in a string form + * + * \pre subtype_ must not be empty + */ CustomEvent(std::string_view subtype_, std::string_view payload_); const tstring subtype; diff --git a/modules/base/rendering/screenspacedashboard_lua.inl b/modules/base/rendering/screenspacedashboard_lua.inl index 104fc3eaf0..352d0c2d3b 100644 --- a/modules/base/rendering/screenspacedashboard_lua.inl +++ b/modules/base/rendering/screenspacedashboard_lua.inl @@ -24,7 +24,7 @@ namespace { -//Adds a new dashboard item to an existing SceenSpaceDashboard. +// Adds a new dashboard item to an existing SceenSpaceDashboard. [[codegen::luawrap]] void addDashboardItemToScreenSpace(std::string identifier, ghoul::Dictionary dashboard) { diff --git a/modules/imgui/src/guigibscomponent.cpp b/modules/imgui/src/guigibscomponent.cpp index 5dc107bc2a..f8dea1b050 100644 --- a/modules/imgui/src/guigibscomponent.cpp +++ b/modules/imgui/src/guigibscomponent.cpp @@ -104,6 +104,7 @@ void GuiGIBSComponent::render() { ImGui::InputText("Image Format", ImageFormatBuffer.data(), ImageFormatBuffer.size()); if (ImGui::Button("Add Layer")) { + // Extract values from the ImGui fields std::string layer = std::string(LayerBuffer.data()); std::string startDate = std::string(StartDateBuffer.data()); std::string endDate = std::string(EndDateBuffer.data()); @@ -112,17 +113,37 @@ void GuiGIBSComponent::render() { std::string imageRes = std::string(ImageResolutionBuffer.data()); std::string imageFormat = std::string(ImageFormatBuffer.data()); + // Construct the components of the Lua function std::string xmlFunc = fmt::format( - "openspace.globebrowsing.createTemporalGibsGdalXml(" - "'{}', '{}', '{}', '{}', '{}', '{}', '{}')", - layer, startDate, endDate, temporalRes, imageRes, imageFormat, temporalFormat + "openspace.globebrowsing.createTemporalGibsGdalXml('{}', '{}', '{}')", + layer, imageRes, imageFormat + ); + + if (startDate == "Present") { + startDate.clear(); + } + std::string layerScript = fmt::format( + "{{" + " Identifier = '{}'," + " Type = 'TemporalTileLayer'," + " Enabled = true," + " Mode = 'Prototyped'," + " Prototyped = {{" + " Time = {{" + " Start = '{}'," + " End = '{}'" + " }}," + " TemporalResolution = '{}'," + " TimeFormat = '{}'," + " Prototype = {}" + " }}" + "}}", + layer, startDate, endDate, temporalRes, temporalFormat, xmlFunc ); std::string script = fmt::format( - "openspace.globebrowsing.addLayer('Earth', 'ColorLayers', {{ " - "Identifier = '{}', Enabled = true, Type = 'TemporalTileLayer', " - "FilePath = {} }})", - layer, xmlFunc + "openspace.globebrowsing.addLayer('Earth', 'ColorLayers', {})", + layerScript ); global::scriptEngine->queueScript( script, diff --git a/modules/webbrowser/CMakeLists.txt b/modules/webbrowser/CMakeLists.txt index a07882f351..98c7d33ddc 100644 --- a/modules/webbrowser/CMakeLists.txt +++ b/modules/webbrowser/CMakeLists.txt @@ -157,8 +157,20 @@ set(WEBBROWSER_RESOURCES_SRCS ) # Place Helper in separate executable -# The naming style " Helper" is required by Chromium. -set(CEF_HELPER_TARGET "OpenSpace Helper" CACHE INTERNAL "CEF_HELPER_TARGET") +# The naming style " Helper" is required by Chromium. +set(CEF_HELPER_FILE_REQUIRES_RENAME FALSE) +if (UNIX AND (${CMAKE_GENERATOR} STREQUAL "Unix Makefiles")) + # Linux builds that use GNU Make cannot handle spaces in filenames. For this type + # of build, the build file will have an underscore instead of a space, and this + # will be renamed back to a space when the build is complete. + set(CEF_HELPER_FILE_REQUIRES_RENAME TRUE) +endif() +if (CEF_HELPER_FILE_REQUIRES_RENAME) + # Use '_' instead of ' ' in helper filename + set(CEF_HELPER_TARGET "OpenSpace_Helper" CACHE INTERNAL "CEF_HELPER_TARGET") +else() + set(CEF_HELPER_TARGET "OpenSpace Helper" CACHE INTERNAL "CEF_HELPER_TARGET") +endif() set(CEF_HELPER_TARGET_GPU "OpenSpace Helper (GPU)" CACHE INTERNAL "CEF_HELPER_TARGET_GPU") set(CEF_HELPER_TARGET_RENDERER "OpenSpace Helper (Renderer)" CACHE INTERNAL "CEF_HELPER_TARGET_RENDERER") @@ -269,12 +281,24 @@ list(APPEND deps "${CEF_RESOURCE_DIR}/${j}") endforeach() add_external_library_dependencies("${deps}") -# Linux needs to have copies of CEF files in Resources/ in its build-type dir to avoid -# the 'Couldn't mmap icu data file' runtime error if (UNIX) + # Linux needs to have copies of CEF files in Resources/ in its build-type dir to avoid + # the 'Couldn't mmap icu data file' runtime error file(COPY ${CEF_ROOT}/Resources/ DESTINATION ${CEF_ROOT}/${CMAKE_BUILD_TYPE}/ FILES_MATCHING PATTERN * ) + + if (CEF_HELPER_FILE_REQUIRES_RENAME) + # Rename to "OpenSpace Helper" after build & link in order to prevent GNU Make from + # having to deal with the space in the filename + ADD_CUSTOM_COMMAND( + TARGET ${CEF_HELPER_TARGET} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E rename + "$/${CEF_HELPER_TARGET}" + "$/OpenSpace Helper" + COMMENT "Renaming ${CEF_HELPER_TARGET} to 'OpenSpace Helper'" + ) + endif() endif () diff --git a/src/engine/moduleengine.cpp b/src/engine/moduleengine.cpp index 705a5a3758..51be3d0f54 100644 --- a/src/engine/moduleengine.cpp +++ b/src/engine/moduleengine.cpp @@ -37,11 +37,24 @@ namespace { constexpr const char* _loggerCat = "ModuleEngine"; + + constexpr openspace::properties::Property::PropertyInfo AllModulesInfo = { + "AllModules", + "All Modules", + "The list of all modules that were compiled for this version of OpenSpace in the " + "same order in which they were initialized." + }; } // namespace namespace openspace { -ModuleEngine::ModuleEngine() : properties::PropertyOwner({ "Modules" }) {} +ModuleEngine::ModuleEngine() + : properties::PropertyOwner({ "Modules" }) + , _allModules(AllModulesInfo) +{ + _allModules.setReadOnly(true); + addProperty(_allModules); +} void ModuleEngine::initialize( const std::map& moduleConfigurations) @@ -50,9 +63,13 @@ void ModuleEngine::initialize( std::vector modules = AllModules(); + std::vector moduleNames; + moduleNames.reserve(modules.size()); for (OpenSpaceModule* m : modules) { registerModule(std::unique_ptr(m)); + moduleNames.push_back(m->guiName()); } + _allModules = moduleNames; for (OpenSpaceModule* m : modules) { const std::string& identifier = m->identifier(); diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 43323feeab..5a28ff9c05 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -1241,6 +1241,7 @@ void OpenSpaceEngine::postSynchronizationPreDraw() { global::renderEngine->updateRenderer(); global::renderEngine->updateScreenSpaceRenderables(); global::renderEngine->updateShaderPrograms(); + global::luaConsole->update(); if (!master) { _scene->camera()->invalidateCache(); @@ -1281,15 +1282,6 @@ void OpenSpaceEngine::render(const glm::mat4& sceneMatrix, const glm::mat4& view TracyGpuZone("Render") LTRACE("OpenSpaceEngine::render(begin)"); - const bool isGuiWindow = - global::windowDelegate->hasGuiWindow() ? - global::windowDelegate->isGuiWindow() : - true; - - if (isGuiWindow) { - global::luaConsole->update(); - } - global::renderEngine->render(sceneMatrix, viewMatrix, projectionMatrix); for (const std::function& func : *global::callback::render) { diff --git a/src/events/event.cpp b/src/events/event.cpp index e02857e7e9..16c1d84432 100644 --- a/src/events/event.cpp +++ b/src/events/event.cpp @@ -184,6 +184,17 @@ void log(int i, const CustomEvent& e) { LINFO(fmt::format("[{}] CustomEvent: {} ({})", i, e.subtype, e.payload)); } +void log(int i, const EventRenderableEnabled& e) { + ghoul_assert(e.type == EventRenderableEnabled::Type, "Wrong type"); + LINFO(fmt::format("[{}] EventRenderableEnabled: {}", i, e.node)); +} + +void log(int i, const EventRenderableDisabled& e) { + ghoul_assert(e.type == EventRenderableDisabled::Type, "Wrong type"); + LINFO(fmt::format("[{}] EventRenderableDisabled: {}", i, e.node)); +} + + std::string_view toString(Event::Type type) { switch (type) { case Event::Type::SceneGraphNodeAdded: return "SceneGraphNodeAdded"; @@ -204,6 +215,8 @@ std::string_view toString(Event::Type type) { case Event::Type::LayerRemoved: return "LayerRemoved"; case Event::Type::SessionRecordingPlayback: return "SessionRecordingPlayback"; case Event::Type::PointSpacecraft: return "PointSpacecraft"; + case Event::Type::RenderableEnabled: return "RenderableEnabled"; + case Event::Type::RenderableDisabled: return "RenderableDisabled"; case Event::Type::Custom: return "Custom"; default: throw ghoul::MissingCaseException(); @@ -262,6 +275,12 @@ Event::Type fromString(std::string_view str) { else if (str == "PointSpacecraft") { return Event::Type::PointSpacecraft; } + else if (str == "RenderableEnabled") { + return Event::Type::RenderableEnabled; + } + else if (str == "RenderableDisabled") { + return Event::Type::RenderableDisabled; + } else if (str == "Custom") { return Event::Type::Custom; } @@ -428,6 +447,18 @@ ghoul::Dictionary toParameter(const Event& e) { d.setValue("Dec", static_cast(e).dec); d.setValue("Duration", static_cast(e).duration); break; + case Event::Type::RenderableEnabled: + d.setValue( + "Node", + std::string(static_cast(e).node) + ); + break; + case Event::Type::RenderableDisabled: + d.setValue( + "Node", + std::string(static_cast(e).node) + ); + break; case Event::Type::Custom: d.setValue( "Subtype", std::string(static_cast(e).subtype) @@ -497,6 +528,12 @@ void logAllEvents(const Event* e) { case Event::Type::PointSpacecraft: log(i, *static_cast(e)); break; + case Event::Type::RenderableEnabled: + log(i, *static_cast(e)); + break; + case Event::Type::RenderableDisabled: + log(i, *static_cast(e)); + break; case Event::Type::Custom: log(i, *static_cast(e)); break; @@ -616,6 +653,17 @@ EventPointSpacecraft::EventPointSpacecraft(double ra_, double dec_, double durat , duration(duration_) {} +EventRenderableEnabled::EventRenderableEnabled(const SceneGraphNode* node_) + : Event(Type) + , node(temporaryString(node_->identifier())) +{} + +EventRenderableDisabled::EventRenderableDisabled(const SceneGraphNode* node_) + : Event(Type) + , node(temporaryString(node_->identifier())) +{} + + CustomEvent::CustomEvent(std::string_view subtype_, std::string_view payload_) : Event(Type) , subtype(subtype_) diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 21a56ed1bb..ee3c373a2e 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -51,29 +51,6 @@ namespace { constexpr const char* _loggerCat = "FramebufferRenderer"; - // If this is true (detected automatically), the OpenGL debug information functions - // are available and will be used to mark object names and debug groups - bool HasGLDebugInfo = false; - - struct GLDebugGroup { - explicit GLDebugGroup(std::string_view name) { - if (HasGLDebugInfo) { - glPushDebugGroup( - GL_DEBUG_SOURCE_APPLICATION, - 0, - static_cast(name.length()), - name.data() - ); - } - } - - ~GLDebugGroup() { - if (HasGLDebugInfo) { - glPopDebugGroup(); - } - } - }; - constexpr const glm::vec4 PosBufferClearVal = { 1e32, 1e32, 1e32, 1.f }; constexpr const std::array HDRUniformNames = { @@ -115,10 +92,6 @@ void FramebufferRenderer::initialize() { LDEBUG("Initializing FramebufferRenderer"); - HasGLDebugInfo = glbinding::Binding::ObjectLabel.isResolved() && - glbinding::Binding::PushDebugGroup.isResolved() && - glbinding::Binding::PopDebugGroup.isResolved(); - const GLfloat vertexData[] = { // x y -1.f, -1.f, @@ -207,7 +180,7 @@ void FramebufferRenderer::initialize() { _gBuffers.depthTexture, 0 ); - if (HasGLDebugInfo) { + if (glbinding::Binding::ObjectLabel.isResolved()) { glObjectLabel(GL_FRAMEBUFFER, _gBuffers.framebuffer, -1, "G-Buffer Main"); } @@ -722,10 +695,6 @@ void FramebufferRenderer::updateResolution() { ZoneScoped TracyGpuZone("Renderer updateResolution") - HasGLDebugInfo = glbinding::Binding::ObjectLabel.isResolved() && - glbinding::Binding::PushDebugGroup.isResolved() && - glbinding::Binding::PopDebugGroup.isResolved(); - glBindTexture(GL_TEXTURE_2D, _gBuffers.colorTexture); glTexImage2D( GL_TEXTURE_2D, @@ -742,7 +711,7 @@ void FramebufferRenderer::updateResolution() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - if (HasGLDebugInfo) { + if (glbinding::Binding::ObjectLabel.isResolved()) { glObjectLabel(GL_TEXTURE, _gBuffers.colorTexture, -1, "G-Buffer Color"); } @@ -762,7 +731,7 @@ void FramebufferRenderer::updateResolution() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - if (HasGLDebugInfo) { + if (glbinding::Binding::ObjectLabel.isResolved()) { glObjectLabel(GL_TEXTURE, _gBuffers.positionTexture, -1, "G-Buffer Position"); } @@ -782,7 +751,7 @@ void FramebufferRenderer::updateResolution() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - if (HasGLDebugInfo) { + if (glbinding::Binding::ObjectLabel.isResolved()) { glObjectLabel(GL_TEXTURE, _gBuffers.normalTexture, -1, "G-Buffer Normal"); } @@ -802,7 +771,7 @@ void FramebufferRenderer::updateResolution() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - if (HasGLDebugInfo) { + if (glbinding::Binding::ObjectLabel.isResolved()) { glObjectLabel(GL_TEXTURE, _gBuffers.depthTexture, -1, "G-Buffer Depth"); } @@ -1172,21 +1141,21 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac { TracyGpuZone("Background") - GLDebugGroup group("Background"); + ghoul::GLDebugGroup group("Background"); data.renderBinMask = static_cast(Renderable::RenderBin::Background); scene->render(data, tasks); } { TracyGpuZone("Opaque") - GLDebugGroup group("Opaque"); + ghoul::GLDebugGroup group("Opaque"); data.renderBinMask = static_cast(Renderable::RenderBin::Opaque); scene->render(data, tasks); } { TracyGpuZone("PreDeferredTransparent") - GLDebugGroup group("PreDeferredTransparent"); + ghoul::GLDebugGroup group("PreDeferredTransparent"); data.renderBinMask = static_cast( Renderable::RenderBin::PreDeferredTransparent ); @@ -1196,13 +1165,13 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac // Run Volume Tasks { TracyGpuZone("Raycaster Tasks") - GLDebugGroup group("Raycaster Tasks"); + ghoul::GLDebugGroup group("Raycaster Tasks"); performRaycasterTasks(tasks.raycasterTasks, viewport); } if (!tasks.deferredcasterTasks.empty()) { TracyGpuZone("Deferred Caster Tasks") - GLDebugGroup group("Deferred Caster Tasks"); + ghoul::GLDebugGroup group("Deferred Caster Tasks"); // We use ping pong rendering in order to be able to render multiple deferred // tasks at same time (e.g. more than 1 ATM being seen at once) to the same final @@ -1218,7 +1187,7 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac { TracyGpuZone("PostDeferredTransparent") - GLDebugGroup group("PostDeferredTransparent"); + ghoul::GLDebugGroup group("PostDeferredTransparent"); data.renderBinMask = static_cast( Renderable::RenderBin::PostDeferredTransparent ); @@ -1227,7 +1196,7 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac { TracyGpuZone("Overlay") - GLDebugGroup group("Overlay"); + ghoul::GLDebugGroup group("Overlay"); data.renderBinMask = static_cast(Renderable::RenderBin::Overlay); scene->render(data, tasks); } @@ -1252,14 +1221,14 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac { // Apply the selected TMO on the results and resolve the result to the default FBO TracyGpuZone("Apply TMO") - GLDebugGroup group("Apply TMO"); + ghoul::GLDebugGroup group("Apply TMO"); applyTMO(blackoutFactor, viewport); } if (_enableFXAA) { TracyGpuZone("Apply FXAA") - GLDebugGroup group("Apply FXAA"); + ghoul::GLDebugGroup group("Apply FXAA"); glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); applyFXAA(viewport); } diff --git a/src/rendering/luaconsole.cpp b/src/rendering/luaconsole.cpp index be52c2fc1b..e01c6ca254 100644 --- a/src/rendering/luaconsole.cpp +++ b/src/rendering/luaconsole.cpp @@ -634,6 +634,8 @@ void LuaConsole::render() { using namespace ghoul::fontrendering; + ghoul::GLDebugGroup group("LuaConsole"); + // Don't render the console if it's collapsed. if (_currentHeight < 1.f) { return; diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp index 6b8af1b1ec..72577c5a74 100644 --- a/src/rendering/renderable.cpp +++ b/src/rendering/renderable.cpp @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include #include @@ -168,6 +170,14 @@ Renderable::Renderable(const ghoul::Dictionary& dictionary) _enabled = p.enabled.value_or(_enabled); addProperty(_enabled); + _enabled.onChange([this]() { + if (isEnabled()) { + global::eventEngine->publishEvent(_parent); + } + else { + global::eventEngine->publishEvent(_parent); + } + }); _opacity = p.opacity.value_or(_opacity); // We don't add the property here as subclasses should decide on their own whether