mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-05 19:19:39 -06:00
Merge remote-tracking branch 'origin/master' into issue/2645
This commit is contained in:
@@ -189,17 +189,6 @@ if (APPLE)
|
||||
)
|
||||
endif ()
|
||||
|
||||
if (MSVC)
|
||||
option(OPENSPACE_NVTOOLS_ENABLED "Include support for Nvidia Tools Extensions" OFF)
|
||||
set(OPENSPACE_NVTOOLS_PATH "C:/Program Files/NVIDIA Corporation/NvToolsExt")
|
||||
if (OPENSPACE_NVTOOLS_ENABLED)
|
||||
begin_dependency("Nvidia Tools Extension")
|
||||
target_compile_definitions(openspace-core PUBLIC "OPENSPACE_HAS_NVTOOLS")
|
||||
target_include_directories(openspace-core PUBLIC "${OPENSPACE_NVTOOLS_PATH}/include")
|
||||
end_dependency()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
begin_header("Configuring Modules")
|
||||
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/modules")
|
||||
end_header("End: Configuring Modules")
|
||||
|
||||
@@ -110,22 +110,8 @@ namespace {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::ifstream inFile;
|
||||
try {
|
||||
inFile.open(filename, std::ifstream::in);
|
||||
}
|
||||
catch (const std::ifstream::failure& e) {
|
||||
throw ghoul::RuntimeError(fmt::format(
|
||||
"Exception opening {} profile for read: {}", filename, e.what()
|
||||
));
|
||||
}
|
||||
std::string content;
|
||||
std::string line;
|
||||
while (std::getline(inFile, line)) {
|
||||
content += line;
|
||||
}
|
||||
try {
|
||||
return Profile(content);
|
||||
return Profile(filename);
|
||||
}
|
||||
catch (const Profile::ParsingError& e) {
|
||||
QMessageBox::critical(
|
||||
@@ -401,8 +387,16 @@ QWidget* LauncherWindow::createCentralWidget() {
|
||||
connect(
|
||||
&dialog,
|
||||
&SettingsDialog::saveSettings,
|
||||
[](Settings s) {
|
||||
[this](Settings s) {
|
||||
saveSettings(s, findSettings());
|
||||
|
||||
if (s.profile.has_value()) {
|
||||
populateProfilesList(*s.profile);
|
||||
}
|
||||
|
||||
if (s.configuration.has_value()) {
|
||||
populateWindowConfigsList(*s.configuration);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -25,15 +25,18 @@
|
||||
#include "profile/cameradialog.h"
|
||||
|
||||
#include "profile/line.h"
|
||||
#include <openspace/navigation/navigationstate.h>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDoubleValidator>
|
||||
#include <QFileDialog>
|
||||
#include <QFrame>
|
||||
#include <QGridLayout>
|
||||
#include <QKeyEvent>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QTabWidget>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QPushButton>
|
||||
#include <QTabWidget>
|
||||
|
||||
namespace {
|
||||
constexpr int CameraTypeNode = 0;
|
||||
@@ -345,6 +348,45 @@ QWidget* CameraDialog::createNavStateWidget() {
|
||||
mainLayout->addWidget(box);
|
||||
}
|
||||
|
||||
QPushButton* loadFile = new QPushButton("Load state from file");
|
||||
loadFile->setIcon(loadFile->style()->standardIcon(QStyle::SP_FileIcon));
|
||||
connect(
|
||||
loadFile, &QPushButton::clicked,
|
||||
[this]() {
|
||||
QString file = QFileDialog::getOpenFileName(
|
||||
this,
|
||||
"Select navigate state file"
|
||||
);
|
||||
|
||||
std::ifstream f(file.toStdString());
|
||||
std::string contents = std::string(
|
||||
(std::istreambuf_iterator<char>(f)),
|
||||
std::istreambuf_iterator<char>()
|
||||
);
|
||||
nlohmann::json json = nlohmann::json::parse(contents);
|
||||
|
||||
using namespace openspace::interaction;
|
||||
NavigationState state = NavigationState(json);
|
||||
|
||||
_navState.anchor->setText(QString::fromStdString(state.anchor));
|
||||
_navState.aim->setText(QString::fromStdString(state.aim));
|
||||
_navState.refFrame->setText(QString::fromStdString(state.referenceFrame));
|
||||
_navState.positionX->setText(QString::number(state.position.x));
|
||||
_navState.positionY->setText(QString::number(state.position.y));
|
||||
_navState.positionZ->setText(QString::number(state.position.z));
|
||||
|
||||
if (state.up.has_value()) {
|
||||
_navState.upX->setText(QString::number(state.up->x));
|
||||
_navState.upY->setText(QString::number(state.up->y));
|
||||
_navState.upZ->setText(QString::number(state.up->z));
|
||||
}
|
||||
|
||||
_navState.yaw->setText(QString::number(state.yaw));
|
||||
_navState.pitch->setText(QString::number(state.pitch));
|
||||
}
|
||||
);
|
||||
mainLayout->addWidget(loadFile);
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,10 +71,6 @@
|
||||
#include <modules/spout/spoutwrapper.h>
|
||||
#endif // OPENSPACE_HAS_SPOUT
|
||||
|
||||
#ifdef OPENSPACE_HAS_NVTOOLS
|
||||
#include "nvToolsExt.h"
|
||||
#endif // OPENSPACE_HAS_NVTOOLS
|
||||
|
||||
#ifdef OPENSPACE_BREAK_ON_FLOATING_POINT_EXCEPTION
|
||||
#include <float.h>
|
||||
#endif // OPENSPACE_BREAK_ON_FLOATING_POINT_EXCEPTION
|
||||
@@ -96,7 +92,6 @@ constexpr std::string_view OpenVRTag = "OpenVR";
|
||||
const Window* currentWindow = nullptr;
|
||||
const BaseViewport* currentViewport = nullptr;
|
||||
Frustum::Mode currentFrustumMode;
|
||||
glm::mat4 currentModelViewProjectionMatrix;
|
||||
glm::mat4 currentModelMatrix;
|
||||
glm::ivec2 currentDrawResolution;
|
||||
|
||||
@@ -130,7 +125,6 @@ std::vector<SpoutWindow> SpoutWindows;
|
||||
|
||||
#endif // OPENSPACE_HAS_SPOUT
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// MiniDump generation
|
||||
@@ -417,9 +411,6 @@ void mainPreSyncFunc() {
|
||||
void mainPostSyncPreDrawFunc() {
|
||||
ZoneScoped;
|
||||
|
||||
#ifdef OPENSPACE_HAS_NVTOOLS
|
||||
nvtxRangePush("postSyncPreDraw");
|
||||
#endif // OPENSPACE_HAS_NVTOOLS
|
||||
LTRACE("main::postSynchronizationPreDraw(begin)");
|
||||
|
||||
global::openSpaceEngine->postSynchronizationPreDraw();
|
||||
@@ -432,10 +423,6 @@ void mainPostSyncPreDrawFunc() {
|
||||
#endif // OPENVR_SUPPORT
|
||||
|
||||
LTRACE("main::postSynchronizationPreDraw(end)");
|
||||
|
||||
#ifdef OPENSPACE_HAS_NVTOOLS
|
||||
nvtxRangePop();
|
||||
#endif // OPENSPACE_HAS_NVTOOLS
|
||||
}
|
||||
|
||||
|
||||
@@ -443,9 +430,6 @@ void mainPostSyncPreDrawFunc() {
|
||||
void mainRenderFunc(const sgct::RenderData& data) {
|
||||
ZoneScoped;
|
||||
|
||||
#ifdef OPENSPACE_HAS_NVTOOLS
|
||||
nvtxRangePush("render");
|
||||
#endif // OPENSPACE_HAS_NVTOOLS
|
||||
LTRACE("main::mainRenderFunc(begin)");
|
||||
|
||||
currentWindow = &data.window;
|
||||
@@ -491,7 +475,6 @@ void mainRenderFunc(const sgct::RenderData& data) {
|
||||
sizeof(mat4)
|
||||
);
|
||||
currentModelMatrix = modelMatrix;
|
||||
currentModelViewProjectionMatrix = modelMatrix * viewMatrix * projectionMatrix;
|
||||
global::openSpaceEngine->render(modelMatrix, viewMatrix, projectionMatrix);
|
||||
|
||||
#ifdef OPENSPACE_HAS_SPOUT
|
||||
@@ -522,9 +505,6 @@ void mainRenderFunc(const sgct::RenderData& data) {
|
||||
}
|
||||
|
||||
LTRACE("main::mainRenderFunc(end)");
|
||||
#ifdef OPENSPACE_HAS_NVTOOLS
|
||||
nvtxRangePop();
|
||||
#endif // OPENSPACE_HAS_NVTOOLS
|
||||
}
|
||||
|
||||
|
||||
@@ -641,6 +621,8 @@ void mainCharCallback(unsigned int codepoint, int modifiers, sgct::Window* windo
|
||||
|
||||
|
||||
void mainDropCallback(int amount, const char** paths) {
|
||||
ZoneScoped;
|
||||
|
||||
ghoul_assert(amount > 0, "Expected at least one file path");
|
||||
ghoul_assert(paths, "expected non-nullptr");
|
||||
|
||||
@@ -651,25 +633,25 @@ void mainDropCallback(int amount, const char** paths) {
|
||||
|
||||
|
||||
|
||||
std::vector<std::byte> mainEncodeFun() {
|
||||
std::vector<std::byte> mainEncode() {
|
||||
ZoneScoped;
|
||||
LTRACE("main::mainEncodeFun(begin)");
|
||||
LTRACE("main::mainEncode(begin)");
|
||||
|
||||
std::vector<std::byte> data = global::openSpaceEngine->encode();
|
||||
|
||||
LTRACE("main::mainEncodeFun(end)");
|
||||
LTRACE("main::mainEncode(end)");
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void mainDecodeFun(const std::vector<std::byte>& data) {
|
||||
void mainDecode(const std::vector<std::byte>& data) {
|
||||
ZoneScoped;
|
||||
LTRACE("main::mainDecodeFun(begin)");
|
||||
LTRACE("main::mainDecode(begin)");
|
||||
|
||||
global::openSpaceEngine->decode(data);
|
||||
|
||||
LTRACE("main::mainDecodeFun(end)");
|
||||
LTRACE("main::mainDecode(end)");
|
||||
}
|
||||
|
||||
|
||||
@@ -690,10 +672,9 @@ void mainLogCallback(Log::Level level, std::string_view message) {
|
||||
case Log::Level::Error:
|
||||
LERRORC("SGCT", message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
void setSgctDelegateFunctions() {
|
||||
WindowDelegate& sgctDelegate = *global::windowDelegate;
|
||||
@@ -1113,6 +1094,9 @@ std::string selectedSgctProfileFromLauncher(LauncherWindow& lw, bool hasCliSGCTC
|
||||
return config;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
#ifdef OPENSPACE_BREAK_ON_FLOATING_POINT_EXCEPTION
|
||||
_clearfp();
|
||||
@@ -1379,6 +1363,44 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
glfwInit();
|
||||
|
||||
// We are just reloading the configuration file here in case the user has changed
|
||||
// anything in the settings panel. In that case want to apply these settings
|
||||
// immediately rather than waiting for the next startup.
|
||||
// What follows is some copy-paste code that should be cleaned up at some point
|
||||
|
||||
LDEBUG("Reloading configuration from disk");
|
||||
// Find configuration
|
||||
std::filesystem::path configurationFilePath;
|
||||
if (commandlineArguments.configuration.has_value()) {
|
||||
configurationFilePath = absPath(*commandlineArguments.configuration);
|
||||
}
|
||||
else {
|
||||
LDEBUG("Finding configuration");
|
||||
configurationFilePath = findConfiguration();
|
||||
}
|
||||
|
||||
// The previous incarnation of this was initializing GLFW to get the primary
|
||||
// monitor's resolution, but that had some massive performance implications as
|
||||
// there was some issue with the swap buffer handling inside of GLFW. My
|
||||
// assumption is that GLFW doesn't like being initialized, destroyed, and then
|
||||
// initialized again. Therefore we are using the platform specific functions now
|
||||
glm::ivec2 size = glm::ivec2(1920, 1080);
|
||||
#ifdef WIN32
|
||||
DEVMODEW dm = { 0 };
|
||||
dm.dmSize = sizeof(DEVMODEW);
|
||||
BOOL success = EnumDisplaySettingsW(nullptr, ENUM_CURRENT_SETTINGS, &dm);
|
||||
if (success) {
|
||||
size.x = dm.dmPelsWidth;
|
||||
size.y = dm.dmPelsHeight;
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
*global::configuration = loadConfigurationFromFile(
|
||||
configurationFilePath.string(),
|
||||
findSettings(),
|
||||
size
|
||||
);
|
||||
|
||||
global::configuration->profile = win.selectedProfile();
|
||||
windowConfiguration = selectedSgctProfileFromLauncher(
|
||||
win,
|
||||
@@ -1421,21 +1443,22 @@ int main(int argc, char* argv[]) {
|
||||
config::Cluster cluster = loadCluster(absPath(windowConfiguration).string());
|
||||
|
||||
LDEBUG("Setting callbacks");
|
||||
Engine::Callbacks callbacks;
|
||||
callbacks.initOpenGL = mainInitFunc;
|
||||
callbacks.preSync = mainPreSyncFunc;
|
||||
callbacks.postSyncPreDraw = mainPostSyncPreDrawFunc;
|
||||
callbacks.draw = mainRenderFunc;
|
||||
callbacks.draw2D = mainDraw2DFunc;
|
||||
callbacks.postDraw = mainPostDrawFunc;
|
||||
callbacks.keyboard = mainKeyboardCallback;
|
||||
callbacks.mouseButton = mainMouseButtonCallback;
|
||||
callbacks.mousePos = mainMousePosCallback;
|
||||
callbacks.mouseScroll = mainMouseScrollCallback;
|
||||
callbacks.character = mainCharCallback;
|
||||
callbacks.drop = mainDropCallback;
|
||||
callbacks.encode = mainEncodeFun;
|
||||
callbacks.decode = mainDecodeFun;
|
||||
Engine::Callbacks callbacks = {
|
||||
.initOpenGL = mainInitFunc,
|
||||
.preSync = mainPreSyncFunc,
|
||||
.postSyncPreDraw = mainPostSyncPreDrawFunc,
|
||||
.draw = mainRenderFunc,
|
||||
.draw2D = mainDraw2DFunc,
|
||||
.postDraw = mainPostDrawFunc,
|
||||
.encode = mainEncode,
|
||||
.decode = mainDecode,
|
||||
.keyboard = mainKeyboardCallback,
|
||||
.character = mainCharCallback,
|
||||
.mouseButton = mainMouseButtonCallback,
|
||||
.mousePos = mainMousePosCallback,
|
||||
.mouseScroll = mainMouseScrollCallback,
|
||||
.drop = mainDropCallback
|
||||
};
|
||||
Log::instance().setNotifyLevel(Log::Level::Debug);
|
||||
|
||||
try {
|
||||
|
||||
@@ -22,8 +22,10 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/configuration.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/settings.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/engine/configuration.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
@@ -44,15 +46,19 @@ int main(int, char**) {
|
||||
|
||||
ghoul::initialize();
|
||||
|
||||
std::string configFile = configuration::findConfiguration();
|
||||
global::configuration = configuration::loadConfigurationFromFile(configFile);
|
||||
global::openSpaceEngine.initialize();
|
||||
std::filesystem::path configFile = findConfiguration();
|
||||
std::filesystem::path settings = findSettings();
|
||||
*global::configuration = loadConfigurationFromFile(
|
||||
configFile,
|
||||
settings,
|
||||
glm::ivec2(0, 0)
|
||||
);
|
||||
global::openSpaceEngine->initialize();
|
||||
|
||||
|
||||
TaskLoader taskLoader;
|
||||
std::vector<std::unique_ptr<Task>> tasks = taskLoader.tasksFromFile(
|
||||
absPath("${TASKS}/full_sync.task")
|
||||
);
|
||||
std::filesystem::path t = absPath("${TASKS}/full_sync.task");
|
||||
std::vector<std::unique_ptr<Task>> tasks = taskLoader.tasksFromFile(t.string());
|
||||
|
||||
for (size_t i = 0; i < tasks.size(); i++) {
|
||||
Task& task = *tasks[i].get();
|
||||
|
||||
@@ -63,14 +63,45 @@ local ToggleTrails = {
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
local ToggleTrailsInstant = {
|
||||
Identifier = "os.ToggleTrailsInstant",
|
||||
Name = "Toggle all trails instantly",
|
||||
Command = [[
|
||||
local capList = openspace.property("*Trail.Renderable.Fade")
|
||||
local list = openspace.property("*trail.Renderable.Fade")
|
||||
if (#capList == 0) and (#list == 0) then
|
||||
openspace.printWarning("No trails to toggle")
|
||||
else
|
||||
local prop
|
||||
if #capList > 0 then
|
||||
prop = capList[1]
|
||||
else
|
||||
prop = list[1]
|
||||
end
|
||||
local currentFade = openspace.propertyValue(prop)
|
||||
local newFade = 0
|
||||
if currentFade < 1 then
|
||||
newFade = 1
|
||||
end
|
||||
openspace.setPropertyValue("Scene.*Trail.Renderable.Fade", newFade)
|
||||
openspace.setPropertyValue("Scene.*trail.Renderable.Fade", newFade)
|
||||
end
|
||||
]],
|
||||
Documentation = "Toggle fade instantly for all trails in the Scene",
|
||||
GuiPath = "/Trails",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.action.registerAction(FadeUpTrails)
|
||||
openspace.action.registerAction(FadeDownTrails)
|
||||
openspace.action.registerAction(ToggleTrails)
|
||||
openspace.action.registerAction(ToggleTrailsInstant)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.action.removeAction(ToggleTrailsInstant)
|
||||
openspace.action.removeAction(ToggleTrails)
|
||||
openspace.action.removeAction(FadeDownTrails)
|
||||
openspace.action.removeAction(FadeUpTrails)
|
||||
@@ -79,3 +110,4 @@ end)
|
||||
asset.export("FadeUpTrails", FadeUpTrails.Identifier)
|
||||
asset.export("FadeDownTrails", FadeDownTrails.Identifier)
|
||||
asset.export("ToggleTrails", ToggleTrails.Identifier)
|
||||
asset.export("ToggleTrailsInstant", ToggleTrailsInstant.Identifier)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
asset.require("./base")
|
||||
local trailAction = asset.require("actions/trails/toggle_trails_planets_moons").ToggleTrails
|
||||
local allTrailsAction = asset.require("actions/trails/toggle_all_trails").ToggleTrails
|
||||
local allTrailsInstantAction = asset.require("actions/trails/toggle_all_trails").ToggleTrailsInstant
|
||||
|
||||
|
||||
|
||||
@@ -22,13 +22,13 @@ asset.onInitialize(function()
|
||||
openspace.action.registerAction(TogglePlanetLabels)
|
||||
openspace.bindKey("L", TogglePlanetLabels.Identifier)
|
||||
|
||||
openspace.bindKey("H", trailAction)
|
||||
openspace.bindKey("SHIFT+H", allTrailsAction)
|
||||
openspace.bindKey("T", allTrailsAction)
|
||||
openspace.bindKey("SHIFT+T", allTrailsInstantAction)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.clearKey("SHIFT+H")
|
||||
openspace.clearKey("H")
|
||||
openspace.clearKey("SHIFT+T")
|
||||
openspace.clearKey("T")
|
||||
|
||||
openspace.action.removeAction(TogglePlanetLabels)
|
||||
openspace.clearKey("L")
|
||||
|
||||
@@ -194,7 +194,7 @@ asset.onInitialize(function()
|
||||
openspace.bindKey("Ctrl+F", ToggleRollFriction.Identifier)
|
||||
|
||||
openspace.action.registerAction(FadeToBlack)
|
||||
openspace.bindKey("W", FadeToBlack.Identifier)
|
||||
openspace.bindKey("B", FadeToBlack.Identifier)
|
||||
|
||||
openspace.action.registerAction(ToggleMainGui)
|
||||
openspace.bindKey("TAB", ToggleMainGui.Identifier)
|
||||
@@ -246,7 +246,7 @@ asset.onDeinitialize(function()
|
||||
openspace.clearKey("TAB")
|
||||
openspace.action.removeAction(ToggleMainGui)
|
||||
|
||||
openspace.clearKey("W")
|
||||
openspace.clearKey("B")
|
||||
openspace.action.removeAction(FadeToBlack)
|
||||
|
||||
openspace.clearKey("Ctrl+F")
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
local transforms = asset.require("scene/solarsystem/planets/earth/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local coreKernels = asset.require("spice/core")
|
||||
|
||||
|
||||
local models = asset.resource({
|
||||
Name = "Tiangong Models",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "tiangong_model",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local omm = asset.resource({
|
||||
Name = "Satellite OMM Data (Tiangong)",
|
||||
Type = "UrlSynchronization",
|
||||
Identifier = "satellite_omm_data_tiangong",
|
||||
Url = "https://www.celestrak.com/NORAD/elements/gp.php?CATNR=48274&FORMAT=kvn",
|
||||
Filename = "Tiangong.txt",
|
||||
SecondsUntilResync = 24 * 60 * 60
|
||||
})
|
||||
|
||||
|
||||
local TiangongPosition = {
|
||||
Identifier = "TiangongPosition",
|
||||
Parent = transforms.EarthInertial.Identifier,
|
||||
BoundingSphere = 54.5, -- half the width
|
||||
Transform = {
|
||||
Translation = {
|
||||
Type = "GPTranslation",
|
||||
Observer = transforms.EarthInertial.Identifier,
|
||||
File = omm .. "Tiangong.txt",
|
||||
Format = "OMM"
|
||||
},
|
||||
Rotation = {
|
||||
Type = "SpiceRotation",
|
||||
SourceFrame = coreKernels.Frame.Galactic,
|
||||
DestinationFrame = coreKernels.Frame.J2000
|
||||
}
|
||||
},
|
||||
Tag = { "earth_satellite" },
|
||||
GUI = {
|
||||
Name = "Tiangong Position",
|
||||
Path = "/Solar System/Planets/Earth/Satellites/Tiangong",
|
||||
Hidden = true
|
||||
}
|
||||
}
|
||||
|
||||
local TiangongModel = {
|
||||
Identifier = "Tiangong",
|
||||
Parent = TiangongPosition.Identifier,
|
||||
Transform = {
|
||||
Rotation = {
|
||||
Type = "FixedRotation",
|
||||
Attached = "Tiangong",
|
||||
XAxis = { 0.01, -0.09, 1.0 },
|
||||
XAxisOrthogonal = true,
|
||||
YAxis = transforms.EarthInertial.Identifier
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = asset.resource(models .. "tiangong.glb"),
|
||||
LightSources = {
|
||||
sun.LightSource
|
||||
},
|
||||
PerformShading = true
|
||||
},
|
||||
Tag = { "earth_satellite" },
|
||||
GUI = {
|
||||
Name = "Tiangong",
|
||||
Path = "/Solar System/Planets/Earth/Satellites/Tiangong"
|
||||
}
|
||||
}
|
||||
|
||||
local TiangongTrail = {
|
||||
Identifier = "Tiangong_trail",
|
||||
Parent = transforms.EarthInertial.Identifier,
|
||||
Renderable = {
|
||||
Type = "RenderableTrailOrbit",
|
||||
Translation = {
|
||||
Type = "GPTranslation",
|
||||
Observer = transforms.EarthInertial.Identifier,
|
||||
File = omm .. "Tiangong.txt",
|
||||
Format = "OMM"
|
||||
},
|
||||
RenderBinMode = "PostDeferredTransparent",
|
||||
Color = { 0.9, 0.28, 0.33 },
|
||||
Fade = 1.5,
|
||||
Resolution = 320
|
||||
},
|
||||
Tag = { "earth_satellite" },
|
||||
GUI = {
|
||||
Name = "Tiangong Trail",
|
||||
Path = "/Solar System/Planets/Earth/Satellites/Tiangong"
|
||||
}
|
||||
}
|
||||
|
||||
-- @TODO (emmbr, 2021-05-27) add to scene when label rendering issues have been fixed
|
||||
local TiangongLabel = {
|
||||
Identifier = "TiangongLabel",
|
||||
Parent = TiangongPosition.Identifier,
|
||||
Renderable = {
|
||||
Type = "RenderableLabel",
|
||||
Enabled = false,
|
||||
Text = "Tiangong",
|
||||
FontSize = 70.0,
|
||||
Size = 3.4,
|
||||
MinMaxSize = { 1, 100 },
|
||||
OrientationOption = "Camera View Direction",
|
||||
BlendMode = "Additive",
|
||||
EnableFading = true,
|
||||
FadeDistances = { 0.15, 15.0 },
|
||||
FadeWidths = { 1.0, 25.0 }
|
||||
},
|
||||
Tag = { "solarsystem_labels" },
|
||||
GUI = {
|
||||
Name = "Tiangong Label",
|
||||
Path = "/Solar System/Planets/Earth/Satellites"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
local i = openspace.space.readKeplerFile(omm .. "Tiangong.txt", "OMM")
|
||||
TiangongTrail.Renderable.Period = i[1].Period / (60 * 60 * 24)
|
||||
|
||||
openspace.addSceneGraphNode(TiangongPosition)
|
||||
openspace.addSceneGraphNode(TiangongModel)
|
||||
openspace.addSceneGraphNode(TiangongTrail)
|
||||
|
||||
openspace.setPropertyValueSingle("Scene.Tiangong.Rotation.yAxisInvertObject", true)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(TiangongTrail)
|
||||
openspace.removeSceneGraphNode(TiangongModel)
|
||||
openspace.removeSceneGraphNode(TiangongPosition)
|
||||
end)
|
||||
|
||||
asset.export(TiangongTrail)
|
||||
asset.export(TiangongModel)
|
||||
asset.export(TiangongPosition)
|
||||
|
||||
|
||||
|
||||
asset.meta = {
|
||||
Name = "Tiangong",
|
||||
Version = "2.0",
|
||||
Description = [[Model and Trail for Tiangong. Model from Turbosquid, trail from
|
||||
Celestrak.]],
|
||||
Author = "OpenSpace Team",
|
||||
URL = "https://celestrak.com/"
|
||||
}
|
||||
@@ -3,6 +3,7 @@ asset.require("./communications/geostationary")
|
||||
asset.require("./navigation/gps")
|
||||
asset.require("./misc/spacestations")
|
||||
asset.require("./misc/iss")
|
||||
asset.require("./misc/tiangong")
|
||||
asset.require("./misc/tle-new")
|
||||
|
||||
|
||||
|
||||
@@ -46,5 +46,3 @@ return {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-- https://astrowebmaps.wr.usgs.gov/webmapatlas/Layers/maps.html
|
||||
Submodule ext/ghoul updated: 06d72a031c...2905908df8
@@ -158,7 +158,6 @@ private:
|
||||
|
||||
std::unique_ptr<Scene> _scene;
|
||||
std::unique_ptr<AssetManager> _assetManager;
|
||||
bool _shouldAbortLoading = false;
|
||||
std::unique_ptr<LoadingScreen> _loadingScreen;
|
||||
std::unique_ptr<VersionChecker> _versionChecker;
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define __OPENSPACE_CORE___NAVIGATIONSTATE___H__
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/json.h>
|
||||
#include <optional>
|
||||
|
||||
namespace openspace {
|
||||
@@ -37,12 +38,14 @@ namespace openspace::interaction {
|
||||
struct NavigationState {
|
||||
NavigationState() = default;
|
||||
explicit NavigationState(const ghoul::Dictionary& dictionary);
|
||||
explicit NavigationState(const nlohmann::json& json);
|
||||
NavigationState(std::string anchor, std::string aim, std::string referenceFrame,
|
||||
glm::dvec3 position, std::optional<glm::dvec3> up = std::nullopt,
|
||||
double yaw = 0.0, double pitch = 0.0);
|
||||
|
||||
CameraPose cameraPose() const;
|
||||
ghoul::Dictionary dictionary() const;
|
||||
nlohmann::json toJson() const;
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
std::string anchor;
|
||||
|
||||
@@ -46,6 +46,9 @@ namespace ghoul::opengl {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class AssetManager;
|
||||
class Scene;
|
||||
|
||||
class LoadingScreen {
|
||||
public:
|
||||
BooleanType(ShowMessage);
|
||||
@@ -57,29 +60,11 @@ public:
|
||||
ShowLogMessages showLogMessages);
|
||||
~LoadingScreen();
|
||||
|
||||
void abort();
|
||||
void exec(AssetManager& manager, Scene& scene);
|
||||
|
||||
void render();
|
||||
|
||||
void postMessage(std::string message);
|
||||
void setCatastrophicError(CatastrophicError catastrophicError);
|
||||
|
||||
void finalize();
|
||||
|
||||
enum class Phase {
|
||||
PreStart,
|
||||
Construction,
|
||||
Synchronization,
|
||||
Initialization
|
||||
};
|
||||
void setPhase(Phase phase);
|
||||
|
||||
|
||||
enum class ItemStatus {
|
||||
Started,
|
||||
Initializing,
|
||||
Finished,
|
||||
Failed
|
||||
};
|
||||
|
||||
struct ProgressInfo {
|
||||
float progress = 0.f;
|
||||
|
||||
@@ -87,10 +72,29 @@ public:
|
||||
int64_t totalSize = -1;
|
||||
};
|
||||
|
||||
enum class ItemStatus {
|
||||
Started,
|
||||
Initializing,
|
||||
Finished,
|
||||
Failed
|
||||
};
|
||||
|
||||
void updateItem(const std::string& itemIdentifier, const std::string& itemName,
|
||||
ItemStatus newStatus, ProgressInfo progressInfo);
|
||||
|
||||
private:
|
||||
enum class Phase {
|
||||
PreStart,
|
||||
Construction,
|
||||
Synchronization,
|
||||
Initialization
|
||||
};
|
||||
|
||||
void postMessage(std::string message);
|
||||
void setCatastrophicError(CatastrophicError catastrophicError);
|
||||
|
||||
void finalize();
|
||||
void setPhase(Phase phase);
|
||||
|
||||
void renderLogMessages() const;
|
||||
|
||||
@@ -127,6 +131,8 @@ private:
|
||||
std::vector<Item> _items;
|
||||
std::mutex _itemsMutex;
|
||||
|
||||
bool _shouldAbortLoading = false;
|
||||
|
||||
std::random_device _randomDevice;
|
||||
std::default_random_engine _randomEngine;
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ public:
|
||||
using CameraType = std::variant<CameraGoToNode, CameraNavState, CameraGoToGeo>;
|
||||
|
||||
Profile() = default;
|
||||
explicit Profile(const std::string& content);
|
||||
explicit Profile(const std::filesystem::path& path);
|
||||
std::string serialize() const;
|
||||
|
||||
/**
|
||||
|
||||
@@ -55,14 +55,14 @@
|
||||
namespace {
|
||||
constexpr std::string_view _loggerCat = "RenderablePointCloud";
|
||||
|
||||
constexpr std::array<const char*, 29> UniformNames = {
|
||||
constexpr std::array<const char*, 32> UniformNames = {
|
||||
"cameraViewMatrix", "projectionMatrix", "modelMatrix", "cameraPosition",
|
||||
"cameraLookUp", "renderOption", "maxAngularSize", "color", "opacity",
|
||||
"scaleExponent", "scaleFactor", "up", "right", "fadeInValue", "hasSpriteTexture",
|
||||
"spriteTexture", "useColorMap", "colorMapTexture", "cmapRangeMin", "cmapRangeMax",
|
||||
"nanColor", "useNanColor", "hideOutsideRange", "enableMaxSizeControl",
|
||||
"aboveRangeColor", "useAboveRangeColor", "belowRangeColor", "useBelowRangeColor",
|
||||
"hasDvarScaling"
|
||||
"hasDvarScaling", "enableOutline", "outlineColor", "outlineWeight"
|
||||
};
|
||||
|
||||
enum RenderOption {
|
||||
@@ -229,6 +229,30 @@ namespace {
|
||||
openspace::properties::Property::Visibility::AdvancedUser
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo EnableOutlineInfo = {
|
||||
"EnableOutline",
|
||||
"Enable Point Outline",
|
||||
"This setting determines if each point should have an outline or not. An outline "
|
||||
"is only applied when rendering as colored points (not when using textures).",
|
||||
openspace::properties::Property::Visibility::User
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo OutlineColorInfo = {
|
||||
"OutlineColor",
|
||||
"Outline Color",
|
||||
"This value defines the color of the outline. Darker colors will be "
|
||||
"less visible if Additive Blending is enabled.",
|
||||
openspace::properties::Property::Visibility::User
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo OutlineWeightInfo = {
|
||||
"OutlineWeight",
|
||||
"Outline Weight",
|
||||
"This setting determines the thickness of the outline. A value of 0 will "
|
||||
"not show any outline, while a value of 1 will cover the whole point.",
|
||||
openspace::properties::Property::Visibility::AdvancedUser
|
||||
};
|
||||
|
||||
// A RenderablePointCloud can be used to render point-based datasets in 3D space,
|
||||
// optionally including color mapping, a sprite texture and labels. There are several
|
||||
// properties that affect the visuals of the points, such as settings for scaling,
|
||||
@@ -336,6 +360,15 @@ namespace {
|
||||
// Settings related to the choice of color map, parameters, etc.
|
||||
std::optional<ghoul::Dictionary> colorMapping
|
||||
[[codegen::reference("colormappingcomponent")]];
|
||||
|
||||
// [[codegen::verbatim(EnableOutlineInfo.description)]]
|
||||
std::optional<bool> enableOutline;
|
||||
|
||||
// [[codegen::verbatim(OutlineColorInfo.description)]]
|
||||
std::optional<glm::vec3> outlineColor;
|
||||
|
||||
// [[codegen::verbatim(OutlineColorInfo.description)]]
|
||||
std::optional<float> outlineWeight;
|
||||
};
|
||||
// Settings related to the coloring of the points, such as a fixed color,
|
||||
// color map, etc.
|
||||
@@ -419,10 +452,14 @@ RenderablePointCloud::SizeSettings::SizeMapping::SizeMapping()
|
||||
RenderablePointCloud::ColorSettings::ColorSettings(const ghoul::Dictionary& dictionary)
|
||||
: properties::PropertyOwner({ "Coloring", "Coloring", "" })
|
||||
, pointColor(PointColorInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(1.f))
|
||||
, enableOutline(EnableOutlineInfo, false)
|
||||
, outlineColor(OutlineColorInfo, glm::vec3(0.23f), glm::vec3(0.f), glm::vec3(1.f))
|
||||
, outlineWeight(OutlineWeightInfo, 0.2f, 0.f, 1.f)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
if (p.coloring.has_value()) {
|
||||
const bool hasColoring = p.coloring.has_value();
|
||||
if (hasColoring) {
|
||||
const Parameters::ColorSettings settings = *p.coloring;
|
||||
pointColor = settings.fixedColor.value_or(pointColor);
|
||||
|
||||
@@ -432,9 +469,20 @@ RenderablePointCloud::ColorSettings::ColorSettings(const ghoul::Dictionary& dict
|
||||
);
|
||||
addPropertySubOwner(colorMapping.get());
|
||||
}
|
||||
|
||||
enableOutline = p.coloring->enableOutline.value_or(enableOutline);
|
||||
outlineColor = p.coloring->outlineColor.value_or(outlineColor);
|
||||
outlineWeight = p.coloring->outlineWeight.value_or(outlineWeight);
|
||||
}
|
||||
pointColor.setViewOption(properties::Property::ViewOptions::Color);
|
||||
addProperty(pointColor);
|
||||
|
||||
addProperty(enableOutline);
|
||||
|
||||
outlineColor.setViewOption(properties::Property::ViewOptions::Color);
|
||||
addProperty(outlineColor);
|
||||
|
||||
addProperty(outlineWeight);
|
||||
}
|
||||
|
||||
RenderablePointCloud::Fading::Fading(const ghoul::Dictionary& dictionary)
|
||||
@@ -735,6 +783,9 @@ void RenderablePointCloud::bindDataForPointRendering() {
|
||||
}
|
||||
|
||||
_program->setUniform(_uniformCache.color, _colorSettings.pointColor);
|
||||
_program->setUniform(_uniformCache.enableOutline, _colorSettings.enableOutline);
|
||||
_program->setUniform(_uniformCache.outlineColor, _colorSettings.outlineColor);
|
||||
_program->setUniform(_uniformCache.outlineWeight, _colorSettings.outlineWeight);
|
||||
|
||||
bool useColorMap = _hasColorMapFile && _colorSettings.colorMapping->enabled &&
|
||||
_colorSettings.colorMapping->texture();
|
||||
|
||||
@@ -132,6 +132,9 @@ protected:
|
||||
explicit ColorSettings(const ghoul::Dictionary& dictionary);
|
||||
properties::Vec3Property pointColor;
|
||||
std::unique_ptr<ColorMappingComponent> colorMapping;
|
||||
properties::BoolProperty enableOutline;
|
||||
properties::Vec3Property outlineColor;
|
||||
properties::FloatProperty outlineWeight;
|
||||
};
|
||||
ColorSettings _colorSettings;
|
||||
|
||||
@@ -162,7 +165,7 @@ protected:
|
||||
right, fadeInValue, hasSpriteTexture, spriteTexture, useColormap, colorMapTexture,
|
||||
cmapRangeMin, cmapRangeMax, nanColor, useNanColor, hideOutsideRange,
|
||||
enableMaxSizeControl, aboveRangeColor, useAboveRangeColor, belowRangeColor,
|
||||
useBelowRangeColor, hasDvarScaling
|
||||
useBelowRangeColor, hasDvarScaling, enableOutline, outlineColor, outlineWeight
|
||||
) _uniformCache;
|
||||
|
||||
std::string _dataFile;
|
||||
|
||||
@@ -49,6 +49,9 @@ uniform sampler1D colorMapTexture;
|
||||
uniform float cmapRangeMin;
|
||||
uniform float cmapRangeMax;
|
||||
uniform bool hideOutsideRange;
|
||||
uniform bool enableOutline;
|
||||
uniform vec3 outlineColor;
|
||||
uniform float outlineWeight;
|
||||
|
||||
uniform float fadeInValue;
|
||||
|
||||
@@ -80,24 +83,26 @@ Fragment getFragment() {
|
||||
discard;
|
||||
}
|
||||
|
||||
if (!hasSpriteTexture) {
|
||||
// Moving the origin to the center
|
||||
vec2 st = (texCoord - vec2(0.5)) * 2.0;
|
||||
if (length(st) > 1.0) {
|
||||
// Moving the origin to the center and calculating the length
|
||||
float lengthFromCenter = length((texCoord - vec2(0.5)) * 2.0);
|
||||
if (!hasSpriteTexture) {
|
||||
if (lengthFromCenter > 1.0) {
|
||||
discard;
|
||||
}
|
||||
}
|
||||
|
||||
vec4 fullColor = vec4(1.0);
|
||||
if (hasSpriteTexture) {
|
||||
fullColor = texture(spriteTexture, texCoord);
|
||||
}
|
||||
|
||||
if (useColorMap) {
|
||||
fullColor *= sampleColorMap(gs_colorParameter);
|
||||
fullColor = sampleColorMap(gs_colorParameter);
|
||||
}
|
||||
else {
|
||||
fullColor.rgb *= color;
|
||||
fullColor.rgb = color;
|
||||
}
|
||||
|
||||
if (hasSpriteTexture) {
|
||||
fullColor *= texture(spriteTexture, texCoord);
|
||||
} else if (enableOutline && (lengthFromCenter > (1.0 - outlineWeight))) {
|
||||
fullColor.rgb = outlineColor;
|
||||
}
|
||||
|
||||
fullColor.a *= opacity * fadeInValue;
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
#pragma warning (disable : 4251)
|
||||
#endif // _MSC_VER
|
||||
|
||||
#include <cpl_conv.h>
|
||||
#include <cpl_string.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -550,10 +551,12 @@ void GlobeBrowsingModule::loadWMSCapabilities(std::string name, std::string glob
|
||||
{
|
||||
auto downloadFunction = [](const std::string& downloadUrl) {
|
||||
LDEBUG("Opening WMS capabilities: " + downloadUrl);
|
||||
CPLSetConfigOption("GDAL_HTTP_TIMEOUT", "15"); // 3 seconds
|
||||
GDALDatasetH dataset = GDALOpen(
|
||||
downloadUrl.c_str(),
|
||||
GA_ReadOnly
|
||||
);
|
||||
CPLSetConfigOption("GDAL_HTTP_TIMEOUT", "3"); // 3 seconds
|
||||
|
||||
if (!dataset) {
|
||||
LWARNING("Could not open dataset: " + downloadUrl);
|
||||
|
||||
@@ -112,8 +112,8 @@ namespace {
|
||||
case Mode::UserControl: return "UserControl";
|
||||
case Mode::CameraPath: return "CameraPath";
|
||||
case Mode::SessionRecordingPlayback: return "SessionRecording";
|
||||
default: throw ghoul::MissingCaseException();
|
||||
}
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo PrintEventsInfo = {
|
||||
@@ -391,21 +391,7 @@ void OpenSpaceEngine::initialize() {
|
||||
}
|
||||
|
||||
// Load the profile
|
||||
std::ifstream inFile;
|
||||
try {
|
||||
inFile.open(profile, std::ifstream::in);
|
||||
}
|
||||
catch (const std::ifstream::failure& e) {
|
||||
throw ghoul::RuntimeError(fmt::format(
|
||||
"Exception opening profile file for read: {} ({})", profile, e.what()
|
||||
));
|
||||
}
|
||||
|
||||
std::string content(
|
||||
(std::istreambuf_iterator<char>(inFile)),
|
||||
std::istreambuf_iterator<char>()
|
||||
);
|
||||
*global::profile = Profile(content);
|
||||
*global::profile = Profile(profile);
|
||||
|
||||
// Set up asset loader
|
||||
_assetManager = std::make_unique<AssetManager>(
|
||||
@@ -768,119 +754,10 @@ void OpenSpaceEngine::loadAssets() {
|
||||
_assetManager->add(a);
|
||||
}
|
||||
|
||||
_loadingScreen->setPhase(LoadingScreen::Phase::Construction);
|
||||
_loadingScreen->postMessage("Loading assets");
|
||||
|
||||
std::unordered_set<const ResourceSynchronization*> finishedSynchronizations;
|
||||
|
||||
while (true) {
|
||||
_loadingScreen->render();
|
||||
_assetManager->update();
|
||||
|
||||
std::vector<const Asset*> allAssets = _assetManager->allAssets();
|
||||
|
||||
std::vector<const ResourceSynchronization*> allSyncs =
|
||||
_assetManager->allSynchronizations();
|
||||
|
||||
// Filter already synchronized assets so we don't check them anymore
|
||||
auto syncIt = std::remove_if(
|
||||
allSyncs.begin(),
|
||||
allSyncs.end(),
|
||||
[&finishedSynchronizations](const ResourceSynchronization* sync) {
|
||||
return finishedSynchronizations.contains(sync);
|
||||
}
|
||||
);
|
||||
allSyncs.erase(syncIt, allSyncs.end());
|
||||
|
||||
auto it = allSyncs.begin();
|
||||
while (it != allSyncs.end()) {
|
||||
ZoneScopedN("Update resource synchronization");
|
||||
|
||||
if ((*it)->isSyncing()) {
|
||||
LoadingScreen::ProgressInfo progressInfo;
|
||||
|
||||
progressInfo.progress = [](const ResourceSynchronization* sync) {
|
||||
if (!sync->nTotalBytesIsKnown()) {
|
||||
return 0.f;
|
||||
}
|
||||
if (sync->nTotalBytes() == 0) {
|
||||
return 1.f;
|
||||
}
|
||||
return
|
||||
static_cast<float>(sync->nSynchronizedBytes()) /
|
||||
static_cast<float>(sync->nTotalBytes());
|
||||
}(*it);
|
||||
|
||||
progressInfo.currentSize = (*it)->nSynchronizedBytes();
|
||||
if ((*it)->nTotalBytesIsKnown()) {
|
||||
progressInfo.totalSize = (*it)->nTotalBytes();
|
||||
}
|
||||
|
||||
_loadingScreen->updateItem(
|
||||
(*it)->identifier(),
|
||||
(*it)->name(),
|
||||
LoadingScreen::ItemStatus::Started,
|
||||
progressInfo
|
||||
);
|
||||
++it;
|
||||
}
|
||||
else if ((*it)->isRejected()) {
|
||||
_loadingScreen->updateItem(
|
||||
(*it)->identifier(),
|
||||
(*it)->name(),
|
||||
LoadingScreen::ItemStatus::Failed,
|
||||
LoadingScreen::ProgressInfo()
|
||||
);
|
||||
++it;
|
||||
}
|
||||
else {
|
||||
LoadingScreen::ProgressInfo progressInfo;
|
||||
progressInfo.progress = 1.f;
|
||||
|
||||
_loadingScreen->updateItem(
|
||||
(*it)->identifier(),
|
||||
(*it)->name(),
|
||||
LoadingScreen::ItemStatus::Finished,
|
||||
progressInfo
|
||||
);
|
||||
finishedSynchronizations.insert(*it);
|
||||
it = allSyncs.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
if (_shouldAbortLoading) {
|
||||
global::windowDelegate->terminate();
|
||||
break;
|
||||
}
|
||||
|
||||
bool finishedLoading = std::all_of(
|
||||
allAssets.begin(),
|
||||
allAssets.end(),
|
||||
[](const Asset* asset) { return asset->isInitialized() || asset->isFailed(); }
|
||||
);
|
||||
|
||||
if (finishedLoading) {
|
||||
break;
|
||||
}
|
||||
} // while(true)
|
||||
|
||||
if (_shouldAbortLoading) {
|
||||
_loadingScreen = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
_loadingScreen->setPhase(LoadingScreen::Phase::Initialization);
|
||||
|
||||
_loadingScreen->postMessage("Initializing scene");
|
||||
while (_scene->isInitializing()) {
|
||||
_loadingScreen->render();
|
||||
}
|
||||
|
||||
_loadingScreen->postMessage("Initializing OpenGL");
|
||||
_loadingScreen->finalize();
|
||||
|
||||
_loadingScreen->exec(*_assetManager, *_scene);
|
||||
_loadingScreen = nullptr;
|
||||
|
||||
|
||||
global::renderEngine->updateScene();
|
||||
|
||||
global::syncEngine->addSyncables(global::timeManager->syncables());
|
||||
@@ -1308,7 +1185,7 @@ void OpenSpaceEngine::keyboardCallback(Key key, KeyModifier mod, KeyAction actio
|
||||
// If the loading screen object exists, we are currently loading and want key
|
||||
// presses to behave differently
|
||||
if (key == Key::Escape) {
|
||||
_shouldAbortLoading = true;
|
||||
_loadingScreen->abort();
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@@ -557,6 +557,10 @@ void NavigationHandler::saveNavigationState(const std::filesystem::path& filepat
|
||||
}
|
||||
|
||||
std::filesystem::path absolutePath = absPath(filepath);
|
||||
if (!absolutePath.has_extension()) {
|
||||
// Adding the .navstate extension to the filepath if it came without one
|
||||
absolutePath.replace_extension(".navstate");
|
||||
}
|
||||
LINFO(fmt::format("Saving camera position: {}", absolutePath));
|
||||
|
||||
std::ofstream ofs(absolutePath);
|
||||
@@ -567,7 +571,7 @@ void NavigationHandler::saveNavigationState(const std::filesystem::path& filepat
|
||||
));
|
||||
}
|
||||
|
||||
ofs << "return " << ghoul::formatLua(state.dictionary());
|
||||
ofs << state.toJson().dump(2);
|
||||
}
|
||||
|
||||
void NavigationHandler::loadNavigationState(const std::string& filepath) {
|
||||
@@ -578,22 +582,15 @@ void NavigationHandler::loadNavigationState(const std::string& filepath) {
|
||||
throw ghoul::FileNotFoundError(absolutePath.string(), "NavigationState");
|
||||
}
|
||||
|
||||
ghoul::Dictionary navigationStateDictionary;
|
||||
try {
|
||||
ghoul::lua::loadDictionaryFromFile(
|
||||
absolutePath.string(),
|
||||
navigationStateDictionary
|
||||
);
|
||||
openspace::documentation::testSpecificationAndThrow(
|
||||
NavigationState::Documentation(),
|
||||
navigationStateDictionary,
|
||||
"NavigationState"
|
||||
);
|
||||
setNavigationStateNextFrame(NavigationState(navigationStateDictionary));
|
||||
}
|
||||
catch (ghoul::RuntimeError& e) {
|
||||
LERROR(fmt::format("Unable to set camera position: {}", e.message));
|
||||
}
|
||||
std::ifstream f(filepath);
|
||||
std::string contents = std::string(
|
||||
std::istreambuf_iterator<char>(f),
|
||||
std::istreambuf_iterator<char>()
|
||||
);
|
||||
nlohmann::json json = nlohmann::json::parse(contents);
|
||||
|
||||
NavigationState state = NavigationState(json);
|
||||
setNavigationStateNextFrame(state);
|
||||
}
|
||||
|
||||
std::vector<std::string> NavigationHandler::listAllJoysticks() const {
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current navigation state as a lua table. The optional argument is the scene
|
||||
* Return the current navigation state as a Lua table. The optional argument is the scene
|
||||
* graph node to use as reference frame. By default, the reference frame will picked based
|
||||
* on whether the orbital navigator is currently following the anchor node rotation. If it
|
||||
* is, the anchor will be chosen as reference frame. If not, the reference frame will be
|
||||
|
||||
@@ -89,11 +89,42 @@ NavigationState::NavigationState(const ghoul::Dictionary& dictionary) {
|
||||
referenceFrame = p.referenceFrame.value_or(anchor);
|
||||
aim = p.aim.value_or(aim);
|
||||
|
||||
if (p.up.has_value()) {
|
||||
up = *p.up;
|
||||
up = p.up;
|
||||
yaw = p.yaw.value_or(yaw);
|
||||
pitch = p.pitch.value_or(pitch);
|
||||
}
|
||||
|
||||
yaw = p.yaw.value_or(yaw);
|
||||
pitch = p.pitch.value_or(pitch);
|
||||
NavigationState::NavigationState(const nlohmann::json& json) {
|
||||
position.x = json["position"]["x"].get<double>();
|
||||
position.y = json["position"]["y"].get<double>();
|
||||
position.z = json["position"]["z"].get<double>();
|
||||
|
||||
anchor = json["anchor"];
|
||||
|
||||
if (auto it = json.find("referenceframe"); it != json.end()) {
|
||||
referenceFrame = it->get<std::string>();
|
||||
}
|
||||
else {
|
||||
referenceFrame = anchor;
|
||||
}
|
||||
|
||||
if (auto it = json.find("aim"); it != json.end()) {
|
||||
aim = it->get<std::string>();
|
||||
}
|
||||
|
||||
if (auto it = json.find("up"); it != json.end()) {
|
||||
up = glm::dvec3();
|
||||
up->x = it->at("x").get<double>();
|
||||
up->y = it->at("y").get<double>();
|
||||
up->z = it->at("z").get<double>();
|
||||
}
|
||||
|
||||
if (auto it = json.find("yaw"); it != json.end()) {
|
||||
yaw = it->get<double>();
|
||||
}
|
||||
|
||||
if (auto it = json.find("pitch"); it != json.end()) {
|
||||
pitch = it->get<double>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,16 +205,56 @@ ghoul::Dictionary NavigationState::dictionary() const {
|
||||
}
|
||||
if (up.has_value()) {
|
||||
cameraDict.setValue("Up", *up);
|
||||
}
|
||||
if (std::abs(yaw) > Epsilon) {
|
||||
cameraDict.setValue("Yaw", yaw);
|
||||
}
|
||||
if (std::abs(pitch) > Epsilon) {
|
||||
cameraDict.setValue("Pitch", pitch);
|
||||
}
|
||||
return cameraDict;
|
||||
}
|
||||
|
||||
if (std::abs(yaw) > Epsilon) {
|
||||
cameraDict.setValue("Yaw", yaw);
|
||||
}
|
||||
if (std::abs(pitch) > Epsilon) {
|
||||
cameraDict.setValue("Pitch", pitch);
|
||||
}
|
||||
nlohmann::json NavigationState::toJson() const {
|
||||
nlohmann::json result = nlohmann::json::object();
|
||||
|
||||
// Obligatory version number
|
||||
result["version"] = 1;
|
||||
|
||||
{
|
||||
nlohmann::json posObj = nlohmann::json::object();
|
||||
posObj["x"] = position.x;
|
||||
posObj["y"] = position.y;
|
||||
posObj["z"] = position.z;
|
||||
result["position"] = posObj;
|
||||
}
|
||||
|
||||
return cameraDict;
|
||||
result["anchor"] = anchor;
|
||||
|
||||
if (anchor != referenceFrame) {
|
||||
result["referenceframe"] = referenceFrame;
|
||||
}
|
||||
|
||||
if (!aim.empty()) {
|
||||
result["aim"] = aim;
|
||||
}
|
||||
|
||||
if (up.has_value()) {
|
||||
nlohmann::json upObj = nlohmann::json::object();
|
||||
upObj["x"] = up->x;
|
||||
upObj["y"] = up->y;
|
||||
upObj["z"] = up->z;
|
||||
result["up"] = upObj;
|
||||
}
|
||||
|
||||
if (std::abs(yaw) > Epsilon) {
|
||||
result["yaw"] = yaw;
|
||||
}
|
||||
if (std::abs(pitch) > Epsilon) {
|
||||
result["pitch"] = pitch;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
documentation::Documentation NavigationState::Documentation() {
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/rendering/helper.h>
|
||||
#include <openspace/scene/asset.h>
|
||||
#include <openspace/scene/assetmanager.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/util/resourcesynchronization.h>
|
||||
#include <ghoul/fmt.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/font/font.h>
|
||||
@@ -43,6 +47,7 @@
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <unordered_set>
|
||||
|
||||
|
||||
namespace {
|
||||
@@ -167,6 +172,117 @@ LoadingScreen::~LoadingScreen() {
|
||||
_log = nullptr;
|
||||
}
|
||||
|
||||
void LoadingScreen::abort() {
|
||||
_shouldAbortLoading = true;
|
||||
}
|
||||
|
||||
void LoadingScreen::exec(AssetManager& manager, Scene& scene) {
|
||||
setPhase(LoadingScreen::Phase::Construction);
|
||||
postMessage("Loading assets");
|
||||
|
||||
std::unordered_set<const ResourceSynchronization*> finishedSynchronizations;
|
||||
while (true) {
|
||||
render();
|
||||
manager.update();
|
||||
|
||||
std::vector<const Asset*> allAssets = manager.allAssets();
|
||||
|
||||
std::vector<const ResourceSynchronization*> allSyncs =
|
||||
manager.allSynchronizations();
|
||||
|
||||
// Filter already synchronized assets so we don't check them anymore
|
||||
auto syncIt = std::remove_if(
|
||||
allSyncs.begin(),
|
||||
allSyncs.end(),
|
||||
[&finishedSynchronizations](const ResourceSynchronization* sync) {
|
||||
return finishedSynchronizations.contains(sync);
|
||||
}
|
||||
);
|
||||
allSyncs.erase(syncIt, allSyncs.end());
|
||||
|
||||
auto it = allSyncs.begin();
|
||||
while (it != allSyncs.end()) {
|
||||
ZoneScopedN("Update resource synchronization");
|
||||
|
||||
if ((*it)->isSyncing()) {
|
||||
LoadingScreen::ProgressInfo progressInfo;
|
||||
|
||||
progressInfo.progress = [](const ResourceSynchronization* sync) {
|
||||
if (!sync->nTotalBytesIsKnown()) {
|
||||
return 0.f;
|
||||
}
|
||||
if (sync->nTotalBytes() == 0) {
|
||||
return 1.f;
|
||||
}
|
||||
return
|
||||
static_cast<float>(sync->nSynchronizedBytes()) /
|
||||
static_cast<float>(sync->nTotalBytes());
|
||||
}(*it);
|
||||
|
||||
progressInfo.currentSize = (*it)->nSynchronizedBytes();
|
||||
if ((*it)->nTotalBytesIsKnown()) {
|
||||
progressInfo.totalSize = (*it)->nTotalBytes();
|
||||
}
|
||||
|
||||
updateItem(
|
||||
(*it)->identifier(),
|
||||
(*it)->name(),
|
||||
LoadingScreen::ItemStatus::Started,
|
||||
progressInfo
|
||||
);
|
||||
++it;
|
||||
}
|
||||
else if ((*it)->isRejected()) {
|
||||
updateItem(
|
||||
(*it)->identifier(),
|
||||
(*it)->name(),
|
||||
LoadingScreen::ItemStatus::Failed,
|
||||
LoadingScreen::ProgressInfo()
|
||||
);
|
||||
++it;
|
||||
}
|
||||
else {
|
||||
LoadingScreen::ProgressInfo progressInfo;
|
||||
progressInfo.progress = 1.f;
|
||||
|
||||
updateItem(
|
||||
(*it)->identifier(),
|
||||
(*it)->name(),
|
||||
LoadingScreen::ItemStatus::Finished,
|
||||
progressInfo
|
||||
);
|
||||
finishedSynchronizations.insert(*it);
|
||||
it = allSyncs.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
if (_shouldAbortLoading) {
|
||||
global::windowDelegate->terminate();
|
||||
return;
|
||||
}
|
||||
|
||||
bool finishedLoading = std::all_of(
|
||||
allAssets.begin(),
|
||||
allAssets.end(),
|
||||
[](const Asset* asset) { return asset->isInitialized() || asset->isFailed(); }
|
||||
);
|
||||
|
||||
if (finishedLoading) {
|
||||
break;
|
||||
}
|
||||
} // while(true)
|
||||
|
||||
setPhase(LoadingScreen::Phase::Initialization);
|
||||
|
||||
postMessage("Initializing scene");
|
||||
while (scene.isInitializing()) {
|
||||
render();
|
||||
}
|
||||
|
||||
postMessage("Initializing OpenGL");
|
||||
finalize();
|
||||
}
|
||||
|
||||
void LoadingScreen::render() {
|
||||
ZoneScoped;
|
||||
FrameMarkStart("Loading");
|
||||
|
||||
@@ -741,7 +741,24 @@ std::string Profile::serialize() const {
|
||||
return r.dump(2);
|
||||
}
|
||||
|
||||
Profile::Profile(const std::string& content) {
|
||||
Profile::Profile(const std::filesystem::path& path) {
|
||||
ghoul_assert(std::filesystem::is_regular_file(path), "Path must exist");
|
||||
|
||||
std::ifstream inFile;
|
||||
try {
|
||||
inFile.open(path, std::ifstream::in);
|
||||
}
|
||||
catch (const std::ifstream::failure& e) {
|
||||
throw ghoul::RuntimeError(fmt::format(
|
||||
"Exception opening profile file for read: {} ({})", path, e.what()
|
||||
));
|
||||
}
|
||||
|
||||
std::string content(
|
||||
(std::istreambuf_iterator<char>(inFile)),
|
||||
std::istreambuf_iterator<char>()
|
||||
);
|
||||
|
||||
try {
|
||||
nlohmann::json profile = nlohmann::json::parse(content);
|
||||
profile.at("version").get_to(version);
|
||||
|
||||
@@ -146,30 +146,13 @@ namespace openspace {
|
||||
|
||||
using namespace openspace;
|
||||
|
||||
namespace {
|
||||
/// Loads the contents of the file and creates a profile from it
|
||||
Profile loadProfile(const std::filesystem::path& filename) {
|
||||
if (!std::filesystem::exists(filename)) {
|
||||
throw std::runtime_error("Could not find file)");
|
||||
}
|
||||
|
||||
std::ifstream f(filename);
|
||||
std::string content(
|
||||
(std::istreambuf_iterator<char>(f)),
|
||||
std::istreambuf_iterator<char>()
|
||||
);
|
||||
|
||||
return Profile(content);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//
|
||||
// Minimal
|
||||
// The absolute minimal profile that can be loaded
|
||||
//
|
||||
TEST_CASE("Minimal", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/minimal.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -182,7 +165,7 @@ TEST_CASE("Minimal", "[profile]") {
|
||||
//
|
||||
TEST_CASE("Basic Meta (full)", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/basic/meta_full.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -201,7 +184,7 @@ TEST_CASE("Basic Meta (full)", "[profile]") {
|
||||
|
||||
TEST_CASE("Basic Meta (empty)", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/basic/meta_empty.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -214,7 +197,7 @@ TEST_CASE("Basic Meta (empty)", "[profile]") {
|
||||
|
||||
TEST_CASE("Basic Meta (no name)", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/basic/meta_no_name.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -232,7 +215,7 @@ TEST_CASE("Basic Meta (no name)", "[profile]") {
|
||||
|
||||
TEST_CASE("Basic Meta (no version)", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/basic/meta_no_version.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -250,7 +233,7 @@ TEST_CASE("Basic Meta (no version)", "[profile]") {
|
||||
|
||||
TEST_CASE("Basic Meta (no description)", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/basic/meta_no_description.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -268,7 +251,7 @@ TEST_CASE("Basic Meta (no description)", "[profile]") {
|
||||
|
||||
TEST_CASE("Basic Meta (no author)", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/basic/meta_no_author.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -286,7 +269,7 @@ TEST_CASE("Basic Meta (no author)", "[profile]") {
|
||||
|
||||
TEST_CASE("Basic Meta (no url)", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/basic/meta_no_url.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -304,7 +287,7 @@ TEST_CASE("Basic Meta (no url)", "[profile]") {
|
||||
|
||||
TEST_CASE("Basic Meta (no license)", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/basic/meta_no_license.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -322,7 +305,7 @@ TEST_CASE("Basic Meta (no license)", "[profile]") {
|
||||
|
||||
TEST_CASE("Basic Module", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/basic/modules.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -357,7 +340,7 @@ TEST_CASE("Basic Module", "[profile]") {
|
||||
|
||||
TEST_CASE("Basic Assets", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/basic/assets.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -371,7 +354,7 @@ TEST_CASE("Basic Assets", "[profile]") {
|
||||
|
||||
TEST_CASE("Basic Properties", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/basic/properties.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -424,7 +407,7 @@ TEST_CASE("Basic Properties", "[profile]") {
|
||||
|
||||
TEST_CASE("Basic Keybindings", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/basic/keybindings.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -480,7 +463,7 @@ TEST_CASE("Basic Keybindings", "[profile]") {
|
||||
|
||||
TEST_CASE("Basic Time Relative", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/basic/time_relative.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -495,7 +478,7 @@ TEST_CASE("Basic Time Relative", "[profile]") {
|
||||
|
||||
TEST_CASE("Basic Time Absolute", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/basic/time_absolute.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -510,7 +493,7 @@ TEST_CASE("Basic Time Absolute", "[profile]") {
|
||||
|
||||
TEST_CASE("Basic Delta Times", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/basic/deltatimes.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -526,7 +509,7 @@ TEST_CASE("Basic Delta Times", "[profile]") {
|
||||
|
||||
TEST_CASE("Basic Camera NavState (full)", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/basic/camera_navstate_full.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -547,7 +530,7 @@ TEST_CASE("Basic Camera NavState (full)", "[profile]") {
|
||||
TEST_CASE("Basic Camera NavState (no aim)", "[profile]") {
|
||||
constexpr std::string_view File =
|
||||
"${TESTDIR}/profile/basic/camera_navstate_no_aim.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -567,7 +550,7 @@ TEST_CASE("Basic Camera NavState (no aim)", "[profile]") {
|
||||
TEST_CASE("Basic Camera NavState (no pitch)", "[profile]") {
|
||||
constexpr std::string_view File =
|
||||
"${TESTDIR}/profile/basic/camera_navstate_no_pitch.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -587,7 +570,7 @@ TEST_CASE("Basic Camera NavState (no pitch)", "[profile]") {
|
||||
TEST_CASE("Basic Camera NavState (no up)", "[profile]") {
|
||||
constexpr std::string_view File =
|
||||
"${TESTDIR}/profile/basic/camera_navstate_no_up.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -607,7 +590,7 @@ TEST_CASE("Basic Camera NavState (no up)", "[profile]") {
|
||||
TEST_CASE("Basic Camera NavState (no yaw)", "[profile]") {
|
||||
constexpr std::string_view File =
|
||||
"${TESTDIR}/profile/basic/camera_navstate_no_yaw.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -626,7 +609,7 @@ TEST_CASE("Basic Camera NavState (no yaw)", "[profile]") {
|
||||
|
||||
TEST_CASE("Basic Camera GoToGeo (full)", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/basic/camera_gotogeo.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -643,7 +626,7 @@ TEST_CASE("Basic Camera GoToGeo (full)", "[profile]") {
|
||||
TEST_CASE("Basic Camera GoToGeo (with altitude)", "[profile]") {
|
||||
constexpr std::string_view File =
|
||||
"${TESTDIR}/profile/basic/camera_gotogeo_altitude.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -661,7 +644,7 @@ TEST_CASE("Basic Camera GoToGeo (with altitude)", "[profile]") {
|
||||
TEST_CASE("Basic Camera GoToNode", "[profile]") {
|
||||
constexpr std::string_view File =
|
||||
"${TESTDIR}/profile/basic/camera_gotonode.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -676,7 +659,7 @@ TEST_CASE("Basic Camera GoToNode", "[profile]") {
|
||||
TEST_CASE("Basic Camera GoToNode (with height)", "[profile]") {
|
||||
constexpr std::string_view File =
|
||||
"${TESTDIR}/profile/basic/camera_gotonode_height.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -691,7 +674,7 @@ TEST_CASE("Basic Camera GoToNode (with height)", "[profile]") {
|
||||
|
||||
TEST_CASE("Basic Mark Nodes", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/basic/mark_nodes.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -706,7 +689,7 @@ TEST_CASE("Basic Mark Nodes", "[profile]") {
|
||||
TEST_CASE("Basic Additional Scripts", "[profile]") {
|
||||
constexpr std::string_view File =
|
||||
"${TESTDIR}/profile/basic/additional_scripts.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -723,7 +706,7 @@ TEST_CASE("Basic Additional Scripts", "[profile]") {
|
||||
//
|
||||
TEST_CASE("Integration Full Test", "[profile]") {
|
||||
constexpr std::string_view File = "${TESTDIR}/profile/integration/full_test.profile";
|
||||
Profile profile = loadProfile(absPath(File));
|
||||
Profile profile = Profile(absPath(File));
|
||||
|
||||
Profile ref;
|
||||
ref.version = Profile::CurrentVersion;
|
||||
@@ -1074,7 +1057,7 @@ TEST_CASE("(Error) Version: Missing value 'major'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/version/missing_major.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'version.major' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1083,7 +1066,7 @@ TEST_CASE("(Error) Version: Missing value 'minor'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/version/missing_minor.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'version.minor' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1092,7 +1075,7 @@ TEST_CASE("(Error) Version: Wrong type 'major'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/version/wrongtype_major.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'version.major' must be a number")
|
||||
);
|
||||
}
|
||||
@@ -1101,7 +1084,7 @@ TEST_CASE("(Error) Version: Wrong type 'minor'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/version/wrongtype_minor.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'version.minor' must be a number")
|
||||
);
|
||||
}
|
||||
@@ -1110,7 +1093,7 @@ TEST_CASE("(Error) Version: Wrong type 'major' and 'minor'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/version/wrongtype_major_minor.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'version.major' must be a number")
|
||||
);
|
||||
}
|
||||
@@ -1124,7 +1107,7 @@ TEST_CASE("(Error) Module: Missing value 'name'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/module/missing_name.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'module.name' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1133,7 +1116,7 @@ TEST_CASE("(Error) Module: Wrong type 'name'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/module/wrongtype_name.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'module.name' must be a string")
|
||||
);
|
||||
}
|
||||
@@ -1142,7 +1125,7 @@ TEST_CASE("(Error) Module: Wrong type 'loadedInstruction'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/module/wrongtype_loadedInstruction.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'module.loadedInstruction' must be a string")
|
||||
);
|
||||
}
|
||||
@@ -1151,7 +1134,7 @@ TEST_CASE("(Error) Module: Wrong type 'notLoadedInstruction'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/module/wrongtype_notLoadedInstruction.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'module.notLoadedInstruction' must be a string")
|
||||
);
|
||||
}
|
||||
@@ -1164,7 +1147,7 @@ TEST_CASE("(Error) Property: Missing value 'name'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/property/missing_name.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'property.name' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1173,7 +1156,7 @@ TEST_CASE("(Error) Property: Missing value 'value'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/property/missing_value.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'property.value' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1182,7 +1165,7 @@ TEST_CASE("(Error) Property: Missing value 'name' and 'value'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/property/missing_name_value.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'property.name' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1191,7 +1174,7 @@ TEST_CASE("(Error) Property: Wrong value 'type'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/property/wrongvalue_type.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) Unknown property set type")
|
||||
);
|
||||
}
|
||||
@@ -1200,7 +1183,7 @@ TEST_CASE("(Error) Property: Wrong type 'name'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/property/wrongtype_name.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'property.name' must be a string")
|
||||
);
|
||||
}
|
||||
@@ -1209,7 +1192,7 @@ TEST_CASE("(Error) Property: Wrong type 'value'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/property/wrongtype_value.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'property.value' must be a string")
|
||||
);
|
||||
}
|
||||
@@ -1222,7 +1205,7 @@ TEST_CASE("(Error) Keybinding: Missing value 'key'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/keybinding/missing_key.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'keybinding.key' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1231,7 +1214,7 @@ TEST_CASE("(Error) Keybinding: Missing value 'documentation'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/keybinding/missing_documentation.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'keybinding.documentation' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1240,7 +1223,7 @@ TEST_CASE("(Error) Keybinding: Missing value 'name'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/keybinding/missing_name.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'keybinding.name' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1249,7 +1232,7 @@ TEST_CASE("(Error) Keybinding: Missing value 'gui_path'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/keybinding/missing_guipath.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'keybinding.gui_path' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1258,7 +1241,7 @@ TEST_CASE("(Error) Keybinding: Missing value 'is_local'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/keybinding/missing_islocal.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'keybinding.is_local' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1267,7 +1250,7 @@ TEST_CASE("(Error) Keybinding: Wrong value 'key'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/keybinding/wrongvalue_key.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("Could not find key for 'F50'")
|
||||
);
|
||||
}
|
||||
@@ -1276,7 +1259,7 @@ TEST_CASE("(Error) Keybinding: Wrong value 'key, modifier'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/keybinding/wrongvalue_modifier.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("Unknown modifier key 'KEYKEY'")
|
||||
);
|
||||
}
|
||||
@@ -1285,7 +1268,7 @@ TEST_CASE("(Error) Keybinding: Wrong type 'documentation'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/keybinding/wrongtype_documentation.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'keybinding.documentation' must be a string")
|
||||
);
|
||||
}
|
||||
@@ -1294,7 +1277,7 @@ TEST_CASE("(Error) Keybinding: Wrong type 'gui_path'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/keybinding/wrongtype_guipath.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'keybinding.gui_path' must be a string")
|
||||
);
|
||||
}
|
||||
@@ -1303,7 +1286,7 @@ TEST_CASE("(Error) Keybinding: Wrong type 'is_local'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/keybinding/wrongtype_islocal.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'keybinding.is_local' must be a boolean")
|
||||
);
|
||||
}
|
||||
@@ -1312,7 +1295,7 @@ TEST_CASE("(Error) Keybinding: Wrong type 'name'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/keybinding/wrongtype_name.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'keybinding.name' must be a string")
|
||||
);
|
||||
}
|
||||
@@ -1321,7 +1304,7 @@ TEST_CASE("(Error) Keybinding: Wrong type 'script'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/keybinding/wrongtype_script.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'keybinding.script' must be a string")
|
||||
);
|
||||
}
|
||||
@@ -1334,7 +1317,7 @@ TEST_CASE("(Error) Time: Wrong value 'type'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/time/wrongvalue_type.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) Unknown time type")
|
||||
);
|
||||
}
|
||||
@@ -1343,7 +1326,7 @@ TEST_CASE("(Error) Time (absolute): Missing value 'type'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/time/missing_type.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'time.type' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1352,7 +1335,7 @@ TEST_CASE("(Error) Time (relative): Missing value 'value'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/time/relative_missing_value.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'time.value' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1364,7 +1347,7 @@ TEST_CASE("(Error) Deltatimes: Wrong type", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/deltatimes/wrongtype_value.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::ContainsSubstring("type must be number, but is string")
|
||||
);
|
||||
}
|
||||
@@ -1376,7 +1359,7 @@ TEST_CASE("(Error) Camera: Wrong value 'type'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/wrongvalue_type.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) Unknown camera type")
|
||||
);
|
||||
}
|
||||
@@ -1385,7 +1368,7 @@ TEST_CASE("(Error) Camera (NavState): Missing value 'anchor'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_missing_anchor.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.anchor' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1394,7 +1377,7 @@ TEST_CASE("(Error) Camera (NavState): Missing value 'frame'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_missing_frame.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.frame' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1403,7 +1386,7 @@ TEST_CASE("(Error) Camera (NavState): Missing value 'position'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_missing_position.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.position' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1412,7 +1395,7 @@ TEST_CASE("(Error) Camera (NavState): Wrong type 'anchor'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_wrongtype_anchor.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.anchor' must be a string")
|
||||
);
|
||||
}
|
||||
@@ -1421,7 +1404,7 @@ TEST_CASE("(Error) Camera (NavState): Wrong type 'aim'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_wrongtype_aim.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.aim' must be a string")
|
||||
);
|
||||
}
|
||||
@@ -1430,7 +1413,7 @@ TEST_CASE("(Error) Camera (NavState): Wrong type 'frame'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_wrongtype_frame.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.frame' must be a string")
|
||||
);
|
||||
}
|
||||
@@ -1439,7 +1422,7 @@ TEST_CASE("(Error) Camera (NavState): Wrong type 'position'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_wrongtype_position.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.position' must be an object")
|
||||
);
|
||||
}
|
||||
@@ -1448,7 +1431,7 @@ TEST_CASE("(Error) Camera (NavState): Missing value 'position.x'", "[profile]")
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_missing_position_x.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.position.x' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1457,7 +1440,7 @@ TEST_CASE("(Error) Camera (NavState): Wrong type 'position.x'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_wrongtype_position_x.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.position.x' must be a number")
|
||||
);
|
||||
}
|
||||
@@ -1466,7 +1449,7 @@ TEST_CASE("(Error) Camera (NavState): Missing value 'position.y'", "[profile]")
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_missing_position_y.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.position.y' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1475,7 +1458,7 @@ TEST_CASE("(Error) Camera (NavState): Wrong type 'position.y'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_wrongtype_position_y.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.position.y' must be a number")
|
||||
);
|
||||
}
|
||||
@@ -1484,7 +1467,7 @@ TEST_CASE("(Error) Camera (NavState): Missing value 'position.z'", "[profile]")
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_missing_position_z.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.position.z' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1493,7 +1476,7 @@ TEST_CASE("(Error) Camera (NavState): Wrong type 'position.z'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_wrongtype_position_z.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.position.z' must be a number")
|
||||
);
|
||||
}
|
||||
@@ -1502,7 +1485,7 @@ TEST_CASE("(Error) Camera (NavState): Wrong type 'up'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_wrongtype_up.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.up' must be an object")
|
||||
);
|
||||
}
|
||||
@@ -1511,7 +1494,7 @@ TEST_CASE("(Error) Camera (NavState): Missing value 'up.x'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_missing_up_x.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.up.x' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1520,7 +1503,7 @@ TEST_CASE("(Error) Camera (NavState): Wrong type 'up.x'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_wrongtype_up_x.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.up.x' must be a number")
|
||||
);
|
||||
}
|
||||
@@ -1529,7 +1512,7 @@ TEST_CASE("(Error) Camera (NavState): Missing value 'up.y'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_missing_up_y.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.up.y' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1538,7 +1521,7 @@ TEST_CASE("(Error) Camera (NavState): Wrong type 'up.y'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_wrongtype_up_y.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.up.y' must be a number")
|
||||
);
|
||||
}
|
||||
@@ -1547,7 +1530,7 @@ TEST_CASE("(Error) Camera (NavState): Missing value 'up.z'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_missing_up_z.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.up.z' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1556,7 +1539,7 @@ TEST_CASE("(Error) Camera (NavState): Wrong type 'up.z'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_wrongtype_up_z.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.up.z' must be a number")
|
||||
);
|
||||
}
|
||||
@@ -1565,7 +1548,7 @@ TEST_CASE("(Error) Camera (NavState): Wrong type 'yaw'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_wrongtype_yaw.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.yaw' must be a number")
|
||||
);
|
||||
}
|
||||
@@ -1574,7 +1557,7 @@ TEST_CASE("(Error) Camera (NavState): Wrong type 'pitch'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/navstate_wrongtype_pitch.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.pitch' must be a number")
|
||||
);
|
||||
}
|
||||
@@ -1583,7 +1566,7 @@ TEST_CASE("(Error) Camera (GoToGeo): Missing value 'anchor'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/gotogeo_missing_anchor.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.anchor' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1592,7 +1575,7 @@ TEST_CASE("(Error) Camera (GoToGeo): Missing value 'latitude'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/gotogeo_missing_latitude.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.latitude' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1601,7 +1584,7 @@ TEST_CASE("(Error) Camera (GoToGeo): Missing value 'longitude'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/gotogeo_missing_longitude.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.longitude' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1610,7 +1593,7 @@ TEST_CASE("(Error) Camera (GoToGeo): Wrong type 'anchor'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/gotogeo_wrongtype_anchor.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.anchor' must be a string")
|
||||
);
|
||||
}
|
||||
@@ -1619,7 +1602,7 @@ TEST_CASE("(Error) Camera (GoToGeo): Wrong type 'latitude'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/gotogeo_wrongtype_latitude.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.latitude' must be a number")
|
||||
);
|
||||
}
|
||||
@@ -1628,7 +1611,7 @@ TEST_CASE("(Error) Camera (GoToGeo): Wrong type 'longitude'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/gotogeo_wrongtype_longitude.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.longitude' must be a number")
|
||||
);
|
||||
}
|
||||
@@ -1637,7 +1620,7 @@ TEST_CASE("(Error) Camera (GoToGeo): Wrong type 'altitude'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/gotogeo_wrongtype_altitude.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.altitude' must be a number")
|
||||
);
|
||||
}
|
||||
@@ -1646,7 +1629,7 @@ TEST_CASE("(Error) Camera (GoToNode): Wrong type 'anchor'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/gotonode_wrongtype_anchor.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.anchor' must be a string")
|
||||
);
|
||||
}
|
||||
@@ -1655,7 +1638,7 @@ TEST_CASE("(Error) Camera (GoToNode): Wrong type 'height'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/gotonode_wrongtype_height.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.height' must be a number")
|
||||
);
|
||||
}
|
||||
@@ -1664,7 +1647,7 @@ TEST_CASE("(Error) Camera (GoToNode): Missing value 'anchor'", "[profile]") {
|
||||
constexpr std::string_view TestFile =
|
||||
"${TESTDIR}/profile/error/camera/gotonode_missing_anchor.profile";
|
||||
CHECK_THROWS_WITH(
|
||||
loadProfile(absPath(TestFile)),
|
||||
Profile(absPath(TestFile)),
|
||||
Catch::Matchers::Equals("(profile) 'camera.anchor' field is missing")
|
||||
);
|
||||
}
|
||||
@@ -1677,7 +1660,7 @@ TEST_CASE("(Error) Camera (GoToNode): Missing value 'anchor'", "[profile]") {
|
||||
// constexpr std::string_view TestFile =
|
||||
// "${TESTDIR}/profile/error/camera/gotonode_invalidvalue_negative_height.profile";
|
||||
// CHECK_THROWS_WITH(
|
||||
// loadProfile(absPath(TestFile)),
|
||||
// Profile(absPath(TestFile)),
|
||||
// Catch::Matchers::Equals("(profile) 'camera.height' must be a larger than zero")
|
||||
// );
|
||||
//}
|
||||
@@ -1686,7 +1669,7 @@ TEST_CASE("(Error) Camera (GoToNode): Missing value 'anchor'", "[profile]") {
|
||||
// constexpr std::string_view TestFile =
|
||||
// "${TESTDIR}/profile/error/camera/gotonode_invalidvalue_zero_height.profile";
|
||||
// CHECK_THROWS_WITH(
|
||||
// loadProfile(absPath(TestFile)),
|
||||
// Profile(absPath(TestFile)),
|
||||
// Catch::Matchers::Equals("(profile) 'camera.height' must be a larger than zero")
|
||||
// );
|
||||
//}
|
||||
|
||||
12
tests/visual/eclipse/earth1966.ostest
Normal file
12
tests/visual/eclipse/earth1966.ostest
Normal file
@@ -0,0 +1,12 @@
|
||||
[
|
||||
{ "type": "pause",
|
||||
"value": "true"},
|
||||
{ "type": "time",
|
||||
"value": "1966-11-12T14:28:39.00"},
|
||||
{ "type": "navigationstate",
|
||||
"value": "{Anchor='Earth',Position={8117064.770626424,-15651002.199110571,-9165703.435119975},Up={-0.39241745239503034,-0.6078072727788707,0.6903469143937023}"},
|
||||
{ "type": "wait",
|
||||
"value": "30"},
|
||||
{ "type": "screenshot",
|
||||
"value": ""}
|
||||
]
|
||||
Reference in New Issue
Block a user