diff --git a/.gitmodules b/.gitmodules index d08e0ad1..21f2c5f3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -8,12 +8,6 @@ [submodule "third_party/Qt-Advanced-Docking-System"] path = third_party/Qt-Advanced-Docking-System url = https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git -[submodule "third_party/ramses-logic"] - path = third_party/ramses-logic - url = https://github.com/GENIVI/ramses-logic.git -[submodule "third_party/glm"] - path = third_party/glm - url = https://github.com/g-truc/glm.git [submodule "third_party/tinygltf"] path = third_party/tinygltf url = https://github.com/syoyo/tinygltf.git @@ -24,3 +18,9 @@ [submodule "third_party/zip"] path = third_party/zip url = https://github.com/kuba--/zip +[submodule "third_party/ramses"] + path = third_party/ramses + url = https://github.com/bmwcarit/ramses.git +[submodule "third_party/boost"] + path = third_party/boost + url = https://github.com/boostorg/boost.git diff --git a/CHANGELOG.md b/CHANGELOG.md index 8446ff85..bd7daa9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,62 @@ If a copy of the MPL was not distributed with this file, You can obtain one at h --> +## [2.0.0] Switch to Ramses 28, Abstract Scene View, Misc UI Iprovements and Bugfixes +* **This is a major version upgrade for both RamsesComposer and Ramses/LogicEngine containing changes that can break existing scenes.** +* **File version number has changed. Files saved with RaCo 2.0.0 cannot be opened by previous versions.** +* **Update from Ramses-Logic 1.4.2 and Ramses 27.0.130 to Ramses 28.0.0. The LogicEngine has been merged into Ramses.** +* **Scenes exported with RaCo 2.0.0 can't be loaded with Ramses versions prior to 28.0.0.** +* **Export will only write a single file containing both Ramses and LogicEngine objects.** +* **The feature level will start counting up from 1 in RaCo 2.0.0 and Ramses 28.0.0 again. The RaCo 2.0.0 feature level 1 does include all features from any feature level in RaCo <2.0.0 or Ramses 27.0.130 though. This implies that scenes of any feature level saved with RaCo <2.0.0 are automatically upgraded and all previously available features will be enabled upon loading.** +* **RamsesComposer now requires Ubuntu 20.04 and gcc 9.4.0 instead of Ubuntu 18.04 and gcc 8.4.0 to build.** + +### Breaking Changes + +The following changes can break existing scenes upon loading +* Bool uniforms are now represented by `bool` instead of `int32` properties in `Materials`. Due to the change in the property type the property value will be lost. In addition links ending on bool uniform properties will break. +* Module statements in `LuaInterface` objects are never ignored anymore. They were ignored at feature levels <5 in Raco <2.0.0. See also changes for v.1.6.0. + +The following changes may break python scripts processing a scene but existing scenes will be migrated automatically when loading them +* Conversion of the fixed number of `layer` properties in the `RenderPass` and `buffer` and `bufferMS` properties in the `RenderTarget` into array-type containers. Breaking python scripts due to the changes in the property names. +* Conversion of the `targets` and `joints` properties in the `Skin` and `animationChannels` in the `Animation` to array-type properties. Breaking python scripts due to the changes in the property names. +* The newly introduced array-type properties mentioned above have the indices starting at 1 as property names as for the `LuaScript` array-type properties. +* Split the `RenderTarget` type into separate `RenderTarget` and `RenderTargetMS` types with only a single `buffers` array-type property which can contain only `RenderBuffer`s or `RenderBufferMS`s. +* Introduced generic meta data scheme. + * The meta data is now stored in a new `metadata` property. + * Each category of meta data has a named container property inside the `metadata` property and can be accessed from the Python API like any other property. + * The gltfExtras meta data is now stored in the `gltfExtras` category inside the `metadata` container. The Python API `metadata` function has been removed. +* Removed the `userTags` property from the `ProjectSettings` object. +* The `logic_path` parameter was removed from the `export` function in the Python API. + + +### Added +* Added abstract scene view which shows a 3d representation of all objects in the scene in world space. This has a separate camera which can be moved around freely and also allows to manipulate the transformation proerties of objects using the mouse and/or the keyboard. +* Added button in property browser to show objects referencing the current object. +* Added prefab lookup button to the property browser. +* Added texture preview in the property browser. +* Added controls to allow the resizing of array-of-reference properties. This applies to the `animationChannels` property in `Animation`, the `layer` property in `RenderPass`, the `buffers` property in `RenderTarget` and `RenderTargetMS`, and the `targets` property in `Skin` objects. +* Added `resize` property member function to the Python API to resize array-type properties. +* Added composite commands to the Python API which generate only a single undo stack entry. See Python API reference for details. +* Added shortcuts for the mostly used functions. +* Added warning when an opened RCA file is changed externally. +* Added dialog to copy the content of scalar read-only properties into the clipboard as plain text. + +### Changes +* After starting a new instance of RaCo with "Load external project" via the context menu of an object, that object will be automatically selected in the new instance. +* Object filtering in the tree views now can be done using complex boolean expressions. The search syntax is described in the `User interface overview` section of the `Introduction` chapter in the documentation. + +### Fixes +* Prevent crash when opening invalid or broken project files and show an error dialog instead. +* Fixed crash caused by a tabbed away Preview Window when closing RaCo. +* Fixed crash when the folder of the currently loaded project is deleted. +* Prevent directories from being added as external projects when calling the `addExternalProject` Python API function with a directory as argument. +* Export of `Nodes` with `enabled`=false and `visibilty`=true is now correct. +* Fixed generation of multiple undo stack entries when a property inside a `Prefab` is changed multiple times. The undo stack entries are now merged as for properties outside `Prefabs`. +* Fixed update of partially linked array uniform properties to avoid discarding the non-linked property values during updates. +* Prevent user from taking screenshots when multisampling factor is greater than zero. +* Add manual update (refresh) button to the preview which will reset the preview itself and all offscreen buffers and rerender the scene. + + ## [1.10.0] Multiedit, Shader Includes, Drag-and-drop Support, Misc Usability Improvements and Bugfixes ### Added diff --git a/CMakeGraphVizOptions.cmake b/CMakeGraphVizOptions.cmake index 14008f4a..2397feb3 100644 --- a/CMakeGraphVizOptions.cmake +++ b/CMakeGraphVizOptions.cmake @@ -1,3 +1,3 @@ -set(GRAPHVIZ_IGNORE_TARGETS "^.+test$" "Qt5" "absl_.*" "^ramses-" "platform-" fmt lz4 psapi flatbuffers lua sol2 "rlogic-" imgui flatc "gtest_" "gmock" "harfbuzz" "Surface_" "Context_" "Window_" "Device_" opengl32 qtadvanceddocking AdvancedDockingSystemDemo CentralWidgetExample DeleteOnCloseTest EmptyDockAreaExample SidebarExample SimpleExample benchmark_main freetype "-ignore" lzma "spdlog" "Threads::Threads" zlibstatic assimp openctm libLodepng) +set(GRAPHVIZ_IGNORE_TARGETS "^.+test$" "Qt5" "absl_.*" "^ramses-" "platform-" fmt lz4 psapi flatbuffers lua sol2 zip "rlogic-" imgui flatc "gtest_" "gmock" "harfbuzz" "Surface_" "Context_" "Window_" "Device_" opengl32 qtadvanceddocking AdvancedDockingSystemDemo CentralWidgetExample DeleteOnCloseTest EmptyDockAreaExample SidebarExample SimpleExample benchmark_main freetype "-ignore" lzma "spdlog" "Threads::Threads" zlibstatic assimp openctm libLodepng "boost_" "test_" lodepng cityhash ProjectConfig synchronization Platform test-asset-producer "absl::" "pybind11::" pybind11_headers FlatBuffers CLI11 Python::Python tinygltf glm) set(GRAPHVIZ_GENERATE_PER_TARGET FALSE) set(GRAPHVIZ_GENERATE_DEPENDERS FALSE) diff --git a/CMakeLists.txt b/CMakeLists.txt index 17c22c9e..791866fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ cmake_minimum_required(VERSION 3.19) SET(CMAKE_CONFIGURATION_TYPES "Debug;RelWithDebInfo") -project(RaCoOS VERSION 1.10.0) +project(RaCoOS VERSION 2.0.0) SET(RACO_RELEASE_DIRECTORY ${CMAKE_BINARY_DIR}/release) @@ -196,11 +196,10 @@ macro(deploy_dlls_and_strip_symbols exetarget dlltarget outdir) endmacro() macro(deploy_ramses_client_only_shared_dlls tgt outdir) deploy_dlls_and_strip_symbols(${tgt} raco::ramses-lib-client-only "${outdir}") - deploy_dlls_and_strip_symbols(${tgt} raco::ramses-logic-lib-client-only "${outdir}") endmacro() macro(deploy_ramses_with_renderer_shared_dlls tgt) + deploy_dlls_and_strip_symbols(${tgt} raco::ramses-lib-client-only "$") deploy_dlls_and_strip_symbols(${tgt} raco::ramses-lib "$") - deploy_dlls_and_strip_symbols(${tgt} raco::ramses-logic-lib "$") endmacro() macro(deploy_headless_shared_dlls tgt) deploy_dlls_and_strip_symbols(${tgt} openctm "$") @@ -210,7 +209,7 @@ macro(deploy_gui_shared_dlls tgt) deploy_dlls_and_strip_symbols(${tgt} qtadvanceddocking "$") endmacro() macro(deploy_viewer tgt) - deploy_dlls_and_strip_symbols(${tgt} ramses-logic-viewer "$") + deploy_dlls_and_strip_symbols(${tgt} ramses-viewer "$") endmacro() macro(deploy_python_dlls tgt) IF(WIN32) @@ -229,10 +228,6 @@ if(PACKAGE_TESTS) enable_testing() include(GoogleTest) set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) # needed to build on Windows - set(raco_test_resources_base_path "${CMAKE_CURRENT_SOURCE_DIR}/resources") - #if (WINDOWS) - #string(REPLACE "/" "\\\\" raco_test_resources_base_path "${raco_test_resources_base_path}") - #endif() add_subdirectory(third_party/googletest) # See https://cmake.org/cmake/help/v3.10/module/GoogleTest.html @@ -257,7 +252,7 @@ if(PACKAGE_TESTS) DISCOVERY_MODE PRE_TEST ) set_target_properties(${TESTNAME} PROPERTIES FOLDER tests) - target_compile_definitions(${TESTNAME} PRIVATE -DRACO_TEST_RESOURCES_BASE_PATH="${raco_test_resources_base_path}") + target_compile_definitions(${TESTNAME} PRIVATE DEFAULT_RESOURCES_DIRECTORY="${RACO_RELEASE_DIRECTORY}/projects") # TODO: Working directory for tests (should be also config specific), required for tests which modify files endmacro() macro(raco_package_add_qt_test TESTNAME FILES LIBRARIES TEST_WORKING_DIRECTORY) @@ -277,13 +272,11 @@ if(PACKAGE_TESTS) endmacro() macro(raco_package_add_headless_test TESTNAME FILES LIBRARIES TEST_WORKING_DIRECTORY) raco_package_add_qt_test(${TESTNAME} "${FILES}" "${LIBRARIES}" "${TEST_WORKING_DIRECTORY}") - target_link_libraries(${TESTNAME} raco::ramses-logic-lib-client-only) deploy_headless_shared_dlls(${TESTNAME}) deploy_ramses_client_only_shared_dlls(${TESTNAME} "$") endmacro() macro(raco_package_add_gui_test TESTNAME FILES LIBRARIES TEST_WORKING_DIRECTORY) raco_package_add_qt_test(${TESTNAME} "${FILES}" "${LIBRARIES}" "${TEST_WORKING_DIRECTORY}") - target_link_libraries(${TESTNAME} raco::ramses-lib raco::ramses-logic-lib) deploy_gui_shared_dlls(${TESTNAME}) deploy_ramses_with_renderer_shared_dlls(${TESTNAME} "$") endmacro() diff --git a/EditorApp/CMakeLists.txt b/EditorApp/CMakeLists.txt index eb4532e0..ae02469e 100644 --- a/EditorApp/CMakeLists.txt +++ b/EditorApp/CMakeLists.txt @@ -35,7 +35,6 @@ add_executable(RaCoEditor WIN32 ${SOURCES} ${APP_ICON_RESOURCE_WINDOWS}) target_compile_definitions( RaCoEditor PUBLIC -DRACO_OSS_COMMIT="sha1 ${RAMSES_OSS_COMMIT_HASH}" ) target_compile_definitions( RaCoEditor PUBLIC -DRACO_OSS_VERSION="${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") target_compile_definitions( RaCoEditor PUBLIC -DRAMSES_VERSION="${RAMSES_VERSION_MAJOR}.${RAMSES_VERSION_MINOR}.${RAMSES_VERSION_PATCH}" ) -target_compile_definitions( RaCoEditor PUBLIC -DRLOGIC_VERSION="${RLOGIC_VERSION_MAJOR}.${RLOGIC_VERSION_MINOR}.${RLOGIC_VERSION_PATCH}" ) enable_warnings_as_errors(RaCoEditor) set_target_properties(RaCoEditor PROPERTIES OUTPUT_NAME "RamsesComposer" RUNTIME_OUTPUT_DIRECTORY "${RACO_RELEASE_DIRECTORY}/bin/$") @@ -70,6 +69,7 @@ PUBLIC Qt5::Widgets qtadvanceddocking raco::PythonAPI + raco::ApplicationLib raco::RamsesWidgets PRIVATE raco::pybind11 diff --git a/EditorApp/OpenRecentMenu.cpp b/EditorApp/OpenRecentMenu.cpp index 9e34870f..ce835ed2 100644 --- a/EditorApp/OpenRecentMenu.cpp +++ b/EditorApp/OpenRecentMenu.cpp @@ -15,6 +15,8 @@ #include #include +using namespace raco; + OpenRecentMenu::OpenRecentMenu(QWidget* parent) : QMenu{"Open &Recent", parent} { QObject::connect(this, &QMenu::aboutToShow, this, [this]() { refreshRecentFileMenu(); @@ -23,7 +25,7 @@ OpenRecentMenu::OpenRecentMenu(QWidget* parent) : QMenu{"Open &Recent", parent} void OpenRecentMenu::addRecentFile(const QString& file) { if (file.size()) { - auto recentFilesStore = raco::core::PathManager::recentFilesStoreSettings(); + auto recentFilesStore = core::PathManager::recentFilesStoreSettings(); QStringList recentFiles{recentFilesStore.value("recent_files").toStringList()}; auto it = std::find(recentFiles.begin(), recentFiles.end(), file); if (it != recentFiles.end()) { @@ -39,7 +41,7 @@ void OpenRecentMenu::addRecentFile(const QString& file) { recentFilesStore.sync(); if (recentFilesStore.status() != QSettings::NoError) { - LOG_ERROR(raco::log_system::COMMON, "Saving recent files list failed: {}", raco::core::PathManager::recentFilesStorePath().string()); + LOG_ERROR(log_system::COMMON, "Saving recent files list failed: {}", core::PathManager::recentFilesStorePath().string()); } } } @@ -61,7 +63,7 @@ bool isOneDriveIniFile(std::filesystem::path path) { } // Check whether specified path is on OneDrive. -bool isOneDrivePath(raco::utils::u8path path) { +bool isOneDrivePath(utils::u8path path) { auto onedriveIniFilename = "desktop.ini"; auto fsPath = std::filesystem::path(path.internalPath()); @@ -90,7 +92,7 @@ bool isOneDrivePath(raco::utils::u8path path) { std::filesystem::path foundPath(*itFound); if (isOneDriveIniFile(foundPath)) { - LOG_INFO(raco::log_system::COMMON, "OneDrive root found at: {}", foundPath.string()); + LOG_INFO(log_system::COMMON, "OneDrive root found at: {}", foundPath.string()); return true; } } @@ -103,7 +105,7 @@ bool isOneDrivePath(raco::utils::u8path path) { } void OpenRecentMenu::refreshRecentFileMenu() { - auto recentFilesStore = raco::core::PathManager::recentFilesStoreSettings(); + auto recentFilesStore = core::PathManager::recentFilesStoreSettings(); QStringList recentFiles{recentFilesStore.value("recent_files").toStringList()}; setDisabled(recentFiles.size() == 0); while (actions().size() > 0) { @@ -116,13 +118,13 @@ void OpenRecentMenu::refreshRecentFileMenu() { auto* action = addAction(actionText); auto fileString = file.toStdString(); - if (!raco::utils::u8path(fileString).exists()) { + if (!utils::u8path(fileString).exists()) { action->setEnabled(false); action->setText(actionText + " (unavailable)"); - } else if (isOneDrivePath(raco::utils::u8path(fileString))) { + } else if (isOneDrivePath(utils::u8path(fileString))) { // Not touching cloud file to prevent its download. action->setText(actionText + " (OneDrive)"); - } else if (!raco::utils::u8path(fileString).userHasReadAccess()) { + } else if (!utils::u8path(fileString).userHasReadAccess()) { action->setEnabled(false); action->setText(actionText + " (no read access)"); } diff --git a/EditorApp/main.cpp b/EditorApp/main.cpp index a0681fbe..01a3bc11 100644 --- a/EditorApp/main.cpp +++ b/EditorApp/main.cpp @@ -33,6 +33,8 @@ namespace py = pybind11; +using namespace raco; + void createStdOutConsole(); #ifdef _WIN32 @@ -72,11 +74,6 @@ int main(int argc, char* argv[]) { QStringList() << "c" << "console", "Open with std out console."); - QCommandLineOption forwardCommandLineArgs( - QStringList() << "a" - << "framework-arguments", - "Override arguments passed to the ramses framework.", - "default-args"); QCommandLineOption noDumpFileCheckOption( QStringList() << "d" << "nodump", @@ -86,6 +83,11 @@ int main(int argc, char* argv[]) { << "project", "Load a scene from specified path.", "project-path"); + QCommandLineOption objectId( + QStringList() << "i" + << "objectid", + "Select object with the given ID immediately after start.", + "object-id"); QCommandLineOption ramsesTraceLogMessageAction( QStringList() << "t" << "trace-messages-ramses", @@ -93,9 +95,9 @@ int main(int argc, char* argv[]) { QCommandLineOption ramsesLogicFeatureLevel( QStringList() << "f" << "featurelevel", - fmt::format("RamsesLogic feature level (-1, {} ... {})", static_cast(raco::ramses_base::BaseEngineBackend::minFeatureLevel), static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel)).c_str(), + fmt::format("RamsesLogic feature level (-1, {} ... {})", static_cast(ramses_base::BaseEngineBackend::minFeatureLevel), static_cast(ramses_base::BaseEngineBackend::maxFeatureLevel)).c_str(), "feature-level", - QString::fromStdString(std::to_string(static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel)))); + QString::fromStdString(std::to_string(static_cast(ramses_base::BaseEngineBackend::maxFeatureLevel)))); QCommandLineOption pyrunOption( QStringList() << "r" << "run", @@ -108,16 +110,18 @@ int main(int argc, char* argv[]) { "python-path"); parser.addOption(consoleOption); - parser.addOption(forwardCommandLineArgs); parser.addOption(noDumpFileCheckOption); parser.addOption(loadProjectAction); + parser.addOption(objectId); parser.addOption(ramsesTraceLogMessageAction); parser.addOption(ramsesLogicFeatureLevel); parser.addOption(pyrunOption); parser.addOption(pythonPathOption); + ramses_base::addRamseFrameworkOptions(parser); + // apply global style, must be done before application instance - QApplication::setStyle(new raco::style::RaCoStyle()); + QApplication::setStyle(new style::RaCoStyle()); // application must be instantiated before parsing command line QApplication a(argc, argv); @@ -147,15 +151,15 @@ int main(int argc, char* argv[]) { parser.process(args); bool noDumpFiles = parser.isSet(noDumpFileCheckOption); - raco::utils::crashdump::installCrashDumpHandler(noDumpFiles); + utils::crashdump::installCrashDumpHandler(noDumpFiles); if (parser.isSet(consoleOption)) { createStdOutConsole(); } - auto appDataPath = raco::utils::u8path(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation).toStdString()).parent_path() / "RamsesComposer"; - raco::core::PathManager::init(QCoreApplication::applicationDirPath().toStdString(), appDataPath); - raco::log_system::init(raco::core::PathManager::logFileDirectory(), std::string(raco::core::PathManager::LOG_FILE_EDITOR_BASE_NAME), QCoreApplication::applicationPid()); + auto appDataPath = utils::u8path(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation).toStdString()).parent_path() / "RamsesComposer"; + core::PathManager::init(QCoreApplication::applicationDirPath().toStdString(), appDataPath); + log_system::init(core::PathManager::logFileDirectory(), std::string(core::PathManager::LOG_FILE_EDITOR_BASE_NAME), QCoreApplication::applicationPid()); const QStringList positionalArgs = parser.positionalArguments(); @@ -168,16 +172,21 @@ int main(int argc, char* argv[]) { projectFile = QFileInfo(positionalArgs.at(0)).absoluteFilePath(); } + QString objectToFocusId{}; + if (parser.isSet(objectId)) { + objectToFocusId = parser.value(objectId); + } + int initialLoadFeatureLevel = -1; - raco::components::RaCoPreferences::init(); - int newFileFeatureLevel = std::min(raco::components::RaCoPreferences::instance().featureLevel, static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel)); + components::RaCoPreferences::init(); + int newFileFeatureLevel = std::min(components::RaCoPreferences::instance().featureLevel, static_cast(ramses_base::BaseEngineBackend::maxFeatureLevel)); if (parser.isSet(ramsesLogicFeatureLevel)) { initialLoadFeatureLevel = parser.value(ramsesLogicFeatureLevel).toInt(); if (!(initialLoadFeatureLevel == -1 || - initialLoadFeatureLevel >= static_cast(raco::ramses_base::BaseEngineBackend::minFeatureLevel) && - initialLoadFeatureLevel <= static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel))) { - LOG_ERROR(raco::log_system::COMMON, fmt::format("RamsesLogic feature level {} outside valid range (-1, {} ... {})", initialLoadFeatureLevel, static_cast(raco::ramses_base::BaseEngineBackend::minFeatureLevel), static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel))); + initialLoadFeatureLevel >= static_cast(ramses_base::BaseEngineBackend::minFeatureLevel) && + initialLoadFeatureLevel <= static_cast(ramses_base::BaseEngineBackend::maxFeatureLevel))) { + LOG_ERROR(log_system::COMMON, fmt::format("RamsesLogic feature level {} outside valid range (-1, {} ... {})", initialLoadFeatureLevel, static_cast(ramses_base::BaseEngineBackend::minFeatureLevel), static_cast(ramses_base::BaseEngineBackend::maxFeatureLevel))); exit(1); } } @@ -186,13 +195,13 @@ int main(int argc, char* argv[]) { if (parser.isSet(pyrunOption)) { QFileInfo path(parser.value(pyrunOption)); if (path.exists()) { - if (raco::utils::u8path(path.filePath().toStdString()).userHasReadAccess()) { + if (utils::u8path(path.filePath().toStdString()).userHasReadAccess()) { pythonScriptPath = path.absoluteFilePath(); } else { - LOG_ERROR(raco::log_system::PYTHON, "Python script file could not be read {}", path.filePath().toStdString()); + LOG_ERROR(log_system::PYTHON, "Python script file could not be read {}", path.filePath().toStdString()); } } else { - LOG_ERROR(raco::log_system::PYTHON, "Python script file not found {}", path.filePath().toStdString()); + LOG_ERROR(log_system::PYTHON, "Python script file not found {}", path.filePath().toStdString()); } } @@ -202,24 +211,27 @@ int main(int argc, char* argv[]) { } // set font, must be done after application instance - raco::style::RaCoStyle::installFont(); + style::RaCoStyle::installFont(); - auto ramsesCommandLineArgs = parser.value(forwardCommandLineArgs).toStdString(); - int initialFeatureLevel = initialLoadFeatureLevel == -1 ? static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel) : initialLoadFeatureLevel; - raco::ramses_widgets::RendererBackend rendererBackend{static_cast(initialFeatureLevel), parser.isSet(forwardCommandLineArgs) ? ramsesCommandLineArgs : ""}; + ramses::RamsesFrameworkConfig ramsesConfig(ramses_base::BaseEngineBackend::defaultRamsesFrameworkConfig()); + for (auto category : ramses_base::ramsesLogCategories()) { + ramsesConfig.setLogLevel(category.toStdString(), ramses_base::getRamsesLogLevelFromArg(parser.value(category))); + } + + ramses_widgets::RendererBackend rendererBackend(ramsesConfig); std::unique_ptr app; try { app = std::make_unique(rendererBackend, raco::application::RaCoApplicationLaunchSettings(projectFile, true, parser.isSet(ramsesTraceLogMessageAction), newFileFeatureLevel, initialLoadFeatureLevel, true)); } catch (const raco::application::FutureFileVersion& error) { - LOG_ERROR(raco::log_system::COMMON, "File load error: project file was created with newer file version {} but current file version is {}.", error.fileVersion_, raco::serialization::RAMSES_PROJECT_FILE_VERSION); + LOG_ERROR(log_system::COMMON, "File load error: project file was created with newer file version {} but current file version is {}.", error.fileVersion_, serialization::RAMSES_PROJECT_FILE_VERSION); app.reset(); - } catch (const raco::core::ExtrefError& error) { - LOG_ERROR(raco::log_system::COMMON, "File Load Error: external reference update failed with error {}.", error.what()); + } catch (const core::ExtrefError& error) { + LOG_ERROR(log_system::COMMON, "File Load Error: external reference update failed with error {}.", error.what()); app.reset(); } catch (const std::exception& error) { - LOG_ERROR(raco::log_system::COMMON, "File Load Error: {}", error.what()); + LOG_ERROR(log_system::COMMON, "File Load Error: {}", error.what()); app.reset(); } @@ -230,6 +242,9 @@ int main(int argc, char* argv[]) { } MainWindow w{app.get(), &rendererBackend, wPythonSearchPaths}; + if (!objectToFocusId.isEmpty()) { + w.Q_EMIT focusRequestedForTreeDock(objectToFocusId, ""); + } if (!pythonScriptPath.isEmpty()) { auto pythonScriptPathStr = pythonScriptPath.toStdString(); @@ -239,11 +254,11 @@ int main(int argc, char* argv[]) { pos_argv_cp.emplace_back(s.c_str()); } - auto currentRunStatus = raco::python_api::runPythonScript(app.get(), QCoreApplication::applicationFilePath().toStdWString(), pythonScriptPath.toStdString(), wPythonSearchPaths, pos_argv_cp); - LOG_INFO(raco::log_system::PYTHON, currentRunStatus.stdOutBuffer); + auto currentRunStatus = python_api::runPythonScript(app.get(), QCoreApplication::applicationFilePath().toStdWString(), pythonScriptPath.toStdString(), wPythonSearchPaths, pos_argv_cp); + LOG_INFO(log_system::PYTHON, currentRunStatus.stdOutBuffer); if (!currentRunStatus.stdErrBuffer.empty()) { - LOG_ERROR(raco::log_system::PYTHON, currentRunStatus.stdErrBuffer); + LOG_ERROR(log_system::PYTHON, currentRunStatus.stdErrBuffer); } } diff --git a/EditorApp/mainwindow.cpp b/EditorApp/mainwindow.cpp index 67b18ff5..4e5db100 100644 --- a/EditorApp/mainwindow.cpp +++ b/EditorApp/mainwindow.cpp @@ -35,16 +35,16 @@ #include "log_system/log.h" #include "object_tree_view/ObjectTreeDock.h" #include "object_tree_view/ObjectTreeView.h" -#include "object_tree_view_model/ObjectTreeViewDefaultModel.h" -#include "object_tree_view_model/ObjectTreeViewExternalProjectModel.h" #include "object_tree_view_model/ObjectTreeViewPrefabModel.h" #include "object_tree_view_model/ObjectTreeViewResourceModel.h" -#include "object_tree_view_model/ObjectTreeViewSortProxyModels.h" +#include "object_tree_view_model/ObjectTreeViewExternalProjectModel.h" #include "property_browser/PropertyBrowserItem.h" #include "property_browser/PropertyBrowserModel.h" -#include "property_browser/PropertyBrowserWidget.h" + +#include "ramses_adaptor/AbstractSceneAdaptor.h" #include "ramses_adaptor/SceneBackend.h" #include "ramses_base/BaseEngineBackend.h" +#include "ramses_widgets/AbstractViewMainWindow.h" #include "ramses_widgets/PreviewMainWindow.h" #include "ui_mainwindow.h" @@ -98,122 +98,148 @@ static const int timerInterval60Fps = 17; +using namespace raco; using namespace raco::core; -namespace { - -using SDataChangeDispatcher = raco::components::SDataChangeDispatcher; -using SceneBackend = raco::ramses_adaptor::SceneBackend; +using SDataChangeDispatcher = components::SDataChangeDispatcher; +using SceneBackend = ramses_adaptor::SceneBackend; -RaCoDockManager* createDockManager(MainWindow* parent) { - auto* dockManager{new RaCoDockManager(parent)}; +RaCoDockManager* MainWindow::createDockManager() { + auto* dockManager{new RaCoDockManager(this)}; dockManager->setConfigFlag(RaCoDockManager::eConfigFlag::TabCloseButtonIsToolButton, true); dockManager->setStyleSheet(""); - dockManager->iconProvider().registerCustomIcon(ads::TabCloseIcon, parent->style()->standardIcon(QStyle::StandardPixmap::SP_TitleBarCloseButton)); - dockManager->iconProvider().registerCustomIcon(ads::DockAreaCloseIcon, parent->style()->standardIcon(QStyle::StandardPixmap::SP_TitleBarCloseButton)); - dockManager->iconProvider().registerCustomIcon(ads::DockAreaMenuIcon, parent->style()->standardIcon(QStyle::StandardPixmap::SP_TitleBarMenuButton)); - dockManager->iconProvider().registerCustomIcon(ads::DockAreaUndockIcon, parent->style()->standardIcon(QStyle::StandardPixmap::SP_TitleBarNormalButton)); + dockManager->iconProvider().registerCustomIcon(ads::TabCloseIcon, this->style()->standardIcon(QStyle::StandardPixmap::SP_TitleBarCloseButton)); + dockManager->iconProvider().registerCustomIcon(ads::DockAreaCloseIcon, this->style()->standardIcon(QStyle::StandardPixmap::SP_TitleBarCloseButton)); + dockManager->iconProvider().registerCustomIcon(ads::DockAreaMenuIcon, this->style()->standardIcon(QStyle::StandardPixmap::SP_TitleBarMenuButton)); + dockManager->iconProvider().registerCustomIcon(ads::DockAreaUndockIcon, this->style()->standardIcon(QStyle::StandardPixmap::SP_TitleBarNormalButton)); if (PathManager::layoutFilePath().existsFile()) { - auto settings = raco::core::PathManager::layoutSettings(); + auto settings = core::PathManager::layoutSettings(); dockManager->loadAllLayouts(settings); } - QObject::connect(dockManager, &RaCoDockManager::perspectiveListChanged, [parent, dockManager]() { - parent->updateSavedLayoutMenu(); + QObject::connect(dockManager, &RaCoDockManager::perspectiveListChanged, [this, dockManager]() { + this->updateSavedLayoutMenu(); }); return dockManager; } -ads::CDockWidget* createDockWidget(const QString& title, QWidget* parent) { +ads::CDockWidget* MainWindow::createDockWidget(const QString& title, QWidget* parent) { auto* dock = new ads::CDockWidget(title, parent); dock->setAttribute(Qt::WA_DeleteOnClose); dock->setFeature(ads::CDockWidget::DockWidgetDeleteOnClose, true); return dock; } -ads::CDockAreaWidget* createAndAddPreview(MainWindow* mainWindow, const char* dockObjName, RaCoDockManager* dockManager, raco::ramses_widgets::RendererBackend& rendererBackend, raco::application::RaCoApplication* application) { - const auto& viewport = application->activeRaCoProject().project()->settings()->viewport_; - const auto& backgroundColor = *application->activeRaCoProject().project()->settings()->backgroundColor_; - auto* previewWidget = new raco::ramses_widgets::PreviewMainWindow{rendererBackend, application->sceneBackendImpl(), {*viewport->i1_, *viewport->i2_}, application->activeRaCoProject().project(), application->dataChangeDispatcher()}; - QObject::connect(mainWindow, &MainWindow::viewportChanged, previewWidget, &raco::ramses_widgets::PreviewMainWindow::setViewport); - previewWidget->displayScene(application->sceneBackendImpl()->currentSceneId(), backgroundColor); +ads::CDockAreaWidget* MainWindow::createAndAddPreview(const char* dockObjName) { + const auto& viewport = racoApplication_->activeRaCoProject().project()->settings()->viewport_; + const auto& backgroundColor = *racoApplication_->activeRaCoProject().project()->settings()->backgroundColor_; + auto* previewWidget = new ramses_widgets::PreviewMainWindow{*rendererBackend_, racoApplication_->sceneBackendImpl(), {*viewport->i1_, *viewport->i2_}, racoApplication_->activeRaCoProject().project(), racoApplication_->dataChangeDispatcher()}; + QObject::connect(this, &MainWindow::viewportChanged, previewWidget, &ramses_widgets::PreviewMainWindow::setViewport); + previewWidget->displayScene(racoApplication_->sceneBackendImpl()->currentSceneId(), backgroundColor); previewWidget->setWindowFlags(Qt::Widget); + const auto shortcut = new QShortcut(QKeySequence(Qt::Key_F12), previewWidget, nullptr, nullptr, Qt::ApplicationShortcut); + QObject::connect(shortcut, &QShortcut::activated, [previewWidget]() { + previewWidget->saveScreenshot(); + }); + raco::gui_python_api::setupPreviewWindow(previewWidget); - auto* dock = createDockWidget(MainWindow::DockWidgetTypes::RAMSES_PREVIEW, mainWindow); + auto* dock = createDockWidget(MainWindow::DockWidgetTypes::RAMSES_PREVIEW, this); dock->setObjectName(dockObjName); dock->setWidget(previewWidget); - QObject::connect(dock, &ads::CDockWidget::closed, [mainWindow]() { - mainWindow->setNewPreviewMenuEntryEnabled(true); + QObject::connect(dock, &ads::CDockWidget::closed, [this]() { + ui->actionNewPreview->setEnabled(true); raco::gui_python_api::setupPreviewWindow(nullptr); }); - mainWindow->setNewPreviewMenuEntryEnabled(false); - return dockManager->addDockWidget(ads::CenterDockWidgetArea, dock); + ui->actionNewPreview->setEnabled(false); + return dockManager_->addDockWidget(ads::CenterDockWidgetArea, dock); } -void connectPropertyBrowserAndTreeDockManager(raco::property_browser::PropertyBrowserWidget* propertyBrowser, raco::object_tree::view::ObjectTreeDockManager& treeDockManager) { - QObject::connect(&treeDockManager, &raco::object_tree::view::ObjectTreeDockManager::newObjectTreeItemsSelected, propertyBrowser, &raco::property_browser::PropertyBrowserWidget::setObjects); - QObject::connect(&treeDockManager, &raco::object_tree::view::ObjectTreeDockManager::selectionCleared, propertyBrowser, &raco::property_browser::PropertyBrowserWidget::clear); +ads::CDockAreaWidget* MainWindow::createAndAddAbstractSceneView(const char* dockObjName) { + auto* widget = new ramses_widgets::AbstractViewMainWindow{*rendererBackend_, racoApplication_->abstractScene(), &treeDockManager_, racoApplication_->activeRaCoProject().commandInterface()}; + widget->setWindowFlags(Qt::Widget); + + QObject::connect(widget, &ramses_widgets::AbstractViewMainWindow::selectionRequested, this, &MainWindow::focusToSelection); + + QObject::connect(&treeDockManager_, &object_tree::view::ObjectTreeDockManager::newObjectTreeItemsSelected, widget, &ramses_widgets::AbstractViewMainWindow::onSelectionChanged); + QObject::connect(&treeDockManager_, &object_tree::view::ObjectTreeDockManager::selectionCleared, widget, &ramses_widgets::AbstractViewMainWindow::onSelectionCleared); + + auto* dock = createDockWidget(MainWindow::DockWidgetTypes::ABSTRACT_SCENE_VIEW, this); + dock->setObjectName(dockObjName); + dock->setWidget(widget); + QObject::connect(dock, &ads::CDockWidget::closed, [this]() { + ui->actionNewAbstractSceneView->setEnabled(true); + }); + ui->actionNewAbstractSceneView->setEnabled(false); + return dockManager_->addDockWidget(ads::CenterDockWidgetArea, dock); } -ads::CDockAreaWidget* createAndAddPropertyBrowser(MainWindow* mainWindow, const char* dockObjName, RaCoDockManager* dockManager, raco::object_tree::view::ObjectTreeDockManager& treeDockManager, raco::application::RaCoApplication* application) { - auto propertyBrowser = new raco::property_browser::PropertyBrowserWidget(application->dataChangeDispatcher(), application->activeRaCoProject().commandInterface(), application->sceneBackendImpl(), &treeDockManager, mainWindow); - QObject::connect(propertyBrowser->model(), &raco::property_browser::PropertyBrowserModel::objectSelectionRequested, mainWindow, &MainWindow::focusToObject); - QObject::connect(mainWindow, &MainWindow::objectFocusRequestedForPropertyBrowser, propertyBrowser, &raco::property_browser::PropertyBrowserWidget::setObjectFromObjectId); - connectPropertyBrowserAndTreeDockManager(propertyBrowser, treeDockManager); - auto* dockWidget = createDockWidget(MainWindow::DockWidgetTypes::PROPERTY_BROWSER, mainWindow); +ads::CDockAreaWidget* MainWindow::createAndAddPropertyBrowser(const char* dockObjName) { + auto propertyBrowser = new property_browser::PropertyBrowserWidget(racoApplication_->dataChangeDispatcher(), racoApplication_->activeRaCoProject().commandInterface(), racoApplication_->sceneBackendImpl(), &treeDockManager_, this); + QObject::connect(this, &MainWindow::focusRequestedForPropertyBrowser, propertyBrowser, &property_browser::PropertyBrowserWidget::setObjectFromObjectId); + QObject::connect(propertyBrowser->model(), &property_browser::PropertyBrowserModel::selectionRequested, this, &MainWindow::focusToSelection); + + QObject::connect(&treeDockManager_, &object_tree::view::ObjectTreeDockManager::newObjectTreeItemsSelected, propertyBrowser, &property_browser::PropertyBrowserWidget::setObjects); + QObject::connect(&treeDockManager_, &object_tree::view::ObjectTreeDockManager::selectionCleared, propertyBrowser, &property_browser::PropertyBrowserWidget::clear); + + auto* dockWidget = createDockWidget(MainWindow::DockWidgetTypes::PROPERTY_BROWSER, this); dockWidget->setWidget(propertyBrowser); dockWidget->setObjectName(dockObjName); - return dockManager->addDockWidget(ads::RightDockWidgetArea, dockWidget); + return dockManager_->addDockWidget(ads::RightDockWidgetArea, dockWidget); } -void createAndAddProjectSettings(MainWindow* mainWindow, const char* dockObjName, RaCoDockManager* dockManager, raco::application::RaCoProject* project, SDataChangeDispatcher dataChangeDispatcher, CommandInterface* commandInterface, SceneBackend* sceneBackend) { - auto* dock = createDockWidget(MainWindow::DockWidgetTypes::PROJECT_SETTINGS, mainWindow); +void MainWindow::createAndAddProjectSettings(const char* dockObjName) { + auto* dock = createDockWidget(MainWindow::DockWidgetTypes::PROJECT_SETTINGS, this); dock->setObjectName(dockObjName); - auto propertyBrowser = new raco::property_browser::PropertyBrowserWidget(dataChangeDispatcher, commandInterface, sceneBackend, nullptr, mainWindow); - propertyBrowser->setObjects({project->project()->settings()}); + auto propertyBrowser = new property_browser::PropertyBrowserWidget(racoApplication_->dataChangeDispatcher(), racoApplication_->activeRaCoProject().commandInterface(), racoApplication_->sceneBackendImpl(), nullptr, this); + propertyBrowser->setObjects({racoApplication_->activeRaCoProject().project()->settings()}, {}); propertyBrowser->setLockable(false); dock->setWidget(propertyBrowser); - dockManager->addDockWidget(ads::RightDockWidgetArea, dock); + dockManager_->addDockWidget(ads::RightDockWidgetArea, dock); } -ads::CDockAreaWidget* createAndAddObjectTree(const char* title, const char* dockObjName, raco::object_tree::model::ObjectTreeViewDefaultModel* dockModel, raco::object_tree::model::ObjectTreeViewDefaultSortFilterProxyModel* sortFilterModel, ads::DockWidgetArea area, MainWindow* mainWindow, RaCoDockManager* dockManager, raco::object_tree::view::ObjectTreeDockManager& treeDockManager, ads::CDockAreaWidget* dockArea) { - auto* dockObjectView = new raco::object_tree::view::ObjectTreeDock(title, mainWindow); - QObject::connect(dockModel, &raco::object_tree::model::ObjectTreeViewDefaultModel::meshImportFailed, mainWindow, &MainWindow::showMeshImportErrorMessage); +ads::CDockAreaWidget* MainWindow::createAndAddObjectTree(const char* title, const char* dockObjName, object_tree::model::ObjectTreeViewDefaultModel* dockModel, object_tree::model::ObjectTreeViewDefaultSortFilterProxyModel* sortFilterModel, ads::DockWidgetArea area, ads::CDockAreaWidget* dockArea) { + auto* dockObjectView = new object_tree::view::ObjectTreeDock(title, this); + QObject::connect(dockModel, &object_tree::model::ObjectTreeViewDefaultModel::meshImportFailed, this, &MainWindow::showMeshImportErrorMessage); dockModel->buildObjectTree(); - auto newTreeView = new raco::object_tree::view::ObjectTreeView(title, dockModel, sortFilterModel); + auto newTreeView = new object_tree::view::ObjectTreeView(title, dockModel, sortFilterModel); if (sortFilterModel && sortFilterModel->sortingEnabled()) { newTreeView->sortByColumn( title == MainWindow::DockWidgetTypes::RESOURCES - ? raco::object_tree::model::ObjectTreeViewDefaultModel::COLUMNINDEX_NAME - : raco::object_tree::model::ObjectTreeViewDefaultModel::COLUMNINDEX_TYPE, + ? object_tree::model::ObjectTreeViewDefaultModel::COLUMNINDEX_NAME + : object_tree::model::ObjectTreeViewDefaultModel::COLUMNINDEX_TYPE, Qt::SortOrder::AscendingOrder); } // Enable Visibility column only for specific tree views. - if (title == MainWindow::DockWidgetTypes::SCENE_GRAPH || title == MainWindow::DockWidgetTypes::PREFABS) { - newTreeView->resizeColumnToContents(raco::object_tree::model::ObjectTreeViewDefaultModel::COLUMNINDEX_VISIBILITY); + if (title == MainWindow::DockWidgetTypes::SCENE_GRAPH) { + newTreeView->resizeColumnToContents(object_tree::model::ObjectTreeViewDefaultModel::COLUMNINDEX_PREVIEW_VISIBILITY); + newTreeView->resizeColumnToContents(object_tree::model::ObjectTreeViewDefaultModel::COLUMNINDEX_ABSTRACT_VIEW_VISIBILITY); + } else if (title == MainWindow::DockWidgetTypes::PREFABS) { + newTreeView->resizeColumnToContents(object_tree::model::ObjectTreeViewDefaultModel::COLUMNINDEX_PREVIEW_VISIBILITY); + newTreeView->setColumnHidden(object_tree::model::ObjectTreeViewDefaultModel::COLUMNINDEX_ABSTRACT_VIEW_VISIBILITY, true); } else { - newTreeView->setColumnHidden(raco::object_tree::model::ObjectTreeViewDefaultModel::COLUMNINDEX_VISIBILITY, true); + newTreeView->setColumnHidden(object_tree::model::ObjectTreeViewDefaultModel::COLUMNINDEX_PREVIEW_VISIBILITY, true); + newTreeView->setColumnHidden(object_tree::model::ObjectTreeViewDefaultModel::COLUMNINDEX_ABSTRACT_VIEW_VISIBILITY, true); } dockObjectView->setTreeView(newTreeView); - treeDockManager.addTreeDock(dockObjectView); + treeDockManager_.addTreeDock(dockObjectView); dockModel->setParent(dockObjectView); dockObjectView->setObjectName(dockObjName); - return dockManager->addDockWidget(area, dockObjectView, dockArea); + return dockManager_->addDockWidget(area, dockObjectView, dockArea); } -ads::CDockAreaWidget* createAndAddProjectBrowser(MainWindow* mainWindow, const char* dockObjName, RaCoDockManager* dockManager, raco::object_tree::view::ObjectTreeDockManager& treeDockManager, raco::application::RaCoApplication* racoApplication, ads::CDockAreaWidget* dockArea) { - auto* model = new raco::object_tree::model::ObjectTreeViewExternalProjectModel(racoApplication->activeRaCoProject().commandInterface(), racoApplication->dataChangeDispatcher(), racoApplication->externalProjects()); - return createAndAddObjectTree(MainWindow::DockWidgetTypes::PROJECT_BROWSER, dockObjName, model, new raco::object_tree::model::ObjectTreeViewDefaultSortFilterProxyModel(mainWindow), ads::BottomDockWidgetArea, mainWindow, dockManager, treeDockManager, dockArea); +ads::CDockAreaWidget* MainWindow::createAndAddProjectBrowser(const char* dockObjName, ads::CDockAreaWidget* dockArea) { + auto* model = new object_tree::model::ObjectTreeViewExternalProjectModel(racoApplication_->activeRaCoProject().commandInterface(), racoApplication_->dataChangeDispatcher(), racoApplication_->externalProjects()); + return createAndAddObjectTree(MainWindow::DockWidgetTypes::PROJECT_BROWSER, dockObjName, model, new object_tree::model::ObjectTreeViewDefaultSortFilterProxyModel(this), ads::BottomDockWidgetArea, dockArea); } -ads::CDockAreaWidget* createAndAddResourceTree(MainWindow* mainWindow, const char* dockObjName, RaCoDockManager* dockManager, raco::object_tree::view::ObjectTreeDockManager& treeDockManager, raco::application::RaCoApplication* racoApplication, ads::CDockAreaWidget* dockArea) { +ads::CDockAreaWidget* MainWindow::createAndAddResourceTree(const char* dockObjName, ads::CDockAreaWidget* dockArea) { using namespace raco::user_types; static const std::vector allowedCreateableUserTypes{ @@ -230,31 +256,32 @@ ads::CDockAreaWidget* createAndAddResourceTree(MainWindow* mainWindow, const cha RenderBuffer::typeDescription.typeName, RenderBufferMS::typeDescription.typeName, RenderTarget::typeDescription.typeName, + RenderTargetMS::typeDescription.typeName, RenderLayer::typeDescription.typeName, RenderPass::typeDescription.typeName}; - auto* model = new raco::object_tree::model::ObjectTreeViewResourceModel(racoApplication->activeRaCoProject().commandInterface(), racoApplication->dataChangeDispatcher(), racoApplication->externalProjects(), allowedCreateableUserTypes); + auto* model = new object_tree::model::ObjectTreeViewResourceModel(racoApplication_->activeRaCoProject().commandInterface(), racoApplication_->dataChangeDispatcher(), racoApplication_->externalProjects(), allowedCreateableUserTypes); model->setAcceptableFileExtensions(QStringList{"gltf", "glb", "ctm", "png", "vert", "frag", "geom", "def", "glsl", "lua"}); model->setAcceptLuaModules(true); return createAndAddObjectTree( - MainWindow::DockWidgetTypes::RESOURCES, dockObjName, model, new raco::object_tree::model::ObjectTreeViewResourceSortFilterProxyModel(mainWindow), - ads::BottomDockWidgetArea, mainWindow, dockManager, treeDockManager, dockArea); + MainWindow::DockWidgetTypes::RESOURCES, dockObjName, model, new object_tree::model::ObjectTreeViewResourceSortFilterProxyModel(this), + ads::BottomDockWidgetArea, dockArea); } -ads::CDockAreaWidget* createAndAddPrefabTree(MainWindow* mainWindow, const char* dockObjName, RaCoDockManager* dockManager, raco::object_tree::view::ObjectTreeDockManager& treeDockManager, raco::application::RaCoApplication* racoApplication, ads::CDockAreaWidget* dockArea) { +ads::CDockAreaWidget* MainWindow::createAndAddPrefabTree(const char* dockObjName, ads::CDockAreaWidget* dockArea) { using namespace raco::user_types; static const std::vector allowedCreateableUserTypes{ Prefab::typeDescription.typeName}; - auto* model = new raco::object_tree::model::ObjectTreeViewPrefabModel(racoApplication->activeRaCoProject().commandInterface(), racoApplication->dataChangeDispatcher(), racoApplication->externalProjects(), allowedCreateableUserTypes); + auto* model = new object_tree::model::ObjectTreeViewPrefabModel(racoApplication_->activeRaCoProject().commandInterface(), racoApplication_->dataChangeDispatcher(), racoApplication_->externalProjects(), allowedCreateableUserTypes); return createAndAddObjectTree( - MainWindow::DockWidgetTypes::PREFABS, dockObjName, model, new raco::object_tree::model::ObjectTreeViewTopLevelSortFilterProxyModel(mainWindow), - ads::BottomDockWidgetArea, mainWindow, dockManager, treeDockManager, dockArea); + MainWindow::DockWidgetTypes::PREFABS, dockObjName, model, new object_tree::model::ObjectTreeViewTopLevelSortFilterProxyModel(this), + ads::BottomDockWidgetArea, dockArea); } -ads::CDockAreaWidget* createAndAddSceneGraphTree(MainWindow* mainWindow, const char* dockObjName, RaCoDockManager* dockManager, raco::object_tree::view::ObjectTreeDockManager& treeDockManager, raco::application::RaCoApplication* racoApplication) { +ads::CDockAreaWidget* MainWindow::createAndAddSceneGraphTree(const char* dockObjName) { using namespace raco::user_types; static const std::vector allowedCreateableUserTypes{ @@ -268,46 +295,46 @@ ads::CDockAreaWidget* createAndAddSceneGraphTree(MainWindow* mainWindow, const c LuaInterface::typeDescription.typeName, Skin::typeDescription.typeName}; - auto* model = new raco::object_tree::model::ObjectTreeViewDefaultModel(racoApplication->activeRaCoProject().commandInterface(), racoApplication->dataChangeDispatcher(), racoApplication->externalProjects(), allowedCreateableUserTypes); + auto* model = new object_tree::model::ObjectTreeViewDefaultModel(racoApplication_->activeRaCoProject().commandInterface(), racoApplication_->dataChangeDispatcher(), racoApplication_->externalProjects(), allowedCreateableUserTypes); model->setAcceptableFileExtensions(QStringList{"lua", "gltf", "glb"}); model->setAcceptLuaScripts(true); model->setAcceptLuaInterfaces(true); model->setDropGltfOpensAssetImportDialog(true); - return createAndAddObjectTree(MainWindow::DockWidgetTypes::SCENE_GRAPH, dockObjName, model, new raco::object_tree::model::ObjectTreeViewDefaultSortFilterProxyModel(mainWindow, false), - ads::LeftDockWidgetArea, mainWindow, dockManager, treeDockManager, nullptr); + return createAndAddObjectTree(MainWindow::DockWidgetTypes::SCENE_GRAPH, dockObjName, model, new object_tree::model::ObjectTreeViewDefaultSortFilterProxyModel(this, false), + ads::LeftDockWidgetArea, nullptr); } -ads::CDockAreaWidget* createAndAddUndoView(raco::application::RaCoApplication* application, const char* dockObjName, raco::application::RaCoProject* project, MainWindow* mainWindow, RaCoDockManager* dockManager, ads::CDockAreaWidget* dockArea = nullptr) { - auto* dock = createDockWidget(MainWindow::DockWidgetTypes::UNDO_STACK, mainWindow); - dock->setWidget(new raco::common_widgets::UndoView(project->undoStack(), application->dataChangeDispatcher(), mainWindow)); +ads::CDockAreaWidget* MainWindow::createAndAddUndoView(const char* dockObjName, ads::CDockAreaWidget* dockArea) { + auto* dock = createDockWidget(MainWindow::DockWidgetTypes::UNDO_STACK, this); + dock->setWidget(new raco::common_widgets::UndoView(racoApplication_->activeRaCoProject().undoStack(), racoApplication_->dataChangeDispatcher(), this)); dock->setObjectName(dockObjName); - return dockManager->addDockWidget(ads::BottomDockWidgetArea, dock, dockArea); + return dockManager_->addDockWidget(ads::BottomDockWidgetArea, dock, dockArea); } -ads::CDockAreaWidget* createAndAddErrorView(MainWindow* mainWindow, raco::application::RaCoApplication* application, const char* dockObjName, RaCoDockManager* dockManager, raco::object_tree::view::ObjectTreeDockManager& treeDockManager, raco::common_widgets::LogViewModel* logViewModel, ads::CDockAreaWidget* dockArea = nullptr) { - auto* errorView = new raco::common_widgets::ErrorView(application->activeRaCoProject().commandInterface(), application->dataChangeDispatcher(), false, logViewModel); - QObject::connect(errorView, &raco::common_widgets::ErrorView::objectSelectionRequested, &treeDockManager, &raco::object_tree::view::ObjectTreeDockManager::selectObjectAcrossAllTreeDocks); - auto* dock = createDockWidget(MainWindow::DockWidgetTypes::ERROR_VIEW, mainWindow); +ads::CDockAreaWidget* MainWindow::createAndAddErrorView(const char* dockObjName, ads::CDockAreaWidget* dockArea) { + auto* errorView = new raco::common_widgets::ErrorView(racoApplication_->activeRaCoProject().commandInterface(), racoApplication_->dataChangeDispatcher(), false, logViewModel_); + QObject::connect(errorView, &raco::common_widgets::ErrorView::objectSelectionRequested, &treeDockManager_, &object_tree::view::ObjectTreeDockManager::selectObjectAcrossAllTreeDocks); + auto* dock = createDockWidget(MainWindow::DockWidgetTypes::ERROR_VIEW, this); dock->setWidget(errorView); dock->setObjectName(dockObjName); - return dockManager->addDockWidget(ads::BottomDockWidgetArea, dock, dockArea); + return dockManager_->addDockWidget(ads::BottomDockWidgetArea, dock, dockArea); } -ads::CDockAreaWidget* createAndAddLogView(MainWindow* mainWindow, raco::application::RaCoApplication* application, const char* dockObjName, RaCoDockManager* dockManager, raco::object_tree::view::ObjectTreeDockManager& treeDockManager, raco::common_widgets::LogViewModel* logViewModel, ads::CDockAreaWidget* dockArea = nullptr) { - auto* logView = new raco::common_widgets::LogView(logViewModel); - auto* dock = createDockWidget(MainWindow::DockWidgetTypes::LOG_VIEW, mainWindow); +ads::CDockAreaWidget* MainWindow::createAndAddLogView(const char* dockObjName, ads::CDockAreaWidget* dockArea) { + auto* logView = new raco::common_widgets::LogView(logViewModel_); + auto* dock = createDockWidget(MainWindow::DockWidgetTypes::LOG_VIEW, this); dock->setWidget(logView); dock->setObjectName(dockObjName); - return dockManager->addDockWidget(ads::BottomDockWidgetArea, dock, dockArea); + return dockManager_->addDockWidget(ads::BottomDockWidgetArea, dock, dockArea); } -ads::CDockAreaWidget* createAndAddPythonRunner(MainWindow* mainWindow, raco::application::RaCoApplication* application, const char* dockObjName, std::map& scriptEntries, std::map& commandLineParamEntries, RaCoDockManager* dockManager, ads::CDockAreaWidget* dockArea = nullptr) { - auto* pythonRunner = new raco::common_widgets::RunScriptDialog(scriptEntries, commandLineParamEntries, mainWindow); - auto* dock = createDockWidget(MainWindow::DockWidgetTypes::PYTHON_RUNNER, mainWindow); +ads::CDockAreaWidget* MainWindow::createAndAddPythonRunner(const char* dockObjName, ads::CDockAreaWidget* dockArea) { + auto* pythonRunner = new raco::common_widgets::RunScriptDialog(pythonScriptCache_, pythonScriptArgumentCache_, this); + auto* dock = createDockWidget(MainWindow::DockWidgetTypes::PYTHON_RUNNER, this); dock->setWidget(pythonRunner); dock->setObjectName(dockObjName); - QObject::connect(pythonRunner, &raco::common_widgets::RunScriptDialog::pythonScriptRunRequested, [mainWindow, application, dock, pythonRunner](const QString& scriptPath, const QStringList& arguments) { + QObject::connect(pythonRunner, &raco::common_widgets::RunScriptDialog::pythonScriptRunRequested, [this, dock, pythonRunner](const QString& scriptPath, const QStringList& arguments) { pythonRunner->setScriptIsRunning(true); pythonRunner->repaint(); std::vector pos_argv_s; @@ -320,29 +347,29 @@ ads::CDockAreaWidget* createAndAddPythonRunner(MainWindow* mainWindow, raco::app pos_argv_cp.emplace_back(s.c_str()); } - auto currentRunStatus = raco::python_api::runPythonScript(application, QCoreApplication::applicationFilePath().toStdWString(), scriptPath.toStdString(), mainWindow->pythonSearchPaths(), pos_argv_cp); + auto currentRunStatus = python_api::runPythonScript(racoApplication_, QCoreApplication::applicationFilePath().toStdWString(), scriptPath.toStdString(), pythonSearchPaths(), pos_argv_cp); pythonRunner->addPythonOutput(currentRunStatus.stdOutBuffer, currentRunStatus.stdErrBuffer); pythonRunner->setScriptIsRunning(false); }); - return dockManager->addDockWidget(ads::RightDockWidgetArea, dock, dockArea); + return dockManager_->addDockWidget(ads::RightDockWidgetArea, dock, dockArea); } -ads::CDockAreaWidget* createAndAddTracePlayer(MainWindow* mainWindow, RaCoDockManager* dockManager, raco::components::TracePlayer* tracePlayer) { - if (auto existingTraceplayerDock{dockManager->findDockWidget(MainWindow::DockWidgetTypes::TRACE_PLAYER)}) { +ads::CDockAreaWidget* MainWindow::createAndAddTracePlayer() { + if (auto existingTraceplayerDock{dockManager_->findDockWidget(MainWindow::DockWidgetTypes::TRACE_PLAYER)}) { return existingTraceplayerDock->dockAreaWidget(); } - auto* newTraceplayerDock{createDockWidget(MainWindow::DockWidgetTypes::TRACE_PLAYER, mainWindow)}; + auto* newTraceplayerDock{createDockWidget(MainWindow::DockWidgetTypes::TRACE_PLAYER, this)}; newTraceplayerDock->setMinimumSizeHintMode(ads::CDockWidget::eMinimumSizeHintMode::MinimumSizeHintFromContent); - auto* traceplayerWidget{new raco::common_widgets::TracePlayerWidget(newTraceplayerDock->objectName(), tracePlayer)}; + auto* traceplayerWidget{new raco::common_widgets::TracePlayerWidget(newTraceplayerDock->objectName(), &racoApplication_->activeRaCoProject().tracePlayer())}; newTraceplayerDock->setWidget(traceplayerWidget, ads::CDockWidget::ForceNoScrollArea); ads::CDockWidget* existingPreviewDock{nullptr}; constexpr auto isRamsesPreviewWidget{ [](const ads::CDockWidget* dockWidget) { return dockWidget->windowTitle() == MainWindow::DockWidgetTypes::RAMSES_PREVIEW; }}; - const auto& dockWidgetsMap{dockManager->dockWidgetsMap()}; + const auto& dockWidgetsMap{dockManager_->dockWidgetsMap()}; if (const auto itr = std::find_if(dockWidgetsMap.begin(), dockWidgetsMap.end(), isRamsesPreviewWidget); itr != dockWidgetsMap.end()) { existingPreviewDock = *itr; } @@ -366,24 +393,23 @@ ads::CDockAreaWidget* createAndAddTracePlayer(MainWindow* mainWindow, RaCoDockMa previewDockArea = existingPreviewDock->dockAreaWidget(); } - return dockManager->addDockWidget(ads::TopDockWidgetArea, newTraceplayerDock, previewDockArea); + return dockManager_->addDockWidget(ads::TopDockWidgetArea, newTraceplayerDock, previewDockArea); } -void createInitialWidgets(MainWindow* mainWindow, raco::ramses_widgets::RendererBackend& rendererBackend, raco::application::RaCoApplication* application, RaCoDockManager* dockManager, raco::object_tree::view::ObjectTreeDockManager& treeDockManager) { - createAndAddPreview(mainWindow, "defaultPreview", dockManager, rendererBackend, application); +void MainWindow::createInitialWidgets() { + auto centerDockArea = createAndAddPreview("defaultPreview"); + createAndAddErrorView("defaultErrorView", centerDockArea); - auto leftDockArea = createAndAddSceneGraphTree(mainWindow, "defaultSceneGraph", dockManager, treeDockManager, application); - leftDockArea = createAndAddResourceTree(mainWindow, "defaultResourceTree", dockManager, treeDockManager, application, leftDockArea); - createAndAddPrefabTree(mainWindow, "defaultPrefabTree", dockManager, treeDockManager, application, leftDockArea); + auto leftDockArea = createAndAddSceneGraphTree( "defaultSceneGraph"); + leftDockArea = createAndAddResourceTree("defaultResourceTree", leftDockArea); + createAndAddPrefabTree("defaultPrefabTree", leftDockArea); - createAndAddUndoView(application, "defaultUndoView", &application->activeRaCoProject(), mainWindow, dockManager, leftDockArea); + createAndAddUndoView("defaultUndoView", leftDockArea); - createAndAddPropertyBrowser(mainWindow, "defaultPropertyBrowser", dockManager, treeDockManager, application); + createAndAddPropertyBrowser("defaultPropertyBrowser"); } -} // namespace - -MainWindow::MainWindow(raco::application::RaCoApplication* racoApplication, raco::ramses_widgets::RendererBackend* rendererBackend, const std::vector& pythonSearchPaths, QWidget* parent) +MainWindow::MainWindow(raco::application::RaCoApplication* racoApplication, ramses_widgets::RendererBackend* rendererBackend, const std::vector& pythonSearchPaths, QWidget* parent) : QMainWindow(parent), pythonSearchPaths_(pythonSearchPaths), rendererBackend_(rendererBackend), @@ -399,35 +425,62 @@ MainWindow::MainWindow(raco::application::RaCoApplication* racoApplication, raco updateUpgradeMenu(); - dockManager_ = createDockManager(this); + dockManager_ = createDockManager(); setWindowIcon(QIcon(":applicationLogo")); logViewModel_ = new raco::common_widgets::LogViewModel(this); // Shortcuts { - auto undoShortcut = new QShortcut(QKeySequence::Undo, this, nullptr, nullptr, Qt::ApplicationShortcut); + const auto undoShortcut = new QShortcut(QKeySequence::Undo, this, nullptr, nullptr, Qt::ApplicationShortcut); QObject::connect(undoShortcut, &QShortcut::activated, this, [this]() { EditMenu::globalUndoCallback(racoApplication_); }); - auto redoShortcut = new QShortcut(QKeySequence::Redo, this, nullptr, nullptr, Qt::ApplicationShortcut); + + const auto redoShortcut = new QShortcut(QKeySequence::Redo, this, nullptr, nullptr, Qt::ApplicationShortcut); QObject::connect(redoShortcut, &QShortcut::activated, this, [this]() { EditMenu::globalRedoCallback(racoApplication_); }); + ui->actionExport->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E)); + ui->actionExport->setShortcutContext(Qt::ApplicationShortcut); + + ui->actionNew->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_N)); + ui->actionNew->setShortcutContext(Qt::ApplicationShortcut); + + ui->actionOpen->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_O)); + ui->actionOpen->setShortcutContext(Qt::ApplicationShortcut); + + const auto openRecentShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_O), this, nullptr, nullptr, Qt::ApplicationShortcut); + QObject::connect(openRecentShortcut, &QShortcut::activated, this, [this]() { + // Open menu File + const int menuFileX = ui->menuBar->pos().x(); + const int menuFileY = ui->menuBar->pos().y() + ui->menuBar->height(); + ui->menuFile->popup(mapToGlobal(QPoint(menuFileX, menuFileY))); + // Trigger Open Recent menu + const auto recentFileAction = recentFileMenu_->menuAction(); + ui->menuFile->setActiveAction(recentFileAction); + recentFileAction->trigger(); + }); + + ui->actionQuit->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q)); + ui->actionQuit->setShortcutContext(Qt::ApplicationShortcut); + ui->actionSave->setShortcut(QKeySequence::Save); ui->actionSave->setShortcutContext(Qt::ApplicationShortcut); QObject::connect(ui->actionSave, &QAction::triggered, this, &MainWindow::saveActiveProject); - - ui->actionSaveAs->setShortcut(QKeySequence::SaveAs); + + ui->actionSaveAs->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_S)); ui->actionSaveAs->setShortcutContext(Qt::ApplicationShortcut); QObject::connect(ui->actionSaveAs, &QAction::triggered, this, &MainWindow::saveAsActiveProject); - + + ui->actionSaveAsWithNewID->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_S)); + ui->actionSaveAsWithNewID->setShortcutContext(Qt::ApplicationShortcut); QObject::connect(ui->actionSaveAsWithNewID, &QAction::triggered, this, &MainWindow::saveAsActiveProjectWithNewID); } QObject::connect(ui->actionOpen, &QAction::triggered, [this]() { - auto file = QFileDialog::getOpenFileName(this, "Open", QString::fromStdString(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Project).string()), "Ramses Composer Assembly (*.rca);; All files (*.*)"); + auto file = QFileDialog::getOpenFileName(this, "Open", QString::fromStdString(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Project).string()), "Ramses Composer Assembly (*.rca);; All files (*.*)"); if (file.size() > 0) { openProject(file); } @@ -447,24 +500,25 @@ MainWindow::MainWindow(raco::application::RaCoApplication* racoApplication, raco auto dialog = new raco::common_widgets::PreferencesView(this); dialog->resize(500, 500); dialog->exec(); - racoApplication_->setApplicationFeatureLevel(raco::components::RaCoPreferences::instance().featureLevel); + racoApplication_->setNewFileFeatureLevel(components::RaCoPreferences::instance().featureLevel); racoApplication_->activeRaCoProject().applyPreferences(); }); // View actions - QObject::connect(ui->actionNewPreview, &QAction::triggered, [this]() { createAndAddPreview(this, EditorObject::normalizedObjectID("").c_str(), dockManager_, *rendererBackend_, racoApplication_); }); - QObject::connect(ui->actionNewPropertyBrowser, &QAction::triggered, [this]() { createAndAddPropertyBrowser(this, EditorObject::normalizedObjectID("").c_str(), dockManager_, treeDockManager_, racoApplication_); }); - QObject::connect(ui->actionNewProjectBrowser, &QAction::triggered, [this]() { createAndAddProjectBrowser(this, EditorObject::normalizedObjectID("").c_str(), dockManager_, treeDockManager_, racoApplication_, nullptr); }); - QObject::connect(ui->actionNewSceneGraphTree, &QAction::triggered, [this]() { createAndAddSceneGraphTree(this, EditorObject::normalizedObjectID("").c_str(), dockManager_, treeDockManager_, racoApplication_); }); - QObject::connect(ui->actionNewResourcesTree, &QAction::triggered, [this]() { createAndAddResourceTree(this, EditorObject::normalizedObjectID("").c_str(), dockManager_, treeDockManager_, racoApplication_, nullptr); }); - QObject::connect(ui->actionNewPrefabTree, &QAction::triggered, [this]() { createAndAddPrefabTree(this, EditorObject::normalizedObjectID("").c_str(), dockManager_, treeDockManager_, racoApplication_, nullptr); }); - QObject::connect(ui->actionNewUndoView, &QAction::triggered, [this]() { createAndAddUndoView(racoApplication_, EditorObject::normalizedObjectID("").c_str(), &racoApplication_->activeRaCoProject(), this, dockManager_); }); - QObject::connect(ui->actionNewErrorView, &QAction::triggered, [this]() { createAndAddErrorView(this, racoApplication_, EditorObject::normalizedObjectID("").c_str(), dockManager_, treeDockManager_, logViewModel_); }); - QObject::connect(ui->actionNewLogView, &QAction::triggered, [this]() { createAndAddLogView(this, racoApplication_, EditorObject::normalizedObjectID("").c_str(), dockManager_, treeDockManager_, logViewModel_); }); - QObject::connect(ui->actionNewPythonRunner, &QAction::triggered, [this]() { createAndAddPythonRunner(this, racoApplication_, EditorObject::normalizedObjectID("").c_str(), pythonScriptCache_, pythonScriptArgumentCache_, dockManager_); }); + QObject::connect(ui->actionNewPreview, &QAction::triggered, [this]() { createAndAddPreview(EditorObject::normalizedObjectID("").c_str()); }); + QObject::connect(ui->actionNewAbstractSceneView, &QAction::triggered, [this]() { createAndAddAbstractSceneView(EditorObject::normalizedObjectID("").c_str()); }); + QObject::connect(ui->actionNewPropertyBrowser, &QAction::triggered, [this]() { createAndAddPropertyBrowser(EditorObject::normalizedObjectID("").c_str()); }); + QObject::connect(ui->actionNewProjectBrowser, &QAction::triggered, [this]() { createAndAddProjectBrowser(EditorObject::normalizedObjectID("").c_str(), nullptr); }); + QObject::connect(ui->actionNewSceneGraphTree, &QAction::triggered, [this]() { createAndAddSceneGraphTree(EditorObject::normalizedObjectID("").c_str()); }); + QObject::connect(ui->actionNewResourcesTree, &QAction::triggered, [this]() { createAndAddResourceTree(EditorObject::normalizedObjectID("").c_str(), nullptr); }); + QObject::connect(ui->actionNewPrefabTree, &QAction::triggered, [this]() { createAndAddPrefabTree(EditorObject::normalizedObjectID("").c_str(), nullptr); }); + QObject::connect(ui->actionNewUndoView, &QAction::triggered, [this]() { createAndAddUndoView(EditorObject::normalizedObjectID("").c_str()); }); + QObject::connect(ui->actionNewErrorView, &QAction::triggered, [this]() { createAndAddErrorView( EditorObject::normalizedObjectID("").c_str()); }); + QObject::connect(ui->actionNewLogView, &QAction::triggered, [this]() { createAndAddLogView(EditorObject::normalizedObjectID("").c_str()); }); + QObject::connect(ui->actionNewPythonRunner, &QAction::triggered, [this]() { createAndAddPythonRunner(EditorObject::normalizedObjectID("").c_str()); }); QObject::connect(ui->actionRestoreDefaultLayout, &QAction::triggered, [this]() { resetDockManager(); - createInitialWidgets(this, *rendererBackend_, racoApplication_, dockManager_, treeDockManager_); + createInitialWidgets(); }); QObject::connect(ui->actionSaveCurrentLayout, &QAction::triggered, [this]() { @@ -491,8 +545,8 @@ MainWindow::MainWindow(raco::application::RaCoApplication* racoApplication, raco saveDockManagerCustomLayouts(); }); - QObject::connect(ui->actionTracePlayer, &QAction::triggered, [this]() { createAndAddTracePlayer(this, dockManager_, &racoApplication_->activeRaCoProject().tracePlayer()); }); - QObject::connect(ui->actionProjectSettings, &QAction::triggered, [this]() { createAndAddProjectSettings(this, EditorObject::normalizedObjectID("").c_str(), dockManager_, &racoApplication_->activeRaCoProject(), racoApplication_->dataChangeDispatcher(), racoApplication_->activeRaCoProject().commandInterface(), racoApplication_->sceneBackendImpl()); }); + QObject::connect(ui->actionTracePlayer, &QAction::triggered, [this]() { createAndAddTracePlayer(); }); + QObject::connect(ui->actionProjectSettings, &QAction::triggered, [this]() { createAndAddProjectSettings(EditorObject::normalizedObjectID("").c_str()); }); configureDebugActions(ui, this, racoApplication_->activeRaCoProject().commandInterface()); // Help actions @@ -501,7 +555,7 @@ MainWindow::MainWindow(raco::application::RaCoApplication* racoApplication, raco about.exec(); }); - QObject::connect(this, &MainWindow::objectFocusRequestedForTreeDock, &treeDockManager_, &raco::object_tree::view::ObjectTreeDockManager::selectObjectAcrossAllTreeDocks); + QObject::connect(this, &MainWindow::focusRequestedForTreeDock, &treeDockManager_, &object_tree::view::ObjectTreeDockManager::selectObjectAndPropertyAcrossAllTreeDocks); setAcceptDrops(true); @@ -527,7 +581,7 @@ void MainWindow::saveDockManagerCustomLayouts() { dockManager_->saveCustomLayouts(settings); settings.sync(); if (settings.status() != QSettings::NoError) { - LOG_ERROR(raco::log_system::COMMON, "Saving custom layout failed: {}", raco::core::PathManager::recentFilesStorePath().string()); + LOG_ERROR(log_system::COMMON, "Saving custom layout failed: {}", core::PathManager::recentFilesStorePath().string()); QMessageBox::critical(this, "Saving custom layout failed", QString("Custom layout data could not be saved to disk and will be lost after closing Ramses Composer. Check whether the application can write to its config directory.\nFile: ") + QString::fromStdString(PathManager::layoutFilePath().string())); } @@ -542,7 +596,7 @@ void MainWindow::timerEvent(QTimerEvent* event) { Q_EMIT viewportChanged({*viewport->i1_, *viewport->i2_}); - for (auto preview : findChildren()) { + for (auto preview : findChildren()) { preview->commit(racoApplication_->rendererDirty_); preview->displayScene(racoApplication_->sceneBackendImpl()->currentSceneId(), backgroundColor); } @@ -550,6 +604,9 @@ void MainWindow::timerEvent(QTimerEvent* event) { auto logicEngineExecutionEnd = std::chrono::high_resolution_clock::now(); timingsModel_.addLogicEngineTotalExecutionDuration(std::chrono::duration_cast(logicEngineExecutionEnd - startLoop).count()); racoApplication_->sceneBackendImpl()->flush(); + if (racoApplication_->abstractScene()) { + racoApplication_->abstractScene()->scene()->flush(); + } rendererBackend_->doOneLoop(); } @@ -557,14 +614,14 @@ void MainWindow::timerEvent(QTimerEvent* event) { void MainWindow::closeEvent(QCloseEvent* event) { if (resolveDirtiness()) { killTimer(renderTimerId_); - auto settings = raco::core::PathManager::layoutSettings(); + auto settings = core::PathManager::layoutSettings(); settings.setValue("geometry", saveGeometry()); settings.setValue("windowState", saveState()); dockManager_->saveCurrentLayoutInCache(settings); settings.sync(); if (settings.status() != QSettings::NoError) { - LOG_WARNING(raco::log_system::COMMON, "Saving layout failed: {}", raco::core::PathManager::recentFilesStorePath().string()); + LOG_WARNING(log_system::COMMON, "Saving layout failed: {}", core::PathManager::recentFilesStorePath().string()); } QMainWindow::closeEvent(event); event->accept(); @@ -604,20 +661,20 @@ QFileInfo MainWindow::getDragAndDropFileInfo(const QDropEvent* event) { void MainWindow::restoreSettings() { if (PathManager::layoutFilePath().existsFile()) { - auto settings = raco::core::PathManager::layoutSettings(); + auto settings = core::PathManager::layoutSettings(); restoreGeometry(settings.value("geometry").toByteArray()); restoreState(settings.value("windowState").toByteArray()); } } -void MainWindow::openProject(const QString& file, int featureLevel, bool generateNewObjectIDs) { +void MainWindow::openProject(const QString& file, int featureLevel, bool generateNewObjectIDs, bool ignoreDirtiness) { auto fileString = file.toStdString(); - if (!fileString.empty() && (!raco::utils::u8path(fileString).exists() || !raco::utils::u8path(fileString).userHasReadAccess())) { + if (!fileString.empty() && (!utils::u8path(fileString).exists() || !utils::u8path(fileString).userHasReadAccess())) { QMessageBox::warning(this, "File Load Error", fmt::format("Project file {} is not available for loading.\n\nCheck whether the file at the specified path still exists and that you have read access to that file.", fileString).c_str(), QMessageBox::Close); return; } - if (!resolveDirtiness()) { + if (!ignoreDirtiness && !resolveDirtiness()) { return; } @@ -626,11 +683,11 @@ void MainWindow::openProject(const QString& file, int featureLevel, bool generat } { - auto settings = raco::core::PathManager::layoutSettings(); + auto settings = core::PathManager::layoutSettings(); dockManager_->saveCurrentLayoutInCache(settings); settings.sync(); if (settings.status() != QSettings::NoError) { - LOG_WARNING(raco::log_system::COMMON, "Saving layout failed: {}", raco::core::PathManager::recentFilesStorePath().string()); + LOG_WARNING(log_system::COMMON, "Saving layout failed: {}", core::PathManager::recentFilesStorePath().string()); } } @@ -640,7 +697,6 @@ void MainWindow::openProject(const QString& file, int featureLevel, bool generat delete dockManager_; logViewModel_->clear(); - killTimer(renderTimerId_); try { @@ -649,7 +705,7 @@ void MainWindow::openProject(const QString& file, int featureLevel, bool generat fmt::format("External project '{}' was not found!\n\nSpecify replacement project and relink?", projectPath).c_str(), QMessageBox::Yes | QMessageBox::No); if (answer == QMessageBox::Yes) { - auto projectDirectory = raco::utils::u8path(projectPath).normalized().parent_path().string(); + auto projectDirectory = utils::u8path(projectPath).normalized().parent_path().string(); auto file = QFileDialog::getOpenFileName(this, "Replace: " + QString::fromStdString(projectPath), QString::fromStdString(projectDirectory), @@ -681,7 +737,7 @@ void MainWindow::openProject(const QString& file, int featureLevel, bool generat } catch (const raco::application::FutureFileVersion& error) { racoApplication_->switchActiveRaCoProject({}, {}); - QMessageBox::warning(this, "File Load Error", fmt::format("Project file was created with newer version of {app_name}. Please upgrade.\n\nExpected File Version: {expected_file_version}\nFound File Version: {file_version}", fmt::arg("app_name", "Ramses Composer"), fmt::arg("expected_file_version", raco::serialization::RAMSES_PROJECT_FILE_VERSION), fmt::arg("file_version", error.fileVersion_)).c_str(), QMessageBox::Close); + QMessageBox::warning(this, "File Load Error", fmt::format("Project file was created with newer version of {app_name}. Please upgrade.\n\nExpected File Version: {expected_file_version}\nFound File Version: {file_version}", fmt::arg("app_name", "Ramses Composer"), fmt::arg("expected_file_version", serialization::RAMSES_PROJECT_FILE_VERSION), fmt::arg("file_version", error.fileVersion_)).c_str(), QMessageBox::Close); } catch (const ExtrefError& error) { racoApplication_->switchActiveRaCoProject({}, {}); QMessageBox::warning(this, "File Load Error", fmt::format("External reference update failed.\n\n{}", error.what()).c_str(), QMessageBox::Close); @@ -693,7 +749,7 @@ void MainWindow::openProject(const QString& file, int featureLevel, bool generat renderTimerId_ = startTimer(timerInterval60Fps); // Recreate our layout with new context - dockManager_ = createDockManager(this); + dockManager_ = createDockManager(); restoreCachedLayout(); configureDebugActions(ui, this, racoApplication_->activeRaCoProject().commandInterface()); @@ -701,6 +757,10 @@ void MainWindow::openProject(const QString& file, int featureLevel, bool generat updateActiveProjectConnection(); updateProjectSavedConnection(); updateUpgradeMenu(); + + for (auto abstractView : findChildren()) { + abstractView->focusCamera(racoApplication_->activeRaCoProject().project()->instances()); + } } MainWindow::~MainWindow() { @@ -745,6 +805,30 @@ bool MainWindow::upgradeActiveProject(int newFeatureLevel) { return false; } +bool MainWindow::promptToReloadActiveProject() { + if (racoApplication_->activeProjectPath().empty()) { + return false; + } + + auto reloadConfirmed = QMessageBox::NoButton; + + if (racoApplication_->activeRaCoProject().dirty()) { + reloadConfirmed = QMessageBox::warning(this, "Project File Modification Detected", + "Active project file has unsaved changes and has been changed externally! Do you want to reload it and lose all unsaved changes?", + QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No)); + } else { + reloadConfirmed = QMessageBox::question(this, "Project File Modification Detected", + "Active project file has been changed externally. Do you want to reload it?" ); + } + + if (reloadConfirmed == QMessageBox::Yes) { + openProject(QString::fromStdString(racoApplication_->activeProjectPath()), racoApplication_->activeRaCoProject().project()->featureLevel(), false, true); + return true; + } + + return false; +} + bool MainWindow::saveActiveProject() { if (racoApplication_->canSaveActiveProject()) { if (racoApplication_->activeProjectPath().empty()) { @@ -771,12 +855,12 @@ bool MainWindow::saveActiveProject() { } bool MainWindow::isUpgradePrevented() { - if (raco::components::RaCoPreferences::instance().preventAccidentalUpgrade) { + if (components::RaCoPreferences::instance().preventAccidentalUpgrade) { const auto filename = QString::fromStdString(racoApplication_->activeProjectPath()); - constexpr auto currentFileVersion = raco::serialization::RAMSES_PROJECT_FILE_VERSION; + constexpr auto currentFileVersion = serialization::RAMSES_PROJECT_FILE_VERSION; try { - auto previousFileVersion = raco::serialization::deserializeFileVersion(raco::application::RaCoProject::loadFileDocument(filename)); + auto previousFileVersion = serialization::deserializeFileVersion(raco::application::RaCoProject::loadJsonDocument(filename)); if (currentFileVersion > previousFileVersion) { const auto answer = QMessageBox::warning(this, "Save File Warning", fmt::format("The project with the file version {} will be overwritten with the file version {}. Are you sure you want to save it with the new file version", previousFileVersion, currentFileVersion).c_str(), QMessageBox::Save, QMessageBox::Cancel); if (answer == QMessageBox::Cancel) { @@ -794,7 +878,7 @@ bool MainWindow::saveAsActiveProject(bool newID) { if (racoApplication_->canSaveActiveProject()) { const bool setProjectName = racoApplication_->activeProjectPath().empty(); const auto dialogCaption = newID ? "Save As with new ID..." : "Save As..."; - auto newPath = QFileDialog::getSaveFileName(this, dialogCaption, QString::fromStdString(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Project).string()), "Ramses Composer Assembly (*.rca)"); + auto newPath = QFileDialog::getSaveFileName(this, dialogCaption, QString::fromStdString(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Project).string()), "Ramses Composer Assembly (*.rca)"); if (newPath.isEmpty()) { return false; } @@ -849,7 +933,7 @@ void MainWindow::updateSavedLayoutMenu() { } void MainWindow::updateUpgradeMenu() { - auto maxFeatureLevel = static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel); + auto maxFeatureLevel = static_cast(ramses_base::BaseEngineBackend::maxFeatureLevel); auto currentFeatureLevel = racoApplication_->activeRaCoProject().project()->featureLevel(); if ((currentFeatureLevel < maxFeatureLevel) && (!racoApplication_->activeProjectPath().empty())) { ui->menuUpgrade->clear(); @@ -890,7 +974,7 @@ QString MainWindow::getActiveProjectFolder() { void MainWindow::restoreCachedLayout() { auto cachedLayoutInfo = dockManager_->getCachedLayoutInfo(); if (cachedLayoutInfo.empty()) { - createInitialWidgets(this, *rendererBackend_, racoApplication_, dockManager_, treeDockManager_); + createInitialWidgets(); #ifdef Q_OS_WIN // explicit maximization of docks needed or else RaCo will not look properly maximized on Windows @@ -915,56 +999,72 @@ void MainWindow::restoreCustomLayout(const QString& layoutName) { } void MainWindow::regenerateLayoutDocks(const RaCoDockManager::LayoutDocks& docks) { - setNewPreviewMenuEntryEnabled(true); + ui->actionNewPreview->setEnabled(true); + ui->actionNewAbstractSceneView->setEnabled(true); auto hasPreview = false; + bool hasAbstractSceneView = false; for (const auto& [savedDockType, savedDockName] : docks) { auto dockNameString = savedDockName.toStdString(); auto dockNameCString = dockNameString.c_str(); if (savedDockType == DockWidgetTypes::PREFABS) { - createAndAddPrefabTree(this, dockNameCString, dockManager_, treeDockManager_, racoApplication_, nullptr); + createAndAddPrefabTree(dockNameCString, nullptr); } else if (savedDockType == DockWidgetTypes::PROJECT_BROWSER) { - createAndAddProjectBrowser(this, dockNameCString, dockManager_, treeDockManager_, racoApplication_, nullptr); + createAndAddProjectBrowser(dockNameCString, nullptr); } else if (savedDockType == DockWidgetTypes::PROJECT_SETTINGS) { - createAndAddProjectSettings(this, dockNameCString, dockManager_, &racoApplication_->activeRaCoProject(), racoApplication_->dataChangeDispatcher(), racoApplication_->activeRaCoProject().commandInterface(), racoApplication_->sceneBackendImpl()); + createAndAddProjectSettings(dockNameCString); } else if (savedDockType == DockWidgetTypes::PROPERTY_BROWSER) { - createAndAddPropertyBrowser(this, dockNameCString, dockManager_, treeDockManager_, racoApplication_); + createAndAddPropertyBrowser(dockNameCString); } else if (savedDockType == DockWidgetTypes::RAMSES_PREVIEW) { if (!hasPreview) { - createAndAddPreview(this, dockNameCString, dockManager_, *rendererBackend_, racoApplication_); + createAndAddPreview(dockNameCString); // prevent loading of multiple preview windows hasPreview = true; } + } else if (savedDockType == DockWidgetTypes::ABSTRACT_SCENE_VIEW) { + if (!hasAbstractSceneView) { + createAndAddAbstractSceneView(dockNameCString); + // prevent loading of multiple windows + hasAbstractSceneView = true; + } } else if (savedDockType == DockWidgetTypes::RESOURCES) { - createAndAddResourceTree(this, dockNameCString, dockManager_, treeDockManager_, racoApplication_, nullptr); + createAndAddResourceTree(dockNameCString, nullptr); } else if (savedDockType == DockWidgetTypes::SCENE_GRAPH) { - createAndAddSceneGraphTree(this, dockNameCString, dockManager_, treeDockManager_, racoApplication_); + createAndAddSceneGraphTree(dockNameCString); } else if (savedDockType == DockWidgetTypes::UNDO_STACK) { - createAndAddUndoView(racoApplication_, dockNameCString, &racoApplication_->activeRaCoProject(), this, dockManager_); + createAndAddUndoView(dockNameCString); } else if (savedDockType == DockWidgetTypes::ERROR_VIEW) { - createAndAddErrorView(this, racoApplication_, dockNameCString, dockManager_, treeDockManager_, logViewModel_); + createAndAddErrorView(dockNameCString); } else if (savedDockType == DockWidgetTypes::LOG_VIEW) { - createAndAddLogView(this, racoApplication_, dockNameCString, dockManager_, treeDockManager_, logViewModel_); + createAndAddLogView(dockNameCString); } else if (savedDockType == DockWidgetTypes::TRACE_PLAYER) { - createAndAddTracePlayer(this, dockManager_, &racoApplication_->activeRaCoProject().tracePlayer()); + createAndAddTracePlayer(); } else if (savedDockType == DockWidgetTypes::PYTHON_RUNNER) { - createAndAddPythonRunner(this, racoApplication_, dockNameCString, pythonScriptCache_, pythonScriptArgumentCache_, dockManager_); + createAndAddPythonRunner(dockNameCString); } else { - LOG_DEBUG(raco::log_system::COMMON, "Ignoring unknown dock type '{}'.", savedDockType.toStdString()); + LOG_DEBUG(log_system::COMMON, "Ignoring unknown dock type '{}'.", savedDockType.toStdString()); } } } void MainWindow::resetDockManager() { delete dockManager_; - dockManager_ = createDockManager(this); + dockManager_ = createDockManager(); +} + +void MainWindow::activeProjectFileChanged() { + updateApplicationTitle(); + promptToReloadActiveProject(); } void MainWindow::updateActiveProjectConnection() { QObject::disconnect(activeProjectFileConnection_); if (!racoApplication_->activeProjectPath().empty()) { - activeProjectFileConnection_ = QObject::connect(&racoApplication_->activeRaCoProject(), &raco::application::RaCoProject::activeProjectFileChanged, [this]() { - updateApplicationTitle(); - }); + activeProjectFileConnection_ = QObject::connect( + &racoApplication_->activeRaCoProject(), + &raco::application::RaCoProject::activeProjectFileChanged, + this, + &MainWindow::activeProjectFileChanged, + Qt::QueuedConnection); } } @@ -976,11 +1076,13 @@ void MainWindow::updateProjectSavedConnection() { }); } -void MainWindow::focusToObject(const QString& objectID) { - if (treeDockManager_.getTreeDockAmount() != 0 && treeDockManager_.docksContainObject(objectID)) { - Q_EMIT objectFocusRequestedForTreeDock(objectID); - } else { - Q_EMIT objectFocusRequestedForPropertyBrowser(objectID); +void MainWindow::focusToSelection(const QString& objectID, const QString& objectProperty) { + if (racoApplication_->activeRaCoProject().project()->getInstanceByID(objectID.toStdString())) { + if (treeDockManager_.getTreeDockAmount() != 0 && treeDockManager_.docksContainObject(objectID)) { + Q_EMIT focusRequestedForTreeDock(objectID, objectProperty); + } else { + Q_EMIT focusRequestedForPropertyBrowser(objectID, objectProperty); + } } } @@ -993,8 +1095,3 @@ void MainWindow::showMeshImportErrorMessage(const std::string& filePath, const s importErrorBox.setTextInteractionFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse); importErrorBox.exec(); } - -// As long as we can't cleverly create multiple previews on the same scene, the "New Preview" menu item should only be enabled to create one Ramses preview. -void MainWindow::setNewPreviewMenuEntryEnabled(bool enabled) { - ui->actionNewPreview->setEnabled(enabled); -} diff --git a/EditorApp/mainwindow.h b/EditorApp/mainwindow.h index 46e438f5..af5a28bc 100644 --- a/EditorApp/mainwindow.h +++ b/EditorApp/mainwindow.h @@ -13,7 +13,10 @@ #include "common_widgets/TimingsWidget.h" #include "common_widgets/log_model/LogViewModel.h" #include "object_tree_view/ObjectTreeDockManager.h" +#include "object_tree_view_model/ObjectTreeViewDefaultModel.h" +#include "object_tree_view_model/ObjectTreeViewSortProxyModels.h" #include "ramses_widgets/RendererBackend.h" +#include "property_browser/PropertyBrowserWidget.h" #include #include @@ -43,6 +46,7 @@ class MainWindow : public QMainWindow { static inline const char* PROJECT_SETTINGS{"Project Settings"}; static inline const char* PROPERTY_BROWSER{"Property Browser"}; static inline const char* RAMSES_PREVIEW{"Ramses Preview"}; + static inline const char* ABSTRACT_SCENE_VIEW{"Abstract Scene View"}; static inline const char* RESOURCES{"Resources"}; static inline const char* SCENE_GRAPH{"Scene Graph"}; static inline const char* UNDO_STACK{"Undo Stack"}; @@ -59,7 +63,6 @@ class MainWindow : public QMainWindow { QWidget* parent = nullptr); ~MainWindow(); - void setNewPreviewMenuEntryEnabled(bool enabled); void updateApplicationTitle(); void updateSavedLayoutMenu(); void updateUpgradeMenu(); @@ -68,7 +71,7 @@ class MainWindow : public QMainWindow { public Q_SLOTS: void showMeshImportErrorMessage(const std::string& filePath, const std::string& meshError); - void focusToObject(const QString& objectID); + void focusToSelection(const QString& objectID, const QString& property); protected: void timerEvent(QTimerEvent* event) override; @@ -84,11 +87,13 @@ public Q_SLOTS: void regenerateLayoutDocks(const RaCoDockManager::LayoutDocks& docks); void saveDockManagerCustomLayouts(); bool isUpgradePrevented(); + bool promptToReloadActiveProject(); protected Q_SLOTS: - void openProject(const QString& file = {}, int featureLevel = -1, bool generateNewObjectIDs = false); + void openProject(const QString& file = {}, int featureLevel = -1, bool generateNewObjectIDs = false, bool ignoreDirtiness = false); bool saveActiveProject(); bool upgradeActiveProject(int newFeatureLevel); + void activeProjectFileChanged(); bool saveAsActiveProject(bool newID = false); bool saveAsActiveProjectWithNewID(); void resetDockManager(); @@ -97,10 +102,33 @@ protected Q_SLOTS: Q_SIGNALS: void viewportChanged(const QSize& sceneSize); - void objectFocusRequestedForPropertyBrowser(const QString& objectID); - void objectFocusRequestedForTreeDock(const QString& objectID); + void focusRequestedForPropertyBrowser(const QString& objectID, const QString& property); + void focusRequestedForTreeDock(const QString& objectID, const QString& property); private: + RaCoDockManager* createDockManager(); + static ads::CDockWidget* createDockWidget(const QString& title, QWidget *parent); + + ads::CDockAreaWidget* createAndAddTracePlayer(); + + ads::CDockAreaWidget* createAndAddPreview(const char* dockObjName); + ads::CDockAreaWidget* createAndAddAbstractSceneView(const char* dockObjName); + ads::CDockAreaWidget* createAndAddPropertyBrowser(const char* dockObjName); + ads::CDockAreaWidget* createAndAddSceneGraphTree(const char* dockObjName); + void createAndAddProjectSettings(const char* dockObjName); + + ads::CDockAreaWidget* createAndAddPrefabTree(const char* dockObjName, ads::CDockAreaWidget* dockArea); + ads::CDockAreaWidget* createAndAddResourceTree(const char* dockObjName, ads::CDockAreaWidget* dockArea); + ads::CDockAreaWidget* createAndAddUndoView(const char* dockObjName, ads::CDockAreaWidget* dockArea = nullptr); + ads::CDockAreaWidget* createAndAddErrorView(const char* dockObjName, ads::CDockAreaWidget* dockArea = nullptr); + ads::CDockAreaWidget* createAndAddLogView(const char* dockObjName, ads::CDockAreaWidget* dockArea = nullptr); + ads::CDockAreaWidget* createAndAddPythonRunner(const char* dockObjName, ads::CDockAreaWidget* dockArea = nullptr); + ads::CDockAreaWidget* createAndAddProjectBrowser(const char* dockObjName, ads::CDockAreaWidget* dockArea); + + ads::CDockAreaWidget* createAndAddObjectTree(const char* title, const char* dockObjName, raco::object_tree::model::ObjectTreeViewDefaultModel* dockModel, raco::object_tree::model::ObjectTreeViewDefaultSortFilterProxyModel* sortFilterModel, ads::DockWidgetArea area, ads::CDockAreaWidget* dockArea); + + void createInitialWidgets(); + Ui::MainWindow* ui; OpenRecentMenu* recentFileMenu_; RaCoDockManager* dockManager_; diff --git a/EditorApp/mainwindow.ui b/EditorApp/mainwindow.ui index ea3d4879..59a80ee2 100644 --- a/EditorApp/mainwindow.ui +++ b/EditorApp/mainwindow.ui @@ -74,6 +74,7 @@ + @@ -131,9 +132,9 @@ - - Save As with new &ID... - + + Save As with new &ID... + @@ -249,7 +250,12 @@ New Pyt&hon Runner - + + + + New &Abstract Scene View + + diff --git a/EditorApp/versiondialog.cpp b/EditorApp/versiondialog.cpp index 252628ad..eeaeb680 100644 --- a/EditorApp/versiondialog.cpp +++ b/EditorApp/versiondialog.cpp @@ -15,10 +15,6 @@ #define RAMSES_VERSION "?.?.?" #endif -#ifndef RLOGIC_VERSION -#define RLOGIC_VERSION "?.?.?" -#endif - #ifndef RACO_OSS_COMMIT #define RACO_OSS_COMMIT "???" #endif @@ -36,8 +32,6 @@ VersionDialog::VersionDialog(QWidget *parent) : ui->ramsesComposerCommit->setText(QString(RACO_OSS_COMMIT)); ui->ramsesVersion->setText(QString::fromStdString(raco::ramses_base::getRamsesVersionString())); ui->ramsesBuiltVersion->setText(QString(RAMSES_VERSION)); - ui->logicEngineVersion->setText(QString::fromStdString(raco::ramses_base::getLogicEngineVersionString())); - ui->logicEngineBuiltVersion->setText(QString(RLOGIC_VERSION)); } VersionDialog::~VersionDialog() diff --git a/EditorApp/versiondialog.ui b/EditorApp/versiondialog.ui index 07f3650d..3b1a955d 100644 --- a/EditorApp/versiondialog.ui +++ b/EditorApp/versiondialog.ui @@ -7,7 +7,7 @@ 0 0 326 - 193 + 178 @@ -23,13 +23,6 @@ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - Logic Engine (built against) - - - @@ -44,20 +37,6 @@ - - - - - - - - - - - - - - @@ -65,15 +44,15 @@ - - + + - Logic Engine + - - + + @@ -86,8 +65,8 @@ - - + + @@ -100,13 +79,6 @@ - - - - - - - diff --git a/HeadlessApp/CMakeLists.txt b/HeadlessApp/CMakeLists.txt index 0cb5fe38..e3b4b89e 100644 --- a/HeadlessApp/CMakeLists.txt +++ b/HeadlessApp/CMakeLists.txt @@ -27,8 +27,6 @@ PUBLIC raco::RamsesBase raco::UserTypes raco::LogSystem - raco::ramses-lib-client-only - raco::ramses-logic-lib-client-only Qt5::Core raco::PythonAPI PRIVATE diff --git a/HeadlessApp/main.cpp b/HeadlessApp/main.cpp index d99e71e1..e16910d1 100644 --- a/HeadlessApp/main.cpp +++ b/HeadlessApp/main.cpp @@ -30,32 +30,34 @@ namespace py = pybind11; +using namespace raco; + class Worker : public QObject { Q_OBJECT public: - Worker(QObject* parent, QString& projectFile, QString& exportPath, QString& pythonScriptPath, QStringList& pythonSearchPaths, bool compressExport, QStringList positionalArguments, int featureLevel, raco::application::ELuaSavingMode luaSavingMode) - : QObject(parent), projectFile_(projectFile), exportPath_(exportPath), pythonScriptPath_(pythonScriptPath), pythonSearchPaths_(pythonSearchPaths), compressExport_(compressExport), positionalArguments_(positionalArguments), featureLevel_(featureLevel), luaSavingMode_(luaSavingMode) { + Worker(QObject* parent, QString& projectFile, QString& exportPath, QString& pythonScriptPath, QStringList& pythonSearchPaths, bool compressExport, QStringList positionalArguments, int featureLevel, raco::application::ELuaSavingMode luaSavingMode, ramses::RamsesFrameworkConfig ramsesConfig) + : QObject(parent), projectFile_(projectFile), exportPath_(exportPath), pythonScriptPath_(pythonScriptPath), pythonSearchPaths_(pythonSearchPaths), compressExport_(compressExport), positionalArguments_(positionalArguments), featureLevel_(featureLevel), luaSavingMode_(luaSavingMode), ramsesConfig_(ramsesConfig) { } public Q_SLOTS: void run() { - int initialFeatureLevel = featureLevel_ == -1 ? static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel) : featureLevel_; - raco::ramses_base::HeadlessEngineBackend backend{static_cast(initialFeatureLevel)}; + int initialFeatureLevel = featureLevel_ == -1 ? static_cast(ramses_base::BaseEngineBackend::maxFeatureLevel) : featureLevel_; + ramses_base::HeadlessEngineBackend backend(ramsesConfig_); std::unique_ptr app; try { app = std::make_unique(backend, raco::application::RaCoApplicationLaunchSettings{projectFile_, false, true, featureLevel_, featureLevel_, false}); } catch (const raco::application::FutureFileVersion& error) { - LOG_ERROR(raco::log_system::COMMON, "File load error: project file was created with newer file version {} but current file version is {}.", error.fileVersion_, raco::serialization::RAMSES_PROJECT_FILE_VERSION); + LOG_ERROR(log_system::COMMON, "File load error: project file was created with newer file version {} but current file version is {}.", error.fileVersion_, serialization::RAMSES_PROJECT_FILE_VERSION); app.reset(); exitCode_ = 1; - } catch (const raco::core::ExtrefError& error) { - LOG_ERROR(raco::log_system::COMMON, "File Load Error: external reference update failed with error {}.", error.what()); + } catch (const core::ExtrefError& error) { + LOG_ERROR(log_system::COMMON, "File Load Error: external reference update failed with error {}.", error.what()); app.reset(); exitCode_ = 1; } catch (const std::exception& error) { - LOG_ERROR(raco::log_system::COMMON, "File Load Error: {}", error.what()); + LOG_ERROR(log_system::COMMON, "File Load Error: {}", error.what()); app.reset(); exitCode_ = 1; } @@ -77,20 +79,19 @@ public Q_SLOTS: wPythonSearchPaths.emplace_back(path.toStdWString()); } - auto currentRunStatus = raco::python_api::runPythonScript(app.get(), QCoreApplication::applicationFilePath().toStdWString(), pythonScriptPath_.toStdString(), wPythonSearchPaths, pos_argv_cp); + auto currentRunStatus = python_api::runPythonScript(app.get(), QCoreApplication::applicationFilePath().toStdWString(), pythonScriptPath_.toStdString(), wPythonSearchPaths, pos_argv_cp); exitCode_ = currentRunStatus.exitCode; - LOG_INFO(raco::log_system::PYTHON, currentRunStatus.stdOutBuffer); + LOG_INFO(log_system::PYTHON, currentRunStatus.stdOutBuffer); if (!currentRunStatus.stdErrBuffer.empty()) { - LOG_ERROR(raco::log_system::PYTHON, currentRunStatus.stdErrBuffer); + LOG_ERROR(log_system::PYTHON, currentRunStatus.stdErrBuffer); } } else if (!exportPath_.isEmpty()) { QString ramsesPath = exportPath_ + "." + raco::names::FILE_EXTENSION_RAMSES_EXPORT; - QString logicPath = exportPath_ + "." + raco::names::FILE_EXTENSION_LOGIC_EXPORT; std::string error; - if (!app->exportProject(ramsesPath.toStdString(), logicPath.toStdString(), compressExport_, error, false, luaSavingMode_)) { - LOG_ERROR(raco::log_system::COMMON, "error exporting to {}\n{}", ramsesPath.toStdString(), error.c_str()); + if (!app->exportProject(ramsesPath.toStdString(), compressExport_, error, false, luaSavingMode_)) { + LOG_ERROR(log_system::COMMON, "error exporting to {}\n{}", ramsesPath.toStdString(), error.c_str()); exitCode_ = 1; } } @@ -112,35 +113,11 @@ public Q_SLOTS: int featureLevel_; raco::application::ELuaSavingMode luaSavingMode_; int exitCode_ = 0; + ramses::RamsesFrameworkConfig ramsesConfig_; }; #include "main.moc" -spdlog::level::level_enum getLevelFromArg(const QString& arg) { - bool logLevelValid; - int logLevel = arg.toInt(&logLevelValid); - spdlog::level::level_enum spdLogLevel; - switch (logLevelValid ? logLevel : -1) { - case 0: - return spdlog::level::level_enum::off; - case 1: - return spdlog::level::level_enum::critical; - case 2: - return spdlog::level::level_enum::err; - case 3: - return spdlog::level::level_enum::warn; - case 4: - return spdlog::level::level_enum::info; - case 5: - return spdlog::level::level_enum::debug; - case 6: - return spdlog::level::level_enum::trace; - default: - LOG_WARNING(raco::log_system::COMMON, "Invalid Log Level: \"{}\". Continuing with verbose log output.", arg.toStdString().c_str()); - return spdlog::level::level_enum::trace; - } -} - int main(int argc, char* argv[]) { QCoreApplication::setApplicationName("Ramses Composer Headless"); QCoreApplication::setApplicationVersion(RACO_OSS_VERSION); @@ -174,6 +151,7 @@ int main(int argc, char* argv[]) { "Maximum information level that should be printed as console log output. Possible options: 0 (off), 1 (critical), 2 (error), 3 (warn), 4 (info), 5 (debug), 6 (trace).", "log-level", "6"); + QCommandLineOption pyrunOption( QStringList() << "r" << "run", @@ -188,9 +166,9 @@ int main(int argc, char* argv[]) { QCommandLineOption ramsesLogicFeatureLevel( QStringList() << "f" << "featurelevel", - fmt::format("RamsesLogic feature level (-1, {} ... {})", static_cast(raco::ramses_base::BaseEngineBackend::minFeatureLevel), static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel)).c_str(), + fmt::format("RamsesLogic feature level (-1, {} ... {})", static_cast(ramses_base::BaseEngineBackend::minFeatureLevel), static_cast(ramses_base::BaseEngineBackend::maxFeatureLevel)).c_str(), "feature-level", - QString::fromStdString(std::to_string(static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel)))); + QString::fromStdString(std::to_string(static_cast(ramses_base::BaseEngineBackend::maxFeatureLevel)))); QCommandLineOption pythonPathOption( QStringList() << "y" << "pythonpath", @@ -208,25 +186,28 @@ int main(int argc, char* argv[]) { parser.addOption(compressExportAction); parser.addOption(noDumpFileCheckOption); parser.addOption(logLevelOption); + + ramses_base::addRamseFrameworkOptions(parser); + parser.addOption(pyrunOption); parser.addOption(logFileOutputOption); parser.addOption(ramsesLogicFeatureLevel); parser.addOption(pythonPathOption); parser.addOption(luaSavingModeOption); - + // application must be instantiated before parsing command line QCoreApplication a(argc, argv); parser.process(QCoreApplication::arguments()); bool noDumpFiles = parser.isSet(noDumpFileCheckOption); - raco::utils::crashdump::installCrashDumpHandler(noDumpFiles); + utils::crashdump::installCrashDumpHandler(noDumpFiles); - auto appDataPath = raco::utils::u8path(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation).toStdString()).parent_path() / "RamsesComposer"; - raco::core::PathManager::init(QCoreApplication::applicationDirPath().toStdString(), appDataPath); + auto appDataPath = utils::u8path(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation).toStdString()).parent_path() / "RamsesComposer"; + core::PathManager::init(QCoreApplication::applicationDirPath().toStdString(), appDataPath); auto customLogFileName = parser.value(logFileOutputOption).toStdString(); - auto logFilePath = raco::utils::u8path(customLogFileName); + auto logFilePath = utils::u8path(customLogFileName); bool customLogFileNameFailed = false; if (!customLogFileName.empty()) { @@ -240,22 +221,26 @@ int main(int argc, char* argv[]) { } if (!customLogFileName.empty() && !customLogFileNameFailed) { - raco::log_system::init(logFilePath); + log_system::init(logFilePath); } else { - raco::log_system::init(raco::core::PathManager::logFileDirectory(), std::string(raco::core::PathManager::LOG_FILE_HEADLESS_BASE_NAME), QCoreApplication::applicationPid()); + log_system::init(core::PathManager::logFileDirectory(), std::string(core::PathManager::LOG_FILE_HEADLESS_BASE_NAME), QCoreApplication::applicationPid()); } if (customLogFileNameFailed) { // TODO why is this an error: we seem to be able to continue so make this a warning instead!? // TODO this error only appears in log file but not on stdout if invoked from command line!! why?? - LOG_ERROR(raco::log_system::LOGGING, "Could not create log file at: " + customLogFileName + ". Using default location instead: " + logFilePath.string()); + LOG_ERROR(log_system::LOGGING, "Could not create log file at: " + customLogFileName + ". Using default location instead: " + logFilePath.string()); } - auto logLevel = getLevelFromArg(parser.value(logLevelOption)); - raco::log_system::setConsoleLogLevel(logLevel); - raco::ramses_base::setRamsesLogLevel(logLevel); - raco::ramses_base::setLogicLogLevel(logLevel); + auto logLevel = ramses_base::getLevelFromArg(parser.value(logLevelOption)); + log_system::setConsoleLogLevel(logLevel); + + ramses::RamsesFrameworkConfig ramsesConfig(ramses_base::BaseEngineBackend::defaultRamsesFrameworkConfig()); + for (auto category : ramses_base::ramsesLogCategories()) { + ramsesConfig.setLogLevel(category.toStdString(), ramses_base::getRamsesLogLevelFromArg(parser.value(category))); + } + QString projectFile{}; if (parser.isSet(loadProjectAction)) { QFileInfo path(parser.value(loadProjectAction)); @@ -270,8 +255,6 @@ int main(int argc, char* argv[]) { exportPath = path.absoluteFilePath(); if (path.suffix().compare(raco::names::FILE_EXTENSION_RAMSES_EXPORT, Qt::CaseInsensitive) == 0) { exportPath.chop(static_cast(strlen(raco::names::FILE_EXTENSION_RAMSES_EXPORT) + 1)); - } else if (path.suffix().compare(raco::names::FILE_EXTENSION_LOGIC_EXPORT, Qt::CaseInsensitive) == 0) { - exportPath.chop(static_cast(strlen(raco::names::FILE_EXTENSION_LOGIC_EXPORT) + 1)); } } @@ -279,15 +262,15 @@ int main(int argc, char* argv[]) { if (parser.isSet(pyrunOption)) { QFileInfo path(parser.value(pyrunOption)); if (path.exists()) { - if (raco::utils::u8path(path.filePath().toStdString()).userHasReadAccess()) { + if (utils::u8path(path.filePath().toStdString()).userHasReadAccess()) { pythonScriptPath = path.absoluteFilePath(); } else { - LOG_ERROR(raco::log_system::PYTHON, "Python script file could not be read {}", path.filePath().toStdString()); + LOG_ERROR(log_system::PYTHON, "Python script file could not be read {}", path.filePath().toStdString()); // TODO needs test exit(1); } } else { - LOG_ERROR(raco::log_system::PYTHON, "Python script file not found {}", path.filePath().toStdString()); + LOG_ERROR(log_system::PYTHON, "Python script file not found {}", path.filePath().toStdString()); exit(1); } } @@ -297,15 +280,15 @@ int main(int argc, char* argv[]) { pythonSearchPaths = parser.values(pythonPathOption); } - LOG_INFO(raco::log_system::PYTHON, "positional arguments = {}", parser.positionalArguments().join(", ").toStdString()); + LOG_INFO(log_system::PYTHON, "positional arguments = {}", parser.positionalArguments().join(", ").toStdString()); int featureLevel = -1; if (parser.isSet(ramsesLogicFeatureLevel)) { featureLevel = parser.value(ramsesLogicFeatureLevel).toInt(); if (!(featureLevel == -1 || - featureLevel >= static_cast(raco::ramses_base::BaseEngineBackend::minFeatureLevel) && - featureLevel <= static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel))) { - LOG_ERROR(raco::log_system::COMMON, fmt::format("RamsesLogic feature level {} outside valid range (-1, {} ... {})", featureLevel, static_cast(raco::ramses_base::BaseEngineBackend::minFeatureLevel), static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel))); + featureLevel >= static_cast(ramses_base::BaseEngineBackend::minFeatureLevel) && + featureLevel <= static_cast(ramses_base::BaseEngineBackend::maxFeatureLevel))) { + LOG_ERROR(log_system::COMMON, fmt::format("RamsesLogic feature level {} outside valid range (-1, {} ... {})", featureLevel, static_cast(ramses_base::BaseEngineBackend::minFeatureLevel), static_cast(ramses_base::BaseEngineBackend::maxFeatureLevel))); exit(1); } } @@ -320,12 +303,12 @@ int main(int argc, char* argv[]) { } else if (option == "source_and_byte_code") { luaSavingMode = raco::application::ELuaSavingMode::SourceAndByteCode; } else { - LOG_ERROR(raco::log_system::COMMON, fmt::format("Invalid lua saving mode: {}. Possible values are: source_code (default), byte_code, source_and_byte_code.", option.toStdString())); + LOG_ERROR(log_system::COMMON, fmt::format("Invalid lua saving mode: {}. Possible values are: source_code (default), byte_code, source_and_byte_code.", option.toStdString())); exit(1); } } - Worker* task = new Worker(&a, projectFile, exportPath, pythonScriptPath, pythonSearchPaths, compressExport, parser.positionalArguments(), featureLevel, luaSavingMode); + Worker* task = new Worker(&a, projectFile, exportPath, pythonScriptPath, pythonSearchPaths, compressExport, parser.positionalArguments(), featureLevel, luaSavingMode, ramsesConfig); QObject::connect(task, &Worker::finished, &QCoreApplication::exit); QTimer::singleShot(0, task, &Worker::run); diff --git a/HeadlessApp/tests/CMakeLists.txt b/HeadlessApp/tests/CMakeLists.txt index d77b1d88..b904f1c5 100644 --- a/HeadlessApp/tests/CMakeLists.txt +++ b/HeadlessApp/tests/CMakeLists.txt @@ -40,8 +40,9 @@ set_tests_properties(RaCoHeadless_load_multi_file_zip PROPERTIES WILL_FAIL True) add_racocommand_test(RaCoHeadless_load_success "${CMAKE_CURRENT_BINARY_DIR}" "-p" "${CMAKE_SOURCE_DIR}/resources/example_scene.rca") add_racocommand_test(RaCoHeadless_export_lua_saving_mode_source_code_success "${CMAKE_CURRENT_BINARY_DIR}" "-p" "${CMAKE_SOURCE_DIR}/resources/example_scene.rca" "-e" "lua_saving_mode_source" "-s" "source_code") -add_racocommand_test(RaCoHeadless_export_lua_saving_mode_byte_code_fl2_success "${CMAKE_CURRENT_BINARY_DIR}" "-p" "${CMAKE_SOURCE_DIR}/resources/example_scene.rca" "-e" "lua_saving_mode_byte_fl2" "-s" "byte_code" "-f" "2") -add_racocommand_test(RaCoHeadless_export_lua_saving_mode_source_and_byte_code_fl2_success "${CMAKE_CURRENT_BINARY_DIR}" "-p" "${CMAKE_SOURCE_DIR}/resources/example_scene.rca" "-e" "lua_saving_mode_source_byte_fl2" "-s" "source_and_byte_code" "-f" "2") +add_racocommand_test(RaCoHeadless_export_lua_saving_mode_byte_code_success "${CMAKE_CURRENT_BINARY_DIR}" "-p" "${CMAKE_SOURCE_DIR}/resources/example_scene.rca" "-e" "lua_saving_mode_byte" "-s" "byte_code") +add_racocommand_test(RaCoHeadless_export_lua_saving_mode_source_and_byte_code_success "${CMAKE_CURRENT_BINARY_DIR}" "-p" "${CMAKE_SOURCE_DIR}/resources/example_scene.rca" "-e" "lua_saving_mode_source_byte" "-s" "source_and_byte_code" +) add_racocommand_test(RaCoHeadless_export_lua_saving_mode_long_option "${CMAKE_CURRENT_BINARY_DIR}" "-p" "${CMAKE_SOURCE_DIR}/resources/example_scene.rca" "-e" "lua_saving_mode_long_option_source" "--luasavingmode" "source_code") add_racocommand_test(RaCoHeadless_export_lua_saving_mode_fail "${CMAKE_CURRENT_BINARY_DIR}" "-p" "${CMAKE_SOURCE_DIR}/resources/example_scene.rca" "-e" "lua_saving_mode_fail" "-s" "invalid_setting") set_tests_properties(RaCoHeadless_export_lua_saving_mode_fail PROPERTIES WILL_FAIL True) diff --git a/PyAPITests/CMakeLists.txt b/PyAPITests/CMakeLists.txt index 687cebdd..438dd06d 100644 --- a/PyAPITests/CMakeLists.txt +++ b/PyAPITests/CMakeLists.txt @@ -12,8 +12,6 @@ macro(add_python_test TESTNAME) add_racocommand_test("PyAPI_${TESTNAME}" "${CMAKE_CURRENT_SOURCE_DIR}" -r run_test.py "${TESTNAME}") endmacro() -add_racocommand_test("PyAPI_feature_level_1_checks" "${CMAKE_CURRENT_SOURCE_DIR}" -f 1 -r run_test.py feature_level_1_checks) - add_python_test(pyt_general) add_python_test(exit_code) diff --git a/PyAPITests/feature_level_1_checks.py b/PyAPITests/feature_level_1_checks.py deleted file mode 100644 index 892788dc..00000000 --- a/PyAPITests/feature_level_1_checks.py +++ /dev/null @@ -1,76 +0,0 @@ -# -# SPDX-License-Identifier: MPL-2.0 -# -# This file is part of Ramses Composer -# (see https://github.com/bmwcarit/ramses-composer). -# -# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. -# If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -import unittest -import raco -import os - -class FeatureLevel_1(unittest.TestCase): - def setUp(self): - raco.reset() - - def cwd(self): - return os.getcwd() - - def test_node_enabled_fail(self): - node = raco.create("Node", "node") - self.assertEqual(dir(node), ['objectName', 'rotation', 'scaling', 'translation', 'visibility']) - - with self.assertRaises(RuntimeError): - tmp = node.enabled.value() - - with self.assertRaises(RuntimeError): - node.enabled = False - - - def test_anchor_point_fail(self): - with self.assertRaises(RuntimeError): - anchor = raco.create("AnchorPoint", "test_anchor") - - - def test_perspective_camera_frustum_fail(self): - camera = raco.create("PerspectiveCamera", "camera") - - with self.assertRaises(RuntimeError): - tmp = camera.frustumType.value() - - with self.assertRaises(RuntimeError): - camera.frustumType = raco.EFrustumType.Planes - - with self.assertRaises(RuntimeError): - camera.frustum.leftPlane = 1.0 - - def test_renderpass_prop_fail(self): - renderpass = raco.create("RenderPass", "render_pass") - - with self.assertRaises(RuntimeError): - dummy = renderpass.renderOnce.value() - - with self.assertRaises(RuntimeError): - renderpass.renderOnce = True - - def test_renderpass_link_fail(self): - lua = raco.create("LuaScript", "lua") - lua.uri = self.cwd() + R"/../resources/scripts/types-scalar.lua" - - renderpass = raco.create("RenderPass", "render_pass") - - self.assertEqual(renderpass.enabled.value(), True) - with self.assertRaises(RuntimeError): - raco.addLink(lua.outputs.obool, renderpass.enabled) - - self.assertEqual(renderpass.renderOrder.value(), 1) - with self.assertRaises(RuntimeError): - raco.addLink(lua.outputs.ointeger, renderpass.renderOrder) - - self.assertEqual(renderpass.clearColor.x.value(), 0.0) - with self.assertRaises(RuntimeError): - raco.addLink(lua.outputs.ovector4f, renderpass.clearColor) - - \ No newline at end of file diff --git a/PyAPITests/pyt_general.py b/PyAPITests/pyt_general.py index 7a8ae45f..59e4d07f 100644 --- a/PyAPITests/pyt_general.py +++ b/PyAPITests/pyt_general.py @@ -39,8 +39,8 @@ def test_reset(self): def test_reset_feature_levels(self): raco.reset(1) self.assertEqual(raco.projectFeatureLevel(), 1) - raco.reset(2) - self.assertEqual(raco.projectFeatureLevel(), 2) + raco.reset(raco.maxFeatureLevel()) + self.assertEqual(raco.projectFeatureLevel(), raco.maxFeatureLevel()) def test_load(self): raco.load(self.cwd() + "/../resources/example_scene.rca") @@ -72,25 +72,37 @@ def test_load(self): with self.assertRaises(RuntimeError): raco.load(self.cwd() + "/../resources/multi-file-zip.rca") - def test_load_feature_levels(self): - raco.load(self.cwd() + "/../resources/empty-fl1.rca") + def test_load_raco_1x_feature_levels(self): + raco.load(self.cwd() + "/../resources/empty-raco-1x-fl1.rca") self.assertEqual(raco.projectFeatureLevel(), 1) - raco.load(self.cwd() + "/../resources/empty-fl1.rca", 1) + raco.load(self.cwd() + "/../resources/empty-raco-1x-fl1.rca", 1) self.assertEqual(raco.projectFeatureLevel(), 1) - raco.load(self.cwd() + "/../resources/empty-fl1.rca", 2) - self.assertEqual(raco.projectFeatureLevel(), 2) + raco.load(self.cwd() + "/../resources/empty-raco-1x-fl1.rca", raco.maxFeatureLevel()) + self.assertEqual(raco.projectFeatureLevel(), raco.maxFeatureLevel()) - raco.load(self.cwd() + "/../resources/empty-fl2.rca") - self.assertEqual(raco.projectFeatureLevel(), 2) + raco.load(self.cwd() + "/../resources/empty-raco-1x-fl2.rca") + self.assertEqual(raco.projectFeatureLevel(), 1) - with self.assertRaises(RuntimeError): - raco.load(self.cwd() + "/../resources/empty-fl2.rca", 1) + raco.load(self.cwd() + "/../resources/empty-raco-1x-fl2.rca", 1) + self.assertEqual(raco.projectFeatureLevel(), 1) + + raco.load(self.cwd() + "/../resources/empty-raco-1x-fl2.rca", raco.maxFeatureLevel()) + self.assertEqual(raco.projectFeatureLevel(), raco.maxFeatureLevel()) + + def test_load_raco_2x_feature_levels(self): + raco.load(self.cwd() + "/../resources/empty-raco-2x-fl1.rca") + self.assertEqual(raco.projectFeatureLevel(), 1) + + raco.load(self.cwd() + "/../resources/empty-raco-2x-fl1.rca", 1) self.assertEqual(raco.projectFeatureLevel(), 1) - raco.load(self.cwd() + "/../resources/empty-fl2.rca", 2) - self.assertEqual(raco.projectFeatureLevel(), 2) + raco.load(self.cwd() + "/../resources/empty-raco-2x-fl1.rca", raco.maxFeatureLevel()) + self.assertEqual(raco.projectFeatureLevel(), raco.maxFeatureLevel()) + + # TODO check that feature level downgrade is not possible: + # currently can't be tested since max feature level is 1 def test_save_check_object_id(self): objectInitID = self.findObjectByType("ProjectSettings").objectID() @@ -138,8 +150,8 @@ def test_object_functions(self): self.assertEqual(node.parent(), None) self.assertEqual(node.children(), []) self.assertTrue(node.objectID() != None) - self.assertEqual(dir(node), ['enabled', 'objectName', 'rotation', 'scaling', 'translation', 'visibility']) - self.assertEqual(node.keys(), ['objectName', 'visibility', 'enabled', 'translation', 'rotation', 'scaling']) + self.assertEqual(dir(node), ['enabled', 'metaData', 'objectName', 'rotation', 'scaling', 'translation', 'visibility']) + self.assertEqual(node.keys(), ['objectName', 'metaData', 'visibility', 'enabled', 'translation', 'rotation', 'scaling']) self.assertTrue(node.objectName, "my_node") self.assertTrue(node["objectName"], "my_node") @@ -799,11 +811,11 @@ def test_engine_update_lua_link(self): self.assertEqual(end.inputs.in_float.value(), 2.0) - def test_feature_level_2_node_enabled(self): + def test_node_enabled(self): node = raco.create("Node", "node") self.assertEqual(node.enabled.value(), True) - def test_feature_level_2_perspective_camera_frustum(self): + def test_perspective_camera_frustum(self): camera = raco.create("PerspectiveCamera", "camera") self.assertEqual(camera.frustumType.value(), raco.EFrustumType.Aspect_FoV) @@ -823,18 +835,18 @@ def test_feature_level_2_perspective_camera_frustum(self): camera.frustumType = raco.EFrustumType.Aspect_FoV self.assertEqual(camera.frustum.aspectRatio.value(), 3.0) - def test_feature_level_2_anchor_point(self): + def test_anchor_point(self): node = raco.create("Node", "node") anchor = raco.create("AnchorPoint", "test_anchor") anchor.node = node - def test_feature_level_2_renderpass_prop(self): + def test_renderpass_prop(self): renderpass = raco.create("RenderPass", "render_pass") self.assertEqual(renderpass.renderOnce.value(), False) - def test_feature_level_2_renderpass_link(self): + def test_renderpass_link(self): lua = raco.create("LuaScript", "lua") lua.uri = self.cwd() + R"/../resources/scripts/types-scalar.lua" @@ -1122,16 +1134,17 @@ def test_import_gltf_invalid_path(self): raco.importGLTF("thisShouldNotExist.gltf") def test_get_mesh_metadata(self): - node = raco.create("Node", "node1") - self.assertEqual(None, node.metadata()) - mesh = raco.create("Mesh", "mesh1") - self.assertEqual(None, mesh.metadata()) + with self.assertRaises(RuntimeError): + mesh.metadata() + + self.assertFalse("gltfExtras" in mesh.metaData.keys()) mesh.uri = self.cwd() + R"/../resources/meshes/CesiumMilkTruck/CesiumMilkTruck.gltf" mesh.bakeMeshes = False mesh.meshIndex = 1 - self.assertEqual({'prop1': 'truck mesh property'}, mesh.metadata()) + self.assertTrue("gltfExtras" in mesh.metaData.keys()) + self.assertEqual(mesh.metaData.gltfExtras.prop1.value(), 'truck mesh property') def test_setTags(self): node = raco.create("Node", "node") @@ -1172,7 +1185,7 @@ def test_setUserTags(self): texture.setUserTags(['foo', 'bar']) self.assertEqual(texture.getUserTags(), ['foo', 'bar']) - def test_feature_level_3_render_order(self): + def test_render_order(self): lua = raco.create("LuaScript", "lua") lua.uri = self.cwd() + R"/../resources/scripts/types-scalar.lua" @@ -1244,50 +1257,27 @@ def test_add_external_references_multiple_times_same_types_should_work(self): # Export with specified lua save mode, assert success and cleanup def export(self, name, save_mode): out_dir = self.cwd() - logic_file = os.path.join(out_dir, f'{name}.rlogic') ramses_file = os.path.join(out_dir, f'{name}.ramses') - if os.path.exists(logic_file): - os.remove(logic_file) + if os.path.exists(ramses_file): + os.remove(ramses_file) try: - raco.export( - ramses_file, - logic_file, - False, - save_mode) - self.assertEqual(os.path.exists(logic_file), True) + raco.export(ramses_file, False, save_mode) + self.assertEqual(os.path.exists(ramses_file), True) except RuntimeError: raise finally: - if os.path.exists(logic_file): - os.remove(logic_file) if os.path.exists(ramses_file): os.remove(ramses_file) - def test_feature_level_2_export_lua_save_mode(self): + def test_export_lua_save_mode(self): # Add a lua script to project lua = raco.create("LuaScript", "lua") lua.uri = self.cwd() + R"/../resources/scripts/types-scalar.lua" - # All available modes are supported starting from Feature Level 2 self.export("lua_SourceCodeOnly", raco.ELuaSavingMode.SourceCodeOnly) self.export("lua_ByteCodeOnly", raco.ELuaSavingMode.ByteCodeOnly) self.export("lua_SourceAndByteCode", raco.ELuaSavingMode.SourceAndByteCode) - def test_feature_level_1_export_lua_save_mode(self): - raco.reset(1) - - # Add a lua script to project - lua = raco.create("LuaScript", "lua") - lua.uri = self.cwd() + R"/../resources/scripts/types-scalar.lua" - - # In Feature Level 1 only Source Code lua saving mode is supported - self.export("lua_SourceCodeOnly_FL1", raco.ELuaSavingMode.SourceCodeOnly) - # Ramses Logic treats SourceAndByteCode as SourceCodeOnly and exports successfully - self.export("lua_SourceAndByteCode_FL1", raco.ELuaSavingMode.SourceAndByteCode) - - # Ramses Logic rejects ByteCodeOnly - with self.assertRaises(RuntimeError): - self.export("lua_ByteCodeOnly_FL1", raco.ELuaSavingMode.ByteCodeOnly) def test_resolveUriPropertyToAbsolutePath (self): # load scene to obtain known current project folder: @@ -1306,4 +1296,29 @@ def test_resolveUriPropertyToAbsolutePath (self): self.assertEqual(os.path.normpath(abs_path), os.path.normpath(self.cwd() + "/../scripts/types-scalar.lua")) with self.assertRaises(RuntimeError): - raco.resolveUriPropertyToAbsolutePath(lua.objectName) \ No newline at end of file + raco.resolveUriPropertyToAbsolutePath(lua.objectName) + + def test_array_resize(self): + # grow + skin = raco.create("Skin", "skin") + self.assertEqual(len(skin.targets.keys()), 1) + + skin.targets.resize(3) + self.assertEqual(len(skin.targets.keys()), 3) + + # shrink + target = raco.create("RenderTarget", "target") + self.assertEqual(len(target.buffers.keys()), 1) + + target.buffers.resize(3) + self.assertEqual(len(target.buffers.keys()), 3) + + # invalid property + node = raco.create("Node", "node") + with self.assertRaises(RuntimeError): + node.translation.resize(1) + + # not resizable + with self.assertRaises(RuntimeError): + skin.joints.resizeArray(2) + diff --git a/README.md b/README.md index cbeccd36..11a9c437 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,15 @@ The authoring tool for the RAMSES rendering ecosystem. Find the [user documentation here](https://ramses-composer.readthedocs.io/). Find a broader overview of [the Ramses SDK here](https://ramses-sdk.readthedocs.io/). +## Building -## Setup +### Dependencies + +Building RamsesComposer requires Qt 5.15.2 and CMake >=3.19 to be installed. Additionally, on Linux Python 3.8, linuxdeployqt, and gcc >=8 are needed. + +For platform-specific build instruction see below. + +### Setup Make sure you have Git LFS installed: @@ -34,12 +41,12 @@ To build Ramses Composer you first need to checkout and initialize it's dependen \raco> git submodule update --init --recursive ``` -## Environment variables +### Environment variables If your Qt installation is not in the default location (Currently: ```C:/Qt/5.15.2/msvc2019_64```), set the environment variable ```RACO_QT_BASE``` to it. -## Build with CMake +### Build with CMake ```console \raco> mkdir build @@ -48,7 +55,38 @@ set the environment variable ```RACO_QT_BASE``` to it. \raco\build> cmake --build . --target RaCoEditor --config # either Release or Debug ``` -Ramses Composer is built on Windows 10 with Visual Studio 2019 and on Ubuntu 18.04 with gcc 8.4.0. +Ramses Composer is built on Windows 10 with Visual Studio 2019 and on Ubuntu 20.04 with gcc 9.4.0. + +### Windows + +In order to install Qt headers and binaries, download the [official Qt online installer](https://www.qt.io/download-qt-installer) and select Qt 5.15.2 MSVC 2019 64-bit. + +### Linux (Ubuntu 20.04) + +The linux build needs newer versions of CMake and Qt than available from the Ubuntu 20.04 repositories. Install CMake >= 3.19 and Qt 5.15.2. + +Installing Qt into /usr/local/opt/Qt/5.15.2 can be done like this: +```console +apt-get install python3-pip +python3 -m pip install --upgrade pip +python3 -m pip install aqtinstall +python3 -m aqt install --outputdir /usr/local/opt/Qt 5.15.2 linux desktop +``` +Alternatively you can use the [official Qt installer](https://www.qt.io/download-qt-installer). + +The environment variable QTBASEDIR needs to be set to the Qt base directory when running CMake, e.g. to /usr/local/opt/Qt in the example above. + +To build ramses renderer dependent project you also need to install OpenGL dependencies: + +```console +sudo apt install libegl1-mesa +sudo apt install libegl1-mesa-dev +``` + +Further Python 3.8.0 needs to be installed to allow building Ramses Composer: +```console +sudo apt install python3.8-dev +``` ## Starting Ramses Composer @@ -66,7 +104,7 @@ Starting RaCoEditor with an extra console showing stdout (Windows only): Starting RaCoEditor with an extra console and configured ramses framework log levels: ```console -\raco\build\release\bin\\RamsesComposer.exe -c -r '--log-level-contexts-filter info:RAPI,off:RPER,debug:RRND,off:RFRA,off:RDSM,info:RCOM --log-level-console trace' +\raco\build\release\bin\\RamsesComposer.exe -c --RAPI 4 --RPER 0 --RRND 5 --RFRA 0 --RDSM 0' ``` RaCoEditor can also be given the initial project file as an command line argument: @@ -75,7 +113,7 @@ RaCoEditor can also be given the initial project file as an command line argumen ``` The `````` has to be either an absolute path or relative to the current working directory. -### Starting on Linux (Ubuntu 18.04) +### Starting on Linux (Ubuntu 20.04) The Linux release contains all required Qt shared libraries. Ramses Composer Headless and Ramses Composer can be started using the provided shell script `./RaCoHeadless.sh` resp. `./RamsesComposer.sh`. @@ -112,33 +150,6 @@ The build process for the Ramses Composer generates a "release" folder in the CM the distributed zip-files - so after building Ramses Composer the developer will run Ramses Composer in the same environment as the user. -## Linux (Ubuntu 18.04) - -The linux build needs newer versions of CMake and Qt than available from the Ubuntu 18.04 repositories. Install CMake >= 3.19 and Qt 5.15.2. It also needs gcc/g++ >=8 which is available from the Ubuntu 18.04 repositories. - -Installing Qt into /usr/local/opt/Qt/5.15.2 can be done like this: -```console -apt-get install python3-pip -python3 -m pip install --upgrade pip -python3 -m pip install aqtinstall -python3 -m aqt install --outputdir /usr/local/opt/Qt 5.15.2 linux desktop -``` -Alternatively you can use the [official Qt installer](https://www.qt.io/download-qt-installer). - -The environment variable QTBASEDIR needs to be set to the Qt base directory when running CMake, e.g. to /usr/local/opt/Qt in the example above. - -To build ramses renderer dependent project you also need to install OpenGL dependencies: - -```console -sudo apt install libegl1-mesa -sudo apt install libegl1-mesa-dev -``` - -Further Python 3.8.0 needs to be installed to allow building Ramses Composer: -```console -sudo apt install python3.8-dev -``` - ## Development ### Logging system @@ -159,12 +170,12 @@ LOG_DEBUG(COMMON, "The important value is {}.", importantValue); LOG(DEBUG, COMMON, "The important value is {}.", importantValue); LOG_DEBUG_IF(COMMON, importantValue > 1, "The important value is {}.", importantValue); ``` -We are using predifined log contexts (e.g. ```COMMON```, ```PROPERTY_BROWSER```) which are +We are using predefined log contexts (e.g. ```COMMON```, ```PROPERTY_BROWSER```) which are predeclared in ```log.h```. If you need a new log context add it there and also initialize a logger for this context during ```log_system::init()```. Available log levels are ```TRACE, DEBUG, INFO, WARNING, ERROR, CRITICAL```. -Further information about capabailites and formatting can be found at [spdlog](https://github.com/gabime/spdlog) and [fmt](https://github.com/fmtlib/fmt). +Further information about capabilities and formatting can be found at [spdlog](https://github.com/gabime/spdlog) and [fmt](https://github.com/fmtlib/fmt). ### Testing Example of how to use the raco::testing library: @@ -187,19 +198,42 @@ ${CMAKE_CURRENT_SOURCE_DIR} # source directory for the resources below ``` This example will create the setup for having a working directory with the specified resources already copied when using the testing/RacoBaseTest.h fixture. + +### Project structure visualization + +You can use cmake and graphviz to generate a dependency diagram between the cmake targets from inside the build/ directory as follows: +``` +cmake --graphviz=deps.dot .. +dot -Tpng -o deps.png deps.dot +``` +Graphviz needs to be installed for this. + + +### Debugging with Visual Studio + +To enable the Visual Studio debugger to use better visualization of the RamsesComposer data structures there are two `.natvis` files in the top-level repository directory. Copying them to the directory $HOME/Visual Studio 2022/Visualizers will allow Visual Studio to pick them up automatically. + +The attached visualizers are +* raco.natvis adds visualization for RamsesComposer data structures. Feel free to improve this and add more/better visualizations. +* qt5.natvis adds visualization for Qt data structures (e.g. strings). + + ## Third Party Components The UI is based on [Qt](https://www.qt.io). Qt is used as Open Source under the LGPL 3 license in the form of unmodified dynamic libraries from Qt 5.15.2. You can find the [source code here](https://github.com/bmwcarit/ramses-composer/releases/download/v0.8.1/qt-src-5.15.2.tgz). Ramses Composer uses a number of third party libraries: -* Python +* boost::spirit * glm * googletest +* lodepng +* Lua * OpenCTM-1.0.3 +* pybind11 +* Python * Qt Advanced Docking System * RAMSES -* RAMSES logic * spdlog * tinygltf * zip diff --git a/cmake/ramsesversions.cmake b/cmake/ramsesversions.cmake index bfe22f4b..ee771fe8 100644 --- a/cmake/ramsesversions.cmake +++ b/cmake/ramsesversions.cmake @@ -4,7 +4,3 @@ EXECUTE_PROCESS(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD WORKING_DIRECTO string(REGEX REPLACE "([0-9]+)\.([0-9]+)\.([0-9]+)" "\\1" RAMSES_VERSION_MAJOR "${ramses-sdk_VERSION}") string(REGEX REPLACE "([0-9]+)\.([0-9]+)\.([0-9]+)" "\\2" RAMSES_VERSION_MINOR "${ramses-sdk_VERSION}") string(REGEX REPLACE "([0-9]+)\.([0-9]+)\.([0-9]+)" "\\3" RAMSES_VERSION_PATCH "${ramses-sdk_VERSION}") - -string(REGEX REPLACE "([0-9]+)\.([0-9]+)\.([0-9]+)" "\\1" RLOGIC_VERSION_MAJOR "${ramses-logic_VERSION}") -string(REGEX REPLACE "([0-9]+)\.([0-9]+)\.([0-9]+)" "\\2" RLOGIC_VERSION_MINOR "${ramses-logic_VERSION}") -string(REGEX REPLACE "([0-9]+)\.([0-9]+)\.([0-9]+)" "\\3" RLOGIC_VERSION_PATCH "${ramses-logic_VERSION}") diff --git a/components/libApplication/include/application/ExternalProjectsStore.h b/components/libApplication/include/application/ExternalProjectsStore.h index 505c5938..fd09b77d 100644 --- a/components/libApplication/include/application/ExternalProjectsStore.h +++ b/components/libApplication/include/application/ExternalProjectsStore.h @@ -27,7 +27,7 @@ namespace raco::application { class RaCoApplication; -class ExternalProjectsStore : public raco::core::ExternalProjectsStoreInterface { +class ExternalProjectsStore : public core::ExternalProjectsStoreInterface { public: ExternalProjectsStore(RaCoApplication* app); @@ -38,14 +38,14 @@ class ExternalProjectsStore : public raco::core::ExternalProjectsStoreInterface bool isCurrent(const std::string& projectPath) const; // @return project if loaded successfully - raco::core::Project* addExternalProject(const std::string& projectPath, core::LoadContext& loadContext) override; + core::Project* addExternalProject(const std::string& projectPath, core::LoadContext& loadContext) override; void removeExternalProject(const std::string& projectPath) override; bool canRemoveExternalProject(const std::string& projectPath) const override; - raco::core::CommandInterface* getExternalProjectCommandInterface(const std::string& projectPath) const override; + core::CommandInterface* getExternalProjectCommandInterface(const std::string& projectPath) const override; bool isExternalProject(const std::string& projectPath) const override; - std::vector> allExternalProjects() const override; - raco::core::Project* getExternalProject(const std::string& projectPath) const override; + std::vector> allExternalProjects() const override; + core::Project* getExternalProject(const std::string& projectPath) const override; void setRelinkCallback(std::function relinkCallback) override; void clearRelinkCallback() override; @@ -77,7 +77,7 @@ class ExternalProjectsStore : public raco::core::ExternalProjectsStoreInterface components::ProjectFileChangeMonitor externalProjectFileChangeMonitor_; - std::unordered_map externalProjectFileChangeListeners_; + std::unordered_map externalProjectFileChangeListeners_; std::unique_ptr flError_; }; diff --git a/components/libApplication/include/application/RaCoApplication.h b/components/libApplication/include/application/RaCoApplication.h index b0612f0d..9bcfc8eb 100644 --- a/components/libApplication/include/application/RaCoApplication.h +++ b/components/libApplication/include/application/RaCoApplication.h @@ -31,7 +31,8 @@ class BaseEngineBackend; namespace raco::ramses_adaptor { class SceneBackend; -} +class AbstractSceneAdaptor; +} // namespace raco::ramses_adaptor namespace raco::application { @@ -52,7 +53,7 @@ struct RaCoApplicationLaunchSettings { bool runningInUI; }; -// Lua script saving mode. Wraps rlogic::ELuaSavingMode. +// Lua script saving mode. Wraps ramses::ELuaSavingMode. enum class ELuaSavingMode { SourceCodeOnly = 0, ByteCodeOnly, @@ -97,7 +98,6 @@ class RaCoApplication{ bool exportProject( const std::string& ramsesExport, - const std::string& logicExport, bool compress, std::string& outError, bool forceExportWithErrors = false, @@ -109,16 +109,17 @@ class RaCoApplication{ bool canSaveActiveProject() const; - raco::core::ExternalProjectsStoreInterface* externalProjects(); - raco::core::MeshCache* meshCache(); + core::ExternalProjectsStoreInterface* externalProjects(); + core::MeshCache* meshCache(); const core::SceneBackendInterface* sceneBackend() const; - raco::ramses_adaptor::SceneBackend* sceneBackendImpl() const; + ramses_adaptor::SceneBackend* sceneBackendImpl() const; + ramses_adaptor::AbstractSceneAdaptor* abstractScene() const; - raco::components::SDataChangeDispatcher dataChangeDispatcher(); + components::SDataChangeDispatcher dataChangeDispatcher(); - raco::core::EngineInterface* engine(); + core::EngineInterface* engine(); QString generateApplicationTitle() const; @@ -133,8 +134,8 @@ class RaCoApplication{ static int maxFeatureLevel(); static const std::string& featureLevelDescriptions(); - void setApplicationFeatureLevel(int featureLevel); - int applicationFeatureLevel() const; + void setNewFileFeatureLevel(int featureLevel); + int newFileFeatureLevel() const; bool rendererDirty_ = false; @@ -144,19 +145,21 @@ class RaCoApplication{ // Needs to access externalProjectsStore_ directly: friend class ::ObjectTreeViewExternalProjectModelTest; - bool exportProjectImpl(const std::string& ramsesExport, const std::string& logicExport, bool compress, std::string& outError, bool forceExportWithErrors, ELuaSavingMode luaSavingMode) const; + bool exportProjectImpl(const std::string& ramsesExport, bool compress, std::string& outError, bool forceExportWithErrors, ELuaSavingMode luaSavingMode) const; - void setupScene(bool optimizedForExport); + void setupScene(bool optimizedForExport, bool setupAbstractScene); ramses_base::BaseEngineBackend* engine_; - // The application feature level is used to set the feature level for newly created scenes. - int applicationFeatureLevel_; + // Used to set the feature level for newly created scenes. + int newFileFeatureLevel_; - raco::components::SDataChangeDispatcher dataChangeDispatcher_; - raco::components::SDataChangeDispatcher dataChangeDispatcherEngine_; + components::SDataChangeDispatcher dataChangeDispatcher_; + components::SDataChangeDispatcher dataChangeDispatcherPreviewScene_; + components::SDataChangeDispatcher dataChangeDispatcherAbstractScene_; - std::unique_ptr scenesBackend_; + std::unique_ptr previewSceneBackend_; + std::unique_ptr abstractScene_; components::MeshCacheImpl meshCache_; diff --git a/components/libApplication/include/application/RaCoProject.h b/components/libApplication/include/application/RaCoProject.h index 598c27e4..33ffc0fe 100644 --- a/components/libApplication/include/application/RaCoProject.h +++ b/components/libApplication/include/application/RaCoProject.h @@ -68,12 +68,14 @@ class RaCoProject : public QObject { */ static std::unique_ptr createNew(RaCoApplication* app, bool createDefaultScene, int featureLevel); + static int preloadFeatureLevel(const QString& filename, int featureLevel); + /** * @brief Loads and checks project file * @param filename path to the project file * @return file JSON content */ - static QJsonDocument loadFileDocument(const QFileInfo& fileInfo); + static QJsonDocument loadJsonDocument(const QString& filename); /** * @brief Load scene @@ -92,30 +94,30 @@ class RaCoProject : public QObject { // @exception ExtrefError void updateExternalReferences(core::LoadContext& loadContext); - raco::core::Project* project(); - raco::core::Errors const* errors() const; - raco::core::Errors* errors(); - raco::core::DataChangeRecorder* recorder(); - raco::core::CommandInterface* commandInterface(); - raco::core::UndoStack* undoStack(); - raco::core::MeshCache* meshCache(); - raco::components::TracePlayer& tracePlayer(); + core::Project* project(); + core::Errors const* errors() const; + core::Errors* errors(); + core::DataChangeRecorder* recorder(); + core::CommandInterface* commandInterface(); + core::UndoStack* undoStack(); + core::MeshCache* meshCache(); + components::TracePlayer& tracePlayer(); QJsonDocument serializeProject(const std::unordered_map>& currentVersions); void applyPreferences() const; void applyDefaultCachedPaths(); - void setupCachedPathSubscriptions(const raco::components::SDataChangeDispatcher& dataChangeDispatcher); + void setupCachedPathSubscriptions(const components::SDataChangeDispatcher& dataChangeDispatcher); Q_SIGNALS: void activeProjectFileChanged(); void projectSuccessfullySaved(); private: - void subscribeDefaultCachedPathChanges(const raco::components::SDataChangeDispatcher& dataChangeDispatcher); + void subscribeDefaultCachedPathChanges(const components::SDataChangeDispatcher& dataChangeDispatcher); // @exception ExtrefError - RaCoProject(const QString& file, raco::core::Project& p, raco::core::EngineInterface* engineInterface, const raco::core::UndoStack::Callback& callback, raco::core::ExternalProjectsStoreInterface* externalProjectsStore, RaCoApplication* app, core::LoadContext& loadContext); + RaCoProject(const QString& file, core::Project& p, core::EngineInterface* engineInterface, const core::UndoStack::Callback& callback, core::ExternalProjectsStoreInterface* externalProjectsStore, RaCoApplication* app, core::LoadContext& loadContext, int fileVersion); QJsonDocument serializeProjectData(const std::unordered_map>& currentVersions); @@ -125,27 +127,29 @@ class RaCoProject : public QObject { void generateAllProjectSubfolders(); void updateActiveFileListener(); - raco::core::DataChangeRecorder recorder_; - raco::core::Errors errors_; - raco::core::Project project_; + core::DataChangeRecorder recorder_; + core::Errors errors_; + core::Project project_; - raco::components::Subscription lifecycleSubscription_; - raco::components::Subscription imageSubdirectoryUpdateSubscription_; - raco::components::Subscription meshSubdirectoryUpdateSubscription_; - raco::components::Subscription scriptSubdirectoryUpdateSubscription_; - raco::components::Subscription interfaceSubdirectoryUpdateSubscription_; - raco::components::Subscription shaderSubdirectoryUpdateSubscription_; + components::Subscription lifecycleSubscription_; + components::Subscription imageSubdirectoryUpdateSubscription_; + components::Subscription meshSubdirectoryUpdateSubscription_; + components::Subscription scriptSubdirectoryUpdateSubscription_; + components::Subscription interfaceSubdirectoryUpdateSubscription_; + components::Subscription shaderSubdirectoryUpdateSubscription_; - std::shared_ptr context_; + std::shared_ptr context_; bool dirty_{false}; components::ProjectFileChangeMonitor activeProjectFileChangeMonitor_; - raco::components::ProjectFileChangeMonitor::UniqueListener activeProjectFileChangeListener_; + components::ProjectFileChangeMonitor::UniqueListener activeProjectFileChangeListener_; + + core::MeshCache* meshCache_; + core::UndoStack undoStack_; + core::CommandInterface commandInterface_; + std::unique_ptr tracePlayer_; - raco::core::MeshCache* meshCache_; - raco::core::UndoStack undoStack_; - raco::core::CommandInterface commandInterface_; - std::unique_ptr tracePlayer_; + std::filesystem::file_time_type lastModifiedTime_; }; } // namespace raco::application diff --git a/components/libApplication/src/ExternalProjectsStore.cpp b/components/libApplication/src/ExternalProjectsStore.cpp index 6a714545..d91549d9 100644 --- a/components/libApplication/src/ExternalProjectsStore.cpp +++ b/components/libApplication/src/ExternalProjectsStore.cpp @@ -43,7 +43,7 @@ void ExternalProjectsStore::buildProjectGraph(const std::string& absPath, std::v auto racoProject = externalProjects_.at(absPath).get(); if (racoProject) { ProjectGraphNode node{absPath}; - raco::core::Project& project = *racoProject->project(); + core::Project& project = *racoProject->project(); for (auto item : project.externalProjectsMap()) { auto path = project.lookupExternalProjectPath(item.first); buildProjectGraph(path, outProjects); @@ -71,8 +71,8 @@ void ExternalProjectsStore::updateExternalProjectsDependingOn(const std::string& core::LoadContext loadContext; loadContext.featureLevel = featureLevel; externalProjects_[it->path]->updateExternalReferences(loadContext); - } catch (const raco::core::ExtrefError& e) { - LOG_ERROR(raco::log_system::COMMON, "Exterrnal reference update failed {}", e.what()); + } catch (const core::ExtrefError& e) { + LOG_ERROR(log_system::COMMON, "Exterrnal reference update failed {}", e.what()); } dirty.insert(it->path); } @@ -87,13 +87,13 @@ void ExternalProjectsStore::updateExternalProjectsDependingOn(const std::string& core::LoadContext loadContext; loadContext.featureLevel = activeProject_->project()->featureLevel(); activeProject_->updateExternalReferences(loadContext); - } catch (const raco::core::ExtrefError& e) { - LOG_ERROR(raco::log_system::COMMON, "Exterrnal reference update failed {}", e.what()); + } catch (const core::ExtrefError& e) { + LOG_ERROR(log_system::COMMON, "Exterrnal reference update failed {}", e.what()); } } } -bool raco::application::ExternalProjectsStore::isCurrent(const std::string& projectPath) const { +bool application::ExternalProjectsStore::isCurrent(const std::string& projectPath) const { auto it = externalProjects_.find(projectPath); if (it != externalProjects_.end()) { auto racoProject = it->second.get(); @@ -104,7 +104,11 @@ bool raco::application::ExternalProjectsStore::isCurrent(const std::string& proj return false; } -raco::core::Project* ExternalProjectsStore::addExternalProject(const std::string& origProjectPath, core::LoadContext& loadContext) { +core::Project* ExternalProjectsStore::addExternalProject(const std::string& origProjectPath, core::LoadContext& loadContext) { + if (utils::u8path(origProjectPath).existsDirectory()) { + return nullptr; + } + std::string projectPath = origProjectPath; if (relinkPathMapCache_.find(projectPath) != relinkPathMapCache_.end()) { projectPath = relinkPathMapCache_.at(projectPath); @@ -120,13 +124,13 @@ raco::core::Project* ExternalProjectsStore::addExternalProject(const std::string } if (std::find(loadContext.pathStack.begin(), loadContext.pathStack.end(), projectPath) != loadContext.pathStack.end()) { - LOG_ERROR(raco::log_system::COMMON, "Can not add Project '{}' to Project Browser: project loop detected '{}' -> '{}'", projectPath, fmt::join(loadContext.pathStack, "' -> '"), projectPath); + LOG_ERROR(log_system::COMMON, "Can not add Project '{}' to Project Browser: project loop detected '{}' -> '{}'", projectPath, fmt::join(loadContext.pathStack, "' -> '"), projectPath); return nullptr; } QFileInfo fileInfo(QString::fromStdString(projectPath)); QString absPath = fileInfo.absoluteFilePath(); - if (!raco::utils::u8path(absPath.toStdString()).existsFile() && relinkCallback_) { + if (!utils::u8path(absPath.toStdString()).existsFile() && relinkCallback_) { // Query for replacement path auto relinkPath = relinkCallback_(projectPath); if (!relinkPath.empty()) { @@ -171,20 +175,20 @@ bool ExternalProjectsStore::loadExternalProject(const std::string& projectPath, try { project = RaCoProject::loadFromFile(QString::fromStdString(projectPath), application_, loadContext, true, loadContext.featureLevel); success = true; - } catch (raco::application::FutureFileVersion& fileVerError) { - LOG_ERROR(raco::log_system::OBJECT_TREE_VIEW, "Can not add Project {} to Project Browser - incompatible file version {} of project file", projectPath, fileVerError.fileVersion_); - } catch (raco::core::ExtrefError& error) { - LOG_ERROR(raco::log_system::COMMON, "Can not add Project {} to Project Browser: loading failed {}", projectPath, error.what()); - } catch (const raco::application::FeatureLevelLoadError& error) { - LOG_ERROR(raco::log_system::COMMON, "Feature level load error during external reference update"); - flError_.reset(new raco::application::FeatureLevelLoadError(error)); + } catch (application::FutureFileVersion& fileVerError) { + LOG_ERROR(log_system::OBJECT_TREE_VIEW, "Can not add Project {} to Project Browser - incompatible file version {} of project file", projectPath, fileVerError.fileVersion_); + } catch (core::ExtrefError& error) { + LOG_ERROR(log_system::COMMON, "Can not add Project {} to Project Browser: loading failed {}", projectPath, error.what()); + } catch (const application::FeatureLevelLoadError& error) { + LOG_ERROR(log_system::COMMON, "Feature level load error during external reference update"); + flError_.reset(new application::FeatureLevelLoadError(error)); } catch (std::runtime_error& error) { - LOG_ERROR(raco::log_system::COMMON, "Loading external project '{}' failed with error: {}", projectPath, error.what()); + LOG_ERROR(log_system::COMMON, "Loading external project '{}' failed with error: {}", projectPath, error.what()); } } if (projectPath == activeProjectPath() || (project && activeProject_ && project->project()->projectID() == activeProject_->project()->projectID())) { - LOG_ERROR(raco::log_system::COMMON, "Can not add Project {} to Project Browser: would create project loop", projectPath); + LOG_ERROR(log_system::COMMON, "Can not add Project {} to Project Browser: would create project loop", projectPath); project = nullptr; success = false; } @@ -209,7 +213,7 @@ void ExternalProjectsStore::removeExternalProject(const std::string& projectPath } } -raco::core::CommandInterface* ExternalProjectsStore::getExternalProjectCommandInterface(const std::string& projectPath) const { +core::CommandInterface* ExternalProjectsStore::getExternalProjectCommandInterface(const std::string& projectPath) const { auto it = externalProjects_.find(projectPath); if (it == externalProjects_.end() || it->second == nullptr) { return nullptr; @@ -221,8 +225,8 @@ bool ExternalProjectsStore::isExternalProject(const std::string& projectPath) co return externalProjects_.find(projectPath) != externalProjects_.end(); } -std::vector> ExternalProjectsStore::allExternalProjects() const { - std::vector> projects; +std::vector> ExternalProjectsStore::allExternalProjects() const { + std::vector> projects; projects.reserve(externalProjects_.size()); for (auto const& p : externalProjects_) { if (p.second) { @@ -234,9 +238,9 @@ std::vector> ExternalProje return projects; } -raco::core::Project* ExternalProjectsStore::getExternalProject(const std::string& projectPath) const { +core::Project* ExternalProjectsStore::getExternalProject(const std::string& projectPath) const { auto it = externalProjects_.find(projectPath); - if (it != externalProjects_.end()) { + if (it != externalProjects_.end() && it->second) { return it->second->project(); } return nullptr; diff --git a/components/libApplication/src/RaCoApplication.cpp b/components/libApplication/src/RaCoApplication.cpp index 72a025cb..b758cc66 100644 --- a/components/libApplication/src/RaCoApplication.cpp +++ b/components/libApplication/src/RaCoApplication.cpp @@ -21,11 +21,11 @@ #include "core/Project.h" #include "core/ProjectMigration.h" #include "ramses_adaptor/SceneBackend.h" +#include "ramses_adaptor/AbstractSceneAdaptor.h" #include "ramses_base/BaseEngineBackend.h" #include "user_types/Animation.h" #include "core/Handles.h" -#include #ifdef OS_WINDOWS // see: https://doc.qt.io/qt-5/qfileinfo.html#ntfs-permissions @@ -54,15 +54,15 @@ RaCoApplicationLaunchSettings::RaCoApplicationLaunchSettings(QString argInitialP RaCoApplication::RaCoApplication(ramses_base::BaseEngineBackend& engine, const RaCoApplicationLaunchSettings& settings) : engine_{&engine}, - applicationFeatureLevel_(settings.newFileFeatureLevel), - dataChangeDispatcher_{std::make_shared()}, - dataChangeDispatcherEngine_{std::make_shared()}, - scenesBackend_{new ramses_adaptor::SceneBackend(engine, dataChangeDispatcherEngine_)}, + newFileFeatureLevel_(settings.newFileFeatureLevel), + dataChangeDispatcher_{std::make_shared()}, + dataChangeDispatcherPreviewScene_{std::make_shared()}, + dataChangeDispatcherAbstractScene_{std::make_shared()}, + previewSceneBackend_{new ramses_adaptor::SceneBackend(engine, dataChangeDispatcherPreviewScene_)}, externalProjectsStore_(this) { ramses_base::installRamsesLogHandler(settings.enableRamsesTrace); - ramses_base::installLogicLogHandler(); // Preferences need to be initalized before we have a fist initial project - raco::components::RaCoPreferences::init(); + components::RaCoPreferences::init(); runningInUI_ = settings.runningInUI; @@ -96,7 +96,8 @@ std::string RaCoApplication::activeProjectFolder() const { } void RaCoApplication::resetSceneBackend() { - scenesBackend_->reset(); + previewSceneBackend_->reset(); + abstractScene_.reset(); } class WithRelinkCallback { @@ -113,9 +114,18 @@ class WithRelinkCallback { ExternalProjectsStore& externalProjectsStore_; }; -void RaCoApplication::setupScene(bool optimizeForExport) { - engine_->setFeatureLevel(static_cast(activeRaCoProject().project()->featureLevel())); - scenesBackend_->setScene(activeRaCoProject().project(), activeRaCoProject().errors(), optimizeForExport); +void RaCoApplication::setupScene(bool optimizeForExport, bool setupAbstractScene) { + auto featureLevel = static_cast(activeRaCoProject().project()->featureLevel()); + + previewSceneBackend_->setScene(activeRaCoProject().project(), activeRaCoProject().errors(), optimizeForExport, ramses_adaptor::SceneBackend::toSceneId(*activeRaCoProject().project()->settings()->sceneId_)); + if (runningInUI_) { + if (setupAbstractScene) { + abstractScene_.reset(); + abstractScene_ = std::make_unique(&engine_->client(), ramses_base::BaseEngineBackend::abstractSceneId(), activeRaCoProject().project(), dataChangeDispatcherAbstractScene_, &meshCache_, previewSceneBackend_->sceneAdaptor()); + } else if (abstractScene_) { + abstractScene_->setPreviewAdaptor(previewSceneBackend_->sceneAdaptor()); + } + } } void RaCoApplication::switchActiveRaCoProject(const QString& file, std::function relinkCallback, bool createDefaultScene, int featureLevel, bool generateNewObjectIDs) { @@ -123,7 +133,8 @@ void RaCoApplication::switchActiveRaCoProject(const QString& file, std::function WithRelinkCallback withRelinkCallback(externalProjectsStore_, relinkCallback); activeProject_.reset(); - scenesBackend_->reset(); + previewSceneBackend_->reset(); + abstractScene_.reset(); // The module cache should already by empty after removing the local and external projects but explicitly clear it anyway // to avoid potential problems. @@ -134,11 +145,16 @@ void RaCoApplication::switchActiveRaCoProject(const QString& file, std::function if (!(featureLevel == -1 || featureLevel >= ramses_base::BaseEngineBackend::minFeatureLevel && featureLevel <= ramses_base::BaseEngineBackend::maxFeatureLevel)) { - throw std::runtime_error(fmt::format("RamsesLogic feature level {} outside valid range ({} ... {})", featureLevel, static_cast(raco::ramses_base::BaseEngineBackend::minFeatureLevel), static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel))); + throw std::runtime_error(fmt::format("RamsesLogic feature level {} outside valid range ({} ... {})", featureLevel, static_cast(ramses_base::BaseEngineBackend::minFeatureLevel), static_cast(ramses_base::BaseEngineBackend::maxFeatureLevel))); } + if (file.isEmpty()) { - activeProject_ = RaCoProject::createNew(this, createDefaultScene, static_cast(featureLevel == -1 ? applicationFeatureLevel_ : featureLevel)); + int newFeatureLevel = featureLevel == -1 ? newFileFeatureLevel_ : featureLevel; + engine_->setFeatureLevel(static_cast(newFeatureLevel)); + activeProject_ = RaCoProject::createNew(this, createDefaultScene, newFeatureLevel); } else { + auto fileFeatureLevel = RaCoProject::preloadFeatureLevel(file, featureLevel); + engine_->setFeatureLevel(static_cast(fileFeatureLevel)); activeProject_ = RaCoProject::loadFromFile(file, this, loadContext, false, featureLevel, generateNewObjectIDs); } @@ -149,7 +165,7 @@ void RaCoApplication::switchActiveRaCoProject(const QString& file, std::function activeProject_->applyDefaultCachedPaths(); activeProject_->setupCachedPathSubscriptions(dataChangeDispatcher_); - setupScene(false); + setupScene(false, true); startTime_ = std::chrono::high_resolution_clock::now(); doOneLoop(); @@ -168,51 +184,51 @@ bool RaCoApplication::saveAsWithNewIDs(const QString& newPath, std::string& outE } core::ErrorLevel RaCoApplication::getExportSceneDescriptionAndStatus(std::vector& outDescription, std::string& outMessage) { - setupScene(true); + setupScene(true, false); logicEngineNeedsUpdate_ = true; doOneLoop(); - outDescription = scenesBackend_->getSceneItemDescriptions(); + outDescription = previewSceneBackend_->getSceneItemDescriptions(); - core::ErrorLevel errorLevel = scenesBackend_->sceneValid(); + core::ErrorLevel errorLevel = previewSceneBackend_->sceneValid(); if (errorLevel != core::ErrorLevel::NONE) { outMessage = sceneBackend()->getValidationReport(errorLevel); } else { outMessage = std::string(); } - setupScene(false); + setupScene(false, false); logicEngineNeedsUpdate_ = true; rendererDirty_ = true; return errorLevel; } -bool RaCoApplication::exportProject(const std::string& ramsesExport, const std::string& logicExport, bool compress, std::string& outError, bool forceExportWithErrors, ELuaSavingMode luaSavingMode) { - setupScene(true); +bool RaCoApplication::exportProject(const std::string& ramsesExport, bool compress, std::string& outError, bool forceExportWithErrors, ELuaSavingMode luaSavingMode) { + setupScene(true, false); logicEngineNeedsUpdate_ = true; doOneLoop(); - bool status = exportProjectImpl(ramsesExport, logicExport, compress, outError, forceExportWithErrors, luaSavingMode); + bool status = exportProjectImpl(ramsesExport, compress, outError, forceExportWithErrors, luaSavingMode); - setupScene(false); + setupScene(false, false); logicEngineNeedsUpdate_ = true; rendererDirty_ = true; return status; } -bool RaCoApplication::exportProjectImpl(const std::string& ramsesExport, const std::string& logicExport, bool compress, std::string& outError, bool forceExportWithErrors, ELuaSavingMode luaSavingMode) const { +bool RaCoApplication::exportProjectImpl(const std::string& ramsesExport, bool compress, std::string& outError, bool forceExportWithErrors, ELuaSavingMode luaSavingMode) const { // Flushing the scene prevents inconsistent states being saved which could lead to unexpected bevahiour after loading the scene: - scenesBackend_->flush(); + previewSceneBackend_->flush(); if (!forceExportWithErrors) { - if (activeRaCoProject().errors()->hasError(raco::core::ErrorLevel::ERROR)) { + if (activeRaCoProject().errors()->hasError(core::ErrorLevel::ERROR)) { outError = "Export failed: scene contains Composer errors:\n"; for (const auto& [object, objErrors] : activeRaCoProject().errors()->getAllErrors()) { for (const auto& [handle, error] : objErrors) { - if (error.level() >= raco::core::ErrorLevel::ERROR) { - outError.append(raco::core::Errors::formatError(error)); + if (error.level() >= core::ErrorLevel::ERROR) { + outError.append(core::Errors::formatError(error)); } } } @@ -223,44 +239,35 @@ bool RaCoApplication::exportProjectImpl(const std::string& ramsesExport, const s return false; } } - auto status = scenesBackend_->currentScene()->saveToFile(ramsesExport.c_str(), compress); - if (status != ramses::StatusOK) { - outError = scenesBackend_->currentScene()->getStatusMessage(status); - return false; - } - rlogic::SaveFileConfig metadata; - // Since the SceneBackend filters some validation warnings we have to disable validation when saving, because - // we can't selectively disable some validation warnings here: - metadata.setValidationEnabled(false); + + ramses::SaveFileConfig config; + config.setCompressionEnabled(compress); // Use JSON format for the metadata string to allow future extensibility // CAREFUL: only include data here which we are certain all users agree to have included in the exported files. - metadata.setMetadataString(fmt::format( + config.setMetadataString(fmt::format( R"___({{ "generator" : "{}" }})___", QCoreApplication::applicationName().toStdString())); - metadata.setExporterVersion(RACO_VERSION_MAJOR, RACO_VERSION_MINOR, RACO_VERSION_PATCH, raco::serialization::RAMSES_PROJECT_FILE_VERSION); - - metadata.setLuaSavingMode(static_cast(luaSavingMode)); + config.setExporterVersion(RACO_VERSION_MAJOR, RACO_VERSION_MINOR, RACO_VERSION_PATCH, serialization::RAMSES_PROJECT_FILE_VERSION); + config.setLuaSavingMode(static_cast(luaSavingMode)); - if (!engine_->logicEngine().saveToFile(logicExport.c_str(), metadata)) { - if (engine_->logicEngine().getErrors().size() > 0) { - outError = engine_->logicEngine().getErrors().at(0).message; - } else { - outError = "Unknown Errror: ramses-logic failed to export."; - } + if (!previewSceneBackend_->currentScene()->saveToFile(ramsesExport.c_str(), config)) { + outError = previewSceneBackend_->getLastError().value().message; return false; } + return true; } void RaCoApplication::doOneLoop() { // write data into engine - if (ramses_adaptor::SceneBackend::toSceneId(*activeRaCoProject().project()->settings()->sceneId_) != scenesBackend_->currentSceneId()) { - scenesBackend_->setScene(activeRaCoProject().project(), activeRaCoProject().errors(), false); + if (ramses_adaptor::SceneBackend::toSceneId(*activeRaCoProject().project()->settings()->sceneId_) != previewSceneBackend_->currentSceneId()) { + // No need to setup the abstract scene again since its scene id never changes + setupScene(false, false); } - for (const auto& timerNode : engine_->logicEngine().getCollection()) { + for (const auto& timerNode : previewSceneBackend_->logicEngine()->getCollection()) { if (timerNode->getInputs()->getChild("ticker_us")->get() == 0) { logicEngineNeedsUpdate_ = true; break; @@ -278,16 +285,22 @@ void RaCoApplication::doOneLoop() { activeProject_->tracePlayer().refresh(elapsedMsec); auto dataChanges = activeProject_->recorder()->release(); - dataChangeDispatcherEngine_->dispatch(dataChanges); - if (logicEngineNeedsUpdate_ || !dataChanges.getAllChangedObjects(true, true, true).empty()) { - if (!engine_->logicEngine().update()) { - LOG_ERROR_IF(raco::log_system::RAMSES_BACKEND, !engine_->logicEngine().getErrors().empty(), "{}", LogicEngineErrors{engine_->logicEngine()}); + dataChangeDispatcherPreviewScene_->dispatch(dataChanges); + if (logicEngineNeedsUpdate_ || !dataChanges.getAllChangedObjects(true, true, true).empty() || !dataChanges.getDeletedObjects().empty()) { + if (!previewSceneBackend_->logicEngine()->update()) { + auto issue = previewSceneBackend_->getLastError().value(); + LOG_ERROR(log_system::RAMSES_BACKEND, issue.message); + previewSceneBackend_->sceneAdaptor()->updateRuntimeError(issue); + } else { + previewSceneBackend_->sceneAdaptor()->clearRuntimeError(); } - // read modified engine data / runtime errors - scenesBackend_->readDataFromEngine(dataChanges); + // read modified engine data + previewSceneBackend_->readDataFromEngine(dataChanges); logicEngineNeedsUpdate_ = false; } + dataChangeDispatcherAbstractScene_->dispatch(dataChanges); + dataChangeDispatcher_->dispatch(dataChanges); } @@ -303,18 +316,22 @@ bool RaCoApplication::canSaveActiveProject() const { } const core::SceneBackendInterface* RaCoApplication::sceneBackend() const { - return scenesBackend_.get(); + return previewSceneBackend_.get(); +} + +ramses_adaptor::SceneBackend* RaCoApplication::sceneBackendImpl() const { + return previewSceneBackend_.get(); } -raco::ramses_adaptor::SceneBackend* RaCoApplication::sceneBackendImpl() const { - return scenesBackend_.get(); +ramses_adaptor::AbstractSceneAdaptor* RaCoApplication::abstractScene() const { + return abstractScene_.get(); } -raco::components::SDataChangeDispatcher RaCoApplication::dataChangeDispatcher() { +components::SDataChangeDispatcher RaCoApplication::dataChangeDispatcher() { return dataChangeDispatcher_; } -raco::core::EngineInterface* RaCoApplication::engine() { +core::EngineInterface* RaCoApplication::engine() { return engine_->coreInterface(); } @@ -353,23 +370,23 @@ void RaCoApplication::overrideTime(std::function getTime) { } int RaCoApplication::minFeatureLevel() { - return static_cast(raco::ramses_base::BaseEngineBackend::minFeatureLevel); + return static_cast(ramses_base::BaseEngineBackend::minFeatureLevel); } int RaCoApplication::maxFeatureLevel() { - return static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel); + return static_cast(ramses_base::BaseEngineBackend::maxFeatureLevel); } const std::string& RaCoApplication::featureLevelDescriptions() { - return raco::ramses_base::BaseEngineBackend::featureLevelDescriptions; + return ramses_base::BaseEngineBackend::featureLevelDescriptions; } -void RaCoApplication::setApplicationFeatureLevel(int featureLevel) { - applicationFeatureLevel_ = featureLevel; +void RaCoApplication::setNewFileFeatureLevel(int featureLevel) { + newFileFeatureLevel_ = featureLevel; } -int RaCoApplication::applicationFeatureLevel() const { - return applicationFeatureLevel_; +int RaCoApplication::newFileFeatureLevel() const { + return newFileFeatureLevel_; } const FeatureLevelLoadError* RaCoApplication::getFlError() const { @@ -380,7 +397,7 @@ core::ExternalProjectsStoreInterface* RaCoApplication::externalProjects() { return &externalProjectsStore_; } -raco::core::MeshCache* RaCoApplication::meshCache() { +core::MeshCache* RaCoApplication::meshCache() { return &meshCache_; } diff --git a/components/libApplication/src/RaCoProject.cpp b/components/libApplication/src/RaCoProject.cpp index 7f2a93d2..f3f47257 100644 --- a/components/libApplication/src/RaCoProject.cpp +++ b/components/libApplication/src/RaCoProject.cpp @@ -59,7 +59,7 @@ namespace raco::application { using namespace raco::core; -RaCoProject::RaCoProject(const QString& file, Project& p, EngineInterface* engineInterface, const UndoStack::Callback& callback, ExternalProjectsStoreInterface* externalProjectsStore, RaCoApplication* app, LoadContext& loadContext) +RaCoProject::RaCoProject(const QString& file, Project& p, EngineInterface* engineInterface, const UndoStack::Callback& callback, ExternalProjectsStoreInterface* externalProjectsStore, RaCoApplication* app, LoadContext& loadContext, int fileVersion) : recorder_{}, errors_{&recorder_}, project_{p}, @@ -79,12 +79,12 @@ RaCoProject::RaCoProject(const QString& file, Project& p, EngineInterface* engin // TODO: remove this eventually when we are reasonably certain that no such projects have been encountered. for (const auto& object : project_.instances()) { if (object->isType() && - object->query()) { + object->query()) { throw std::runtime_error("project contains external reference RenderPass."); } if ((object->isType() || object->isType()) && - object->query()) { + object->query()) { if (!PrefabOperations::findContainingPrefab(object)) { throw std::runtime_error("file contains external reference camera outside a prefab"); } @@ -98,7 +98,7 @@ RaCoProject::RaCoProject(const QString& file, Project& p, EngineInterface* engin } // Needed because // - link duplicates may have different link validity - // - we used to allow links between logicengine primitive Vec2f/... and structs with the same content properties + // - we used to allow links between logicengine primitive Vec2f/... and structs with the same content properties // although they can't be linked in the logicengine. context_->initLinkValidity(); @@ -113,7 +113,7 @@ RaCoProject::RaCoProject(const QString& file, Project& p, EngineInterface* engin // Push currently loading project on the project load stack to enable project loop detection to work. loadContext.pathStack.emplace_back(file.toStdString()); - context_->updateExternalReferences(loadContext); + context_->updateExternalReferences(loadContext, fileVersion); loadContext.pathStack.pop_back(); undoStack_.reset(); @@ -124,7 +124,7 @@ RaCoProject::RaCoProject(const QString& file, Project& p, EngineInterface* engin } dirty_ = false; - tracePlayer_ = std::make_unique(*project(), context_->uiChanges(), *undoStack()); + tracePlayer_ = std::make_unique(*project(), context_->uiChanges(), *undoStack()); } void RaCoProject::onAfterProjectPathChange(const std::string& oldPath, const std::string& newPath) { @@ -151,8 +151,8 @@ void RaCoProject::onAfterProjectPathChange(const std::string& oldPath, const std for (const auto& property : ValueTreeIteratorAdaptor(ValueHandle{object})) { if (auto anno = property.query(); anno && !anno->isProjectSubdirectoryURI()) { auto uriPath = property.asString(); - if (!uriPath.empty() && raco::utils::u8path(uriPath).is_relative()) { - context_->set(property, raco::utils::u8path(uriPath).rerootRelativePath(oldPath, newPath).string()); + if (!uriPath.empty() && utils::u8path(uriPath).is_relative()) { + context_->set(property, utils::u8path(uriPath).rerootRelativePath(oldPath, newPath).string()); } } } @@ -164,7 +164,7 @@ void RaCoProject::onAfterProjectPathChange(const std::string& oldPath, const std } void RaCoProject::generateProjectSubfolder(const std::string& subFolderPath) { - auto path = raco::utils::u8path(subFolderPath).normalizedAbsolutePath(project_.currentFolder()); + auto path = utils::u8path(subFolderPath).normalizedAbsolutePath(project_.currentFolder()); if (!path.existsDirectory()) { std::filesystem::create_directories(path); } @@ -187,54 +187,53 @@ void RaCoProject::applyDefaultCachedPaths() { auto projectFolder = project_.currentFolder(); PathManager::setCachedPath(PathManager::FolderTypeKeys::Project, projectFolder); - PathManager::setCachedPath(PathManager::FolderTypeKeys::Image, raco::utils::u8path(defaultFolders->imageSubdirectory_.asString()).normalizedAbsolutePath(projectFolder)); - PathManager::setCachedPath(PathManager::FolderTypeKeys::Mesh, raco::utils::u8path(defaultFolders->meshSubdirectory_.asString()).normalizedAbsolutePath(projectFolder)); - PathManager::setCachedPath(PathManager::FolderTypeKeys::Script, raco::utils::u8path(defaultFolders->scriptSubdirectory_.asString()).normalizedAbsolutePath(projectFolder)); - PathManager::setCachedPath(PathManager::FolderTypeKeys::Interface, raco::utils::u8path(defaultFolders->interfaceSubdirectory_.asString()).normalizedAbsolutePath(projectFolder)); - PathManager::setCachedPath(PathManager::FolderTypeKeys::Shader, raco::utils::u8path(defaultFolders->shaderSubdirectory_.asString()).normalizedAbsolutePath(projectFolder)); + PathManager::setCachedPath(PathManager::FolderTypeKeys::Image, utils::u8path(defaultFolders->imageSubdirectory_.asString()).normalizedAbsolutePath(projectFolder)); + PathManager::setCachedPath(PathManager::FolderTypeKeys::Mesh, utils::u8path(defaultFolders->meshSubdirectory_.asString()).normalizedAbsolutePath(projectFolder)); + PathManager::setCachedPath(PathManager::FolderTypeKeys::Script, utils::u8path(defaultFolders->scriptSubdirectory_.asString()).normalizedAbsolutePath(projectFolder)); + PathManager::setCachedPath(PathManager::FolderTypeKeys::Interface, utils::u8path(defaultFolders->interfaceSubdirectory_.asString()).normalizedAbsolutePath(projectFolder)); + PathManager::setCachedPath(PathManager::FolderTypeKeys::Shader, utils::u8path(defaultFolders->shaderSubdirectory_.asString()).normalizedAbsolutePath(projectFolder)); } -void RaCoProject::setupCachedPathSubscriptions(const raco::components::SDataChangeDispatcher& dataChangeDispatcher) { +void RaCoProject::setupCachedPathSubscriptions(const components::SDataChangeDispatcher& dataChangeDispatcher) { lifecycleSubscription_ = dataChangeDispatcher->registerOnObjectsLifeCycle([this, dataChangeDispatcher](SEditorObject obj) { if (obj->isType()) { subscribeDefaultCachedPathChanges(dataChangeDispatcher); - } - }, - [](auto) {}); + } }, + [](auto) {}); subscribeDefaultCachedPathChanges(dataChangeDispatcher); } -void RaCoProject::subscribeDefaultCachedPathChanges(const raco::components::SDataChangeDispatcher& dataChangeDispatcher) { +void RaCoProject::subscribeDefaultCachedPathChanges(const components::SDataChangeDispatcher& dataChangeDispatcher) { auto project = this->project(); auto settings = project_.settings(); imageSubdirectoryUpdateSubscription_ = dataChangeDispatcher->registerOn({settings, &ProjectSettings::defaultResourceDirectories_, &DefaultResourceDirectories::imageSubdirectory_}, [project, settings]() { - auto path = raco::utils::u8path(settings->defaultResourceDirectories_->imageSubdirectory_.asString()).normalizedAbsolutePath(project->currentFolder()); + auto path = utils::u8path(settings->defaultResourceDirectories_->imageSubdirectory_.asString()).normalizedAbsolutePath(project->currentFolder()); PathManager::setCachedPath(PathManager::FolderTypeKeys::Image, path); }); meshSubdirectoryUpdateSubscription_ = dataChangeDispatcher->registerOn({settings, &ProjectSettings::defaultResourceDirectories_, &DefaultResourceDirectories::meshSubdirectory_}, [project, settings]() { - auto path = raco::utils::u8path(settings->defaultResourceDirectories_->meshSubdirectory_.asString()).normalizedAbsolutePath(project->currentFolder()); + auto path = utils::u8path(settings->defaultResourceDirectories_->meshSubdirectory_.asString()).normalizedAbsolutePath(project->currentFolder()); PathManager::setCachedPath(PathManager::FolderTypeKeys::Mesh, path); }); scriptSubdirectoryUpdateSubscription_ = dataChangeDispatcher->registerOn({settings, &ProjectSettings::defaultResourceDirectories_, &DefaultResourceDirectories::scriptSubdirectory_}, [project, settings]() { - auto path = raco::utils::u8path(settings->defaultResourceDirectories_->scriptSubdirectory_.asString()).normalizedAbsolutePath(project->currentFolder()); + auto path = utils::u8path(settings->defaultResourceDirectories_->scriptSubdirectory_.asString()).normalizedAbsolutePath(project->currentFolder()); PathManager::setCachedPath(PathManager::FolderTypeKeys::Script, path); }); interfaceSubdirectoryUpdateSubscription_ = dataChangeDispatcher->registerOn({settings, &ProjectSettings::defaultResourceDirectories_, &DefaultResourceDirectories::interfaceSubdirectory_}, [project, settings]() { - auto path = raco::utils::u8path(settings->defaultResourceDirectories_->interfaceSubdirectory_.asString()).normalizedAbsolutePath(project->currentFolder()); + auto path = utils::u8path(settings->defaultResourceDirectories_->interfaceSubdirectory_.asString()).normalizedAbsolutePath(project->currentFolder()); PathManager::setCachedPath(PathManager::FolderTypeKeys::Interface, path); }); shaderSubdirectoryUpdateSubscription_ = dataChangeDispatcher->registerOn({settings, &ProjectSettings::defaultResourceDirectories_, &DefaultResourceDirectories::shaderSubdirectory_}, [project, settings]() { - auto path = raco::utils::u8path(settings->defaultResourceDirectories_->shaderSubdirectory_.asString()).normalizedAbsolutePath(project->currentFolder()); + auto path = utils::u8path(settings->defaultResourceDirectories_->shaderSubdirectory_.asString()).normalizedAbsolutePath(project->currentFolder()); PathManager::setCachedPath(PathManager::FolderTypeKeys::Shader, path); }); } @@ -242,7 +241,21 @@ void RaCoProject::subscribeDefaultCachedPathChanges(const raco::components::SDat void RaCoProject::updateActiveFileListener() { activeProjectFileChangeListener_ = activeProjectFileChangeMonitor_.registerFileChangedHandler(project_.currentPath(), [this]() { - Q_EMIT activeProjectFileChanged(); + + const auto path = project_.currentPath(); + const bool isPathInvalid = !path.empty() && (!utils::u8path(path).exists() || !utils::u8path(path).userHasReadAccess()); + + if (path.empty() || isPathInvalid) { + return; + } + + const auto modifiedTime{std::filesystem::last_write_time(project_.currentPath())}; + const auto deltaSeconds = std::chrono::duration_cast(modifiedTime - lastModifiedTime_).count(); + + if (deltaSeconds > 0) { + // File was modified after this instance took its timestamp on load/save. + Q_EMIT activeProjectFileChanged(); + } }); } @@ -253,12 +266,12 @@ RaCoProject::~RaCoProject() { } std::unique_ptr RaCoProject::createNew(RaCoApplication* app, bool createDefaultScene, int featureLevel) { - LOG_INFO(raco::log_system::PROJECT, "Creating new project."); + LOG_INFO(log_system::PROJECT, "Creating new project."); Project p{}; p.setCurrentPath(components::RaCoPreferences::instance().userProjectsDirectory.toStdString()); if (featureLevel == -1) { - featureLevel = static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel); + featureLevel = static_cast(ramses_base::BaseEngineBackend::maxFeatureLevel); } LoadContext loadContext; @@ -270,9 +283,10 @@ std::unique_ptr RaCoProject::createNew(RaCoApplication* app, bool c [app]() { app->dataChangeDispatcher()->setUndoChanged(); }, app->externalProjects(), app, - loadContext)); + loadContext, + -1)); - const auto& prefs = raco::components::RaCoPreferences::instance(); + const auto& prefs = components::RaCoPreferences::instance(); auto settings = result->context_->createObject(ProjectSettings::typeDescription.typeName); result->context_->set({settings, &ProjectSettings::defaultResourceDirectories_, &DefaultResourceDirectories::imageSubdirectory_}, prefs.imageSubdirectory.toStdString()); result->context_->set({settings, &ProjectSettings::defaultResourceDirectories_, &DefaultResourceDirectories::meshSubdirectory_}, prefs.meshSubdirectory.toStdString()); @@ -282,15 +296,17 @@ std::unique_ptr RaCoProject::createNew(RaCoApplication* app, bool c result->context_->set({settings, &ProjectSettings::featureLevel_}, featureLevel); if (createDefaultScene) { - auto sMeshNode = result->context_->createObject(raco::user_types::MeshNode::typeDescription.typeName, raco::components::Naming::format(raco::user_types::MeshNode::typeDescription.typeName)); - auto sNode = result->context_->createObject(raco::user_types::Node::typeDescription.typeName, raco::components::Naming::format(raco::user_types::Node::typeDescription.typeName))->as(); - auto sCamera = result->context_->createObject(raco::user_types::PerspectiveCamera::typeDescription.typeName, raco::components::Naming::format(raco::user_types::PerspectiveCamera::typeDescription.typeName))->as(); - auto sRenderPass = result->context_->createObject(raco::user_types::RenderPass::typeDescription.typeName, "MainRenderPass")->as(); - auto sRenderLayer = result->context_->createObject(raco::user_types::RenderLayer::typeDescription.typeName, "MainRenderLayer")->as(); - + auto sMeshNode = result->context_->createObject(user_types::MeshNode::typeDescription.typeName, components::Naming::format(user_types::MeshNode::typeDescription.typeName)); + auto sNode = result->context_->createObject(user_types::Node::typeDescription.typeName, components::Naming::format(user_types::Node::typeDescription.typeName))->as(); + auto sCamera = result->context_->createObject(user_types::PerspectiveCamera::typeDescription.typeName, components::Naming::format(user_types::PerspectiveCamera::typeDescription.typeName))->as(); + auto sRenderPass = result->context_->createObject(user_types::RenderPass::typeDescription.typeName, "MainRenderPass")->as(); + auto sRenderLayer = result->context_->createObject(user_types::RenderLayer::typeDescription.typeName, "MainRenderLayer")->as(); + + result->context_->set({sMeshNode, &user_types::MeshNode::scaling_}, std::array{2.0, 2.0, 2.0}); + result->context_->set({sMeshNode, &user_types::MeshNode::instanceCount_}, -1); result->context_->set({sRenderPass, &user_types::RenderPass::camera_}, sCamera); - result->context_->set({sRenderPass, &user_types::RenderPass::layer0_}, sRenderLayer); - result->context_->addProperty({sRenderLayer, &user_types::RenderLayer::renderableTags_}, "render_main", std::make_unique>(0, LinkEndAnnotation(3))); + result->context_->set(ValueHandle(sRenderPass, &user_types::RenderPass::layers_)[0], sRenderLayer); + result->context_->addProperty({sRenderLayer, &user_types::RenderLayer::renderableTags_}, "render_main", std::make_unique>(0, LinkEndAnnotation())); result->context_->set({sNode, &user_types::Node::tags_}, std::vector({"render_main"})); result->context_->set({sCamera, &user_types::Node::translation_, &Vec3f::z}, 10.0); @@ -306,18 +322,18 @@ std::unique_ptr RaCoProject::createNew(RaCoApplication* app, bool c return result; } -QJsonDocument RaCoProject::loadFileDocument(const QFileInfo& fileInfo) { - const QString absPath = fileInfo.absoluteFilePath(); - - if (fileInfo.suffix().compare(raco::names::PROJECT_FILE_EXTENSION, Qt::CaseInsensitive) != 0) { - throw std::runtime_error(fmt::format("Load file: wrong extension {}", fileInfo.filePath().toStdString())); +QJsonDocument RaCoProject::loadJsonDocument(const QString& filename) { + QFileInfo path(filename); + QString absPath = path.absoluteFilePath(); + if (path.suffix().compare(names::PROJECT_FILE_EXTENSION, Qt::CaseInsensitive) != 0) { + throw std::runtime_error(fmt::format("Load file: wrong extension {}", path.filePath().toStdString())); } - if (!raco::utils::u8path(absPath.toStdString()).existsFile()) { + if (!utils::u8path(absPath.toStdString()).existsFile()) { throw std::runtime_error(fmt::format("File not found {}", absPath.toLatin1())); } - if (!raco::utils::u8path(absPath.toStdString()).userHasReadAccess()) { + if (!utils::u8path(absPath.toStdString()).userHasReadAccess()) { throw std::runtime_error(fmt::format("Project file could not be read {}", absPath.toLatin1())); } @@ -333,8 +349,8 @@ QJsonDocument RaCoProject::loadFileDocument(const QFileInfo& fileInfo) { throw std::runtime_error(fmt::format("File {} has invalid content", absPath.toLatin1())); } - if (raco::utils::zip::isZipFile({fileContents.begin(), fileContents.begin() + 4})) { - auto unzippedProj = raco::utils::zip::zipToProject(fileContents, fileContents.size()); + if (utils::zip::isZipFile({fileContents.begin(), fileContents.begin() + 4})) { + auto unzippedProj = utils::zip::zipToProject(fileContents, fileContents.size()); if (unzippedProj.success) { fileContents = QByteArray(unzippedProj.payload.c_str()); @@ -347,25 +363,40 @@ QJsonDocument RaCoProject::loadFileDocument(const QFileInfo& fileInfo) { if (document.isNull()) { throw std::runtime_error("Loading JSON file resulted in a null document object"); } + return document; } +int RaCoProject::preloadFeatureLevel(const QString& filename, int featureLevel) { + LOG_INFO(log_system::PROJECT, "Loading project from {}", filename.toLatin1()); + + QFileInfo path(filename); + QString absPath = path.absoluteFilePath(); + + auto document = loadJsonDocument(filename); + + auto fileFeatureLevel = serialization::deserializeFeatureLevel(document); + + return std::max(static_cast(fileFeatureLevel), featureLevel); +} + std::unique_ptr RaCoProject::loadFromFile(const QString& filename, RaCoApplication* app, LoadContext& loadContext, bool logErrors, int featureLevel, bool generateNewObjectIDs) { - LOG_INFO(raco::log_system::PROJECT, "Loading project from {}", filename.toLatin1()); + LOG_INFO(log_system::PROJECT, "Loading project from {}", filename.toLatin1()); + + QFileInfo path(filename); + QString absPath = path.absoluteFilePath(); - QFileInfo fileInfo(filename); - const QString absPath = fileInfo.absoluteFilePath(); - const auto document = loadFileDocument(filename); + auto document = loadJsonDocument(filename); - auto fileVersion{raco::serialization::deserializeFileVersion(document)}; - if (fileVersion > raco::serialization::RAMSES_PROJECT_FILE_VERSION) { + auto fileVersion{serialization::deserializeFileVersion(document)}; + if (fileVersion > serialization::RAMSES_PROJECT_FILE_VERSION) { throw FutureFileVersion{fileVersion}; } if (fileVersion == 0) { throw std::runtime_error("File is not a RamsesComposer file."); } - auto result{raco::serialization::deserializeProject(document, absPath.toStdString())}; + auto result{serialization::deserializeProject(document, absPath.toStdString())}; for (const auto& instance : result.objects) { instance->onAfterDeserialization(); @@ -382,18 +413,18 @@ std::unique_ptr RaCoProject::loadFromFile(const QString& filename, p.addLink(link); } for (auto [id, info] : result.externalProjectsMap) { - auto absPath = raco::utils::u8path(info.path).normalizedAbsolutePath(p.currentFolder()); + auto absPath = utils::u8path(info.path).normalizedAbsolutePath(p.currentFolder()); p.addExternalProjectMapping(id, absPath.string(), info.name); } if (featureLevel != -1) { - if (featureLevel >= p.featureLevel() && featureLevel <= static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel)) { + if (featureLevel >= p.featureLevel() && featureLevel <= static_cast(ramses_base::BaseEngineBackend::maxFeatureLevel)) { p.setFeatureLevel(featureLevel); } else { if (featureLevel < p.featureLevel()) { throw FeatureLevelLoadError(fmt::format("New Feature level {} smaller than project feature level {}.", featureLevel, p.featureLevel()), featureLevel, p.featureLevel(), absPath.toStdString()); } else { - throw std::runtime_error(fmt::format("RamsesLogic feature level {} outside valid range ({} ... {})", featureLevel, static_cast(raco::ramses_base::BaseEngineBackend::minFeatureLevel), static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel))); + throw std::runtime_error(fmt::format("RamsesLogic feature level {} outside valid range ({} ... {})", featureLevel, static_cast(ramses_base::BaseEngineBackend::minFeatureLevel), static_cast(ramses_base::BaseEngineBackend::maxFeatureLevel))); } } } @@ -411,11 +442,12 @@ std::unique_ptr RaCoProject::loadFromFile(const QString& filename, [app]() { app->dataChangeDispatcher()->setUndoChanged(); }, app->externalProjects(), app, - loadContext}; + loadContext, + fileVersion}; for (const auto& [objectID, infoMessage] : result.migrationObjWarnings) { if (const auto migratedObj = newProject->project()->getInstanceByID(objectID)) { - newProject->errors()->addError(raco::core::ErrorCategory::MIGRATION, ErrorLevel::WARNING, migratedObj, infoMessage); + newProject->errors()->addError(core::ErrorCategory::MIGRATION, ErrorLevel::WARNING, migratedObj, infoMessage); } } @@ -426,7 +458,9 @@ std::unique_ptr RaCoProject::loadFromFile(const QString& filename, newProject->errors()->logAllErrors(); } - LOG_INFO(raco::log_system::PROJECT, "Finished loading project from {}", absPath.toLatin1()); + LOG_INFO(log_system::PROJECT, "Finished loading project from {}", absPath.toLatin1()); + + newProject->lastModifiedTime_ = std::filesystem::last_write_time(absPath.toStdString()); return std::unique_ptr(newProject); } @@ -624,7 +658,7 @@ QJsonDocument RaCoProject::serializeProject(const std::unordered_mapmodelChanges().getChangedValues()) { for (const auto& handle : handles) { if (!canReconstructPropertyPredicate(handle)) { - LOG_WARNING(raco::log_system::PROJECT, "serializeProject: optimization changed property {}; using non-optimized fallback instead.", handle); + LOG_WARNING(log_system::PROJECT, "serializeProject: optimization changed property {}; using non-optimized fallback instead.", handle); lostData = true; } } @@ -637,7 +671,7 @@ QJsonDocument RaCoProject::serializeProject(const std::unordered_mapobjectID(); auto endObj = project_.getInstanceByID(endID); if (endObj && !canReconstructLinkPredicate(link)) { - LOG_WARNING(raco::log_system::PROJECT, "serializeProject: optimization removed link {}; using non-optimized fallback instead.", link); + LOG_WARNING(log_system::PROJECT, "serializeProject: optimization removed link {}; using non-optimized fallback instead.", link); lostData = true; } } @@ -664,7 +698,7 @@ QJsonDocument RaCoProject::serializeProject(const std::unordered_mapsaveAsZip_; @@ -672,25 +706,23 @@ bool RaCoProject::save(std::string& outError) { if (!file.open(flags)) { std::string msg = fmt::format("Saving project failed: Could not open file for writing: {} FileError {} {}", path, file.error(), file.errorString().toStdString()); - LOG_ERROR(raco::log_system::PROJECT, msg); + LOG_ERROR(log_system::PROJECT, msg); outError = msg; return false; } - auto ramsesVersion = raco::ramses_base::getRamsesVersion(); - auto ramsesLogicEngineVersion = raco::ramses_base::getLogicEngineVersion(); + auto ramsesVersion = ramses_base::getRamsesVersion(); std::unordered_map> currentVersions = { - {raco::serialization::keys::FILE_VERSION, {raco::serialization::RAMSES_PROJECT_FILE_VERSION}}, - {raco::serialization::keys::RAMSES_VERSION, {ramsesVersion.major, ramsesVersion.minor, ramsesVersion.patch}}, - {raco::serialization::keys::RAMSES_LOGIC_ENGINE_VERSION, {static_cast(ramsesLogicEngineVersion.major), static_cast(ramsesLogicEngineVersion.minor), static_cast(ramsesLogicEngineVersion.patch)}}, - {raco::serialization::keys::RAMSES_COMPOSER_VERSION, {RACO_VERSION_MAJOR, RACO_VERSION_MINOR, RACO_VERSION_PATCH}}}; + {serialization::keys::FILE_VERSION, {serialization::RAMSES_PROJECT_FILE_VERSION}}, + {serialization::keys::RAMSES_VERSION, {ramsesVersion.major, ramsesVersion.minor, ramsesVersion.patch}}, + {serialization::keys::RAMSES_COMPOSER_VERSION, {RACO_VERSION_MAJOR, RACO_VERSION_MINOR, RACO_VERSION_PATCH}}}; auto projectFileData = serializeProject(currentVersions).toJson(); if (saveAsZip) { - auto zippedFile = (raco::utils::zip::projectToZip(projectFileData.constData(), (project_.currentFileName() + ".json").c_str())); + auto zippedFile = (utils::zip::projectToZip(projectFileData.constData(), (project_.currentFileName() + ".json").c_str())); if (zippedFile.empty()) { - LOG_ERROR(raco::log_system::PROJECT, "Saving project failed: Error while zipping project file"); + LOG_ERROR(log_system::PROJECT, "Saving project failed: Error while zipping project file"); return false; } @@ -702,16 +734,18 @@ bool RaCoProject::save(std::string& outError) { file.write(projectFileData); if (!file.flush() || file.error() != QFile::FileError::NoError) { std::string msg = fmt::format("Saving project failed: Could not open file for writing: {} FileError {} {}", path, file.error(), file.errorString().toStdString()); - LOG_ERROR(raco::log_system::PROJECT, msg); + LOG_ERROR(log_system::PROJECT, msg); outError = msg; return false; } file.close(); + lastModifiedTime_ = std::filesystem::last_write_time(path); + generateAllProjectSubfolders(); dirty_ = false; - LOG_INFO(raco::log_system::PROJECT, "Finished saving project to {}", path); + LOG_INFO(log_system::PROJECT, "Finished saving project to {}", path); Q_EMIT projectSuccessfullySaved(); return true; } @@ -730,10 +764,10 @@ bool RaCoProject::saveAs(const QString& fileName, std::string& outError, bool se // However the onAfterProjectPathChange will perform an unconditional undo stack push. // This means that using the context in the operations below is OK as long as we perform the onAfterProjectPathChange afterwards. if (setProjectName) { - auto projName = raco::utils::u8path(newPath).stem().string(); + auto projName = utils::u8path(newPath).stem().string(); auto settings = project_.settings(); if (settings->objectName().empty()) { - context_->set({settings, &raco::core::EditorObject::objectName_}, projName); + context_->set({settings, &core::EditorObject::objectName_}, projName); } } project_.setCurrentPath(newPath); @@ -786,7 +820,7 @@ MeshCache* RaCoProject::meshCache() { return meshCache_; } -raco::components::TracePlayer& RaCoProject::tracePlayer() { +components::TracePlayer& RaCoProject::tracePlayer() { return *tracePlayer_; } diff --git a/components/libApplication/tests/CMakeLists.txt b/components/libApplication/tests/CMakeLists.txt index a4395d72..3303c49c 100644 --- a/components/libApplication/tests/CMakeLists.txt +++ b/components/libApplication/tests/CMakeLists.txt @@ -30,6 +30,7 @@ raco_package_add_headless_test( raco_package_test_resources_process( libApplication_test "${CMAKE_SOURCE_DIR}/resources" + empty-raco-1x-fl2.rca shaders/basic.frag shaders/basic.vert meshes/RiggedFigure/RiggedFigure.gltf diff --git a/components/libApplication/tests/RaCoApplication_test.cpp b/components/libApplication/tests/RaCoApplication_test.cpp index a9dedfc6..e2f9422c 100644 --- a/components/libApplication/tests/RaCoApplication_test.cpp +++ b/components/libApplication/tests/RaCoApplication_test.cpp @@ -24,36 +24,45 @@ #include "core/ProjectSettings.h" using raco::application::RaCoApplication; -using raco::components::Naming; +using components::Naming; class RaCoApplicationFixture : public RaCoApplicationTest {}; TEST_F(RaCoApplicationFixture, feature_level_load_keep_file_featue_level) { - application.switchActiveRaCoProject({}, {}, true, 1); + application.switchActiveRaCoProject({}, {}, true, ramses_base::BaseEngineBackend::minFeatureLevel); std::string msg; ASSERT_TRUE(application.activeRaCoProject().saveAs((test_path() / "project.rca").string().c_str(), msg)); - application.switchActiveRaCoProject({}, {}, true, 2); - EXPECT_EQ(application.activeRaCoProject().project()->featureLevel(), 2); + application.switchActiveRaCoProject({}, {}, true, ramses_base::BaseEngineBackend::maxFeatureLevel); + EXPECT_EQ(application.activeRaCoProject().project()->featureLevel(), ramses_base::BaseEngineBackend::maxFeatureLevel); application.switchActiveRaCoProject((test_path() / "project.rca").string().c_str(), {}, false); - EXPECT_EQ(application.activeRaCoProject().project()->featureLevel(), 1); + EXPECT_EQ(application.activeRaCoProject().project()->featureLevel(), ramses_base::BaseEngineBackend::minFeatureLevel); } - TEST_F(RaCoApplicationFixture, feature_level_load_upgrade) { - application.switchActiveRaCoProject({}, {}, true, 1); + application.switchActiveRaCoProject({}, {}, true, ramses_base::BaseEngineBackend::minFeatureLevel); std::string msg; ASSERT_TRUE(application.activeRaCoProject().saveAs((test_path() / "project.rca").string().c_str(), msg)); - application.switchActiveRaCoProject((test_path() / "project.rca").string().c_str(), {}, false, 2); + application.switchActiveRaCoProject((test_path() / "project.rca").string().c_str(), {}, false, ramses_base::BaseEngineBackend::maxFeatureLevel); + EXPECT_EQ(application.activeRaCoProject().project()->featureLevel(), ramses_base::BaseEngineBackend::maxFeatureLevel); } TEST_F(RaCoApplicationFixture, feature_level_load_downgrade) { - application.switchActiveRaCoProject({}, {}, true, 2); - std::string msg; - ASSERT_TRUE(application.activeRaCoProject().saveAs((test_path() / "project.rca").string().c_str(), msg)); + if (ramses_base::BaseEngineBackend::minFeatureLevel < ramses_base::BaseEngineBackend::maxFeatureLevel) { + application.switchActiveRaCoProject({}, {}, true, ramses_base::BaseEngineBackend::maxFeatureLevel); + std::string msg; + ASSERT_TRUE(application.activeRaCoProject().saveAs((test_path() / "project.rca").string().c_str(), msg)); - EXPECT_THROW(application.switchActiveRaCoProject((test_path() / "project.rca").string().c_str(), {}, false, 1), std::runtime_error); + EXPECT_THROW(application.switchActiveRaCoProject((test_path() / "project.rca").string().c_str(), {}, false, ramses_base::BaseEngineBackend::minFeatureLevel), std::runtime_error); + } +} + +TEST_F(RaCoApplicationFixture, feature_level_load_downgrade_fl_upgrade_raco_major_version) { + application.switchActiveRaCoProject((test_path() / "empty-raco-1x-fl2.rca").string().c_str(), {}, false, 1); + + EXPECT_EQ(application.activeRaCoProject().project()->featureLevel(), 1); + EXPECT_EQ(backend.featureLevel(), ramses::EFeatureLevel::EFeatureLevel_01); } TEST_F(RaCoApplicationFixture, exportNewProject) { @@ -62,7 +71,6 @@ TEST_F(RaCoApplicationFixture, exportNewProject) { std::string error; auto success = application.exportProject( (test_path() / "new.ramses").string().c_str(), - (test_path() / "new.logic").string().c_str(), false, error); ASSERT_TRUE(success); @@ -71,37 +79,33 @@ TEST_F(RaCoApplicationFixture, exportNewProject) { TEST_F(RaCoApplicationFixture, exportDuckProject) { auto* commandInterface = application.activeRaCoProject().commandInterface(); - auto mesh = commandInterface->createObject(raco::user_types::Mesh::typeDescription.typeName, Naming::format("MeshDuck")); + auto mesh = commandInterface->createObject(user_types::Mesh::typeDescription.typeName, Naming::format("MeshDuck")); commandInterface->set({mesh, {"uri"}}, std::string{(test_path() / "meshes" / "Duck.glb").string()}); - auto material = commandInterface->createObject(raco::user_types::Material::typeDescription.typeName, Naming::format("MaterialDuck")); + auto material = commandInterface->createObject(user_types::Material::typeDescription.typeName, Naming::format("MaterialDuck")); commandInterface->set({material, {"uriVertex"}}, (test_path() / "shaders" / "basic.vert").string()); commandInterface->set({material, {"uriFragment"}}, (test_path() / "shaders" / "basic.frag").string()); - auto node = commandInterface->createObject(raco::user_types::Node::typeDescription.typeName, Naming::format("NodeDuck")); - auto meshNode = commandInterface->createObject(raco::user_types::MeshNode::typeDescription.typeName, Naming::format("MeshNodeDuck")); + auto node = commandInterface->createObject(user_types::Node::typeDescription.typeName, Naming::format("NodeDuck")); + auto meshNode = commandInterface->createObject(user_types::MeshNode::typeDescription.typeName, Naming::format("MeshNodeDuck")); commandInterface->moveScenegraphChildren({meshNode}, node); - commandInterface->set(raco::core::ValueHandle{meshNode, {"mesh"}}, mesh); - commandInterface->set(raco::core::ValueHandle{meshNode, {"materials", "material", "material"}}, material); + commandInterface->set(core::ValueHandle{meshNode, {"mesh"}}, mesh); + commandInterface->set(core::ValueHandle{meshNode, {"materials", "material", "material"}}, material); commandInterface->set({meshNode, {"materials", "material", "private"}}, true); - commandInterface->set(raco::core::ValueHandle{meshNode, {"materials", "material", "uniforms", "u_color", "x"}}, 1.0); + commandInterface->set(core::ValueHandle{meshNode, {"materials", "material", "uniforms", "u_color", "x"}}, 1.0); - commandInterface->set(raco::core::ValueHandle{meshNode, {"translation", "y"}}, -2.0); - commandInterface->set(raco::core::ValueHandle{meshNode, {"rotation", "x"}}, 90.0); - commandInterface->set(raco::core::ValueHandle{meshNode, {"scaling", "x"}}, 20.0); - commandInterface->set(raco::core::ValueHandle{meshNode, {"scaling", "y"}}, 20.0); - commandInterface->set(raco::core::ValueHandle{meshNode, {"scaling", "z"}}, 20.0); + commandInterface->set(core::ValueHandle{meshNode, {"translation", "y"}}, -2.0); + commandInterface->set(core::ValueHandle{meshNode, {"rotation", "x"}}, 90.0); + commandInterface->set(core::ValueHandle{meshNode, {"scaling", "x"}}, 20.0); + commandInterface->set(core::ValueHandle{meshNode, {"scaling", "y"}}, 20.0); + commandInterface->set(core::ValueHandle{meshNode, {"scaling", "z"}}, 20.0); application.doOneLoop(); std::string error; - auto success = application.exportProject( - (test_path() / "new.ramses").string().c_str(), - (test_path() / "new.logic").string().c_str(), - true, - error); + auto success = application.exportProject((test_path() / "new.ramses").string().c_str(), true, error); ASSERT_TRUE(success); } @@ -109,35 +113,35 @@ TEST_F(RaCoApplicationFixture, export_interface_link_opt_1) { application.switchActiveRaCoProject(QString::fromStdString((test_path() / "export-interface-link-opt-1.rca").string()), {}); std::string error; - EXPECT_TRUE(application.exportProject((test_path() / "export-interface-link-opt-1.ramses").string(), (test_path() / "export-interface-link-opt-1.rlogic").string(), false, error, false)); + EXPECT_TRUE(application.exportProject((test_path() / "export-interface-link-opt-1.ramses").string(), false, error, false)); } TEST_F(RaCoApplicationFixture, export_interface_link_opt_2) { application.switchActiveRaCoProject(QString::fromStdString((test_path() / "export-interface-link-opt-2.rca").string()), {}); std::string error; - EXPECT_TRUE(application.exportProject((test_path() / "export-interface-link-opt-2.ramses").string(), (test_path() / "export-interface-link-opt-2.rlogic").string(), false, error, false)); + EXPECT_TRUE(application.exportProject((test_path() / "export-interface-link-opt-2.ramses").string(), false, error, false)); } TEST_F(RaCoApplicationFixture, export_interface_link_opt_3) { application.switchActiveRaCoProject(QString::fromStdString((test_path() / "export-interface-link-opt-3.rca").string()), {}); std::string error; - EXPECT_TRUE(application.exportProject((test_path() / "export-interface-link-opt-3.ramses").string(), (test_path() / "export-interface-link-opt-3.rlogic").string(), false, error, false)); + EXPECT_TRUE(application.exportProject((test_path() / "export-interface-link-opt-3.ramses").string(), false, error, false)); } TEST_F(RaCoApplicationFixture, export_interface_link_opt_4) { application.switchActiveRaCoProject(QString::fromStdString((test_path() / "export-interface-link-opt-4.rca").string()), {}); std::string error; - EXPECT_TRUE(application.exportProject((test_path() / "export-interface-link-opt-4.ramses").string(), (test_path() / "export-interface-link-opt-4.rlogic").string(), false, error, false)); + EXPECT_TRUE(application.exportProject((test_path() / "export-interface-link-opt-4.ramses").string(), false, error, false)); } TEST_F(RaCoApplicationFixture, export_interface_opt_no_ending_link) { application.switchActiveRaCoProject(QString::fromStdString((test_path() / "export-interface-opt-no-ending.rca").string()), {}); std::string message; - std::vector sceneDescription; + std::vector sceneDescription; auto sceneStatus = application.getExportSceneDescriptionAndStatus(sceneDescription, message); EXPECT_TRUE(std::any_of(sceneDescription.begin(), sceneDescription.end(), [this](const auto& item) { @@ -149,7 +153,7 @@ TEST_F(RaCoApplicationFixture, export_interface_opt_ending_valid) { application.switchActiveRaCoProject(QString::fromStdString((test_path() / "export-interface-opt-ending-valid.rca").string()), {}); std::string message; - std::vector sceneDescription; + std::vector sceneDescription; auto sceneStatus = application.getExportSceneDescriptionAndStatus(sceneDescription, message); EXPECT_FALSE(std::any_of(sceneDescription.begin(), sceneDescription.end(), [this](const auto& item) { @@ -161,7 +165,7 @@ TEST_F(RaCoApplicationFixture, export_interface_opt_ending_invalid) { application.switchActiveRaCoProject(QString::fromStdString((test_path() / "export-interface-opt-ending-invalid.rca").string()), {}); std::string message; - std::vector sceneDescription; + std::vector sceneDescription; auto sceneStatus = application.getExportSceneDescriptionAndStatus(sceneDescription, message); EXPECT_TRUE(std::any_of(sceneDescription.begin(), sceneDescription.end(), [this](const auto& item) { @@ -169,30 +173,13 @@ TEST_F(RaCoApplicationFixture, export_interface_opt_ending_invalid) { })); } -TEST_F(RaCoApplicationFixture, export_with_lua_save_mode_for_feature_level_1) { - // Feature Level 1 only supports ELuaSavingMode::SourceCodeOnly. - application.switchActiveRaCoProject({}, {}, true, 1); - application.doOneLoop(); - - std::string error; - EXPECT_TRUE(application.exportProject( - (test_path() / "SourceCodeOnly.ramses").string(), - (test_path() / "SourceCodeOnly.logic").string(), - false, - error, - false, - raco::application::ELuaSavingMode::SourceCodeOnly)); -} - TEST_F(RaCoApplicationFixture, export_with_lua_save_modes) { - // Feature Level 2 is required for all lua save modes. - application.switchActiveRaCoProject({}, {}, true, 2); + application.switchActiveRaCoProject({}, {}, true, 1); application.doOneLoop(); std::string error; EXPECT_TRUE(application.exportProject( (test_path() / "ByteCodeOnly.ramses").string(), - (test_path() / "ByteCodeOnly.logic").string(), false, error, false, @@ -200,7 +187,6 @@ TEST_F(RaCoApplicationFixture, export_with_lua_save_modes) { EXPECT_TRUE(application.exportProject( (test_path() / "SourceCodeOnly.ramses").string(), - (test_path() / "SourceCodeOnly.logic").string(), false, error, false, @@ -208,7 +194,6 @@ TEST_F(RaCoApplicationFixture, export_with_lua_save_modes) { EXPECT_TRUE(application.exportProject( (test_path() / "SourceAndByteCode.ramses").string(), - (test_path() / "SourceAndByteCode.logic").string(), false, error, false, @@ -220,14 +205,14 @@ TEST_F(RaCoApplicationFixture, cant_delete_ProjectSettings) { commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); ASSERT_EQ(application.activeRaCoProject().project()->instances().size(), 1); - EXPECT_TRUE(raco::select(application.activeRaCoProject().project()->instances()) != nullptr); + EXPECT_TRUE(raco::select(application.activeRaCoProject().project()->instances()) != nullptr); } TEST_F(RaCoApplicationFixture, importglTFScenegraphCorrectNodeAmount) { auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string(); desc.bakeAllSubmeshes = false; @@ -264,7 +249,7 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphVectorsGetLinked) { auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/InterpolationTest/InterpolationTest.gltf").string(); desc.bakeAllSubmeshes = false; @@ -278,13 +263,13 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphMeshWithNegativeScaleWillBeIm auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/negativeScaleQuad.gltf").string(); desc.bakeAllSubmeshes = false; auto [scenegraph, dummyCacheEntry] = raco::getMeshSceneGraphWithHandler(commandInterface->meshCache(), desc); commandInterface->insertAssetScenegraph(scenegraph, desc.absPath, nullptr); - auto node = raco::core::ValueHandle(raco::core::Queries::findByName(raco::core::Queries::filterForNotResource(commandInterface->project()->instances()), "Quad")); + auto node = core::ValueHandle(core::Queries::findByName(core::Queries::filterForNotResource(commandInterface->project()->instances()), "Quad")); constexpr auto DELTA = 0.0001; ASSERT_NEAR(node.get("scaling").get("x").asDouble(), 3.0, DELTA); @@ -295,9 +280,9 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphMeshWithNegativeScaleWillBeIm TEST_F(RaCoApplicationFixture, importglTFScenegraphCachedMeshPathGetsChanged) { auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - raco::core::PathManager::setCachedPath(raco::core::PathManager::FolderTypeKeys::Mesh, {}); + core::PathManager::setCachedPath(core::PathManager::FolderTypeKeys::Mesh, {}); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string(); desc.bakeAllSubmeshes = false; @@ -305,14 +290,14 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphCachedMeshPathGetsChanged) { commandInterface->insertAssetScenegraph(scenegraph, desc.absPath, nullptr); application.dataChangeDispatcher()->dispatch(*application.activeRaCoProject().recorder()); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Mesh), test_path() / "meshes/CesiumMilkTruck"); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Mesh), test_path() / "meshes/CesiumMilkTruck"); } TEST_F(RaCoApplicationFixture, importglTFScenegraphCorrectScenegraphStructureTruck) { auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string(); desc.bakeAllSubmeshes = false; @@ -347,8 +332,8 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphCorrectScenegraphStructureTru auto projectInstances = commandInterface->project()->instances(); for (const auto& parentPair : parentMap) { auto [expectedChildName, expectedParentName] = parentPair; - auto expectedChild = raco::core::Queries::findByName(raco::core::Queries::filterForNotResource(projectInstances), expectedChildName); - auto expectedParent = raco::core::Queries::findByName(raco::core::Queries::filterForNotResource(projectInstances), expectedParentName); + auto expectedChild = core::Queries::findByName(core::Queries::filterForNotResource(projectInstances), expectedChildName); + auto expectedParent = core::Queries::findByName(core::Queries::filterForNotResource(projectInstances), expectedParentName); ASSERT_EQ(expectedChild->getParent(), expectedParent); } } @@ -356,17 +341,17 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphCorrectScenegraphStructureTru TEST_F(RaCoApplicationFixture, importglTFScenegraphCorrectRootNodeInsertion) { auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - auto myRoot = commandInterface->createObject(raco::user_types::Node::typeDescription.typeName, "myRoot"); + auto myRoot = commandInterface->createObject(user_types::Node::typeDescription.typeName, "myRoot"); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string(); desc.bakeAllSubmeshes = false; auto [scenegraph, dummyCacheEntry] = raco::getMeshSceneGraphWithHandler(commandInterface->meshCache(), desc); commandInterface->insertAssetScenegraph(scenegraph, desc.absPath, myRoot); - auto yup2Zup = raco::core::Queries::findByName(commandInterface->project()->instances(), "Yup2Zup"); - auto meshSceneRoot = raco::core::Queries::findByName(commandInterface->project()->instances(), "CesiumMilkTruck.gltf"); + auto yup2Zup = core::Queries::findByName(commandInterface->project()->instances(), "Yup2Zup"); + auto meshSceneRoot = core::Queries::findByName(commandInterface->project()->instances(), "CesiumMilkTruck.gltf"); ASSERT_EQ(yup2Zup->getParent(), meshSceneRoot); ASSERT_EQ(meshSceneRoot->getParent(), myRoot); } @@ -375,24 +360,24 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphCorrectRootNodeRenaming) { auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/ToyCar/ToyCar.gltf").string(); desc.bakeAllSubmeshes = false; auto [scenegraph, dummyCacheEntry] = raco::getMeshSceneGraphWithHandler(commandInterface->meshCache(), desc); commandInterface->insertAssetScenegraph(scenegraph, desc.absPath, nullptr); - auto root = raco::core::Queries::findByName(commandInterface->project()->instances(), "ToyCar.gltf"); + auto root = core::Queries::findByName(commandInterface->project()->instances(), "ToyCar.gltf"); ASSERT_NE(root, nullptr); } TEST_F(RaCoApplicationFixture, importglTFScenegraphImportSceneGraphTwice) { auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - auto firstRoot = commandInterface->createObject(raco::user_types::Node::typeDescription.typeName, "myRoot"); - auto secondRoot = commandInterface->createObject(raco::user_types::Node::typeDescription.typeName, "myRoot"); + auto firstRoot = commandInterface->createObject(user_types::Node::typeDescription.typeName, "myRoot"); + auto secondRoot = commandInterface->createObject(user_types::Node::typeDescription.typeName, "myRoot"); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string(); desc.bakeAllSubmeshes = false; @@ -408,10 +393,10 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphImportSceneGraphTwice) { TEST_F(RaCoApplicationFixture, importglTFScenegraphImportSceneGraphTwiceButMeshesGetChangedBeforeSecondImport) { auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - auto firstRoot = commandInterface->createObject(raco::user_types::Node::typeDescription.typeName, "myRoot"); - auto secondRoot = commandInterface->createObject(raco::user_types::Node::typeDescription.typeName, "myRoot"); + auto firstRoot = commandInterface->createObject(user_types::Node::typeDescription.typeName, "myRoot"); + auto secondRoot = commandInterface->createObject(user_types::Node::typeDescription.typeName, "myRoot"); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string(); desc.bakeAllSubmeshes = false; @@ -419,7 +404,7 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphImportSceneGraphTwiceButMeshe auto [sceneGraph, dummyCacheEntry] = raco::getMeshSceneGraphWithHandler(commandInterface->meshCache(), desc); commandInterface->insertAssetScenegraph(sceneGraph, desc.absPath, firstRoot); - auto allMeshes = raco::core::Queries::filterByTypeName(commandInterface->project()->instances(), {raco::user_types::Mesh::typeDescription.typeName}); + auto allMeshes = core::Queries::filterByTypeName(commandInterface->project()->instances(), {user_types::Mesh::typeDescription.typeName}); commandInterface->set({allMeshes[0], {"uri"}}, std::string("blah")); commandInterface->set({allMeshes[1], {"bakeMeshes"}}, true); @@ -439,10 +424,10 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphImportSceneGraphTwiceButMeshe TEST_F(RaCoApplicationFixture, importglTFScenegraphImportSceneGraphTwiceButAnimationChannelsGetChangedBeforeSecondImport) { auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - auto firstRoot = commandInterface->createObject(raco::user_types::Node::typeDescription.typeName, "myRoot"); - auto secondRoot = commandInterface->createObject(raco::user_types::Node::typeDescription.typeName, "myRoot"); + auto firstRoot = commandInterface->createObject(user_types::Node::typeDescription.typeName, "myRoot"); + auto secondRoot = commandInterface->createObject(user_types::Node::typeDescription.typeName, "myRoot"); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string(); desc.bakeAllSubmeshes = false; @@ -450,7 +435,7 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphImportSceneGraphTwiceButAnima auto [sceneGraph, dummyCacheEntry] = raco::getMeshSceneGraphWithHandler(commandInterface->meshCache(), desc); commandInterface->insertAssetScenegraph(sceneGraph, desc.absPath, firstRoot); - auto allAnimChannels = raco::core::Queries::filterByTypeName(commandInterface->project()->instances(), {raco::user_types::AnimationChannel::typeDescription.typeName}); + auto allAnimChannels = core::Queries::filterByTypeName(commandInterface->project()->instances(), {user_types::AnimationChannel::typeDescription.typeName}); commandInterface->set({allAnimChannels[0], {"animationIndex"}}, 2); commandInterface->set({allAnimChannels[1], {"samplerIndex"}}, 3); @@ -465,7 +450,7 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphUnbakedMeshesGetTransformed) auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string(); desc.bakeAllSubmeshes = false; @@ -475,9 +460,9 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphUnbakedMeshesGetTransformed) application.dataChangeDispatcher()->dispatch(*application.activeRaCoProject().recorder()); auto instances = commandInterface->project()->instances(); - auto yup2Zup = raco::core::ValueHandle{raco::core::Queries::findByName(instances, "Yup2Zup")}; - auto node = raco::core::ValueHandle{raco::core::Queries::findByName(instances, "Node")}; - auto node001 = raco::core::ValueHandle{raco::core::Queries::findByName(instances, "Node.001")}; + auto yup2Zup = core::ValueHandle{core::Queries::findByName(instances, "Yup2Zup")}; + auto node = core::ValueHandle{core::Queries::findByName(instances, "Node")}; + auto node001 = core::ValueHandle{core::Queries::findByName(instances, "Node.001")}; constexpr auto DELTA = 0.0001; ASSERT_NEAR(yup2Zup.get("rotation").get("x").asDouble(), 90.0, DELTA); @@ -501,12 +486,12 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphCorrectAutomaticMaterialAssig auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - auto truck = commandInterface->createObject(raco::user_types::Material::typeDescription.typeName, "truck"); - auto glass = commandInterface->createObject(raco::user_types::Material::typeDescription.typeName, "glass"); - auto windowTrim = commandInterface->createObject(raco::user_types::Material::typeDescription.typeName, "window_trim"); - auto wheels = commandInterface->createObject(raco::user_types::Material::typeDescription.typeName, "wheels"); + auto truck = commandInterface->createObject(user_types::Material::typeDescription.typeName, "truck"); + auto glass = commandInterface->createObject(user_types::Material::typeDescription.typeName, "glass"); + auto windowTrim = commandInterface->createObject(user_types::Material::typeDescription.typeName, "window_trim"); + auto wheels = commandInterface->createObject(user_types::Material::typeDescription.typeName, "wheels"); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string(); desc.bakeAllSubmeshes = false; @@ -514,7 +499,7 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphCorrectAutomaticMaterialAssig auto [scenegraph, dummyCacheEntry] = raco::getMeshSceneGraphWithHandler(commandInterface->meshCache(), desc); commandInterface->insertAssetScenegraph(scenegraph, desc.absPath, nullptr); - std::map materialMap = { + std::map materialMap = { {"Cesium_Milk_Truck_meshnode_0", truck}, {"Cesium_Milk_Truck_meshnode_1", glass}, {"Cesium_Milk_Truck_meshnode_2", windowTrim}, @@ -523,8 +508,8 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphCorrectAutomaticMaterialAssig }; for (auto instance : application.activeRaCoProject().project()->instances()) { - if (instance->isType()) { - auto activeMaterial = raco::core::ValueHandle(instance).get("materials")[0].get("material").asRef(); + if (instance->isType()) { + auto activeMaterial = core::ValueHandle(instance).get("materials")[0].get("material").asRef(); auto expectedMaterial = materialMap[instance->objectName()]; ASSERT_EQ(activeMaterial, expectedMaterial); @@ -536,7 +521,7 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphUnmarkedNodesDoNotGetImported auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string(); desc.bakeAllSubmeshes = false; @@ -567,16 +552,16 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphUnmarkedNodesDoNotGetImported // ---- Node.001 // ----- Wheels.001 - ASSERT_EQ(raco::core::Queries::findByName(application.activeRaCoProject().project()->instances(), "Node.001"), nullptr); - ASSERT_EQ(raco::core::Queries::findByName(application.activeRaCoProject().project()->instances(), "Wheels.001"), nullptr); - ASSERT_EQ(raco::core::Queries::findByName(application.activeRaCoProject().project()->instances(), "Cesium_Milk_Truck")->children_.asTable().size(), 2); + ASSERT_EQ(core::Queries::findByName(application.activeRaCoProject().project()->instances(), "Node.001"), nullptr); + ASSERT_EQ(core::Queries::findByName(application.activeRaCoProject().project()->instances(), "Wheels.001"), nullptr); + ASSERT_EQ(core::Queries::findByName(application.activeRaCoProject().project()->instances(), "Cesium_Milk_Truck")->children_->size(), 2); } TEST_F(RaCoApplicationFixture, importglTFScenegraphImportedAnimationDoesNotGetPartitioned) { auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/RiggedFigure/RiggedFigure.gltf").string(); desc.bakeAllSubmeshes = false; @@ -585,18 +570,18 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphImportedAnimationDoesNotGetPa commandInterface->insertAssetScenegraph(scenegraph, desc.absPath, nullptr); - auto allAnims = raco::core::Queries::filterByTypeName(application.activeRaCoProject().project()->instances(), {raco::user_types::Animation::typeDescription.typeName}); + auto allAnims = core::Queries::filterByTypeName(application.activeRaCoProject().project()->instances(), {user_types::Animation::typeDescription.typeName}); // 57 AnimationChannels in 1 Animation object ASSERT_EQ(allAnims.size(), 1); - ASSERT_EQ(allAnims.front()->get("animationChannels")->asTable().size(), 57); + ASSERT_EQ(allAnims.front()->get("animationChannels")->asArray().size(), 57); } TEST_F(RaCoApplicationFixture, importglTFScenegraphDeselectedAnimationsDoNotGetImported) { auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string(); desc.bakeAllSubmeshes = false; @@ -606,7 +591,7 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphDeselectedAnimationsDoNotGetI commandInterface->insertAssetScenegraph(scenegraph, desc.absPath, nullptr); - auto allAnims = raco::core::Queries::filterByTypeName(application.activeRaCoProject().project()->instances(), {raco::user_types::Animation::typeDescription.typeName}); + auto allAnims = core::Queries::filterByTypeName(application.activeRaCoProject().project()->instances(), {user_types::Animation::typeDescription.typeName}); ASSERT_TRUE(allAnims.empty()); ASSERT_TRUE(application.activeRaCoProject().project()->links().size() == 0); } @@ -616,7 +601,7 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphDeselectedNodesWillNotCreateL auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string(); desc.bakeAllSubmeshes = false; @@ -635,7 +620,7 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphDeselectedAnimationChannelsDo auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string(); desc.bakeAllSubmeshes = false; @@ -649,13 +634,13 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphDeselectedAnimationChannelsDo commandInterface->insertAssetScenegraph(scenegraph, desc.absPath, nullptr); - auto allAnimChannels = raco::core::Queries::filterByTypeName(application.activeRaCoProject().project()->instances(), {raco::user_types::AnimationChannel::typeDescription.typeName}); + auto allAnimChannels = core::Queries::filterByTypeName(application.activeRaCoProject().project()->instances(), {user_types::AnimationChannel::typeDescription.typeName}); ASSERT_TRUE(allAnimChannels.empty()); - auto allAnims = raco::core::Queries::filterByTypeName(application.activeRaCoProject().project()->instances(), {raco::user_types::Animation::typeDescription.typeName}); + auto allAnims = core::Queries::filterByTypeName(application.activeRaCoProject().project()->instances(), {user_types::Animation::typeDescription.typeName}); ASSERT_EQ(allAnims.size(), 1); - auto& channels = allAnims.front()->get("animationChannels")->asTable(); + auto& channels = allAnims.front()->get("animationChannels")->asArray(); for (auto i = 0; i < channels.size(); ++i) { ASSERT_EQ(channels[i]->asRef(), nullptr); } @@ -689,7 +674,7 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphWithNoMeshes) { auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/meshless.gltf").string(); desc.bakeAllSubmeshes = false; @@ -718,7 +703,7 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphWithNoMeshesAndNoNodes) { )"); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = nodeless; desc.bakeAllSubmeshes = false; @@ -731,7 +716,7 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphMeshNodesDontReferenceDeselec auto* commandInterface = application.activeRaCoProject().commandInterface(); commandInterface->deleteObjects(application.activeRaCoProject().project()->instances()); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string(); desc.bakeAllSubmeshes = false; @@ -750,11 +735,11 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphMeshNodesDontReferenceDeselec commandInterface->insertAssetScenegraph(scenegraph, desc.absPath, nullptr); - auto allMeshNodes = raco::core::Queries::filterByTypeName(application.activeRaCoProject().project()->instances(), {raco::user_types::MeshNode::typeDescription.typeName}); + auto allMeshNodes = core::Queries::filterByTypeName(application.activeRaCoProject().project()->instances(), {user_types::MeshNode::typeDescription.typeName}); ASSERT_EQ(allMeshNodes.size(), 5); for (const auto& meshNode : allMeshNodes) { - auto referencingMesh = raco::core::ValueHandle(meshNode, {"mesh"}).asRef(); + auto referencingMesh = core::ValueHandle(meshNode, {"mesh"}).asRef(); if (meshNode->objectName() == "Cesium_Milk_Truck_meshnode_0") { ASSERT_EQ(referencingMesh, nullptr); } else { @@ -766,36 +751,36 @@ TEST_F(RaCoApplicationFixture, importglTFScenegraphMeshNodesDontReferenceDeselec TEST_F(RaCoApplicationFixture, LuaScriptRuntimeErrorCausesInformationForAllScripts) { auto* commandInterface = application.activeRaCoProject().commandInterface(); - auto const workingScript{ commandInterface->createObject(raco::user_types::LuaScript::typeDescription.typeName) }; - auto const runtimeErrorScript{commandInterface->createObject(raco::user_types::LuaScript::typeDescription.typeName)}; + auto const workingScript{ commandInterface->createObject(user_types::LuaScript::typeDescription.typeName) }; + auto const runtimeErrorScript{commandInterface->createObject(user_types::LuaScript::typeDescription.typeName)}; - commandInterface->set(raco::core::ValueHandle{ runtimeErrorScript, {"uri"}}, test_path().append("scripts/runtime-error.lua").string()); - commandInterface->set(raco::core::ValueHandle{ workingScript, {"uri"} }, test_path().append("scripts/SimpleScript.lua").string()); + commandInterface->set(core::ValueHandle{ runtimeErrorScript, {"uri"}}, test_path().append("scripts/runtime-error.lua").string()); + commandInterface->set(core::ValueHandle{ workingScript, {"uri"} }, test_path().append("scripts/SimpleScript.lua").string()); EXPECT_FALSE(application.activeRaCoProject().errors()->hasError(workingScript)); EXPECT_FALSE(application.activeRaCoProject().errors()->hasError(runtimeErrorScript)); - commandInterface->set(raco::core::ValueHandle{ runtimeErrorScript, {"inputs"} }.get("choice"), 1); + commandInterface->set(core::ValueHandle{ runtimeErrorScript, {"inputs"} }.get("choice"), 1); application.doOneLoop(); EXPECT_TRUE(application.activeRaCoProject().errors()->hasError(runtimeErrorScript)); - EXPECT_EQ(application.activeRaCoProject().errors()->getError(runtimeErrorScript).level(), raco::core::ErrorLevel::ERROR); + EXPECT_EQ(application.activeRaCoProject().errors()->getError(runtimeErrorScript).level(), core::ErrorLevel::ERROR); EXPECT_TRUE(application.activeRaCoProject().errors()->getError(runtimeErrorScript).message().find("value") != std::string::npos); EXPECT_TRUE(application.activeRaCoProject().errors()->hasError(workingScript)); - EXPECT_EQ(application.activeRaCoProject().errors()->getError(workingScript).level(), raco::core::ErrorLevel::INFORMATION); + EXPECT_EQ(application.activeRaCoProject().errors()->getError(workingScript).level(), core::ErrorLevel::INFORMATION); EXPECT_TRUE(application.activeRaCoProject().errors()->getError(workingScript).message().find("runtime error") != std::string::npos); } TEST_F(RaCoApplicationFixture, LuaScriptFixingRuntimeErrorRemovesLogicError) { auto* commandInterface = application.activeRaCoProject().commandInterface(); - auto emptyScript{commandInterface->createObject(raco::user_types::LuaScript::typeDescription.typeName)}; - auto runtimeErrorScript{commandInterface->createObject(raco::user_types::LuaScript::typeDescription.typeName)}; - commandInterface->set(raco::core::ValueHandle{runtimeErrorScript, {"uri"}}, test_path().append("scripts/runtime-error.lua").string()); - commandInterface->set(raco::core::ValueHandle{runtimeErrorScript, {"inputs"}}.get("choice"), 1); + auto emptyScript{commandInterface->createObject(user_types::LuaScript::typeDescription.typeName)}; + auto runtimeErrorScript{commandInterface->createObject(user_types::LuaScript::typeDescription.typeName)}; + commandInterface->set(core::ValueHandle{runtimeErrorScript, {"uri"}}, test_path().append("scripts/runtime-error.lua").string()); + commandInterface->set(core::ValueHandle{runtimeErrorScript, {"inputs"}}.get("choice"), 1); application.doOneLoop(); - commandInterface->set(raco::core::ValueHandle{runtimeErrorScript, {"inputs"}}.get("choice"), 0); + commandInterface->set(core::ValueHandle{runtimeErrorScript, {"inputs"}}.get("choice"), 0); application.doOneLoop(); EXPECT_FALSE(application.activeRaCoProject().errors()->hasError(runtimeErrorScript)); @@ -805,59 +790,59 @@ TEST_F(RaCoApplicationFixture, LuaScriptFixingRuntimeErrorRemovesLogicError) { TEST_F(RaCoApplicationFixture, LuaScriptFixingRuntimeErrorDoesNotDeleteOtherErrors) { auto* commandInterface = application.activeRaCoProject().commandInterface(); - auto emptyURIScript{ commandInterface->createObject(raco::user_types::LuaScript::typeDescription.typeName) }; - auto compileErrorScript{commandInterface->createObject(raco::user_types::LuaScript::typeDescription.typeName)}; - auto runtimeErrorScript1{commandInterface->createObject(raco::user_types::LuaScript::typeDescription.typeName)}; - auto runtimeErrorScript2{ commandInterface->createObject(raco::user_types::LuaScript::typeDescription.typeName) }; - commandInterface->set(raco::core::ValueHandle{ compileErrorScript, {"uri"} }, test_path().append("scripts/compile-error.lua").string()); - commandInterface->set(raco::core::ValueHandle{runtimeErrorScript1, {"uri"}}, test_path().append("scripts/runtime-error.lua").string()); - commandInterface->set(raco::core::ValueHandle{runtimeErrorScript1, {"inputs"}}.get("choice"), 1); - commandInterface->set(raco::core::ValueHandle{ runtimeErrorScript2, {"uri"} }, test_path().append("scripts/runtime-error.lua").string()); - commandInterface->set(raco::core::ValueHandle{ runtimeErrorScript2, {"inputs"} }.get("choice"), 0); - - application.doOneLoop(); - EXPECT_EQ(application.activeRaCoProject().errors()->getError(runtimeErrorScript1).level(), raco::core::ErrorLevel::ERROR); - EXPECT_EQ(application.activeRaCoProject().errors()->getError(runtimeErrorScript2).level(), raco::core::ErrorLevel::INFORMATION); - EXPECT_EQ(application.activeRaCoProject().errors()->getError(compileErrorScript).level(), raco::core::ErrorLevel::ERROR); - commandInterface->set(raco::core::ValueHandle{runtimeErrorScript1, {"inputs"}}.get("choice"), 0); - commandInterface->set(raco::core::ValueHandle{ runtimeErrorScript2, {"inputs"} }.get("choice"), 1); - application.doOneLoop(); - - EXPECT_EQ(application.activeRaCoProject().errors()->getError(runtimeErrorScript2).level(), raco::core::ErrorLevel::ERROR); - EXPECT_EQ(application.activeRaCoProject().errors()->getError(runtimeErrorScript1).level(), raco::core::ErrorLevel::INFORMATION); - EXPECT_EQ(application.activeRaCoProject().errors()->getError(compileErrorScript).level(), raco::core::ErrorLevel::ERROR); - EXPECT_TRUE(application.activeRaCoProject().errors()->hasError(raco::core::ValueHandle(emptyURIScript, { "uri" }))); - - commandInterface->set(raco::core::ValueHandle{ runtimeErrorScript2, {"inputs"} }.get("choice"), 0); - application.doOneLoop(); +auto emptyURIScript{ commandInterface->createObject(user_types::LuaScript::typeDescription.typeName) }; +auto compileErrorScript{ commandInterface->createObject(user_types::LuaScript::typeDescription.typeName) }; +auto runtimeErrorScript1{ commandInterface->createObject(user_types::LuaScript::typeDescription.typeName) }; +auto runtimeErrorScript2{ commandInterface->createObject(user_types::LuaScript::typeDescription.typeName) }; +commandInterface->set(core::ValueHandle{ compileErrorScript, {"uri"} }, test_path().append("scripts/compile-error.lua").string()); +commandInterface->set(core::ValueHandle{ runtimeErrorScript1, {"uri"} }, test_path().append("scripts/runtime-error.lua").string()); +commandInterface->set(core::ValueHandle{ runtimeErrorScript1, {"inputs"} }.get("choice"), 1); +commandInterface->set(core::ValueHandle{ runtimeErrorScript2, {"uri"} }, test_path().append("scripts/runtime-error.lua").string()); +commandInterface->set(core::ValueHandle{ runtimeErrorScript2, {"inputs"} }.get("choice"), 0); + +application.doOneLoop(); +EXPECT_EQ(application.activeRaCoProject().errors()->getError(runtimeErrorScript1).level(), core::ErrorLevel::ERROR); +EXPECT_EQ(application.activeRaCoProject().errors()->getError(runtimeErrorScript2).level(), core::ErrorLevel::INFORMATION); +EXPECT_EQ(application.activeRaCoProject().errors()->getError(compileErrorScript).level(), core::ErrorLevel::ERROR); +commandInterface->set(core::ValueHandle{ runtimeErrorScript1, {"inputs"} }.get("choice"), 0); +commandInterface->set(core::ValueHandle{ runtimeErrorScript2, {"inputs"} }.get("choice"), 1); +application.doOneLoop(); + +EXPECT_EQ(application.activeRaCoProject().errors()->getError(runtimeErrorScript2).level(), core::ErrorLevel::ERROR); +EXPECT_EQ(application.activeRaCoProject().errors()->getError(runtimeErrorScript1).level(), core::ErrorLevel::INFORMATION); +EXPECT_EQ(application.activeRaCoProject().errors()->getError(compileErrorScript).level(), core::ErrorLevel::ERROR); +EXPECT_TRUE(application.activeRaCoProject().errors()->hasError(core::ValueHandle(emptyURIScript, { "uri" }))); + +commandInterface->set(core::ValueHandle{ runtimeErrorScript2, {"inputs"} }.get("choice"), 0); +application.doOneLoop(); } TEST_F(RaCoApplicationFixture, LuaScriptNewestRuntimeErrorGetsProperlyUpdated) { auto* commandInterface = application.activeRaCoProject().commandInterface(); - auto runtimeErrorScript1{commandInterface->createObject(raco::user_types::LuaScript::typeDescription.typeName)}; - auto runtimeErrorScript2{commandInterface->createObject(raco::user_types::LuaScript::typeDescription.typeName)}; - commandInterface->set(raco::core::ValueHandle{runtimeErrorScript1, {"uri"}}, test_path().append("scripts/runtime-error.lua").string()); - commandInterface->set(raco::core::ValueHandle{runtimeErrorScript2, {"uri"}}, test_path().append("scripts/runtime-error.lua").string()); - commandInterface->set(raco::core::ValueHandle{runtimeErrorScript1, {"inputs"}}.get("choice"), 1); - commandInterface->set(raco::core::ValueHandle{runtimeErrorScript2, {"inputs"}}.get("choice"), 0); + auto runtimeErrorScript1{ commandInterface->createObject(user_types::LuaScript::typeDescription.typeName) }; + auto runtimeErrorScript2{ commandInterface->createObject(user_types::LuaScript::typeDescription.typeName) }; + commandInterface->set(core::ValueHandle{ runtimeErrorScript1, {"uri"} }, test_path().append("scripts/runtime-error.lua").string()); + commandInterface->set(core::ValueHandle{ runtimeErrorScript2, {"uri"} }, test_path().append("scripts/runtime-error.lua").string()); + commandInterface->set(core::ValueHandle{ runtimeErrorScript1, {"inputs"} }.get("choice"), 1); + commandInterface->set(core::ValueHandle{ runtimeErrorScript2, {"inputs"} }.get("choice"), 0); application.doOneLoop(); - EXPECT_EQ(application.activeRaCoProject().errors()->getError(runtimeErrorScript1).level(), raco::core::ErrorLevel::ERROR); - EXPECT_EQ(application.activeRaCoProject().errors()->getError(runtimeErrorScript2).level(), raco::core::ErrorLevel::INFORMATION); + EXPECT_EQ(application.activeRaCoProject().errors()->getError(runtimeErrorScript1).level(), core::ErrorLevel::ERROR); + EXPECT_EQ(application.activeRaCoProject().errors()->getError(runtimeErrorScript2).level(), core::ErrorLevel::INFORMATION); - commandInterface->set(raco::core::ValueHandle{runtimeErrorScript1, {"inputs"}}.get("choice"), 0); + commandInterface->set(core::ValueHandle{ runtimeErrorScript1, {"inputs"} }.get("choice"), 0); application.doOneLoop(); EXPECT_TRUE(application.activeRaCoProject().errors()->getAllErrors().empty()); - commandInterface->set(raco::core::ValueHandle{runtimeErrorScript2, {"inputs"}}.get("choice"), 1); + commandInterface->set(core::ValueHandle{ runtimeErrorScript2, {"inputs"} }.get("choice"), 1); application.doOneLoop(); - EXPECT_EQ(application.activeRaCoProject().errors()->getError(runtimeErrorScript1).level(), raco::core::ErrorLevel::INFORMATION); - EXPECT_EQ(application.activeRaCoProject().errors()->getError(runtimeErrorScript2).level(), raco::core::ErrorLevel::ERROR); + EXPECT_EQ(application.activeRaCoProject().errors()->getError(runtimeErrorScript1).level(), core::ErrorLevel::INFORMATION); + EXPECT_EQ(application.activeRaCoProject().errors()->getError(runtimeErrorScript2).level(), core::ErrorLevel::ERROR); - commandInterface->set(raco::core::ValueHandle{runtimeErrorScript2, {"inputs"}}.get("choice"), 0); + commandInterface->set(core::ValueHandle{ runtimeErrorScript2, {"inputs"} }.get("choice"), 0); application.doOneLoop(); EXPECT_TRUE(application.activeRaCoProject().errors()->getAllErrors().empty()); @@ -866,12 +851,12 @@ TEST_F(RaCoApplicationFixture, LuaScriptNewestRuntimeErrorGetsProperlyUpdated) { TEST_F(RaCoApplicationFixture, LuaScriptCompileErrorDoesNotCauseErrorForAllScripts) { auto* commandInterface = application.activeRaCoProject().commandInterface(); - auto emptyScript{commandInterface->createObject(raco::user_types::LuaScript::typeDescription.typeName)}; - auto compileErrorScript{commandInterface->createObject(raco::user_types::LuaScript::typeDescription.typeName)}; - commandInterface->set(raco::core::ValueHandle{compileErrorScript, {"uri"}}, test_path().append("scripts/compile-error.lua").string()); + auto emptyScript{ commandInterface->createObject(user_types::LuaScript::typeDescription.typeName) }; + auto compileErrorScript{ commandInterface->createObject(user_types::LuaScript::typeDescription.typeName) }; + commandInterface->set(core::ValueHandle{ compileErrorScript, {"uri"} }, test_path().append("scripts/compile-error.lua").string()); application.doOneLoop(); - + EXPECT_TRUE(application.activeRaCoProject().errors()->hasError(compileErrorScript)); EXPECT_FALSE(application.activeRaCoProject().errors()->hasError(emptyScript)); } @@ -879,12 +864,12 @@ TEST_F(RaCoApplicationFixture, LuaScriptCompileErrorDoesNotCauseErrorForAllScrip TEST_F(RaCoApplicationFixture, LuaScriptDeletingScriptWithRunTimeErrorUpdatesAllErrors) { auto* commandInterface = application.activeRaCoProject().commandInterface(); - auto emptyScript{commandInterface->createObject(raco::user_types::LuaScript::typeDescription.typeName)}; - auto runtimeErrorScript{commandInterface->createObject(raco::user_types::LuaScript::typeDescription.typeName)}; - auto node{commandInterface->createObject(raco::user_types::Node::typeDescription.typeName)}; - auto mesh{commandInterface->createObject(raco::user_types::Mesh::typeDescription.typeName)}; - commandInterface->set(raco::core::ValueHandle{runtimeErrorScript, {"uri"}}, test_path().append("scripts/runtime-error.lua").string()); - commandInterface->set(raco::core::ValueHandle{runtimeErrorScript, {"inputs"}}.get("choice"), 1); + auto emptyScript{ commandInterface->createObject(user_types::LuaScript::typeDescription.typeName) }; + auto runtimeErrorScript{ commandInterface->createObject(user_types::LuaScript::typeDescription.typeName) }; + auto node{ commandInterface->createObject(user_types::Node::typeDescription.typeName) }; + auto mesh{ commandInterface->createObject(user_types::Mesh::typeDescription.typeName) }; + commandInterface->set(core::ValueHandle{ runtimeErrorScript, {"uri"} }, test_path().append("scripts/runtime-error.lua").string()); + commandInterface->set(core::ValueHandle{ runtimeErrorScript, {"inputs"} }.get("choice"), 1); application.doOneLoop(); @@ -894,39 +879,71 @@ TEST_F(RaCoApplicationFixture, LuaScriptDeletingScriptWithRunTimeErrorUpdatesAll // resources don't show Ramses Logic errors as of now ASSERT_FALSE(application.activeRaCoProject().errors()->hasError(mesh)); - commandInterface->deleteObjects({runtimeErrorScript}); + commandInterface->deleteObjects({ runtimeErrorScript }); application.doOneLoop(); ASSERT_FALSE(application.activeRaCoProject().errors()->hasError(emptyScript)); ASSERT_FALSE(application.activeRaCoProject().errors()->hasError(node)); ASSERT_FALSE(application.activeRaCoProject().errors()->hasError(mesh)); // "empty URI" error - ASSERT_TRUE(application.activeRaCoProject().errors()->hasError(raco::core::ValueHandle{mesh, {"uri"}})); + ASSERT_TRUE(application.activeRaCoProject().errors()->hasError(core::ValueHandle{ mesh, {"uri"} })); } TEST_F(RaCoApplicationFixture, feature_level_copy_paste_downgrade) { - application.switchActiveRaCoProject({}, {}, false, 2); - auto* cmd = application.activeRaCoProject().commandInterface(); - auto node = cmd->createObject(raco::user_types::Node::typeDescription.typeName, "node"); - std::string clipboard = cmd->copyObjects({node}, true); + if (ramses_base::BaseEngineBackend::minFeatureLevel < ramses_base::BaseEngineBackend::maxFeatureLevel) { + application.switchActiveRaCoProject({}, {}, false, ramses_base::BaseEngineBackend::maxFeatureLevel); + auto* cmd = application.activeRaCoProject().commandInterface(); + auto node = cmd->createObject(user_types::Node::typeDescription.typeName, "node"); + std::string clipboard = cmd->copyObjects({node}, true); - application.switchActiveRaCoProject({}, {}, false, 1); - cmd = application.activeRaCoProject().commandInterface(); - EXPECT_EQ(application.activeRaCoProject().project()->featureLevel(), 1); + application.switchActiveRaCoProject({}, {}, false, ramses_base::BaseEngineBackend::minFeatureLevel); + cmd = application.activeRaCoProject().commandInterface(); + EXPECT_EQ(application.activeRaCoProject().project()->featureLevel(), ramses_base::BaseEngineBackend::minFeatureLevel); - EXPECT_THROW(cmd->pasteObjects(clipboard), std::runtime_error); + EXPECT_THROW(cmd->pasteObjects(clipboard), std::runtime_error); + } } TEST_F(RaCoApplicationFixture, feature_level_copy_paste_upgrade) { - application.switchActiveRaCoProject({}, {}, false, 1); + application.switchActiveRaCoProject({}, {}, false, ramses_base::BaseEngineBackend::minFeatureLevel); auto* cmd = application.activeRaCoProject().commandInterface(); - auto node = cmd->createObject(raco::user_types::Node::typeDescription.typeName, "node"); + auto node = cmd->createObject(user_types::Node::typeDescription.typeName, "node"); std::string clipboard = cmd->copyObjects({node}, true); - application.switchActiveRaCoProject({}, {}, false, 2); + application.switchActiveRaCoProject({}, {}, false, ramses_base::BaseEngineBackend::maxFeatureLevel); cmd = application.activeRaCoProject().commandInterface(); - EXPECT_EQ(application.activeRaCoProject().project()->featureLevel(), 2); + EXPECT_EQ(application.activeRaCoProject().project()->featureLevel(), ramses_base::BaseEngineBackend::maxFeatureLevel); auto pasted = cmd->pasteObjects(clipboard); EXPECT_EQ(pasted.size(), 1); } + +TEST_F(RaCoApplicationFixture, add_external_project_valid_file) { + core::LoadContext loadContext; + loadContext.featureLevel = application.activeRaCoProject().project()->featureLevel(); + loadContext.pathStack.emplace_back(application.activeRaCoProject().project()->currentPath()); + + application.externalProjects()->addExternalProject((test_path() / "export-interface-link-opt-1.rca").string(), loadContext); + EXPECT_TRUE(application.externalProjects()->isExternalProject((test_path() / "export-interface-link-opt-1.rca").string())); + EXPECT_FALSE(application.externalProjects()->getExternalProject((test_path() / "export-interface-link-opt-1.rca").string()) == nullptr); +} + +TEST_F(RaCoApplicationFixture, add_external_project_directory) { + core::LoadContext loadContext; + loadContext.featureLevel = application.activeRaCoProject().project()->featureLevel(); + loadContext.pathStack.emplace_back(application.activeRaCoProject().project()->currentPath()); + + application.externalProjects()->addExternalProject(test_path().string(), loadContext); + EXPECT_FALSE(application.externalProjects()->isExternalProject(test_path().string())); + +} + +TEST_F(RaCoApplicationFixture, add_external_project_no_such_file) { + core::LoadContext loadContext; + loadContext.featureLevel = application.activeRaCoProject().project()->featureLevel(); + loadContext.pathStack.emplace_back(application.activeRaCoProject().project()->currentPath()); + + application.externalProjects()->addExternalProject((test_path() / "no-such-file.rca").string(), loadContext); + EXPECT_TRUE(application.externalProjects()->isExternalProject((test_path() / "no-such-file.rca").string())); + EXPECT_TRUE(application.externalProjects()->getExternalProject((test_path() / "no-such-file.rca").string()) == nullptr); +} diff --git a/components/libApplication/tests/RaCoProject_test.cpp b/components/libApplication/tests/RaCoProject_test.cpp index 107f305d..ebf9328f 100644 --- a/components/libApplication/tests/RaCoProject_test.cpp +++ b/components/libApplication/tests/RaCoProject_test.cpp @@ -43,7 +43,7 @@ TEST_F(RaCoProjectFixture, saveLoadWithLink) { TEST_F(RaCoProjectFixture, saveLoadWithBrokenLink) { auto linkedScene = raco::createLinkedScene(commandInterface(), test_path()); - raco::utils::file::write((test_path() / "lua_script.lua").string(), R"( + utils::file::write((test_path() / "lua_script.lua").string(), R"( function interface(IN,OUT) OUT.newTranslation = Type:Vec3f() end @@ -57,15 +57,15 @@ end ASSERT_EQ(1, application.activeRaCoProject().project()->links().size()); ASSERT_FALSE((*application.activeRaCoProject().project()->links().begin())->isValid()); - auto node = raco::core::Queries::findByName(application.activeRaCoProject().project()->instances(), "node"); + auto node = core::Queries::findByName(application.activeRaCoProject().project()->instances(), "node"); ASSERT_TRUE(application.activeRaCoProject().errors()->hasError(node)); } TEST_F(RaCoProjectFixture, saveLoadWithBrokenAndValidLink) { { - const auto luaScript{application.activeRaCoProject().commandInterface()->createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script")}; - const auto node{application.activeRaCoProject().commandInterface()->createObject(raco::user_types::Node::typeDescription.typeName, "node")}; - raco::utils::file::write((test_path() / "lua_script.lua").string(), R"( + const auto luaScript{application.activeRaCoProject().commandInterface()->createObject(user_types::LuaScript::typeDescription.typeName, "lua_script")}; + const auto node{application.activeRaCoProject().commandInterface()->createObject(user_types::Node::typeDescription.typeName, "node")}; + utils::file::write((test_path() / "lua_script.lua").string(), R"( function interface(IN,OUT) OUT.translation = Type:Vec3f() OUT.rotation = Type:Vec3f() @@ -85,7 +85,7 @@ end ASSERT_TRUE(application.activeRaCoProject().saveAs((test_path() / "project.rca").string().c_str(), msg)); } - raco::utils::file::write((test_path() / "lua_script.lua").string(), R"( + utils::file::write((test_path() / "lua_script.lua").string(), R"( function interface(IN,OUT) OUT.newTranslation = Type:Vec3f() OUT.rotation = Type:Vec3f() @@ -96,8 +96,8 @@ end { application.switchActiveRaCoProject(QString::fromStdString((test_path() / "project.rca").string()), {}); - auto node = raco::core::Queries::findByName(application.activeRaCoProject().project()->instances(), "node"); - auto luaScript = raco::core::Queries::findByName(application.activeRaCoProject().project()->instances(), "lua_script"); + auto node = core::Queries::findByName(application.activeRaCoProject().project()->instances(), "node"); + auto luaScript = core::Queries::findByName(application.activeRaCoProject().project()->instances(), "lua_script"); checkLinks(*application.activeRaCoProject().project(), {{{luaScript, {"outputs", "translation"}}, {node, {"translation"}}, false}, @@ -106,7 +106,7 @@ end ASSERT_TRUE(application.activeRaCoProject().errors()->hasError(node)); } - raco::utils::file::write((test_path() / "lua_script.lua").string(), R"( + utils::file::write((test_path() / "lua_script.lua").string(), R"( function interface(IN,OUT) OUT.translation = Type:Vec3f() OUT.rotation = Type:Vec3f() @@ -117,8 +117,8 @@ end { application.switchActiveRaCoProject(QString::fromStdString((test_path() / "project.rca").string()), {}); - auto node = raco::core::Queries::findByName(application.activeRaCoProject().project()->instances(), "node"); - auto luaScript = raco::core::Queries::findByName(application.activeRaCoProject().project()->instances(), "lua_script"); + auto node = core::Queries::findByName(application.activeRaCoProject().project()->instances(), "node"); + auto luaScript = core::Queries::findByName(application.activeRaCoProject().project()->instances(), "lua_script"); checkLinks(*application.activeRaCoProject().project(), {{{luaScript, {"outputs", "translation"}}, {node, {"translation"}}, true}, @@ -134,7 +134,7 @@ TEST_F(RaCoProjectFixture, saveWithValidLinkLoadWithBrokenLink) { std::string msg; ASSERT_TRUE(application.activeRaCoProject().saveAs((test_path() / "project.rca").string().c_str(), msg)); } - raco::utils::file::write((test_path() / "lua_script.lua").string(), R"( + utils::file::write((test_path() / "lua_script.lua").string(), R"( function interface(IN,OUT) OUT.newTranslation = Type:Vec3f() end @@ -146,7 +146,7 @@ end application.switchActiveRaCoProject(QString::fromStdString((test_path() / "project.rca").string()), {}); ASSERT_EQ(1, application.activeRaCoProject().project()->links().size()); ASSERT_FALSE((*application.activeRaCoProject().project()->links().begin())->isValid()); - auto node = raco::core::Queries::findByName(application.activeRaCoProject().project()->instances(), "node"); + auto node = core::Queries::findByName(application.activeRaCoProject().project()->instances(), "node"); ASSERT_TRUE(application.activeRaCoProject().errors()->hasError(node)); } } @@ -154,7 +154,7 @@ end TEST_F(RaCoProjectFixture, saveWithBrokenLinkLoadWithValidLink) { { auto linkedScene = raco::createLinkedScene(*application.activeRaCoProject().commandInterface(), test_path()); - raco::utils::file::write((test_path() / "lua_script.lua").string(), R"( + utils::file::write((test_path() / "lua_script.lua").string(), R"( function interface(IN,OUT) OUT.newTranslation = Type:Vec3f() end @@ -165,7 +165,7 @@ end ASSERT_TRUE(application.activeRaCoProject().saveAs((test_path() / "project.rca").string().c_str(), msg)); } - raco::utils::file::write((test_path() / "lua_script.lua").string(), R"( + utils::file::write((test_path() / "lua_script.lua").string(), R"( function interface(IN,OUT) OUT.translation = Type:Vec3f() end @@ -188,7 +188,7 @@ TEST_F(RaCoProjectFixture, saveLoadWithLinkRemoveOutputPropertyBeforeLoading) { } // replace OUT.translation with OUT.scale in external script file - raco::utils::file::write((test_path() / "lua_script.lua").string(), R"( + utils::file::write((test_path() / "lua_script.lua").string(), R"( function interface(IN,OUT) OUT.scale = Type:Vec3f() end @@ -207,7 +207,7 @@ end TEST_F(RaCoProjectFixture, saveLoadWithLuaScriptNewOutputPropertyGetsCalculated) { auto luaScriptPath = (test_path() / "lua_script.lua").string(); - raco::utils::file::write(luaScriptPath, R"( + utils::file::write(luaScriptPath, R"( function interface(IN,OUT) IN.integer = Type:Int32() OUT.integer = Type:Int32() @@ -221,14 +221,14 @@ end )"); { - const auto luaScript{application.activeRaCoProject().commandInterface()->createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script")}; - application.activeRaCoProject().commandInterface()->set(raco::core::ValueHandle{luaScript, {"uri"}}, luaScriptPath); - application.activeRaCoProject().commandInterface()->set(raco::core::ValueHandle{luaScript, {"inputs", "integer"}}, 5); + const auto luaScript{application.activeRaCoProject().commandInterface()->createObject(user_types::LuaScript::typeDescription.typeName, "lua_script")}; + application.activeRaCoProject().commandInterface()->set(core::ValueHandle{luaScript, {"uri"}}, luaScriptPath); + application.activeRaCoProject().commandInterface()->set(core::ValueHandle{luaScript, {"inputs", "integer"}}, 5); std::string msg; ASSERT_TRUE(application.activeRaCoProject().saveAs((test_path() / "project.rca").string().c_str(), msg)); } - raco::utils::file::write((test_path() / "lua_script.lua").string(), R"( + utils::file::write((test_path() / "lua_script.lua").string(), R"( function interface(IN,OUT) IN.integer = Type:Int32() OUT.integerTwo = Type:Int32() @@ -243,15 +243,15 @@ end { application.switchActiveRaCoProject(QString::fromStdString((test_path() / "project.rca").string()), {}); application.doOneLoop(); - auto luaScript = raco::core::Queries::findByName(application.activeRaCoProject().project()->instances(), "lua_script"); - auto newPropertyOutput = raco::core::ValueHandle{luaScript, {"outputs", "integerTwo"}}.asInt(); + auto luaScript = core::Queries::findByName(application.activeRaCoProject().project()->instances(), "lua_script"); + auto newPropertyOutput = core::ValueHandle{luaScript, {"outputs", "integerTwo"}}.asInt(); ASSERT_EQ(newPropertyOutput, 5); } } TEST_F(RaCoProjectFixture, saveAsMeshRerootRelativeURIHierarchyDown) { application.activeRaCoProject().project()->setCurrentPath((test_path() / "project.rca").string()); - auto mesh = application.activeRaCoProject().commandInterface()->createObject(raco::user_types::Mesh::typeDescription.typeName, "mesh"); + auto mesh = application.activeRaCoProject().commandInterface()->createObject(user_types::Mesh::typeDescription.typeName, "mesh"); std::string relativeUri{"Duck.glb"}; application.activeRaCoProject().commandInterface()->set({mesh, {"uri"}}, relativeUri); @@ -267,31 +267,31 @@ TEST_F(RaCoProjectFixture, saveAsMeshRerootRelativeURIHierarchyDown) { TEST_F(RaCoProjectFixture, saveAsThenLoadAnimationKeepsChannelAmount) { auto* commandInterface = application.activeRaCoProject().commandInterface(); - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string(); desc.bakeAllSubmeshes = false; auto [scenegraph, dummyCacheEntry] = raco::getMeshSceneGraphWithHandler(commandInterface->meshCache(), desc); commandInterface->insertAssetScenegraph(scenegraph, desc.absPath, nullptr); - commandInterface->createObject(raco::user_types::Animation::typeDescription.typeName, "userAnim"); + commandInterface->createObject(user_types::Animation::typeDescription.typeName, "userAnim"); std::string msg; ASSERT_TRUE(application.activeRaCoProject().saveAs((test_path() / "anims.rca").string().c_str(), msg)); application.switchActiveRaCoProject("", {}); application.switchActiveRaCoProject(QString::fromStdString((test_path() / "anims.rca").string()), {}); - auto anims = raco::core::Queries::filterByTypeName(application.activeRaCoProject().project()->instances(), {raco::user_types::Animation::typeDescription.typeName}); - auto importedAnim = raco::core::Queries::findByName(anims, "Wheels"); - auto userAnim = raco::core::Queries::findByName(anims, "userAnim"); + auto anims = core::Queries::filterByTypeName(application.activeRaCoProject().project()->instances(), {user_types::Animation::typeDescription.typeName}); + auto importedAnim = core::Queries::findByName(anims, "Wheels"); + auto userAnim = core::Queries::findByName(anims, "userAnim"); - ASSERT_EQ(userAnim->as()->animationChannels_.asTable().size(), raco::user_types::Animation::ANIMATION_CHANNEL_AMOUNT); - ASSERT_EQ(importedAnim->as()->animationChannels_.asTable().size(), 2); + ASSERT_EQ(userAnim->as()->animationChannels_->size(), 1); + ASSERT_EQ(importedAnim->as()->animationChannels_->size(), 2); } TEST_F(RaCoProjectFixture, saveAsMeshRerootRelativeURIHierarchyUp) { application.activeRaCoProject().project()->setCurrentPath((test_path() / "project" / "project.rca").string()); - auto mesh = application.activeRaCoProject().commandInterface()->createObject(raco::user_types::Mesh::typeDescription.typeName, "mesh"); + auto mesh = application.activeRaCoProject().commandInterface()->createObject(user_types::Mesh::typeDescription.typeName, "mesh"); std::string relativeUri{"Duck.glb"}; application.activeRaCoProject().commandInterface()->set({mesh, {"uri"}}, relativeUri); @@ -305,7 +305,7 @@ TEST_F(RaCoProjectFixture, saveAsMeshRerootRelativeURIHierarchyUp) { TEST_F(RaCoProjectFixture, saveAsMaterialRerootRelativeURI) { application.activeRaCoProject().project()->setCurrentPath((test_path() / "project.rca").string()); - auto mat = application.activeRaCoProject().commandInterface()->createObject(raco::user_types::Material::typeDescription.typeName, "material"); + auto mat = application.activeRaCoProject().commandInterface()->createObject(user_types::Material::typeDescription.typeName, "material"); std::string relativeUri{"relativeURI"}; application.activeRaCoProject().commandInterface()->set({mat, {"uriVertex"}}, relativeUri); @@ -322,7 +322,7 @@ TEST_F(RaCoProjectFixture, saveAsMaterialRerootRelativeURI) { TEST_F(RaCoProjectFixture, saveAsLuaScriptRerootRelativeURI) { application.activeRaCoProject().project()->setCurrentPath((test_path() / "project.rca").string()); - auto lua = application.activeRaCoProject().commandInterface()->createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua"); + auto lua = application.activeRaCoProject().commandInterface()->createObject(user_types::LuaScript::typeDescription.typeName, "lua"); std::string relativeUri{"relativeURI"}; application.activeRaCoProject().commandInterface()->set({lua, {"uri"}}, relativeUri); @@ -338,7 +338,7 @@ TEST_F(RaCoProjectFixture, saveAsLuaScriptRerootRelativeURI) { TEST_F(RaCoProjectFixture, saveAsSimulateSavingFromNewProjectCorrectlyRerootedRelativeURI) { std::filesystem::create_directory(test_path() / "project"); application.activeRaCoProject().project()->setCurrentPath((test_path() / "project").string()); - auto mesh = application.activeRaCoProject().commandInterface()->createObject(raco::user_types::Mesh::typeDescription.typeName, "lua"); + auto mesh = application.activeRaCoProject().commandInterface()->createObject(user_types::Mesh::typeDescription.typeName, "lua"); std::string relativeUri{"relativeURI.ctm"}; application.activeRaCoProject().commandInterface()->set({mesh, {"uri"}}, relativeUri); @@ -347,14 +347,14 @@ TEST_F(RaCoProjectFixture, saveAsSimulateSavingFromNewProjectCorrectlyRerootedRe std::string msg; ASSERT_TRUE(application.activeRaCoProject().saveAs((test_path() / "project" / "project.rca").string().c_str(), msg)); - ASSERT_EQ(raco::core::ValueHandle(mesh, {"uri"}).asString(), relativeUri); + ASSERT_EQ(core::ValueHandle(mesh, {"uri"}).asString(), relativeUri); } #if defined(_WIN32) TEST_F(RaCoProjectFixture, saveAsToDifferentDriveSetsRelativeURIsToAbsolute) { std::filesystem::create_directory(test_path() / "project"); application.activeRaCoProject().project()->setCurrentPath((test_path() / "project").string()); - auto mesh = application.activeRaCoProject().commandInterface()->createObject(raco::user_types::Mesh::typeDescription.typeName, "lua"); + auto mesh = application.activeRaCoProject().commandInterface()->createObject(user_types::Mesh::typeDescription.typeName, "lua"); std::string relativeUri{"relativeURI.ctm"}; application.activeRaCoProject().commandInterface()->set({mesh, {"uri"}}, relativeUri); @@ -364,7 +364,7 @@ TEST_F(RaCoProjectFixture, saveAsToDifferentDriveSetsRelativeURIsToAbsolute) { std::string msg; application.activeRaCoProject().saveAs("Z:/projectOnDifferentDrive.rca", msg); - ASSERT_EQ(raco::core::ValueHandle(mesh, {"uri"}).asString(), (test_path() / "project" / relativeUri).string()); + ASSERT_EQ(core::ValueHandle(mesh, {"uri"}).asString(), (test_path() / "project" / relativeUri).string()); } #endif @@ -399,20 +399,20 @@ TEST_F(RaCoProjectFixture, save_as_with_new_id_preserves_prefab_id_structure_nes application.activeRaCoProject().project()->setCurrentPath((test_path() / "project.rca").string()); - auto prefab = cmd.createObject(raco::user_types::Prefab::typeDescription.typeName, "prefab"); - auto lua = cmd.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua"); + auto prefab = cmd.createObject(user_types::Prefab::typeDescription.typeName, "prefab"); + auto lua = cmd.createObject(user_types::LuaScript::typeDescription.typeName, "lua"); cmd.moveScenegraphChildren({lua}, prefab); - auto prefab_2 = cmd.createObject(raco::user_types::Prefab::typeDescription.typeName, "prefab2"); - auto inst_1 = cmd.createObject(raco::user_types::PrefabInstance::typeDescription.typeName, "inst"); + auto prefab_2 = cmd.createObject(user_types::Prefab::typeDescription.typeName, "prefab2"); + auto inst_1 = cmd.createObject(user_types::PrefabInstance::typeDescription.typeName, "inst"); cmd.moveScenegraphChildren({inst_1}, prefab_2); - cmd.set({inst_1, &raco::user_types::PrefabInstance::template_}, prefab); + cmd.set({inst_1, &user_types::PrefabInstance::template_}, prefab); EXPECT_EQ(inst_1->children_->size(), 1); auto lua_1 = inst_1->children_->asVector()[0]; - auto inst_2 = cmd.createObject(raco::user_types::PrefabInstance::typeDescription.typeName, "inst2"); - cmd.set({inst_2, &raco::user_types::PrefabInstance::template_}, prefab_2); + auto inst_2 = cmd.createObject(user_types::PrefabInstance::typeDescription.typeName, "inst2"); + cmd.set({inst_2, &user_types::PrefabInstance::template_}, prefab_2); EXPECT_EQ(inst_2->children_->size(), 1); auto inst_3 = inst_2->children_->asVector()[0]; EXPECT_EQ(inst_3->children_->size(), 1); @@ -487,11 +487,11 @@ TEST_F(RaCoProjectFixture, idChange) { } TEST_F(RaCoProjectFixture, restoredLinkWorksInLogicEngine) { - auto start{application.activeRaCoProject().commandInterface()->createObject(raco::user_types::LuaScript::typeDescription.typeName, "start")}; + auto start{application.activeRaCoProject().commandInterface()->createObject(user_types::LuaScript::typeDescription.typeName, "start")}; application.activeRaCoProject().commandInterface()->set({start, {"uri"}}, test_path().append("scripts/SimpleScript.lua").string()); application.doOneLoop(); - auto end{application.activeRaCoProject().commandInterface()->createObject(raco::user_types::LuaScript::typeDescription.typeName, "end")}; + auto end{application.activeRaCoProject().commandInterface()->createObject(user_types::LuaScript::typeDescription.typeName, "end")}; application.activeRaCoProject().commandInterface()->set({end, {"uri"}}, test_path().append("scripts/SimpleScript.lua").string()); application.doOneLoop(); @@ -506,14 +506,14 @@ TEST_F(RaCoProjectFixture, restoredLinkWorksInLogicEngine) { application.activeRaCoProject().commandInterface()->set({end, {"uri"}}, test_path().append("scripts/SimpleScript.lua").string()); application.activeRaCoProject().commandInterface()->set({start, {"inputs", "in_float"}}, 3.0); application.doOneLoop(); - ASSERT_EQ(raco::core::ValueHandle(end, {"inputs", "in_float"}).asDouble(), 3.0); + ASSERT_EQ(core::ValueHandle(end, {"inputs", "in_float"}).asDouble(), 3.0); } TEST_F(RaCoProjectFixture, brokenLinkDoesNotResetProperties) { - auto linkStart{application.activeRaCoProject().commandInterface()->createObject(raco::user_types::LuaScript::typeDescription.typeName, "start")}; + auto linkStart{application.activeRaCoProject().commandInterface()->createObject(user_types::LuaScript::typeDescription.typeName, "start")}; application.activeRaCoProject().commandInterface()->set({linkStart, {"uri"}}, test_path().append("scripts/types-scalar.lua").string()); - auto linkEnd{application.activeRaCoProject().commandInterface()->createObject(raco::user_types::LuaScript::typeDescription.typeName, "end")}; + auto linkEnd{application.activeRaCoProject().commandInterface()->createObject(user_types::LuaScript::typeDescription.typeName, "end")}; application.activeRaCoProject().commandInterface()->set({linkEnd, {"uri"}}, test_path().append("scripts/types-scalar.lua").string()); application.doOneLoop(); @@ -529,8 +529,8 @@ TEST_F(RaCoProjectFixture, brokenLinkDoesNotResetProperties) { application.activeRaCoProject().commandInterface()->set({linkEnd, {"inputs", "float"}}, 20.0); application.doOneLoop(); - auto output_int = raco::core::ValueHandle{linkEnd, {"outputs", "ointeger"}}.asInt(); - auto output_bool = raco::core::ValueHandle{linkEnd, {"outputs", "flag"}}.asBool(); + auto output_int = core::ValueHandle{linkEnd, {"outputs", "ointeger"}}.asInt(); + auto output_bool = core::ValueHandle{linkEnd, {"outputs", "flag"}}.asBool(); ASSERT_EQ(output_int, 40); ASSERT_EQ(output_bool, true); } @@ -538,7 +538,7 @@ TEST_F(RaCoProjectFixture, brokenLinkDoesNotResetProperties) { TEST_F(RaCoProjectFixture, launchApplicationWithNoResourceSubFoldersCachedPathsAreSetToUserProjectsDirectoryAndSubFolders) { auto newProjectFolder = test_path() / "newProject"; std::filesystem::create_directory(newProjectFolder); - raco::components::RaCoPreferences::instance().userProjectsDirectory = QString::fromStdString(newProjectFolder.string()); + components::RaCoPreferences::instance().userProjectsDirectory = QString::fromStdString(newProjectFolder.string()); application.switchActiveRaCoProject({}, {}); const auto& defaultResourceDirectories = application.activeRaCoProject().project()->settings()->defaultResourceDirectories_; @@ -548,26 +548,26 @@ TEST_F(RaCoProjectFixture, launchApplicationWithNoResourceSubFoldersCachedPathsA auto interfaceSubdirectory = defaultResourceDirectories->interfaceSubdirectory_.asString(); auto shaderSubdirectory = defaultResourceDirectories->shaderSubdirectory_.asString(); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Project), newProjectFolder); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Mesh), newProjectFolder / meshSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Image), newProjectFolder / imageSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Script), newProjectFolder / scriptSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Interface), newProjectFolder / interfaceSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Shader), newProjectFolder / shaderSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Project), newProjectFolder); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Mesh), newProjectFolder / meshSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Image), newProjectFolder / imageSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Script), newProjectFolder / scriptSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Interface), newProjectFolder / interfaceSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Shader), newProjectFolder / shaderSubdirectory); } TEST_F(RaCoProjectFixture, launchApplicationWithResourceSubFoldersCachedPathsAreSetToUserProjectsDirectoryAndSubFolders) { - raco::components::RaCoPreferences::instance().userProjectsDirectory = QString::fromStdString(test_path().string()); + components::RaCoPreferences::instance().userProjectsDirectory = QString::fromStdString(test_path().string()); application.switchActiveRaCoProject({}, {}); - const auto& prefs = raco::components::RaCoPreferences::instance(); + const auto& prefs = components::RaCoPreferences::instance(); std::filesystem::create_directory(test_path() / prefs.meshSubdirectory.toStdString()); std::filesystem::create_directory(test_path() / prefs.scriptSubdirectory.toStdString()); std::filesystem::create_directory(test_path() / prefs.interfaceSubdirectory.toStdString()); std::filesystem::create_directory(test_path() / prefs.imageSubdirectory.toStdString()); std::filesystem::create_directory(test_path() / prefs.shaderSubdirectory.toStdString()); - auto newProjectFolder = raco::components::RaCoPreferences::instance().userProjectsDirectory.toStdString(); + auto newProjectFolder = components::RaCoPreferences::instance().userProjectsDirectory.toStdString(); const auto& defaultResourceDirectories = application.activeRaCoProject().project()->settings()->defaultResourceDirectories_; auto imageSubdirectory = defaultResourceDirectories->imageSubdirectory_.asString(); @@ -576,12 +576,12 @@ TEST_F(RaCoProjectFixture, launchApplicationWithResourceSubFoldersCachedPathsAre auto interfaceSubdirectory = defaultResourceDirectories->interfaceSubdirectory_.asString(); auto shaderSubdirectory = defaultResourceDirectories->shaderSubdirectory_.asString(); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Project), newProjectFolder); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Mesh), newProjectFolder + "/" + meshSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Script), newProjectFolder + "/" + scriptSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Interface), newProjectFolder + "/" + interfaceSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Image), newProjectFolder + "/" + imageSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Shader), newProjectFolder + "/" + shaderSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Project), newProjectFolder); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Mesh), newProjectFolder + "/" + meshSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Script), newProjectFolder + "/" + scriptSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Interface), newProjectFolder + "/" + interfaceSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Image), newProjectFolder + "/" + imageSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Shader), newProjectFolder + "/" + shaderSubdirectory); } TEST_F(RaCoProjectFixture, saveAs_set_path_updates_cached_path) { @@ -608,11 +608,11 @@ TEST_F(RaCoProjectFixture, saveAs_set_path_updates_cached_path) { std::string newProjectFolder = application.activeRaCoProject().project()->currentFolder(); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Mesh), newProjectFolder + "/" + meshSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Script), newProjectFolder + "/" + scriptSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Interface), newProjectFolder + "/" + interfaceSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Image), newProjectFolder + "/" + imageSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Shader), newProjectFolder + "/" + shaderSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Mesh), newProjectFolder + "/" + meshSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Script), newProjectFolder + "/" + scriptSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Interface), newProjectFolder + "/" + interfaceSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Image), newProjectFolder + "/" + imageSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Shader), newProjectFolder + "/" + shaderSubdirectory); } TEST_F(RaCoProjectFixture, saveAs_with_new_id_set_path_updates_cached_path) { @@ -639,11 +639,11 @@ TEST_F(RaCoProjectFixture, saveAs_with_new_id_set_path_updates_cached_path) { std::string newProjectFolder = application.activeRaCoProject().project()->currentFolder(); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Mesh), newProjectFolder + "/" + meshSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Script), newProjectFolder + "/" + scriptSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Interface), newProjectFolder + "/" + interfaceSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Image), newProjectFolder + "/" + imageSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Shader), newProjectFolder + "/" + shaderSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Mesh), newProjectFolder + "/" + meshSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Script), newProjectFolder + "/" + scriptSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Interface), newProjectFolder + "/" + interfaceSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Image), newProjectFolder + "/" + imageSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Shader), newProjectFolder + "/" + shaderSubdirectory); } TEST_F(RaCoProjectFixture, saveAsNewProjectGeneratesResourceSubFolders) { @@ -673,28 +673,28 @@ TEST_F(RaCoProjectFixture, saveAsNewProjectGeneratesResourceSubFolders) { std::string msg; ASSERT_TRUE(application.activeRaCoProject().saveAs(QString::fromStdString(newProjectFolder + "/project.rca"), msg)); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Project).string(), newProjectFolder); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Project).string(), newProjectFolder); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Image).string(), imageSubdirectory); - ASSERT_TRUE(raco::utils::u8path(imageSubdirectory).existsDirectory()); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Image).string(), imageSubdirectory); + ASSERT_TRUE(utils::u8path(imageSubdirectory).existsDirectory()); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Mesh).string(), newProjectFolder + "/" + meshSubdirectory); - ASSERT_TRUE(raco::utils::u8path(newProjectFolder + "/" + meshSubdirectory).existsDirectory()); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Mesh).string(), newProjectFolder + "/" + meshSubdirectory); + ASSERT_TRUE(utils::u8path(newProjectFolder + "/" + meshSubdirectory).existsDirectory()); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Script).string(), newProjectFolder + "/" + scriptSubdirectory); - ASSERT_TRUE(raco::utils::u8path(newProjectFolder + "/" + scriptSubdirectory).existsDirectory()); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Script).string(), newProjectFolder + "/" + scriptSubdirectory); + ASSERT_TRUE(utils::u8path(newProjectFolder + "/" + scriptSubdirectory).existsDirectory()); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Interface).string(), newProjectFolder + "/" + interfaceSubdirectory); - ASSERT_TRUE(raco::utils::u8path(newProjectFolder + "/" + interfaceSubdirectory).existsDirectory()); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Interface).string(), newProjectFolder + "/" + interfaceSubdirectory); + ASSERT_TRUE(utils::u8path(newProjectFolder + "/" + interfaceSubdirectory).existsDirectory()); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Shader).string(), newProjectFolder + "/" + shaderSubdirectory); - ASSERT_TRUE(raco::utils::u8path(newProjectFolder + "/" + shaderSubdirectory).existsDirectory()); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Shader).string(), newProjectFolder + "/" + shaderSubdirectory); + ASSERT_TRUE(utils::u8path(newProjectFolder + "/" + shaderSubdirectory).existsDirectory()); } TEST_F(RaCoProjectFixture, saveAsThenCreateNewProjectResetsCachedPaths) { - raco::components::RaCoPreferences::instance().userProjectsDirectory = QString::fromStdString(test_path().string()); + components::RaCoPreferences::instance().userProjectsDirectory = QString::fromStdString(test_path().string()); - const auto& prefs = raco::components::RaCoPreferences::instance(); + const auto& prefs = components::RaCoPreferences::instance(); std::filesystem::create_directory(test_path() / prefs.meshSubdirectory.toStdString()); std::filesystem::create_directory(test_path() / prefs.scriptSubdirectory.toStdString()); std::filesystem::create_directory(test_path() / prefs.interfaceSubdirectory.toStdString()); @@ -713,14 +713,14 @@ TEST_F(RaCoProjectFixture, saveAsThenCreateNewProjectResetsCachedPaths) { auto interfaceSubdirectory = defaultResourceDirectories->interfaceSubdirectory_.asString(); auto shaderSubdirectory = defaultResourceDirectories->shaderSubdirectory_.asString(); - auto newProjectFolder = raco::components::RaCoPreferences::instance().userProjectsDirectory.toStdString(); + auto newProjectFolder = components::RaCoPreferences::instance().userProjectsDirectory.toStdString(); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Project), newProjectFolder); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Mesh), newProjectFolder + "/" + meshSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Script), newProjectFolder + "/" + scriptSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Interface), newProjectFolder + "/" + interfaceSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Image), newProjectFolder + "/" + imageSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Shader), newProjectFolder + "/" + shaderSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Project), newProjectFolder); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Mesh), newProjectFolder + "/" + meshSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Script), newProjectFolder + "/" + scriptSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Interface), newProjectFolder + "/" + interfaceSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Image), newProjectFolder + "/" + imageSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Shader), newProjectFolder + "/" + shaderSubdirectory); } TEST_F(RaCoProjectFixture, saveAsThenLoadProjectProperlySetCachedPaths) { @@ -739,18 +739,18 @@ TEST_F(RaCoProjectFixture, saveAsThenLoadProjectProperlySetCachedPaths) { auto interfaceSubdirectory = defaultResourceDirectories->interfaceSubdirectory_.asString(); auto shaderSubdirectory = defaultResourceDirectories->shaderSubdirectory_.asString(); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Project), newProjectFolder); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Mesh), newProjectFolder / meshSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Script), newProjectFolder / scriptSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Interface), newProjectFolder / interfaceSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Image), newProjectFolder / imageSubdirectory); - ASSERT_EQ(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Shader), newProjectFolder / shaderSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Project), newProjectFolder); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Mesh), newProjectFolder / meshSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Script), newProjectFolder / scriptSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Interface), newProjectFolder / interfaceSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Image), newProjectFolder / imageSubdirectory); + ASSERT_EQ(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Shader), newProjectFolder / shaderSubdirectory); } TEST_F(RaCoProjectFixture, loadingBrokenJSONFileThrowsException) { auto jsonPath = (test_path() / "brokenJSON.rca").string(); - raco::utils::file::write(jsonPath, R"( + utils::file::write(jsonPath, R"( { "externalProjects": { }, @@ -761,15 +761,15 @@ TEST_F(RaCoProjectFixture, loadingBrokenJSONFileThrowsException) { TEST_F(RaCoProjectFixture, saveLoadAsZip) { { auto linkedScene = raco::createLinkedScene(*application.activeRaCoProject().commandInterface(), test_path()); - auto lua = std::get(linkedScene); - const auto nodeRotEuler{application.activeRaCoProject().commandInterface()->createObject(raco::user_types::Node::typeDescription.typeName, "node_eul")}; - const auto nodeRotQuat{application.activeRaCoProject().commandInterface()->createObject(raco::user_types::Node::typeDescription.typeName, "node_quat")}; + auto lua = std::get(linkedScene); + const auto nodeRotEuler{application.activeRaCoProject().commandInterface()->createObject(user_types::Node::typeDescription.typeName, "node_eul")}; + const auto nodeRotQuat{application.activeRaCoProject().commandInterface()->createObject(user_types::Node::typeDescription.typeName, "node_quat")}; application.activeRaCoProject().commandInterface()->addLink({lua, {"outputs", "translation"}}, {nodeRotEuler, {"translation"}}); application.activeRaCoProject().commandInterface()->addLink({lua, {"outputs", "translation"}}, {nodeRotQuat, {"translation"}}); application.activeRaCoProject().commandInterface()->addLink({lua, {"outputs", "rotation3"}}, {nodeRotEuler, {"rotation"}}); application.activeRaCoProject().commandInterface()->addLink({lua, {"outputs", "rotation4"}}, {nodeRotQuat, {"rotation"}}); - application.activeRaCoProject().commandInterface()->set({application.activeRaCoProject().project()->settings(), &raco::user_types::ProjectSettings::saveAsZip_}, true); + application.activeRaCoProject().commandInterface()->set({application.activeRaCoProject().project()->settings(), &user_types::ProjectSettings::saveAsZip_}, true); std::string msg; application.activeRaCoProject().saveAs((test_path() / "project.rca").string().c_str(), msg); @@ -784,9 +784,9 @@ TEST_F(RaCoProjectFixture, saveLoadAsZip) { TEST_F(RaCoProjectFixture, saveLoadRotationLinksGetReinstated) { { auto linkedScene = raco::createLinkedScene(*application.activeRaCoProject().commandInterface(), test_path()); - auto lua = std::get(linkedScene); - const auto nodeRotEuler{application.activeRaCoProject().commandInterface()->createObject(raco::user_types::Node::typeDescription.typeName, "node_eul")}; - const auto nodeRotQuat{application.activeRaCoProject().commandInterface()->createObject(raco::user_types::Node::typeDescription.typeName, "node_quat")}; + auto lua = std::get(linkedScene); + const auto nodeRotEuler{application.activeRaCoProject().commandInterface()->createObject(user_types::Node::typeDescription.typeName, "node_eul")}; + const auto nodeRotQuat{application.activeRaCoProject().commandInterface()->createObject(user_types::Node::typeDescription.typeName, "node_quat")}; application.activeRaCoProject().commandInterface()->addLink({lua, {"outputs", "translation"}}, {nodeRotEuler, {"translation"}}); application.activeRaCoProject().commandInterface()->addLink({lua, {"outputs", "translation"}}, {nodeRotQuat, {"translation"}}); @@ -805,9 +805,9 @@ TEST_F(RaCoProjectFixture, saveLoadRotationLinksGetReinstated) { TEST_F(RaCoProjectFixture, saveLoadRotationInvalidLinksGetReinstated) { { auto linkedScene = raco::createLinkedScene(*application.activeRaCoProject().commandInterface(), test_path()); - auto lua = std::get(linkedScene); - const auto nodeRotEuler{application.activeRaCoProject().commandInterface()->createObject(raco::user_types::Node::typeDescription.typeName, "node_eul")}; - const auto nodeRotQuat{application.activeRaCoProject().commandInterface()->createObject(raco::user_types::Node::typeDescription.typeName, "node_quat")}; + auto lua = std::get(linkedScene); + const auto nodeRotEuler{application.activeRaCoProject().commandInterface()->createObject(user_types::Node::typeDescription.typeName, "node_eul")}; + const auto nodeRotQuat{application.activeRaCoProject().commandInterface()->createObject(user_types::Node::typeDescription.typeName, "node_quat")}; application.activeRaCoProject().commandInterface()->addLink({lua, {"outputs", "translation"}}, {nodeRotEuler, {"translation"}}); application.activeRaCoProject().commandInterface()->addLink({lua, {"outputs", "translation"}}, {nodeRotQuat, {"translation"}}); @@ -834,9 +834,9 @@ TEST_F(RaCoProjectFixture, saveLoadRotationInvalidLinksGetReinstated) { TEST_F(RaCoProjectFixture, saveLoadRotationInvalidLinksGetReinstatedWithDifferentTypes) { { auto linkedScene = raco::createLinkedScene(*application.activeRaCoProject().commandInterface(), test_path()); - auto lua = std::get(linkedScene); - const auto nodeRotEuler{application.activeRaCoProject().commandInterface()->createObject(raco::user_types::Node::typeDescription.typeName, "node_eul")}; - const auto nodeRotQuat{application.activeRaCoProject().commandInterface()->createObject(raco::user_types::Node::typeDescription.typeName, "node_quat")}; + auto lua = std::get(linkedScene); + const auto nodeRotEuler{application.activeRaCoProject().commandInterface()->createObject(user_types::Node::typeDescription.typeName, "node_eul")}; + const auto nodeRotQuat{application.activeRaCoProject().commandInterface()->createObject(user_types::Node::typeDescription.typeName, "node_quat")}; application.activeRaCoProject().commandInterface()->addLink({lua, {"outputs", "translation"}}, {nodeRotEuler, {"translation"}}); application.activeRaCoProject().commandInterface()->addLink({lua, {"outputs", "translation"}}, {nodeRotQuat, {"translation"}}); @@ -854,7 +854,7 @@ TEST_F(RaCoProjectFixture, saveLoadRotationInvalidLinksGetReinstatedWithDifferen application.switchActiveRaCoProject(QString::fromStdString((test_path() / "project.rca").string()), {}); application.doOneLoop(); - auto lua = raco::core::Queries::findByName(application.activeRaCoProject().project()->instances(), "lua_script"); + auto lua = core::Queries::findByName(application.activeRaCoProject().project()->instances(), "lua_script"); auto switchedRotationTypes = makeFile("switchedTypes.lua", R"( function interface(IN,OUT) OUT.translation = Type:Vec3f() @@ -880,7 +880,7 @@ TEST_F(RaCoProjectFixture, copyPasteShallowAnimationReferencingAnimationChannel) application.activeRaCoProject().commandInterface()->insertAssetScenegraph(scenegraph, path, nullptr); application.doOneLoop(); - auto anim = raco::core::Queries::findByName(application.activeRaCoProject().project()->instances(), "Step Scale"); + auto anim = core::Queries::findByName(application.activeRaCoProject().project()->instances(), "Step Scale"); ASSERT_NE(anim, nullptr); clipboard = application.activeRaCoProject().commandInterface()->copyObjects({anim}); } @@ -899,7 +899,7 @@ TEST_F(RaCoProjectFixture, copyPasteDeepAnimationReferencingAnimationChannel) { application.activeRaCoProject().commandInterface()->insertAssetScenegraph(scenegraph, path, nullptr); application.doOneLoop(); - auto anim = raco::core::Queries::findByName(application.activeRaCoProject().project()->instances(), "Step Scale"); + auto anim = core::Queries::findByName(application.activeRaCoProject().project()->instances(), "Step Scale"); ASSERT_NE(anim, nullptr); clipboard = application.activeRaCoProject().commandInterface()->copyObjects({anim}, true); } @@ -913,14 +913,14 @@ TEST_F(RaCoProjectFixture, copyPasteShallowLuaScriptReferencingLuaScriptModule) std::string clipboard; { application.activeRaCoProject().project()->setCurrentPath((test_path() / "project.rca").string()); - auto module = application.activeRaCoProject().commandInterface()->createObject(raco::user_types::LuaScriptModule::typeDescription.typeName, "m"); - auto script = application.activeRaCoProject().commandInterface()->createObject(raco::user_types::LuaScript::typeDescription.typeName, "s"); + auto module = application.activeRaCoProject().commandInterface()->createObject(user_types::LuaScriptModule::typeDescription.typeName, "m"); + auto script = application.activeRaCoProject().commandInterface()->createObject(user_types::LuaScript::typeDescription.typeName, "s"); application.doOneLoop(); - application.activeRaCoProject().commandInterface()->set({module, &raco::user_types::LuaScriptModule::uri_}, test_path().append("scripts/moduleDefinition.lua").string()); + application.activeRaCoProject().commandInterface()->set({module, &user_types::LuaScriptModule::uri_}, test_path().append("scripts/moduleDefinition.lua").string()); application.doOneLoop(); - application.activeRaCoProject().commandInterface()->set({script, &raco::user_types::LuaScript::uri_}, test_path().append("scripts/moduleDependency.lua").string()); + application.activeRaCoProject().commandInterface()->set({script, &user_types::LuaScript::uri_}, test_path().append("scripts/moduleDependency.lua").string()); application.doOneLoop(); application.activeRaCoProject().commandInterface()->set({script, {"luaModules", "coalas"}}, module); @@ -938,14 +938,14 @@ TEST_F(RaCoProjectFixture, copyPasteDeepLuaScriptReferencingLuaScriptModule) { std::string clipboard; { application.activeRaCoProject().project()->setCurrentPath((test_path() / "project.rca").string()); - auto module = application.activeRaCoProject().commandInterface()->createObject(raco::user_types::LuaScriptModule::typeDescription.typeName, "m"); - auto script = application.activeRaCoProject().commandInterface()->createObject(raco::user_types::LuaScript::typeDescription.typeName, "s"); + auto module = application.activeRaCoProject().commandInterface()->createObject(user_types::LuaScriptModule::typeDescription.typeName, "m"); + auto script = application.activeRaCoProject().commandInterface()->createObject(user_types::LuaScript::typeDescription.typeName, "s"); application.doOneLoop(); - application.activeRaCoProject().commandInterface()->set({module, &raco::user_types::LuaScriptModule::uri_}, test_path().append("scripts/moduleDefinition.lua").string()); + application.activeRaCoProject().commandInterface()->set({module, &user_types::LuaScriptModule::uri_}, test_path().append("scripts/moduleDefinition.lua").string()); application.doOneLoop(); - application.activeRaCoProject().commandInterface()->set({script, &raco::user_types::LuaScript::uri_}, test_path().append("scripts/moduleDependency.lua").string()); + application.activeRaCoProject().commandInterface()->set({script, &user_types::LuaScript::uri_}, test_path().append("scripts/moduleDependency.lua").string()); application.doOneLoop(); application.activeRaCoProject().commandInterface()->set({script, {"luaModules", "coalas"}}, module); @@ -1013,13 +1013,13 @@ TEST_F(RaCoProjectFixture, loadDoubleModuleReferenceWithoutError) { std::vector msgs_; }; spdlog::drop_all(); - raco::log_system::init(); + log_system::init(); const auto logsink = std::make_shared(); - raco::log_system::registerSink(logsink); + log_system::registerSink(logsink); application.switchActiveRaCoProject(QString::fromStdString((test_path() / "loadDoubleModuleReferenceWithoutError.rca").string()), {}); ASSERT_TRUE(application.activeRaCoProject().project() != nullptr); ASSERT_FALSE(logsink->containsError()); - raco::log_system::unregisterSink(logsink); + log_system::unregisterSink(logsink); } TEST_F(RaCoProjectFixture, saveLoadScenegraphOrder) { @@ -1042,7 +1042,7 @@ TEST_F(RaCoProjectFixture, saveLoadScenegraphOrder) { EXPECT_EQ(rootNodeNames(), std::vector({"project", "node1", "node2"})); - auto node2 = raco::core::Queries::findByName(project().instances(), "node2"); + auto node2 = core::Queries::findByName(project().instances(), "node2"); commandInterface().moveScenegraphChildren({node2}, {}, 0); EXPECT_EQ(rootNodeNames(), std::vector({"node2", "project", "node1"})); ASSERT_TRUE(application.activeRaCoProject().saveAs((test_path() / "project2.rca").string().c_str(), msg)); diff --git a/components/libComponents/include/components/DataChangeDispatcher.h b/components/libComponents/include/components/DataChangeDispatcher.h index 9ed766e3..1feb9413 100644 --- a/components/libComponents/include/components/DataChangeDispatcher.h +++ b/components/libComponents/include/components/DataChangeDispatcher.h @@ -129,8 +129,8 @@ class DataChangeDispatcher { // This will regisiter a callback which is invoked by dispatch() after all other changes have been dispatched. Subscription registerOnAfterDispatch(Callback callback); - void registerBulkChangeCallback(BulkChangeCallback callback); - void resetBulkChangeCallback(); + void addBulkChangeCallback(uint64_t ID, BulkChangeCallback callback); + void removeBulkChangeCallback(uint64_t ID); void dispatch(const core::DataChangeRecorder& dataChanges); @@ -179,7 +179,7 @@ class DataChangeDispatcher { std::set, std::owner_less>> onAfterDispatchListeners_{}; - BulkChangeCallback bulkChangeCallback_; + std::map bulkChangeCallbacks_; }; using SDataChangeDispatcher = std::shared_ptr; diff --git a/components/libComponents/include/components/FileChangeListenerImpl.h b/components/libComponents/include/components/FileChangeListenerImpl.h index eca632ba..a134e3fb 100644 --- a/components/libComponents/include/components/FileChangeListenerImpl.h +++ b/components/libComponents/include/components/FileChangeListenerImpl.h @@ -57,7 +57,7 @@ class FileChangeListenerImpl { Node rootNode_; - std::map watchedFiles_; + std::map watchedFiles_; Callback fileChangeCallback_; @@ -71,18 +71,18 @@ class FileChangeListenerImpl { QMetaObject::Connection delayedLoadTimerConnection_; void addPathToWatch(const QString &path); - void installFileWatch(const raco::utils::u8path &path); + void installFileWatch(const utils::u8path &path); void launchDelayedLoad(const utils::u8path &path); void onFileChanged(const QString &filePath); void onDelayedLoad(); void onDirectoryChanged(const QString &dirPath); - Node *createDirectoryWatches(const raco::utils::u8path &path); + Node *createDirectoryWatches(const utils::u8path &path); void removeDirectoryWatches(Node* node); - Node *getNode(const raco::utils::u8path &path); + Node *getNode(const utils::u8path &path); void updateDirectoryWatches(Node *node); - static bool fileCanBeAccessed(const raco::utils::u8path &path); + static bool fileCanBeAccessed(const utils::u8path &path); }; } // namespace raco::components diff --git a/components/libComponents/include/components/FileChangeMonitorImpl.h b/components/libComponents/include/components/FileChangeMonitorImpl.h index 34b95599..cf1ccb83 100644 --- a/components/libComponents/include/components/FileChangeMonitorImpl.h +++ b/components/libComponents/include/components/FileChangeMonitorImpl.h @@ -66,7 +66,7 @@ class GenericFileChangeMonitorImpl : public Base { std::unordered_map> callbacks_; }; -class ProjectFileChangeMonitor : public GenericFileChangeMonitorImpl>> { +class ProjectFileChangeMonitor : public GenericFileChangeMonitorImpl>> { public: ProjectFileChangeMonitor() : GenericFileChangeMonitorImpl() {} diff --git a/components/libComponents/include/components/MeshCacheImpl.h b/components/libComponents/include/components/MeshCacheImpl.h index 8d81e65a..2b7a2b20 100644 --- a/components/libComponents/include/components/MeshCacheImpl.h +++ b/components/libComponents/include/components/MeshCacheImpl.h @@ -27,12 +27,12 @@ class MeshCacheImpl : public GenericFileChangeMonitorImpl { public: MeshCacheImpl() {} - core::SharedMeshData loadMesh(const raco::core::MeshDescriptor& descriptor) override; + core::SharedMeshData loadMesh(const core::MeshDescriptor& descriptor) override; const core::MeshScenegraph* getMeshScenegraph(const std::string& absPath) override; std::string getMeshError(const std::string& absPath) override; int getTotalMeshCount(const std::string& absPath) override; - raco::core::SharedAnimationSamplerData getAnimationSamplerData(const std::string& absPath, int animIndex, int samplerIndex) override; + core::SharedAnimationSamplerData getAnimationSamplerData(const std::string& absPath, int animIndex, int samplerIndex) override; core::SharedSkinData loadSkin(const std::string& absPath, int skinIndex, std::string& outError) override; diff --git a/components/libComponents/include/components/RaCoNameConstants.h b/components/libComponents/include/components/RaCoNameConstants.h index 362c4960..daa48876 100644 --- a/components/libComponents/include/components/RaCoNameConstants.h +++ b/components/libComponents/include/components/RaCoNameConstants.h @@ -13,6 +13,5 @@ namespace raco::names { constexpr const char* PROJECT_FILE_EXTENSION{"rca"}; constexpr const char* FILE_EXTENSION_RAMSES_EXPORT{"ramses"}; -constexpr const char* FILE_EXTENSION_LOGIC_EXPORT{"rlogic"}; } // namespace raco::names \ No newline at end of file diff --git a/components/libComponents/include/components/RaCoPreferences.h b/components/libComponents/include/components/RaCoPreferences.h index 492622ca..144b37a3 100644 --- a/components/libComponents/include/components/RaCoPreferences.h +++ b/components/libComponents/include/components/RaCoPreferences.h @@ -39,6 +39,8 @@ class RaCoPreferences final : public QObject { QString shaderSubdirectory; QString screenshotDirectory; + // The feature level in the settings is not capped to the maximum allowed feature level. + // Capping is done on application startup and in the PreferencesView instead. int featureLevel; bool isUriValidationCaseSensitive; bool preventAccidentalUpgrade; diff --git a/components/libComponents/include/components/TracePlayer.h b/components/libComponents/include/components/TracePlayer.h index 99c50058..15ed3135 100644 --- a/components/libComponents/include/components/TracePlayer.h +++ b/components/libComponents/include/components/TracePlayer.h @@ -85,14 +85,14 @@ class TracePlayer { core::DataChangeRecorder& uiChanges() const; private: - raco::core::SEditorObject findLua(const std::string& luaObjName, bool logErrors = true); + core::SEditorObject findLua(const std::string& luaObjName, bool logErrors = true); QJsonObject parseFrame(int frameIndex); QJsonObject parseSceneData(const QJsonObject& qjFrame, int frameIndex = -1); QJsonObject parseTracePlayerData(const QJsonObject& qjFrame, int frameIndex = -1); int parseTimestamp(const QJsonObject& qjTracePlayerData, int frameIndex = -1); bool parseFrameAndUpdateLua(); - void updateLua(const QJsonValue& jsonChild, std::vector& keysChain, const raco::core::SEditorObject& lua); - void updateLuaProperty(const raco::core::SEditorObject& lua, const std::vector& keysChain, const QJsonValue& jsonChild, bool logErrors = true); + void updateLua(const QJsonValue& jsonChild, std::vector& keysChain, const core::SEditorObject& lua); + void updateLuaProperty(const core::SEditorObject& lua, const std::vector& keysChain, const QJsonValue& jsonChild, bool logErrors = true); std::string streamKeysChain(const std::vector& keysChain) const; void qjParseErrMsg(const QJsonParseError& qjParseError, const std::string& fileName); void clearError(const std::string& msg, core::ErrorLevel level); @@ -106,7 +106,7 @@ class TracePlayer { void makeFramesConsistent(); QJsonValue deepAddMissingProperties(const QJsonValue& qjPrev, const QJsonValue& qjCurr, std::vector& propertyPath, int index); QJsonValue buildFullFrameFromLua(std::unordered_set const& sceneLuaList); - QJsonValue deepCopyFromLua(raco::core::ValueHandle const& luaValHandle); + QJsonValue deepCopyFromLua(core::ValueHandle const& luaValHandle); void rebuildFrameSceneData(int index, const QJsonValue& qjPrev, const QJsonValue& qjCurr); void readLinesForNextFrame(); int getPropertyLineNumber(const QString& propertyKey); diff --git a/components/libComponents/src/DataChangeDispatcher.cpp b/components/libComponents/src/DataChangeDispatcher.cpp index 166444cf..3a7e6938 100644 --- a/components/libComponents/src/DataChangeDispatcher.cpp +++ b/components/libComponents/src/DataChangeDispatcher.cpp @@ -416,12 +416,12 @@ Subscription DataChangeDispatcher::registerOnAfterDispatch(Callback callback) { }}; } -void DataChangeDispatcher::registerBulkChangeCallback(BulkChangeCallback callback) { - bulkChangeCallback_ = callback; +void DataChangeDispatcher::addBulkChangeCallback(uint64_t id, BulkChangeCallback callback) { + bulkChangeCallbacks_[id] = callback; } -void DataChangeDispatcher::resetBulkChangeCallback() { - bulkChangeCallback_ = nullptr; +void DataChangeDispatcher::removeBulkChangeCallback(uint64_t id) { + bulkChangeCallbacks_.erase(id); } void DataChangeDispatcher::emitUpdateFor(const std::map>& valueHandles) const { @@ -536,6 +536,7 @@ void DataChangeDispatcher::assertEmpty() { assert(externalProjectMapChangedListeners_.empty()); assert(rootOrderChangedListeners_.empty()); assert(onAfterDispatchListeners_.empty()); + assert(bulkChangeCallbacks_.empty()); } void DataChangeDispatcher::emitDeleted(SEditorObject obj) const { @@ -561,8 +562,8 @@ void DataChangeDispatcher::emitPreviewDirty(SEditorObject obj) const { } void DataChangeDispatcher::emitBulkChange(const SEditorObjectSet& changedObjects) const { - if (bulkChangeCallback_) { - bulkChangeCallback_(changedObjects); + for (const auto& [id, callback] : bulkChangeCallbacks_) { + callback(changedObjects); } } diff --git a/components/libComponents/src/FileChangeListenerImpl.cpp b/components/libComponents/src/FileChangeListenerImpl.cpp index d68e393a..a39448c2 100644 --- a/components/libComponents/src/FileChangeListenerImpl.cpp +++ b/components/libComponents/src/FileChangeListenerImpl.cpp @@ -49,7 +49,7 @@ void FileChangeListenerImpl::addPathToWatch(const QString& path) { } } -void FileChangeListenerImpl::installFileWatch(const raco::utils::u8path& path) { +void FileChangeListenerImpl::installFileWatch(const utils::u8path& path) { if (path.exists()) { auto pathQtString = QString::fromStdString(path.string()); auto fileWatcherContainsFilePath = fileWatcher_.files().contains(pathQtString); @@ -61,7 +61,7 @@ void FileChangeListenerImpl::installFileWatch(const raco::utils::u8path& path) { } void FileChangeListenerImpl::add(const std::string& absPath) { - const raco::utils::u8path& path(absPath); + const utils::u8path& path(absPath); // create directoriy watchers up to root -> return direct parent directory auto directoryNode = createDirectoryWatches(path.parent_path()); @@ -72,7 +72,7 @@ void FileChangeListenerImpl::add(const std::string& absPath) { watchedFiles_[path] = it->second.get(); } -FileChangeListenerImpl::Node* FileChangeListenerImpl::createDirectoryWatches(const raco::utils::u8path& path) { +FileChangeListenerImpl::Node* FileChangeListenerImpl::createDirectoryWatches(const utils::u8path& path) { if (path != path.root_path()) { auto node = createDirectoryWatches(path.parent_path()); @@ -91,7 +91,7 @@ FileChangeListenerImpl::Node* FileChangeListenerImpl::createDirectoryWatches(con return &rootNode_; } -FileChangeListenerImpl::Node* FileChangeListenerImpl::getNode(const raco::utils::u8path& path) { +FileChangeListenerImpl::Node* FileChangeListenerImpl::getNode(const utils::u8path& path) { if (path != path.root_path()) { auto node = getNode(path.parent_path()); @@ -113,7 +113,7 @@ void FileChangeListenerImpl::updateDirectoryWatches(Node* node) { } void FileChangeListenerImpl::remove(const std::string& absPath) { - const raco::utils::u8path& path(absPath); + const utils::u8path& path(absPath); if (fileWatcher_.removePath(QString::fromStdString(path.string()))) { // remove file node and all parent directories which have no child nodes anymore @@ -181,7 +181,7 @@ void FileChangeListenerImpl::onDirectoryChanged(const QString& dirPathString) { } } -bool FileChangeListenerImpl::fileCanBeAccessed(const raco::utils::u8path& path) { +bool FileChangeListenerImpl::fileCanBeAccessed(const utils::u8path& path) { #if (defined(OS_WINDOWS)) auto fileHandle = CreateFileW(path.wstring().c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); diff --git a/components/libComponents/src/MeshCacheImpl.cpp b/components/libComponents/src/MeshCacheImpl.cpp index 8174d068..cc6a4f47 100644 --- a/components/libComponents/src/MeshCacheImpl.cpp +++ b/components/libComponents/src/MeshCacheImpl.cpp @@ -50,31 +50,31 @@ void MeshCacheImpl::notify(const std::string& absPath) { } } -raco::core::SharedMeshData MeshCacheImpl::loadMesh(const raco::core::MeshDescriptor &descriptor) { +core::SharedMeshData MeshCacheImpl::loadMesh(const core::MeshDescriptor &descriptor) { auto *loader = getLoader(descriptor.absPath); assert(loader != nullptr); return loader->loadMesh(descriptor); } -const raco::core::MeshScenegraph *raco::components::MeshCacheImpl::getMeshScenegraph(const std::string &absPath) { +const core::MeshScenegraph *components::MeshCacheImpl::getMeshScenegraph(const std::string &absPath) { auto *loader = getLoader(absPath); assert(loader != nullptr); return loader->getScenegraph(absPath); } -std::string raco::components::MeshCacheImpl::getMeshError(const std::string &absPath) { +std::string components::MeshCacheImpl::getMeshError(const std::string &absPath) { auto *loader = getLoader(absPath); assert(loader != nullptr); return loader->getError(); } -int raco::components::MeshCacheImpl::getTotalMeshCount(const std::string &absPath) { +int components::MeshCacheImpl::getTotalMeshCount(const std::string &absPath) { auto *loader = getLoader(absPath); assert(loader != nullptr); return loader->getTotalMeshCount(); } -raco::core::SharedAnimationSamplerData MeshCacheImpl::getAnimationSamplerData(const std::string &absPath, int animIndex, int samplerIndex) { +core::SharedAnimationSamplerData MeshCacheImpl::getAnimationSamplerData(const std::string &absPath, int animIndex, int samplerIndex) { auto *loader = getLoader(absPath); assert(loader != nullptr); return loader->getAnimationSamplerData(absPath, animIndex, samplerIndex); @@ -100,7 +100,7 @@ bool endsWith(std::string const &text, std::string const &ending) { return 0 == text.compare(startPos, ending.length(), ending); } -raco::core::MeshCacheEntry *MeshCacheImpl::getLoader(std::string absPath) { +core::MeshCacheEntry *MeshCacheImpl::getLoader(std::string absPath) { bool isGltfMesh = endsWith(absPath, ".gltf") || endsWith(absPath, ".glb"); bool isCTMMesh = endsWith(absPath, ".ctm"); if (isGltfMesh || isCTMMesh) { @@ -112,9 +112,9 @@ raco::core::MeshCacheEntry *MeshCacheImpl::getLoader(std::string absPath) { assert(callbacks_.find(absPath) != callbacks_.end()); if (meshCacheEntries_.count(absPath) == 0) { if (isGltfMesh) { - meshCacheEntries_[absPath] = std::unique_ptr(new mesh_loader::glTFFileLoader(absPath)); + meshCacheEntries_[absPath] = std::unique_ptr(new mesh_loader::glTFFileLoader(absPath)); } else if (isCTMMesh) { - meshCacheEntries_[absPath] = std::unique_ptr(new mesh_loader::CTMFileLoader(absPath)); + meshCacheEntries_[absPath] = std::unique_ptr(new mesh_loader::CTMFileLoader(absPath)); } } return meshCacheEntries_[absPath].get(); diff --git a/components/libComponents/src/RaCoPreferences.cpp b/components/libComponents/src/RaCoPreferences.cpp index da714da8..07c5a093 100644 --- a/components/libComponents/src/RaCoPreferences.cpp +++ b/components/libComponents/src/RaCoPreferences.cpp @@ -25,7 +25,7 @@ void RaCoPreferences::init() noexcept { } bool RaCoPreferences::save() { - auto settings = raco::core::PathManager::preferenceSettings(); + auto settings = core::PathManager::preferenceSettings(); settings.setValue("userProjectsDirectory", userProjectsDirectory); settings.setValue("imageSubdirectory", imageSubdirectory); @@ -44,12 +44,12 @@ bool RaCoPreferences::save() { } void RaCoPreferences::load() { - auto settings = raco::core::PathManager::preferenceSettings(); + auto settings = core::PathManager::preferenceSettings(); std::string dir = settings.value("userProjectsDirectory", "").toString().toStdString(); - if (raco::utils::u8path(dir).existsDirectory()) { + if (utils::u8path(dir).existsDirectory()) { userProjectsDirectory = QString::fromStdString(dir); } else { - userProjectsDirectory = QString::fromStdString(raco::core::PathManager::defaultProjectFallbackPath().string()); + userProjectsDirectory = QString::fromStdString(core::PathManager::defaultProjectFallbackPath().string()); } imageSubdirectory = settings.value("imageSubdirectory", "images").toString(); diff --git a/components/libComponents/src/TracePlayer.cpp b/components/libComponents/src/TracePlayer.cpp index d8f9a434..719a02f4 100644 --- a/components/libComponents/src/TracePlayer.cpp +++ b/components/libComponents/src/TracePlayer.cpp @@ -370,7 +370,7 @@ int TracePlayer::getPropertyLineNumber(const QString& propertyKey) { return propertyLine; } -QJsonValue TracePlayer::deepCopyFromLua(raco::core::ValueHandle const& luaValHandle) { +QJsonValue TracePlayer::deepCopyFromLua(core::ValueHandle const& luaValHandle) { switch (luaValHandle.type()) { case data_storage::PrimitiveType::Struct: case data_storage::PrimitiveType::Table: { @@ -592,9 +592,9 @@ int TracePlayer::parseTimestamp(const QJsonObject& qjTracePlayerData, int frameI core::SEditorObject TracePlayer::findLua(const std::string& luaObjName, bool logErrors) { /// find matching LuaScript or LuaInterface - const auto isControllableLua{[&luaObjName](const raco::core::SEditorObject& o) { + const auto isControllableLua{[&luaObjName](const core::SEditorObject& o) { return ( - ((o->objectName() == luaObjName) && (!raco::core::PrefabOperations::findContainingPrefab(o))) && + ((o->objectName() == luaObjName) && (!core::PrefabOperations::findContainingPrefab(o))) && ((o->isType()) || (o->isType() && (!core::PrefabOperations::findContainingPrefabInstance(o))))); }}; @@ -692,7 +692,7 @@ std::string TracePlayer::streamKeysChain(const std::vector& keysCha void TracePlayer::updateLuaProperty(const core::SEditorObject& lua, const std::vector& keysChain, const QJsonValue& jsonChild, bool logErrors) { const std::string keysStream{lua->objectName() + "->" + streamKeysChain(keysChain)}; - if (auto const valHandle{raco::core::ValueHandle{lua, keysChain}}) { + if (auto const valHandle{core::ValueHandle{lua, keysChain}}) { clearError("Property was not found! ( propPath: " + keysStream + " )", core::ErrorLevel::WARNING); if (core::Queries::linkState(racoCoreInterface_->project(), valHandle).current != core::Queries::CurrentLinkState::NOT_LINKED) { @@ -705,7 +705,7 @@ void TracePlayer::updateLuaProperty(const core::SEditorObject& lua, const std::v switch (jsonChild.type()) { case QJsonValue::Bool: { - if (valHandle.type() != raco::data_storage::PrimitiveType::Bool) { + if (valHandle.type() != data_storage::PrimitiveType::Bool) { if (logErrors) { addError("Property type mismatch >> Expected a Bool! ( propPath: " + keysStream + " )", core::ErrorLevel::WARNING); } @@ -716,9 +716,9 @@ void TracePlayer::updateLuaProperty(const core::SEditorObject& lua, const std::v break; } case QJsonValue::Double: { - if (valHandle.type() == raco::data_storage::PrimitiveType::Int) { + if (valHandle.type() == data_storage::PrimitiveType::Int) { racoCoreInterface_->setCodeControlledValueHandle(valHandle, static_cast(jsonChild.toDouble())); - } else if (valHandle.type() == raco::data_storage::PrimitiveType::Double) { + } else if (valHandle.type() == data_storage::PrimitiveType::Double) { racoCoreInterface_->setCodeControlledValueHandle(valHandle, jsonChild.toDouble()); } else { if (logErrors) { @@ -730,7 +730,7 @@ void TracePlayer::updateLuaProperty(const core::SEditorObject& lua, const std::v break; } case QJsonValue::String: { - if (valHandle.type() != raco::data_storage::PrimitiveType::String) { + if (valHandle.type() != data_storage::PrimitiveType::String) { if (logErrors) { addError("Property type mismatch >> Expected a String! ( propPath: " + keysStream + " )", core::ErrorLevel::WARNING); } @@ -760,13 +760,13 @@ void TracePlayer::addError(const std::string& msg, core::ErrorLevel level, bool switch (level) { case core::ErrorLevel::ERROR: - LOG_ERROR(raco::log_system::TRACE_PLAYER, msg); + LOG_ERROR(log_system::TRACE_PLAYER, msg); break; case core::ErrorLevel::WARNING: - LOG_WARNING(raco::log_system::TRACE_PLAYER, msg); + LOG_WARNING(log_system::TRACE_PLAYER, msg); break; case core::ErrorLevel::INFORMATION: - LOG_INFO(raco::log_system::TRACE_PLAYER, msg); + LOG_INFO(log_system::TRACE_PLAYER, msg); break; default: break; diff --git a/components/libComponents/tests/DataChangeDispatcher_test.cpp b/components/libComponents/tests/DataChangeDispatcher_test.cpp index 279ded1c..f89f4c0d 100644 --- a/components/libComponents/tests/DataChangeDispatcher_test.cpp +++ b/components/libComponents/tests/DataChangeDispatcher_test.cpp @@ -165,8 +165,8 @@ class LifeCycleListenertest : public DataChangeDispatcherTest { SEditorObject node_start; SEditorObject node_end; - testing::MockFunction creationCallback{}; - testing::MockFunction deletionCallback{}; + testing::MockFunction creationCallback{}; + testing::MockFunction deletionCallback{}; }; TEST_F(LifeCycleListenertest, generic) { diff --git a/components/libComponents/tests/FileChangeMonitor_test.cpp b/components/libComponents/tests/FileChangeMonitor_test.cpp index e5f60d24..dfb20de2 100644 --- a/components/libComponents/tests/FileChangeMonitor_test.cpp +++ b/components/libComponents/tests/FileChangeMonitor_test.cpp @@ -36,7 +36,7 @@ class BasicFileChangeMonitorTest : public TestEnvironmentCore { // Wait for the timer to queue its event, and then process the timer event, which eventually // leads to the callbacks registered with FileMonitor::registerFileChangedHandler to be called. - std::this_thread::sleep_for(std::chrono::milliseconds(raco::components::FileChangeListenerImpl::DELAYED_FILE_LOAD_TIME_MSEC + 100)); + std::this_thread::sleep_for(std::chrono::milliseconds(components::FileChangeListenerImpl::DELAYED_FILE_LOAD_TIME_MSEC + 100)); QCoreApplication::processEvents(); } while (fileChangeCounter_ < count && std::chrono::duration_cast(std::chrono::steady_clock::now() - start).count() <= timeOutInMS); @@ -51,8 +51,8 @@ class BasicFileChangeMonitorTest : public TestEnvironmentCore { int fileChangeCounter_{0}; std::function testCallback_ = [this]() { ++fileChangeCounter_; }; - std::unique_ptr testFileChangeMonitor_ = std::make_unique(); - std::vector createdFileListeners_; + std::unique_ptr testFileChangeMonitor_ = std::make_unique(); + std::vector createdFileListeners_; }; class FileChangeMonitorTest : public BasicFileChangeMonitorTest { @@ -64,7 +64,7 @@ class FileChangeMonitorTest : public BasicFileChangeMonitorTest { TestEnvironmentCore::SetUp(); std::filesystem::create_directory(testFolderPath_); - raco::utils::file::write(testFilePath_, {}); + utils::file::write(testFilePath_, {}); createdFileListeners_.emplace_back(testFileChangeMonitor_->registerFileChangedHandler(testFilePath_.string(), testCallback_)); } @@ -82,7 +82,7 @@ class FileChangeMonitorTest : public BasicFileChangeMonitorTest { TestEnvironmentCore::TearDown(); } - void runRenamingRoutine(raco::utils::u8path& originPath, const char* firstRename, const char* secondRename) { + void runRenamingRoutine(utils::u8path& originPath, const char* firstRename, const char* secondRename) { auto newFilePath = originPath; newFilePath.replace_filename(firstRename); @@ -102,8 +102,8 @@ class FileChangeMonitorTest : public BasicFileChangeMonitorTest { ASSERT_TRUE(waitForFileChangeCounterGEq(3)); } - raco::utils::u8path testFolderPath_{test_path().append(TEST_RESOURCES_FOLDER_NAME)}; - raco::utils::u8path testFilePath_{raco::utils::u8path(testFolderPath_).append(TEST_FILE_NAME)}; + utils::u8path testFolderPath_{test_path().append(TEST_RESOURCES_FOLDER_NAME)}; + utils::u8path testFilePath_{utils::u8path(testFolderPath_).append(TEST_FILE_NAME)}; }; TEST_F(FileChangeMonitorTest, InstantiationNoFileChange) { @@ -111,18 +111,18 @@ TEST_F(FileChangeMonitorTest, InstantiationNoFileChange) { } TEST_F(FileChangeMonitorTest, FileModificationCreation) { - testFilePath_ = raco::utils::u8path(testFolderPath_).append("differentFile.txt"); + testFilePath_ = utils::u8path(testFolderPath_).append("differentFile.txt"); createdFileListeners_.emplace_back(testFileChangeMonitor_->registerFileChangedHandler(testFilePath_.string(), testCallback_)); ASSERT_TRUE(waitForFileChangeCounterGEq(0)); - raco::utils::file::write(testFilePath_, {}); + utils::file::write(testFilePath_, {}); ASSERT_TRUE(waitForFileChangeCounterGEq(1)); } TEST_F(FileChangeMonitorTest, FileModificationEditing) { - raco::utils::file::write(testFilePath_, "Test"); + utils::file::write(testFilePath_, "Test"); ASSERT_TRUE(waitForFileChangeCounterGEq(1)); } @@ -191,7 +191,7 @@ TEST_F(BasicFileChangeMonitorTest, create_file_existing_directory) { createdFileListeners_.emplace_back(testFileChangeMonitor_->registerFileChangedHandler((testFolderPath / test_file_name).string(), testCallback_)); EXPECT_EQ(fileChangeCounter_, 0); - raco::utils::file::write(testFolderPath / test_file_name, {}); + utils::file::write(testFolderPath / test_file_name, {}); ASSERT_TRUE(waitForFileChangeCounterGEq(1)); } @@ -205,7 +205,7 @@ TEST_F(BasicFileChangeMonitorTest, create_file_no_directory) { std::filesystem::create_directory(testFolderPath); ASSERT_TRUE(waitForFileChangeCounterGEq(0)); - raco::utils::file::write(testFolderPath / test_file_name, {}); + utils::file::write(testFolderPath / test_file_name, {}); ASSERT_TRUE(waitForFileChangeCounterGEq(1)); } @@ -224,7 +224,7 @@ TEST_F(BasicFileChangeMonitorTest, directory_rename_appearance) { std::string test_file_name = "test.txt"; std::filesystem::create_directory(initialFolderPath); - raco::utils::file::write(initialFolderPath / test_file_name, {}); + utils::file::write(initialFolderPath / test_file_name, {}); createdFileListeners_.emplace_back(testFileChangeMonitor_->registerFileChangedHandler((testFolderPath / test_file_name).string(), testCallback_)); EXPECT_EQ(fileChangeCounter_, 0); @@ -239,7 +239,7 @@ TEST_F(BasicFileChangeMonitorTest, directory_appear_file_change) { std::string test_file_name = "test.txt"; std::filesystem::create_directory(initialFolderPath); - raco::utils::file::write(initialFolderPath / test_file_name, {}); + utils::file::write(initialFolderPath / test_file_name, {}); createdFileListeners_.emplace_back(testFileChangeMonitor_->registerFileChangedHandler((testFolderPath / test_file_name).string(), testCallback_)); EXPECT_EQ(fileChangeCounter_, 0); @@ -247,7 +247,7 @@ TEST_F(BasicFileChangeMonitorTest, directory_appear_file_change) { std::filesystem::rename(initialFolderPath, testFolderPath); ASSERT_TRUE(waitForFileChangeCounterGEq(1)); - raco::utils::file::write(testFolderPath / test_file_name, "Test"); + utils::file::write(testFolderPath / test_file_name, "Test"); ASSERT_TRUE(waitForFileChangeCounterGEq(2)); } @@ -257,7 +257,7 @@ TEST_F(BasicFileChangeMonitorTest, directory_appear_file_disappear) { std::string test_file_name = "test.txt"; std::filesystem::create_directory(initialFolderPath); - raco::utils::file::write(initialFolderPath / test_file_name, {}); + utils::file::write(initialFolderPath / test_file_name, {}); createdFileListeners_.emplace_back(testFileChangeMonitor_->registerFileChangedHandler((testFolderPath / test_file_name).string(), testCallback_)); EXPECT_EQ(fileChangeCounter_, 0); @@ -276,7 +276,7 @@ TEST_F(BasicFileChangeMonitorTest, directory_appear_file_appear) { std::string test_file_name = "test.txt"; std::filesystem::create_directory(initialFolderPath); - raco::utils::file::write(initialFolderPath / initial_test_file_name, {}); + utils::file::write(initialFolderPath / initial_test_file_name, {}); createdFileListeners_.emplace_back(testFileChangeMonitor_->registerFileChangedHandler((testFolderPath / test_file_name).string(), testCallback_)); EXPECT_EQ(fileChangeCounter_, 0); diff --git a/components/libComponents/tests/TracePlayer_test.cpp b/components/libComponents/tests/TracePlayer_test.cpp index cc42bd92..47ab19de 100644 --- a/components/libComponents/tests/TracePlayer_test.cpp +++ b/components/libComponents/tests/TracePlayer_test.cpp @@ -40,21 +40,21 @@ class TracePlayerTest : public RacoBaseTest<> { void SetUp() override { RacoBaseTest::SetUp(); spdlog::drop_all(); - raco::log_system::init(); - raco::log_system::setConsoleLogLevel(spdlog::level::level_enum::info); + log_system::init(); + log_system::setConsoleLogLevel(spdlog::level::level_enum::info); application.overrideTime([this] { return tracePlayerTestTime_; }); cmd_ = application.activeRaCoProject().commandInterface(); player_ = &application.activeRaCoProject().tracePlayer(); - tracePlayerDataLua_ = createLua("TracePlayerData", LuaType::LuaScript, false)->as(); + tracePlayerDataLua_ = createLua("TracePlayerData", LuaType::LuaScript, false)->as(); createLua("saInfo", LuaType::LuaScript); } - raco::core::CommandInterface* cmd_{nullptr}; + core::CommandInterface* cmd_{nullptr}; TracePlayer* player_{nullptr}; - std::vector luaObjs_; - raco::user_types::SLuaScript tracePlayerDataLua_{nullptr}; + std::vector luaObjs_; + user_types::SLuaScript tracePlayerDataLua_{nullptr}; /// states transition validation void isInit() const; @@ -65,19 +65,19 @@ class TracePlayerTest : public RacoBaseTest<> { /// utilities QJsonArray const* const loadTrace(std::string const& fileName); - raco::core::SEditorObject createLua(std::string const& luaName, const LuaType type, bool sceneScript = true, raco::core::SEditorObject parent = nullptr); - std::unordered_map const* const backupSceneLuaObjs(QJsonArray const* const); - void deleteLuaObj(raco::core::SEditorObject lua); + core::SEditorObject createLua(std::string const& luaName, const LuaType type, bool sceneScript = true, core::SEditorObject parent = nullptr); + std::unordered_map const* const backupSceneLuaObjs(QJsonArray const* const); + void deleteLuaObj(core::SEditorObject lua); void playOneFrame(); void increaseTimeAndDoOneLoop(); void setMinMaxFrameTime(long minFrameTime, long maxFrameTime); /// validations bool isValidRange() const; - bool areLuaObjsRestored(std::unordered_map const* const luaObjsBackup) const; + bool areLuaObjsRestored(std::unordered_map const* const luaObjsBackup) const; bool areAllLuaObjsLocked() const; bool areAllLuaObjsUnlocked() const; - raco::core::SEditorObject findLua(std::string const& luaName) const; + core::SEditorObject findLua(std::string const& luaName) const; long long tracePlayerTestTime_{0}; // we need a reproducable time line to avoid flaky tests. long long lastFrameTime_{-1}; @@ -87,21 +87,21 @@ class TracePlayerTest : public RacoBaseTest<> { int argc{0}; QCoreApplication eventLoop_{argc, nullptr}; - raco::ramses_base::HeadlessEngineBackend backend{raco::ramses_base::BaseEngineBackend::maxFeatureLevel}; + ramses_base::HeadlessEngineBackend backend{}; raco::application::RaCoApplication application{backend, {{}, false, false, -1, -1, false}}; }; /* ************************************** helper functions ************************************** */ -raco::core::SEditorObject TracePlayerTest::createLua(std::string const& luaName, const LuaType type, bool sceneScript, raco::core::SEditorObject parent) { +core::SEditorObject TracePlayerTest::createLua(std::string const& luaName, const LuaType type, bool sceneScript, core::SEditorObject parent) { const auto lua_filename{luaName + ".lua"}; - raco::core::SEditorObject luaObj; + core::SEditorObject luaObj; if (type == LuaType::LuaScript) { - luaObj = cmd_->createObject(raco::user_types::LuaScript::typeDescription.typeName, luaName, parent); + luaObj = cmd_->createObject(user_types::LuaScript::typeDescription.typeName, luaName, parent); } else if (type == LuaType::LuaInterface) { - luaObj = cmd_->createObject(raco::user_types::LuaInterface::typeDescription.typeName, luaName, parent); + luaObj = cmd_->createObject(user_types::LuaInterface::typeDescription.typeName, luaName, parent); } - cmd_->set(raco::core::ValueHandle{luaObj, {"uri"}}, (test_path() / "lua_scripts" / lua_filename).string()); + cmd_->set(core::ValueHandle{luaObj, {"uri"}}, (test_path() / "lua_scripts" / lua_filename).string()); if (sceneScript) { luaObjs_.push_back(luaObj); @@ -110,12 +110,12 @@ raco::core::SEditorObject TracePlayerTest::createLua(std::string const& luaName, return luaObj; } -raco::core::SEditorObject TracePlayerTest::findLua(std::string const& luaObjName) const { - const auto isControllableLua{[&luaObjName](const raco::core::SEditorObject& o) { +core::SEditorObject TracePlayerTest::findLua(std::string const& luaObjName) const { + const auto isControllableLua{[&luaObjName](const core::SEditorObject& o) { return ( - ((o->objectName() == luaObjName) && (!raco::core::PrefabOperations::findContainingPrefab(o))) && - ((o->isType()) || - (o->isType() && (!raco::core::PrefabOperations::findContainingPrefabInstance(o))))); + ((o->objectName() == luaObjName) && (!core::PrefabOperations::findContainingPrefab(o))) && + ((o->isType()) || + (o->isType() && (!core::PrefabOperations::findContainingPrefabInstance(o))))); }}; if (const auto itrLuaObj{std::find_if(cmd_->project()->instances().cbegin(), cmd_->project()->instances().cend(), isControllableLua)}; @@ -126,7 +126,7 @@ raco::core::SEditorObject TracePlayerTest::findLua(std::string const& luaObjName } const auto lua{*itrLuaObj}; - if (raco::user_types::Queries::isReadOnly(lua)) { + if (user_types::Queries::isReadOnly(lua)) { return nullptr; } @@ -136,8 +136,8 @@ raco::core::SEditorObject TracePlayerTest::findLua(std::string const& luaObjName return nullptr; } -void TracePlayerTest::deleteLuaObj(raco::core::SEditorObject lua) { - EXPECT_EQ(cmd_->deleteObjects(std::vector{lua}), 1); +void TracePlayerTest::deleteLuaObj(core::SEditorObject lua) { + EXPECT_EQ(cmd_->deleteObjects(std::vector{lua}), 1); const auto lastRemoved{luaObjs_.erase(std::remove(luaObjs_.begin(), luaObjs_.end(), lua), luaObjs_.end())}; EXPECT_EQ(lastRemoved, luaObjs_.end()); } @@ -147,8 +147,8 @@ QJsonArray const* const TracePlayerTest::loadTrace(std::string const& fileName) } /// backup features Lua nodes from Scene (e.g. saInfo Lua node) to validate backup/restore mechanism -std::unordered_map const* const TracePlayerTest::backupSceneLuaObjs(QJsonArray const* const qjTrace) { - std::unordered_map* const luaObjsBackup{new std::unordered_map()}; +std::unordered_map const* const TracePlayerTest::backupSceneLuaObjs(QJsonArray const* const qjTrace) { + std::unordered_map* const luaObjsBackup{new std::unordered_map()}; for (int frameIndex{0}; frameIndex < qjTrace->size(); ++frameIndex) { const auto qjSceneData{qjTrace->at(frameIndex).toObject().value("SceneData").toObject()}; @@ -188,7 +188,7 @@ bool TracePlayerTest::isValidRange() const { return ((player_->getIndex() >= 0) && (player_->getIndex() < player_->getTraceLen())); } -bool TracePlayerTest::areLuaObjsRestored(std::unordered_map const* const luaObjsBackup) const { +bool TracePlayerTest::areLuaObjsRestored(std::unordered_map const* const luaObjsBackup) const { bool restored{true}; bool atLeastOneWasFound{false}; @@ -767,18 +767,18 @@ TEST_F(TracePlayerTest, TF81_LinkedProperty) { const auto saInfoLua{findLua("saInfo")}; const auto srcLua{createLua("dummyAllTypes", LuaType::LuaScript)}; - const auto srcPropIn = raco::core::ValueHandle{srcLua, {"inputs", "propIntegerIn"}}; - const auto srcPropOut = raco::core::ValueHandle{srcLua, {"outputs", "propIntegerOut"}}; - const auto destProp = raco::core::ValueHandle{saInfoLua, {"inputs", "ACC", "state"}}; + const auto srcPropIn = core::ValueHandle{srcLua, {"inputs", "propIntegerIn"}}; + const auto srcPropOut = core::ValueHandle{srcLua, {"outputs", "propIntegerOut"}}; + const auto destProp = core::ValueHandle{saInfoLua, {"inputs", "ACC", "state"}}; cmd_->set(srcPropIn, 123000321); /*** Test setting linked property ***/ { EXPECT_NE(123000321, destProp.asInt()); - EXPECT_EQ(raco::core::Queries::CurrentLinkState::NOT_LINKED, raco::core::Queries::linkState(*cmd_->project(), destProp).current); + EXPECT_EQ(core::Queries::CurrentLinkState::NOT_LINKED, core::Queries::linkState(*cmd_->project(), destProp).current); EXPECT_NE(nullptr, cmd_->addLink(srcPropOut, destProp)); increaseTimeAndDoOneLoop(); - EXPECT_EQ(raco::core::Queries::CurrentLinkState::LINKED, raco::core::Queries::linkState(*cmd_->project(), destProp).current); + EXPECT_EQ(core::Queries::CurrentLinkState::LINKED, core::Queries::linkState(*cmd_->project(), destProp).current); EXPECT_EQ(123000321, destProp.asInt()); player_->play(); @@ -796,7 +796,7 @@ TEST_F(TracePlayerTest, TF81_LinkedProperty) { player_->play(); increaseTimeAndDoOneLoop(); playOneFrame(); - EXPECT_EQ(raco::core::Queries::CurrentLinkState::NOT_LINKED, raco::core::Queries::linkState(*cmd_->project(), destProp).current); + EXPECT_EQ(core::Queries::CurrentLinkState::NOT_LINKED, core::Queries::linkState(*cmd_->project(), destProp).current); playOneFrame(); EXPECT_NE(123000321, destProp.asInt()); ASSERT_EQ(log.size(), 0); @@ -812,13 +812,13 @@ TEST_F(TracePlayerTest, TF81_LinkedProperty) { EXPECT_NE(nullptr, cmd_->addLink(srcPropOut, destProp)); increaseTimeAndDoOneLoop(); - EXPECT_EQ(raco::core::Queries::CurrentLinkState::LINKED, raco::core::Queries::linkState(*cmd_->project(), destProp).current); + EXPECT_EQ(core::Queries::CurrentLinkState::LINKED, core::Queries::linkState(*cmd_->project(), destProp).current); player_->play(); playOneFrame(); EXPECT_EQ(123000322, destProp.asInt()); - cmd_->set(raco::core::ValueHandle{srcLua, {"uri"}}, (test_path() / "lua_scripts" / "dummyAllTypes_NoInteger.lua").string()); - EXPECT_EQ(raco::core::Queries::CurrentLinkState::BROKEN, raco::core::Queries::linkState(*cmd_->project(), destProp).current); + cmd_->set(core::ValueHandle{srcLua, {"uri"}}, (test_path() / "lua_scripts" / "dummyAllTypes_NoInteger.lua").string()); + EXPECT_EQ(core::Queries::CurrentLinkState::BROKEN, core::Queries::linkState(*cmd_->project(), destProp).current); playOneFrame(); EXPECT_EQ(123000322, destProp.asInt()); const auto& log{player_->getLog()}; @@ -827,7 +827,7 @@ TEST_F(TracePlayerTest, TF81_LinkedProperty) { cmd_->removeLink(destProp.getDescriptor()); increaseTimeAndDoOneLoop(); - EXPECT_EQ(raco::core::Queries::CurrentLinkState::NOT_LINKED, raco::core::Queries::linkState(*cmd_->project(), destProp).current); + EXPECT_EQ(core::Queries::CurrentLinkState::NOT_LINKED, core::Queries::linkState(*cmd_->project(), destProp).current); playOneFrame(); EXPECT_NE(123000322, destProp.asInt()); ASSERT_EQ(log.size(), 0); @@ -870,7 +870,7 @@ TEST_F(TracePlayerTest, TF93_Move_Lua_Under_Prefab) { increaseTimeAndDoOneLoop(); } - cmd_->moveScenegraphChildren({findLua("saInfo")}, cmd_->createObject(raco::user_types::Prefab::typeDescription.typeName, "TestPrefab")); + cmd_->moveScenegraphChildren({findLua("saInfo")}, cmd_->createObject(user_types::Prefab::typeDescription.typeName, "TestPrefab")); playOneFrame(); @@ -933,14 +933,14 @@ TEST_F(TracePlayerTest, TF96_Lock_ReadOnly_NestedPrefabInstanceLua) { deleteLuaObj(findLua("saInfo")); - const auto parentPrefab{cmd_->createObject(raco::user_types::Prefab::typeDescription.typeName)}; - const auto childPrefab{cmd_->createObject(raco::user_types::Prefab::typeDescription.typeName)}; + const auto parentPrefab{cmd_->createObject(user_types::Prefab::typeDescription.typeName)}; + const auto childPrefab{cmd_->createObject(user_types::Prefab::typeDescription.typeName)}; createLua("saInfo", LuaType::LuaScript, true, childPrefab); - const auto prefabInstance_parentPrefab{cmd_->createObject(raco::user_types::PrefabInstance::typeDescription.typeName, std::string(), parentPrefab)}; - cmd_->set(raco::core::ValueHandle{prefabInstance_parentPrefab, &raco::user_types::PrefabInstance::template_}, childPrefab); - const auto prefabInstance_sceneGraph{cmd_->createObject(raco::user_types::PrefabInstance::typeDescription.typeName)}; - cmd_->set(raco::core::ValueHandle{prefabInstance_sceneGraph, &raco::user_types::PrefabInstance::template_}, parentPrefab); + const auto prefabInstance_parentPrefab{cmd_->createObject(user_types::PrefabInstance::typeDescription.typeName, std::string(), parentPrefab)}; + cmd_->set(core::ValueHandle{prefabInstance_parentPrefab, &user_types::PrefabInstance::template_}, childPrefab); + const auto prefabInstance_sceneGraph{cmd_->createObject(user_types::PrefabInstance::typeDescription.typeName)}; + cmd_->set(core::ValueHandle{prefabInstance_sceneGraph, &user_types::PrefabInstance::template_}, parentPrefab); playOneFrame(); @@ -957,7 +957,7 @@ TEST_F(TracePlayerTest, TF101_Undo_NoEffect_WhilePaused) { } player_->pause(); - cmd_->createObject(raco::user_types::LuaScript::typeDescription.typeName, "dummyLua"); + cmd_->createObject(user_types::LuaScript::typeDescription.typeName, "dummyLua"); cmd_->undoStack().undo(); increaseTimeAndDoOneLoop(); @@ -974,7 +974,7 @@ TEST_F(TracePlayerTest, TF102_Undo_NoEffect_WhilePlaying) { increaseTimeAndDoOneLoop(); } - cmd_->createObject(raco::user_types::LuaScript::typeDescription.typeName, "dummyLua"); + cmd_->createObject(user_types::LuaScript::typeDescription.typeName, "dummyLua"); cmd_->undoStack().undo(); playOneFrame(); @@ -985,8 +985,8 @@ TEST_F(TracePlayerTest, TF102_Undo_NoEffect_WhilePlaying) { TEST_F(TracePlayerTest, TF103_Check_Properties_Consistency) { deleteLuaObj(findLua("saInfo")); const auto luaSceneControls{createLua("SceneControls", LuaType::LuaScript)}; - const auto luaModule{cmd_->createObject(raco::user_types::LuaScriptModule::typeDescription.typeName, "m")}; - cmd_->set({luaModule, &raco::user_types::LuaScriptModule::uri_}, test_path().append("lua_scripts/modules/anim_utils.lua").string()); + const auto luaModule{cmd_->createObject(user_types::LuaScriptModule::typeDescription.typeName, "m")}; + cmd_->set({luaModule, &user_types::LuaScriptModule::uri_}, test_path().append("lua_scripts/modules/anim_utils.lua").string()); cmd_->set({luaSceneControls, {"luaModules", "anim_utils"}}, luaModule); loadTrace("raco_traces/g05_demo.rctrace"); @@ -1019,8 +1019,8 @@ TEST_F(TracePlayerTest, TF103_Check_Properties_Consistency) { TEST_F(TracePlayerTest, TF104_Disregarded_Properties) { deleteLuaObj(findLua("saInfo")); const auto luaSceneControls{createLua("SceneControls", LuaType::LuaScript)}; - const auto luaModule{cmd_->createObject(raco::user_types::LuaScriptModule::typeDescription.typeName, "m")}; - cmd_->set({luaModule, &raco::user_types::LuaScriptModule::uri_}, test_path().append("lua_scripts/modules/anim_utils.lua").string()); + const auto luaModule{cmd_->createObject(user_types::LuaScriptModule::typeDescription.typeName, "m")}; + cmd_->set({luaModule, &user_types::LuaScriptModule::uri_}, test_path().append("lua_scripts/modules/anim_utils.lua").string()); cmd_->set({luaSceneControls, {"luaModules", "anim_utils"}}, luaModule); { @@ -1053,30 +1053,30 @@ TEST_F(TracePlayerTest, TF104_Disregarded_Properties) { /// switch Lua to anther one that contains extra properties. We need to cheat here and briefly unlock the editor object. /// the same change could happen by changing the underlying file, but that is harder to accomplish right here. - const auto luaText{raco::utils::file::read((test_path() / "lua_scripts" / "SceneControls_withExtras.lua").string())}; - const auto fileUsedByScript{luaSceneControls->as()->uri_.asString()}; - raco::utils::file::write(fileUsedByScript, luaText); + const auto luaText{utils::file::read((test_path() / "lua_scripts" / "SceneControls_withExtras.lua").string())}; + const auto fileUsedByScript{luaSceneControls->as()->uri_.asString()}; + utils::file::write(fileUsedByScript, luaText); // Make sure the file system watcher picks up the change int maxNumLoops{50}; - while (!raco::core::ValueHandle{luaSceneControls, {"inputs", "extra_property"}} && --maxNumLoops >= 0) { + while (!core::ValueHandle{luaSceneControls, {"inputs", "extra_property"}} && --maxNumLoops >= 0) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); // give the file monitor thread some time. QCoreApplication::processEvents(); increaseTimeAndDoOneLoop(); } ASSERT_GE(maxNumLoops, 0); - ASSERT_EQ(static_cast(raco::core::ValueHandle{luaSceneControls, {"inputs", "extra_property"}}), true); + ASSERT_EQ(static_cast(core::ValueHandle{luaSceneControls, {"inputs", "extra_property"}}), true); /// handle to extra_property - const auto extraPropValHandle{raco::core::ValueHandle{luaSceneControls, {"inputs", "extra_property"}}}; - raco::core::CodeControlledPropertyModifier::setPrimitive(extraPropValHandle, 12345, player_->uiChanges()); + const auto extraPropValHandle{core::ValueHandle{luaSceneControls, {"inputs", "extra_property"}}}; + core::CodeControlledPropertyModifier::setPrimitive(extraPropValHandle, 12345, player_->uiChanges()); /// handle to Extra_Struct properties - const auto extraChild1PropValHandle{raco::core::ValueHandle{luaSceneControls, {"inputs", "Extra_Struct", "extra_child1"}}}; - const auto extraChild2PropValHandle{raco::core::ValueHandle{luaSceneControls, {"inputs", "Extra_Struct", "extra_child2"}}}; - raco::core::CodeControlledPropertyModifier::setPrimitive(extraChild1PropValHandle, true, player_->uiChanges()); - raco::core::CodeControlledPropertyModifier::setPrimitive(extraChild2PropValHandle, 54321, player_->uiChanges()); + const auto extraChild1PropValHandle{core::ValueHandle{luaSceneControls, {"inputs", "Extra_Struct", "extra_child1"}}}; + const auto extraChild2PropValHandle{core::ValueHandle{luaSceneControls, {"inputs", "Extra_Struct", "extra_child2"}}}; + core::CodeControlledPropertyModifier::setPrimitive(extraChild1PropValHandle, true, player_->uiChanges()); + core::CodeControlledPropertyModifier::setPrimitive(extraChild2PropValHandle, 54321, player_->uiChanges()); /// continue playback till end of trace while (player_->getIndex() < player_->getTraceLen() - 1) { @@ -1098,8 +1098,8 @@ TEST_F(TracePlayerTest, TF105_ArrayOfDifferentTypes) { deleteLuaObj(findLua("saInfo")); const auto luaSceneControls{createLua("SceneControls_withArrays", LuaType::LuaScript)}; - const auto luaModule{cmd_->createObject(raco::user_types::LuaScriptModule::typeDescription.typeName, "m")}; - cmd_->set({luaModule, &raco::user_types::LuaScriptModule::uri_}, test_path().append("lua_scripts/modules/anim_utils.lua").string()); + const auto luaModule{cmd_->createObject(user_types::LuaScriptModule::typeDescription.typeName, "m")}; + cmd_->set({luaModule, &user_types::LuaScriptModule::uri_}, test_path().append("lua_scripts/modules/anim_utils.lua").string()); cmd_->set({luaSceneControls, {"luaModules", "anim_utils"}}, luaModule); loadTrace("raco_traces/g05_demo_Arrays.rctrace"); @@ -1130,8 +1130,8 @@ TEST_F(TracePlayerTest, TF105_ArrayOfDifferentTypes) { TEST_F(TracePlayerTest, TF106_ConsistentWithUndo) { const auto luaSceneControls{createLua("SceneControls", LuaType::LuaScript)}; - const auto luaModule{cmd_->createObject(raco::user_types::LuaScriptModule::typeDescription.typeName, "m")}; - cmd_->set({luaModule, &raco::user_types::LuaScriptModule::uri_}, test_path().append("lua_scripts/modules/anim_utils.lua").string()); + const auto luaModule{cmd_->createObject(user_types::LuaScriptModule::typeDescription.typeName, "m")}; + cmd_->set({luaModule, &user_types::LuaScriptModule::uri_}, test_path().append("lua_scripts/modules/anim_utils.lua").string()); cmd_->set({luaSceneControls, {"luaModules", "anim_utils"}}, luaModule); const auto luaObjsBackup{backupSceneLuaObjs(loadTrace("raco_traces/g05_demo_withDummy.rctrace"))}; @@ -1163,9 +1163,9 @@ TEST_F(TracePlayerTest, TF107_ReloadResets) { loadTrace("raco_traces/ChargingSlider_Colors_Test.rctrace"); isStopped(); - const auto C1 = raco::core::ValueHandle{lua, {"inputs", "SystemColors", "C1"}}; - const auto C2 = raco::core::ValueHandle{lua, {"inputs", "SystemColors", "C2"}}; - const auto C3 = raco::core::ValueHandle{lua, {"inputs", "SystemColors", "C3"}}; + const auto C1 = core::ValueHandle{lua, {"inputs", "SystemColors", "C1"}}; + const auto C2 = core::ValueHandle{lua, {"inputs", "SystemColors", "C2"}}; + const auto C3 = core::ValueHandle{lua, {"inputs", "SystemColors", "C3"}}; EXPECT_EQ(0.0, C1.asVec3f().x.asDouble()); EXPECT_EQ(0.0, C1.asVec3f().y.asDouble()); diff --git a/components/libMeshLoader/include/mesh_loader/CTMFileLoader.h b/components/libMeshLoader/include/mesh_loader/CTMFileLoader.h index 0c071f9c..6a410bf0 100644 --- a/components/libMeshLoader/include/mesh_loader/CTMFileLoader.h +++ b/components/libMeshLoader/include/mesh_loader/CTMFileLoader.h @@ -15,19 +15,19 @@ class CTMimporter; namespace raco::mesh_loader { -class CTMFileLoader : public raco::core::MeshCacheEntry { +class CTMFileLoader : public core::MeshCacheEntry { public: CTMFileLoader(std::string absPath); virtual ~CTMFileLoader() = default; - raco::core::SharedMeshData loadMesh(const raco::core::MeshDescriptor& descriptor) override; + core::SharedMeshData loadMesh(const core::MeshDescriptor& descriptor) override; std::string getError() override; void reset() override; - const raco::core::MeshScenegraph* getScenegraph(const std::string& absPath) override; + const core::MeshScenegraph* getScenegraph(const std::string& absPath) override; int getTotalMeshCount() override; - raco::core::SharedAnimationSamplerData getAnimationSamplerData(const std::string& absPath, int animIndex, int samplerIndex) override; + core::SharedAnimationSamplerData getAnimationSamplerData(const std::string& absPath, int animIndex, int samplerIndex) override; - raco::core::SharedSkinData loadSkin(const std::string& absPath, int skinIndex, std::string& outError) override; + core::SharedSkinData loadSkin(const std::string& absPath, int skinIndex, std::string& outError) override; private: bool loadFile(); diff --git a/components/libMeshLoader/include/mesh_loader/CTMMesh.h b/components/libMeshLoader/include/mesh_loader/CTMMesh.h index 2f9585c6..b685f371 100644 --- a/components/libMeshLoader/include/mesh_loader/CTMMesh.h +++ b/components/libMeshLoader/include/mesh_loader/CTMMesh.h @@ -18,7 +18,7 @@ class CTMimporter; namespace raco::mesh_loader { -class CTMMesh : public raco::core::MeshData { +class CTMMesh : public core::MeshData { public: CTMMesh(CTMimporter& importer); @@ -41,6 +41,8 @@ class CTMMesh : public raco::core::MeshData { VertexAttribDataType attribDataType(int attribIndex) const override; const char* attribBuffer(int attribIndex) const override; + const std::vector& triangleBuffer() const override; + private: struct Attribute { std::string name; @@ -54,6 +56,8 @@ class CTMMesh : public raco::core::MeshData { std::vector indexBuffer_; std::vector attributes_; std::vector submeshIndexBufferRanges_; + + std::vector triangleBuffer_; }; } // namespace raco::mesh_loader \ No newline at end of file diff --git a/components/libMeshLoader/include/mesh_loader/glTFFileLoader.h b/components/libMeshLoader/include/mesh_loader/glTFFileLoader.h index 1f4beb57..5c7accf0 100644 --- a/components/libMeshLoader/include/mesh_loader/glTFFileLoader.h +++ b/components/libMeshLoader/include/mesh_loader/glTFFileLoader.h @@ -19,26 +19,26 @@ class Node; namespace raco::mesh_loader { -class glTFFileLoader final : public raco::core::MeshCacheEntry { +class glTFFileLoader final : public core::MeshCacheEntry { public: glTFFileLoader(std::string absPath); ~glTFFileLoader() override; - raco::core::SharedMeshData loadMesh(const raco::core::MeshDescriptor& descriptor) override; - const raco::core::MeshScenegraph* getScenegraph(const std::string& absPath) override; + core::SharedMeshData loadMesh(const core::MeshDescriptor& descriptor) override; + const core::MeshScenegraph* getScenegraph(const std::string& absPath) override; int getTotalMeshCount() override; - raco::core::SharedAnimationSamplerData getAnimationSamplerData(const std::string& absPath, int animIndex, int samplerIndex) override; + core::SharedAnimationSamplerData getAnimationSamplerData(const std::string& absPath, int animIndex, int samplerIndex) override; std::string getError() override; void reset() override; - raco::core::SharedSkinData loadSkin(const std::string& absPath, int skinIndex, std::string& outError) override; + core::SharedSkinData loadSkin(const std::string& absPath, int skinIndex, std::string& outError) override; private: std::string path_; std::unique_ptr scene_; std::unique_ptr importer_; - std::unique_ptr sceneGraph_; + std::unique_ptr sceneGraph_; std::string error_; std::string warning_; diff --git a/components/libMeshLoader/include/mesh_loader/glTFMesh.h b/components/libMeshLoader/include/mesh_loader/glTFMesh.h index 89e12ca2..52c9eff2 100644 --- a/components/libMeshLoader/include/mesh_loader/glTFMesh.h +++ b/components/libMeshLoader/include/mesh_loader/glTFMesh.h @@ -24,7 +24,7 @@ class Model; namespace raco::mesh_loader { -class glTFMesh : public raco::core::MeshData { +class glTFMesh : public core::MeshData { public: glTFMesh(const tinygltf::Model &scene, const core::MeshScenegraph &sceneGraph, const core::MeshDescriptor &descriptor); @@ -47,6 +47,8 @@ class glTFMesh : public raco::core::MeshData { VertexAttribDataType attribDataType(int attribute_index) const override; const char* attribBuffer(int attribute_index) const override; + const std::vector& triangleBuffer() const override; + private: struct Attribute { std::string name; @@ -78,6 +80,8 @@ class glTFMesh : public raco::core::MeshData { std::vector materials_; std::map metadata_; + + std::vector triangleBuffer_; }; } // namespace raco::mesh_loader \ No newline at end of file diff --git a/components/libMeshLoader/src/CTMFileLoader.cpp b/components/libMeshLoader/src/CTMFileLoader.cpp index 21a44185..c156ea66 100644 --- a/components/libMeshLoader/src/CTMFileLoader.cpp +++ b/components/libMeshLoader/src/CTMFileLoader.cpp @@ -59,7 +59,7 @@ void CTMFileLoader::reset() { valid_ = false; } -const raco::core::MeshScenegraph* CTMFileLoader::getScenegraph(const std::string& absPath) { +const core::MeshScenegraph* CTMFileLoader::getScenegraph(const std::string& absPath) { // Scenegraph import for CTM is unsupported as CTM does not contain any scenegraph. return nullptr; } @@ -68,12 +68,12 @@ int CTMFileLoader::getTotalMeshCount() { return 1; } -raco::core::SharedAnimationSamplerData CTMFileLoader::getAnimationSamplerData(const std::string& absPath, int animIndex, int samplerIndex) { +core::SharedAnimationSamplerData CTMFileLoader::getAnimationSamplerData(const std::string& absPath, int animIndex, int samplerIndex) { // CTM has no animations yet return {}; } -raco::core::SharedSkinData CTMFileLoader::loadSkin(const std::string& absPath, int skinIndex, std::string& outError) { +core::SharedSkinData CTMFileLoader::loadSkin(const std::string& absPath, int skinIndex, std::string& outError) { return {}; } @@ -83,7 +83,7 @@ raco::core::SharedSkinData CTMFileLoader::loadSkin(const std::string& absPath, i try { // Since we want to work with UTF-8 paths, we need to supply our own stream reading function here. - std::ifstream in{raco::utils::u8path(path_).internalPath(), std::ifstream::in | std::ifstream::binary}; + std::ifstream in{utils::u8path(path_).internalPath(), std::ifstream::in | std::ifstream::binary}; auto readFunction = [](void* aBuf, CTMuint aCount, void* aUserData) -> CTMuint { auto in = static_cast(aUserData); @@ -95,7 +95,7 @@ raco::core::SharedSkinData CTMFileLoader::loadSkin(const std::string& absPath, i valid_ = true; } catch (ctm_error const& e) { valid_ = false; - if (e.error_code() == CTM_BAD_FORMAT && raco::utils::file::isGitLfsPlaceholderFile(path_)) { + if (e.error_code() == CTM_BAD_FORMAT && utils::file::isGitLfsPlaceholderFile(path_)) { error_ = "Git LFS placeholder file detected."; } else { error_ = errorCodeToString(e.error_code()); @@ -107,11 +107,11 @@ raco::core::SharedSkinData CTMFileLoader::loadSkin(const std::string& absPath, i -raco::core::SharedMeshData CTMFileLoader::loadMesh(const raco::core::MeshDescriptor& descriptor) { +core::SharedMeshData CTMFileLoader::loadMesh(const core::MeshDescriptor& descriptor) { if (loadFile()) { return std::make_shared(*importer_.get()); } - return raco::core::SharedMeshData(); + return core::SharedMeshData(); } std::string CTMFileLoader::getError() { diff --git a/components/libMeshLoader/src/CTMMesh.cpp b/components/libMeshLoader/src/CTMMesh.cpp index dea9fffa..2210eb19 100644 --- a/components/libMeshLoader/src/CTMMesh.cpp +++ b/components/libMeshLoader/src/CTMMesh.cpp @@ -55,6 +55,10 @@ CTMMesh::CTMMesh(CTMimporter& importer) { } submeshIndexBufferRanges_ = {{0, 3 * numTriangles_}}; + + // Build non-indexed triangle buffer to be used for picking in ramses + auto vertexData = reinterpret_cast(attribBuffer(attribIndex(MeshData::ATTRIBUTE_POSITION))); + triangleBuffer_ = core::MeshData::buildTriangleBuffer(vertexData, indexBuffer_); } uint32_t CTMMesh::numSubmeshes() const { @@ -119,4 +123,8 @@ const char* CTMMesh::attribBuffer(int attribIndex) const { return reinterpret_cast(attributes_.at(attribIndex).data.data()); } +const std::vector& CTMMesh::triangleBuffer() const { + return triangleBuffer_; +} + } // namespace raco::mesh_loader \ No newline at end of file diff --git a/components/libMeshLoader/src/glTFFileLoader.cpp b/components/libMeshLoader/src/glTFFileLoader.cpp index c0d82daa..bc15b3c7 100644 --- a/components/libMeshLoader/src/glTFFileLoader.cpp +++ b/components/libMeshLoader/src/glTFFileLoader.cpp @@ -29,6 +29,8 @@ namespace { +using namespace raco; + std::array, 3> tinyglTFtrafoMatrixToXYZTrafos(const std::vector& tinyMatrix) { assert(tinyMatrix.size() == 16); @@ -47,10 +49,89 @@ std::array, 3> tinyglTFtrafoMatrixToXYZTrafos(const std::v trafos[0] = {translation.x, translation.y, translation.z}; trafos[1] = {scale.x, scale.y, scale.z}; - trafos[2] = raco::utils::math::quaternionToXYZDegrees(rotation.x, rotation.y, rotation.z, rotation.w); + trafos[2] = utils::math::quaternionToXYZDegrees(rotation.x, rotation.y, rotation.z, rotation.w); return trafos; } + +void unpackAnimationData(const std::vector>& data, + size_t numKeyFrames, + core::MeshAnimationInterpolation interpolation, + core::EnginePrimitive componentType, + std::vector>& keyFrames, + std::vector>& tangentsIn, + std::vector>& tangentsOut) { + auto animInterpolationIsCubic = (interpolation == core::MeshAnimationInterpolation::CubicSpline) || (interpolation == core::MeshAnimationInterpolation::CubicSpline_Quaternion); + + if (!animInterpolationIsCubic) { + if (componentType == core::EnginePrimitive::Array) { + // Morph targets: + // data buffer has numKeyFrames * number(morph targets) element vectors of size 1 + // we need to change this in numKeyFrames vector of length number(morph targets) + auto numTargets = data.size() / numKeyFrames; + assert(data.size() % numKeyFrames == 0); + for (size_t i = 0; i < numKeyFrames; i++) { + std::vector vec; + for (size_t target = 0; target < numTargets; target++) { + vec.emplace_back(data[i * numTargets + target][0]); + } + keyFrames.emplace_back(vec); + } + } else { + for (const auto& vecfKeyframe : data) { + if (componentType == core::EnginePrimitive::Vec3f) { + keyFrames.push_back({vecfKeyframe[0], vecfKeyframe[1], vecfKeyframe[2]}); + } else if (componentType == core::EnginePrimitive::Vec4f) { + keyFrames.push_back({vecfKeyframe[0], vecfKeyframe[1], vecfKeyframe[2], vecfKeyframe[3]}); + } + } + } + } else { + if (componentType == core::EnginePrimitive::Array) { + // Morph targets with cubic interpolation + // buffer structure: each keyframe described by a_1 ... a_k v_1 ... v_k b_1 ... b_k + // where 1...k are the morph targets, + // a/b are the in/out tangents, and v are the values + + auto numTargets = data.size() / (3 * numKeyFrames); + assert(data.size() % (3 * numKeyFrames) == 0); + + for (size_t i = 0; i < numKeyFrames; i++) { + std::vector tangentIn; + std::vector value; + std::vector tangentOut; + + for (size_t target = 0; target < numTargets; target++) { + tangentIn.emplace_back(data[(3 * i + 0) * numTargets + target][0]); + value.emplace_back(data[(3 * i + 1) * numTargets + target][0]); + tangentOut.emplace_back(data[(3 * i + 2) * numTargets + target][0]); + } + + tangentsIn.push_back(tangentIn); + keyFrames.emplace_back(value); + tangentsOut.push_back(tangentOut); + } + + } else { + for (auto i = 0; i < data.size(); i += 3) { + auto& tangentIn = data[i]; + auto& vecfKeyframe = data[i + 1]; + auto& tangentOut = data[i + 2]; + + if (componentType == core::EnginePrimitive::Vec3f) { + tangentsIn.push_back({tangentIn[0], tangentIn[1], tangentIn[2]}); + keyFrames.push_back({vecfKeyframe[0], vecfKeyframe[1], vecfKeyframe[2]}); + tangentsOut.push_back({tangentOut[0], tangentOut[1], tangentOut[2]}); + } else if (componentType == core::EnginePrimitive::Vec4f) { + tangentsIn.push_back({tangentIn[0], tangentIn[1], tangentIn[2], tangentIn[3]}); + keyFrames.push_back({vecfKeyframe[0], vecfKeyframe[1], vecfKeyframe[2], vecfKeyframe[3]}); + tangentsOut.push_back({tangentOut[0], tangentOut[1], tangentOut[2], tangentOut[3]}); + } + } + } + } +} + } // namespace namespace raco::mesh_loader { @@ -73,7 +154,7 @@ void glTFFileLoader::reset() { } bool glTFFileLoader::buildglTFScenegraph() { - sceneGraph_.reset(new raco::core::MeshScenegraph); + sceneGraph_.reset(new core::MeshScenegraph); // import nodes std::vector totalMeshPrimitiveSums(scene_->meshes.size()); @@ -103,7 +184,7 @@ bool glTFFileLoader::buildglTFScenegraph() { // import meshes - we are currently replicating Assimp's primitive-> mesh behavior auto& nodes = scene_->nodes; - sceneGraph_->nodes = std::vector>(nodes.size(), raco::core::MeshScenegraphNode()); + sceneGraph_->nodes = std::vector>(nodes.size(), core::MeshScenegraphNode()); std::vector nodesAffectedByRamsesTrafo; for (auto nodeIndex = 0; nodeIndex < nodes.size(); ++nodeIndex) { @@ -137,7 +218,7 @@ bool glTFFileLoader::buildglTFScenegraph() { newNode.transformations.rotation = trafos[2]; } else { transferNodeTransformations(newNode.transformations.translation, tinyNode.translation, 0.0); - auto eulerRotation = tinyNode.rotation.empty() ? std::array{} : raco::utils::math::quaternionToXYZDegrees(tinyNode.rotation[0], tinyNode.rotation[1], tinyNode.rotation[2], tinyNode.rotation[3]); + auto eulerRotation = tinyNode.rotation.empty() ? std::array{} : utils::math::quaternionToXYZDegrees(tinyNode.rotation[0], tinyNode.rotation[1], tinyNode.rotation[2], tinyNode.rotation[3]); transferNodeTransformations(newNode.transformations.rotation, eulerRotation, 0.0); transferNodeTransformations(newNode.transformations.scale, tinyNode.scale, 1.0); } @@ -158,7 +239,7 @@ bool glTFFileLoader::importglTFScene(const std::string& absPath) { std::string err; std::string warn; - if (raco::utils::u8path(absPath).extension() == ".glb") { + if (utils::u8path(absPath).extension() == ".glb") { importer_->LoadBinaryFromFile(&*scene_, &err, &warn, absPath); } else { importer_->LoadASCIIFromFile(&*scene_, &err, &warn, absPath); @@ -169,7 +250,7 @@ bool glTFFileLoader::importglTFScene(const std::string& absPath) { if (!err.empty()) { error_ = err; if (error_.find("parse_error") != std::string::npos || error_ == "Invalid magic.") { - if (raco::utils::file::isGitLfsPlaceholderFile(absPath)) { + if (utils::file::isGitLfsPlaceholderFile(absPath)) { error_ = "Git LFS placeholder file detected."; } } @@ -189,7 +270,7 @@ bool glTFFileLoader::importglTFScene(const std::string& absPath) { } void glTFFileLoader::importAnimations() { - sceneGraph_->animations.resize(scene_->animations.size(), raco::core::MeshAnimation{}); + sceneGraph_->animations.resize(scene_->animations.size(), core::MeshAnimation{}); sceneGraph_->animationSamplers.resize(scene_->animations.size()); for (auto animIndex = 0; animIndex < scene_->animations.size(); ++animIndex) { @@ -226,13 +307,12 @@ void glTFFileLoader::importSkins() { }); if (it != scene_->nodes.end()) { int nodeIndex = it - scene_->nodes.begin(); - sceneGraph_->skins.emplace_back(raco::core::SkinDescription{name, nodeIndex, skin.joints}); + sceneGraph_->skins.emplace_back(core::SkinDescription{name, nodeIndex, skin.joints}); } } } - -const raco::core::MeshScenegraph* glTFFileLoader::getScenegraph(const std::string& absPath) { +const core::MeshScenegraph* glTFFileLoader::getScenegraph(const std::string& absPath) { if (!importglTFScene(absPath)) { return nullptr; } @@ -248,7 +328,7 @@ int glTFFileLoader::getTotalMeshCount() { return primitiveCount; } -raco::core::SharedAnimationSamplerData glTFFileLoader::getAnimationSamplerData(const std::string& absPath, int animIndex, int samplerIndex) { +core::SharedAnimationSamplerData glTFFileLoader::getAnimationSamplerData(const std::string& absPath, int animIndex, int samplerIndex) { if (!importglTFScene(absPath)) { return {}; } @@ -264,23 +344,23 @@ raco::core::SharedAnimationSamplerData glTFFileLoader::getAnimationSamplerData(c const auto& tinyAnim = scene_->animations[animIndex]; const auto& sampler = tinyAnim.samplers[samplerIndex]; - raco::core::MeshAnimationInterpolation interpolation = raco::core::MeshAnimationInterpolation::Linear; + core::MeshAnimationInterpolation interpolation = core::MeshAnimationInterpolation::Linear; if (sampler.interpolation == "LINEAR") { if (scene_->accessors[sampler.output].type == TINYGLTF_TYPE_VEC4) { // VEC4 must be a rotation animation in glTF so this must be a quaternion interpolation type: - interpolation = raco::core::MeshAnimationInterpolation::Linear_Quaternion; + interpolation = core::MeshAnimationInterpolation::Linear_Quaternion; } else { - interpolation = raco::core::MeshAnimationInterpolation::Linear; + interpolation = core::MeshAnimationInterpolation::Linear; } } else if (sampler.interpolation == "CUBICSPLINE") { if (scene_->accessors[sampler.output].type == TINYGLTF_TYPE_VEC4) { // VEC4 must be a rotation animation in glTF so this must be a quaternion interpolation type: - interpolation = raco::core::MeshAnimationInterpolation::CubicSpline_Quaternion; + interpolation = core::MeshAnimationInterpolation::CubicSpline_Quaternion; } else { - interpolation = raco::core::MeshAnimationInterpolation::CubicSpline; + interpolation = core::MeshAnimationInterpolation::CubicSpline; } } else if (sampler.interpolation == "STEP") { - interpolation = raco::core::MeshAnimationInterpolation::Step; + interpolation = core::MeshAnimationInterpolation::Step; } else { LOG_ERROR(log_system::MESH_LOADER, "animation sampler at index {}.{} has no valid interpolation type. Using linear interpolation as a fallback.", animIndex, samplerIndex); } @@ -297,32 +377,53 @@ raco::core::SharedAnimationSamplerData glTFFileLoader::getAnimationSamplerData(c output.emplace_back(outputData.getNormalizedData(count)); } - return std::make_shared(raco::core::AnimationSamplerData{interpolation, input, output}); + core::EnginePrimitive componentType; + switch (output.front().size()) { + case 1: + componentType = core::EnginePrimitive::Array; + break; + case 3: + componentType = core::EnginePrimitive::Vec3f; + break; + case 4: + componentType = core::EnginePrimitive::Vec4f; + break; + default: + assert(false); + } + + std::vector> keyFrames; + std::vector> tangentsIn; + std::vector> tangentsOut; + + unpackAnimationData(output, input.size(), interpolation, componentType, keyFrames, tangentsIn, tangentsOut); + + return std::make_shared(core::AnimationSamplerData{interpolation, componentType, input, keyFrames, tangentsIn, tangentsOut}); } -raco::core::SharedMeshData glTFFileLoader::loadMesh(const core::MeshDescriptor& descriptor) { +core::SharedMeshData glTFFileLoader::loadMesh(const core::MeshDescriptor& descriptor) { if (!importglTFScene(descriptor.absPath)) { - return raco::core::SharedMeshData(); + return core::SharedMeshData(); } auto meshCount = getTotalMeshCount(); if (meshCount == 0) { error_ = "Mesh file contains no valid submeshes to select"; - return raco::core::SharedMeshData(); + return core::SharedMeshData(); } else if (descriptor.bakeAllSubmeshes) { if (std::all_of(sceneGraph_->nodes.begin(), sceneGraph_->nodes.end(), [](const auto& node) { return node->subMeshIndices.empty(); })) { error_ = "Mesh file contains no bakeable submeshes.\nSubmeshes should be referenced by nodes to be bakeable."; - return raco::core::SharedMeshData(); + return core::SharedMeshData(); } } if (!descriptor.bakeAllSubmeshes && (descriptor.submeshIndex < 0 || descriptor.submeshIndex >= meshCount)) { error_ = "Selected submesh index is out of valid submesh index range [0," + std::to_string(meshCount - 1) + "]"; - return raco::core::SharedMeshData(); + return core::SharedMeshData(); } return std::make_shared(*scene_, *sceneGraph_, descriptor); } -raco::core::SharedSkinData glTFFileLoader::loadSkin(const std::string& absPath, int skinIndex, std::string& outError) { +core::SharedSkinData glTFFileLoader::loadSkin(const std::string& absPath, int skinIndex, std::string& outError) { if (!importglTFScene(absPath)) { outError = error_.empty() ? "Invalid GLTF file." : error_; return {}; @@ -341,14 +442,18 @@ raco::core::SharedSkinData glTFFileLoader::loadSkin(const std::string& absPath, auto& skin = scene_->skins[skinIndex]; auto matrixData = glTFBufferData(*scene_, skin.inverseBindMatrices, {TINYGLTF_COMPONENT_TYPE_FLOAT}, {TINYGLTF_TYPE_MAT4}); - std::vector> matrixBuffer; + std::vector matrixBuffer; for (auto index = 0; index < matrixData.accessor_.count; index++) { - auto elementData = matrixData.getDataArray>(index); - matrixBuffer.emplace_back(elementData); + auto m = matrixData.getDataArray>(index); + matrixBuffer.emplace_back(glm::mat4x4( + m[0], m[1], m[2], m[3], + m[4], m[5], m[6], m[7], + m[8], m[9], m[10], m[11], + m[12], m[13], m[14], m[15])); } - return std::make_shared(raco::core::SkinData{matrixBuffer, scene_->skins.size()}); + return std::make_shared(core::SkinData{matrixBuffer, scene_->skins.size()}); } std::string glTFFileLoader::getError() { diff --git a/components/libMeshLoader/src/glTFMesh.cpp b/components/libMeshLoader/src/glTFMesh.cpp index bb887d13..bf83293b 100644 --- a/components/libMeshLoader/src/glTFMesh.cpp +++ b/components/libMeshLoader/src/glTFMesh.cpp @@ -121,11 +121,15 @@ glTFMesh::glTFMesh(const tinygltf::Model &scene, const core::MeshScenegraph &sce materials_ = {"material"}; // Add the vertices - attributes_.emplace_back(Attribute{ + const auto& posAttribute = attributes_.emplace_back(Attribute{ ATTRIBUTE_POSITION, VertexAttribDataType::VAT_Float3, vertexBuffer}); + // Build non-indexed triangle buffer to be used for picking in ramses + auto vertexData = reinterpret_cast(posAttribute.data.data()); + triangleBuffer_ = core::MeshData::buildTriangleBuffer(vertexData, indexBuffer_); + for (size_t index = 0; index < morphVertexBuffers.size(); index++) { if (!morphVertexBuffers[index].empty()) { attributes_.emplace_back(Attribute{ @@ -259,6 +263,10 @@ const char *glTFMesh::attribBuffer(int attribute_index) const { return reinterpret_cast(attributes_.at(attribute_index).data.data()); } +const std::vector& glTFMesh::triangleBuffer() const { + return triangleBuffer_; +} + void convertVectorWithTransformation(std::vector vector, std::vector &buffer, glm::dmat4 *trafoMatrix, double component_4) { if (trafoMatrix) { auto transformed = *trafoMatrix * glm::dvec4(vector[0], vector[1], vector[2], component_4); diff --git a/components/libMeshLoader/tests/FileLoader_test.cpp b/components/libMeshLoader/tests/FileLoader_test.cpp index 2c75c00c..1fd994cd 100644 --- a/components/libMeshLoader/tests/FileLoader_test.cpp +++ b/components/libMeshLoader/tests/FileLoader_test.cpp @@ -19,13 +19,13 @@ using namespace raco; class MeshLoaderTest : public TestEnvironmentCore { public: - raco::core::SharedMeshData loadMesh(const std::string &relPath, bool bake = true, int submeshIndex = 0) { + core::SharedMeshData loadMesh(const std::string &relPath, bool bake = true, int submeshIndex = 0) { core::MeshDescriptor desc{test_path().append(relPath).string(), submeshIndex, bake}; mesh_loader::glTFFileLoader fileloader(desc.absPath); return fileloader.loadMesh(desc); } - static void check_attribute(raco::core::SharedMeshData mesh, const std::string &name, raco::core::MeshData::VertexAttribDataType type, int elemCount) { + static void check_attribute(core::SharedMeshData mesh, const std::string &name, core::MeshData::VertexAttribDataType type, int elemCount) { int index = mesh->attribIndex(name); ASSERT_TRUE(index >= 0); @@ -34,7 +34,7 @@ class MeshLoaderTest : public TestEnvironmentCore { } protected: - std::vector getPositionData(const raco::core::SharedMeshData mesh) { + std::vector getPositionData(const core::SharedMeshData mesh) { auto posIndex = mesh->attribIndex(mesh->ATTRIBUTE_POSITION); auto firstPos = mesh->attribBuffer(posIndex); @@ -157,57 +157,57 @@ TEST_F(MeshLoaderTest, glTFWithTangentsAndBitangents) { auto mesh = loadMesh("meshes/AnimatedMorphCube/AnimatedMorphCube.gltf", false, 0); ASSERT_EQ(mesh->numAttributes(), 8); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_POSITION, raco::core::MeshData::VertexAttribDataType::VAT_Float3, 24); - check_attribute(mesh, fmt::format("{}_Morph_{}", raco::core::MeshData::ATTRIBUTE_POSITION, 0), raco::core::MeshData::VertexAttribDataType::VAT_Float3, 24); - check_attribute(mesh, fmt::format("{}_Morph_{}", raco::core::MeshData::ATTRIBUTE_POSITION, 1), raco::core::MeshData::VertexAttribDataType::VAT_Float3, 24); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_NORMAL, raco::core::MeshData::VertexAttribDataType::VAT_Float3, 24); - check_attribute(mesh, fmt::format("{}_Morph_{}", raco::core::MeshData::ATTRIBUTE_NORMAL, 0), raco::core::MeshData::VertexAttribDataType::VAT_Float3, 24); - check_attribute(mesh, fmt::format("{}_Morph_{}", raco::core::MeshData::ATTRIBUTE_NORMAL, 1), raco::core::MeshData::VertexAttribDataType::VAT_Float3, 24); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_TANGENT, raco::core::MeshData::VertexAttribDataType::VAT_Float3, 24); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_BITANGENT, raco::core::MeshData::VertexAttribDataType::VAT_Float3, 24); + check_attribute(mesh, core::MeshData::ATTRIBUTE_POSITION, core::MeshData::VertexAttribDataType::VAT_Float3, 24); + check_attribute(mesh, fmt::format("{}_Morph_{}", core::MeshData::ATTRIBUTE_POSITION, 0), core::MeshData::VertexAttribDataType::VAT_Float3, 24); + check_attribute(mesh, fmt::format("{}_Morph_{}", core::MeshData::ATTRIBUTE_POSITION, 1), core::MeshData::VertexAttribDataType::VAT_Float3, 24); + check_attribute(mesh, core::MeshData::ATTRIBUTE_NORMAL, core::MeshData::VertexAttribDataType::VAT_Float3, 24); + check_attribute(mesh, fmt::format("{}_Morph_{}", core::MeshData::ATTRIBUTE_NORMAL, 0), core::MeshData::VertexAttribDataType::VAT_Float3, 24); + check_attribute(mesh, fmt::format("{}_Morph_{}", core::MeshData::ATTRIBUTE_NORMAL, 1), core::MeshData::VertexAttribDataType::VAT_Float3, 24); + check_attribute(mesh, core::MeshData::ATTRIBUTE_TANGENT, core::MeshData::VertexAttribDataType::VAT_Float3, 24); + check_attribute(mesh, core::MeshData::ATTRIBUTE_BITANGENT, core::MeshData::VertexAttribDataType::VAT_Float3, 24); } TEST_F(MeshLoaderTest, glTFWithMultipleTexCoords) { auto mesh = loadMesh("meshes/MosquitoInAmber/MosquitoInAmber.gltf", false, 1); ASSERT_EQ(mesh->numAttributes(), 5); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_POSITION, raco::core::MeshData::VertexAttribDataType::VAT_Float3, 3057); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_NORMAL, raco::core::MeshData::VertexAttribDataType::VAT_Float3, 3057); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_UVMAP, raco::core::MeshData::VertexAttribDataType::VAT_Float2, 3057); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_UVMAP + std::to_string(1), raco::core::MeshData::VertexAttribDataType::VAT_Float2, 3057); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_UVMAP + std::to_string(2), raco::core::MeshData::VertexAttribDataType::VAT_Float2, 3057); + check_attribute(mesh, core::MeshData::ATTRIBUTE_POSITION, core::MeshData::VertexAttribDataType::VAT_Float3, 3057); + check_attribute(mesh, core::MeshData::ATTRIBUTE_NORMAL, core::MeshData::VertexAttribDataType::VAT_Float3, 3057); + check_attribute(mesh, core::MeshData::ATTRIBUTE_UVMAP, core::MeshData::VertexAttribDataType::VAT_Float2, 3057); + check_attribute(mesh, core::MeshData::ATTRIBUTE_UVMAP + std::to_string(1), core::MeshData::VertexAttribDataType::VAT_Float2, 3057); + check_attribute(mesh, core::MeshData::ATTRIBUTE_UVMAP + std::to_string(2), core::MeshData::VertexAttribDataType::VAT_Float2, 3057); } TEST_F(MeshLoaderTest, glTFWithMultipleColors) { auto mesh = loadMesh("meshes/MultipleVCols/multiple_VCols.gltf"); ASSERT_EQ(mesh->numAttributes(), 6); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_POSITION, raco::core::MeshData::VertexAttribDataType::VAT_Float3, 625); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_NORMAL, raco::core::MeshData::VertexAttribDataType::VAT_Float3, 625); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_UVMAP, raco::core::MeshData::VertexAttribDataType::VAT_Float2, 625); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_COLOR, raco::core::MeshData::VertexAttribDataType::VAT_Float4, 625); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_COLOR + std::to_string(1), raco::core::MeshData::VertexAttribDataType::VAT_Float4, 625); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_COLOR + std::to_string(2), raco::core::MeshData::VertexAttribDataType::VAT_Float4, 625); + check_attribute(mesh, core::MeshData::ATTRIBUTE_POSITION, core::MeshData::VertexAttribDataType::VAT_Float3, 625); + check_attribute(mesh, core::MeshData::ATTRIBUTE_NORMAL, core::MeshData::VertexAttribDataType::VAT_Float3, 625); + check_attribute(mesh, core::MeshData::ATTRIBUTE_UVMAP, core::MeshData::VertexAttribDataType::VAT_Float2, 625); + check_attribute(mesh, core::MeshData::ATTRIBUTE_COLOR, core::MeshData::VertexAttribDataType::VAT_Float4, 625); + check_attribute(mesh, core::MeshData::ATTRIBUTE_COLOR + std::to_string(1), core::MeshData::VertexAttribDataType::VAT_Float4, 625); + check_attribute(mesh, core::MeshData::ATTRIBUTE_COLOR + std::to_string(2), core::MeshData::VertexAttribDataType::VAT_Float4, 625); } TEST_F(MeshLoaderTest, glTFWithSingleJointWeightSet) { auto mesh = loadMesh("meshes/SimpleSkin/SimpleSkin.gltf"); ASSERT_EQ(mesh->numAttributes(), 3); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_POSITION, raco::core::MeshData::VertexAttribDataType::VAT_Float3, 10); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_JOINTS + std::to_string(0), raco::core::MeshData::VertexAttribDataType::VAT_Float4, 10); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_WEIGHTS + std::to_string(0), raco::core::MeshData::VertexAttribDataType::VAT_Float4, 10); + check_attribute(mesh, core::MeshData::ATTRIBUTE_POSITION, core::MeshData::VertexAttribDataType::VAT_Float3, 10); + check_attribute(mesh, core::MeshData::ATTRIBUTE_JOINTS + std::to_string(0), core::MeshData::VertexAttribDataType::VAT_Float4, 10); + check_attribute(mesh, core::MeshData::ATTRIBUTE_WEIGHTS + std::to_string(0), core::MeshData::VertexAttribDataType::VAT_Float4, 10); } TEST_F(MeshLoaderTest, glTFWithMultipleJointWeightSets) { auto mesh = loadMesh("meshes/SimpleSkin/SimpleSkin-multi-joint-set.gltf"); ASSERT_EQ(mesh->numAttributes(), 5); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_POSITION, raco::core::MeshData::VertexAttribDataType::VAT_Float3, 10); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_JOINTS + std::to_string(0), raco::core::MeshData::VertexAttribDataType::VAT_Float4, 10); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_JOINTS + std::to_string(1), raco::core::MeshData::VertexAttribDataType::VAT_Float4, 10); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_WEIGHTS + std::to_string(0), raco::core::MeshData::VertexAttribDataType::VAT_Float4, 10); - check_attribute(mesh, raco::core::MeshData::ATTRIBUTE_WEIGHTS + std::to_string(1), raco::core::MeshData::VertexAttribDataType::VAT_Float4, 10); + check_attribute(mesh, core::MeshData::ATTRIBUTE_POSITION, core::MeshData::VertexAttribDataType::VAT_Float3, 10); + check_attribute(mesh, core::MeshData::ATTRIBUTE_JOINTS + std::to_string(0), core::MeshData::VertexAttribDataType::VAT_Float4, 10); + check_attribute(mesh, core::MeshData::ATTRIBUTE_JOINTS + std::to_string(1), core::MeshData::VertexAttribDataType::VAT_Float4, 10); + check_attribute(mesh, core::MeshData::ATTRIBUTE_WEIGHTS + std::to_string(0), core::MeshData::VertexAttribDataType::VAT_Float4, 10); + check_attribute(mesh, core::MeshData::ATTRIBUTE_WEIGHTS + std::to_string(1), core::MeshData::VertexAttribDataType::VAT_Float4, 10); } TEST_F(MeshLoaderTest, gltFCheckSkinData) { @@ -226,7 +226,7 @@ TEST_F(MeshLoaderTest, ctmWithGitLfsPlaceholderFile) { core::MeshDescriptor desc; desc.absPath = path; - auto fileLoader = std::unique_ptr(new mesh_loader::CTMFileLoader(path)); + auto fileLoader = std::unique_ptr(new mesh_loader::CTMFileLoader(path)); auto mesh = fileLoader.get()->loadMesh(desc); ASSERT_EQ(fileLoader->getError(), "Git LFS placeholder file detected."); diff --git a/components/libPythonAPI/include/python_api/PythonAPI.h b/components/libPythonAPI/include/python_api/PythonAPI.h index 5b117764..10c18c2f 100644 --- a/components/libPythonAPI/include/python_api/PythonAPI.h +++ b/components/libPythonAPI/include/python_api/PythonAPI.h @@ -22,6 +22,6 @@ struct PythonRunStatus { }; bool preparePythonEnvironment(std::wstring argv0, const std::vector& pythonSearchPaths, bool searchPythonFolderForTest = false); -void setup(raco::application::RaCoApplication* app); -PythonRunStatus runPythonScript(raco::application::RaCoApplication* app, const std::wstring& applicationPath, const std::string& pythonScriptPath, const std::vector& pythonSearchPaths, const std::vector& pos_argv_cp); +void setup(application::RaCoApplication* app); +PythonRunStatus runPythonScript(application::RaCoApplication* app, const std::wstring& applicationPath, const std::string& pythonScriptPath, const std::vector& pythonSearchPaths, const std::vector& pos_argv_cp); } diff --git a/components/libPythonAPI/src/PythonAPI.cpp b/components/libPythonAPI/src/PythonAPI.cpp index 19835f1e..f6d6e9f4 100644 --- a/components/libPythonAPI/src/PythonAPI.cpp +++ b/components/libPythonAPI/src/PythonAPI.cpp @@ -43,57 +43,60 @@ namespace py = pybind11; namespace { + +using namespace raco; + raco::application::RaCoApplication* app; raco::python_api::PythonRunStatus currentRunStatus; -py::object python_get_scalar_value(raco::core::ValueHandle handle) { +py::object python_get_scalar_value(core::ValueHandle handle) { using namespace raco::user_types; switch (handle.type()) { - case raco::data_storage::PrimitiveType::Bool: + case data_storage::PrimitiveType::Bool: return py::cast(handle.asBool()); break; - case raco::data_storage::PrimitiveType::Int: - if (auto anno = handle.query()) { - switch (static_cast(anno->type_.asInt())) { - case raco::core::EUserTypeEnumerations::CullMode: + case data_storage::PrimitiveType::Int: + if (auto anno = handle.query()) { + switch (static_cast(anno->type_.asInt())) { + case core::EUserTypeEnumerations::CullMode: return py::cast(static_cast(handle.asInt())); - case raco::core::EUserTypeEnumerations::BlendOperation: + case core::EUserTypeEnumerations::BlendOperation: return py::cast(static_cast(handle.asInt())); - case raco::core::EUserTypeEnumerations::BlendFactor: + case core::EUserTypeEnumerations::BlendFactor: return py::cast(static_cast(handle.asInt())); - case raco::core::EUserTypeEnumerations::DepthFunction: + case core::EUserTypeEnumerations::DepthFunction: return py::cast(static_cast(handle.asInt())); - case raco::core::EUserTypeEnumerations::TextureAddressMode: + case core::EUserTypeEnumerations::TextureAddressMode: return py::cast(static_cast(handle.asInt())); - case raco::core::EUserTypeEnumerations::TextureMinSamplingMethod: - case raco::core::EUserTypeEnumerations::TextureMagSamplingMethod: + case core::EUserTypeEnumerations::TextureMinSamplingMethod: + case core::EUserTypeEnumerations::TextureMagSamplingMethod: return py::cast(static_cast(handle.asInt())); - case raco::core::EUserTypeEnumerations::TextureFormat: + case core::EUserTypeEnumerations::TextureFormat: return py::cast(static_cast(handle.asInt())); - case raco::core::EUserTypeEnumerations::RenderBufferFormat: + case core::EUserTypeEnumerations::RenderBufferFormat: return py::cast(static_cast(handle.asInt())); - case raco::core::EUserTypeEnumerations::RenderLayerOrder: + case core::EUserTypeEnumerations::RenderLayerOrder: return py::cast(static_cast(handle.asInt())); - case raco::core::EUserTypeEnumerations::RenderLayerMaterialFilterMode: + case core::EUserTypeEnumerations::RenderLayerMaterialFilterMode: return py::cast(static_cast(handle.asInt())); - case raco::core::EUserTypeEnumerations::FrustumType: + case core::EUserTypeEnumerations::FrustumType: return py::cast(static_cast(handle.asInt())); - case raco::core::EUserTypeEnumerations::StencilFunction: + case core::EUserTypeEnumerations::StencilFunction: return py::cast(static_cast(handle.asInt())); - case raco::core::EUserTypeEnumerations::StencilOperation: + case core::EUserTypeEnumerations::StencilOperation: return py::cast(static_cast(handle.asInt())); default: @@ -104,16 +107,16 @@ py::object python_get_scalar_value(raco::core::ValueHandle handle) { return py::cast(handle.asInt()); } break; - case raco::data_storage::PrimitiveType::Int64: + case data_storage::PrimitiveType::Int64: return py::cast(handle.asInt64()); break; - case raco::data_storage::PrimitiveType::Double: + case data_storage::PrimitiveType::Double: return py::cast(handle.asDouble()); break; - case raco::data_storage::PrimitiveType::String: + case data_storage::PrimitiveType::String: return py::cast(handle.asString()); break; - case raco::data_storage::PrimitiveType::Ref: + case data_storage::PrimitiveType::Ref: return py::cast(handle.asRef()); break; default: @@ -122,44 +125,44 @@ py::object python_get_scalar_value(raco::core::ValueHandle handle) { } } -void checkObject(raco::core::SEditorObject object) { +void checkObject(core::SEditorObject object) { if (!app->activeRaCoProject().project()->isInstance(object)) { throw std::runtime_error(fmt::format("Object '{}' not in project", object->objectName())); } } template -void checkTypedObject(raco::core::SEditorObject object) { +void checkTypedObject(core::SEditorObject object) { checkObject(object); if (!object->isType()) { throw std::runtime_error(fmt::format("Object '{}' is not of expected type '{}'", object->objectName(), UserType::typeDescription.typeName)); } } -void checkProperty(const raco::core::PropertyDescriptor& desc) { +void checkProperty(const core::PropertyDescriptor& desc) { checkObject(desc.object()); - raco::core::ValueHandle handle{desc}; - if (!handle || handle.constValueRef()->query()) { + core::ValueHandle handle{desc}; + if (!handle || handle.constValueRef()->query()) { throw std::runtime_error(fmt::format("Property '{}' doesn't exist in object '{}'", desc.getPropertyPath(), desc.object()->objectName())); } - if (auto anno = handle.query(); anno && *anno->featureLevel_ > app->activeRaCoProject().project()->featureLevel()) { + if (auto anno = handle.query(); anno && *anno->featureLevel_ > app->activeRaCoProject().project()->featureLevel()) { throw std::runtime_error(fmt::format("Property {} inaccessible at feature level {}", handle.getPropertyPath(), app->activeRaCoProject().project()->featureLevel())); } } -void checkHiddenProperty(const raco::core::PropertyDescriptor& desc) { +void checkHiddenProperty(const core::PropertyDescriptor& desc) { checkObject(desc.object()); - raco::core::ValueHandle handle{desc}; + core::ValueHandle handle{desc}; if (!handle) { throw std::runtime_error(fmt::format("Property '{}' doesn't exist in object '{}'", desc.getPropertyPath(), desc.object()->objectName())); } - if (auto anno = handle.query(); anno && *anno->featureLevel_ > app->activeRaCoProject().project()->featureLevel()) { + if (auto anno = handle.query(); anno && *anno->featureLevel_ > app->activeRaCoProject().project()->featureLevel()) { throw std::runtime_error(fmt::format("Property {} inaccessible at feature level {}", handle.getPropertyPath(), app->activeRaCoProject().project()->featureLevel())); } } template -void set_scalar_value_typed(const raco::core::ValueHandle& handle, py::object value, std::string_view typeName) { +void set_scalar_value_typed(const core::ValueHandle& handle, py::object value, std::string_view typeName) { try { app->activeRaCoProject().commandInterface()->set(handle, value.cast()); app->doOneLoop(); @@ -169,55 +172,55 @@ void set_scalar_value_typed(const raco::core::ValueHandle& handle, py::object va } } -template +template std::array to_std_array(const py::list& pyList) { auto result = std::array{}; std::transform(pyList.begin(), pyList.end(), result.begin(), [](const auto& pyObject) { return pyObject.template cast(); }); return result; } -void set_as_vec(raco::core::ValueHandle const& handle, const py::list& pyList) { +void set_as_vec(core::ValueHandle const& handle, const py::list& pyList) { auto* commandInterface = app->activeRaCoProject().commandInterface(); const auto typeDesc = &handle.constValueRef()->asStruct().getTypeDescription(); - if (typeDesc == &raco::core::Vec2f::typeDescription) { + if (typeDesc == &core::Vec2f::typeDescription) { commandInterface->set(handle, to_std_array(pyList)); - } else if (typeDesc == &raco::core::Vec3f::typeDescription) { + } else if (typeDesc == &core::Vec3f::typeDescription) { commandInterface->set(handle, to_std_array(pyList)); - } else if (typeDesc == &raco::core::Vec4f::typeDescription) { + } else if (typeDesc == &core::Vec4f::typeDescription) { commandInterface->set(handle, to_std_array(pyList)); - } else if (typeDesc == &raco::core::Vec2i::typeDescription) { + } else if (typeDesc == &core::Vec2i::typeDescription) { commandInterface->set(handle, to_std_array(pyList)); - } else if (typeDesc == &raco::core::Vec3i::typeDescription) { + } else if (typeDesc == &core::Vec3i::typeDescription) { commandInterface->set(handle, to_std_array(pyList)); - } else if (typeDesc == &raco::core::Vec4i::typeDescription) { + } else if (typeDesc == &core::Vec4i::typeDescription) { commandInterface->set(handle, to_std_array(pyList)); - } else { + } else { throw std::runtime_error(fmt::format("Set property '{}': should be of vector type.", handle.getPropertyPath())); } } -void python_set_value(const raco::core::PropertyDescriptor& desc, py::object value) { +void python_set_value(const core::PropertyDescriptor& desc, py::object value) { checkProperty(desc); - raco::core::ValueHandle handle{desc}; + core::ValueHandle handle{desc}; if (!handle.hasSubstructure()) { switch (handle.type()) { - case raco::data_storage::PrimitiveType::Bool: + case data_storage::PrimitiveType::Bool: set_scalar_value_typed(handle, value, "bool"); break; - case raco::data_storage::PrimitiveType::Int: + case data_storage::PrimitiveType::Int: set_scalar_value_typed(handle, value, "int"); break; - case raco::data_storage::PrimitiveType::Int64: + case data_storage::PrimitiveType::Int64: set_scalar_value_typed(handle, value, "int64"); break; - case raco::data_storage::PrimitiveType::Double: + case data_storage::PrimitiveType::Double: set_scalar_value_typed(handle, value, "double"); break; - case raco::data_storage::PrimitiveType::String: + case data_storage::PrimitiveType::String: set_scalar_value_typed(handle, value, "string"); break; - case raco::data_storage::PrimitiveType::Ref: - set_scalar_value_typed(handle, value, "reference"); + case data_storage::PrimitiveType::Ref: + set_scalar_value_typed(handle, value, "reference"); break; } } else if ( @@ -255,9 +258,9 @@ void python_load_project(std::string& path, int featureLevel) { } } -void python_import_gltf(const std::string path, const raco::core::SEditorObject parent) { - auto fileLocation = raco::utils::u8path(path); - fileLocation = fileLocation.normalizedAbsolutePath(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Mesh, app->activeProjectFolder())); +void python_import_gltf(const std::string path, const core::SEditorObject parent) { + auto fileLocation = utils::u8path(path); + fileLocation = fileLocation.normalizedAbsolutePath(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Mesh, app->activeProjectFolder())); auto absPath = fileLocation.string(); @@ -273,11 +276,11 @@ void python_import_gltf(const std::string path, const raco::core::SEditorObject app->doOneLoop(); } -raco::core::Project* python_add_external_project(const std::string& path) { - auto projectFileLocation = raco::utils::u8path(path); +core::Project* python_add_external_project(const std::string& path) { + auto projectFileLocation = utils::u8path(path); projectFileLocation = projectFileLocation.normalizedAbsolutePath(app->activeProjectFolder()); - raco::core::LoadContext loadContext; + core::LoadContext loadContext; loadContext.featureLevel = app->activeRaCoProject().project()->featureLevel(); loadContext.pathStack.emplace_back(app->activeRaCoProject().project()->currentPath()); auto* project = app->externalProjects()->addExternalProject(projectFileLocation.string(), loadContext); @@ -291,9 +294,9 @@ raco::core::Project* python_add_external_project(const std::string& path) { py::object python_add_external_references(const std::string& path, const std::vector& types) { auto* project = python_add_external_project(path); if (project == nullptr) { - return py::cast(std::vector()); + return py::cast(std::vector()); } - std::vector editorObjects; + std::vector editorObjects; for (const auto& type : types) { for (const auto& item : project->instances()) { if (item->getTypeDescription().typeName == type) { @@ -309,9 +312,9 @@ py::object python_add_external_references(const std::string& path, const std::ve return py::cast(result); } -py::object getPropertyChildProperties(const raco::core::PropertyDescriptor& desc) { +py::object getPropertyChildProperties(const core::PropertyDescriptor& desc) { checkProperty(desc); - auto handle = raco::core::ValueHandle(desc); + auto handle = core::ValueHandle(desc); std::vector propNames; if (handle.hasSubstructure()) { for (size_t index = 0; index < handle.size(); index++) { @@ -321,12 +324,12 @@ py::object getPropertyChildProperties(const raco::core::PropertyDescriptor& desc return py::cast(propNames); } -py::object getObjectChildProperties(raco::core::SEditorObject obj) { +py::object getObjectChildProperties(core::SEditorObject obj) { checkObject(obj); std::vector propNames; for (size_t index = 0; index < obj->size(); index++) { - if (!obj->get(index)->query()) { - auto anno = obj->get(index)->query(); + if (!obj->get(index)->query()) { + auto anno = obj->get(index)->query(); if (!anno || *anno->featureLevel_ <= app->activeRaCoProject().project()->featureLevel()) { propNames.emplace_back(obj->name(index)); } @@ -335,11 +338,11 @@ py::object getObjectChildProperties(raco::core::SEditorObject obj) { return py::cast(propNames); } -std::vector getTags(raco::core::SEditorObject obj, std::string tagPropertyName) { - raco::core::PropertyDescriptor desc(obj, {tagPropertyName}); +std::vector getTags(core::SEditorObject obj, std::string tagPropertyName) { + core::PropertyDescriptor desc(obj, {tagPropertyName}); checkHiddenProperty(desc); - raco::core::ValueHandle handle(desc); - if (handle.query() || handle.query()) { + core::ValueHandle handle(desc); + if (handle.query() || handle.query()) { return handle.constValueRef()->asTable().asVector(); } else { throw std::runtime_error(fmt::format("Property '{}' is not a tag container.", desc.getPropertyPath())); @@ -347,11 +350,11 @@ std::vector getTags(raco::core::SEditorObject obj, std::string tagP return std::vector(); } -void setTags(raco::core::SEditorObject obj, std::vector tags, std::string tagPropertyName) { - raco::core::PropertyDescriptor desc(obj, {tagPropertyName}); +void setTags(core::SEditorObject obj, std::vector tags, std::string tagPropertyName) { + core::PropertyDescriptor desc(obj, {tagPropertyName}); checkHiddenProperty(desc); - raco::core::ValueHandle handle(desc); - if (handle.query() || handle.query()) { + core::ValueHandle handle(desc); + if (handle.query() || handle.query()) { app->activeRaCoProject().commandInterface()->setTags(handle, tags); app->doOneLoop(); } else { @@ -359,6 +362,26 @@ void setTags(raco::core::SEditorObject obj, std::vector tags, std:: } } +class CompositeCommand { +public: + CompositeCommand(const std::string& description) : description_(description) {} + + void enter() { + app->activeRaCoProject().undoStack()->beginCompositeCommand(); + LOG_DEBUG(log_system::PYTHON, "Being composite command '{}'.", description_); + } + + bool exit(std::optional ex_type, std::optional ex_value, std::optional traceback) { + bool haveException = ex_type.has_value(); + app->activeRaCoProject().undoStack()->endCompositeCommand(description_, haveException); + LOG_DEBUG(log_system::PYTHON, "End composite command '{}'. Exception = {}", description_, haveException); + return false; + } + +private: + std::string description_; +}; + } // namespace PYBIND11_EMBEDDED_MODULE(raco_py_io, m) { @@ -503,7 +526,9 @@ PYBIND11_EMBEDDED_MODULE(raco, m) { .value("RGBA16F", ERenderBufferFormat::RGBA16F) .value("RGBA32F", ERenderBufferFormat::RGBA32F) + .value("Depth16", ERenderBufferFormat::Depth16) .value("Depth24", ERenderBufferFormat::Depth24) + .value("Depth32", ERenderBufferFormat::Depth32) .value("Depth24_Stencil8", ERenderBufferFormat::Depth24_Stencil8); py::enum_(m, "ERenderLayerOrder") @@ -539,10 +564,16 @@ PYBIND11_EMBEDDED_MODULE(raco, m) { m.def("load", [](std::string path) { + if (app->activeRaCoProject().undoStack()->depth() > 0) { + throw std::runtime_error("Can't load project inside composite command."); + } python_load_project(path, -1); }); m.def("load", [](std::string path, int featureLevel) { + if (app->activeRaCoProject().undoStack()->depth() > 0) { + throw std::runtime_error("Can't load project inside composite command."); + } python_load_project(path, featureLevel); }); @@ -550,7 +581,9 @@ PYBIND11_EMBEDDED_MODULE(raco, m) { if (app->isRunningInUI()) { throw std::runtime_error(fmt::format("Can not reset project: project-switching Python functions currently not allowed in UI.")); } - + if (app->activeRaCoProject().undoStack()->depth() > 0) { + throw std::runtime_error("Can't reset project inside composite command."); + } app->switchActiveRaCoProject(QString(), {}, false); }); @@ -558,11 +591,17 @@ PYBIND11_EMBEDDED_MODULE(raco, m) { if (app->isRunningInUI()) { throw std::runtime_error(fmt::format("Can not reset project: project-switching Python functions currently not allowed in UI.")); } - + if (app->activeRaCoProject().undoStack()->depth() > 0) { + throw std::runtime_error("Can't reset project inside composite command."); + } app->switchActiveRaCoProject(QString(), {}, false, featureLevel); - }); +}); m.def("save", [](std::string path) { + if (app->activeRaCoProject().undoStack()->depth() > 0) { + throw std::runtime_error("Can't save project inside composite command."); + } + if (app->canSaveActiveProject()) { std::string errorMsg; if (!app->activeRaCoProject().saveAs(QString::fromStdString(path), errorMsg, app->activeProjectPath().empty())) { @@ -575,7 +614,10 @@ PYBIND11_EMBEDDED_MODULE(raco, m) { m.def("save", [](std::string path, bool setNewIDs) { if (app->isRunningInUI()) { - throw std::runtime_error(fmt::format("Can not load project: project-switching Python functions currently not allowed in UI.")); + throw std::runtime_error(fmt::format("Can not save project: project-switching Python functions currently not allowed in UI.")); + } + if (app->activeRaCoProject().undoStack()->depth() > 0) { + throw std::runtime_error("Can't save project inside composite command."); } if (app->canSaveActiveProject()) { @@ -611,22 +653,22 @@ PYBIND11_EMBEDDED_MODULE(raco, m) { m.def("externalProjects", []() { py::list externalPaths; for (auto const& [id, info] : app->activeRaCoProject().project()->externalProjectsMap()) { - auto absPath = raco::utils::u8path(info.path).normalizedAbsolutePath(app->activeRaCoProject().project()->currentFolder()); + auto absPath = utils::u8path(info.path).normalizedAbsolutePath(app->activeRaCoProject().project()->currentFolder()); externalPaths.append(py::cast(absPath.string())); } return externalPaths; }); - m.def("export", [](std::string ramsesExport, std::string logicExport, bool compress) { + m.def("export", [](std::string ramsesExport, bool compress) { std::string outError; - if (!app->exportProject(ramsesExport, logicExport, compress, outError)) { + if (!app->exportProject(ramsesExport, compress, outError)) { throw std::runtime_error(fmt::format(("Export failed: {}", outError))); } }); - m.def("export", [](std::string ramsesExport, std::string logicExport, bool compress, raco::application::ELuaSavingMode luaSavingMode) { + m.def("export", [](std::string ramsesExport, bool compress, raco::application::ELuaSavingMode luaSavingMode) { std::string outError; - if (!app->exportProject(ramsesExport, logicExport, compress, outError, false, luaSavingMode)) { + if (!app->exportProject(ramsesExport, compress, outError, false, luaSavingMode)) { throw std::runtime_error(fmt::format(("Export failed: {}", outError))); } }); @@ -639,7 +681,7 @@ PYBIND11_EMBEDDED_MODULE(raco, m) { python_import_gltf(path, nullptr); }); - m.def("importGLTF", [](const std::string path, const raco::core::SEditorObject parent) { + m.def("importGLTF", [](const std::string path, const core::SEditorObject parent) { checkObject(parent); python_import_gltf(path, parent); }); @@ -656,66 +698,72 @@ PYBIND11_EMBEDDED_MODULE(raco, m) { return python_add_external_references(path, {type}); }); - py::class_(m, "PropertyDescriptor") - .def("__repr__", [](const raco::core::PropertyDescriptor& desc) { - auto handle = raco::core::ValueHandle(desc); + py::class_(m, "PropertyDescriptor") + .def("__repr__", [](const core::PropertyDescriptor& desc) { + auto handle = core::ValueHandle(desc); return fmt::format("", handle.constValueRef()->baseTypeName(), desc.getPropertyPath()); }) - .def("__dir__", [](const raco::core::PropertyDescriptor& desc) -> py::object { + .def("__dir__", [](const core::PropertyDescriptor& desc) -> py::object { return getPropertyChildProperties(desc); }) - .def("keys", [](const raco::core::PropertyDescriptor& desc) -> py::object { + .def("keys", [](const core::PropertyDescriptor& desc) -> py::object { return getPropertyChildProperties(desc); }) - .def("__getattr__", [](const raco::core::PropertyDescriptor& desc, const std::string& name) -> py::object { + .def("__getattr__", [](const core::PropertyDescriptor& desc, const std::string& name) -> py::object { auto childDesc = desc.child(name); checkProperty(childDesc); return py::cast(childDesc); }) - .def("__setattr__", [](const raco::core::PropertyDescriptor& desc, const std::string& name, py::object value) { + .def("__setattr__", [](const core::PropertyDescriptor& desc, const std::string& name, py::object value) { python_set_value(desc.child(name), value); }) - .def("__getitem__", [](const raco::core::PropertyDescriptor& desc, const std::string& name) -> py::object { + .def("__getitem__", [](const core::PropertyDescriptor& desc, const std::string& name) -> py::object { auto childDesc = desc.child(name); checkProperty(childDesc); return py::cast(childDesc); }) - .def("__setitem__", [](const raco::core::PropertyDescriptor& desc, const std::string& name, py::object value) { + .def("__setitem__", [](const core::PropertyDescriptor& desc, const std::string& name, py::object value) { python_set_value(desc.child(name), value); }) .def(py::self == py::self) - .def("object", [](const raco::core::PropertyDescriptor& desc) -> py::object { + .def("object", [](const core::PropertyDescriptor& desc) -> py::object { checkObject(desc.object()); return py::cast(desc.object()); }) // TODO get parent property - .def("typeName", [](const raco::core::PropertyDescriptor& desc) -> py::object { + .def("typeName", [](const core::PropertyDescriptor& desc) -> py::object { + checkProperty(desc); + return py::cast(core::ValueHandle(desc).constValueRef()->baseTypeName()); + }) + .def("propName", [](const core::PropertyDescriptor& desc) -> py::object { checkProperty(desc); - return py::cast(raco::core::ValueHandle(desc).constValueRef()->baseTypeName()); + return py::cast(core::ValueHandle(desc).getPropName()); }) - .def("propName", [](const raco::core::PropertyDescriptor& desc) -> py::object { + .def("hasSubstructure", [](const core::PropertyDescriptor& desc) -> py::object { checkProperty(desc); - return py::cast(raco::core::ValueHandle(desc).getPropName()); + return py::cast(core::ValueHandle(desc).hasSubstructure()); }) - .def("hasSubstructure", [](const raco::core::PropertyDescriptor& desc) -> py::object { + .def("isReadOnly", [](const core::PropertyDescriptor& desc) { checkProperty(desc); - return py::cast(raco::core::ValueHandle(desc).hasSubstructure()); + return core::Queries::isReadOnly(*app->activeRaCoProject().project(), core::ValueHandle(desc)); }) - .def("isReadOnly", [](const raco::core::PropertyDescriptor& desc) { + .def("isValidLinkStart", [](const core::PropertyDescriptor& desc) { checkProperty(desc); - return raco::core::Queries::isReadOnly(*app->activeRaCoProject().project(), raco::core::ValueHandle(desc)); + return core::Queries::isValidLinkStart(core::ValueHandle(desc)); }) - .def("isValidLinkStart", [](const raco::core::PropertyDescriptor& desc) { + .def("isValidLinkEnd", [](const core::PropertyDescriptor& desc) { checkProperty(desc); - return raco::core::Queries::isValidLinkStart(raco::core::ValueHandle(desc)); + return core::Queries::isValidLinkEnd(*app->activeRaCoProject().project(), core::ValueHandle(desc)); }) - .def("isValidLinkEnd", [](const raco::core::PropertyDescriptor& desc) { + .def("resize", [](const core::PropertyDescriptor& desc, size_t newSize) { checkProperty(desc); - return raco::core::Queries::isValidLinkEnd(*app->activeRaCoProject().project(), raco::core::ValueHandle(desc)); + core::ValueHandle handle{desc}; + app->activeRaCoProject().commandInterface()->resizeArray(handle, newSize); + app->doOneLoop(); }) - .def("value", [](const raco::core::PropertyDescriptor& desc) -> py::object { + .def("value", [](const core::PropertyDescriptor& desc) -> py::object { checkProperty(desc); - auto handle = raco::core::ValueHandle(desc); + auto handle = core::ValueHandle(desc); if (!handle.hasSubstructure()) { return python_get_scalar_value(handle); } else { @@ -723,127 +771,117 @@ PYBIND11_EMBEDDED_MODULE(raco, m) { } }); - py::class_(m, "EditorObject") - .def("__repr__", [](const raco::core::EditorObject& obj) { + py::class_(m, "EditorObject") + .def("__repr__", [](const core::EditorObject& obj) { return fmt::format("<{}: '{}'>", obj.getTypeDescription().typeName, obj.objectName()); }) - .def("__dir__", [](raco::core::SEditorObject obj) { + .def("__dir__", [](core::SEditorObject obj) { return getObjectChildProperties(obj); }) - .def("keys", [](raco::core::SEditorObject obj) { + .def("keys", [](core::SEditorObject obj) { return getObjectChildProperties(obj); }) - .def("__getattr__", [](raco::core::SEditorObject obj, std::string name) -> py::object { - raco::core::PropertyDescriptor desc(obj, {name}); + .def("__getattr__", [](core::SEditorObject obj, std::string name) -> py::object { + core::PropertyDescriptor desc(obj, {name}); checkProperty(desc); return py::cast(desc); }) - .def("__setattr__", [](raco::core::SEditorObject obj, std::string name, py::object value) { + .def("__setattr__", [](core::SEditorObject obj, std::string name, py::object value) { python_set_value({obj, {name}}, value); }) - .def("__getitem__", [](raco::core::SEditorObject obj, std::string name) -> py::object { - raco::core::PropertyDescriptor desc(obj, {name}); + .def("__getitem__", [](core::SEditorObject obj, std::string name) -> py::object { + core::PropertyDescriptor desc(obj, {name}); checkProperty(desc); return py::cast(desc); }) - .def("__setitem__", [](raco::core::SEditorObject obj, std::string name, py::object value) { + .def("__setitem__", [](core::SEditorObject obj, std::string name, py::object value) { python_set_value({obj, {name}}, value); }) - .def("typeName", [](raco::core::SEditorObject obj) { + .def("typeName", [](core::SEditorObject obj) { checkObject(obj); return obj->getTypeDescription().typeName; }) - .def("children", [](raco::core::SEditorObject obj) { + .def("children", [](core::SEditorObject obj) { checkObject(obj); - return obj->children_->asVector(); + return obj->children_->asVector(); }) - .def("isReadOnly", [](raco::core::SEditorObject obj) { + .def("isReadOnly", [](core::SEditorObject obj) { checkObject(obj); - return raco::core::Queries::isReadOnly(obj); + return core::Queries::isReadOnly(obj); }) - .def("isResource", [](raco::core::SEditorObject obj) { + .def("isResource", [](core::SEditorObject obj) { checkObject(obj); - return raco::core::Queries::isResource(obj); + return core::Queries::isResource(obj); }) - .def("isExternalReference", [](raco::core::SEditorObject obj) { + .def("isExternalReference", [](core::SEditorObject obj) { checkObject(obj); - return obj->query() != nullptr; + return obj->query() != nullptr; }) - .def("getPrefab", [](raco::core::SEditorObject obj) -> py::object { + .def("getPrefab", [](core::SEditorObject obj) -> py::object { checkObject(obj); - return py::cast(raco::core::SEditorObject(raco::core::PrefabOperations::findContainingPrefab(obj))); + return py::cast(core::SEditorObject(core::PrefabOperations::findContainingPrefab(obj))); }) - .def("getPrefabInstance", [](raco::core::SEditorObject obj) -> py::object { + .def("getPrefabInstance", [](core::SEditorObject obj) -> py::object { checkObject(obj); - return py::cast(raco::core::SEditorObject(raco::core::PrefabOperations::findContainingPrefabInstance(obj))); + return py::cast(core::SEditorObject(core::PrefabOperations::findContainingPrefabInstance(obj))); }) - .def("getOuterContainingPrefabInstance", [](raco::core::SEditorObject obj) -> py::object { + .def("getOuterContainingPrefabInstance", [](core::SEditorObject obj) -> py::object { checkObject(obj); - return py::cast(raco::core::SEditorObject(raco::core::PrefabOperations::findOuterContainingPrefabInstance(obj))); + return py::cast(core::SEditorObject(core::PrefabOperations::findOuterContainingPrefabInstance(obj))); }) - .def("parent", [](raco::core::SEditorObject obj) { + .def("parent", [](core::SEditorObject obj) { checkObject(obj); return py::cast(obj->getParent()); }) - .def("objectID", [](raco::core::SEditorObject obj) { + .def("objectID", [](core::SEditorObject obj) { checkObject(obj); return py::cast(obj->objectID()); }) - .def("metadata", [](raco::core::SEditorObject obj) { - checkObject(obj); - if (obj->isType()) { - auto metaData = obj->as()->metaData_; - if (!metaData.empty()) { - return py::cast(metaData); - } - } - return py::cast(nullptr); - }) - .def("getTags", [](raco::core::SEditorObject obj) -> std::vector { + .def("getTags", [](core::SEditorObject obj) -> std::vector { return getTags(obj, "tags"); }) - .def("setTags", [](raco::core::SEditorObject obj, std::vector tags) { + .def("setTags", [](core::SEditorObject obj, std::vector tags) { setTags(obj, tags, "tags"); }) - .def("getMaterialFilterTags", [](raco::core::SEditorObject obj) -> std::vector { + .def("getMaterialFilterTags", [](core::SEditorObject obj) -> std::vector { return getTags(obj, "materialFilterTags"); }) - .def("setMaterialFilterTags", [](raco::core::SEditorObject obj, std::vector tags) { + .def("setMaterialFilterTags", [](core::SEditorObject obj, std::vector tags) { setTags(obj, tags, "materialFilterTags"); }) - .def("getUserTags", [](raco::core::SEditorObject obj) -> std::vector { + .def("getUserTags", [](core::SEditorObject obj) -> std::vector { return getTags(obj, "userTags"); }) - .def("setUserTags", [](raco::core::SEditorObject obj, std::vector tags) { + .def("setUserTags", [](core::SEditorObject obj, std::vector tags) { setTags(obj, tags, "userTags"); }) - .def("getRenderableTags", [](raco::core::SEditorObject obj) -> std::vector> { - checkTypedObject(obj); - raco::core::ValueHandle handle(obj, &raco::user_types::RenderLayer::renderableTags_); + .def("getRenderableTags", [](core::SEditorObject obj) -> std::vector> { + checkTypedObject(obj); + core::ValueHandle handle(obj, &user_types::RenderLayer::renderableTags_); std::vector> renderables; for (size_t index = 0; index < handle.size(); index++) { renderables.emplace_back(handle[index].getPropName(), handle[index].asInt()); } return renderables; }) - .def("setRenderableTags", [](raco::core::SEditorObject obj, std::vector> renderables) { - checkTypedObject(obj); - raco::core::ValueHandle handle(obj, &raco::user_types::RenderLayer::renderableTags_); + .def("setRenderableTags", [](core::SEditorObject obj, std::vector> renderables) { + checkTypedObject(obj); + core::ValueHandle handle(obj, &user_types::RenderLayer::renderableTags_); if (handle) { app->activeRaCoProject().commandInterface()->setRenderableTags(handle, renderables); app->doOneLoop(); } }); - py::class_(m, "LinkDescriptor") - .def("__repr__", [](const raco::core::LinkDescriptor& desc) { + py::class_(m, "LinkDescriptor") + .def("__repr__", [](const core::LinkDescriptor& desc) { return fmt::format("", desc.start.getPropertyPath(), desc.end.getPropertyPath(), desc.isValid, desc.isWeak); }) .def(py::self == py::self) - .def_readonly("start", &raco::core::LinkDescriptor::start) - .def_readonly("end", &raco::core::LinkDescriptor::end) - .def_readonly("valid", &raco::core::LinkDescriptor::isValid) - .def_readonly("weak", &raco::core::LinkDescriptor::isWeak); + .def_readonly("start", &core::LinkDescriptor::start) + .def_readonly("end", &core::LinkDescriptor::end) + .def_readonly("valid", &core::LinkDescriptor::isValid) + .def_readonly("weak", &core::LinkDescriptor::isWeak); m.def("instances", []() { return app->activeRaCoProject().project()->instances(); @@ -855,23 +893,23 @@ PYBIND11_EMBEDDED_MODULE(raco, m) { return object; }); - m.def("delete", [](raco::core::SEditorObject obj) { + m.def("delete", [](core::SEditorObject obj) { auto result = app->activeRaCoProject().commandInterface()->deleteObjects({obj}); app->doOneLoop(); return result; }); - m.def("delete", [](std::vector objects) { + m.def("delete", [](std::vector objects) { auto result = app->activeRaCoProject().commandInterface()->deleteObjects(objects); app->doOneLoop(); return result; }); - m.def("moveScenegraph", [](raco::core::SEditorObject object, raco::core::SEditorObject newParent) { + m.def("moveScenegraph", [](core::SEditorObject object, core::SEditorObject newParent) { app->activeRaCoProject().commandInterface()->moveScenegraphChildren({object}, newParent); app->doOneLoop(); }); - m.def("moveScenegraph", [](raco::core::SEditorObject object, raco::core::SEditorObject newParent, int insertBeforeIndex) { + m.def("moveScenegraph", [](core::SEditorObject object, core::SEditorObject newParent, int insertBeforeIndex) { app->activeRaCoProject().commandInterface()->moveScenegraphChildren({object}, newParent, insertBeforeIndex); app->doOneLoop(); }); @@ -885,31 +923,31 @@ PYBIND11_EMBEDDED_MODULE(raco, m) { return pyLinks; }); - m.def("getLink", [](const raco::core::PropertyDescriptor& end) -> py::object { + m.def("getLink", [](const core::PropertyDescriptor& end) -> py::object { checkObject(end.object()); - if (auto link = raco::core::Queries::getLink(*app->activeRaCoProject().project(), end)) { + if (auto link = core::Queries::getLink(*app->activeRaCoProject().project(), end)) { return py::cast(link->descriptor()); } return py::none(); }); - m.def("addLink", [](const raco::core::PropertyDescriptor& start, const raco::core::PropertyDescriptor& end) -> py::object { - if (auto newLink = app->activeRaCoProject().commandInterface()->addLink(raco::core::ValueHandle(start), raco::core::ValueHandle(end))) { + m.def("addLink", [](const core::PropertyDescriptor& start, const core::PropertyDescriptor& end) -> py::object { + if (auto newLink = app->activeRaCoProject().commandInterface()->addLink(core::ValueHandle(start), core::ValueHandle(end))) { app->doOneLoop(); return py::cast(newLink->descriptor()); } return py::none(); }); - m.def("addLink", [](const raco::core::PropertyDescriptor& start, const raco::core::PropertyDescriptor& end, bool isWeak) -> py::object { - if (auto newLink = app->activeRaCoProject().commandInterface()->addLink(raco::core::ValueHandle(start), raco::core::ValueHandle(end), isWeak)) { + m.def("addLink", [](const core::PropertyDescriptor& start, const core::PropertyDescriptor& end, bool isWeak) -> py::object { + if (auto newLink = app->activeRaCoProject().commandInterface()->addLink(core::ValueHandle(start), core::ValueHandle(end), isWeak)) { app->doOneLoop(); return py::cast(newLink->descriptor()); } return py::none(); }); - m.def("removeLink", [](const raco::core::PropertyDescriptor& end) { + m.def("removeLink", [](const core::PropertyDescriptor& end) { app->activeRaCoProject().commandInterface()->removeLink(end); app->doOneLoop(); }); @@ -918,17 +956,17 @@ PYBIND11_EMBEDDED_MODULE(raco, m) { return py::cast(app->activeRaCoProject().project()->getInstanceByID(id)); }); - py::class_(m, "ErrorItem") - .def("__repr__", [](const raco::core::ErrorItem& errorItem) { + py::class_(m, "ErrorItem") + .def("__repr__", [](const core::ErrorItem& errorItem) { auto pyobj = py::cast(errorItem).attr("handle")(); std::string handleRepr = py::repr(pyobj); return fmt::format("", errorItem.category(), errorItem.level(), errorItem.message(), handleRepr); }) - .def("category", &raco::core::ErrorItem::category) - .def("level", &raco::core::ErrorItem::level) - .def("message", &raco::core::ErrorItem::message) - .def("handle", [](const raco::core::ErrorItem& errorItem) -> py::object { - if (errorItem.valueHandle() == raco::core::ValueHandle()) { + .def("category", &core::ErrorItem::category) + .def("level", &core::ErrorItem::level) + .def("message", &core::ErrorItem::message) + .def("handle", [](const core::ErrorItem& errorItem) -> py::object { + if (errorItem.valueHandle() == core::ValueHandle()) { // Project global errors -> return None return py::none(); } else if (errorItem.valueHandle().isObject()) { @@ -947,7 +985,7 @@ PYBIND11_EMBEDDED_MODULE(raco, m) { py::list pyErrorItems; for (const auto& [object, objErrors] : app->activeRaCoProject().errors()->getAllErrors()) { for (const auto& [handle, error] : objErrors) { - pyErrorItems.append(raco::core::ErrorItem(error)); + pyErrorItems.append(core::ErrorItem(error)); } } return pyErrorItems; @@ -963,6 +1001,11 @@ PYBIND11_EMBEDDED_MODULE(raco, m) { throw std::runtime_error(fmt::format("Can't resolve uri to absolute path: '{}' is not a uri property.", desc.getPropertyPath())); } }); + + py::class_(m, "compositeCommand") + .def(py::init()) + .def("__enter__", &CompositeCommand::enter) + .def("__exit__", &CompositeCommand::exit); } namespace raco::python_api { @@ -972,7 +1015,7 @@ bool preparePythonEnvironment(std::wstring argv0, const std::vector& pythonSearchPaths, const std::vector& pos_argv_cp) { +PythonRunStatus runPythonScript(application::RaCoApplication* app, const std::wstring& applicationPath, const std::string& pythonScriptPath, const std::vector& pythonSearchPaths, const std::vector& pos_argv_cp) { currentRunStatus.stdOutBuffer.clear(); currentRunStatus.stdErrBuffer.clear(); - if (raco::python_api::preparePythonEnvironment(applicationPath, pythonSearchPaths)) { + if (python_api::preparePythonEnvironment(applicationPath, pythonSearchPaths)) { py::scoped_interpreter pyGuard{true, static_cast(pos_argv_cp.size()), pos_argv_cp.data()}; - raco::python_api::setup(app); + python_api::setup(app); currentRunStatus.stdOutBuffer.append(fmt::format("running python script {}\n\n", pythonScriptPath)); try { py::eval_file(pythonScriptPath); diff --git a/components/libPythonAPI/tests/PythonAPI_Simple_test.cpp b/components/libPythonAPI/tests/PythonAPI_Simple_test.cpp index c39c7d6f..b978ed18 100644 --- a/components/libPythonAPI/tests/PythonAPI_Simple_test.cpp +++ b/components/libPythonAPI/tests/PythonAPI_Simple_test.cpp @@ -20,22 +20,24 @@ #include "testing/RaCoApplicationTest.h" -#include "ramses_adaptor/SceneBackend.h" #include "application/RaCoApplication.h" -#include "ramses_base/HeadlessEngineBackend.h" #include "python_api/PythonAPI.h" +#include "ramses_adaptor/SceneBackend.h" +#include "ramses_base/HeadlessEngineBackend.h" +#include "testing/TestUtil.h" + +#include "user_types/Node.h" namespace py = pybind11; using raco::application::RaCoApplication; - class PythonTest : public RaCoApplicationTest { public: PythonTest() : RaCoApplicationTest() { - raco::python_api::preparePythonEnvironment(QCoreApplication::applicationFilePath().toStdWString(), {}, true); + python_api::preparePythonEnvironment(QCoreApplication::applicationFilePath().toStdWString(), {}, true); pyGuard = std::make_unique(); - raco::python_api::setup(&application); + python_api::setup(&application); } std::unique_ptr pyGuard; @@ -51,7 +53,7 @@ print("Hello world from Python!") TEST_F(PythonTest, export_empty) { py::exec(R"( import raco -raco.export("empty.ramses", "empty.rlogic", False) +raco.export("empty.ramses", False) )"); } @@ -59,7 +61,7 @@ TEST_F(PythonTest, export_single) { py::exec(R"( import raco raco.load(")" + (test_path() / "example_scene.rca").string() + R"(") -raco.export("test.ramses", "test.rlogic", False) +raco.export("test.ramses", False) )"); } @@ -67,15 +69,197 @@ TEST_F(PythonTest, export_multi) { py::exec(R"( import raco raco.load(")" + (test_path() / "example_scene.rca").string() + R"(") -raco.export("test-duck.ramses", "test-duck.rlogic", False) +raco.export("test-duck.ramses", False) raco.load(")" + (test_path() / "empty.rca").string() + R"(") -raco.export("test-empty.ramses", "test-empty.rlogic", False) +raco.export("test-empty.ramses", False) )"); } TEST_F(PythonTest, exception_throw_python) { EXPECT_THROW(py::exec(R"( raise RunTimeError("something wrong here!") -)"), std::runtime_error); +)"), + std::runtime_error); +} + +TEST_F(PythonTest, separate_commands) { + auto start_index = application.activeRaCoProject().undoStack()->getIndex(); + py::exec(R"( +import raco +raco.create("Node", "node_1") +raco.create("Node", "node_2") +)"); + auto end_index = application.activeRaCoProject().undoStack()->getIndex(); + EXPECT_EQ(end_index - start_index, 2); +} + +TEST_F(PythonTest, composite_command) { + auto start_index = application.activeRaCoProject().undoStack()->getIndex(); + py::exec(R"( +import raco +with raco.compositeCommand("test"): + raco.create("Node", "node_1") + raco.create("Node", "node_2") +)"); + auto end_index = application.activeRaCoProject().undoStack()->getIndex(); + EXPECT_EQ(end_index - start_index, 1); +} + +TEST_F(PythonTest, composite_command_nested) { + auto start_index = application.activeRaCoProject().undoStack()->getIndex(); + py::exec(R"( +import raco +with raco.compositeCommand("outer"): + with raco.compositeCommand("inner"): + raco.create("Node", "node_1") + raco.create("Node", "node_2") +)"); + auto end_index = application.activeRaCoProject().undoStack()->getIndex(); + EXPECT_EQ(end_index - start_index, 1); +} + +TEST_F(PythonTest, composite_command_exception) { + auto start_index = application.activeRaCoProject().undoStack()->getIndex(); + try { + py::exec(R"( +import raco +with raco.compositeCommand("test"): + raco.create("Node", "node_1") + raco.create("Node", "node_2") + raise RuntimeError("error") +)"); + } catch (std::exception&) { + } + auto end_index = application.activeRaCoProject().undoStack()->getIndex(); + EXPECT_EQ(end_index - start_index, 0); +} + +TEST_F(PythonTest, composite_command_nested_exception_inner) { + auto start_index = application.activeRaCoProject().undoStack()->getIndex(); + try { + py::exec(R"( +import raco +with raco.compositeCommand("outer"): + with raco.compositeCommand("inner"): + raco.create("Node", "node_1") + raise RuntimeError("error") + raco.create("Node", "node_2") +)"); + } catch (std::exception&) { + } + auto end_index = application.activeRaCoProject().undoStack()->getIndex(); + EXPECT_EQ(end_index - start_index, 0); } + +TEST_F(PythonTest, composite_command_nested_exception_outer) { + auto start_index = application.activeRaCoProject().undoStack()->getIndex(); + try { + py::exec(R"( +import raco +with raco.compositeCommand("outer"): + with raco.compositeCommand("inner"): + raco.create("Node", "node_1") + raco.create("Node", "node_2") + raise RuntimeError("error") +)"); + } catch (std::exception&) { + } + auto end_index = application.activeRaCoProject().undoStack()->getIndex(); + EXPECT_EQ(end_index - start_index, 0); +} + +TEST_F(PythonTest, composite_command_nested_exception_inner_caught) { + auto start_index = application.activeRaCoProject().undoStack()->getIndex(); + try { + py::exec(R"( +import raco +with raco.compositeCommand("outer"): + try: + with raco.compositeCommand("inner"): + raco.create("Node", "node_1") + raise RuntimeError("error") + except: + pass + raco.create("Node", "node_2") +)"); + } catch (std::exception&) { + } + auto end_index = application.activeRaCoProject().undoStack()->getIndex(); + + EXPECT_EQ(end_index - start_index, 1); + EXPECT_TRUE(raco::select(project().instances(), "node_1") != nullptr); + EXPECT_TRUE(raco::select(project().instances(), "node_2") != nullptr); +} + +TEST_F(PythonTest, composite_command_fail_reset) { + std::string script = R"( +import raco +with raco.compositeCommand("test"): + raco.reset() +)"; + auto start_index = application.activeRaCoProject().undoStack()->getIndex(); + EXPECT_THROW(py::exec(script), std::runtime_error); + auto end_index = application.activeRaCoProject().undoStack()->getIndex(); + EXPECT_EQ(start_index, end_index); +} + +TEST_F(PythonTest, composite_command_fail_reset_with_feature_level) { + std::string script = R"( +import raco +with raco.compositeCommand("test"): + raco.reset(1) +)"; + auto start_index = application.activeRaCoProject().undoStack()->getIndex(); + EXPECT_THROW(py::exec(script), std::runtime_error); + auto end_index = application.activeRaCoProject().undoStack()->getIndex(); + EXPECT_EQ(start_index, end_index); +} + +TEST_F(PythonTest, composite_command_fail_load) { + std::string script = R"( +import raco +with raco.compositeCommand("test"): + raco.load("nosuchfile") +)"; + auto start_index = application.activeRaCoProject().undoStack()->getIndex(); + EXPECT_THROW(py::exec(script), std::runtime_error); + auto end_index = application.activeRaCoProject().undoStack()->getIndex(); + EXPECT_EQ(start_index, end_index); +} + +TEST_F(PythonTest, composite_command_fail_load_with_feature_level) { + std::string script = R"( +import raco +with raco.compositeCommand("test"): + raco.load("nosuchfile", 1) +)"; + auto start_index = application.activeRaCoProject().undoStack()->getIndex(); + EXPECT_THROW(py::exec(script), std::runtime_error); + auto end_index = application.activeRaCoProject().undoStack()->getIndex(); + EXPECT_EQ(start_index, end_index); +} + +TEST_F(PythonTest, composite_command_fail_save) { + std::string script = R"( +import raco +with raco.compositeCommand("test"): + raco.save("nosuchfile") +)"; + auto start_index = application.activeRaCoProject().undoStack()->getIndex(); + EXPECT_THROW(py::exec(script), std::runtime_error); + auto end_index = application.activeRaCoProject().undoStack()->getIndex(); + EXPECT_EQ(start_index, end_index); +} + +TEST_F(PythonTest, composite_command_fail_save_with_newids) { + std::string script = R"( +import raco +with raco.compositeCommand("test"): + raco.save("nosuchfile", True) +)"; + auto start_index = application.activeRaCoProject().undoStack()->getIndex(); + EXPECT_THROW(py::exec(script), std::runtime_error); + auto end_index = application.activeRaCoProject().undoStack()->getIndex(); + EXPECT_EQ(start_index, end_index); +} \ No newline at end of file diff --git a/components/libRamsesBase/CMakeLists.txt b/components/libRamsesBase/CMakeLists.txt index 1901b082..54718d3d 100644 --- a/components/libRamsesBase/CMakeLists.txt +++ b/components/libRamsesBase/CMakeLists.txt @@ -11,8 +11,8 @@ If a copy of the MPL was not distributed with this file, You can obtain one at h raco_find_qt_components(Core) add_library(libLodepng - ../../third_party/ramses-logic/external/ramses/external/lodepng/lodepng.h - ../../third_party/ramses-logic/external/ramses/external/lodepng/lodepng.cpp + ../../third_party/ramses/external/lodepng/lodepng.h + ../../third_party/ramses/external/lodepng/lodepng.cpp ) set_target_properties(libLodepng PROPERTIES FOLDER third_party/libLodepng) @@ -23,11 +23,20 @@ add_library(libRamsesBase include/ramses_base/CoreInterfaceImpl.h src/ramses_base/CoreInterfaceImpl.cpp include/ramses_base/EnumerationTranslations.h src/ramses_base/EnumerationTranslations.cpp include/ramses_base/HeadlessEngineBackend.h src/ramses_base/HeadlessEngineBackend.cpp - include/ramses_base/LogicEngine.h include/ramses_base/RamsesHandles.h include/ramses_base/RamsesFormatter.h include/ramses_base/Utils.h src/ramses_base/Utils.cpp + include/ramses_adaptor/AbstractSceneAdaptor.h src/ramses_adaptor/AbstractSceneAdaptor.cpp + include/ramses_adaptor/AbstractMeshAdaptor.h src/ramses_adaptor/AbstractMeshAdaptor.cpp + include/ramses_adaptor/AbstractMeshNodeAdaptor.h src/ramses_adaptor/AbstractMeshNodeAdaptor.cpp + include/ramses_adaptor/AbstractNodeAdaptor.h src/ramses_adaptor/AbstractNodeAdaptor.cpp + include/ramses_adaptor/AbstractObjectAdaptor.h src/ramses_adaptor/AbstractObjectAdaptor.cpp + include/ramses_adaptor/ClearDepthObject.h src/ramses_adaptor/ClearDepthObject.cpp + include/ramses_adaptor/InfiniteGrid.h src/ramses_adaptor/InfiniteGrid.cpp + include/ramses_adaptor/CameraController.h src/ramses_adaptor/CameraController.cpp + include/ramses_adaptor/Gizmos.h src/ramses_adaptor/Gizmos.cpp + include/ramses_adaptor/AnchorPointAdaptor.h src/ramses_adaptor/AnchorPointAdaptor.cpp include/ramses_adaptor/AnimationAdaptor.h src/ramses_adaptor/AnimationAdaptor.cpp include/ramses_adaptor/AnimationChannelAdaptor.h src/ramses_adaptor/AnimationChannelAdaptor.cpp @@ -35,6 +44,7 @@ add_library(libRamsesBase include/ramses_adaptor/BuildOptions.h include/ramses_adaptor/BlitPassAdaptor.h src/ramses_adaptor/BlitPassAdaptor.cpp include/ramses_adaptor/CubeMapAdaptor.h src/ramses_adaptor/CubeMapAdaptor.cpp + include/ramses_adaptor/DefaultRamsesObjects.h src/ramses_adaptor/DefaultRamsesObjects.cpp include/ramses_adaptor/Factories.h src/ramses_adaptor/Factories.cpp include/ramses_adaptor/LinkAdaptor.h src/ramses_adaptor/LinkAdaptor.cpp include/ramses_adaptor/LuaInterfaceAdaptor.h src/ramses_adaptor/LuaInterfaceAdaptor.cpp @@ -65,23 +75,25 @@ target_include_directories(libRamsesBase PUBLIC include/ PRIVATE - $ + $ ) enable_warnings_as_errors(libRamsesBase) +set_target_properties(libRamsesBase PROPERTIES AUTOMOC TRUE) + # At this point we don't know yet if we will link against ramses-client-only or ramses with renderer # thus we link against the ramses interfaces and ramses-logic-static which also links against ramses interfaces (see CMakeLists.txt in third_party folder) # The actuall dynamic ramses lib is linked by the headless executable (client-only) and preview widget (with renderer). target_link_libraries(libRamsesBase PUBLIC - ramses-client-api - ramses-framework-api - ramses-logic-api + raco::ramses-lib-client-only raco::UserTypes raco::Components + Qt5::Core PRIVATE raco::Utils raco::LogSystem + raco::MeshLoader libLodepng ) add_library(raco::RamsesBase ALIAS libRamsesBase) diff --git a/components/libRamsesBase/include/ramses_adaptor/AbstractMeshAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/AbstractMeshAdaptor.h new file mode 100644 index 00000000..b6963753 --- /dev/null +++ b/components/libRamsesBase/include/ramses_adaptor/AbstractMeshAdaptor.h @@ -0,0 +1,44 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "core/Context.h" +#include "ramses_adaptor/AbstractObjectAdaptor.h" +#include "components/DataChangeDispatcher.h" +#include "ramses_adaptor/utilities.h" +#include "user_types/Mesh.h" +#include + +namespace raco::ramses_adaptor { + +class SceneAdaptor; +using VertexDataMap = std::unordered_map; + +class AbstractMeshAdaptor final : public AbstractUserTypeObjectAdaptor { +public: + explicit AbstractMeshAdaptor(AbstractSceneAdaptor* sceneAdaptor, user_types::SMesh mesh); + + ramses_base::RamsesArrayResource indicesPtr(); + const VertexDataMap& vertexData() const; + const ramses_base::RamsesArrayBuffer triangleBuffer() const; + bool isValid(); + + bool sync() override; + +private: + VertexDataMap vertexDataMap_; + ramses_base::RamsesArrayResource indices_; + ramses_base::RamsesArrayBuffer triangleBuffer_; + core::FileChangeMonitor::UniqueListener meshFileChangeListener_; + components::Subscription subscription_; + components::Subscription nameSubscription_; +}; + +}; // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/include/ramses_adaptor/AbstractMeshNodeAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/AbstractMeshNodeAdaptor.h new file mode 100644 index 00000000..a19ce27e --- /dev/null +++ b/components/libRamsesBase/include/ramses_adaptor/AbstractMeshNodeAdaptor.h @@ -0,0 +1,75 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "ramses_adaptor/AbstractMeshAdaptor.h" +#include "ramses_adaptor/AbstractNodeAdaptor.h" +#include "ramses_adaptor/utilities.h" +#include "user_types/Mesh.h" +#include "user_types/MeshNode.h" +#include +#include + + +namespace raco::ramses_adaptor { + +class SceneAdaptor; + +class AbstractMeshNodeAdaptor final : public AbstractSpatialAdaptor { +public: + using BaseAdaptor = AbstractSpatialAdaptor; + + explicit AbstractMeshNodeAdaptor(AbstractSceneAdaptor* sceneAdaptor, user_types::SMeshNode node); + ~AbstractMeshNodeAdaptor(); + + user_types::SMesh mesh(); + /** + * @returns the associated MeshAdaptor if it exists and is valid (e.g. a mesh is set) + */ + AbstractMeshAdaptor* meshAdaptor(); + + bool sync() override; + void syncMaterials(); + void syncMeshObject(); + + RamsesHandle sceneObject() override { + auto handlePtr = getRamsesObjectPointer(); + return std::shared_ptr(handlePtr, handlePtr->get()); + } + + /** + * @brief Get the axis-aligned bounding box of the current MeshNode. + * + * @param worldCoordinates If true the bounding is calculated in world space, i.e. the bounding box + * of the vertices transformed to world space is calculated. Otherrwise the bounding box is calculated + * in object space, i.e. the mesh coordinates without any transformation are used. + * @return The bounding box. + */ + BoundingBox getBoundingBox(bool worldCoordinates); + + bool highlighted() const; + void setHighlighted(bool highlight); + +private: + void syncMaterial(size_t index); + + ramses_base::RamsesAppearance currentAppearance_; + ramses_base::RamsesPickableObject pickObject_; + ramses_base::RamsesArrayBuffer triangles_; + + // Subscriptions + components::Subscription meshSubscription_; + components::Subscription instanceCountSubscription_; + components::Subscription visibilitySubscription_; + + bool highlight_ = false; +}; + +}; // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/include/ramses_adaptor/AbstractNodeAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/AbstractNodeAdaptor.h new file mode 100644 index 00000000..3e0ae44e --- /dev/null +++ b/components/libRamsesBase/include/ramses_adaptor/AbstractNodeAdaptor.h @@ -0,0 +1,111 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "core/Handles.h" +#include "core/Queries.h" + +#include "ramses_adaptor/AbstractObjectAdaptor.h" +#include "ramses_adaptor/AbstractSceneAdaptor.h" +#include "ramses_adaptor/utilities.h" +#include "ramses_base/RamsesHandles.h" +#include "ramses_base/Utils.h" +#include "components/DataChangeDispatcher.h" +#include "user_types/Node.h" +#include + +namespace raco::ramses_adaptor { + +class AbstractNodeAdaptor; + +template +class AbstractSpatialAdaptor : public AbstractTypedObjectAdaptor, public AbstractISceneObjectProvider { +public: + explicit AbstractSpatialAdaptor(AbstractSceneAdaptor* sceneAdaptor, std::shared_ptr editorObject, RamsesHandle&& ramsesObject, AbstractNodeAdaptor* parent = nullptr) + : AbstractTypedObjectAdaptor{sceneAdaptor, editorObject, std::move(ramsesObject)}, + subscriptions_{ + sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject}.get("children"), [this]() { this->tagDirty(); }), + sceneAdaptor->dispatcher()->registerOnChildren(core::ValueHandle{editorObject}.get("translation"), [this](auto) { this->tagDirty(); }), + sceneAdaptor->dispatcher()->registerOnChildren(core::ValueHandle{editorObject}.get("scaling"), [this](auto) { this->tagDirty(); }), + sceneAdaptor->dispatcher()->registerOnChildren(core::ValueHandle{editorObject}.get("rotation"), [this](auto) { this->tagDirty(); })} { + } + + ~AbstractSpatialAdaptor() { + this->resetRamsesObject(); + currentRamsesChildren_.clear(); + } + + bool sync() override { + bool status = AbstractTypedObjectAdaptor::sync(); + syncVisibility(); + syncRotation(); + syncTranslation(); + syncScaling(); + syncChildren(); + this->tagDirty(false); + return status; + } + + RamsesHandle sceneObject() override { + auto handlePtr = this->getRamsesObjectPointer(); + return std::shared_ptr(handlePtr, handlePtr->get()); + } + +protected: + std::vector> currentRamsesChildren_; + +private: + void syncChildren() { + (*this->ramsesObject()).removeAllChildren(); + currentRamsesChildren_.clear(); + + for (const auto& child : *this->editorObject()) { + AbstractSceneAdaptor* scene = this->sceneAdaptor_; + auto castedChild = scene->lookup(child); + if (castedChild) { + auto handle{castedChild->sceneObject()}; + (*this->ramsesObject()).addChild(*handle); + currentRamsesChildren_.emplace_back(handle); + + } + } + } + + void syncVisibility() { + // scene view objects are currently always visible + } + + void syncRotation() { + if (getRacoRotation(this->editorObject()) != getRamsesRotation(this->ramsesObject().get())) { + (*this->ramsesObject()).setRotation(getRacoRotation(this->editorObject()), ramses_adaptor::RAMSES_ROTATION_CONVENTION); + } + } + + void syncTranslation() { + if (getRacoTranslation(this->editorObject()) != getRamsesTranslation(this->ramsesObject().get())) { + (*this->ramsesObject()).setTranslation(getRacoTranslation(this->editorObject())); + } + } + + void syncScaling() { + if (getRacoScaling(this->editorObject()) != getRamsesScaling(this->ramsesObject().get())) { + (*this->ramsesObject()).setScaling(getRacoScaling(this->editorObject())); + } + } + + std::array subscriptions_; +}; + +class AbstractNodeAdaptor final : public AbstractSpatialAdaptor { +public: + explicit AbstractNodeAdaptor(AbstractSceneAdaptor* sceneAdaptor, user_types::SNode node); +}; + +}; // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/include/ramses_adaptor/AbstractObjectAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/AbstractObjectAdaptor.h new file mode 100644 index 00000000..94c1666f --- /dev/null +++ b/components/libRamsesBase/include/ramses_adaptor/AbstractObjectAdaptor.h @@ -0,0 +1,127 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "data_storage/Value.h" +#include "ramses_adaptor/utilities.h" +#include "ramses_base/RamsesHandles.h" +#include +#include +#include + +#include +#include "ramses_base/RamsesFormatter.h" + +namespace raco::ramses_adaptor { + +class AbstractSceneAdaptor; + +using ramses_base::RamsesHandle; + + +class AbstractISceneObjectProvider { +public: + virtual RamsesHandle sceneObject() = 0; +}; + +/** + * Base class for all EditorObject Adaptors + */ +class AbstractObjectAdaptor { +public: + using SEditorObject = core::SEditorObject; + + explicit AbstractObjectAdaptor(AbstractSceneAdaptor* sceneAdaptor) : sceneAdaptor_{sceneAdaptor}, dirtyStatus_{true} {} + virtual ~AbstractObjectAdaptor(); + + virtual SEditorObject baseEditorObject() noexcept = 0; + virtual const SEditorObject baseEditorObject() const noexcept = 0; + + // Return true if externally visible ramses object pointerrs have been changed. + // Sync is expected to clean the dirty status of the current adaptor object. + virtual bool sync(); + + bool isDirty() const; + + // Dirty objects need to be updated in ramses due to changes in the data model. + void tagDirty(bool newStatus = true); + +protected: + AbstractSceneAdaptor* sceneAdaptor_; + bool dirtyStatus_; +}; +using UniqueAbstractObjectAdaptor = std::unique_ptr; + +template +class AbstractUserTypeObjectAdaptor : public AbstractObjectAdaptor { +public: + AbstractUserTypeObjectAdaptor(AbstractSceneAdaptor* sceneAdaptor, std::shared_ptr editorObject) + : AbstractObjectAdaptor(sceneAdaptor), editorObject_(editorObject) { + } + + SEditorObject baseEditorObject() noexcept override { + return editorObject_; + } + + const SEditorObject baseEditorObject() const noexcept override { + return editorObject_; + } + + + std::shared_ptr editorObject() noexcept { + return editorObject_; + } + + const std::shared_ptr& editorObject() const noexcept { + return editorObject_; + } + +protected: + std::shared_ptr editorObject_; +}; + +template +class AbstractTypedObjectAdaptor : public AbstractUserTypeObjectAdaptor { +public: + AbstractTypedObjectAdaptor( + AbstractSceneAdaptor* sceneAdaptor, + std::shared_ptr editorObject, + RamsesHandle&& ramsesObject) : AbstractUserTypeObjectAdaptor{sceneAdaptor, editorObject}, + ramsesObject_{std::move(ramsesObject)} { + } + + RamsesType& ramsesObject() noexcept { + return *ramsesObject_.get(); + } + const RamsesType& ramsesObject() const noexcept { + return *ramsesObject_.get(); + } + RamsesHandle getRamsesObjectPointer() const { + return ramsesObject_; + } + void resetRamsesObject() { + ramsesObject_.reset(); + } + +protected: + bool sync() override { + this->tagDirty(false); + return false; + } + + void reset(RamsesHandle&& newRamsesObject) { + std::swap(ramsesObject_, newRamsesObject); + } + +private: + RamsesHandle ramsesObject_; +}; + +}; // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/include/ramses_adaptor/AbstractSceneAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/AbstractSceneAdaptor.h new file mode 100644 index 00000000..7defd8f2 --- /dev/null +++ b/components/libRamsesBase/include/ramses_adaptor/AbstractSceneAdaptor.h @@ -0,0 +1,199 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "components/DataChangeDispatcher.h" +#include "core/Context.h" +#include "core/Link.h" +#include "ramses_adaptor/AbstractObjectAdaptor.h" +#include "ramses_adaptor/CameraController.h" +#include "ramses_adaptor/ClearDepthObject.h" +#include "ramses_adaptor/DefaultRamsesObjects.h" +#include "ramses_adaptor/Gizmos.h" +#include "ramses_adaptor/InfiniteGrid.h" +#include "ramses_adaptor/utilities.h" +#include "ramses_base/RamsesHandles.h" +#include + +#include + +namespace raco::ramses_adaptor { + +class SceneAdaptor; + + +using SRamsesAdaptorDispatcher = std::shared_ptr; + +class AbstractSceneAdaptor : public QObject { + Q_OBJECT + using Project = core::Project; + using SEditorObject = core::SEditorObject; + using ValueHandle = core::ValueHandle; + using SEditorObjectSet = core::SEditorObjectSet; + +public: + explicit AbstractSceneAdaptor(ramses::RamsesClient* client, ramses::sceneId_t id, Project* project, components::SDataChangeDispatcher dispatcher, core::MeshCache* meshCache, SceneAdaptor* previewAdaptor); + + ~AbstractSceneAdaptor(); + + ramses::Scene* scene(); + ramses::sceneId_t sceneId(); + + void setPreviewAdaptor(SceneAdaptor* previewAdaptor); + SceneAdaptor* previewAdaptor(); + + /* START: Adaptor API */ + ramses::RamsesClient* client(); + const ramses::RamsesClient* client() const; + const SRamsesAdaptorDispatcher dispatcher() const; + const ramses_base::RamsesAppearance defaultAppearance(bool withMeshNormals, bool highlight); + const ramses_base::RamsesArrayResource defaultVertices(int index); + const ramses_base::RamsesArrayResource defaultNormals(int index); + const ramses_base::RamsesArrayBuffer defaultTriangles(int index); + const ramses_base::RamsesArrayResource defaultIndices(int index); + AbstractObjectAdaptor* lookupAdaptor(const core::SEditorObject& editorObject) const; + Project& project() const; + + template + T* lookup(const core::SEditorObject& editorObject) const { + return dynamic_cast(lookupAdaptor(editorObject)); + } + /* END: Adaptor API */ + + void iterateAdaptors(std::function func); + + void rescaleCameraToViewport(uint32_t width, uint32_t height); + + CameraController& cameraController(); + ramses_base::RamsesPerspectiveCamera camera(); + + /** + * @brief Get world-space bounding box of all meshnodes in the scenegraph subtrees of the given objects. + * @return Merged bounding box. + */ + BoundingBox getBoundingBox(std::vector objects); + + float gridScale(); + + void setHighlightedObjects(const std::vector& objects); + void attachGizmo(const std::vector& objects); + + enum class GizmoMode { + None, + Locator, + Translate, + Rotate, + Scale + }; + + void setGizmoMode(GizmoMode mode); + GizmoMode gizmoMode(); + + + void setHighlightUsingTransparency(bool useTransparency); + + ramses::pickableObjectId_t getPickId(SEditorObject object); + ramses::pickableObjectId_t getPickId(); + SEditorObject getPickedObject(ramses::pickableObjectId_t pickId); + std::pair getPickedGizmoElement(const std::vector& pickIds); + + + /** + * @brief Return model matrix for the given object. The model matrix is obtained from Ramses. + * @param object Object to query the model matrix for. This may be a nullptr. + * @return Return model matrix if object is a Node or child type of Node and unit matrix otherwise. + */ + glm::mat4 modelMatrix(SEditorObject object); + + bool hasModelMatrix(SEditorObject object); + + void enableGuides(glm::vec3 origin, glm::vec3 u, glm::vec3 v, int idx_u, int idx_v, bool full_grid, glm::vec2 enable); + void disableGuides(); + +Q_SIGNALS: + /** + * @brief Signal emitted when the grid scale changes + * @param newScale is the new scale of the grid. + */ + void scaleChanged(float newScale); + +private: + bool needAdaptor(SEditorObject object); + void createAdaptor(SEditorObject obj); + void removeAdaptor(SEditorObject obj); + + void performBulkEngineUpdate(const core::SEditorObjectSet& changedObjects); + void rebuildSortedDependencyGraph(SEditorObjectSet const& objects); + void deleteUnusedDefaultResources(); + + void updateGridScale(float cameraDistance); + void updateGizmo(); + + ramses::RamsesClient* client_; + Project* project_; + ramses_base::RamsesScene scene_{}; + core::MeshCache* meshCache_; + SceneAdaptor* previewAdaptor_; + + struct Flags { + bool normals; + bool highlight; + bool transparent; + + bool operator<(const Flags& other) const; + }; + std::map defaultAppearances_; + + std::array defaultIndices_; + std::array defaultVertices_; + std::array defaultNormals_; + std::array defaultTriangles_; + + RamsesGizmoMeshBuffers gizmoArrowBuffers_; + RamsesGizmoMeshBuffers gizmoScaleBuffers_; + RamsesGizmoMeshBuffers gizmoSphereBuffers_; + RamsesGizmoMeshBuffers gizmoTorusBuffers_; + + std::map> adaptors_{}; + + components::Subscription subscription_; + components::Subscription childrenSubscription_; + SRamsesAdaptorDispatcher dispatcher_; + + bool adaptorStatusDirty_ = false; + + std::vector dependencyGraph_; + + ramses_base::RamsesPerspectiveCamera camera_; + ramses_base::RamsesRenderGroup renderGroup_; + ramses_base::RamsesRenderPass renderPass_; + ramses_base::RamsesRenderGroup gizmoRenderGroup_; + ramses_base::RamsesRenderGroup gizmoRenderGroupTransparent_; + + SEditorObject gizmoObject_ = nullptr; + std::unique_ptr gizmo_; + GizmoMode gizmoMode_ = GizmoMode::Locator; + + CameraController cameraController_; + + InfiniteGrid grid_; + float gridScale_; + + ClearDepthObject clearDepth_; + + InfiniteGrid guides_; + + bool highlightUsingTransparency_ = false; + + std::map objectPickIds_; + uint32_t nextFreePickId_{0}; +}; + +} // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/include/ramses_adaptor/AnchorPointAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/AnchorPointAdaptor.h index a1aeccd2..89dbadde 100644 --- a/components/libRamsesBase/include/ramses_adaptor/AnchorPointAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/AnchorPointAdaptor.h @@ -18,10 +18,10 @@ namespace raco::ramses_adaptor { class AnchorPointAdaptor final : public UserTypeObjectAdaptor, public ILogicPropertyProvider { public: - AnchorPointAdaptor(SceneAdaptor* sceneAdaptor, raco::user_types::SAnchorPoint anchorPoint); + AnchorPointAdaptor(SceneAdaptor* sceneAdaptor, user_types::SAnchorPoint anchorPoint); - void getLogicNodes(std::vector& logicNodes) const override; - const rlogic::Property* getProperty(const std::vector& propertyNamesVector) override; + void getLogicNodes(std::vector& logicNodes) const override; + ramses::Property* getProperty(const std::vector& propertyNamesVector) override; void onRuntimeError(core::Errors& errors, std::string const& message, core::ErrorLevel level) override; std::vector getExportInformation() const override; @@ -29,10 +29,10 @@ class AnchorPointAdaptor final : public UserTypeObjectAdaptor subscriptions_; + components::Subscription dirtySubscription_; + std::array subscriptions_; }; } // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/include/ramses_adaptor/AnimationAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/AnimationAdaptor.h index 57161b65..f92d9a93 100644 --- a/components/libRamsesBase/include/ramses_adaptor/AnimationAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/AnimationAdaptor.h @@ -14,16 +14,16 @@ #include "ramses_base/RamsesHandles.h" #include "user_types/Animation.h" -#include +#include namespace raco::ramses_adaptor { class AnimationAdaptor final : public UserTypeObjectAdaptor, public ILogicPropertyProvider { public: - explicit AnimationAdaptor(SceneAdaptor* sceneAdaptor, raco::user_types::SAnimation animation); + explicit AnimationAdaptor(SceneAdaptor* sceneAdaptor, user_types::SAnimation animation); - void getLogicNodes(std::vector& logicNodes) const override; - const rlogic::Property* getProperty(const std::vector& propertyNamesVector) override; + void getLogicNodes(std::vector& logicNodes) const override; + ramses::Property* getProperty(const std::vector& propertyNamesVector) override; void onRuntimeError(core::Errors& errors, std::string const& message, core::ErrorLevel level) override; bool sync(core::Errors* errors) override; @@ -31,10 +31,10 @@ class AnimationAdaptor final : public UserTypeObjectAdaptor getExportInformation() const override; private: - raco::ramses_base::RamsesAnimationNode animNode_; - raco::components::Subscription progressSubscription_; - raco::components::Subscription dirtySubscription_; - raco::components::Subscription nameSubscription_; + ramses_base::RamsesAnimationNode animNode_; + components::Subscription progressSubscription_; + components::Subscription dirtySubscription_; + components::Subscription nameSubscription_; void updateGlobalAnimationSettings(); void updateGlobalAnimationStats(core::Errors* errors); diff --git a/components/libRamsesBase/include/ramses_adaptor/AnimationChannelAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/AnimationChannelAdaptor.h index 4ff9d695..036e2155 100644 --- a/components/libRamsesBase/include/ramses_adaptor/AnimationChannelAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/AnimationChannelAdaptor.h @@ -19,18 +19,18 @@ namespace raco::ramses_adaptor { class AnimationChannelAdaptor final : public UserTypeObjectAdaptor { public: - explicit AnimationChannelAdaptor(SceneAdaptor* sceneAdaptor, raco::user_types::SAnimationChannel channel); + explicit AnimationChannelAdaptor(SceneAdaptor* sceneAdaptor, user_types::SAnimationChannel channel); bool sync(core::Errors* errors) override; - raco::ramses_base::RamsesAnimationChannelHandle handle() const; + ramses_base::RamsesAnimationChannelHandle handle() const; std::vector getExportInformation() const override; private: - raco::ramses_base::RamsesAnimationChannelHandle handle_; + ramses_base::RamsesAnimationChannelHandle handle_; - std::array subscriptions_; - raco::components::Subscription previewDirtySubscription_; + std::array subscriptions_; + components::Subscription previewDirtySubscription_; }; }; // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/include/ramses_adaptor/BaseCameraAdaptorHelpers.h b/components/libRamsesBase/include/ramses_adaptor/BaseCameraAdaptorHelpers.h index e7db84da..d671e622 100644 --- a/components/libRamsesBase/include/ramses_adaptor/BaseCameraAdaptorHelpers.h +++ b/components/libRamsesBase/include/ramses_adaptor/BaseCameraAdaptorHelpers.h @@ -22,9 +22,9 @@ namespace raco::components { class Subscription; } -namespace rlogic { +namespace ramses { class Property; -class RamsesCameraBinding; +class CameraBinding; } namespace ramses { @@ -42,8 +42,8 @@ class ObjectAdaptor; class BaseCameraAdaptorHelpers { public: - static void sync(std::shared_ptr editorObject, ramses::Camera* ramsesCamera, rlogic::RamsesCameraBinding* cameraBinding, core::Errors* errors); - static const rlogic::Property* getProperty(rlogic::RamsesCameraBinding* cameraBinding, const std::vector& propertyNamesVector); + static void sync(std::shared_ptr editorObject, ramses::Camera* ramsesCamera, ramses::CameraBinding* cameraBinding, core::Errors* errors); + static ramses::Property* getProperty(ramses::CameraBinding* cameraBinding, const std::vector& propertyNamesVector); }; }; // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/include/ramses_adaptor/BlitPassAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/BlitPassAdaptor.h index be949ab9..62069f9b 100644 --- a/components/libRamsesBase/include/ramses_adaptor/BlitPassAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/BlitPassAdaptor.h @@ -28,7 +28,7 @@ class BlitPassAdaptor final : public UserTypeObjectAdaptor private: std::array subscriptions_; - raco::ramses_base::RamsesBlitPass blitPass_; + ramses_base::RamsesBlitPass blitPass_; bool recreate_; bool update_; }; diff --git a/components/libRamsesBase/include/ramses_adaptor/BuildOptions.h b/components/libRamsesBase/include/ramses_adaptor/BuildOptions.h index dec5d0e2..4bf6f93b 100644 --- a/components/libRamsesBase/include/ramses_adaptor/BuildOptions.h +++ b/components/libRamsesBase/include/ramses_adaptor/BuildOptions.h @@ -9,8 +9,8 @@ */ #pragma once -#include +#include namespace raco::ramses_adaptor { - constexpr auto RAMSES_ROTATION_CONVENTION { ramses::ERotationConvention::XYZ }; + constexpr auto RAMSES_ROTATION_CONVENTION { ramses::ERotationType::Euler_ZYX }; } diff --git a/components/libRamsesBase/include/ramses_adaptor/CameraController.h b/components/libRamsesBase/include/ramses_adaptor/CameraController.h new file mode 100644 index 00000000..d79b8bfe --- /dev/null +++ b/components/libRamsesBase/include/ramses_adaptor/CameraController.h @@ -0,0 +1,77 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "ramses_adaptor/utilities.h" + +#include + +namespace raco::ramses_adaptor { + +class CameraController : public QObject { + Q_OBJECT +public: + static constexpr float rotationSensitivity = 0.005; + static constexpr float panSensitivity = 0.001; + static constexpr float zoomMoveSensitivity = 0.01; + static constexpr float zoomWheelSensitivity = 0.001; + static constexpr float pitchLimit = 87.0; + + CameraController(ramses_base::RamsesPerspectiveCamera camera); + + void reset(); + + /** + * @brief Focus the camera view frustum on the given bounding box by translating the camera position + * and adjusting the position-lookat distance but keeping the current direction unchanged. + * @param boundingBox Bounding box to focus on. + */ + void focus(const BoundingBox& boundingBox); + + void rescaleCameraToViewport(uint32_t width, uint32_t height); + + void orbitCamera(QPoint deltaMousePos); + + void panCamera(QPoint deltaMousePos); + + void zoomCameraMove(QPoint deltaMousePos); + void zoomCameraWheel(QPoint deltaWheelAngle); + + float cameraDistance(); + + glm::mat4 projectionMatrix(); + glm::mat4 viewMatrix(); + glm::mat4 modelMatrix(); + +Q_SIGNALS: + /** + * @brief Signal emitted when the distance of the camera position to the lookat point changes. + * @param cameraDistance New distance of the camera position from the lookat point. + */ + void distanceChanged(float cameraDistance); + +private: + void update(bool distChanged = false); + glm::vec3 getEulerAngles(); + void zoomCamera(float logFactor); + + ramses_base::RamsesPerspectiveCamera camera_; + + glm::vec3 position_; + glm::vec3 lookAt_; + glm::vec3 up_; + + float angle_; + float aspectRatio_; + float near_; + float far_; +}; + +} // namespace raco::ramses_adaptor \ No newline at end of file diff --git a/components/libRamsesBase/include/ramses_adaptor/ClearDepthObject.h b/components/libRamsesBase/include/ramses_adaptor/ClearDepthObject.h new file mode 100644 index 00000000..5ec04952 --- /dev/null +++ b/components/libRamsesBase/include/ramses_adaptor/ClearDepthObject.h @@ -0,0 +1,33 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "ramses_base/RamsesHandles.h" + +namespace raco::ramses_adaptor { + +class ClearDepthObject { +public: + ClearDepthObject(ramses::Scene* scene); + + void setup(ramses_base::RamsesRenderPass renderPass, int renderOrder); + +private: + ramses::Scene* scene_; + ramses_base::RamsesRenderPass renderPass_; + + ramses_base::RamsesRenderGroup renderGroup_; + ramses_base::RamsesEffect effect_; + ramses_base::RamsesAppearance appearance_; + ramses_base::RamsesGeometry geometry_; + ramses_base::RamsesMeshNode meshNode_; +}; + +} // namespace raco::ramses_adaptor \ No newline at end of file diff --git a/components/libRamsesBase/include/ramses_adaptor/CubeMapAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/CubeMapAdaptor.h index c56259cd..fb31ff4d 100644 --- a/components/libRamsesBase/include/ramses_adaptor/CubeMapAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/CubeMapAdaptor.h @@ -14,8 +14,8 @@ #include "components/DataChangeDispatcher.h" #include "user_types/CubeMap.h" #include -#include -#include +#include +#include namespace raco::ramses_adaptor { @@ -27,14 +27,14 @@ class CubeMapAdaptor : public TypedObjectAdaptor getExportInformation() const override; private: - raco::ramses_base::RamsesTextureCube createTexture(core::Errors* errors); - raco::ramses_base::RamsesTextureCube fallbackCube(); + ramses_base::RamsesTextureCube createTexture(core::Errors* errors); + ramses_base::RamsesTextureCube fallbackCube(); std::string createDefaultTextureDataName(); std::array subscriptions_; - raco::ramses_base::RamsesTextureCube textureData_; + ramses_base::RamsesTextureCube textureData_; - std::map> generateMipmapData(core::Errors* errors, int level, raco::ramses_base::PngDecodingInfo& decodingInfo); + std::map> generateMipmapData(core::Errors* errors, int level, ramses_base::PngDecodingInfo& decodingInfo); }; }; // namespace raco::ramses_adaptor \ No newline at end of file diff --git a/components/libRamsesBase/include/ramses_adaptor/DefaultRamsesObjects.h b/components/libRamsesBase/include/ramses_adaptor/DefaultRamsesObjects.h new file mode 100644 index 00000000..97f2818c --- /dev/null +++ b/components/libRamsesBase/include/ramses_adaptor/DefaultRamsesObjects.h @@ -0,0 +1,62 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "ramses_base/RamsesHandles.h" + +namespace raco::core { +class MeshCache; +} + +namespace raco::ramses_adaptor { + +static constexpr const char* defaultEffectName = "ramses_adaptor::DefaultEffectWithoutNormals"; +static constexpr const char* defaultEffectWithNormalsName = "ramses_adaptor::DefaultEffectWithNormals"; +static constexpr const char* defaultAppearanceName = "ramses_adaptor::DefaultAppearanceWithoutNormals"; +static constexpr const char* defaultAppearanceWithNormalsName = "ramses_adaptor::DefaultAppearanceWithNormals"; +static constexpr const char* defaultIndexDataBufferName = "ramses_adaptor::DefaultIndexDataBuffer"; +static constexpr const char* defaultVertexDataBufferName = "ramses_adaptor::DefaultVertexDataBuffer"; +static constexpr const char* defaultNormalDataBufferName = "ramses_adaptor::DefaultNormalDataBuffer"; +static constexpr const char* defaultRenderGroupName = "ramses_adaptor::DefaultRenderGroup"; +static constexpr const char* defaultRenderPassName = "ramses_adaptor::DefaultRenderPass"; +static constexpr const char* defaultGizmoArrowName = "ramses_adaptor::DefaultGizmoArrow"; + +ramses_base::RamsesAppearance createDefaultAppearance(ramses::Scene* scene, bool withNormals, bool highlight, bool transparent); + + ramses_base::RamsesArrayResource createCubeIndexDataBuffer(ramses::Scene* scene); + ramses_base::RamsesArrayResource createCubeVertexDataBuffer(ramses::Scene* scene); + ramses_base::RamsesArrayResource createCubeNormalDataBuffer(ramses::Scene* scene); + +ramses_base::RamsesArrayResource createCatIndexDataBuffer(ramses::Scene* scene); +ramses_base::RamsesArrayResource createCatVertexDataBuffer(ramses::Scene* scene); +ramses_base::RamsesArrayResource createCatNormalDataBuffer(ramses::Scene* scene); + +ramses_base::RamsesArrayResource createQuadVertexDataBuffer(ramses::Scene* scene); +ramses_base::RamsesArrayResource createQuadIndexDataBuffer(ramses::Scene* scene); + +struct RamsesGizmoMeshBuffers { + ramses_base::RamsesArrayResource indices; + ramses_base::RamsesArrayResource vertices; + ramses_base::RamsesArrayBuffer triangles; +}; + +RamsesGizmoMeshBuffers loadGizmoMesh(ramses::Scene* scene, core::MeshCache* meshCache, const std::string& filename); +RamsesGizmoMeshBuffers createGizmoQuad(ramses::Scene* scene); +RamsesGizmoMeshBuffers createGizmoCube(ramses::Scene* scene); + +extern const char* flatColorVertexShader; +extern const char* flatColorFragmentShader; + +extern const std::vector cubeIndicesData; +extern const std::vector cubeVerticesData; +extern const std::vector cat_vertex_data; +extern const std::vector cat_indices_data; + +} // namespace raco::ramses_adaptor \ No newline at end of file diff --git a/components/libRamsesBase/include/ramses_adaptor/Factories.h b/components/libRamsesBase/include/ramses_adaptor/Factories.h index dc92c465..3635285d 100644 --- a/components/libRamsesBase/include/ramses_adaptor/Factories.h +++ b/components/libRamsesBase/include/ramses_adaptor/Factories.h @@ -10,14 +10,19 @@ #pragma once #include "ramses_adaptor/ObjectAdaptor.h" +#include "ramses_adaptor/AbstractObjectAdaptor.h" namespace raco::ramses_adaptor { class SceneAdaptor; +class AbstractSceneAdaptor; + struct Factories { static UniqueObjectAdaptor createAdaptor(SceneAdaptor* buildContext, core::SEditorObject obj); + static UniqueAbstractObjectAdaptor createAbstractAdaptor(AbstractSceneAdaptor* buildContext, core::SEditorObject obj); + private: }; } // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/include/ramses_adaptor/Gizmos.h b/components/libRamsesBase/include/ramses_adaptor/Gizmos.h new file mode 100644 index 00000000..9d4a0374 --- /dev/null +++ b/components/libRamsesBase/include/ramses_adaptor/Gizmos.h @@ -0,0 +1,74 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "ramses_base/RamsesHandles.h" + +namespace raco::ramses_adaptor { + +class AbstractSceneAdaptor; +struct RamsesGizmoMeshBuffers; + +class GizmoTriad { +public: + GizmoTriad(AbstractSceneAdaptor* sceneAdaptor, ramses::Scene* scene, ramses_base::RamsesRenderGroup renderGroup, ramses_base::RamsesRenderGroup transparentRenderGroup, RamsesGizmoMeshBuffers& buffers, core::SEditorObject node); + + ~GizmoTriad(); + + virtual void update(); + core::SEditorObject object(); + + enum class PickElement { + None, + Axis, + Plane, + Central + }; + + virtual std::pair pickElement(ramses::pickableObjectId_t pickId); + +protected: + ramses_base::RamsesMeshNode createGizmoMeshnode(ramses::Scene* scene, RamsesGizmoMeshBuffers& buffers, glm::vec3 color, float alpha = 1.0, bool invisible = false); + ramses_base::RamsesMeshNode createFrustumMeshnode(ramses::Scene* scene, RamsesGizmoMeshBuffers& buffers, glm::vec3 color, float alpha); + + AbstractSceneAdaptor* sceneAdaptor_; + ramses::Scene* scene_; + ramses_base::RamsesRenderGroup renderGroup_; + ramses_base::RamsesRenderGroup renderGroupTransparent_; + core::SEditorObject node_; + + ramses_base::RamsesNode root_; + std::array arrow_; + std::array pickObject_; + std::array pickId_; + + ramses_base::RamsesMeshNode frustum_; +}; + +class GizmoTransformation : public GizmoTriad { +public: + GizmoTransformation(AbstractSceneAdaptor* sceneAdaptor, ramses::Scene* scene, ramses_base::RamsesRenderGroup renderGroup, ramses_base::RamsesRenderGroup transparentRenderGroup, RamsesGizmoMeshBuffers& axisBuffers, RamsesGizmoMeshBuffers& centralBuffers, core::SEditorObject node, bool enableCentralElement, bool enablePlanes, bool isRotation); + + virtual void update() override; + + virtual std::pair pickElement(ramses::pickableObjectId_t pickId); + +private: + ramses_base::RamsesMeshNode central_; + ramses_base::RamsesPickableObject pickObjectCentral_; + ramses::pickableObjectId_t pickIdCentral_; + + bool enablePlanes_; + std::array plane_; + std::array pickObjectPlane_; + std::array pickIdPlane_; +}; + +} // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/include/ramses_adaptor/InfiniteGrid.h b/components/libRamsesBase/include/ramses_adaptor/InfiniteGrid.h new file mode 100644 index 00000000..a5cb3a0d --- /dev/null +++ b/components/libRamsesBase/include/ramses_adaptor/InfiniteGrid.h @@ -0,0 +1,40 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "ramses_base/RamsesHandles.h" + +namespace raco::ramses_adaptor { + +class InfiniteGrid { +public: + InfiniteGrid(ramses::Scene* scene); + + void setup(ramses_base::RamsesRenderPass renderPass, bool depthTesting, float axisColorFac, int renderOrder); + + void enable(glm::vec3 origin, glm::vec3 u, glm::vec3 v, int idx_u, int idx_v, bool full_grid, glm::vec2 enable); + void disable(); + + void setScale(float scale); + +private: + ramses::Scene* scene_; + ramses_base::RamsesRenderPass renderPass_; + + float scale_ = 1.0; + + ramses_base::RamsesRenderGroup renderGroup_; + ramses_base::RamsesEffect effect_; + ramses_base::RamsesAppearance appearance_; + ramses_base::RamsesGeometry geometry_; + ramses_base::RamsesMeshNode meshNode_; +}; + +} // namespace raco::ramses_adaptor \ No newline at end of file diff --git a/components/libRamsesBase/include/ramses_adaptor/LinkAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/LinkAdaptor.h index 6d513a70..b5f826ec 100644 --- a/components/libRamsesBase/include/ramses_adaptor/LinkAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/LinkAdaptor.h @@ -10,8 +10,8 @@ #pragma once #include "core/Link.h" -#include -#include +#include +#include #include "components/DataChangeDispatcher.h" #include @@ -22,11 +22,11 @@ class SceneAdaptor; class LinkAdaptor { public: struct EngineLink { - const rlogic::Property* origin; - const rlogic::Property* dest; + ramses::Property* origin; + ramses::Property* dest; }; using UniqueEngineLink = std::unique_ptr>; - using SLink = raco::core::SLink; + using SLink = core::SLink; explicit LinkAdaptor(const core::LinkDescriptor& link, SceneAdaptor* sceneAdaptor); ~LinkAdaptor() {} diff --git a/components/libRamsesBase/include/ramses_adaptor/LuaInterfaceAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/LuaInterfaceAdaptor.h index 256d0639..7a8d6e43 100644 --- a/components/libRamsesBase/include/ramses_adaptor/LuaInterfaceAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/LuaInterfaceAdaptor.h @@ -13,7 +13,7 @@ #include "components/DataChangeDispatcher.h" #include "user_types/LuaInterface.h" -#include +#include #include #include @@ -24,8 +24,8 @@ class LuaInterfaceAdaptor : public UserTypeObjectAdaptor editorObject); - void getLogicNodes(std::vector& logicNodes) const override; - const rlogic::Property* getProperty(const std::vector& propertyNamesVector) override; + void getLogicNodes(std::vector& logicNodes) const override; + ramses::Property* getProperty(const std::vector& propertyNamesVector) override; void onRuntimeError(core::Errors& errors, std::string const& message, core::ErrorLevel level) override; std::vector getExportInformation() const override; diff --git a/components/libRamsesBase/include/ramses_adaptor/LuaScriptAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/LuaScriptAdaptor.h index 76ec64de..f72cd670 100644 --- a/components/libRamsesBase/include/ramses_adaptor/LuaScriptAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/LuaScriptAdaptor.h @@ -14,7 +14,7 @@ #include "components/DataChangeDispatcher.h" #include "user_types/LuaScript.h" -#include +#include #include #include @@ -24,8 +24,8 @@ namespace raco::ramses_adaptor { class LuaScriptAdaptor : public UserTypeObjectAdaptor, public ILogicPropertyProvider { public: explicit LuaScriptAdaptor(SceneAdaptor* sceneAdaptor, std::shared_ptr editorObject); - void getLogicNodes(std::vector& logicNodes) const override; - const rlogic::Property* getProperty(const std::vector& propertyNamesVector) override; + void getLogicNodes(std::vector& logicNodes) const override; + ramses::Property* getProperty(const std::vector& propertyNamesVector) override; void onRuntimeError(core::Errors& errors, std::string const& message, core::ErrorLevel level) override; bool sync(core::Errors* errors) override; @@ -37,7 +37,7 @@ class LuaScriptAdaptor : public UserTypeObjectAdaptor, pu void setupInputValuesSubscription(); std::string generateRamsesObjectName() const; - rlogic::LuaScript* rlogicLuaScript() const { + ramses::LuaScript* rlogicLuaScript() const { return luaScript_.get(); } diff --git a/components/libRamsesBase/include/ramses_adaptor/LuaScriptModuleAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/LuaScriptModuleAdaptor.h index 4b86945f..a666b410 100644 --- a/components/libRamsesBase/include/ramses_adaptor/LuaScriptModuleAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/LuaScriptModuleAdaptor.h @@ -14,7 +14,7 @@ #include "components/DataChangeDispatcher.h" #include "user_types/LuaScriptModule.h" -#include +#include #include #include @@ -23,7 +23,7 @@ namespace raco::ramses_adaptor { class LuaScriptModuleAdaptor : public UserTypeObjectAdaptor { public: - explicit LuaScriptModuleAdaptor(SceneAdaptor* sceneAdaptor, raco::user_types::SLuaScriptModule editorObject); + explicit LuaScriptModuleAdaptor(SceneAdaptor* sceneAdaptor, user_types::SLuaScriptModule editorObject); bool sync(core::Errors* errors) override; std::vector getExportInformation() const override; diff --git a/components/libRamsesBase/include/ramses_adaptor/MaterialAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/MaterialAdaptor.h index 341c00cb..1898e115 100644 --- a/components/libRamsesBase/include/ramses_adaptor/MaterialAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/MaterialAdaptor.h @@ -20,7 +20,7 @@ class SceneAdaptor; class MaterialAdaptor final : public TypedObjectAdaptor, public ILogicPropertyProvider { private: - static raco::ramses_base::RamsesEffect createEffect(SceneAdaptor* buildContext); + static ramses_base::RamsesEffect createEffect(SceneAdaptor* buildContext); public: explicit MaterialAdaptor(SceneAdaptor* buildContext, user_types::SMaterial material); @@ -28,24 +28,24 @@ class MaterialAdaptor final : public TypedObjectAdaptor& logicNodes) const override; - const rlogic::Property* getProperty(const std::vector& propertyNamesVector) override; + void getLogicNodes(std::vector& logicNodes) const override; + ramses::Property* getProperty(const std::vector& propertyNamesVector) override; void onRuntimeError(core::Errors& errors, std::string const& message, core::ErrorLevel level) override; std::vector getExportInformation() const override; private: - raco::ramses_base::RamsesAppearance appearance_; - raco::ramses_base::RamsesAppearanceBinding appearanceBinding_; + ramses_base::RamsesAppearance appearance_; + ramses_base::RamsesAppearanceBinding appearanceBinding_; components::Subscription subscription_; components::Subscription optionsSubscription_; components::Subscription uniformSubscription_; }; -void updateAppearance(core::Errors* errors, SceneAdaptor* sceneAdaptor, raco::ramses_base::RamsesAppearance appearance, const core::ValueHandle& optionsContHandle, const core::ValueHandle& uniformConHandle); +void updateAppearance(core::Errors* errors, SceneAdaptor* sceneAdaptor, ramses_base::RamsesAppearance appearance, user_types::BlendOptions& options, const core::ValueHandle& optionsContHandle, const core::ValueHandle& uniformConHandle); }; // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/include/ramses_adaptor/MeshAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/MeshAdaptor.h index cd114a84..1fcb5ba8 100644 --- a/components/libRamsesBase/include/ramses_adaptor/MeshAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/MeshAdaptor.h @@ -19,13 +19,13 @@ namespace raco::ramses_adaptor { class SceneAdaptor; -using VertexDataMap = std::unordered_map; +using VertexDataMap = std::unordered_map; class MeshAdaptor final : public UserTypeObjectAdaptor { public: explicit MeshAdaptor(SceneAdaptor* sceneAdaptor, user_types::SMesh mesh); - raco::ramses_base::RamsesArrayResource indicesPtr(); + ramses_base::RamsesArrayResource indicesPtr(); const VertexDataMap& vertexData() const; bool isValid(); @@ -35,7 +35,7 @@ class MeshAdaptor final : public UserTypeObjectAdaptor { private: VertexDataMap vertexDataMap_; - raco::ramses_base::RamsesArrayResource indices_; + ramses_base::RamsesArrayResource indices_; core::FileChangeMonitor::UniqueListener meshFileChangeListener_; components::Subscription subscription_; components::Subscription nameSubscription_; diff --git a/components/libRamsesBase/include/ramses_adaptor/MeshNodeAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/MeshNodeAdaptor.h index 3cddd47f..2c603dd6 100644 --- a/components/libRamsesBase/include/ramses_adaptor/MeshNodeAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/MeshNodeAdaptor.h @@ -16,7 +16,7 @@ #include "user_types/Mesh.h" #include "user_types/MeshNode.h" #include -#include +#include namespace raco::ramses_adaptor { @@ -47,11 +47,11 @@ class MeshNodeAdaptor final : public SpatialAdaptor(handlePtr, handlePtr->get()); } - void getLogicNodes(std::vector& logicNodes) const override; - const rlogic::Property* getProperty(const std::vector& propertyNamesVector) override; + void getLogicNodes(std::vector& logicNodes) const override; + ramses::Property* getProperty(const std::vector& propertyNamesVector) override; - const raco::ramses_base::RamsesAppearance& privateAppearance() const; - const raco::ramses_base::RamsesAppearanceBinding& appearanceBinding() const; + const ramses_base::RamsesAppearance& privateAppearance() const; + const ramses_base::RamsesAppearanceBinding& appearanceBinding() const; std::vector getExportInformation() const override; private: @@ -60,9 +60,9 @@ class MeshNodeAdaptor final : public SpatialAdaptor, public linksLifecycle_{sceneAdaptor->dispatcher()->registerOnLinksLifeCycleForEnd( this->editorObject(), [this](const core::LinkDescriptor& link) { - raco::core::PropertyDescriptor rotation{this->editorObject(), std::vector{"rotation"}}; + core::PropertyDescriptor rotation{this->editorObject(), std::vector{"rotation"}}; if (link.end == rotation) { setupLinkStartSubscription(); auto oldRotationType = this->rotationType_; @@ -47,7 +47,7 @@ class SpatialAdaptor : public TypedObjectAdaptor, public } }, [this](const core::LinkDescriptor& link) { - raco::core::PropertyDescriptor rotation{this->editorObject(), std::vector{"rotation"}}; + core::PropertyDescriptor rotation{this->editorObject(), std::vector{"rotation"}}; if (link.end == rotation) { setupLinkStartSubscription(); @@ -64,24 +64,24 @@ class SpatialAdaptor : public TypedObjectAdaptor, public sceneAdaptor->dispatcher()->registerOnChildren(core::ValueHandle{editorObject}.get("translation"), [this](auto) { this->tagDirty(); }), sceneAdaptor->dispatcher()->registerOnChildren(core::ValueHandle{editorObject}.get("scaling"), [this](auto) { this->tagDirty(); }), sceneAdaptor->dispatcher()->registerOnChildren(core::ValueHandle{editorObject}.get("rotation"), [this](auto) { this->tagDirty(); })} { - raco::core::PropertyDescriptor rotation{this->editorObject(), std::vector{"rotation"}}; - if (auto link = raco::core::Queries::getLink(sceneAdaptor->project(), rotation)) { + core::PropertyDescriptor rotation{this->editorObject(), std::vector{"rotation"}}; + if (auto link = core::Queries::getLink(sceneAdaptor->project(), rotation)) { rotationType_ = newRotationType(link->descriptor()); setupLinkStartSubscription(); } - nodeBinding_ = raco::ramses_base::ramsesNodeBinding(this->getRamsesObjectPointer(), &sceneAdaptor->logicEngine(), rotationType_, this->editorObject()->objectIDAsRamsesLogicID()); + nodeBinding_ = ramses_base::ramsesNodeBinding(this->getRamsesObjectPointer(), &sceneAdaptor->logicEngine(), rotationType_, this->editorObject()->objectIDAsRamsesLogicID()); } void setupLinkStartSubscription() { - raco::core::PropertyDescriptor rotation{this->editorObject(), std::vector{"rotation"}}; - if (auto link = raco::core::Queries::getLink(this->sceneAdaptor_->project(), rotation)) { + core::PropertyDescriptor rotation{this->editorObject(), std::vector{"rotation"}}; + if (auto link = core::Queries::getLink(this->sceneAdaptor_->project(), rotation)) { // TODO this is total overkill // but we dont have a subscription which will trigger when the property or any parent property is changed. - linkStartSubscription_ = this->sceneAdaptor_->dispatcher()->registerOnChildren(raco::core::ValueHandle{*link->startObject_}, + linkStartSubscription_ = this->sceneAdaptor_->dispatcher()->registerOnChildren(core::ValueHandle{*link->startObject_}, [this](auto) { - raco::core::PropertyDescriptor rotation{this->editorObject(), std::vector{"rotation"}}; - if (auto link = raco::core::Queries::getLink(this->sceneAdaptor_->project(), rotation)) { + core::PropertyDescriptor rotation{this->editorObject(), std::vector{"rotation"}}; + if (auto link = core::Queries::getLink(this->sceneAdaptor_->project(), rotation)) { auto oldRotationType = rotationType_; rotationType_ = newRotationType(link->descriptor()); if (rotationType_ != oldRotationType) { @@ -94,11 +94,11 @@ class SpatialAdaptor : public TypedObjectAdaptor, public } } - void getLogicNodes(std::vector& logicNodes) const override { + void getLogicNodes(std::vector& logicNodes) const override { logicNodes.push_back(nodeBinding_.get()); } - const rlogic::Property* getProperty(const std::vector& propertyNamesVector) override { + ramses::Property* getProperty(const std::vector& propertyNamesVector) override { if (nodeBinding_) { return nodeBinding_->getInputs()->getChild(propertyNamesVector[0]); } @@ -135,7 +135,7 @@ class SpatialAdaptor : public TypedObjectAdaptor, public return std::shared_ptr(handlePtr, handlePtr->get()); } - raco::ramses_base::RamsesNodeBinding nodeBinding() const { + ramses_base::RamsesNodeBinding nodeBinding() const { return nodeBinding_; } @@ -160,7 +160,7 @@ class SpatialAdaptor : public TypedObjectAdaptor, public } void syncNodeBinding() { - nodeBinding_ = raco::ramses_base::ramsesNodeBinding(this->getRamsesObjectPointer(), &this->sceneAdaptor_->logicEngine(), rotationType_, this->editorObject()->objectIDAsRamsesLogicID()); + nodeBinding_ = ramses_base::ramsesNodeBinding(this->getRamsesObjectPointer(), &this->sceneAdaptor_->logicEngine(), rotationType_, this->editorObject()->objectIDAsRamsesLogicID()); nodeBinding_->setName(this->editorObject().get()->objectName() + "_NodeBinding"); } @@ -168,47 +168,45 @@ class SpatialAdaptor : public TypedObjectAdaptor, public auto visibility = core::ValueHandle{this->editorObject()}.get("visibility").as(); nodeBinding_->getInputs()->getChild("visibility")->set(visibility); - if (this->sceneAdaptor_->featureLevel() >= rlogic::EFeatureLevel::EFeatureLevel_02) { - auto enabled = core::ValueHandle{this->editorObject()}.get("enabled").as(); - nodeBinding_->getInputs()->getChild("enabled")->set(enabled); - } + auto enabled = core::ValueHandle{this->editorObject()}.get("enabled").as(); + nodeBinding_->getInputs()->getChild("enabled")->set(enabled); } void syncRotation() { - if (Rotation::from(this->editorObject()) != Rotation::from(*this->ramsesObject())) { - Rotation::sync(this->editorObject(), *this->ramsesObject()); + if ((*this->ramsesObject()).getRotationType() != ramses_adaptor::RAMSES_ROTATION_CONVENTION || + getRacoRotation(this->editorObject()) != getRamsesRotation(this->ramsesObject().get())) { + (*this->ramsesObject()).setRotation(getRacoRotation(this->editorObject()), ramses_adaptor::RAMSES_ROTATION_CONVENTION); } - } void syncTranslation() { - if (Translation::from(this->editorObject()) != Translation::from(*this->ramsesObject())) { - Translation::sync(this->editorObject(), *this->ramsesObject()); + if (getRacoTranslation(this->editorObject()) != getRamsesTranslation(this->ramsesObject().get())) { + (*this->ramsesObject()).setTranslation(getRacoTranslation(this->editorObject())); } } void syncScaling() { - if (Scaling::from(this->editorObject()) != Scaling::from(*this->ramsesObject())) { - Scaling::sync(this->editorObject(), *this->ramsesObject()); + if (getRacoScaling(this->editorObject()) != getRamsesScaling(this->ramsesObject().get())) { + (*this->ramsesObject()).setScaling(getRacoScaling(this->editorObject())); } } - rlogic::ERotationType newRotationType(const raco::core::LinkDescriptor& linkDescriptor) { + ramses::ERotationType newRotationType(const core::LinkDescriptor& linkDescriptor) { if (linkDescriptor.isValid) { - auto startHandle = raco::core::ValueHandle{linkDescriptor.start}; + auto startHandle = core::ValueHandle{linkDescriptor.start}; if (startHandle && startHandle.isVec4f()) { - return rlogic::ERotationType::Quaternion; + return ramses::ERotationType::Quaternion; } } return DEFAULT_VEC3_ROTATION_TYPE; } - constexpr static inline rlogic::ERotationType DEFAULT_VEC3_ROTATION_TYPE = rlogic::ERotationType::Euler_ZYX; + constexpr static inline ramses::ERotationType DEFAULT_VEC3_ROTATION_TYPE = ramses::ERotationType::Euler_ZYX; - rlogic::ERotationType rotationType_; - raco::ramses_base::RamsesNodeBinding nodeBinding_; + ramses::ERotationType rotationType_; + ramses_base::RamsesNodeBinding nodeBinding_; std::array subscriptions_; components::Subscription linksLifecycle_; components::Subscription linkStartSubscription_; diff --git a/components/libRamsesBase/include/ramses_adaptor/ObjectAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/ObjectAdaptor.h index e853435d..f2c73de2 100644 --- a/components/libRamsesBase/include/ramses_adaptor/ObjectAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/ObjectAdaptor.h @@ -14,28 +14,34 @@ #include "ramses_adaptor/utilities.h" #include "ramses_adaptor/SceneAdaptor.h" #include "ramses_base/RamsesHandles.h" -#include -#include -#include +#include +#include +#include #include #include "ramses_base/RamsesFormatter.h" namespace raco::ramses_adaptor { -using raco::ramses_base::RamsesHandle; +using ramses_base::RamsesHandle; class ILogicPropertyProvider { public: - virtual void getLogicNodes(std::vector& logicNodes) const = 0; - virtual const rlogic::Property* getProperty(const std::vector& propertyNamesVector) = 0; + virtual void getLogicNodes(std::vector& logicNodes) const = 0; + virtual ramses::Property* getProperty(const std::vector& propertyNamesVector) = 0; virtual void onRuntimeError(core::Errors& errors, std::string const& message, core::ErrorLevel level) = 0; - static const rlogic::Property* getPropertyRecursive(const rlogic::Property* property, const std::vector& propertyNames, size_t startIndex = 0) { + static ramses::Property* getPropertyRecursive(ramses::Property* property, const std::vector& propertyNames, size_t startIndex = 0) { for (size_t index = startIndex; index < propertyNames.size(); index++) { - if (property->getType() == rlogic::EPropertyType::Array) { + if (property->getType() == ramses::EPropertyType::Array) { // convert 1-bases Editor index back to 0-based index - property = property->getChild(std::stoi(propertyNames[index]) - 1); + int childIndex; + auto [ptr, error] = std::from_chars(propertyNames[index].data(), propertyNames[index].data() + propertyNames[index].size(), childIndex); + if (error == std::errc() && index > 0) { + property = property->getChild(childIndex - 1); + } else { + throw std::runtime_error("Invalid property name."); + } } else { property = property->getChild(propertyNames[index]); } @@ -54,8 +60,8 @@ struct ExportInformation { std::string type; const std::string name; - explicit ExportInformation(std::string type, std::string name) : type(std::move(type)), name(std::move(name)) {} - explicit ExportInformation(const ramses::ERamsesObjectType type, std::string name) : name(std::move(name)) { + explicit ExportInformation(std::string type, std::string_view name) : type(std::move(type)), name(std::move(name)) {} + explicit ExportInformation(const ramses::ERamsesObjectType type, std::string_view name) : name(std::move(name)) { this->type = fmt::format("{}", type); } }; @@ -65,7 +71,7 @@ struct ExportInformation { */ class ObjectAdaptor { public: - using SEditorObject = raco::core::SEditorObject; + using SEditorObject = core::SEditorObject; explicit ObjectAdaptor(SceneAdaptor* sceneAdaptor) : sceneAdaptor_{sceneAdaptor}, dirtyStatus_{true} {} virtual ~ObjectAdaptor(); diff --git a/components/libRamsesBase/include/ramses_adaptor/OrthographicCameraAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/OrthographicCameraAdaptor.h index ea895b90..1f8787ca 100644 --- a/components/libRamsesBase/include/ramses_adaptor/OrthographicCameraAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/OrthographicCameraAdaptor.h @@ -14,7 +14,7 @@ #include "components/DataChangeDispatcher.h" #include "user_types/OrthographicCamera.h" #include -#include +#include namespace raco::ramses_adaptor { @@ -23,18 +23,18 @@ class OrthographicCameraAdaptor : public SpatialAdaptor editorObject); ~OrthographicCameraAdaptor() override; - void getLogicNodes(std::vector& logicNodes) const override; + void getLogicNodes(std::vector& logicNodes) const override; bool sync(core::Errors* errors) override; - const rlogic::Property* getProperty(const std::vector& propertyNamesVector) override; + ramses::Property* getProperty(const std::vector& propertyNamesVector) override; - raco::ramses_base::RamsesCameraBinding cameraBinding(); + ramses_base::RamsesCameraBinding cameraBinding(); std::vector getExportInformation() const override; private: components::Subscription viewportSubscription_; components::Subscription frustrumSubscription_; - raco::ramses_base::RamsesCameraBinding cameraBinding_; + ramses_base::RamsesCameraBinding cameraBinding_; }; }; // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/include/ramses_adaptor/PerspectiveCameraAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/PerspectiveCameraAdaptor.h index 7e85f95a..13fd8475 100644 --- a/components/libRamsesBase/include/ramses_adaptor/PerspectiveCameraAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/PerspectiveCameraAdaptor.h @@ -25,16 +25,16 @@ class PerspectiveCameraAdaptor : public SpatialAdaptor& logicNodes) const override; - const rlogic::Property* getProperty(const std::vector& propertyNamesVector) override; + void getLogicNodes(std::vector& logicNodes) const override; + ramses::Property* getProperty(const std::vector& propertyNamesVector) override; - raco::ramses_base::RamsesCameraBinding cameraBinding(); + ramses_base::RamsesCameraBinding cameraBinding(); std::vector getExportInformation() const override; private: components::Subscription viewportSubscription_; components::Subscription frustrumSubscription_; - raco::ramses_base::RamsesCameraBinding cameraBinding_; + ramses_base::RamsesCameraBinding cameraBinding_; }; }; // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/include/ramses_adaptor/RenderBufferAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/RenderBufferAdaptor.h index 31db70d0..0ed3745b 100644 --- a/components/libRamsesBase/include/ramses_adaptor/RenderBufferAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/RenderBufferAdaptor.h @@ -12,7 +12,7 @@ #include "ramses_adaptor/ObjectAdaptor.h" #include "user_types/RenderBuffer.h" #include -#include +#include namespace raco::ramses_adaptor { diff --git a/components/libRamsesBase/include/ramses_adaptor/RenderBufferMSAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/RenderBufferMSAdaptor.h index 61f04b7c..06ee324d 100644 --- a/components/libRamsesBase/include/ramses_adaptor/RenderBufferMSAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/RenderBufferMSAdaptor.h @@ -12,7 +12,7 @@ #include "ramses_adaptor/ObjectAdaptor.h" #include "user_types/RenderBufferMS.h" #include -#include +#include namespace raco::ramses_adaptor { diff --git a/components/libRamsesBase/include/ramses_adaptor/RenderLayerAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/RenderLayerAdaptor.h index 43deb0bb..8853e14a 100644 --- a/components/libRamsesBase/include/ramses_adaptor/RenderLayerAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/RenderLayerAdaptor.h @@ -12,7 +12,7 @@ #include "ramses_adaptor/ObjectAdaptor.h" #include "ramses_base/RamsesHandles.h" #include "user_types/RenderLayer.h" -#include +#include namespace raco::ramses_adaptor { @@ -23,8 +23,8 @@ class RenderLayerAdaptor : public TypedObjectAdaptor getExportInformation() const override; - void getLogicNodes(std::vector& logicNodes) const override; - const rlogic::Property* getProperty(const std::vector& propertyNamesVector) override; + void getLogicNodes(std::vector& logicNodes) const override; + ramses::Property* getProperty(const std::vector& propertyNamesVector) override; void onRuntimeError(core::Errors& errors, std::string const& message, core::ErrorLevel level) override; private: @@ -32,7 +32,7 @@ class RenderLayerAdaptor : public TypedObjectAdaptor& objs, const std::string& tag, bool parentActive, const std::set& materialFilterTags, bool materialFilterExclusive, int32_t& orderIndex, bool sceneGraphOrder); void addNestedLayers(core::Errors* errors, ramses_base::RamsesRenderGroup container, const std::vector& layers, const std::string& tag, int32_t orderIndex, bool sceneGraphOrder); - raco::ramses_base::RamsesRenderGroupBinding binding_; + ramses_base::RamsesRenderGroupBinding binding_; std::array subscriptions_; }; diff --git a/components/libRamsesBase/include/ramses_adaptor/RenderPassAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/RenderPassAdaptor.h index 634e0992..ee9fe551 100644 --- a/components/libRamsesBase/include/ramses_adaptor/RenderPassAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/RenderPassAdaptor.h @@ -11,7 +11,7 @@ #include "ramses_adaptor/ObjectAdaptor.h" #include "user_types/RenderPass.h" -#include +#include namespace raco::ramses_adaptor { @@ -22,14 +22,14 @@ class RenderPassAdaptor : public TypedObjectAdaptor getExportInformation() const override; - void getLogicNodes(std::vector& logicNodes) const override; - const rlogic::Property* getProperty(const std::vector& propertyNamesVector) override; + void getLogicNodes(std::vector& logicNodes) const override; + ramses::Property* getProperty(const std::vector& propertyNamesVector) override; void onRuntimeError(core::Errors& errors, std::string const& message, core::ErrorLevel level) override; private: - raco::ramses_base::UniqueRamsesRenderPassBinding binding_; + ramses_base::UniqueRamsesRenderPassBinding binding_; - std::array subscriptions_; + std::array subscriptions_; }; }; // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/include/ramses_adaptor/RenderTargetAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/RenderTargetAdaptor.h index f05ed43a..9bf284d2 100644 --- a/components/libRamsesBase/include/ramses_adaptor/RenderTargetAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/RenderTargetAdaptor.h @@ -11,22 +11,28 @@ #include "ramses_adaptor/ObjectAdaptor.h" #include "user_types/RenderTarget.h" -#include +#include namespace raco::ramses_adaptor { -class RenderTargetAdaptor : public TypedObjectAdaptor { +class RenderBufferAdaptor; +class RenderBufferMSAdaptor; + +template +class RenderTargetAdaptorT : public TypedObjectAdaptor { public: - explicit RenderTargetAdaptor(SceneAdaptor* sceneAdaptor, std::shared_ptr editorObject); + explicit RenderTargetAdaptorT(SceneAdaptor* sceneAdaptor, std::shared_ptr editorObject); bool sync(core::Errors* errors) override; std::vector getExportInformation() const override; private: - template - bool collectBuffers(std::vector& buffers, const std::initializer_list& userTypeBuffers, ramses::RenderTargetDescription& rtDesc, core::Errors* errors); + bool collectBuffers(std::vector& buffers, const std::vector < std::shared_ptr> & userTypeBuffers, ramses::RenderTargetDescription& rtDesc, core::Errors* errors); - std::array subscriptions_; + components::Subscription subscription_; }; +using RenderTargetAdaptor = RenderTargetAdaptorT; +using RenderTargetMSAdaptor = RenderTargetAdaptorT; + }; // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/include/ramses_adaptor/SceneAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/SceneAdaptor.h index 6d691dcb..5c89657d 100644 --- a/components/libRamsesBase/include/ramses_adaptor/SceneAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/SceneAdaptor.h @@ -11,8 +11,10 @@ #include "core/Context.h" #include "ramses_adaptor/LinkAdaptor.h" -#include "ramses_base/LogicEngine.h" +//#include "ramses_base/LogicEngine.h" #include "ramses_base/RamsesHandles.h" +#include "ramses_base/BaseEngineBackend.h" +#include "ramses_adaptor/utilities.h" #include "components/DataChangeDispatcher.h" #include #include "core/Link.h" @@ -23,14 +25,14 @@ class ObjectAdaptor; using SRamsesAdaptorDispatcher = std::shared_ptr; class SceneAdaptor { - using Project = raco::core::Project; - using SEditorObject = raco::core::SEditorObject; - using SLink = raco::core::SLink; - using ValueHandle = raco::core::ValueHandle; - using SEditorObjectSet = raco::core::SEditorObjectSet; + using Project = core::Project; + using SEditorObject = core::SEditorObject; + using SLink = core::SLink; + using ValueHandle = core::ValueHandle; + using SEditorObjectSet = core::SEditorObjectSet; public: - explicit SceneAdaptor(ramses::RamsesClient* client, ramses_base::LogicEngine* logicEngine, ramses::sceneId_t id, Project* project, components::SDataChangeDispatcher dispatcher, core::Errors *errors, bool optimizeForExport = false); + explicit SceneAdaptor(ramses::RamsesClient* client, ramses::sceneId_t id, Project* project, components::SDataChangeDispatcher dispatcher, core::Errors* errors, bool optimizeForExport = false); ~SceneAdaptor(); @@ -39,12 +41,13 @@ class SceneAdaptor { /* START: Adaptor API */ ramses::RamsesClient* client(); - ramses_base::LogicEngine& logicEngine(); + ramses::LogicEngine& logicEngine(); const ramses::RamsesClient* client() const; const SRamsesAdaptorDispatcher dispatcher() const; const ramses_base::RamsesAppearance defaultAppearance(bool withMeshNormals); - const ramses_base::RamsesArrayResource defaultVertices(); - const ramses_base::RamsesArrayResource defaultIndices(); + const ramses_base::RamsesArrayResource defaultVertices(int index); + const ramses_base::RamsesArrayResource defaultNormals(int index); + const ramses_base::RamsesArrayResource defaultIndices(int index); ObjectAdaptor* lookupAdaptor(const core::SEditorObject& editorObject) const; Project& project() const; @@ -60,7 +63,10 @@ class SceneAdaptor { bool optimizeForExport() const; - rlogic::EFeatureLevel featureLevel() const; + ramses::EFeatureLevel featureLevel() const; + + void updateRuntimeError(const ramses::Issue& issue); + void clearRuntimeError(); private: bool needAdaptor(SEditorObject object); @@ -72,36 +78,27 @@ class SceneAdaptor { void performBulkEngineUpdate(const core::SEditorObjectSet& changedObjects); - struct DependencyNode { - SEditorObject object; - SEditorObjectSet referencedObjects; - }; - - void depthFirstSearch(data_storage::ReflectionInterface* object, DependencyNode& item, SEditorObjectSet const& instances, SEditorObjectSet& sortedObjs, std::vector& outSorted); - - void depthFirstSearch(SEditorObject object, SEditorObjectSet const& instances, SEditorObjectSet& sortedObjs, std::vector& outSorted); void rebuildSortedDependencyGraph(SEditorObjectSet const& objects); - void updateRuntimeErrorList(); void deleteUnusedDefaultResources(); ramses::RamsesClient* client_; - ramses_base::LogicEngine* logicEngine_; Project* project_; core::Errors* errors_; ramses_base::RamsesScene scene_{}; + + ramses_base::BaseEngineBackend::UniqueLogicEngine logicEngine_; + bool optimizeForExport_ = false; // Fallback resources: used when MeshNode doesn't have valid shader program or mesh data - ramses_base::RamsesEffect defaultEffect_{}; - ramses_base::RamsesEffect defaultEffectWithNormals_{}; - ramses_base::RamsesAppearance defaultAppearance_; ramses_base::RamsesAppearance defaultAppearanceWithNormals_; - ramses_base::RamsesArrayResource defaultIndices_{}; - ramses_base::RamsesArrayResource defaultVertices_{}; + std::array defaultIndices_; + std::array defaultVertices_; + std::array defaultNormals_; std::map> adaptors_{}; @@ -122,6 +119,8 @@ class SceneAdaptor { bool adaptorStatusDirty_ = false; std::vector dependencyGraph_; + + SEditorObject lastErrorObject_ = nullptr; }; } // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/include/ramses_adaptor/SceneBackend.h b/components/libRamsesBase/include/ramses_adaptor/SceneBackend.h index 0893e753..af444633 100644 --- a/components/libRamsesBase/include/ramses_adaptor/SceneBackend.h +++ b/components/libRamsesBase/include/ramses_adaptor/SceneBackend.h @@ -13,7 +13,6 @@ #include "ramses_adaptor/SceneAdaptor.h" #include "ramses_base/RamsesHandles.h" #include "components/DataChangeDispatcher.h" -#include "ramses_base/LogicEngine.h" #include #include #include "core/SceneBackendInterface.h" @@ -28,21 +27,23 @@ class BaseEngineBackend; namespace raco::ramses_adaptor { -class SceneBackend : public raco::core::SceneBackendInterface { +class SceneBackend : public core::SceneBackendInterface { public: static ramses::sceneId_t toSceneId(int i); - using Project = raco::core::Project; - using SEditorObject = raco::core::SEditorObject; - using SDataChangeDispatcher = raco::components::SDataChangeDispatcher; + using Project = core::Project; + using SEditorObject = core::SEditorObject; + using SDataChangeDispatcher = components::SDataChangeDispatcher; explicit SceneBackend(ramses_base::BaseEngineBackend& engine, const SDataChangeDispatcher& dispatcher); - void setScene(Project* project, core::Errors* errors, bool optimizeForExport); + void setScene(Project* project, core::Errors* errors, bool optimizeForExport, ramses::sceneId_t sceneId); void reset(); void flush(); void readDataFromEngine(core::DataChangeRecorder &recorder); ramses::sceneId_t currentSceneId() const; - const ramses::Scene* currentScene() const; + ramses::Scene* currentScene() const; + + std::optional getLastError(); SceneAdaptor* sceneAdaptor() const { return scene_.get(); @@ -53,19 +54,15 @@ class SceneBackend : public raco::core::SceneBackendInterface { uint64_t currentSceneIdValue() const override; std::vector getSceneItemDescriptions() const override; std::string getExportedObjectNames(SEditorObject editorObject) const override; + + ramses::LogicEngine* logicEngine() const; - static bool discardLogicEngineMessage(std::string_view message); + static bool discardRamsesMessage(std::string_view message); private: - /** - * @brief call LogicEngine validate() and filter out warnings that RamsesComposer is - * deliberately ignoring. - */ - std::vector logicEngineFilteredValidation() const; std::string ramsesFilteredValidationReport(core::ErrorLevel minLevel) const; ramses::RamsesClient* client() const; - ramses_base::LogicEngine* logicEngine() const; SDataChangeDispatcher dispatcher_; ramses_base::BaseEngineBackend& engine_; diff --git a/components/libRamsesBase/include/ramses_adaptor/SkinAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/SkinAdaptor.h index 0d087650..a54ff034 100644 --- a/components/libRamsesBase/include/ramses_adaptor/SkinAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/SkinAdaptor.h @@ -18,17 +18,17 @@ namespace raco::ramses_adaptor { class SkinAdaptor : public UserTypeObjectAdaptor { public: - SkinAdaptor(SceneAdaptor *sceneAdaptor, raco::user_types::SSkin skin); + SkinAdaptor(SceneAdaptor *sceneAdaptor, user_types::SSkin skin); bool sync(core::Errors* errors) override; std::vector getExportInformation() const override; private: - std::vector skinBindings_; + std::vector skinBindings_; - raco::components::Subscription dirtySubscription_; - std::array subscriptions_; + components::Subscription dirtySubscription_; + std::array subscriptions_; }; } // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/include/ramses_adaptor/TextureExternalAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/TextureExternalAdaptor.h index a38bcb8c..6b4c62f2 100644 --- a/components/libRamsesBase/include/ramses_adaptor/TextureExternalAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/TextureExternalAdaptor.h @@ -12,7 +12,7 @@ #include "ramses_adaptor/ObjectAdaptor.h" #include "user_types/TextureExternal.h" -#include +#include #include diff --git a/components/libRamsesBase/include/ramses_adaptor/TextureSamplerAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/TextureSamplerAdaptor.h index d629c2ba..c1aaac95 100644 --- a/components/libRamsesBase/include/ramses_adaptor/TextureSamplerAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/TextureSamplerAdaptor.h @@ -14,8 +14,8 @@ #include "components/DataChangeDispatcher.h" #include "user_types/Texture.h" #include -#include -#include +#include +#include namespace raco::ramses_adaptor { @@ -31,7 +31,7 @@ class TextureSamplerAdaptor : public TypedObjectAdaptor& getFallbackTextureData(bool flipped); private: - ramses_base::RamsesTexture2D createTexture(core::Errors* errors, raco::ramses_base::PngDecodingInfo &decodingInfo); + ramses_base::RamsesTexture2D createTexture(core::Errors* errors, ramses_base::PngDecodingInfo &decodingInfo); ramses_base::RamsesTexture2D getFallbackTexture(); std::array subscriptions_; diff --git a/components/libRamsesBase/include/ramses_adaptor/TimerAdaptor.h b/components/libRamsesBase/include/ramses_adaptor/TimerAdaptor.h index 49375882..cf94b9a2 100644 --- a/components/libRamsesBase/include/ramses_adaptor/TimerAdaptor.h +++ b/components/libRamsesBase/include/ramses_adaptor/TimerAdaptor.h @@ -19,10 +19,10 @@ namespace raco::ramses_adaptor { class TimerAdaptor final : public UserTypeObjectAdaptor, public ILogicPropertyProvider { public: - TimerAdaptor(SceneAdaptor* sceneAdaptor, raco::user_types::STimer timer); + TimerAdaptor(SceneAdaptor* sceneAdaptor, user_types::STimer timer); - void getLogicNodes(std::vector& logicNodes) const override; - const rlogic::Property* getProperty(const std::vector& propertyNamesVector) override; + void getLogicNodes(std::vector& logicNodes) const override; + ramses::Property* getProperty(const std::vector& propertyNamesVector) override; void onRuntimeError(core::Errors& errors, std::string const& message, core::ErrorLevel level) override; std::vector getExportInformation() const override; @@ -30,10 +30,10 @@ class TimerAdaptor final : public UserTypeObjectAdaptor, publ void readDataFromEngine(core::DataChangeRecorder& recorder); private: - raco::ramses_base::RamsesTimerNode timerNode_; - raco::components::Subscription dirtySubscription_; - raco::components::Subscription nameSubscription_; - raco::components::Subscription inputSubscription_; + ramses_base::RamsesTimerNode timerNode_; + components::Subscription dirtySubscription_; + components::Subscription nameSubscription_; + components::Subscription inputSubscription_; }; }; // namespace raco::ramses_adaptor \ No newline at end of file diff --git a/components/libRamsesBase/include/ramses_adaptor/utilities.h b/components/libRamsesBase/include/ramses_adaptor/utilities.h index 5ea90db4..c3560f9b 100644 --- a/components/libRamsesBase/include/ramses_adaptor/utilities.h +++ b/components/libRamsesBase/include/ramses_adaptor/utilities.h @@ -18,7 +18,6 @@ #include "core/MeshCacheInterface.h" #include "data_storage/Value.h" #include "ramses_adaptor/BuildOptions.h" -#include "ramses_adaptor/SceneAdaptor.h" #include "ramses_base/EnumerationTranslations.h" #include "ramses_base/RamsesHandles.h" #include "user_types/EngineTypeAnnotation.h" @@ -28,164 +27,85 @@ #include "utils/MathUtils.h" #include -#include -#include +#include +#include #include namespace raco::ramses_adaptor { -static constexpr const char* defaultVertexShader = - "#version 300 es\n\ - precision mediump float;\n\ - in vec3 a_Position;\n\ - \n\ - uniform mat4 mvpMatrix;\n\ - void main() {\n\ - gl_Position = mvpMatrix * vec4(a_Position.xyz, 1.0);\n\ - }"; - -static constexpr const char* defaultVertexShaderWithNormals = - R"( -#version 300 es -precision mediump float; -in vec3 a_Position; -in vec3 a_Normal; -out float lambertian; -uniform mat4 mvpMatrix; -void main() { - lambertian = mix(0.4, 0.8, max(abs(dot(vec3(1.5, 2.4, 1.0), a_Normal)), 0.0)); - gl_Position = mvpMatrix * vec4(a_Position, 1.0); -} -)"; - -static constexpr const char* defaultFragmentShader = - "#version 300 es\n\ - precision mediump float;\n\ - \n\ - out vec4 FragColor;\n\ - \n\ - void main() {\n\ - FragColor = vec4(1.0, 0.0, 0.2, 1.0); \n\ - }"; - -static constexpr const char* defaultFragmentShaderWithNormals = - R"( -#version 300 es -precision mediump float; -in float lambertian; -out vec4 fragColor; -void main() { - fragColor = vec4(1.0, 0.5, 0.0, 1.0) * lambertian; -} -)"; - -static constexpr const char* defaultEffectName = "raco::ramses_adaptor::DefaultEffectWithoutNormals"; -static constexpr const char* defaultEffectWithNormalsName = "raco::ramses_adaptor::DefaultEffectWithNormals"; -static constexpr const char* defaultAppearanceName = "raco::ramses_adaptor::DefaultAppearanceWithoutNormals"; -static constexpr const char* defaultAppearanceWithNormalsName = "raco::ramses_adaptor::DefaultAppearanceWithNormals"; -static constexpr const char* defaultIndexDataBufferName = "raco::ramses_adaptor::DefaultIndexDataBuffer"; -static constexpr const char* defaultVertexDataBufferName = "raco::ramses_adaptor::DefaultVertexDataBuffer"; -static constexpr const char* defaultRenderGroupName = "raco::ramses_adaptor::DefaultRenderGroup"; -static constexpr const char* defaultRenderPassName = "raco::ramses_adaptor::DefaultRenderPass"; - -struct Vec3f { - float x, y, z; - bool operator==(const Vec3f& other) const { - return x == other.x && y == other.y && z == other.z; - } - bool operator==(const std::array& other) const { - return x == other[0] && y == other[1] && z == other[2]; - } - bool operator!=(const Vec3f& other) const { - return x != other.x || y != other.y || z != other.z; - } -}; +class SceneAdaptor; -struct Rotation final : public Vec3f { - template - static void sync(const std::shared_ptr& source, ramses::Node& target) { - static_assert(std::is_base_of::value); - Rotation value{from(source)}; - auto status = target.setRotation(value.x, value.y, value.z, raco::ramses_adaptor::RAMSES_ROTATION_CONVENTION); - assert(status == ramses::StatusOK); - } - static Rotation from(const ramses::Node& node) { - Rotation result; - ramses::ERotationConvention convention; - auto status = node.getRotation(result.x, result.y, result.z, convention); - assert(status == ramses::StatusOK); - return result; - } - template - static Rotation from(const std::shared_ptr& node) { - static_assert(std::is_base_of::value); - return {static_cast(node->rotation_->x.asDouble()), static_cast(node->rotation_->y.asDouble()), static_cast(node->rotation_->z.asDouble())}; - } -}; -struct Translation final : public Vec3f { - template - static void sync(const std::shared_ptr& source, ramses::Node& target) { - static_assert(std::is_base_of::value); - Translation value{from(source)}; - auto status = target.setTranslation(value.x, value.y, value.z); - assert(status == ramses::StatusOK); +struct BoundingBox { + BoundingBox() + : min_(std::numeric_limits::max()), + max_(std::numeric_limits::lowest()) { } - static Translation from(const ramses::Node& node) { - Translation result; - auto status = node.getTranslation(result.x, result.y, result.z); - assert(status == ramses::StatusOK); - return result; + + BoundingBox(glm::vec3 min, glm::vec3 max) + : min_(min), + max_(max) { } - template - static Translation from(const std::shared_ptr& node) { - static_assert(std::is_base_of::value); - return {static_cast(node->translation_->x.asDouble()), static_cast(node->translation_->y.asDouble()), static_cast(node->translation_->z.asDouble())}; + + glm::vec3 min_; + glm::vec3 max_; + + bool empty() const { + return min_.x >= max_.x || min_.y >= max_.y || min_.z >= max_.z; } -}; -struct Scaling final : public Vec3f { - template - static void sync(const std::shared_ptr& source, ramses::Node& target) { - static_assert(std::is_base_of::value); - Scaling value{from(source)}; - auto status = target.setScaling(value.x, value.y, value.z); - assert(status == ramses::StatusOK); + glm::vec3 center() const { + return (min_ + max_) / 2.0f; } - static Scaling from(const ramses::Node& node) { - Scaling result; - auto status = node.getScaling(result.x, result.y, result.z); - assert(status == ramses::StatusOK); - return result; + + float size() const { + return glm::length(max_ - min_) / 2.0f; } - template - static Scaling from(const std::shared_ptr& node) { - static_assert(std::is_base_of::value); - return {static_cast(node->scaling_->x.asDouble()), static_cast(node->scaling_->y.asDouble()), static_cast(node->scaling_->z.asDouble())}; + + void merge(glm::vec3 point) { + min_ = glm::min(min_, point); + max_ = glm::max(max_, point); } + + void merge(const BoundingBox& bbox) { + min_ = glm::min(min_, bbox.min_); + max_ = glm::max(max_, bbox.max_); + } }; -constexpr ramses::EDataType convert(core::MeshData::VertexAttribDataType type) { - switch (type) { - case core::MeshData::VertexAttribDataType::VAT_Float: - return ramses::EDataType::Float; - case core::MeshData::VertexAttribDataType::VAT_Float2: - return ramses::EDataType::Vector2F; - case core::MeshData::VertexAttribDataType::VAT_Float3: - return ramses::EDataType::Vector3F; - case core::MeshData::VertexAttribDataType::VAT_Float4: - return ramses::EDataType::Vector4F; - default: - assert(false && "Unknown VertexAttribDataType"); - } - return ramses::EDataType::Float; + +inline glm::vec3 getRamsesRotation(const ramses::Node* ramsesNode) { + glm::vec3 vec; + ramsesNode->getRotation(vec); + return vec; +} + +inline glm::vec3 getRacoRotation(user_types::SNode node) { + return core::ValueHandle(node, &user_types::Node::rotation_).as(); +} + +inline glm::vec3 getRamsesTranslation(const ramses::Node* ramsesNode) { + glm::vec3 vec; + ramsesNode->getTranslation(vec); + return vec; +} + +inline glm::vec3 getRacoTranslation(user_types::SNode node) { + return core::ValueHandle(node, &user_types::Node::translation_).as(); +} + +inline glm::vec3 getRamsesScaling(const ramses::Node* ramsesNode) { + glm::vec3 vec; + ramsesNode->getScaling(vec); + return vec; } -template -inline const rlogic::Property* propertyByNames(const rlogic::Property* property, Args... names); +inline glm::vec3 getRacoScaling(user_types::SNode node) { + return core::ValueHandle(node, &user_types::Node::scaling_).as(); +} template -inline const rlogic::Property* propertyByNames(const rlogic::Property* property, const T& name, Args... names) { +inline const ramses::Property* propertyByNames(const ramses::Property* property, const T& name, Args... names) { if constexpr (sizeof...(Args) > 0) { return propertyByNames(property->getChild(name), names...); } else { @@ -193,7 +113,7 @@ inline const rlogic::Property* propertyByNames(const rlogic::Property* property, } } -inline bool setLuaInputInEngine(rlogic::Property* property, const core::ValueHandle& valueHandle) { +inline bool setLuaInputInEngine(ramses::Property* property, const core::ValueHandle& valueHandle) { assert(property != nullptr); using core::PrimitiveType; @@ -214,17 +134,17 @@ inline bool setLuaInputInEngine(rlogic::Property* property, const core::ValueHan case PrimitiveType::Struct: { auto typeDesc = &valueHandle.constValueRef()->asStruct().getTypeDescription(); if (typeDesc == &core::Vec2f::typeDescription) { - success = property->set(rlogic::vec2f{valueHandle[0].as(), valueHandle[1].as()}); + success = property->set(ramses::vec2f{valueHandle[0].as(), valueHandle[1].as()}); } else if (typeDesc == &core::Vec3f::typeDescription) { - success = property->set(rlogic::vec3f{valueHandle[0].as(), valueHandle[1].as(), valueHandle[2].as()}); + success = property->set(ramses::vec3f{valueHandle[0].as(), valueHandle[1].as(), valueHandle[2].as()}); } else if (typeDesc == &core::Vec4f::typeDescription) { - success = property->set(rlogic::vec4f{valueHandle[0].as(), valueHandle[1].as(), valueHandle[2].as(), valueHandle[3].as()}); + success = property->set(ramses::vec4f{valueHandle[0].as(), valueHandle[1].as(), valueHandle[2].as(), valueHandle[3].as()}); } else if (typeDesc == &core::Vec2i::typeDescription) { - success = property->set(rlogic::vec2i{valueHandle[0].as(), valueHandle[1].as()}); + success = property->set(ramses::vec2i{valueHandle[0].as(), valueHandle[1].as()}); } else if (typeDesc == &core::Vec3i::typeDescription) { - success = property->set(rlogic::vec3i{valueHandle[0].as(), valueHandle[1].as(), valueHandle[2].as()}); + success = property->set(ramses::vec3i{valueHandle[0].as(), valueHandle[1].as(), valueHandle[2].as()}); } else if (typeDesc == &core::Vec4i::typeDescription) { - success = property->set(rlogic::vec4i{valueHandle[0].as(), valueHandle[1].as(), valueHandle[2].as(), valueHandle[3].as()}); + success = property->set(ramses::vec4i{valueHandle[0].as(), valueHandle[1].as(), valueHandle[2].as(), valueHandle[3].as()}); } break; } @@ -234,7 +154,7 @@ inline bool setLuaInputInEngine(rlogic::Property* property, const core::ValueHan case PrimitiveType::Table: success = true; for (size_t i{0}; i < valueHandle.size(); i++) { - if (property->getType() == rlogic::EPropertyType::Array) { + if (property->getType() == ramses::EPropertyType::Array) { success = setLuaInputInEngine(property->getChild(i), valueHandle[i]) && success; } else { success = setLuaInputInEngine(property->getChild(valueHandle[i].getPropName()), valueHandle[i]) && success; @@ -246,11 +166,11 @@ inline bool setLuaInputInEngine(rlogic::Property* property, const core::ValueHan return success; } -void getOutputFromEngine(const rlogic::Property& property, const core::ValueHandle& valueHandle, core::DataChangeRecorder& recorder); +void getOutputFromEngine(const ramses::Property& property, const core::ValueHandle& valueHandle, core::DataChangeRecorder& recorder); -inline void getComplexLuaOutputFromEngine(const rlogic::Property& property, const core::ValueHandle& valueHandle, core::DataChangeRecorder& recorder) { +inline void getComplexLuaOutputFromEngine(const ramses::Property& property, const core::ValueHandle& valueHandle, core::DataChangeRecorder& recorder) { for (size_t i{0}; i < valueHandle.size(); i++) { - if (property.getType() == rlogic::EPropertyType::Array) { + if (property.getType() == ramses::EPropertyType::Array) { getOutputFromEngine(*property.getChild(i), valueHandle[i], recorder); } else { getOutputFromEngine(*property.getChild(valueHandle[i].getPropName()), valueHandle[i], recorder); @@ -258,13 +178,13 @@ inline void getComplexLuaOutputFromEngine(const rlogic::Property& property, cons } } -inline void getOutputFromEngine(const rlogic::Property& property, const core::ValueHandle& valueHandle, core::DataChangeRecorder& recorder) { +inline void getOutputFromEngine(const ramses::Property& property, const core::ValueHandle& valueHandle, core::DataChangeRecorder& recorder) { using core::PrimitiveType; // read quaternion rotation data - if (valueHandle.isVec3f() && property.getType() == rlogic::EPropertyType::Vec4f) { - auto [x, y, z, w] = property.get().value(); - auto [eulerX, eulerY, eulerZ] = raco::utils::math::quaternionToXYZDegrees(x, y, z, w); + if (valueHandle.isVec3f() && property.getType() == ramses::EPropertyType::Vec4f) { + auto v = property.get().value(); + auto [eulerX, eulerY, eulerZ] = utils::math::quaternionToXYZDegrees(v.x, v.y, v.z, v.w); core::CodeControlledPropertyModifier::setVec3f(valueHandle, eulerX, eulerY, eulerZ, recorder); return; } @@ -293,23 +213,23 @@ inline void getOutputFromEngine(const rlogic::Property& property, const core::Va case PrimitiveType::Struct: { auto typeDesc = &valueHandle.constValueRef()->asStruct().getTypeDescription(); if (typeDesc == &core::Vec2f::typeDescription) { - auto [x, y] = property.get().value(); - core::CodeControlledPropertyModifier::setVec2f(valueHandle, x, y, recorder); + auto v = property.get().value(); + core::CodeControlledPropertyModifier::setVec2f(valueHandle, v.x, v.y, recorder); } else if (typeDesc == &core::Vec3f::typeDescription) { - auto [x, y, z] = property.get().value(); - core::CodeControlledPropertyModifier::setVec3f(valueHandle, x, y, z, recorder); + auto v = property.get().value(); + core::CodeControlledPropertyModifier::setVec3f(valueHandle, v.x, v.y, v.z, recorder); } else if (typeDesc == &core::Vec4f::typeDescription) { - auto [x, y, z, w] = property.get().value(); - core::CodeControlledPropertyModifier::setVec4f(valueHandle, x, y, z, w, recorder); + auto v = property.get().value(); + core::CodeControlledPropertyModifier::setVec4f(valueHandle, v.x, v.y, v.z, v.w, recorder); } else if (typeDesc == &core::Vec2i::typeDescription) { - auto [i1, i2] = property.get().value(); - core::CodeControlledPropertyModifier::setVec2i(valueHandle, i1, i2, recorder); + auto v = property.get().value(); + core::CodeControlledPropertyModifier::setVec2i(valueHandle, v.x, v.y, recorder); } else if (typeDesc == &core::Vec3i::typeDescription) { - auto [i1, i2, i3] = property.get().value(); - core::CodeControlledPropertyModifier::setVec3i(valueHandle, i1, i2, i3, recorder); + auto v = property.get().value(); + core::CodeControlledPropertyModifier::setVec3i(valueHandle, v.x, v.y, v.z, recorder); } else if (typeDesc == &core::Vec4i::typeDescription) { - auto [i1, i2, i3, i4] = property.get().value(); - core::CodeControlledPropertyModifier::setVec4i(valueHandle, i1, i2, i3, i4, recorder); + auto v = property.get().value(); + core::CodeControlledPropertyModifier::setVec4i(valueHandle, v.x, v.y, v.z, v.w, recorder); } else { getComplexLuaOutputFromEngine(property, valueHandle, recorder); } @@ -322,60 +242,31 @@ inline void getOutputFromEngine(const rlogic::Property& property, const core::Va } } -inline void setDepthWrite(ramses::Appearance* appearance, const core::ValueHandle& valueHandle) { - appearance->setDepthWrite(valueHandle.as() ? ramses::EDepthWrite_Enabled : ramses::EDepthWrite_Disabled); -} - -inline void setDepthFunction(ramses::Appearance* appearance, const core::ValueHandle& valueHandle) { - auto ramsesDepthFunc = ramses_base::enumerationTranslationsDepthFunc.at(static_cast(valueHandle.asInt())); - appearance->setDepthFunction(ramsesDepthFunc); -} - inline ramses::EDepthWrite getDepthWriteMode(const ramses::Appearance* appearance) { ramses::EDepthWrite depthWrite; appearance->getDepthWriteMode(depthWrite); return depthWrite; } -inline void setBlendMode(ramses::Appearance* appearance, const core::ValueHandle& options) { - int colorOp = options.get("blendOperationColor").as(); - auto ramsesColorOp = ramses_base::enumerationTranslationsBlendOperation.at(static_cast(colorOp)); - int alphaOp = options.get("blendOperationAlpha").as(); - auto ramsesAlphaOp = ramses_base::enumerationTranslationsBlendOperation.at(static_cast(alphaOp)); - appearance->setBlendingOperations(ramsesColorOp, ramsesAlphaOp); - - int srcColor = options.get("blendFactorSrcColor").as(); - auto ramsesSrcColor = ramses_base::enumerationTranslationsBlendFactor.at(static_cast(srcColor)); - - int destColor = options.get("blendFactorDestColor").as(); - auto ramsesDestColor = ramses_base::enumerationTranslationsBlendFactor.at(static_cast(destColor)); - - int srcAlpha = options.get("blendFactorSrcAlpha").as(); - auto ramsesSrcAlpha = ramses_base::enumerationTranslationsBlendFactor.at(static_cast(srcAlpha)); - - int destAlpha = options.get("blendFactorDestAlpha").as(); - auto ramsesDestAlpha = ramses_base::enumerationTranslationsBlendFactor.at(static_cast(destAlpha)); - - appearance->setBlendingFactors(ramsesSrcColor, ramsesDestColor, ramsesSrcAlpha, ramsesDestAlpha); +template +void ramsesSetUniform(ramses::Appearance& appearance, std::string_view uniformName, UniformType value) { + ramses::UniformInput uniform = appearance.getEffect().findUniformInput(uniformName).value(); + appearance.setInputValue(uniform, value); } -inline void setBlendColor(ramses::Appearance* appearance, const core::ValueHandle& color) { - appearance->setBlendingColor( - color.get("x").as(), - color.get("y").as(), - color.get("z").as(), - color.get("w").as()); +inline bool isArrayOfStructs(const ramses::Property& property) { + return property.getType() == ramses::EPropertyType::Array && property.getChildCount() > 0 && property.getChild(0)->getType() == ramses::EPropertyType::Struct; } -inline void setCullMode(ramses::Appearance* appearance, const core::ValueHandle& valueHandle) { - auto ramsesCullMode = ramses_base::enumerationTranslationsCullMode.at(static_cast(valueHandle.asInt())); - appearance->setCullingMode(ramsesCullMode); -} +ramses_base::RamsesNodeBinding lookupNodeBinding(const SceneAdaptor* sceneAdaptor, core::SEditorObject node); -inline bool isArrayOfStructs(const rlogic::Property& property) { - return property.getType() == rlogic::EPropertyType::Array && property.getChildCount() > 0 && property.getChild(0)->getType() == rlogic::EPropertyType::Struct; -} +struct DependencyNode { + core::SEditorObject object; + core::SEditorObjectSet referencedObjects; +}; + +std::vector buildSortedDependencyGraph(core::SEditorObjectSet const& objects); -raco::ramses_base::RamsesNodeBinding lookupNodeBinding(const SceneAdaptor* sceneAdaptor, core::SEditorObject node); +ramses_base::RamsesArrayResource arrayResourceFromAttribute(ramses::Scene* scene, core::SharedMeshData mesh, int attribIndex, std::string_view name); }; // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/include/ramses_base/BaseEngineBackend.h b/components/libRamsesBase/include/ramses_base/BaseEngineBackend.h index 0e158fb3..fed87d97 100644 --- a/components/libRamsesBase/include/ramses_base/BaseEngineBackend.h +++ b/components/libRamsesBase/include/ramses_base/BaseEngineBackend.h @@ -9,12 +9,12 @@ */ #pragma once -#include -#include -#include -#include +#include +#include +#include +#include +#include #include "ramses_base/CoreInterfaceImpl.h" -#include "ramses_base/LogicEngine.h" #include #include @@ -26,27 +26,30 @@ namespace raco::ramses_base { class BaseEngineBackend { Q_DISABLE_COPY(BaseEngineBackend) public: - static const rlogic::EFeatureLevel minFeatureLevel = rlogic::EFeatureLevel::EFeatureLevel_01; - static const rlogic::EFeatureLevel maxFeatureLevel = rlogic::EFeatureLevel::EFeatureLevel_05; + static const ramses::EFeatureLevel minFeatureLevel; + static const ramses::EFeatureLevel maxFeatureLevel; static const std::string featureLevelDescriptions; typedef std::unique_ptr> UniqueClient; typedef std::unique_ptr> UniqueScene; - typedef std::unique_ptr UniqueLogicEngine; + typedef std::unique_ptr UniqueFramework; + typedef std::unique_ptr> UniqueLogicEngine; + // The feature level used in the RamsesFrameworkConfig here is just a placeholder. BaseEngineBackend( - rlogic::EFeatureLevel featureLevel, - const ramses::RamsesFrameworkConfig& frameworkConfig = ramses::RamsesFrameworkConfig{}, + const ramses::RamsesFrameworkConfig& frameworkConfig = ramses::RamsesFrameworkConfig{minFeatureLevel}, const char* applicationName = "Ramses Composer"); virtual ~BaseEngineBackend(); bool connect(); ramses::RamsesFramework& framework(); ramses::RamsesClient& client(); - LogicEngine& logicEngine(); - raco::core::EngineInterface* coreInterface(); + core::EngineInterface* coreInterface(); + ramses::LogicEngine* logicEngine(); - void setFeatureLevel(rlogic::EFeatureLevel newFeatureLevel); - rlogic::EFeatureLevel getFeatureLevel(); + + ramses::EFeatureLevel featureLevel() const; + + void setFeatureLevel(ramses::EFeatureLevel newFeatureLevel); /** * Scene used for internal validation / creation of resource. @@ -54,11 +57,28 @@ class BaseEngineBackend { */ ramses::Scene& internalScene(); + static ramses::sceneId_t abstractSceneId(); + + static ramses::RamsesFrameworkConfig& defaultRamsesFrameworkConfig(); + +protected: + virtual void reset(); + virtual void setup(ramses::EFeatureLevel featureLevel); + private: - ramses::RamsesFramework framework_; - UniqueLogicEngine logicEngine_; + const ramses::RamsesFrameworkConfig& frameworkConfig_; + std::string applicationName_; + + ramses::EFeatureLevel featureLevel_ = minFeatureLevel; + + UniqueFramework framework_; UniqueClient client_; UniqueScene scene_; + + // Global LogicEngine instance only used for LuaScript/Interface/Module parsing. + // This will have the same feature level as the user project. + UniqueLogicEngine logicEngine_; + CoreInterfaceImpl coreInterface_; }; diff --git a/components/libRamsesBase/include/ramses_base/BuildOptions.h b/components/libRamsesBase/include/ramses_base/BuildOptions.h index 76854036..ef03b09d 100644 --- a/components/libRamsesBase/include/ramses_base/BuildOptions.h +++ b/components/libRamsesBase/include/ramses_base/BuildOptions.h @@ -10,12 +10,17 @@ #pragma once #include -#include +#include #ifndef RACO_BACKEND_INTERNAL_SCENE_ID #define RACO_BACKEND_INTERNAL_SCENE_ID std::numeric_limits::max() #endif +#ifndef RACO_BACKEND_ABSTRACT_SCENE_ID +#define RACO_BACKEND_ABSTRACT_SCENE_ID (std::numeric_limits::max() - 1) +#endif + struct BuildOptions { constexpr static ramses::sceneId_t internalSceneId = ramses::sceneId_t { RACO_BACKEND_INTERNAL_SCENE_ID }; + constexpr static ramses::sceneId_t abstractSceneId = ramses::sceneId_t{RACO_BACKEND_ABSTRACT_SCENE_ID}; }; diff --git a/components/libRamsesBase/include/ramses_base/CoreInterfaceImpl.h b/components/libRamsesBase/include/ramses_base/CoreInterfaceImpl.h index 8a2e0426..47913984 100644 --- a/components/libRamsesBase/include/ramses_base/CoreInterfaceImpl.h +++ b/components/libRamsesBase/include/ramses_base/CoreInterfaceImpl.h @@ -19,33 +19,27 @@ namespace raco::ramses_base { class BaseEngineBackend; -class CoreInterfaceImpl final : public raco::core::EngineInterface { +class CoreInterfaceImpl final : public core::EngineInterface { public: explicit CoreInterfaceImpl(BaseEngineBackend* backend); - bool parseShader(const std::string& vertexShader, const std::string& geometryShader, const std::string& fragmentShader, const std::string& shaderDefines, raco::core::PropertyInterfaceList& outUniforms, raco::core::PropertyInterfaceList& outAttributes, std::string& error) override; - bool parseLuaScript(const std::string& luaScript, const std::string& scriptName, const std::vector& stdModules, const raco::data_storage::Table& modules, raco::core::PropertyInterfaceList& outInputs, raco::core::PropertyInterfaceList& outOutputs, std::string& error) override; - bool parseLuaInterface(const std::string& interfaceText, const std::vector& stdModules, const raco::data_storage::Table& modules, bool useModules, PropertyInterfaceList& outInputs, std::string& outError) override; - bool parseLuaScriptModule(raco::core::SEditorObject object, const std::string& luaScriptModule, const std::string& moduleName, const std::vector& stdModules, std::string& outError) override; + bool parseShader(const std::string& vertexShader, const std::string& geometryShader, const std::string& fragmentShader, const std::string& shaderDefines, core::PropertyInterfaceList& outUniforms, core::PropertyInterfaceList& outAttributes, std::string& error) override; + bool parseLuaScript(const std::string& luaScript, const std::string& scriptName, const std::vector& stdModules, const data_storage::Table& modules, core::PropertyInterfaceList& outInputs, core::PropertyInterfaceList& outOutputs, std::string& error) override; + bool parseLuaInterface(const std::string& interfaceText, const std::vector& stdModules, const data_storage::Table& modules, PropertyInterfaceList& outInputs, std::string& outError) override; + bool parseLuaScriptModule(core::SEditorObject object, const std::string& luaScriptModule, const std::string& moduleName, const std::vector& stdModules, std::string& outError) override; bool extractLuaDependencies(const std::string& luaScript, std::vector& moduleList, std::string& outError) override; - std::string luaNameForPrimitiveType(raco::core::EnginePrimitive engineType) const override; + std::string luaNameForPrimitiveType(core::EnginePrimitive engineType) const override; - void removeModuleFromCache(raco::core::SCEditorObject object) override; + void removeModuleFromCache(core::SCEditorObject object) override; void clearModuleCache() override; private: - std::tuple createFullLuaConfig(const std::vector& stdModules, const raco::data_storage::Table& modules); + ramses::LogicEngine* logicEngine(); - typedef std::unique_ptr UniqueLogicEngine; + std::tuple createFullLuaConfig(const std::vector& stdModules, const data_storage::Table& modules); BaseEngineBackend* backend_; - // Second LogicEngine instance only used for LuaScript/Interface/Module parsing. - // This LogicEngine will always be at feature level 1 which is OK as long as we only use it for - // script parsing and the LogicEngine doesn't introduce changes to the script parsing at higher - // feature levels. - UniqueLogicEngine logicEngine_; - - std::map cachedModules_; + std::map cachedModules_; }; } // namespace raco::ramses_base diff --git a/components/libRamsesBase/include/ramses_base/EnumerationTranslations.h b/components/libRamsesBase/include/ramses_base/EnumerationTranslations.h index 704f752e..94cfd6ff 100644 --- a/components/libRamsesBase/include/ramses_base/EnumerationTranslations.h +++ b/components/libRamsesBase/include/ramses_base/EnumerationTranslations.h @@ -11,8 +11,8 @@ #include "user_types/Enumerations.h" -#include -#include +#include +#include #include #include diff --git a/components/libRamsesBase/include/ramses_base/HeadlessEngineBackend.h b/components/libRamsesBase/include/ramses_base/HeadlessEngineBackend.h index a568b84f..2b10e4e2 100644 --- a/components/libRamsesBase/include/ramses_base/HeadlessEngineBackend.h +++ b/components/libRamsesBase/include/ramses_base/HeadlessEngineBackend.h @@ -17,7 +17,7 @@ namespace raco::ramses_base { class HeadlessEngineBackend final : public BaseEngineBackend { Q_DISABLE_COPY(HeadlessEngineBackend) public: - explicit HeadlessEngineBackend(rlogic::EFeatureLevel featureLevel); + explicit HeadlessEngineBackend(const ramses::RamsesFrameworkConfig& frameworkConfig = BaseEngineBackend::defaultRamsesFrameworkConfig()); }; } // namespace raco::ramses_base diff --git a/components/libRamsesBase/include/ramses_base/LogicEngineFormatter.h b/components/libRamsesBase/include/ramses_base/LogicEngineFormatter.h deleted file mode 100644 index 0da025a1..00000000 --- a/components/libRamsesBase/include/ramses_base/LogicEngineFormatter.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SPDX-License-Identifier: MPL-2.0 - * - * This file is part of Ramses Composer - * (see https://github.com/bmwcarit/ramses-composer). - * - * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. - * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#pragma once - -#include -#include - -struct LogicEngineErrors { - const rlogic::LogicEngine& engine; -}; - -template <> -struct fmt::formatter : formatter { - template - auto format(const rlogic::ErrorData& error, FormatContext& ctx) { - return fmt::format_to(ctx.out(), "{}", error.message); - } -}; - -template <> -struct fmt::formatter : formatter { - template - auto format(const LogicEngineErrors& errors, FormatContext& ctx) { - return fmt::format_to(ctx.out(), "{}", fmt::join(errors.engine.getErrors(), "\n")); - } -}; diff --git a/components/libRamsesBase/include/ramses_base/RamsesFormatter.h b/components/libRamsesBase/include/ramses_base/RamsesFormatter.h index e7c0f436..1998833b 100644 --- a/components/libRamsesBase/include/ramses_base/RamsesFormatter.h +++ b/components/libRamsesBase/include/ramses_base/RamsesFormatter.h @@ -10,9 +10,9 @@ #pragma once -#include -#include -#include +#include +#include +#include #include template <> @@ -98,157 +98,73 @@ struct fmt::formatter : formatter { template auto format(const ramses::ERamsesObjectType type, FormatContext& ctx) { switch (type) { - case ramses::ERamsesObjectType::ERamsesObjectType_Invalid: + case ramses::ERamsesObjectType::Invalid: return format_to(ctx.out(), "Invalid"); - case ramses::ERamsesObjectType::ERamsesObjectType_ClientObject: + case ramses::ERamsesObjectType::ClientObject: return format_to(ctx.out(), "ClientObject"); - case ramses::ERamsesObjectType::ERamsesObjectType_RamsesObject: + case ramses::ERamsesObjectType::RamsesObject: return format_to(ctx.out(), "RamsesObject"); - case ramses::ERamsesObjectType::ERamsesObjectType_SceneObject: + case ramses::ERamsesObjectType::SceneObject: return format_to(ctx.out(), "SceneObject"); - case ramses::ERamsesObjectType::ERamsesObjectType_AnimationObject: - return format_to(ctx.out(), "AnimationObject"); - case ramses::ERamsesObjectType::ERamsesObjectType_Client: + case ramses::ERamsesObjectType::Client: return format_to(ctx.out(), "Client"); - case ramses::ERamsesObjectType::ERamsesObjectType_Scene: + case ramses::ERamsesObjectType::Scene: return format_to(ctx.out(), "Scene"); - case ramses::ERamsesObjectType::ERamsesObjectType_AnimationSystem: - return format_to(ctx.out(), "AnimationSystem"); - case ramses::ERamsesObjectType::ERamsesObjectType_AnimationSystemRealTime: - return format_to(ctx.out(), "AnimationSystemRealTime"); - case ramses::ERamsesObjectType::ERamsesObjectType_Node: + case ramses::ERamsesObjectType::LogicEngine: + return format_to(ctx.out(), "LogicEngine"); + case ramses::ERamsesObjectType::LogicObject: + return format_to(ctx.out(), "LogicObject"); + case ramses::ERamsesObjectType::Node: return format_to(ctx.out(), "Node"); - case ramses::ERamsesObjectType::ERamsesObjectType_MeshNode: + case ramses::ERamsesObjectType::MeshNode: return format_to(ctx.out(), "MeshNode"); - case ramses::ERamsesObjectType::ERamsesObjectType_Camera: + case ramses::ERamsesObjectType::Camera: return format_to(ctx.out(), "Camera"); - case ramses::ERamsesObjectType::ERamsesObjectType_PerspectiveCamera: + case ramses::ERamsesObjectType::PerspectiveCamera: return format_to(ctx.out(), "PerspectiveCamera"); - case ramses::ERamsesObjectType::ERamsesObjectType_OrthographicCamera: + case ramses::ERamsesObjectType::OrthographicCamera: return format_to(ctx.out(), "OrthographicCamera"); - case ramses::ERamsesObjectType::ERamsesObjectType_Effect: + case ramses::ERamsesObjectType::Effect: return format_to(ctx.out(), "Effect"); - case ramses::ERamsesObjectType::ERamsesObjectType_AnimatedProperty: - return format_to(ctx.out(), "AnimatedProperty"); - case ramses::ERamsesObjectType::ERamsesObjectType_Animation: - return format_to(ctx.out(), "Animation"); - case ramses::ERamsesObjectType::ERamsesObjectType_AnimationSequence: - return format_to(ctx.out(), "AnimationSequence"); - case ramses::ERamsesObjectType::ERamsesObjectType_Appearance: + case ramses::ERamsesObjectType::Appearance: return format_to(ctx.out(), "Appearance"); - case ramses::ERamsesObjectType::ERamsesObjectType_GeometryBinding: - return format_to(ctx.out(), "GeometryBinding"); - case ramses::ERamsesObjectType::ERamsesObjectType_PickableObject: + case ramses::ERamsesObjectType::Geometry: + return format_to(ctx.out(), "Geometry"); + case ramses::ERamsesObjectType::PickableObject: return format_to(ctx.out(), "PickableObject"); - case ramses::ERamsesObjectType::ERamsesObjectType_Spline: - return format_to(ctx.out(), "Spline"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineStepBool: - return format_to(ctx.out(), "SplineStepBool"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineStepFloat: - return format_to(ctx.out(), "SplineStepFloat"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineStepInt32: - return format_to(ctx.out(), "SplineStepInt32"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineStepVector2f: - return format_to(ctx.out(), "SplinteStepVector2f"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineStepVector3f: - return format_to(ctx.out(), "SplineStepVector3f"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineStepVector4f: - return format_to(ctx.out(), "SplineStepVector4f"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineStepVector2i: - return format_to(ctx.out(), "SplineStepVector2i"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineStepVector3i: - return format_to(ctx.out(), "SplineStepVector3i"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineStepVector4i: - return format_to(ctx.out(), "SplineStepVector4i"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineLinearFloat: - return format_to(ctx.out(), "SplineLinearFloat"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineLinearInt32: - return format_to(ctx.out(), "SplineLinearInt32"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineLinearVector2f: - return format_to(ctx.out(), "SplineLinearVector2f"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineLinearVector3f: - return format_to(ctx.out(), "SplineLinearVector3f"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineLinearVector4f: - return format_to(ctx.out(), "SplineLinearVector4f"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineLinearVector2i: - return format_to(ctx.out(), "SplineLinearVector2i"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineLinearVector3i: - return format_to(ctx.out(), "SplineLinearVector3i"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineLinearVector4i: - return format_to(ctx.out(), "SplineLinearVector4i"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineBezierFloat: - return format_to(ctx.out(), "SplineBezierFloat"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineBezierInt32: - return format_to(ctx.out(), "SplineBezierInt32"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineBezierVector2f: - return format_to(ctx.out(), "SplineBezierVector2f"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineBezierVector3f: - return format_to(ctx.out(), "SplineBezierVector3f"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineBezierVector4f: - return format_to(ctx.out(), "SplineBezierVector4f"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineBezierVector2i: - return format_to(ctx.out(), "SplineBezierVector2i"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineBezierVector3i: - return format_to(ctx.out(), "SplineBezierVector3i"); - case ramses::ERamsesObjectType::ERamsesObjectType_SplineBezierVector4i: - return format_to(ctx.out(), "SplineBezierVector4i"); - case ramses::ERamsesObjectType::ERamsesObjectType_Resource: + case ramses::ERamsesObjectType::Resource: return format_to(ctx.out(), "Resource"); - case ramses::ERamsesObjectType::ERamsesObjectType_Texture2D: + case ramses::ERamsesObjectType::Texture2D: return format_to(ctx.out(), "Texture2D"); - case ramses::ERamsesObjectType::ERamsesObjectType_Texture3D: + case ramses::ERamsesObjectType::Texture3D: return format_to(ctx.out(), "Texture3D"); - case ramses::ERamsesObjectType::ERamsesObjectType_TextureCube: + case ramses::ERamsesObjectType::TextureCube: return format_to(ctx.out(), "TextureCube"); - case ramses::ERamsesObjectType::ERamsesObjectType_ArrayResource: + case ramses::ERamsesObjectType::ArrayResource: return format_to(ctx.out(), "ArrayResource"); - case ramses::ERamsesObjectType::ERamsesObjectType_RenderGroup: + case ramses::ERamsesObjectType::RenderGroup: return format_to(ctx.out(), "RenderGroup"); - case ramses::ERamsesObjectType::ERamsesObjectType_RenderPass: + case ramses::ERamsesObjectType::RenderPass: return format_to(ctx.out(), "RenderPass"); - case ramses::ERamsesObjectType::ERamsesObjectType_BlitPass: + case ramses::ERamsesObjectType::BlitPass: return format_to(ctx.out(), "BlitPass"); - case ramses::ERamsesObjectType::ERamsesObjectType_TextureSampler: + case ramses::ERamsesObjectType::TextureSampler: return format_to(ctx.out(), "TextureSampler"); - case ramses::ERamsesObjectType::ERamsesObjectType_TextureSamplerMS: + case ramses::ERamsesObjectType::TextureSamplerMS: return format_to(ctx.out(), "TextureSamplerMS"); - case ramses::ERamsesObjectType::ERamsesObjectType_RenderBuffer: + case ramses::ERamsesObjectType::RenderBuffer: return format_to(ctx.out(), "RenderBuffer"); - case ramses::ERamsesObjectType::ERamsesObjectType_RenderTarget: + case ramses::ERamsesObjectType::RenderTarget: return format_to(ctx.out(), "RenderTarget"); - case ramses::ERamsesObjectType::ERamsesObjectType_DataBufferObject: - return format_to(ctx.out(), "DataBufferObject"); - case ramses::ERamsesObjectType::ERamsesObjectType_Texture2DBuffer: + case ramses::ERamsesObjectType::ArrayBuffer: + return format_to(ctx.out(), "ArrayBuffer"); + case ramses::ERamsesObjectType::Texture2DBuffer: return format_to(ctx.out(), "Texture2DBuffer"); - case ramses::ERamsesObjectType::ERamsesObjectType_DataObject: + case ramses::ERamsesObjectType::DataObject: return format_to(ctx.out(), "DataObject"); - case ramses::ERamsesObjectType::ERamsesObjectType_DataFloat: - return format_to(ctx.out(), "DataFloat"); - case ramses::ERamsesObjectType::ERamsesObjectType_DataVector2f: - return format_to(ctx.out(), "DataVector2f"); - case ramses::ERamsesObjectType::ERamsesObjectType_DataVector3f: - return format_to(ctx.out(), "DataVector3f"); - case ramses::ERamsesObjectType::ERamsesObjectType_DataVector4f: - return format_to(ctx.out(), "DataVector4f"); - case ramses::ERamsesObjectType::ERamsesObjectType_DataMatrix22f: - return format_to(ctx.out(), "DataMatrix22f"); - case ramses::ERamsesObjectType::ERamsesObjectType_DataMatrix33f: - return format_to(ctx.out(), "DataMatrix33f"); - case ramses::ERamsesObjectType::ERamsesObjectType_DataMatrix44f: - return format_to(ctx.out(), "DataMatrix44f"); - case ramses::ERamsesObjectType::ERamsesObjectType_DataInt32: - return format_to(ctx.out(), "DataInt32"); - case ramses::ERamsesObjectType::ERamsesObjectType_DataVector2i: - return format_to(ctx.out(), "DataVector2i"); - case ramses::ERamsesObjectType::ERamsesObjectType_DataVector3i: - return format_to(ctx.out(), "DataVector3i"); - case ramses::ERamsesObjectType::ERamsesObjectType_DataVector4i: - return format_to(ctx.out(), "DataVector4i"); - case ramses::ERamsesObjectType::ERamsesObjectType_StreamTexture: - return format_to(ctx.out(), "StreamTexture"); - case ramses::ERamsesObjectType::ERamsesObjectType_SceneReference: + case ramses::ERamsesObjectType::SceneReference: return format_to(ctx.out(), "SceneReference"); - case ramses::ERamsesObjectType::ERamsesObjectType_TextureSamplerExternal: + case ramses::ERamsesObjectType::TextureSamplerExternal: return format_to(ctx.out(), "TextureSamplerExternal"); default: return format_to(ctx.out(), "Unknown"); diff --git a/components/libRamsesBase/include/ramses_base/RamsesHandles.h b/components/libRamsesBase/include/ramses_base/RamsesHandles.h index 6ce0d946..1c27c1ff 100644 --- a/components/libRamsesBase/include/ramses_base/RamsesHandles.h +++ b/components/libRamsesBase/include/ramses_base/RamsesHandles.h @@ -12,54 +12,54 @@ #include "log_system/log.h" #include "ramses_base/Utils.h" -#include "ramses_base/LogicEngineFormatter.h" -#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -77,45 +77,48 @@ using RamsesRenderTarget = RamsesHandle; using RamsesTextureSampler = RamsesHandle; using RamsesTextureSamplerMS = RamsesHandle; using RamsesTextureSamplerExternal = RamsesHandle; -using RamsesTimerNode = RamsesHandle; -using RamsesLuaModule = RamsesHandle; -using RamsesLuaScript = RamsesHandle; -using RamsesLuaInterface = RamsesHandle; -using RamsesAnchorPoint = RamsesHandle; -using RamsesSkinBinding = RamsesHandle; +using RamsesTimerNode = RamsesHandle; +using RamsesLuaModule = RamsesHandle; +using RamsesLuaScript = RamsesHandle; +using RamsesLuaInterface = RamsesHandle; +using RamsesAnchorPoint = RamsesHandle; +using RamsesSkinBinding = RamsesHandle; +using RamsesPickableObject = RamsesHandle; /** RESOURCE HANDLES */ using RamsesEffect = RamsesHandle; using RamsesArrayResource = RamsesHandle; +using RamsesArrayBuffer = RamsesHandle; using RamsesTexture2D = RamsesHandle; using RamsesTextureCube = RamsesHandle; using RamsesBlitPass = RamsesHandle; -template -void destroyRamsesObject(OwnerType* owner, RamsesType* obj) { +template +void destroyRamsesObject(ramses::Scene* owner, RamsesType* obj) { if (obj) { - auto status = owner->destroy(*obj); - if (ramses::StatusOK != status) { - LOG_ERROR(raco::log_system::RAMSES_BACKEND, "Deleting Ramses object failed: {}", owner->getStatusMessage(status)); + if (!owner->destroy(*obj)) { + auto error = owner->getRamsesClient().getRamsesFramework().getLastError().value(); + LOG_ERROR(log_system::RAMSES_BACKEND, "Deleting Ramses object failed: {}", error.message); assert(false); exit(1); } } } -template -constexpr RamsesObjectDeleter createRamsesObjectDeleter(OwnerType* owner) { +template +constexpr RamsesObjectDeleter createRamsesObjectDeleter(ramses::Scene* owner) { return [owner](ramses::RamsesObject* obj) { destroyRamsesObject(owner, static_cast(obj)); }; } template -void destroyLogicObject(rlogic::LogicEngine* logicengine, LogicType* obj) { +void destroyLogicObject(ramses::LogicEngine* logicengine, LogicType* obj) { if (obj) { auto status = logicengine->destroy(*obj); if (!status) { - LOG_ERROR(raco::log_system::RAMSES_BACKEND, "Deleting LogicEngine object failed: {}", LogicEngineErrors{*logicengine}); + auto error = logicengine->getScene().getRamsesClient().getRamsesFramework().getLastError().value(); + LOG_ERROR(log_system::RAMSES_BACKEND, "Deleting LogicEngine object failed: {}", error.message); assert(false); exit(1); } @@ -124,8 +127,12 @@ void destroyLogicObject(rlogic::LogicEngine* logicengine, LogicType* obj) { struct RamsesAppearanceHandle { - RamsesAppearanceHandle(ramses::Scene* scene, raco::ramses_base::RamsesEffect effect) - : appearance_(scene->createAppearance(*effect)), scene_(scene), trackedEffect_(effect) {} + RamsesAppearanceHandle(ramses::Scene* scene, ramses_base::RamsesEffect effect, const std::pair& objectID) + : appearance_(scene->createAppearance(*effect)), scene_(scene), trackedEffect_(effect) { + if (appearance_) { + appearance_->setUserId(objectID.first, objectID.second); + } + } ~RamsesAppearanceHandle() { destroyRamsesObject(scene_, appearance_); @@ -143,7 +150,7 @@ struct RamsesAppearanceHandle { return appearance_; } - void replaceTrackedSamplers(std::vector& newSamplers, std::vector& newSamplersMS, std::vector& newSamplersExternal) { + void replaceTrackedSamplers(std::vector& newSamplers, std::vector& newSamplersMS, std::vector& newSamplersExternal) { trackedSamplers_ = newSamplers; trackedSamplersMS_ = newSamplersMS; trackedSamplersExternal_ = newSamplersExternal; @@ -164,90 +171,108 @@ struct RamsesAppearanceHandle { RamsesEffect trackedEffect_; // Samplers currently in use by the appearance_. Needed to keep the samplers alive in ramses. - std::vector trackedSamplers_; - std::vector trackedSamplersMS_; - std::vector trackedSamplersExternal_; + std::vector trackedSamplers_; + std::vector trackedSamplersMS_; + std::vector trackedSamplersExternal_; }; using RamsesAppearance = std::shared_ptr; -inline RamsesAppearance ramsesAppearance(ramses::Scene* scene, raco::ramses_base::RamsesEffect effect) { - return std::make_shared(scene, effect); +inline RamsesAppearance ramsesAppearance(ramses::Scene* scene, ramses_base::RamsesEffect effect, const std::pair& objectID) { + return std::make_shared(scene, effect, objectID); } inline RamsesScene ramsesScene(ramses::sceneId_t id, ramses::RamsesClient* client) { - return {client->createScene(id), createRamsesObjectDeleter(client)}; + return { + client->createScene(ramses::SceneConfig(id, ramses::EScenePublicationMode::LocalAndRemote)), + + [client](ramses::Scene* obj) { + if (obj) { + if (!client->destroy(*obj)) { + auto error = client->getRamsesFramework().getLastError().value(); + LOG_ERROR(log_system::RAMSES_BACKEND, "Deleting Ramses object failed: {}", error.message); + assert(false); + exit(1); + } + } + }}; } -struct RamsesGeometryBindingHandle { - RamsesGeometryBindingHandle(ramses::Scene* scene, raco::ramses_base::RamsesEffect effect) - : geometryBinding_(scene->createGeometryBinding(*effect)), scene_(scene), trackedEffect_(effect) { +struct RamsesGeometryHandle { + RamsesGeometryHandle(ramses::Scene* scene, ramses_base::RamsesEffect effect, const std::pair& objectID) + : geometry_(scene->createGeometry(*effect)), scene_(scene), trackedEffect_(effect) { + if (geometry_) { + geometry_->setUserId(objectID.first, objectID.second); + } } - ~RamsesGeometryBindingHandle() { - destroyRamsesObject(scene_, geometryBinding_); + ~RamsesGeometryHandle() { + destroyRamsesObject(scene_, geometry_); } - ramses::GeometryBinding& operator*() { - return *geometryBinding_; + ramses::Geometry& operator*() { + return *geometry_; } - ramses::GeometryBinding* operator->() { - return geometryBinding_; + ramses::Geometry* operator->() { + return geometry_; } void setIndices(RamsesArrayResource indexBuffer) { - auto status = geometryBinding_->setIndices(*indexBuffer); - if (status == ramses::StatusOK) { + if (geometry_->setIndices(*indexBuffer)) { trackedMeshIndices_ = indexBuffer; } else { - LOG_ERROR(raco::log_system::RAMSES_ADAPTOR, geometryBinding_->getStatusMessage(status)); + auto error = scene_->getRamsesClient().getRamsesFramework().getLastError().value(); + LOG_ERROR(log_system::RAMSES_ADAPTOR, error.message); } } void addAttributeBuffer(const ramses::AttributeInput& attribInput, RamsesArrayResource attributeBuffer) { - auto status = geometryBinding_->setInputBuffer(attribInput, *attributeBuffer); - if (status == ramses::StatusOK) { + if (geometry_->setInputBuffer(attribInput, *attributeBuffer)) { trackedMeshVertexData_.emplace_back(attributeBuffer); } else { - LOG_ERROR(raco::log_system::RAMSES_ADAPTOR, geometryBinding_->getStatusMessage(status)); + auto error = scene_->getRamsesClient().getRamsesFramework().getLastError().value(); + LOG_ERROR(log_system::RAMSES_ADAPTOR, error.message); } } private: - // The geometryBinding_ is owned by this class. - ramses::GeometryBinding* geometryBinding_; + // The geometry_ is owned by this class. + ramses::Geometry* geometry_; - // Kept for reference; needed to destroy the GeometryBinding pointer in ramses. + // Kept for reference; needed to destroy the Geometry pointer in ramses. ramses::Scene* scene_; - // Effect currently used by the geometryBinding_. Needed to keep the effect alive in ramses. + // Effect currently used by the geometry_. Needed to keep the effect alive in ramses. RamsesEffect trackedEffect_; - // Attribute buffers currently used by the geometryBinding_. Needed to keep the buffers alive in ramses. - std::vector trackedMeshVertexData_; + // Attribute buffers currently used by the geometry_. Needed to keep the buffers alive in ramses. + std::vector trackedMeshVertexData_; - // Index buffer currently used by the geometryBinding_. Needed to keep the buffer alive in ramses. - raco::ramses_base::RamsesArrayResource trackedMeshIndices_; + // Index buffer currently used by the geometry_. Needed to keep the buffer alive in ramses. + ramses_base::RamsesArrayResource trackedMeshIndices_; }; -using RamsesGeometryBinding = std::shared_ptr; +using RamsesGeometry = std::shared_ptr; -inline RamsesGeometryBinding ramsesGeometryBinding(ramses::Scene* scene, raco::ramses_base::RamsesEffect effect) { - return std::make_shared(scene, effect); +inline RamsesGeometry ramsesGeometry(ramses::Scene* scene, ramses_base::RamsesEffect effect, const std::pair& objectID) { + return std::make_shared(scene, effect, objectID); } template struct RamsesWrapper { - RamsesWrapper(ramses::Scene* scene) - : ramsesObject_((scene->*PToM)(nullptr)), scene_(scene) { + RamsesWrapper(ramses::Scene* scene, const std::pair& objectID) + : ramsesObject_((scene->*PToM)({})), scene_(scene) { + if (ramsesObject_) { + ramsesObject_->setUserId(objectID.first, objectID.second); + } } ~RamsesWrapper() { destroyRamsesObject(scene_, ramsesObject_); } - const char* getName() const { + std::string_view getName() const { return ramsesObject_->getName(); } @@ -278,35 +303,38 @@ struct RamsesWrapper { using RamsesNodeHandle = RamsesWrapper; using RamsesNode = std::shared_ptr; -inline RamsesNode ramsesNode(ramses::Scene* scene) { - return std::make_shared(scene); +inline RamsesNode ramsesNode(ramses::Scene* scene, const std::pair& objectID) { + return std::make_shared(scene, objectID); } using RamsesOrthographicCameraHandle = RamsesWrapper; using RamsesOrthographicCamera = std::shared_ptr; -inline RamsesOrthographicCamera ramsesOrthographicCamera(ramses::Scene* scene) { - return std::make_shared(scene); +inline RamsesOrthographicCamera ramsesOrthographicCamera(ramses::Scene* scene, const std::pair& objectID) { + return std::make_shared(scene, objectID); } using RamsesPerspectiveCameraHandle = RamsesWrapper; using RamsesPerspectiveCamera = std::shared_ptr; -inline RamsesPerspectiveCamera ramsesPerspectiveCamera(ramses::Scene* scene) { - return std::make_shared(scene); +inline RamsesPerspectiveCamera ramsesPerspectiveCamera(ramses::Scene* scene, const std::pair& objectID) { + return std::make_shared(scene, objectID); } struct RamsesMeshNodeHandle { - RamsesMeshNodeHandle(ramses::Scene* scene) + RamsesMeshNodeHandle(ramses::Scene* scene, const std::pair& objectID) : meshnode_(scene->createMeshNode()), scene_(scene) { + if (meshnode_) { + meshnode_->setUserId(objectID.first, objectID.second); + } } ~RamsesMeshNodeHandle() { destroyRamsesObject(scene_, meshnode_); } - const char* getName() const { + std::string_view getName() const { return meshnode_->getName(); } @@ -325,7 +353,7 @@ struct RamsesMeshNodeHandle { void removeAppearanceAndGeometry() { meshnode_->removeAppearanceAndGeometry(); trackedAppearance_.reset(); - trackedGeometryBinding_.reset(); + trackedGeometry_.reset(); } void setAppearance(RamsesAppearance appearance) { @@ -333,9 +361,9 @@ struct RamsesMeshNodeHandle { trackedAppearance_ = appearance; } - void setGeometryBinding(RamsesGeometryBinding geometryBinding) { - meshnode_->setGeometryBinding(**geometryBinding); - trackedGeometryBinding_ = geometryBinding; + void setGeometry(RamsesGeometry geometry) { + meshnode_->setGeometry(**geometry); + trackedGeometry_ = geometry; } private: @@ -348,28 +376,32 @@ struct RamsesMeshNodeHandle { // Appearance currently used by the meshnode_. Needed to keep the Appearance alive in ramses. RamsesAppearance trackedAppearance_; - // GeometryBinding currently used by the meshnode_. Needed to keep the GeometryBinding alive in ramses. - RamsesGeometryBinding trackedGeometryBinding_; + // Geometry currently used by the meshnode_. Needed to keep the Geometry alive in ramses. + RamsesGeometry trackedGeometry_; }; using RamsesMeshNode = std::shared_ptr; -inline RamsesMeshNode ramsesMeshNode(ramses::Scene* scene) { - return std::make_shared(scene); +inline RamsesMeshNode ramsesMeshNode(ramses::Scene* scene, const std::pair& objectID) { + return std::make_shared(scene, objectID); } struct RamsesRenderGroupHandle; using RamsesRenderGroup = std::shared_ptr; struct RamsesRenderGroupHandle { - RamsesRenderGroupHandle(ramses::Scene* scene) - : renderGroup_(scene->createRenderGroup()), scene_(scene) {} + RamsesRenderGroupHandle(ramses::Scene* scene, const std::pair& objectID) + : renderGroup_(scene->createRenderGroup()), scene_(scene) { + if (renderGroup_) { + renderGroup_->setUserId(objectID.first, objectID.second); + } + } ~RamsesRenderGroupHandle() { destroyRamsesObject(scene_, renderGroup_); } - const char* getName() const { + std::string_view getName() const { return renderGroup_->getName(); } @@ -449,21 +481,29 @@ struct RamsesRenderGroupHandle { std::map trackedGroups_; }; -inline RamsesRenderGroup ramsesRenderGroup(ramses::Scene* scene) { - return std::make_shared(scene); +inline RamsesRenderGroup ramsesRenderGroup(ramses::Scene* scene, const std::pair& objectID) { + return std::make_shared(scene, objectID); } inline RamsesRenderBuffer ramsesRenderBuffer(ramses::Scene* scene, - uint32_t width, uint32_t height, ramses::ERenderBufferType type, ramses::ERenderBufferFormat format, ramses::ERenderBufferAccessMode accessMode, uint32_t sampleCount = 0u, const char* name = nullptr) { - return {scene->createRenderBuffer(width, height, type, format, accessMode, sampleCount, name), - createRamsesObjectDeleter(scene)}; + uint32_t width, uint32_t height, ramses::ERenderBufferFormat format, ramses::ERenderBufferAccessMode accessMode, uint32_t sampleCount, std::string_view name, const std::pair& objectID) { + auto buffer{scene->createRenderBuffer(width, height, format, accessMode, sampleCount, name)}; + if (buffer) { + buffer->setUserId(objectID.first, objectID.second); + } + + return {buffer, createRamsesObjectDeleter(scene)}; } struct RamsesRenderPassHandle { - RamsesRenderPassHandle(std::shared_ptr renderPass) - : renderPass_(renderPass) {} + RamsesRenderPassHandle(std::shared_ptr renderPass, const std::pair& objectID) + : renderPass_(renderPass) { + if (renderPass_) { + renderPass_->setUserId(objectID.first, objectID.second); + } + } - const char* getName() const { + std::string_view getName() const { return renderPass_->getName(); } @@ -480,8 +520,8 @@ struct RamsesRenderPassHandle { trackedRenderGroups_.clear(); } - void addRenderGroup(RamsesRenderGroup renderGroup) { - renderPass_->addRenderGroup(**renderGroup); + void addRenderGroup(RamsesRenderGroup renderGroup, int32_t order = 0) { + renderPass_->addRenderGroup(**renderGroup, order); trackedRenderGroups_.insert(renderGroup); } @@ -496,7 +536,7 @@ struct RamsesRenderPassHandle { using RamsesRenderPass = std::shared_ptr; template -inline std::shared_ptr ramsesRenderPassInternal(ramses::Scene* scene, CameraHandleType camera, RamsesRenderTarget target, const char* name = nullptr) { +inline std::shared_ptr ramsesRenderPassInternal(ramses::Scene* scene, CameraHandleType camera, RamsesRenderTarget target, std::string_view name) { if (!camera) { return {}; } @@ -511,122 +551,192 @@ inline std::shared_ptr ramsesRenderPassInternal(ramses::Scen } template -inline RamsesRenderPass ramsesRenderPass(ramses::Scene* scene, CameraHandleType camera, RamsesRenderTarget target, const char* name = nullptr) { +inline RamsesRenderPass ramsesRenderPass(ramses::Scene* scene, CameraHandleType camera, RamsesRenderTarget target, std::string_view name, const std::pair& objectID) { if (!camera) { return {}; } - return std::make_shared(ramsesRenderPassInternal(scene, camera, target, name)); + return std::make_shared(ramsesRenderPassInternal(scene, camera, target, name), objectID); } -inline RamsesRenderTarget ramsesRenderTarget(ramses::Scene* scene, const ramses::RenderTargetDescription& rtDesc, const std::vector& buffers) { +inline RamsesRenderTarget ramsesRenderTarget(ramses::Scene* scene, const ramses::RenderTargetDescription& rtDesc, const std::vector& buffers, const std::pair& objectID) { if (buffers.empty()) { return nullptr; } + auto target{scene->createRenderTarget(rtDesc)}; + if (target) { + target->setUserId(objectID.first, objectID.second); + } return { - scene->createRenderTarget(rtDesc), + target, [scene, forceCopy = buffers](ramses::RamsesObject* obj) { destroyRamsesObject(scene, static_cast(obj)); }}; } -inline RamsesArrayResource ramsesArrayResource(ramses::Scene* scene, ramses::EDataType type, uint32_t numElements, const void* arrayData, const char* name = nullptr) { - RamsesArrayResource result{scene->createArrayResource(type, numElements, arrayData), createRamsesObjectDeleter(scene)}; - result->setName(name); +template +inline RamsesArrayResource ramsesArrayResource(ramses::Scene* scene, const std::vector& data, std::string_view name = {}) { + return { + scene->createArrayResource(data.size(), data.data(), name), + createRamsesObjectDeleter(scene)}; +} + +template +inline RamsesArrayResource ramsesArrayResource(ramses::Scene* scene, uint32_t numElements, const T* arrayData, std::string_view name = {}) { + return { + scene->createArrayResource(numElements, arrayData, name), + createRamsesObjectDeleter(scene)}; +} + +template +inline RamsesArrayBuffer ramsesArrayBuffer(ramses::Scene* scene, ramses::EDataType type, uint32_t numElements, const T* arrayData, std::string_view name = {}) { + RamsesArrayBuffer result{scene->createArrayBuffer(type, numElements), createRamsesObjectDeleter(scene)}; + auto status = result->setName(name); + status = result->updateData(0, numElements, arrayData); return result; } +template +inline RamsesPickableObject ramsesPickableObject(ramses::Scene* scene, RamsesArrayBuffer geometryBuffer, ramses::pickableObjectId_t pickId, CameraHandleType camera) { + if (!camera) { + return {}; + } + + RamsesPickableObject object{ + scene->createPickableObject(*geometryBuffer.get(), pickId), + [scene, forceBufferCopy = geometryBuffer, forceCameraCopy = camera](ramses::RamsesObject* object) { + destroyRamsesObject(scene, static_cast(object)); + }}; + + if (object) { + object->setCamera(**camera); + } + return object; +} + + template -inline RamsesTextureSampler ramsesTextureSampler(ramses::Scene* scene, ramses::ETextureAddressMode wrapUMode, ramses::ETextureAddressMode wrapVMode, ramses::ETextureSamplingMethod minSamplingMethod, ramses::ETextureSamplingMethod magSamplingMethod, RamsesTexture texture, uint32_t anisotropyLevel, const char* name = nullptr) { - auto ptr = scene->createTextureSampler(wrapUMode, wrapVMode, minSamplingMethod, magSamplingMethod, *texture, anisotropyLevel, name); - return {ptr, +inline RamsesTextureSampler ramsesTextureSampler(ramses::Scene* scene, ramses::ETextureAddressMode wrapUMode, ramses::ETextureAddressMode wrapVMode, ramses::ETextureSamplingMethod minSamplingMethod, ramses::ETextureSamplingMethod magSamplingMethod, RamsesTexture texture, uint32_t anisotropyLevel, std::string_view name, const std::pair& objectID) { + auto sampler = scene->createTextureSampler(wrapUMode, wrapVMode, minSamplingMethod, magSamplingMethod, *texture, anisotropyLevel, name); + if (sampler) { + sampler->setUserId(objectID.first, objectID.second); + } + return {sampler, [scene, forceCopy = texture](ramses::RamsesObject* obj) { - auto status = scene->destroy(*static_cast(obj)); - if (ramses::StatusOK != status) { - throw std::runtime_error(obj->getStatusMessage(status)); + if (!scene->destroy(*static_cast(obj))) { + auto error = scene->getRamsesClient().getRamsesFramework().getLastError().value(); + throw std::runtime_error(error.message); } }}; } -inline RamsesTextureSamplerMS ramsesTextureSamplerMS(ramses::Scene* scene, RamsesRenderBuffer buffer, const char* name = nullptr) { - auto ptr = scene->createTextureSamplerMS(*buffer, name); +inline RamsesTextureSamplerMS ramsesTextureSamplerMS(ramses::Scene* scene, RamsesRenderBuffer buffer, std::string_view name, const std::pair& objectID) { + auto sampler = scene->createTextureSamplerMS(*buffer, name); + if (sampler) { + sampler->setUserId(objectID.first, objectID.second); + } return { - ptr, + sampler, [scene, forceCopy = buffer](ramses::RamsesObject* buffer) { destroyRamsesObject(scene, static_cast(buffer)); }}; } -inline RamsesTextureSamplerExternal ramsesTextureSamplerExternal(ramses::Scene* scene, ramses::ETextureSamplingMethod minSamplingMethod, ramses::ETextureSamplingMethod magSamplingMethod, const char* name = nullptr) { +inline RamsesTextureSamplerExternal ramsesTextureSamplerExternal(ramses::Scene* scene, ramses::ETextureSamplingMethod minSamplingMethod, ramses::ETextureSamplingMethod magSamplingMethod, std::string_view name, const std::pair& objectID) { + auto sampler{scene->createTextureSamplerExternal(minSamplingMethod, magSamplingMethod, name)}; + if (sampler) { + sampler->setUserId(objectID.first, objectID.second); + } + return { - scene->createTextureSamplerExternal(minSamplingMethod, magSamplingMethod, name), + sampler, createRamsesObjectDeleter(scene) }; } /** RESOURCE FACTORIES */ -inline RamsesEffect ramsesEffect(ramses::Scene* scene, const ramses::EffectDescription& description, const char* name = nullptr) { - return {scene->createEffect(description, ramses::ResourceCacheFlag_DoNotCache, name), createRamsesObjectDeleter(scene)}; +inline RamsesEffect ramsesEffect(ramses::Scene* scene, const ramses::EffectDescription& description, std::string_view name, const std::pair& objectID) { + auto effect{scene->createEffect(description, name)}; + if (effect) { + effect->setUserId(objectID.first, objectID.second); + } + + return {effect, createRamsesObjectDeleter(scene)}; } inline RamsesTexture2D ramsesTexture2D(ramses::Scene* scene, ramses::ETextureFormat format, uint32_t width, uint32_t height, - uint32_t mipMapCount, - const ramses::MipLevelData mipLevelData[], + const std::vector& mipLevelData, bool generateMipChain, const ramses::TextureSwizzle& swizzle, - ramses::resourceCacheFlag_t cacheFlag, - const char* name = nullptr) { - return {scene->createTexture2D(format, width, height, mipMapCount, mipLevelData, generateMipChain, swizzle, cacheFlag, name), createRamsesObjectDeleter(scene)}; + std::string_view name, + const std::pair& objectID) { + auto texture{scene->createTexture2D(format, width, height, mipLevelData, generateMipChain, swizzle, name)}; + if (texture) { + texture->setUserId(objectID.first, objectID.second); + } + + return {texture, createRamsesObjectDeleter(scene)}; } -inline RamsesTexture2D ramsesTexture2DFromPng(ramses::Scene* scene, const std::string& uri) { - return {ramses::RamsesUtils::CreateTextureResourceFromPng(uri.c_str(), *scene), - createRamsesObjectDeleter(scene)}; +inline RamsesTexture2D ramsesTexture2DFromPng(ramses::Scene* scene, const std::string& uri, const std::pair& objectID) { + auto texture{ramses::RamsesUtils::CreateTextureResourceFromPng(uri.c_str(), *scene)}; + if (texture) { + texture->setUserId(objectID.first, objectID.second); + } + return {texture, createRamsesObjectDeleter(scene)}; } -inline RamsesTexture2D ramsesTexture2DFromPngBuffer(ramses::Scene* scene, const std::vector& pngData) { - return {ramses::RamsesUtils::CreateTextureResourceFromPngBuffer(pngData, *scene), - createRamsesObjectDeleter(scene)}; +inline RamsesTexture2D ramsesTexture2DFromPngBuffer(ramses::Scene* scene, const std::vector& pngData, const std::pair& objectID) { + auto texture{ramses::RamsesUtils::CreateTextureResourceFromPngBuffer(pngData, *scene)}; + if (texture) { + texture->setUserId(objectID.first, objectID.second); + } + return {texture, createRamsesObjectDeleter(scene)}; } inline RamsesTextureCube ramsesTextureCube(ramses::Scene* scene, ramses::ETextureFormat format, uint32_t width, - uint32_t mipMapCount, - const ramses::CubeMipLevelData mipLevelData[], + const std::vector& mipLevelData, bool generateMipChain, const ramses::TextureSwizzle& swizzle, - ramses::resourceCacheFlag_t cacheFlag, - const char* name = nullptr) { - return {scene->createTextureCube(format, width, mipMapCount, mipLevelData, generateMipChain, swizzle, cacheFlag, name), - createRamsesObjectDeleter(scene)}; + std::string_view name, + const std::pair& objectID) { + auto texture{scene->createTextureCube(format, width, mipLevelData, generateMipChain, swizzle, name)}; + if (texture) { + texture->setUserId(objectID.first, objectID.second); + } + return {texture, createRamsesObjectDeleter(scene)}; } -inline RamsesBlitPass ramsesBlitPass(ramses::Scene* scene, RamsesRenderBuffer source, RamsesRenderBuffer dest, - const char* name = nullptr) { +inline RamsesBlitPass ramsesBlitPass(ramses::Scene* scene, RamsesRenderBuffer source, RamsesRenderBuffer dest, std::string_view name, const std::pair& objectID) { + auto blitpass{scene->createBlitPass(*source, *dest, name)}; + if (blitpass) { + blitpass->setUserId(objectID.first, objectID.second); + } return { - scene->createBlitPass(*source, *dest, name), + blitpass, [scene, forceSourceCopy = source, forceDestCopy = dest](ramses::RamsesObject* object) { destroyRamsesObject(scene, static_cast(object)); }}; } -using RamsesAppearanceBinding = std::shared_ptr; -using UniqueRamsesDataArray = std::unique_ptr>; -using RamsesMeshNodeBinding = std::shared_ptr; -using RamsesNodeBinding = std::shared_ptr; -using RamsesCameraBinding = std::shared_ptr; -using UniqueRamsesRenderPassBinding = std::unique_ptr>; -using RamsesRenderGroupBinding = std::shared_ptr; +using RamsesAppearanceBinding = std::shared_ptr; +using UniqueRamsesDataArray = std::unique_ptr>; +using RamsesMeshNodeBinding = std::shared_ptr; +using RamsesNodeBinding = std::shared_ptr; +using RamsesCameraBinding = std::shared_ptr; +using UniqueRamsesRenderPassBinding = std::unique_ptr>; +using RamsesRenderGroupBinding = std::shared_ptr; -inline RamsesAppearanceBinding ramsesAppearanceBinding(ramses::Appearance& appearance, rlogic::LogicEngine* logicEngine, const std::string& name, const std::pair &objectID) { - RamsesAppearanceBinding binding{logicEngine->createRamsesAppearanceBinding(appearance, name), - [logicEngine](rlogic::RamsesAppearanceBinding* binding) { +inline RamsesAppearanceBinding ramsesAppearanceBinding(ramses::Appearance& appearance, ramses::LogicEngine* logicEngine, const std::string& name, const std::pair &objectID) { + RamsesAppearanceBinding binding{logicEngine->createAppearanceBinding(appearance, name), + [logicEngine](ramses::AppearanceBinding* binding) { destroyLogicObject(logicEngine, binding); }}; @@ -638,9 +748,9 @@ inline RamsesAppearanceBinding ramsesAppearanceBinding(ramses::Appearance& appea } template -inline RamsesNodeBinding ramsesNodeBinding(NodeHandleType node, rlogic::LogicEngine* logicEngine, rlogic::ERotationType rotationType, const std::pair& objectID) { - RamsesNodeBinding binding{logicEngine->createRamsesNodeBinding(**node, rotationType), - [logicEngine, forceNodeCopy = node](rlogic::RamsesNodeBinding* binding) { +inline RamsesNodeBinding ramsesNodeBinding(NodeHandleType node, ramses::LogicEngine* logicEngine, ramses::ERotationType rotationType, const std::pair& objectID) { + RamsesNodeBinding binding{logicEngine->createNodeBinding(**node, rotationType), + [logicEngine, forceNodeCopy = node](ramses::NodeBinding* binding) { destroyLogicObject(logicEngine, binding); }}; @@ -651,9 +761,9 @@ inline RamsesNodeBinding ramsesNodeBinding(NodeHandleType node, rlogic::LogicEng return binding; } -inline RamsesMeshNodeBinding ramsesMeshNodeBinding(RamsesMeshNode meshnode, rlogic::LogicEngine* logicEngine, const std::string& name, const std::pair& objectID) { - RamsesMeshNodeBinding binding{logicEngine->createRamsesMeshNodeBinding(**meshnode, name), - [logicEngine, forceNodeCopy = meshnode](rlogic::RamsesMeshNodeBinding* binding) { +inline RamsesMeshNodeBinding ramsesMeshNodeBinding(RamsesMeshNode meshnode, ramses::LogicEngine* logicEngine, const std::string& name, const std::pair& objectID) { + RamsesMeshNodeBinding binding{logicEngine->createMeshNodeBinding(**meshnode, name), + [logicEngine, forceNodeCopy = meshnode](ramses::MeshNodeBinding* binding) { destroyLogicObject(logicEngine, binding); }}; @@ -665,8 +775,8 @@ inline RamsesMeshNodeBinding ramsesMeshNodeBinding(RamsesMeshNode meshnode, rlog } template -inline UniqueRamsesDataArray ramsesDataArray(const std::vector& vec, rlogic::LogicEngine* logicEngine, const std::string& name, const std::pair& objectID) { - UniqueRamsesDataArray array{logicEngine->createDataArray(vec, name), [logicEngine](rlogic::DataArray* array) { +inline UniqueRamsesDataArray ramsesDataArray(const std::vector& vec, ramses::LogicEngine* logicEngine, const std::string& name, const std::pair& objectID) { + UniqueRamsesDataArray array{logicEngine->createDataArray(vec, name), [logicEngine](ramses::DataArray* array) { destroyLogicObject(logicEngine, array); }}; @@ -678,10 +788,10 @@ inline UniqueRamsesDataArray ramsesDataArray(const std::vector& vec, rlogic:: } template -inline RamsesCameraBinding ramsesCameraBinding(CameraHandleType camera, rlogic::LogicEngine* logicEngine, const std::pair& objectID, bool frustumPlanes) { +inline RamsesCameraBinding ramsesCameraBinding(CameraHandleType camera, ramses::LogicEngine* logicEngine, const std::pair& objectID, bool frustumPlanes) { RamsesCameraBinding binding{ - frustumPlanes ? logicEngine->createRamsesCameraBindingWithFrustumPlanes(**camera) : logicEngine->createRamsesCameraBinding(**camera), - [logicEngine, forceCameraCopy = camera](rlogic::RamsesCameraBinding* binding) { + frustumPlanes ? logicEngine->createCameraBindingWithFrustumPlanes(**camera) : logicEngine->createCameraBinding(**camera), + [logicEngine, forceCameraCopy = camera](ramses::CameraBinding* binding) { destroyLogicObject(logicEngine, binding); }}; @@ -692,8 +802,8 @@ inline RamsesCameraBinding ramsesCameraBinding(CameraHandleType camera, rlogic:: return binding; } -inline UniqueRamsesRenderPassBinding ramsesRenderPassBinding(ramses::RenderPass& renderpass, rlogic::LogicEngine* logicEngine, const std::string& name, const std::pair& objectID) { - UniqueRamsesRenderPassBinding binding{logicEngine->createRamsesRenderPassBinding(renderpass, name), [logicEngine](rlogic::RamsesRenderPassBinding* binding) { +inline UniqueRamsesRenderPassBinding ramsesRenderPassBinding(ramses::RenderPass& renderpass, ramses::LogicEngine* logicEngine, const std::string& name, const std::pair& objectID) { + UniqueRamsesRenderPassBinding binding{logicEngine->createRenderPassBinding(renderpass, name), [logicEngine](ramses::RenderPassBinding* binding) { destroyLogicObject(logicEngine, binding); }}; @@ -705,8 +815,8 @@ inline UniqueRamsesRenderPassBinding ramsesRenderPassBinding(ramses::RenderPass& } -inline RamsesTimerNode ramsesTimer(rlogic::LogicEngine* logicEngine, const std::string& name, const std::pair& objectID) { - RamsesTimerNode node{logicEngine->createTimerNode(name), [logicEngine](rlogic::TimerNode* timer) { +inline RamsesTimerNode ramsesTimer(ramses::LogicEngine* logicEngine, const std::string& name, const std::pair& objectID) { + RamsesTimerNode node{logicEngine->createTimerNode(name), [logicEngine](ramses::TimerNode* timer) { destroyLogicObject(logicEngine, timer); }}; @@ -717,10 +827,10 @@ inline RamsesTimerNode ramsesTimer(rlogic::LogicEngine* logicEngine, const std:: return node; } -inline RamsesLuaModule ramsesLuaModule(const std::string& luaContent, rlogic::LogicEngine* logicEngine, rlogic::LuaConfig& config, const std::string& name, const std::pair& objectID) { +inline RamsesLuaModule ramsesLuaModule(const std::string& luaContent, ramses::LogicEngine* logicEngine, ramses::LuaConfig& config, const std::string& name, const std::pair& objectID) { RamsesLuaModule module{ - logicEngine->createLuaModule(luaContent, config, name), [logicEngine](rlogic::LuaModule* module) { + logicEngine->createLuaModule(luaContent, config, name), [logicEngine](ramses::LuaModule* module) { destroyLogicObject(logicEngine, module); }}; @@ -731,10 +841,10 @@ inline RamsesLuaModule ramsesLuaModule(const std::string& luaContent, rlogic::Lo return module; } -inline RamsesLuaScript ramsesLuaScript(rlogic::LogicEngine* logicEngine, const std::string& scriptText, rlogic::LuaConfig& config, std::vector modules, const std::string& name, const std::pair& objectID) { +inline RamsesLuaScript ramsesLuaScript(ramses::LogicEngine* logicEngine, const std::string& scriptText, ramses::LuaConfig& config, std::vector modules, const std::string& name, const std::pair& objectID) { RamsesLuaScript script{ logicEngine->createLuaScript(scriptText, config, name), - [logicEngine, forceCopy = modules](rlogic::LuaScript* script) { + [logicEngine, forceCopy = modules](ramses::LuaScript* script) { destroyLogicObject(logicEngine, script); }}; @@ -745,29 +855,11 @@ inline RamsesLuaScript ramsesLuaScript(rlogic::LogicEngine* logicEngine, const s return script; } - -/// Old style creation function: doesn't generate error if interface text contains modules() statement -/// used at feature level < 5 -inline RamsesLuaInterface ramsesLuaInterface(rlogic::LogicEngine* logicEngine, const std::string& interfaceText, const std::string& name, const std::pair& objectID) { - RamsesLuaInterface interface { - logicEngine->createLuaInterface(interfaceText, name), - [logicEngine](rlogic::LuaInterface* interface) { - destroyLogicObject(logicEngine, interface); - } - }; - - if (interface) { - interface->setUserId(objectID.first, objectID.second); - } - return interface; -} - -/// New style creation function: must supply modules if interface text contains modules() statement -/// used at feature level >= 5 -inline RamsesLuaInterface ramsesLuaInterface(rlogic::LogicEngine* logicEngine, const std::string& interfaceText, rlogic::LuaConfig& config, std::vector modules, const std::string& name, const std::pair& objectID) { +/// Note that caller must supply modules if interface text contains modules() statement +inline RamsesLuaInterface ramsesLuaInterface(ramses::LogicEngine* logicEngine, const std::string& interfaceText, ramses::LuaConfig& config, std::vector modules, const std::string& name, const std::pair& objectID) { RamsesLuaInterface interface{ logicEngine->createLuaInterface(interfaceText, name, config), - [logicEngine, forceCopy = modules](rlogic::LuaInterface* interface) { + [logicEngine, forceCopy = modules](ramses::LuaInterface* interface) { destroyLogicObject(logicEngine, interface); }}; @@ -779,7 +871,7 @@ inline RamsesLuaInterface ramsesLuaInterface(rlogic::LogicEngine* logicEngine, c struct RamsesAnimationChannelData { std::string name; - rlogic::EInterpolationType interpolationType; + ramses::EInterpolationType interpolationType; UniqueRamsesDataArray keyframeTimes; UniqueRamsesDataArray animOutput; UniqueRamsesDataArray tangentIn; @@ -789,7 +881,7 @@ struct RamsesAnimationChannelData { using RamsesAnimationChannelHandle = RamsesHandle; struct RamsesAnimationNodeHandle { - RamsesAnimationNodeHandle(rlogic::LogicEngine* logicEngine, rlogic::AnimationNode* ramsesAnimationNode, std::vector channelHandles, const std::pair& objectID) + RamsesAnimationNodeHandle(ramses::LogicEngine* logicEngine, ramses::AnimationNode* ramsesAnimationNode, std::vector channelHandles, const std::pair& objectID) : logicEngine_(logicEngine), animationNode_(ramsesAnimationNode), trackedAnimationChannels_(channelHandles) { if (animationNode_) { animationNode_->setUserId(objectID.first, objectID.second); @@ -800,15 +892,15 @@ struct RamsesAnimationNodeHandle { destroyLogicObject(logicEngine_, animationNode_); } - rlogic::AnimationNode& operator*() { + ramses::AnimationNode& operator*() { return *animationNode_; } - rlogic::AnimationNode* operator->() { + ramses::AnimationNode* operator->() { return animationNode_; } - rlogic::AnimationNode* get() { + ramses::AnimationNode* get() { return animationNode_; } @@ -818,10 +910,10 @@ struct RamsesAnimationNodeHandle { private: // Kept for reference. Needed to destroy the animation node. - rlogic::LogicEngine* logicEngine_; + ramses::LogicEngine* logicEngine_; // The animation node is owned by this class. - rlogic::AnimationNode* animationNode_; + ramses::AnimationNode* animationNode_; // AnimationChannels currently used by the animation node. Needed to keep the effect alive in ramses. // May contain nullptrs; @@ -831,7 +923,7 @@ struct RamsesAnimationNodeHandle { using RamsesAnimationNode = std::shared_ptr; -inline RamsesAnimationNode ramsesAnimationNode(rlogic::LogicEngine* logicEngine, const rlogic::AnimationNodeConfig &config, +inline RamsesAnimationNode ramsesAnimationNode(ramses::LogicEngine* logicEngine, const ramses::AnimationNodeConfig &config, std::vector channelHandles, const std::string& name, const std::pair& objectID) { if (channelHandles.empty()) { return {}; @@ -846,10 +938,10 @@ std::vector channelHandles, const std::string& nam -inline RamsesAnchorPoint ramsesAnchorPoint(rlogic::LogicEngine* logicEngine, RamsesNodeBinding nodeBinding, RamsesCameraBinding cameraBinding, const std::string& name, const std::pair& objectID) { +inline RamsesAnchorPoint ramsesAnchorPoint(ramses::LogicEngine* logicEngine, RamsesNodeBinding nodeBinding, RamsesCameraBinding cameraBinding, const std::string& name, const std::pair& objectID) { RamsesAnchorPoint object( logicEngine->createAnchorPoint(*nodeBinding, *cameraBinding, name), - [logicEngine, forceNodeBindingCopy = nodeBinding, forceCameraBdingingCopy = cameraBinding](rlogic::AnchorPoint* object) { + [logicEngine, forceNodeBindingCopy = nodeBinding, forceCameraBdingingCopy = cameraBinding](ramses::AnchorPoint* object) { destroyLogicObject(logicEngine, object); }); @@ -860,20 +952,20 @@ inline RamsesAnchorPoint ramsesAnchorPoint(rlogic::LogicEngine* logicEngine, Ram return object; } -inline RamsesSkinBinding ramsesSkinBinding(rlogic::LogicEngine* logicEngine, +inline RamsesSkinBinding ramsesSkinBinding(ramses::LogicEngine* logicEngine, std::vector joints, - std::vector>& inverseBindMatrices, + std::vector& inverseBindMatrices, RamsesAppearanceBinding& appearanceBinding, ramses::UniformInput& jointMatInput, const std::string& name, const std::pair& objectID) { - std::vector nodeBindings; + std::vector nodeBindings; for (const auto& binding : joints) { nodeBindings.emplace_back(binding.get()); } RamsesSkinBinding object(logicEngine->createSkinBinding(nodeBindings, inverseBindMatrices, *appearanceBinding, jointMatInput, name), - [logicEngine, forceJointsCopy = joints, forceAppearanceBindingCopy = appearanceBinding](rlogic::SkinBinding* object) { + [logicEngine, forceJointsCopy = joints, forceAppearanceBindingCopy = appearanceBinding](ramses::SkinBinding* object) { destroyLogicObject(logicEngine, object); }); @@ -884,9 +976,9 @@ inline RamsesSkinBinding ramsesSkinBinding(rlogic::LogicEngine* logicEngine, return object; } -inline RamsesRenderGroupBinding ramsesRenderGroupBinding(rlogic::LogicEngine* logicEngine, RamsesRenderGroup renderGroup, const rlogic::RamsesRenderGroupBindingElements& elements, std::vector nestedGroups, const std::string& name, const std::pair& objectID) { - RamsesRenderGroupBinding binding{logicEngine->createRamsesRenderGroupBinding(**renderGroup, elements, name), - [logicEngine, forceRenderGroupCopy = renderGroup, forceNestedGroupCopy = nestedGroups](rlogic::RamsesRenderGroupBinding* binding) { +inline RamsesRenderGroupBinding ramsesRenderGroupBinding(ramses::LogicEngine* logicEngine, RamsesRenderGroup renderGroup, const ramses::RenderGroupBindingElements& elements, std::vector nestedGroups, const std::string& name, const std::pair& objectID) { + RamsesRenderGroupBinding binding{logicEngine->createRenderGroupBinding(**renderGroup, elements, name), + [logicEngine, forceRenderGroupCopy = renderGroup, forceNestedGroupCopy = nestedGroups](ramses::RenderGroupBinding* binding) { destroyLogicObject(logicEngine, binding); }}; diff --git a/components/libRamsesBase/include/ramses_base/Utils.h b/components/libRamsesBase/include/ramses_base/Utils.h index 43f97e11..f93fefec 100644 --- a/components/libRamsesBase/include/ramses_base/Utils.h +++ b/components/libRamsesBase/include/ramses_base/Utils.h @@ -14,42 +14,45 @@ #include "core/Project.h" #include "data_storage/Value.h" #include "log_system/log.h" -#include "ramses_base/LogicEngine.h" #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include #include +#include + namespace raco::ramses_base { std::unique_ptr createEffectDescription(const std::string& vertexShader, const std::string& geometryShader, const std::string& fragmentShader, const std::string& shaderDefines); -using PropertyInterfaceList = raco::core::PropertyInterfaceList; +using PropertyInterfaceList = core::PropertyInterfaceList; // Parse shaders using Ramses and return set of uniforms with name and type. // Returns true if shader can be successfully parsed. -bool parseShaderText(ramses::Scene& scene, const std::string& vertexShader, const std::string& geometryShader, const std::string& fragmentShader, const std::string& shaderDefines, PropertyInterfaceList& outUniforms, raco::core::PropertyInterfaceList& outAttributes, std::string& outError); +bool parseShaderText(ramses::Scene& scene, const std::string& vertexShader, const std::string& geometryShader, const std::string& fragmentShader, const std::string& shaderDefines, PropertyInterfaceList& outUniforms, core::PropertyInterfaceList& outAttributes, std::string& outError); -rlogic::LuaConfig defaultLuaConfig(); -rlogic::LuaConfig createLuaConfig(const std::vector& stdModules); +ramses::LuaConfig defaultLuaConfig(); +ramses::LuaConfig createLuaConfig(const std::vector& stdModules); ramses::RamsesVersion getRamsesVersion(); -rlogic::RamsesLogicVersion getLogicEngineVersion(); std::string getRamsesVersionString(); -std::string getLogicEngineVersionString(); + +ramses::ELogLevel toRamsesLogLevel(spdlog::level::level_enum level); void installRamsesLogHandler(bool enableTrace); -void installLogicLogHandler(); -void setRamsesLogLevel(spdlog::level::level_enum level); -void setLogicLogLevel(spdlog::level::level_enum level); + +spdlog::level::level_enum getLevelFromArg(const QString& arg); +ramses::ELogLevel getRamsesLogLevelFromArg(const QString& arg); + +void addRamseFrameworkOptions(QCommandLineParser& parser); +std::vector ramsesLogCategories(); struct PngCompatibilityInfo { std::string errorMsg; - raco::core::ErrorLevel errorLvl; + core::ErrorLevel errorLvl; bool conversionNeeded; }; @@ -59,7 +62,7 @@ struct PngDecodingInfo { int bitdepth = -1; int originalBitdepth = -1; int originalPngFormat = -1; - ramses::ETextureFormat convertedPngFormat = ramses::ETextureFormat::Invalid; + ramses::ETextureFormat convertedPngFormat = ramses::ETextureFormat::RGB8; std::string pngColorChannels; std::string ramsesColorChannels; std::string shaderColorChannels; @@ -75,12 +78,10 @@ std::vector decodeMipMapData(core::Errors* errors, core::Project& std::tuple ramsesTextureFormatToSwizzleInfo(int colorType, ramses::ETextureFormat textureFormat); -int clipAndCheckIntProperty(const raco::core::ValueHandle value, core::Errors* errors, bool* allValid); - -ramses::ERenderBufferType ramsesRenderBufferTypeFromFormat(ramses::ERenderBufferFormat format); +int clipAndCheckIntProperty(const core::ValueHandle value, core::Errors* errors, bool* allValid); -std::vector getRamsesUniformPropertyNames(core::ValueHandle uniformContainerHandle, const std::vector& propertyNames, size_t startIndex = 0); +std::vector getRamsesUniformPropertyNames(core::ValueHandle uniformContainerHandle, const std::vector& propertyNames, size_t startIndex = 0); std::string getRamsesUniformPropertyName(core::ValueHandle uniformContainerHandle, core::ValueHandle uniformHandle); diff --git a/components/libRamsesBase/src/ramses_adaptor/AbstractMeshAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/AbstractMeshAdaptor.cpp new file mode 100644 index 00000000..7e89faa5 --- /dev/null +++ b/components/libRamsesBase/src/ramses_adaptor/AbstractMeshAdaptor.cpp @@ -0,0 +1,70 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#include "ramses_adaptor/AbstractMeshAdaptor.h" + +#include "ramses_adaptor/AbstractSceneAdaptor.h" +#include "ramses_adaptor/utilities.h" +#include "ramses_base/RamsesHandles.h" +#include "user_types/Mesh.h" +#include + +namespace raco::ramses_adaptor { + +using namespace raco::ramses_base; + +AbstractMeshAdaptor::AbstractMeshAdaptor(AbstractSceneAdaptor* sceneAdaptor, user_types::SMesh mesh) + : AbstractUserTypeObjectAdaptor{sceneAdaptor, mesh}, + subscription_{sceneAdaptor_->dispatcher()->registerOnPreviewDirty(editorObject_, [this]() { + tagDirty(); + })} { +} + +ramses_base::RamsesArrayResource AbstractMeshAdaptor::indicesPtr() { + return indices_; +} + +const VertexDataMap& AbstractMeshAdaptor::vertexData() const { + return vertexDataMap_; +} + +const ramses_base::RamsesArrayBuffer AbstractMeshAdaptor::triangleBuffer() const { + return triangleBuffer_; +} + +bool AbstractMeshAdaptor::isValid() { + auto mesh = editorObject_->meshData(); + return mesh.get() != nullptr; +} + +bool AbstractMeshAdaptor::sync() { + AbstractObjectAdaptor::sync(); + triangleBuffer_.reset(); + if (isValid()) { + auto mesh = editorObject_->meshData(); + auto indices = mesh->getIndices(); + indices_ = ramsesArrayResource(sceneAdaptor_->scene(), indices, std::string(this->editorObject_->objectName() + "_MeshIndexData").c_str()); + + for (uint32_t i{0}; i < mesh->numAttributes(); i++) { + auto name = mesh->attribName(i); + std::string attribName = this->editorObject_->objectName() + "_MeshVertexData_" + name; + vertexDataMap_[name] = arrayResourceFromAttribute(sceneAdaptor_->scene(), mesh, i, attribName); + } + + const auto& triangleData = mesh->triangleBuffer(); + triangleBuffer_ = ramsesArrayBuffer(sceneAdaptor_->scene(), ramses::EDataType::Vector3F, triangleData.size(), triangleData.data()); + } else { + vertexDataMap_.clear(); + indices_.reset(); + } + tagDirty(false); + return true; +} + +}; // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/src/ramses_adaptor/AbstractMeshNodeAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/AbstractMeshNodeAdaptor.cpp new file mode 100644 index 00000000..7ce3d508 --- /dev/null +++ b/components/libRamsesBase/src/ramses_adaptor/AbstractMeshNodeAdaptor.cpp @@ -0,0 +1,167 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#include "ramses_adaptor/AbstractMeshNodeAdaptor.h" + +namespace raco::ramses_adaptor { + +AbstractMeshNodeAdaptor::AbstractMeshNodeAdaptor(AbstractSceneAdaptor* sceneAdaptor, user_types::SMeshNode node) + : AbstractSpatialAdaptor{sceneAdaptor, node, ramses_base::ramsesMeshNode(sceneAdaptor->scene(), node->objectIDAsRamsesLogicID())}, + meshSubscription_{ + sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{node, &user_types::MeshNode::mesh_}, [this]() { + tagDirty(); + })}, + instanceCountSubscription_{sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{node, &user_types::MeshNode::instanceCount_}, [this] { + tagDirty(); + })}, + visibilitySubscription_{sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{node, &user_types::MeshNode::editorVisibility_}, [this] { + tagDirty(); + })} { +} + +AbstractMeshNodeAdaptor::~AbstractMeshNodeAdaptor() { + resetRamsesObject(); +} + +user_types::SMesh AbstractMeshNodeAdaptor::mesh() { + return *editorObject()->mesh_; +} + +AbstractMeshAdaptor* AbstractMeshNodeAdaptor::meshAdaptor() { + if (auto m = mesh()) { + auto adaptor = sceneAdaptor_->lookup(m); + if (adaptor->isValid()) { + return adaptor; + } + } + return nullptr; +} + +bool AbstractMeshNodeAdaptor::sync() { + AbstractSpatialAdaptor::sync(); + if (*editorObject()->instanceCount_ >= 1) { + (*ramsesObject()).setInstanceCount(*editorObject()->instanceCount_); + } + + syncMaterials(); + syncMeshObject(); + + (*ramsesObject()).setVisibility(*editorObject()->editorVisibility_ ? ramses::EVisibilityMode::Visible : ramses::EVisibilityMode::Invisible); + + tagDirty(false); + return true; +} + +void AbstractMeshNodeAdaptor::syncMaterials() { + syncMaterial(0); +} + +BoundingBox AbstractMeshNodeAdaptor::getBoundingBox(bool worldCoordinates) { + if (getRamsesObjectPointer() != nullptr) { + glm::mat4x4 trafoMatrix = glm::identity(); + if (worldCoordinates) { + (*ramsesObject()).getModelMatrix(trafoMatrix); + } + + if (triangles_) { + auto numElements = triangles_->getUsedNumberOfElements(); + std::vector data(numElements); + triangles_->getData(data.data(), numElements); + + BoundingBox bbox; + for (auto index = 0; index < numElements; index++) { + auto v = glm::vec3(trafoMatrix * glm::vec4(data[index], 1.0)); + bbox.merge(v); + } + return bbox; + } + } + return {}; +} + +bool AbstractMeshNodeAdaptor::highlighted() const { + return highlight_; +} + +void AbstractMeshNodeAdaptor::setHighlighted(bool highlight) { + highlight_ = highlight; + tagDirty(); +} + +void AbstractMeshNodeAdaptor::syncMaterial(size_t index) { + assert((index == 0) && "We only support one material for now."); + // we need to reset the geometry in case of the new appearance not being compatible with the current geometry + ramsesObject().removeAppearanceAndGeometry(); + + bool haveMeshNormals = false; + if (AbstractMeshAdaptor* meshAdapt = meshAdaptor()) { + auto vertexData = meshAdapt->vertexData(); + if (vertexData.find("a_Normal") != vertexData.end()) { + haveMeshNormals = true; + } + } else { + haveMeshNormals = true; + } + + currentAppearance_ = sceneAdaptor_->defaultAppearance(haveMeshNormals, highlight_); + ramsesObject().setAppearance(currentAppearance_); +} + +void AbstractMeshNodeAdaptor::syncMeshObject() { + pickObject_.reset(); + triangles_.reset(); + auto geometry = ramses_base::ramsesGeometry(sceneAdaptor_->scene(), currentAppearance_->effect(), editorObject()->objectIDAsRamsesLogicID()); + (*geometry)->setName(std::string(this->editorObject()->objectName() + "_Geometry").c_str()); + + if (AbstractMeshAdaptor* meshAdapt = meshAdaptor()) { + LOG_TRACE(log_system::RAMSES_ADAPTOR, "using meshAdaptor"); + + auto vertexData = meshAdapt->vertexData(); + for (uint32_t i = 0; i < currentAppearance_->effect()->getAttributeInputCount(); i++) { + ramses::AttributeInput attribInput = currentAppearance_->effect()->getAttributeInput(i).value(); + std::string attribName = attribInput.getName(); + + auto it = vertexData.find(attribName); + if (it != vertexData.end()) { + geometry->addAttributeBuffer(attribInput, it->second); + } else { + LOG_ERROR(log_system::RAMSES_ADAPTOR, "Attrribute mismatch in MeshNode '{}': attribute '{}' not found in Mesh '{}'.", editorObject()->objectName(), attribName, mesh()->objectName()); + } + } + + geometry->setIndices(meshAdapt->indicesPtr()); + + triangles_ = meshAdapt->triangleBuffer(); + } else { + LOG_TRACE(log_system::RAMSES_ADAPTOR, "using defaultMesh"); + int index = *editorObject()->instanceCount_ == -1 ? 1 : 0; + ramses::AttributeInput inputPosition = (*currentAppearance_)->getEffect().findAttributeInput(core::MeshData::ATTRIBUTE_POSITION).value(); + geometry->addAttributeBuffer(inputPosition, sceneAdaptor_->defaultVertices(index)); + + ramses::AttributeInput inputNormals = (*currentAppearance_)->getEffect().findAttributeInput(core::MeshData::ATTRIBUTE_NORMAL).value(); + geometry->addAttributeBuffer(inputNormals, sceneAdaptor_->defaultNormals(index)); + + geometry->setIndices(sceneAdaptor_->defaultIndices(index)); + + triangles_ = sceneAdaptor_->defaultTriangles(index); + } + + if (*editorObject()->editorVisibility_) { + pickObject_ = ramses_base::ramsesPickableObject(sceneAdaptor_->scene(), triangles_, sceneAdaptor_->getPickId(editorObject()), sceneAdaptor_->camera()); + if (pickObject_) { + ramsesObject().get()->addChild(*(pickObject_.get())); + } else { + LOG_ERROR(log_system::RAMSES_ADAPTOR, "Ramses pickable object creation for '{}' failed", editorObject()->objectName()); + } + } + + ramsesObject().setGeometry(geometry); +} + +}; // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/src/ramses_adaptor/AbstractNodeAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/AbstractNodeAdaptor.cpp new file mode 100644 index 00000000..b557bc94 --- /dev/null +++ b/components/libRamsesBase/src/ramses_adaptor/AbstractNodeAdaptor.cpp @@ -0,0 +1,18 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#include "ramses_adaptor/AbstractNodeAdaptor.h" + +namespace raco::ramses_adaptor { + +AbstractNodeAdaptor::AbstractNodeAdaptor(AbstractSceneAdaptor* sceneAdaptor, user_types::SNode node) + : AbstractSpatialAdaptor{sceneAdaptor, node, ramses_base::ramsesNode(sceneAdaptor->scene(), node->objectIDAsRamsesLogicID())} {} + +} + diff --git a/components/libRamsesBase/src/ramses_adaptor/AbstractObjectAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/AbstractObjectAdaptor.cpp new file mode 100644 index 00000000..690fc537 --- /dev/null +++ b/components/libRamsesBase/src/ramses_adaptor/AbstractObjectAdaptor.cpp @@ -0,0 +1,30 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#include "ramses_adaptor/AbstractObjectAdaptor.h" + + +namespace raco::ramses_adaptor { + +AbstractObjectAdaptor::~AbstractObjectAdaptor() { +} + +bool AbstractObjectAdaptor::sync() { + return false; +} + +bool AbstractObjectAdaptor::isDirty() const { + return dirtyStatus_; +} + +void AbstractObjectAdaptor::tagDirty(bool newStatus) { + dirtyStatus_ = newStatus; +} + +} // namespace raco::ramses_adaptor \ No newline at end of file diff --git a/components/libRamsesBase/src/ramses_adaptor/AbstractSceneAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/AbstractSceneAdaptor.cpp new file mode 100644 index 00000000..21cf6610 --- /dev/null +++ b/components/libRamsesBase/src/ramses_adaptor/AbstractSceneAdaptor.cpp @@ -0,0 +1,475 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#include "ramses_adaptor/AbstractSceneAdaptor.h" + +#include "components/DataChangeDispatcher.h" +#include "components/EditorObjectFormatter.h" +#include "core/Iterators.h" +#include "core/PrefabOperations.h" +#include "core/Project.h" +#include "core/ProjectSettings.h" +#include "core/Queries.h" +#include "ramses_adaptor/AbstractMeshNodeAdaptor.h" +#include "ramses_adaptor/Factories.h" +#include "ramses_base/RamsesHandles.h" +#include "user_types/MeshNode.h" +#include "user_types/RenderPass.h" + +#include +#include +#include +#include + +namespace raco::ramses_adaptor { + +using namespace raco::ramses_base; + +bool AbstractSceneAdaptor::Flags::operator<(const Flags& other) const { + unsigned flags = (normals ? 1 : 0) | (highlight ? 2 : 0) | (transparent ? 4 : 0); + unsigned otherFlags = (other.normals ? 1 : 0) | (other.highlight ? 2 : 0) | (other.transparent ? 4 : 0); + return flags < otherFlags; +} + +AbstractSceneAdaptor::AbstractSceneAdaptor(ramses::RamsesClient* client, ramses::sceneId_t id, Project* project, components::SDataChangeDispatcher dispatcher, core::MeshCache* meshCache, SceneAdaptor* previewAdaptor) + : client_{client}, + project_(project), + scene_{ramsesScene(id, client_)}, + meshCache_(meshCache), + previewAdaptor_(previewAdaptor), + subscription_{dispatcher->registerOnObjectsLifeCycle([this](SEditorObject obj) { createAdaptor(obj); }, [this](SEditorObject obj) { removeAdaptor(obj); })}, + childrenSubscription_(dispatcher->registerOnPropertyChange("children", [this](core::ValueHandle handle) { + adaptorStatusDirty_ = true; + })), + dispatcher_{dispatcher}, + camera_{ramsesPerspectiveCamera(scene(), {0, 0})}, + cameraController_(camera_), + grid_(scene_.get()), + clearDepth_(scene_.get()), + guides_(scene_.get()) { + for (const SEditorObject& obj : project_->instances()) { + createAdaptor(obj); + } + + dispatcher_->addBulkChangeCallback(id.getValue(), [this](const core::SEditorObjectSet& changedObjects) { + performBulkEngineUpdate(changedObjects); + }); + + rescaleCameraToViewport(1440, 720); + + renderGroup_ = ramsesRenderGroup(scene(), {0, 0}); + + renderPass_ = ramses_base::ramsesRenderPass(scene(), camera_, {}, "abstractRenderPass", {0, 0}); + renderPass_->addRenderGroup(renderGroup_); + + gizmoRenderGroup_ = ramsesRenderGroup(scene(), {0, 0}); + renderPass_->addRenderGroup(gizmoRenderGroup_, 3); + + gizmoRenderGroupTransparent_ = ramsesRenderGroup(scene(), {0, 0}); + renderPass_->addRenderGroup(gizmoRenderGroupTransparent_, 1); + + grid_.setup(renderPass_, true, 0.75, 1); + updateGridScale(cameraController_.cameraDistance()); + grid_.enable(glm::vec3(0, 0, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 0, 2, true, glm::vec2(1, 1)); + + clearDepth_.setup(renderPass_, 2); + + guides_.setup(renderPass_, false, 1.0, 4); + + + const auto& instances{project_->instances()}; + core::SEditorObjectSet initialBulkUpdate(instances.begin(), instances.end()); + performBulkEngineUpdate(initialBulkUpdate); + + scene_->flush(); + scene_->publish(ramses::EScenePublicationMode::LocalAndRemote); + + QObject::connect(&cameraController_, &CameraController::distanceChanged, [this](float cameraDistance) { + updateGridScale(cameraDistance); + }); + + gizmoArrowBuffers_ = loadGizmoMesh(scene_.get(), meshCache_, "meshes/gizmo-arrow.glb"); + gizmoScaleBuffers_ = loadGizmoMesh(scene_.get(), meshCache_, "meshes/gizmo-scale.glb"); + gizmoSphereBuffers_ = loadGizmoMesh(scene_.get(), meshCache_, "meshes/sphere-ico.glb"); + gizmoTorusBuffers_ = loadGizmoMesh(scene_.get(), meshCache_, "meshes/gizmo-torus.glb"); +} + +AbstractSceneAdaptor::~AbstractSceneAdaptor() { + dispatcher_->removeBulkChangeCallback(sceneId().getValue()); +} + +void AbstractSceneAdaptor::updateGridScale(float cameraDistance) { + gridScale_ = pow(10.0, floor(log10(cameraDistance / 2.0))); + grid_.setScale(gridScale_); + Q_EMIT scaleChanged(gridScale_); +} + +void AbstractSceneAdaptor::rescaleCameraToViewport(uint32_t width, uint32_t height) { + cameraController_.rescaleCameraToViewport(width, height); +} + +CameraController& AbstractSceneAdaptor::cameraController() { + return cameraController_; +} + +ramses_base::RamsesPerspectiveCamera AbstractSceneAdaptor::camera() { + return camera_; +} + +BoundingBox AbstractSceneAdaptor::getBoundingBox(std::vector selection) { + BoundingBox bbox; + for (auto obj : core::Queries::collectAllChildren(selection)) { + if (auto adaptor = lookup(obj)) { + bbox.merge(adaptor->getBoundingBox(true)); + } + } + return bbox; +} + +float AbstractSceneAdaptor::gridScale() { + return gridScale_; +} + +ramses::Scene* AbstractSceneAdaptor::scene() { + return scene_.get(); +} + +ramses::sceneId_t AbstractSceneAdaptor::sceneId() { + return scene_->getSceneId(); +} + +void AbstractSceneAdaptor::setPreviewAdaptor(SceneAdaptor* previewAdaptor) { + previewAdaptor_ = previewAdaptor; +} + +SceneAdaptor* AbstractSceneAdaptor::previewAdaptor() { + return previewAdaptor_; +} + +bool AbstractSceneAdaptor::needAdaptor(SEditorObject object) { + return !core::PrefabOperations::findContainingPrefab(object) && !object->isType(); +} + +void AbstractSceneAdaptor::createAdaptor(SEditorObject obj) { + if (needAdaptor(obj)) { + auto adaptor = Factories::createAbstractAdaptor(this, obj); + if (adaptor) { + adaptor->tagDirty(); + adaptors_[obj] = std::move(adaptor); + } + } +} + +void AbstractSceneAdaptor::removeAdaptor(SEditorObject obj) { + adaptors_.erase(obj); + deleteUnusedDefaultResources(); + dependencyGraph_.clear(); + if (gizmo_ && gizmo_->object() == obj) { + gizmo_.reset(); + } +} + +void AbstractSceneAdaptor::iterateAdaptors(std::function func) { + for (const auto& [obj, adaptor] : adaptors_) { + func(adaptor.get()); + } +} + +void AbstractSceneAdaptor::deleteUnusedDefaultResources() { + // Resource use count is 1 => it is stored in the scene but not used by any MeshNodeAdaptor + // - delete the resource as to not get unnecessarily exported. + auto it = defaultAppearances_.begin(); + while (it != defaultAppearances_.end()) { + if (it->second.use_count() == 1) { + it = defaultAppearances_.erase(it); + } else { + ++it; + } + } + if (defaultIndices_[0].use_count() == 1) { + defaultIndices_[0].reset(); + } + if (defaultIndices_[1].use_count() == 1) { + defaultIndices_[1].reset(); + } + if (defaultVertices_[0].use_count() == 1) { + defaultVertices_[0].reset(); + } + if (defaultVertices_[1].use_count() == 1) { + defaultVertices_[1].reset(); + } + if (defaultNormals_[0].use_count() == 1) { + defaultNormals_[0].reset(); + } + if (defaultNormals_[1].use_count() == 1) { + defaultNormals_[1].reset(); + } + if (defaultTriangles_[0].use_count() == 1) { + defaultTriangles_[0].reset(); + } + if (defaultTriangles_[1].use_count() == 1) { + defaultTriangles_[1].reset(); + } +} + +ramses::RamsesClient* AbstractSceneAdaptor::client() { + return client_; +} + +const ramses::RamsesClient* AbstractSceneAdaptor::client() const { + return client_; +} + +const SRamsesAdaptorDispatcher AbstractSceneAdaptor::dispatcher() const { + return dispatcher_; +} + +const RamsesAppearance AbstractSceneAdaptor::defaultAppearance(bool withMeshNormals, bool highlight) { + bool transparent = !highlight && highlightUsingTransparency_; + auto flags = Flags{withMeshNormals, highlight, transparent}; + + if (defaultAppearances_.find(flags) == defaultAppearances_.end()) { + defaultAppearances_[flags] = createDefaultAppearance(scene_.get(), withMeshNormals, highlight, transparent); + } + return defaultAppearances_[flags]; +} + + +const RamsesArrayResource AbstractSceneAdaptor::defaultVertices(int index) { + if (!defaultVertices_[index]) { + defaultVertices_[index] = index == 1 ? createCatVertexDataBuffer(scene_.get()) : createCubeVertexDataBuffer(scene_.get()); + } + return defaultVertices_[index]; +} + +const RamsesArrayResource AbstractSceneAdaptor::defaultNormals(int index) { + if (!defaultNormals_[index]) { + defaultNormals_[index] = index == 1 ? createCatNormalDataBuffer(scene_.get()) : createCubeNormalDataBuffer(scene_.get()); + } + return defaultNormals_[index]; +} + +const RamsesArrayBuffer AbstractSceneAdaptor::defaultTriangles(int index) { + if (!defaultTriangles_[index]) { + const std::vector& vertices = index == 1 ? cat_vertex_data : cubeVerticesData; + const std::vector& indices = index == 1 ? cat_indices_data : cubeIndicesData; + auto triangleData = core::MeshData::buildTriangleBuffer(vertices.data(), indices); + defaultTriangles_[index] = ramsesArrayBuffer(scene(), ramses::EDataType::Vector3F, triangleData.size(), triangleData.data()); + } + return defaultTriangles_[index]; +} + +const RamsesArrayResource AbstractSceneAdaptor::defaultIndices(int index) { + if (!defaultIndices_[index]) { + defaultIndices_[index] = index == 1 ? createCatIndexDataBuffer(scene_.get()) : createCubeIndexDataBuffer(scene_.get()); + } + return defaultIndices_[index]; +} + +AbstractObjectAdaptor* AbstractSceneAdaptor::lookupAdaptor(const core::SEditorObject& editorObject) const { + if (!editorObject) { + return nullptr; + } + auto adaptorIt = adaptors_.find(editorObject); + if (adaptorIt != adaptors_.end()) { + return adaptorIt->second.get(); + } + return nullptr; +} + +core::Project& AbstractSceneAdaptor::project() const { + return *project_; +} + +void AbstractSceneAdaptor::rebuildSortedDependencyGraph(SEditorObjectSet const& objects) { + dependencyGraph_ = buildSortedDependencyGraph(objects); +} + +void AbstractSceneAdaptor::performBulkEngineUpdate(const core::SEditorObjectSet& changedObjects) { + if (adaptorStatusDirty_) { + for (const auto& item : dependencyGraph_) { + auto object = item.object; + auto adaptor = lookupAdaptor(object); + + bool haveAdaptor = adaptor != nullptr; + if (haveAdaptor != needAdaptor(object)) { + if (haveAdaptor) { + removeAdaptor(object); + } else { + createAdaptor(object); + } + } + } + adaptorStatusDirty_ = false; + } + + if (dependencyGraph_.empty() || !changedObjects.empty()) { + rebuildSortedDependencyGraph(SEditorObjectSet(project_->instances().begin(), project_->instances().end())); + } + + renderGroup_->removeAllRenderables(); + + SEditorObjectSet updated; + for (const auto& item : dependencyGraph_) { + auto object = item.object; + if (auto adaptor = lookupAdaptor(object)) { + bool needsUpdate = adaptor->isDirty(); + if (!needsUpdate) { + needsUpdate = std::any_of(item.referencedObjects.begin(), item.referencedObjects.end(), + [&updated](SEditorObject const& object) { + return updated.find(object) != updated.end(); + }); + } + + if (needsUpdate) { + auto hasChanged = adaptor->sync(); + if (hasChanged) { + updated.insert(object); + } + } + } + } + + for (const auto& item : dependencyGraph_) { + auto object = item.object; + if (auto adaptor = lookup(object)) { + bool transparent = highlightUsingTransparency_ && !adaptor->highlighted(); + renderGroup_->addMeshNode(adaptor->getRamsesObjectPointer(), transparent ? 1 : 0); + } + } + + if (gizmo_) { + gizmo_->update(); + } + + if (!updated.empty()) { + deleteUnusedDefaultResources(); + } +} + +void AbstractSceneAdaptor::setHighlightedObjects(const std::vector& objects) { + auto highlightedObjects = core::Queries::collectAllChildren(objects); + for (const auto& [obj, adaptor] : adaptors_) { + if (auto meshNodeAdaptor = dynamic_cast(adaptor.get())) { + meshNodeAdaptor->setHighlighted(highlightedObjects.find(obj) != highlightedObjects.end()); + } + } +} + +void AbstractSceneAdaptor::updateGizmo() { + gizmo_.reset(); + if (gizmoObject_) { + switch (gizmoMode_) { + case GizmoMode::Locator: + gizmo_ = std::make_unique(this, scene_.get(), gizmoRenderGroup_, gizmoRenderGroupTransparent_, gizmoArrowBuffers_, gizmoObject_); + break; + case GizmoMode::Translate: + gizmo_ = std::make_unique(this, scene_.get(), gizmoRenderGroup_, gizmoRenderGroupTransparent_, gizmoArrowBuffers_, gizmoSphereBuffers_, gizmoObject_, true, true, false); + break; + case GizmoMode::Rotate: + gizmo_ = std::make_unique(this, scene_.get(), gizmoRenderGroup_, gizmoRenderGroupTransparent_, gizmoTorusBuffers_, gizmoSphereBuffers_, gizmoObject_, false, false, true); + break; + case GizmoMode::Scale: + gizmo_ = std::make_unique(this, scene_.get(), gizmoRenderGroup_, gizmoRenderGroupTransparent_, gizmoScaleBuffers_, gizmoSphereBuffers_, gizmoObject_, false, true, false); + break; + } + } +} + +void AbstractSceneAdaptor::attachGizmo(const std::vector& objects) { + if (objects.size() == 1 && hasModelMatrix(objects.front())) { + if (objects.front() != gizmoObject_) { + gizmoObject_ = objects.front(); + updateGizmo(); + } + } else if (gizmoObject_) { + gizmoObject_.reset(); + updateGizmo(); + } +} + +void AbstractSceneAdaptor::setGizmoMode(GizmoMode mode) { + if (mode != gizmoMode_) { + gizmoMode_ = mode; + updateGizmo(); + } +} + +AbstractSceneAdaptor::GizmoMode AbstractSceneAdaptor::gizmoMode() { + return gizmoMode_; +} + +void AbstractSceneAdaptor::setHighlightUsingTransparency(bool useTransparency) { + if (highlightUsingTransparency_ != useTransparency) { + highlightUsingTransparency_ = useTransparency; + for (const auto& [obj, adaptor] : adaptors_) { + if (auto meshNodeAdaptor = dynamic_cast(adaptor.get())) { + meshNodeAdaptor->tagDirty(); + } + } + } +} + +ramses::pickableObjectId_t AbstractSceneAdaptor::getPickId(SEditorObject object) { + auto it = objectPickIds_.find(object); + if (it != objectPickIds_.end()) { + return it->second; + } + return objectPickIds_[object] = ramses::pickableObjectId_t(nextFreePickId_++); +} + +ramses::pickableObjectId_t AbstractSceneAdaptor::getPickId() { + return ramses::pickableObjectId_t(nextFreePickId_++); +} + +core::SEditorObject AbstractSceneAdaptor::getPickedObject(ramses::pickableObjectId_t pickId) { + auto it = std::find_if(objectPickIds_.begin(), objectPickIds_.end(), [pickId](auto item) { + return item.second == pickId; + }); + if (it != objectPickIds_.end()) { + return it->first; + } + return {}; +} + +std::pair AbstractSceneAdaptor::getPickedGizmoElement(const std::vector& pickIds) { + if (gizmo_) { + for (auto id : pickIds) { + auto element = gizmo_->pickElement(id); + if (element.first != -1) { + return element; + } + } + } + return {-1, GizmoTriad::PickElement::None}; +} + +bool AbstractSceneAdaptor::hasModelMatrix(SEditorObject object) { + return lookup(object) || lookup(object); +} + +glm::mat4 AbstractSceneAdaptor::modelMatrix(SEditorObject node) { + glm::mat4 matrix = glm::identity(); + if (auto adaptor = lookup(node)) { + (*adaptor->ramsesObject()).getModelMatrix(matrix); + } else if (auto adaptor = lookup(node)) { + (*adaptor->ramsesObject()).getModelMatrix(matrix); + } + return matrix; +} + +void AbstractSceneAdaptor::enableGuides(glm::vec3 origin, glm::vec3 u, glm::vec3 v, int idx_u, int idx_v, bool full_grid, glm::vec2 enable) { + guides_.enable(origin, u, v, idx_u, idx_v, full_grid, enable); +} + +void AbstractSceneAdaptor::disableGuides() { + guides_.disable(); +} + +} // namespace raco::ramses_adaptor \ No newline at end of file diff --git a/components/libRamsesBase/src/ramses_adaptor/AnchorPointAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/AnchorPointAdaptor.cpp index af00e111..01db0f11 100644 --- a/components/libRamsesBase/src/ramses_adaptor/AnchorPointAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/AnchorPointAdaptor.cpp @@ -17,7 +17,7 @@ namespace raco::ramses_adaptor { -raco::ramses_adaptor::AnchorPointAdaptor::AnchorPointAdaptor(SceneAdaptor* sceneAdaptor, raco::user_types::SAnchorPoint anchorPoint) +ramses_adaptor::AnchorPointAdaptor::AnchorPointAdaptor(SceneAdaptor* sceneAdaptor, user_types::SAnchorPoint anchorPoint) : UserTypeObjectAdaptor{sceneAdaptor, anchorPoint}, subscriptions_{ sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject_, &user_types::AnchorPoint::objectName_}, [this]() { tagDirty(); }), @@ -26,11 +26,11 @@ raco::ramses_adaptor::AnchorPointAdaptor::AnchorPointAdaptor(SceneAdaptor* scene dirtySubscription_{sceneAdaptor->dispatcher()->registerOnPreviewDirty(editorObject_, [this]() { tagDirty(); })} { } -void AnchorPointAdaptor::getLogicNodes(std::vector& logicNodes) const { +void AnchorPointAdaptor::getLogicNodes(std::vector& logicNodes) const { logicNodes.emplace_back(anchorPoint_.get()); } -const rlogic::Property* AnchorPointAdaptor::getProperty(const std::vector& propertyNamesVector) { +ramses::Property* AnchorPointAdaptor::getProperty(const std::vector& propertyNamesVector) { if (anchorPoint_ && propertyNamesVector.size() >= 2) { return anchorPoint_->getOutputs()->getChild(propertyNamesVector[1]); } @@ -49,9 +49,9 @@ bool AnchorPointAdaptor::sync(core::Errors* errors) { ObjectAdaptor::sync(errors); anchorPoint_.reset(); - raco::ramses_base::RamsesNodeBinding nodeBinding = lookupNodeBinding(sceneAdaptor_, *editorObject_->node_); + ramses_base::RamsesNodeBinding nodeBinding = lookupNodeBinding(sceneAdaptor_, *editorObject_->node_); - raco::ramses_base::RamsesCameraBinding cameraBinding = nullptr; + ramses_base::RamsesCameraBinding cameraBinding = nullptr; auto camera = *editorObject_->camera_; if (auto cameraAdaptor = sceneAdaptor_->lookup(camera)) { cameraBinding = cameraAdaptor->cameraBinding(); @@ -60,7 +60,7 @@ bool AnchorPointAdaptor::sync(core::Errors* errors) { } if (nodeBinding && cameraBinding) { - anchorPoint_ = raco::ramses_base::ramsesAnchorPoint(&sceneAdaptor_->logicEngine(), nodeBinding, cameraBinding, editorObject_->objectName(), editorObject_->objectIDAsRamsesLogicID()); + anchorPoint_ = ramses_base::ramsesAnchorPoint(&sceneAdaptor_->logicEngine(), nodeBinding, cameraBinding, editorObject_->objectName(), editorObject_->objectIDAsRamsesLogicID()); } tagDirty(false); @@ -79,7 +79,7 @@ std::vector AnchorPointAdaptor::getExportInformation() const return {}; } - return {ExportInformation{"AnchorPoint", anchorPoint_->getName().data()}}; + return {ExportInformation{"AnchorPoint", anchorPoint_->getName()}}; } } // namespace raco::ramses_adaptor \ No newline at end of file diff --git a/components/libRamsesBase/src/ramses_adaptor/AnimationAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/AnimationAdaptor.cpp index 43eefc99..8d0bedbe 100644 --- a/components/libRamsesBase/src/ramses_adaptor/AnimationAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/AnimationAdaptor.cpp @@ -15,7 +15,7 @@ namespace raco::ramses_adaptor { using namespace raco::ramses_base; -AnimationAdaptor::AnimationAdaptor(SceneAdaptor* sceneAdaptor, raco::user_types::SAnimation animation) +AnimationAdaptor::AnimationAdaptor(SceneAdaptor* sceneAdaptor, user_types::SAnimation animation) : UserTypeObjectAdaptor{sceneAdaptor, animation}, animNode_{}, progressSubscription_{ @@ -26,13 +26,13 @@ AnimationAdaptor::AnimationAdaptor(SceneAdaptor* sceneAdaptor, raco::user_types: sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject_, &user_types::Animation::objectName_}, [this]() { tagDirty(); })} { } -void AnimationAdaptor::getLogicNodes(std::vector& logicNodes) const { +void AnimationAdaptor::getLogicNodes(std::vector& logicNodes) const { if (animNode_) { logicNodes.emplace_back(animNode_->get()); } } -const rlogic::Property* AnimationAdaptor::getProperty(const std::vector& propertyNamesVector) { +ramses::Property* AnimationAdaptor::getProperty(const std::vector& propertyNamesVector) { if (animNode_) { if (propertyNamesVector.size() > 1 && propertyNamesVector[0] == "outputs") { return ILogicPropertyProvider::getPropertyRecursive((*animNode_)->getOutputs(), propertyNamesVector, 1); @@ -54,12 +54,11 @@ void AnimationAdaptor::onRuntimeError(core::Errors& errors, std::string const& m bool AnimationAdaptor::sync(core::Errors* errors) { errors->removeError({editorObject_->shared_from_this()}); - std::vector newChannelHandles; + std::vector newChannelHandles; - const auto& channelTable = editorObject_->animationChannels_.asTable(); - for (auto channelIndex = 0; channelIndex < channelTable.size(); ++channelIndex) { - auto channel = channelTable.get(channelIndex)->asRef(); - auto channelAdaptor = sceneAdaptor_->lookup(channel); + for (auto channelIndex = 0; channelIndex < editorObject_->animationChannels_->size(); ++channelIndex) { + auto channel = **editorObject_->animationChannels_->get(channelIndex); + auto channelAdaptor = sceneAdaptor_->lookup(channel); if (channelAdaptor && channelAdaptor->handle()) { newChannelHandles.emplace_back(channelAdaptor->handle()); } else { @@ -68,7 +67,7 @@ bool AnimationAdaptor::sync(core::Errors* errors) { } if (!animNode_ || animNode_->channels() != newChannelHandles || (**animNode_).getName() != editorObject_->objectName()) { - rlogic::AnimationNodeConfig config; + ramses::AnimationNodeConfig config; for (auto i = 0; i < newChannelHandles.size(); i++) { auto& newHandle = newChannelHandles[i]; if (newHandle) { @@ -81,18 +80,18 @@ bool AnimationAdaptor::sync(core::Errors* errors) { } } if (!config.getChannels().empty()) { - animNode_ = raco::ramses_base::ramsesAnimationNode(&sceneAdaptor_->logicEngine(), config, newChannelHandles, editorObject_->objectName(), editorObject_->objectIDAsRamsesLogicID()); + animNode_ = ramses_base::ramsesAnimationNode(&sceneAdaptor_->logicEngine(), config, newChannelHandles, editorObject_->objectName(), editorObject_->objectIDAsRamsesLogicID()); if (animNode_) { updateGlobalAnimationStats(errors); errors->removeError({editorObject()}); } else { - errors->addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::ERROR, {editorObject()}, - fmt::format("RamsesLogic Error: {}", sceneAdaptor_->logicEngine().getErrors().at(0).message)); + errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, {editorObject()}, + fmt::format("RamsesLogic Error: {}", sceneAdaptor_->scene()->getRamsesClient().getRamsesFramework().getLastError().value().message)); } } else { animNode_.reset(); - errors->addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::ERROR, {editorObject()}, + errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, {editorObject()}, fmt::format("Can't create RamsesLogic AnimationNode: Animation '{}' contains no valid AnimationChannels.", editorObject()->objectName())); } } @@ -120,7 +119,7 @@ void AnimationAdaptor::updateGlobalAnimationStats(core::Errors* errors) { if (animNode_) { auto duration = (*animNode_)->getOutputs()->getChild("duration")->get().value(); auto infoText = fmt::format("Total Duration: {:.2f} s", duration); - errors->addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::INFORMATION, + errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::INFORMATION, {editorObject_->shared_from_this(), &user_types::Animation::outputs_}, infoText); } } @@ -130,7 +129,7 @@ std::vector AnimationAdaptor::getExportInformation() const { return {}; } - return {ExportInformation{ramses::ERamsesObjectType_Animation, animNode_->get()->getName().data()}}; + return {ExportInformation{"Animation", animNode_->get()->getName()}}; } }; // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/src/ramses_adaptor/AnimationChannelAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/AnimationChannelAdaptor.cpp index 8b0f19c2..ea1969fa 100644 --- a/components/libRamsesBase/src/ramses_adaptor/AnimationChannelAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/AnimationChannelAdaptor.cpp @@ -12,8 +12,9 @@ #include "ramses_adaptor/MeshAdaptor.h" namespace { + template -void createRamsesDataArrays(const raco::ramses_base::RamsesAnimationChannelHandle& handle, rlogic::LogicEngine* engine, const DataType& tangentInData, const DataType& outputData, const DataType& tangentOutData, const std::pair& objectID) { +void createRamsesDataArrays(const raco::ramses_base::RamsesAnimationChannelHandle& handle, ramses::LogicEngine* engine, const DataType& tangentInData, const DataType& outputData, const DataType& tangentOutData, const std::pair& objectID) { auto outputName = handle->name + ".keyframes"; auto tangentInName = handle->name + ".tangentIn"; auto tangentOutName = handle->name + ".tangentOut"; @@ -33,7 +34,7 @@ namespace raco::ramses_adaptor { using namespace raco::ramses_base; -AnimationChannelAdaptor::AnimationChannelAdaptor(SceneAdaptor* sceneAdaptor, raco::user_types::SAnimationChannel channel) +AnimationChannelAdaptor::AnimationChannelAdaptor(SceneAdaptor* sceneAdaptor, user_types::SAnimationChannel channel) : UserTypeObjectAdaptor{sceneAdaptor, channel}, subscriptions_{ sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject_, &user_types::AnimationChannel::objectName_}, [this]() { tagDirty(); }), @@ -43,6 +44,24 @@ AnimationChannelAdaptor::AnimationChannelAdaptor(SceneAdaptor* sceneAdaptor, rac previewDirtySubscription_{sceneAdaptor->dispatcher()->registerOnPreviewDirty(editorObject_, [this]() { tagDirty(); })} { } +std::vector convert_vec3(const std::vector>& data) { + std::vector result; + for (size_t index = 0; index < data.size(); index++) { + const auto& v = data[index]; + result.emplace_back(glm::vec3(v[0], v[1], v[2])); + } + return result; +} + +std::vector convert_vec4(const std::vector>& data) { + std::vector result; + for (size_t index = 0; index < data.size(); index++) { + const auto& v = data[index]; + result.emplace_back(glm::vec4(v[0], v[1], v[2], v[3])); + } + return result; +} + bool AnimationChannelAdaptor::sync(core::Errors* errors) { ObjectAdaptor::sync(errors); handle_.reset(); @@ -50,43 +69,32 @@ bool AnimationChannelAdaptor::sync(core::Errors* errors) { if (auto animSampler = editorObject_->currentSamplerData_) { auto objectID = editorObject_->objectIDAsRamsesLogicID(); - handle_.reset(new raco::ramses_base::RamsesAnimationChannelData); + handle_.reset(new ramses_base::RamsesAnimationChannelData); handle_->name = editorObject_->objectName(); - handle_->keyframeTimes = ramsesDataArray(animSampler->input, &sceneAdaptor_->logicEngine(), handle_->name + ".timestamps", objectID); - - std::map interpolationTypeMap = { - {raco::core::MeshAnimationInterpolation::Linear, rlogic::EInterpolationType::Linear}, - {raco::core::MeshAnimationInterpolation::CubicSpline, rlogic::EInterpolationType::Cubic}, - {raco::core::MeshAnimationInterpolation::Step, rlogic::EInterpolationType::Step}, - {raco::core::MeshAnimationInterpolation::Linear_Quaternion, rlogic::EInterpolationType::Linear_Quaternions}, - {raco::core::MeshAnimationInterpolation::CubicSpline_Quaternion, rlogic::EInterpolationType::Cubic_Quaternions} + handle_->keyframeTimes = ramsesDataArray(animSampler->timeStamps, &sceneAdaptor_->logicEngine(), handle_->name + ".timestamps", objectID); + + std::map interpolationTypeMap = { + {core::MeshAnimationInterpolation::Linear, ramses::EInterpolationType::Linear}, + {core::MeshAnimationInterpolation::CubicSpline, ramses::EInterpolationType::Cubic}, + {core::MeshAnimationInterpolation::Step, ramses::EInterpolationType::Step}, + {core::MeshAnimationInterpolation::Linear_Quaternion, ramses::EInterpolationType::Linear_Quaternions}, + {core::MeshAnimationInterpolation::CubicSpline_Quaternion, ramses::EInterpolationType::Cubic_Quaternions} }; handle_->interpolationType = interpolationTypeMap.at(animSampler->interpolation); - switch (animSampler->getOutputComponentType()) { - case raco::core::EnginePrimitive::Array: { + switch (animSampler->componentType) { + case core::EnginePrimitive::Array: { // Morph target weights - // We can create DataArrays with std::vector only with feature level >= 4, so we - // switch this off at smaller feature levels. - // Strictly this breaks backwards compatibility but morphing was not supported anyway so this should be OK. - - if (sceneAdaptor_->featureLevel() >= 4) { - const auto& [tangentInData, outputData, tangentOutData] = animSampler->getOutputData>(); - createRamsesDataArrays(handle_, &sceneAdaptor_->logicEngine(), tangentInData, outputData, tangentOutData, objectID); - } else { - handle_.reset(); - } + createRamsesDataArrays(handle_, &sceneAdaptor_->logicEngine(), animSampler->tangentsIn, animSampler->keyFrames, animSampler->tangentsOut, objectID); break; } - case raco::core::EnginePrimitive::Vec3f: { - const auto& [tangentInData, outputData, tangentOutData] = animSampler->getOutputData(); - createRamsesDataArrays(handle_, &sceneAdaptor_->logicEngine(), tangentInData, outputData, tangentOutData, objectID); + case core::EnginePrimitive::Vec3f: { + createRamsesDataArrays(handle_, &sceneAdaptor_->logicEngine(), convert_vec3(animSampler->tangentsIn), convert_vec3(animSampler->keyFrames), convert_vec3(animSampler->tangentsOut), objectID); break; } - case raco::core::EnginePrimitive::Vec4f: { - const auto& [tangentInData, outputData, tangentOutData] = animSampler->getOutputData(); - createRamsesDataArrays(handle_, &sceneAdaptor_->logicEngine(), tangentInData, outputData, tangentOutData, objectID); + case core::EnginePrimitive::Vec4f: { + createRamsesDataArrays(handle_, &sceneAdaptor_->logicEngine(), convert_vec4(animSampler->tangentsIn), convert_vec4(animSampler->keyFrames), convert_vec4(animSampler->tangentsOut), objectID); break; } default: @@ -98,7 +106,7 @@ bool AnimationChannelAdaptor::sync(core::Errors* errors) { return true; } -raco::ramses_base::RamsesAnimationChannelHandle AnimationChannelAdaptor::handle() const { +ramses_base::RamsesAnimationChannelHandle AnimationChannelAdaptor::handle() const { return handle_; } @@ -110,19 +118,19 @@ std::vector AnimationChannelAdaptor::getExportInformation() c auto result = std::vector(); if (handle_->keyframeTimes != nullptr) { - result.emplace_back("DataArray", handle_->keyframeTimes->getName().data()); + result.emplace_back("DataArray", handle_->keyframeTimes->getName()); } if (handle_->animOutput != nullptr) { - result.emplace_back("DataArray", handle_->animOutput->getName().data()); + result.emplace_back("DataArray", handle_->animOutput->getName()); } if (handle_->tangentIn != nullptr) { - result.emplace_back("DataArray", handle_->tangentIn->getName().data()); + result.emplace_back("DataArray", handle_->tangentIn->getName()); } if (handle_->tangentOut != nullptr) { - result.emplace_back("DataArray", handle_->tangentOut->getName().data()); + result.emplace_back("DataArray", handle_->tangentOut->getName()); } return result; diff --git a/components/libRamsesBase/src/ramses_adaptor/BaseCameraAdaptorHelpers.cpp b/components/libRamsesBase/src/ramses_adaptor/BaseCameraAdaptorHelpers.cpp index 07ec9375..172ddee6 100644 --- a/components/libRamsesBase/src/ramses_adaptor/BaseCameraAdaptorHelpers.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/BaseCameraAdaptorHelpers.cpp @@ -14,16 +14,16 @@ #include "user_types/BaseCamera.h" -#include +#include #include "ramses_base/RamsesHandles.h" namespace raco::ramses_adaptor { -void BaseCameraAdaptorHelpers::sync(std::shared_ptr editorObject, ramses::Camera* ramsesCamera, rlogic::RamsesCameraBinding* cameraBinding, core::Errors* errors) { +void BaseCameraAdaptorHelpers::sync(std::shared_ptr editorObject, ramses::Camera* ramsesCamera, ramses::CameraBinding* cameraBinding, core::Errors* errors) { bool allValid = true; - int clippedWidth = raco::ramses_base::clipAndCheckIntProperty({editorObject, {"viewport", "width"}}, errors, &allValid); - int clippedHeight = raco::ramses_base::clipAndCheckIntProperty({editorObject, {"viewport", "height"}}, errors, &allValid); + int clippedWidth = ramses_base::clipAndCheckIntProperty({editorObject, {"viewport", "width"}}, errors, &allValid); + int clippedHeight = ramses_base::clipAndCheckIntProperty({editorObject, {"viewport", "height"}}, errors, &allValid); if (allValid) { ramsesCamera->setViewport(*editorObject->viewport_->offsetX_, *editorObject->viewport_->offsetY_, clippedWidth, clippedHeight); @@ -38,7 +38,7 @@ void BaseCameraAdaptorHelpers::sync(std::shared_ptr edit } } -const rlogic::Property* BaseCameraAdaptorHelpers::getProperty(rlogic::RamsesCameraBinding* cameraBinding, const std::vector& propertyNamesVector) { +ramses::Property* BaseCameraAdaptorHelpers::getProperty(ramses::CameraBinding* cameraBinding, const std::vector& propertyNamesVector) { if (cameraBinding && propertyNamesVector.size() >= 1 && propertyNamesVector[0] == "viewport") { return ILogicPropertyProvider::getPropertyRecursive(cameraBinding->getInputs(), propertyNamesVector); } diff --git a/components/libRamsesBase/src/ramses_adaptor/BlitPassAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/BlitPassAdaptor.cpp index 3deef6fb..87078c04 100644 --- a/components/libRamsesBase/src/ramses_adaptor/BlitPassAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/BlitPassAdaptor.cpp @@ -80,22 +80,22 @@ bool BlitPassAdaptor::sync(core::Errors* errors) { if (recreate_) { errors->removeError({editorObject()->shared_from_this()}); blitPass_.reset(); - raco::ramses_base::RamsesRenderBuffer startBuffer; - raco::ramses_base::RamsesRenderBuffer endBuffer; - if (auto srcBuffer = sceneAdaptor_->lookup(*editorObject_->sourceRenderBuffer_)) { + ramses_base::RamsesRenderBuffer startBuffer; + ramses_base::RamsesRenderBuffer endBuffer; + if (auto srcBuffer = sceneAdaptor_->lookup(*editorObject_->sourceRenderBuffer_)) { startBuffer = srcBuffer->buffer(); - } else if (auto srcBufferMS = sceneAdaptor_->lookup(*editorObject_->sourceRenderBufferMS_)) { + } else if (auto srcBufferMS = sceneAdaptor_->lookup(*editorObject_->sourceRenderBufferMS_)) { startBuffer = srcBufferMS->buffer(); } - if (auto destBuffer = sceneAdaptor_->lookup(*editorObject_->targetRenderBuffer_)) { + if (auto destBuffer = sceneAdaptor_->lookup(*editorObject_->targetRenderBuffer_)) { endBuffer = destBuffer->buffer(); - } else if (auto destBufferMS = sceneAdaptor_->lookup(*editorObject_->targetRenderBufferMS_)) { + } else if (auto destBufferMS = sceneAdaptor_->lookup(*editorObject_->targetRenderBufferMS_)) { endBuffer = destBufferMS->buffer(); } if (startBuffer && endBuffer) { - blitPass_ = raco::ramses_base::ramsesBlitPass(sceneAdaptor_->scene(), startBuffer, endBuffer, editorObject_->objectName().c_str()); + blitPass_ = ramses_base::ramsesBlitPass(sceneAdaptor_->scene(), startBuffer, endBuffer, editorObject_->objectName().c_str(), editorObject_->objectIDAsRamsesLogicID()); if (!blitPass_) { errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, {editorObject()->shared_from_this()}, @@ -112,19 +112,17 @@ bool BlitPassAdaptor::sync(core::Errors* errors) { blitPass_->setRenderOrder(*editorObject()->renderOrder_); bool allValid = true; - uint32_t clippedSourceX = raco::ramses_base::clipAndCheckIntProperty({editorObject_, &raco::user_types::BlitPass::sourceX_}, errors, &allValid); - uint32_t clippedSourceY = raco::ramses_base::clipAndCheckIntProperty({editorObject_, &raco::user_types::BlitPass::sourceY_}, errors, &allValid); - uint32_t clippedDestinationX = raco::ramses_base::clipAndCheckIntProperty({editorObject_, &raco::user_types::BlitPass::destinationX_}, errors, &allValid); - uint32_t clippedDestinationY = raco::ramses_base::clipAndCheckIntProperty({editorObject_, &raco::user_types::BlitPass::destinationY_}, errors, &allValid); - uint32_t clippedWidth = raco::ramses_base::clipAndCheckIntProperty({editorObject_, &raco::user_types::BlitPass::width_}, errors, &allValid); - uint32_t clippedHeight = raco::ramses_base::clipAndCheckIntProperty({editorObject_, &raco::user_types::BlitPass::height_}, errors, &allValid); + uint32_t clippedSourceX = ramses_base::clipAndCheckIntProperty({editorObject_, &user_types::BlitPass::sourceX_}, errors, &allValid); + uint32_t clippedSourceY = ramses_base::clipAndCheckIntProperty({editorObject_, &user_types::BlitPass::sourceY_}, errors, &allValid); + uint32_t clippedDestinationX = ramses_base::clipAndCheckIntProperty({editorObject_, &user_types::BlitPass::destinationX_}, errors, &allValid); + uint32_t clippedDestinationY = ramses_base::clipAndCheckIntProperty({editorObject_, &user_types::BlitPass::destinationY_}, errors, &allValid); + uint32_t clippedWidth = ramses_base::clipAndCheckIntProperty({editorObject_, &user_types::BlitPass::width_}, errors, &allValid); + uint32_t clippedHeight = ramses_base::clipAndCheckIntProperty({editorObject_, &user_types::BlitPass::height_}, errors, &allValid); if (allValid) { - auto updateStatus = blitPass_->setBlittingRegion(clippedSourceX, clippedSourceY, clippedDestinationX, clippedDestinationY, clippedWidth, clippedHeight); - - if (updateStatus != ramses::StatusOK) { + if (!blitPass_->setBlittingRegion(clippedSourceX, clippedSourceY, clippedDestinationX, clippedDestinationY, clippedWidth, clippedHeight)) { errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, {editorObject()->shared_from_this()}, - blitPass_->getStatusMessage(updateStatus)); + sceneAdaptor_->scene()->getRamsesClient().getRamsesFramework().getLastError().value().message); } } } diff --git a/components/libRamsesBase/src/ramses_adaptor/CameraController.cpp b/components/libRamsesBase/src/ramses_adaptor/CameraController.cpp new file mode 100644 index 00000000..4d1d9a77 --- /dev/null +++ b/components/libRamsesBase/src/ramses_adaptor/CameraController.cpp @@ -0,0 +1,151 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "ramses_adaptor/CameraController.h" + +#include + +#include + +namespace raco::ramses_adaptor { + +using namespace raco::ramses_base; + +CameraController::CameraController(ramses_base::RamsesPerspectiveCamera camera) + : camera_(camera), + angle_(35.0), + aspectRatio_(1.0) { + reset(); +} + +void CameraController::update(bool distChanged) { + if (distChanged) { + far_ = 10 * cameraDistance(); + near_ = far_ / 100.0; + } + + (*camera_)->setTranslation(position_); + auto rotation = getEulerAngles(); + (*camera_)->setRotation(glm::degrees(rotation), ramses::ERotationType::Euler_XYZ); + (*camera_)->setFrustum(angle_, aspectRatio_, near_, far_); + + if (distChanged) { + Q_EMIT distanceChanged(cameraDistance()); + } +} + +void CameraController::reset() { + up_ = {0.0, 1.0, 0.0}; + lookAt_ = {0.0, 0.0, 0.0}; + position_ = {2.0, 2.0, 10.0}; + update(true); +} + +void CameraController::focus(const BoundingBox& boundingBox) { + auto front = glm::normalize(lookAt_ - position_); + float bboxSize = boundingBox.size(); + float newDist = bboxSize / tan(glm::radians(angle_) / 2.0); + + lookAt_ = boundingBox.center(); + position_ = lookAt_ - newDist * front; + + update(true); +} + +void CameraController::rescaleCameraToViewport(uint32_t width, uint32_t height) { + (*camera_)->setViewport(0, 0, width, height); + aspectRatio_ = static_cast(width) / static_cast(height); + (*camera_)->setFrustum(angle_, aspectRatio_, near_, far_); +} + +glm::vec3 CameraController::getEulerAngles() { + auto front = glm::normalize(lookAt_ - position_); + auto right = glm::normalize(glm::cross(front, up_)); + + auto yaw = atan2(-right.z, right.x); + auto pitch = glm::pi() / 2.0 - glm::angle(up_, front); + + return {pitch, yaw, 0.0}; +} + +void CameraController::orbitCamera(QPoint deltaMousePos) { + auto rotation = getEulerAngles(); + auto dist = glm::length(lookAt_ - position_); + + auto deltaYaw = -deltaMousePos.x() * rotationSensitivity; + auto deltaPitch = -deltaMousePos.y() * rotationSensitivity; + auto newPitch = glm::clamp(rotation.x + deltaPitch, -glm::radians(pitchLimit), glm::radians(pitchLimit)); + rotation = glm::vec3(newPitch, rotation.y + deltaYaw, 0.0); + + auto newFront = glm::rotateY(glm::rotateX(glm::vec3(0.0, 0.0, -1.0), rotation.x), rotation.y); + position_ = lookAt_ - dist * newFront; + + (*camera_)->setTranslation(position_); + (*camera_)->setRotation(glm::degrees(rotation), ramses::ERotationType::Euler_XYZ); +} + +void CameraController::panCamera(QPoint deltaMousePos) { + auto dist = glm::length(lookAt_ - position_); + auto front = glm::normalize(lookAt_ - position_); + auto right = glm::normalize(glm::cross(front, up_)); + auto top = glm::cross(right, front); + + auto translation = panSensitivity * dist * (-static_cast(deltaMousePos.x()) * right + static_cast(deltaMousePos.y()) * top); + + position_ += translation; + lookAt_ += translation; + + (*camera_)->setTranslation(position_); +} + +void CameraController::zoomCamera(float logFactor) { + auto front = glm::normalize(lookAt_ - position_); + auto dist = glm::length(lookAt_ - position_); + + float newDist = std::min(std::max(dist * exp(logFactor), 1e-3f), 1e8f); + + position_ = lookAt_ - newDist * front; + + update(true); +} + +void CameraController::zoomCameraMove(QPoint deltaMousePos) { + zoomCamera(-zoomMoveSensitivity * deltaMousePos.x()); +} + +void CameraController::zoomCameraWheel(QPoint deltaWheelAngle) { + float delta = deltaWheelAngle.y() != 0 ? deltaWheelAngle.y() : deltaWheelAngle.x(); + zoomCamera(-zoomWheelSensitivity * delta); +} + +float CameraController::cameraDistance() { + return glm::length(lookAt_ - position_); +} + +glm::mat4 CameraController::projectionMatrix() { + glm::mat4 matrix; + bool status = (*camera_)->getProjectionMatrix(matrix); + return matrix; +} + +glm::mat4 CameraController::viewMatrix() { + glm::mat4 matrix; + bool status = (*camera_)->getModelMatrix(matrix); + return glm::inverse(matrix); +} + +glm::mat4 CameraController::modelMatrix() { + glm::mat4 matrix; + bool status = (*camera_)->getModelMatrix(matrix); + return matrix; +} + + +} // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/src/ramses_adaptor/ClearDepthObject.cpp b/components/libRamsesBase/src/ramses_adaptor/ClearDepthObject.cpp new file mode 100644 index 00000000..da835fb3 --- /dev/null +++ b/components/libRamsesBase/src/ramses_adaptor/ClearDepthObject.cpp @@ -0,0 +1,75 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "ramses_adaptor/ClearDepthObject.h" + +#include "ramses_adaptor/utilities.h" + +namespace raco::ramses_adaptor { + +using namespace raco::ramses_base; + +ClearDepthObject::ClearDepthObject(ramses::Scene* scene) + : scene_(scene) { +} + +static const std::string vertexShader = R"( +#version 300 es + +precision highp float; + +void main() { + // use this with no geometry: + // - MeshNode::setIndexCount(3) + // - need to set a GeometryBinding but this can be empty + vec3 vertices[3] = vec3[](vec3(-1, -1, 0), vec3(-1, 3, 0), vec3(3, -1, 0)); + + vec3 p_eye = vertices[gl_VertexID]; + + gl_Position = vec4(p_eye, 1.0); +} +)"; + +static const std::string fragmentShader = R"( +#version 300 es + +precision highp float; + +void main() { + gl_FragDepth = gl_DepthRange.far; +} +)"; + +void ClearDepthObject::setup(ramses_base::RamsesRenderPass renderPass, int renderOrder) { + renderGroup_ = ramsesRenderGroup(scene_, {0, 0}); + renderPass->addRenderGroup(renderGroup_, renderOrder); + + ramses::EffectDescription effectDescription{}; + auto status = effectDescription.setVertexShader(vertexShader.c_str()); + status = effectDescription.setFragmentShader(fragmentShader.c_str()); + effect_ = ramsesEffect(scene_, effectDescription, {}, {0, 0}); + appearance_ = ramsesAppearance(scene_, effect_, {0, 0}); + + (*appearance_)->setDepthWrite(ramses::EDepthWrite::Enabled); + (*appearance_)->setDepthFunction(ramses::EDepthFunc::Always); + (*appearance_)->setCullingMode(ramses::ECullMode::Disabled); + (*appearance_)->setColorWriteMask(false, false, false, false); + + geometry_ = ramsesGeometry(scene_, effect_, {0, 0}); + + meshNode_ = ramsesMeshNode(scene_, {0, 0}); + meshNode_->setGeometry(geometry_); + meshNode_->setAppearance(appearance_); + meshNode_->get()->setIndexCount(3); + + renderGroup_->addMeshNode(meshNode_, 0); +} + +} // namespace raco::ramses_adaptor \ No newline at end of file diff --git a/components/libRamsesBase/src/ramses_adaptor/CubeMapAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/CubeMapAdaptor.cpp index 0972b4d6..70dbce46 100644 --- a/components/libRamsesBase/src/ramses_adaptor/CubeMapAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/CubeMapAdaptor.cpp @@ -18,7 +18,7 @@ #include "user_types/Enumerations.h" #include "utils/FileUtils.h" -#include +#include #include #include @@ -55,14 +55,14 @@ CubeMapAdaptor::CubeMapAdaptor(SceneAdaptor* sceneAdaptor, std::shared_ptrmipmapLevel_ < 1 || *editorObject()->mipmapLevel_ > 4) { return fallbackCube(); } std::vector>> rawMipDatas; std::vector mipDatas; - raco::ramses_base::PngDecodingInfo decodingInfo; + ramses_base::PngDecodingInfo decodingInfo; auto mipMapsOk = true; for (auto level = 1; level <= *editorObject()->mipmapLevel_; ++level) { @@ -78,13 +78,13 @@ raco::ramses_base::RamsesTextureCube CubeMapAdaptor::createTexture(core::Errors* for (auto& mipData : rawMipDatas) { // Order: +X, -X, +Y, -Y, +Z, -Z - mipDatas.emplace_back(ramses::CubeMipLevelData(static_cast(mipData["uriRight"].size()), - mipData["uriRight"].data(), - mipData["uriLeft"].data(), - mipData["uriTop"].data(), - mipData["uriBottom"].data(), - mipData["uriFront"].data(), - mipData["uriBack"].data())); + mipDatas.emplace_back(ramses::CubeMipLevelData{ + {reinterpret_cast(mipData["uriRight"].data()), reinterpret_cast(mipData["uriRight"].data()) + mipData["uriRight"].size()}, + {reinterpret_cast(mipData["uriLeft"].data()), reinterpret_cast(mipData["uriLeft"].data()) + mipData["uriLeft"].size()}, + {reinterpret_cast(mipData["uriTop"].data()), reinterpret_cast(mipData["uriTop"].data()) + mipData["uriTop"].size()}, + {reinterpret_cast(mipData["uriBottom"].data()), reinterpret_cast(mipData["uriBottom"].data()) + mipData["uriBottom"].size()}, + {reinterpret_cast(mipData["uriFront"].data()), reinterpret_cast(mipData["uriFront"].data()) + mipData["uriFront"].size()}, + {reinterpret_cast(mipData["uriBack"].data()), reinterpret_cast(mipData["uriBack"].data()) + mipData["uriBack"].size()}}); } auto format = static_cast((*editorObject()->textureFormat_)); @@ -101,10 +101,10 @@ raco::ramses_base::RamsesTextureCube CubeMapAdaptor::createTexture(core::Errors* errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::INFORMATION, {editorObject()->shared_from_this()}, infoText); - return raco::ramses_base::ramsesTextureCube(sceneAdaptor_->scene(), ramsesFormat, decodingInfo.width, *editorObject()->mipmapLevel_, mipDatas.data(), *editorObject()->generateMipmaps_, {}, ramses::ResourceCacheFlag_DoNotCache); + return ramses_base::ramsesTextureCube(sceneAdaptor_->scene(), ramsesFormat, decodingInfo.width, mipDatas, *editorObject()->generateMipmaps_, {}, {}, editorObject()->objectIDAsRamsesLogicID()); } -raco::ramses_base::RamsesTextureCube CubeMapAdaptor::fallbackCube() { +ramses_base::RamsesTextureCube CubeMapAdaptor::fallbackCube() { std::map> data; data["uriRight"] = TextureSamplerAdaptor::getFallbackTextureData(false); @@ -113,29 +113,30 @@ raco::ramses_base::RamsesTextureCube CubeMapAdaptor::fallbackCube() { data["uriBottom"] = TextureSamplerAdaptor::getFallbackTextureData(false); data["uriFront"] = TextureSamplerAdaptor::getFallbackTextureData(false); data["uriBack"] = TextureSamplerAdaptor::getFallbackTextureData(false); - - ramses::CubeMipLevelData mipData = ramses::CubeMipLevelData((uint32_t)data["uriRight"].size(), - data["uriRight"].data(), - data["uriLeft"].data(), - data["uriTop"].data(), - data["uriBottom"].data(), - data["uriFront"].data(), - data["uriBack"].data()); - - return raco::ramses_base::ramsesTextureCube(sceneAdaptor_->scene(), ramses::ETextureFormat::RGBA8, TextureSamplerAdaptor::FALLBACK_TEXTURE_SIZE_PX, 1u, &mipData, *editorObject()->generateMipmaps_, {}, ramses::ResourceCacheFlag_DoNotCache); + + std::vector mipDatas; + mipDatas.emplace_back(ramses::CubeMipLevelData{ + {reinterpret_cast(data["uriRight"].data()), reinterpret_cast(data["uriRight"].data()) + data["uriRight"].size()}, + {reinterpret_cast(data["uriLeft"].data()), reinterpret_cast(data["uriLeft"].data()) + data["uriLeft"].size()}, + {reinterpret_cast(data["uriTop"].data()), reinterpret_cast(data["uriTop"].data()) + data["uriTop"].size()}, + {reinterpret_cast(data["uriBottom"].data()), reinterpret_cast(data["uriBottom"].data()) + data["uriBottom"].size()}, + {reinterpret_cast(data["uriFront"].data()), reinterpret_cast(data["uriFront"].data()) + data["uriFront"].size()}, + {reinterpret_cast(data["uriBack"].data()), reinterpret_cast(data["uriBack"].data()) + data["uriBack"].size()}}); + + return ramses_base::ramsesTextureCube(sceneAdaptor_->scene(), ramses::ETextureFormat::RGBA8, TextureSamplerAdaptor::FALLBACK_TEXTURE_SIZE_PX, mipDatas, *editorObject()->generateMipmaps_, {}, {}, editorObject()->objectIDAsRamsesLogicID()); } std::string CubeMapAdaptor::createDefaultTextureDataName() { return this->editorObject()->objectName() + "_TextureCube"; } -std::map> CubeMapAdaptor::generateMipmapData(core::Errors* errors, int level, raco::ramses_base::PngDecodingInfo& decodingInfo) { +std::map> CubeMapAdaptor::generateMipmapData(core::Errors* errors, int level, ramses_base::PngDecodingInfo& decodingInfo) { std::map> data; auto mipmapOk = true; for (const std::string &propName : {"uriRight", "uriLeft", "uriTop", "uriBottom", "uriFront", "uriBack", }) { auto uriPropName = (level > 1) ? fmt::format("level{}{}", level, propName) : propName; - data[propName] = raco::ramses_base::decodeMipMapData(errors, sceneAdaptor_->project(), editorObject(), uriPropName, level, decodingInfo); + data[propName] = ramses_base::decodeMipMapData(errors, sceneAdaptor_->project(), editorObject(), uriPropName, level, decodingInfo); if (data[propName].empty()) { mipmapOk = false; @@ -151,7 +152,7 @@ std::map> CubeMapAdaptor::generateMipmap bool CubeMapAdaptor::sync(core::Errors* errors) { errors->removeError({editorObject()->shared_from_this()}); - errors->removeError({editorObject()->shared_from_this(), &raco::user_types::CubeMap::textureFormat_}); + errors->removeError({editorObject()->shared_from_this(), &user_types::CubeMap::textureFormat_}); textureData_.reset(); @@ -172,13 +173,15 @@ bool CubeMapAdaptor::sync(core::Errors* errors) { auto magSamplMethod = static_cast(*editorObject()->magSamplingMethod_); auto ramsesMagSamplMethod = ramses_base::enumerationTranslationTextureSamplingMethod.at(magSamplMethod); - auto textureSampler = raco::ramses_base::ramsesTextureSampler(sceneAdaptor_->scene(), + auto textureSampler = ramses_base::ramsesTextureSampler(sceneAdaptor_->scene(), ramsesWrapUMode, ramsesWrapVMode, ramsesMinSamplMethod, ramsesMagSamplMethod, textureData_, - (*editorObject()->anisotropy_ >= 1 ? *editorObject()->anisotropy_ : 1)); + (*editorObject()->anisotropy_ >= 1 ? *editorObject()->anisotropy_ : 1), + {}, + editorObject()->objectIDAsRamsesLogicID()); reset(std::move(textureSampler)); } else { reset(nullptr); diff --git a/components/libRamsesBase/src/ramses_adaptor/DefaultRamsesObjects.cpp b/components/libRamsesBase/src/ramses_adaptor/DefaultRamsesObjects.cpp new file mode 100644 index 00000000..1568cec5 --- /dev/null +++ b/components/libRamsesBase/src/ramses_adaptor/DefaultRamsesObjects.cpp @@ -0,0 +1,874 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "ramses_adaptor/DefaultRamsesObjects.h" + +#include "ramses_adaptor/utilities.h" + +#include "core/MeshCacheInterface.h" +#include "mesh_loader/glTFFileLoader.h" + +namespace raco::ramses_adaptor { + +const char* flatColorVertexShader = + R"( +#version 300 es +precision mediump float; +in vec3 a_Position; +uniform mat4 u_MVPMatrix; +void main() { + gl_Position = u_MVPMatrix * vec4(a_Position.xyz, 1.0); +} +)"; + +const char* flatColorFragmentShader = + R"( +#version 300 es +precision mediump float; +out vec4 FragColor; +uniform vec3 u_color; +uniform float u_alpha; +void main() { + FragColor = vec4(u_color, u_alpha); +} +)"; + +static constexpr const char* phongVertexShader = + R"( +#version 300 es +precision highp float; + +in vec3 a_Position; +in vec3 a_Normal; + +uniform mat4 u_MVMatrix; +uniform mat4 u_PMatrix; +uniform mat4 u_NMatrix; + +out vec3 v_NormalWorldSpace; +out vec3 v_VertexWorldSpace; + +void main() +{ + vec4 vertWS = u_MVMatrix * vec4(a_Position, 1.0); + + v_NormalWorldSpace = vec3(u_NMatrix * vec4(a_Normal, 0.0)); + v_VertexWorldSpace = vertWS.xyz / vertWS.w; + gl_Position = u_PMatrix * vertWS; +} +)"; + +static constexpr const char* phongFragmentShader = + R"( +#version 300 es +precision highp float; + +in vec3 v_NormalWorldSpace; +in vec3 v_VertexWorldSpace; + +// Phong properties +uniform vec3 u_lightColor; +uniform vec3 u_lightDirection; +uniform vec3 u_ambientColor; +uniform vec3 u_diffuseColor; +uniform vec3 u_specularColor; +uniform float u_shininess; +uniform float u_alpha; + +vec3 phongBRDF(vec3 lightDir, vec3 viewDir, vec3 normal, vec3 diffuse, vec3 specular, float shininess) { + vec3 color = diffuse; + vec3 reflectDir = reflect(-lightDir, normal); + float specDot = max(dot(reflectDir, viewDir), 0.0); + color += pow(specDot, shininess) * specular; + return color; +} + +out vec4 FragColor; + +void main() +{ + vec3 lightDir = normalize(-u_lightDirection); + vec3 viewDir = normalize(-v_VertexWorldSpace); + vec3 n = normalize(v_NormalWorldSpace); + + // We pretend that both sides are the front side by flipping the normal if looking from the back: + if (dot(viewDir, n) < 0.0) { + n = -n; + } + + vec3 luminance = u_ambientColor; + float illuminance = dot(lightDir, n); + if(illuminance > 0.0) + { + vec3 brdf = phongBRDF(lightDir, viewDir, n, u_diffuseColor, u_specularColor, u_shininess); + luminance += brdf * illuminance * u_lightColor; + } + + FragColor = vec4(luminance, u_alpha); +} +)"; + +static const glm::vec3 defaultColor(0.2, 0.4, 0.6); +static const glm::vec3 highlightColor(1.0, 0.5, 0.0); + +ramses_base::RamsesAppearance createFlatColorAppearance(ramses::Scene* scene, std::string_view effectName, std::string_view appearanceName, bool highlight, bool transparent) { + ramses::EffectDescription effectDescription{}; + effectDescription.setVertexShader(flatColorVertexShader); + effectDescription.setFragmentShader(flatColorFragmentShader); + effectDescription.setUniformSemantic("u_MVPMatrix", ramses::EEffectUniformSemantic::ModelViewProjectionMatrix); + + auto effect = ramses_base::ramsesEffect(scene, effectDescription, effectName, {0, 0}); + auto appearance = ramses_base::ramsesAppearance(scene, effect, {0, 0}); + (*appearance)->setName(appearanceName); + (*appearance)->setCullingMode(ramses::ECullMode::Disabled); + if (transparent) { + (*appearance)->setDepthWrite(ramses::EDepthWrite::Disabled); + (*appearance)->setBlendingOperations(ramses::EBlendOperation::Add, ramses::EBlendOperation::Add); + (*appearance)->setBlendingFactors(ramses::EBlendFactor::SrcAlpha, ramses::EBlendFactor::OneMinusSrcAlpha, ramses::EBlendFactor::One, ramses::EBlendFactor::One); + } + + ramsesSetUniform(**appearance, "u_color", highlight ? highlightColor : defaultColor); + ramsesSetUniform(**appearance, "u_alpha", transparent ? 0.2f : 1.0f); + + return appearance; +} + +ramses_base::RamsesAppearance createPhongAppearance(ramses::Scene* scene, std::string_view effectName, std::string_view appearanceName, bool highlight, bool transparent) { + ramses::EffectDescription effectDescription{}; + effectDescription.setVertexShader(phongVertexShader); + effectDescription.setFragmentShader(phongFragmentShader); + effectDescription.setUniformSemantic("u_PMatrix", ramses::EEffectUniformSemantic::ProjectionMatrix); + effectDescription.setUniformSemantic("u_MVMatrix", ramses::EEffectUniformSemantic::ModelViewMatrix); + effectDescription.setUniformSemantic("u_NMatrix", ramses::EEffectUniformSemantic::NormalMatrix); + + auto effect = ramses_base::ramsesEffect(scene, effectDescription, effectName, {0, 0}); + auto appearance = ramses_base::ramsesAppearance(scene, effect, {0, 0}); + (*appearance)->setName(appearanceName); + (*appearance)->setCullingMode(ramses::ECullMode::Disabled); + if (transparent) { + (*appearance)->setDepthWrite(ramses::EDepthWrite::Disabled); + (*appearance)->setBlendingOperations(ramses::EBlendOperation::Add, ramses::EBlendOperation::Add); + (*appearance)->setBlendingFactors(ramses::EBlendFactor::SrcAlpha, ramses::EBlendFactor::OneMinusSrcAlpha, ramses::EBlendFactor::One, ramses::EBlendFactor::One); + } + + ramsesSetUniform(**appearance, "u_lightColor", glm::vec3(1.0, 1.0, 1.0)); + ramsesSetUniform(**appearance, "u_lightDirection", glm::vec3(1.0, -1.0, -2.0)); + ramsesSetUniform(**appearance, "u_ambientColor", glm::vec3(0.2, 0.2, 0.2)); + ramsesSetUniform(**appearance, "u_diffuseColor", highlight ? highlightColor : defaultColor); + ramsesSetUniform(**appearance, "u_specularColor", glm::vec3(1.0, 1.0, 1.0)); + ramsesSetUniform(**appearance, "u_shininess", 10.0f); + ramsesSetUniform(**appearance, "u_alpha", transparent ? 0.2f : 1.0f); + + return appearance; +} + +ramses_base::RamsesAppearance createDefaultAppearance(ramses::Scene* scene, bool withNormals, bool highlight, bool transparent) { + if (withNormals) { + return createPhongAppearance(scene, defaultEffectWithNormalsName, defaultAppearanceWithNormalsName, highlight, transparent); + } + return createFlatColorAppearance(scene, defaultEffectName, defaultAppearanceName, highlight, transparent); +} + +const std::vector cubeIndicesData{ + 0, 1, 2, + 2, 3, 0, + 4, 5, 6, + 6, 7, 4, + 8, 9, 10, + 10, 11, 8, + 12, 13, 14, + 14, 15, 12, + 16, 17, 18, + 18, 19, 16, + 20, 21, 22, + 22, 23, 20}; + + ramses_base::RamsesArrayResource createCubeIndexDataBuffer(ramses::Scene* scene) { + return ramses_base::ramsesArrayResource(scene, cubeIndicesData, defaultIndexDataBufferName); + } + +const std::vector cubeVerticesData{ + {1.0, 1.0, 1.0}, + {-1.0, 1.0, 1.0}, + {-1.0, -1.0, 1.0}, + {1.0, -1.0, 1.0}, + {1.0, -1.0, -1.0}, + {1.0, -1.0, 1.0}, + {-1.0, -1.0, 1.0}, + {-1.0, -1.0, -1.0}, + {-1.0, -1.0, -1.0}, + {-1.0, -1.0, 1.0}, + {-1.0, 1.0, 1.0}, + {-1.0, 1.0, -1.0}, + {-1.0, 1.0, -1.0}, + {1.0, 1.0, -1.0}, + {1.0, -1.0, -1.0}, + {-1.0, -1.0, -1.0}, + {1.0, 1.0, -1.0}, + {1.0, 1.0, 1.0}, + {1.0, -1.0, 1.0}, + {1.0, -1.0, -1.0}, + {-1.0, 1.0, -1.0}, + {-1.0, 1.0, 1.0}, + {1.0, 1.0, 1.0}, + {1.0, 1.0, -1.0}}; + + ramses_base::RamsesArrayResource createCubeVertexDataBuffer(ramses::Scene* scene) { + return ramses_base::ramsesArrayResource(scene, cubeVerticesData, defaultVertexDataBufferName); + } + + ramses_base::RamsesArrayResource createCubeNormalDataBuffer(ramses::Scene* scene) { + static std::vector normals{ + {0.0, -0.0, 1.0}, + {0.0, -0.0, 1.0}, + {0.0, -0.0, 1.0}, + {0.0, -0.0, 1.0}, + {0.0, -1.0, 0.0}, + {0.0, -1.0, 0.0}, + {0.0, -1.0, 0.0}, + {0.0, -1.0, 0.0}, + {-1.0, -0.0, 0.0}, + {-1.0, -0.0, 0.0}, + {-1.0, -0.0, 0.0}, + {-1.0, -0.0, 0.0}, + {0.0, 0.0, -1.0}, + {0.0, 0.0, -1.0}, + {0.0, 0.0, -1.0}, + {0.0, 0.0, -1.0}, + {1.0, -0.0, 0.0}, + {1.0, -0.0, 0.0}, + {1.0, -0.0, 0.0}, + {1.0, -0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 1.0, 0.0}}; + return ramses_base::ramsesArrayResource(scene, normals, defaultNormalDataBufferName); + } + +RamsesGizmoMeshBuffers loadGizmoMesh(ramses::Scene* scene, core::MeshCache* meshCache, const std::string& filename) { + auto path(core::PathManager::defaultResourceDirectory() / filename); + mesh_loader::glTFFileLoader loader(path.string()); + + auto mesh = loader.loadMesh({path.string(), 0, true}); + + auto indexData = ramses_base::ramsesArrayResource(scene, mesh->getIndices(), defaultGizmoArrowName); + + auto posIndex = mesh->attribIndex(core::MeshData::ATTRIBUTE_POSITION); + auto posData = ramses_adaptor::arrayResourceFromAttribute(scene, mesh, posIndex, defaultGizmoArrowName); + + const auto& triangleData = mesh->triangleBuffer(); + auto triangleBuffer = ramses_base::ramsesArrayBuffer(scene, ramses::EDataType::Vector3F, triangleData.size(), triangleData.data()); + + return {indexData, posData, triangleBuffer}; +} + +static const std::vector quad_vertex_data = { + {0.0f, 0.0f, 0.f}, + {0.0f, 1.0f, 0.f}, + {1.0f, 0.0f, 0.f}, + {1.0f, 1.0f, 0.f}}; + +ramses_base::RamsesArrayResource createQuadVertexDataBuffer(ramses::Scene* scene) { + return ramses_base::ramsesArrayResource(scene, quad_vertex_data); +} + +ramses_base::RamsesArrayResource createQuadUVDataBuffer(ramses::Scene* scene) { + static const std::vector uv_data = { + {0.0f, 0.0f}, + {0.0f, 1.0f}, + {1.0f, 0.0f}, + {1.0f, 1.0f}}; + return ramses_base::ramsesArrayResource(scene, uv_data); +} + +static const std::vector quad_index_data = { + 0, 2, 1, + 1, 2, 3}; + +ramses_base::RamsesArrayResource createQuadIndexDataBuffer(ramses::Scene* scene) { + return ramses_base::ramsesArrayResource(scene, quad_index_data); +} + +RamsesGizmoMeshBuffers createGizmoQuad(ramses::Scene* scene) { + auto vertexData = createQuadVertexDataBuffer(scene); + auto indexData = createQuadIndexDataBuffer(scene); + + auto triangleData = core::MeshData::buildTriangleBuffer(quad_vertex_data.data(), quad_index_data); + auto triangleBuffer = ramses_base::ramsesArrayBuffer(scene, ramses::EDataType::Vector3F, triangleData.size(), triangleData.data()); + + return {indexData, vertexData, triangleBuffer}; +} + +RamsesGizmoMeshBuffers createGizmoCube(ramses::Scene* scene) { + auto vertexData = createCubeVertexDataBuffer(scene); + auto indexData = createCubeIndexDataBuffer(scene); + + auto triangleData = core::MeshData::buildTriangleBuffer(quad_vertex_data.data(), quad_index_data); + auto triangleBuffer = ramses_base::ramsesArrayBuffer(scene, ramses::EDataType::Vector3F, triangleData.size(), triangleData.data()); + + return {indexData, vertexData, triangleBuffer}; +} + +const std::vector cat_vertex_data = { + {0.000000, -0.687576, -0.782419}, + {0.262228, -0.752914, -0.443125}, + {0.000000, -0.844740, -0.483882}, + {-0.262228, -0.752914, -0.443125}, + {-0.891059, 1.155259, -0.400431}, + {-0.272170, 0.741501, -0.358234}, + {-0.428776, 0.584615, -0.231790}, + {-0.891059, 1.155259, -0.400431}, + {-0.428776, 0.584615, -0.231790}, + {-0.832509, 0.182630, -0.231565}, + {-0.832509, 0.182630, -0.231565}, + {-0.428776, 0.584615, -0.231790}, + {-0.268856, 0.080386, -0.653151}, + {-0.201833, -0.138557, -0.694994}, + {-0.098408, -0.476410, -0.870568}, + {-0.457082, -0.094252, -0.520104}, + {-0.268856, 0.080386, -0.653151}, + {0.000000, 0.606050, -0.418116}, + {0.268856, 0.080386, -0.653151}, + {0.000000, -0.844740, -0.483882}, + {0.000000, -0.844740, -0.055026}, + {-0.264625, -0.752914, -0.002985}, + {-0.262228, -0.752914, -0.443125}, + {-0.832509, 0.182630, -0.231565}, + {-0.262228, -0.752914, -0.443125}, + {-0.733418, -0.312989, -0.156211}, + {0.264625, -0.752914, -0.002985}, + {0.000000, -0.844740, -0.055026}, + {0.000000, -0.844740, -0.483882}, + {0.262228, -0.752914, -0.443125}, + {-0.891059, 1.155259, -0.400431}, + {-0.832509, 0.182630, -0.231565}, + {-0.622732, 0.479086, 0.232224}, + {-0.272170, 0.741501, -0.358234}, + {-0.891059, 1.155259, -0.400431}, + {-0.344476, 0.629688, 0.116868}, + {-0.891059, 1.155259, -0.400431}, + {-0.622732, 0.479086, 0.232224}, + {-0.344476, 0.629688, 0.116868}, + {0.000000, 0.740627, 0.146322}, + {-0.272170, 0.741501, -0.358234}, + {-0.344476, 0.629688, 0.116868}, + {-0.832509, 0.182630, -0.231565}, + {-0.733418, -0.312989, -0.156211}, + {-0.694135, -0.312989, 0.244487}, + {-0.656420, 0.181038, 0.258291}, + {0.000000, 0.740627, 0.146322}, + {-0.344476, 0.629688, 0.116868}, + {-0.349261, 0.536033, 0.476164}, + {0.000000, 0.596703, 0.573425}, + {0.000000, 0.596703, 0.573425}, + {-0.349261, 0.536033, 0.476164}, + {-0.355188, 0.198678, 0.691670}, + {0.000000, 0.217028, 0.796752}, + {-0.733418, -0.312989, -0.156211}, + {-0.262228, -0.752914, -0.443125}, + {-0.264625, -0.752914, -0.002985}, + {-0.694135, -0.312989, 0.244487}, + {0.000000, 0.217028, 0.796752}, + {-0.355188, 0.198678, 0.691670}, + {-0.311519, -0.283536, 0.677898}, + {0.000000, -0.265114, 0.797826}, + {0.000000, -0.696637, 0.511078}, + {-0.253946, -0.641370, 0.469708}, + {-0.264625, -0.752914, -0.002985}, + {0.000000, -0.844740, -0.055026}, + {0.000000, -0.265114, 0.797826}, + {-0.311519, -0.283536, 0.677898}, + {-0.253946, -0.641370, 0.469708}, + {0.000000, -0.696637, 0.511078}, + {-0.253946, -0.641370, 0.469708}, + {-0.311519, -0.283536, 0.677898}, + {-0.694135, -0.312989, 0.244487}, + {-0.694135, -0.312989, 0.244487}, + {-0.311519, -0.283536, 0.677898}, + {-0.355188, 0.198678, 0.691670}, + {-0.656420, 0.181038, 0.258291}, + {-0.622732, 0.479086, 0.232224}, + {-0.355188, 0.198678, 0.691670}, + {-0.349261, 0.536033, 0.476164}, + {-0.622732, 0.479086, 0.232224}, + {-0.832509, 0.182630, -0.231565}, + {-0.656420, 0.181038, 0.258291}, + {-0.098408, -0.476410, -0.870568}, + {0.000000, -0.593829, -0.829373}, + {0.000000, -0.687576, -0.782419}, + {-0.262228, -0.752914, -0.443125}, + {0.098408, -0.476410, -0.870568}, + {0.000000, -0.593829, -0.829373}, + {-0.098408, -0.476410, -0.870568}, + {-0.264625, -0.752914, -0.002985}, + {-0.253946, -0.641370, 0.469708}, + {-0.694135, -0.312989, 0.244487}, + {-0.344476, 0.629688, 0.116868}, + {-0.622732, 0.479086, 0.232224}, + {-0.349261, 0.536033, 0.476164}, + {-0.355188, 0.198678, 0.691670}, + {-0.622732, 0.479086, 0.232224}, + {-0.656420, 0.181038, 0.258291}, + {0.272170, 0.741501, -0.358234}, + {-0.272170, 0.741501, -0.358234}, + {0.000000, 0.740627, 0.146322}, + {-0.832509, 0.182630, -0.231565}, + {-0.268856, 0.080386, -0.653151}, + {-0.201833, -0.138557, -0.694994}, + {-0.457082, -0.094252, -0.520104}, + {-0.428776, 0.584615, -0.231790}, + {-0.272170, 0.741501, -0.358234}, + {0.000000, 0.606050, -0.418116}, + {-0.268856, 0.080386, -0.653151}, + {-0.268856, 0.080386, -0.653151}, + {0.268856, 0.080386, -0.653151}, + {0.201833, -0.138557, -0.694994}, + {-0.201833, -0.138557, -0.694994}, + {0.098408, -0.476410, -0.870568}, + {-0.098408, -0.476410, -0.870568}, + {-0.201833, -0.138557, -0.694994}, + {0.201833, -0.138557, -0.694994}, + {-0.457082, -0.094252, -0.520104}, + {-0.098408, -0.476410, -0.870568}, + {-0.262228, -0.752914, -0.443125}, + {-0.832509, 0.182630, -0.231565}, + {0.891059, 1.155259, -0.400431}, + {0.428776, 0.584615, -0.231790}, + {0.272170, 0.741501, -0.358234}, + {0.891059, 1.155259, -0.400431}, + {0.832509, 0.182630, -0.231565}, + {0.428776, 0.584615, -0.231790}, + {0.832509, 0.182630, -0.231565}, + {0.268856, 0.080386, -0.653151}, + {0.428776, 0.584615, -0.231790}, + {0.201833, -0.138557, -0.694994}, + {0.457082, -0.094252, -0.520104}, + {0.098408, -0.476410, -0.870568}, + {0.832509, 0.182630, -0.231565}, + {0.733418, -0.312989, -0.156211}, + {0.262228, -0.752914, -0.443125}, + {0.891059, 1.155259, -0.400431}, + {0.622732, 0.479086, 0.232224}, + {0.832509, 0.182630, -0.231565}, + {0.272170, 0.741501, -0.358234}, + {0.344476, 0.629688, 0.116868}, + {0.891059, 1.155259, -0.400431}, + {0.891059, 1.155259, -0.400431}, + {0.344476, 0.629688, 0.116868}, + {0.622732, 0.479086, 0.232224}, + {0.000000, 0.740627, 0.146322}, + {0.344476, 0.629688, 0.116868}, + {0.272170, 0.741501, -0.358234}, + {0.832509, 0.182630, -0.231565}, + {0.656420, 0.181038, 0.258291}, + {0.694135, -0.312989, 0.244487}, + {0.733418, -0.312989, -0.156211}, + {0.000000, 0.740627, 0.146322}, + {0.000000, 0.596703, 0.573425}, + {0.349261, 0.536033, 0.476164}, + {0.344476, 0.629688, 0.116868}, + {0.000000, 0.596703, 0.573425}, + {0.000000, 0.217028, 0.796752}, + {0.355188, 0.198678, 0.691670}, + {0.349261, 0.536033, 0.476164}, + {0.733418, -0.312989, -0.156211}, + {0.694135, -0.312989, 0.244487}, + {0.264625, -0.752914, -0.002985}, + {0.262228, -0.752914, -0.443125}, + {0.000000, 0.217028, 0.796752}, + {0.000000, -0.265114, 0.797826}, + {0.311519, -0.283536, 0.677898}, + {0.355188, 0.198678, 0.691670}, + {0.000000, -0.696637, 0.511078}, + {0.000000, -0.844740, -0.055026}, + {0.264625, -0.752914, -0.002985}, + {0.253946, -0.641370, 0.469708}, + {0.000000, -0.265114, 0.797826}, + {0.000000, -0.696637, 0.511078}, + {0.253946, -0.641370, 0.469708}, + {0.311519, -0.283536, 0.677898}, + {0.253946, -0.641370, 0.469708}, + {0.694135, -0.312989, 0.244487}, + {0.311519, -0.283536, 0.677898}, + {0.694135, -0.312989, 0.244487}, + {0.656420, 0.181038, 0.258291}, + {0.355188, 0.198678, 0.691670}, + {0.311519, -0.283536, 0.677898}, + {0.622732, 0.479086, 0.232224}, + {0.349261, 0.536033, 0.476164}, + {0.355188, 0.198678, 0.691670}, + {0.622732, 0.479086, 0.232224}, + {0.656420, 0.181038, 0.258291}, + {0.832509, 0.182630, -0.231565}, + {0.098408, -0.476410, -0.870568}, + {0.262228, -0.752914, -0.443125}, + {0.000000, -0.687576, -0.782419}, + {0.000000, -0.593829, -0.829373}, + {0.264625, -0.752914, -0.002985}, + {0.694135, -0.312989, 0.244487}, + {0.253946, -0.641370, 0.469708}, + {0.344476, 0.629688, 0.116868}, + {0.349261, 0.536033, 0.476164}, + {0.622732, 0.479086, 0.232224}, + {0.355188, 0.198678, 0.691670}, + {0.656420, 0.181038, 0.258291}, + {0.622732, 0.479086, 0.232224}, + {0.832509, 0.182630, -0.231565}, + {0.457082, -0.094252, -0.520104}, + {0.201833, -0.138557, -0.694994}, + {0.268856, 0.080386, -0.653151}, + {0.428776, 0.584615, -0.231790}, + {0.268856, 0.080386, -0.653151}, + {0.000000, 0.606050, -0.418116}, + {0.272170, 0.741501, -0.358234}, + {0.457082, -0.094252, -0.520104}, + {0.832509, 0.182630, -0.231565}, + {0.262228, -0.752914, -0.443125}, + {0.098408, -0.476410, -0.870568}, + {0.272170, 0.741501, -0.358234}, + {0.000000, 0.606050, -0.418116}, + {-0.272170, 0.741501, -0.358234}}; + +static const std::vector cat_normal_data = { + {0.000000, -0.884870, -0.465839}, + {0.000000, -0.884870, -0.465839}, + {0.000000, -0.884870, -0.465839}, + {0.000000, -0.884870, -0.465839}, + {-0.242538, -0.450412, -0.859246}, + {-0.242538, -0.450412, -0.859246}, + {-0.242538, -0.450412, -0.859246}, + {0.158401, -0.159636, -0.974385}, + {0.158401, -0.159636, -0.974385}, + {0.158401, -0.159636, -0.974385}, + {-0.471173, 0.472804, -0.744615}, + {-0.471173, 0.472804, -0.744615}, + {-0.471173, 0.472804, -0.744615}, + {-0.512715, 0.267081, -0.815960}, + {-0.512715, 0.267081, -0.815960}, + {-0.512715, 0.267081, -0.815960}, + {0.000000, 0.408177, -0.912903}, + {0.000000, 0.408177, -0.912903}, + {0.000000, 0.408177, -0.912903}, + {-0.329301, -0.944225, -0.000909}, + {-0.329301, -0.944225, -0.000909}, + {-0.329301, -0.944225, -0.000909}, + {-0.329301, -0.944225, -0.000909}, + {-0.658484, -0.240097, -0.713269}, + {-0.658484, -0.240097, -0.713269}, + {-0.658484, -0.240097, -0.713269}, + {0.329301, -0.944225, -0.000909}, + {0.329301, -0.944225, -0.000909}, + {0.329301, -0.944225, -0.000909}, + {0.329301, -0.944225, -0.000909}, + {-0.914615, 0.015092, 0.404043}, + {-0.914615, 0.015092, 0.404043}, + {-0.914615, 0.015092, 0.404043}, + {0.522378, 0.808883, 0.269868}, + {0.522378, 0.808883, 0.269868}, + {0.522378, 0.808883, 0.269868}, + {-0.055946, 0.670220, 0.740050}, + {-0.055946, 0.670220, 0.740050}, + {-0.055946, 0.670220, 0.740050}, + {-0.315264, 0.933346, 0.171678}, + {-0.315264, 0.933346, 0.171678}, + {-0.315264, 0.933346, 0.171678}, + {-0.970986, -0.045619, 0.234743}, + {-0.970986, -0.045619, 0.234743}, + {-0.970986, -0.045619, 0.234743}, + {-0.970986, -0.045619, 0.234743}, + {-0.278035, 0.919991, 0.276248}, + {-0.278035, 0.919991, 0.276248}, + {-0.278035, 0.919991, 0.276248}, + {-0.278035, 0.919991, 0.276248}, + {-0.290359, 0.501267, 0.815121}, + {-0.290359, 0.501267, 0.815121}, + {-0.290359, 0.501267, 0.815121}, + {-0.290359, 0.501267, 0.815121}, + {-0.689222, -0.723919, 0.030235}, + {-0.689222, -0.723919, 0.030235}, + {-0.689222, -0.723919, 0.030235}, + {-0.689222, -0.723919, 0.030235}, + {-0.318327, -0.026892, 0.947600}, + {-0.318327, -0.026892, 0.947600}, + {-0.318327, -0.026892, 0.947600}, + {-0.318327, -0.026892, 0.947600}, + {-0.260625, -0.935992, 0.236630}, + {-0.260625, -0.935992, 0.236630}, + {-0.260625, -0.935992, 0.236630}, + {-0.260625, -0.935992, 0.236630}, + {-0.264809, -0.526051, 0.808175}, + {-0.264809, -0.526051, 0.808175}, + {-0.264809, -0.526051, 0.808175}, + {-0.264809, -0.526051, 0.808175}, + {-0.651072, -0.457234, 0.605840}, + {-0.651072, -0.457234, 0.605840}, + {-0.651072, -0.457234, 0.605840}, + {-0.784301, -0.022297, 0.619980}, + {-0.784301, -0.022297, 0.619980}, + {-0.784301, -0.022297, 0.619980}, + {-0.784301, -0.022297, 0.619980}, + {-0.651985, 0.416291, 0.633733}, + {-0.651985, 0.416291, 0.633733}, + {-0.651985, 0.416291, 0.633733}, + {-0.932326, 0.134728, 0.335582}, + {-0.932326, 0.134728, 0.335582}, + {-0.932326, 0.134728, 0.335582}, + {-0.584697, -0.529169, -0.614906}, + {-0.584697, -0.529169, -0.614906}, + {-0.584697, -0.529169, -0.614906}, + {-0.584697, -0.529169, -0.614906}, + {0.000000, -0.331050, -0.943613}, + {0.000000, -0.331050, -0.943613}, + {0.000000, -0.331050, -0.943613}, + {-0.647437, -0.738348, 0.188860}, + {-0.647437, -0.738348, 0.188860}, + {-0.647437, -0.738348, 0.188860}, + {-0.388866, 0.892756, 0.227530}, + {-0.388866, 0.892756, 0.227530}, + {-0.388866, 0.892756, 0.227530}, + {-0.815578, 0.141259, 0.561140}, + {-0.815578, 0.141259, 0.561140}, + {-0.815578, 0.141259, 0.561140}, + {-0.000000, 0.999999, 0.001732}, + {-0.000000, 0.999999, 0.001732}, + {-0.000000, 0.999999, 0.001732}, + {-0.586843, 0.015755, -0.809547}, + {-0.586843, 0.015755, -0.809547}, + {-0.586843, 0.015755, -0.809547}, + {-0.586843, 0.015755, -0.809547}, + {-0.385249, 0.374337, -0.843478}, + {-0.385249, 0.374337, -0.843478}, + {-0.385249, 0.374337, -0.843478}, + {-0.385249, 0.374337, -0.843478}, + {0.000000, 0.187717, -0.982223}, + {0.000000, 0.187717, -0.982223}, + {0.000000, 0.187717, -0.982223}, + {0.000000, 0.187717, -0.982223}, + {0.000000, 0.461126, -0.887335}, + {0.000000, 0.461126, -0.887335}, + {0.000000, 0.461126, -0.887335}, + {0.000000, 0.461126, -0.887335}, + {-0.763767, -0.293159, -0.575081}, + {-0.763767, -0.293159, -0.575081}, + {-0.763767, -0.293159, -0.575081}, + {-0.763767, -0.293159, -0.575081}, + {0.242538, -0.450412, -0.859246}, + {0.242538, -0.450412, -0.859246}, + {0.242538, -0.450412, -0.859246}, + {-0.158401, -0.159636, -0.974385}, + {-0.158401, -0.159636, -0.974385}, + {-0.158401, -0.159636, -0.974385}, + {0.471173, 0.472804, -0.744615}, + {0.471173, 0.472804, -0.744615}, + {0.471173, 0.472804, -0.744615}, + {0.512715, 0.267081, -0.815960}, + {0.512715, 0.267081, -0.815960}, + {0.512715, 0.267081, -0.815960}, + {0.658484, -0.240097, -0.713269}, + {0.658484, -0.240097, -0.713269}, + {0.658484, -0.240097, -0.713269}, + {0.914615, 0.015092, 0.404043}, + {0.914615, 0.015092, 0.404043}, + {0.914615, 0.015092, 0.404043}, + {-0.522378, 0.808883, 0.269868}, + {-0.522378, 0.808883, 0.269868}, + {-0.522378, 0.808883, 0.269868}, + {0.055946, 0.670220, 0.740050}, + {0.055946, 0.670220, 0.740050}, + {0.055946, 0.670220, 0.740050}, + {0.315264, 0.933346, 0.171678}, + {0.315264, 0.933346, 0.171678}, + {0.315264, 0.933346, 0.171678}, + {0.970986, -0.045619, 0.234743}, + {0.970986, -0.045619, 0.234743}, + {0.970986, -0.045619, 0.234743}, + {0.970986, -0.045619, 0.234743}, + {0.278035, 0.919991, 0.276248}, + {0.278035, 0.919991, 0.276248}, + {0.278035, 0.919991, 0.276248}, + {0.278035, 0.919991, 0.276248}, + {0.290359, 0.501267, 0.815121}, + {0.290359, 0.501267, 0.815121}, + {0.290359, 0.501267, 0.815121}, + {0.290359, 0.501267, 0.815121}, + {0.689222, -0.723919, 0.030235}, + {0.689222, -0.723919, 0.030235}, + {0.689222, -0.723919, 0.030235}, + {0.689222, -0.723919, 0.030235}, + {0.318327, -0.026892, 0.947600}, + {0.318327, -0.026892, 0.947600}, + {0.318327, -0.026892, 0.947600}, + {0.318327, -0.026892, 0.947600}, + {0.260625, -0.935992, 0.236630}, + {0.260625, -0.935992, 0.236630}, + {0.260625, -0.935992, 0.236630}, + {0.260625, -0.935992, 0.236630}, + {0.264809, -0.526051, 0.808175}, + {0.264809, -0.526051, 0.808175}, + {0.264809, -0.526051, 0.808175}, + {0.264809, -0.526051, 0.808175}, + {0.651072, -0.457234, 0.605840}, + {0.651072, -0.457234, 0.605840}, + {0.651072, -0.457234, 0.605840}, + {0.784301, -0.022297, 0.619980}, + {0.784301, -0.022297, 0.619980}, + {0.784301, -0.022297, 0.619980}, + {0.784301, -0.022297, 0.619980}, + {0.651985, 0.416291, 0.633733}, + {0.651985, 0.416291, 0.633733}, + {0.651985, 0.416291, 0.633733}, + {0.932326, 0.134728, 0.335582}, + {0.932326, 0.134728, 0.335582}, + {0.932326, 0.134728, 0.335582}, + {0.584697, -0.529169, -0.614906}, + {0.584697, -0.529169, -0.614906}, + {0.584697, -0.529169, -0.614906}, + {0.584697, -0.529169, -0.614906}, + {0.647437, -0.738348, 0.188860}, + {0.647437, -0.738348, 0.188860}, + {0.647437, -0.738348, 0.188860}, + {0.388866, 0.892756, 0.227530}, + {0.388866, 0.892756, 0.227530}, + {0.388866, 0.892756, 0.227530}, + {0.815578, 0.141259, 0.561140}, + {0.815578, 0.141259, 0.561140}, + {0.815578, 0.141259, 0.561140}, + {0.586843, 0.015755, -0.809547}, + {0.586843, 0.015755, -0.809547}, + {0.586843, 0.015755, -0.809547}, + {0.586843, 0.015755, -0.809547}, + {0.385249, 0.374337, -0.843478}, + {0.385249, 0.374337, -0.843478}, + {0.385249, 0.374337, -0.843478}, + {0.385249, 0.374337, -0.843478}, + {0.763767, -0.293159, -0.575081}, + {0.763767, -0.293159, -0.575081}, + {0.763767, -0.293159, -0.575081}, + {0.763767, -0.293159, -0.575081}, + {0.000000, 0.404344, -0.914607}, + {0.000000, 0.404344, -0.914607}, + {0.000000, 0.404344, -0.914607}}; + +const std::vector cat_indices_data{ + 0, 1, 2, + 2, 3, 0, + 4, 5, 6, + 7, 8, 9, + 10, 11, 12, + 13, 14, 15, + 16, 17, 18, + 19, 20, 21, + 21, 22, 19, + 23, 24, 25, + 26, 27, 28, + 28, 29, 26, + 30, 31, 32, + 33, 34, 35, + 36, 37, 38, + 39, 40, 41, + 42, 43, 44, + 44, 45, 42, + 46, 47, 48, + 48, 49, 46, + 50, 51, 52, + 52, 53, 50, + 54, 55, 56, + 56, 57, 54, + 58, 59, 60, + 60, 61, 58, + 62, 63, 64, + 64, 65, 62, + 66, 67, 68, + 68, 69, 66, + 70, 71, 72, + 73, 74, 75, + 75, 76, 73, + 77, 78, 79, + 80, 81, 82, + 83, 84, 85, + 85, 86, 83, + 87, 88, 89, + 90, 91, 92, + 93, 94, 95, + 96, 97, 98, + 99, 100, 101, + 102, 103, 104, + 104, 105, 102, + 106, 107, 108, + 108, 109, 106, + 110, 111, 112, + 112, 113, 110, + 114, 115, 116, + 116, 117, 114, + 118, 119, 120, + 120, 121, 118, + 122, 123, 124, + 125, 126, 127, + 128, 129, 130, + 131, 132, 133, + 134, 135, 136, + 137, 138, 139, + 140, 141, 142, + 143, 144, 145, + 146, 147, 148, + 149, 150, 151, + 151, 152, 149, + 153, 154, 155, + 155, 156, 153, + 157, 158, 159, + 159, 160, 157, + 161, 162, 163, + 163, 164, 161, + 165, 166, 167, + 167, 168, 165, + 169, 170, 171, + 171, 172, 169, + 173, 174, 175, + 175, 176, 173, + 177, 178, 179, + 180, 181, 182, + 182, 183, 180, + 184, 185, 186, + 187, 188, 189, + 190, 191, 192, + 192, 193, 190, + 194, 195, 196, + 197, 198, 199, + 200, 201, 202, + 203, 204, 205, + 205, 206, 203, + 207, 208, 209, + 209, 210, 207, + 211, 212, 213, + 213, 214, 211, + 215, 216, 217}; + +ramses_base::RamsesArrayResource createCatVertexDataBuffer(ramses::Scene* scene) { + std::vector data(cat_vertex_data); + for (auto& v : data) { + v.z = -v.z; + } + return ramses_base::ramsesArrayResource(scene, data, defaultVertexDataBufferName); +} + +ramses_base::RamsesArrayResource createCatNormalDataBuffer(ramses::Scene* scene) { + std::vector data(cat_normal_data); + for (auto& v : data) { + v.z = -v.z; + } + return ramses_base::ramsesArrayResource(scene, data, defaultNormalDataBufferName); +} + +ramses_base::RamsesArrayResource createCatIndexDataBuffer(ramses::Scene* scene) { + return ramses_base::ramsesArrayResource(scene, cat_indices_data, defaultIndexDataBufferName); +} + +} // namespace raco::ramses_adaptor \ No newline at end of file diff --git a/components/libRamsesBase/src/ramses_adaptor/Factories.cpp b/components/libRamsesBase/src/ramses_adaptor/Factories.cpp index a49b20a4..c3d5135e 100644 --- a/components/libRamsesBase/src/ramses_adaptor/Factories.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/Factories.cpp @@ -33,6 +33,11 @@ #include "ramses_adaptor/TimerAdaptor.h" #include "ramses_adaptor/TextureSamplerAdaptor.h" #include "ramses_adaptor/TextureExternalAdaptor.h" + +#include "ramses_adaptor/AbstractMeshAdaptor.h" +#include "ramses_adaptor/AbstractMeshNodeAdaptor.h" +#include "ramses_adaptor/AbstractNodeAdaptor.h" + #include "user_types/CubeMap.h" #include "user_types/Texture.h" #include "user_types/PrefabInstance.h" @@ -42,9 +47,10 @@ namespace raco::ramses_adaptor { -using Factory = std::function; UniqueObjectAdaptor Factories::createAdaptor(SceneAdaptor* sceneAdaptor, core::SEditorObject obj) { + using Factory = std::function; + static const std::map factoryByTypename{ // SCENE OBJECTS {user_types::Node::typeDescription.typeName, [](SceneAdaptor* sceneAdaptor, core::SEditorObject obj) { return std::make_unique(sceneAdaptor, std::dynamic_pointer_cast(obj)); }}, @@ -69,6 +75,7 @@ UniqueObjectAdaptor Factories::createAdaptor(SceneAdaptor* sceneAdaptor, core::S {user_types::RenderBuffer::typeDescription.typeName, [](SceneAdaptor* sceneAdaptor, core::SEditorObject obj) { return std::make_unique(sceneAdaptor, std::dynamic_pointer_cast(obj)); }}, {user_types::RenderBufferMS::typeDescription.typeName, [](SceneAdaptor* sceneAdaptor, core::SEditorObject obj) { return std::make_unique(sceneAdaptor, std::dynamic_pointer_cast(obj)); }}, {user_types::RenderTarget::typeDescription.typeName, [](SceneAdaptor* sceneAdaptor, core::SEditorObject obj) { return std::make_unique(sceneAdaptor, std::dynamic_pointer_cast(obj)); }}, + {user_types::RenderTargetMS::typeDescription.typeName, [](SceneAdaptor* sceneAdaptor, core::SEditorObject obj) { return std::make_unique(sceneAdaptor, std::dynamic_pointer_cast(obj)); }}, {user_types::RenderPass::typeDescription.typeName, [](SceneAdaptor* sceneAdaptor, core::SEditorObject obj) { return std::make_unique(sceneAdaptor, std::dynamic_pointer_cast(obj)); }}, {user_types::RenderLayer::typeDescription.typeName, [](SceneAdaptor* sceneAdaptor, core::SEditorObject obj) { return std::make_unique(sceneAdaptor, std::dynamic_pointer_cast(obj)); }}, {user_types::Timer::typeDescription.typeName, [](SceneAdaptor* sceneAdaptor, core::SEditorObject obj) { return std::make_unique(sceneAdaptor, std::dynamic_pointer_cast(obj)); }}, @@ -90,4 +97,29 @@ UniqueObjectAdaptor Factories::createAdaptor(SceneAdaptor* sceneAdaptor, core::S return UniqueObjectAdaptor{}; } + +UniqueAbstractObjectAdaptor Factories::createAbstractAdaptor(AbstractSceneAdaptor* sceneAdaptor, core::SEditorObject obj) { + using Factory = std::function; + + static const std::map factoryByTypename{ + // SCENE OBJECTS + {user_types::Node::typeDescription.typeName, [](AbstractSceneAdaptor* sceneAdaptor, core::SEditorObject obj) { return std::make_unique(sceneAdaptor, std::dynamic_pointer_cast(obj)); }}, + {user_types::MeshNode::typeDescription.typeName, [](AbstractSceneAdaptor* sceneAdaptor, core::SEditorObject obj) { return std::make_unique(sceneAdaptor, std::dynamic_pointer_cast(obj)); }}, + + {user_types::OrthographicCamera::typeDescription.typeName, [](AbstractSceneAdaptor* sceneAdaptor, core::SEditorObject obj) { return std::make_unique(sceneAdaptor, std::dynamic_pointer_cast(obj)); }}, + {user_types::PerspectiveCamera::typeDescription.typeName, [](AbstractSceneAdaptor* sceneAdaptor, core::SEditorObject obj) { return std::make_unique(sceneAdaptor, std::dynamic_pointer_cast(obj)); }}, + + {user_types::PrefabInstance::typeDescription.typeName, [](AbstractSceneAdaptor* sceneAdaptor, core::SEditorObject obj) { return std::make_unique(sceneAdaptor, std::dynamic_pointer_cast(obj)); }}, + + // RESOURCES + {user_types::Mesh::typeDescription.typeName, [](AbstractSceneAdaptor* sceneAdaptor, core::SEditorObject obj) { return std::make_unique(sceneAdaptor, std::dynamic_pointer_cast(obj)); }} + }; + + if (factoryByTypename.find(obj->getTypeDescription().typeName) != factoryByTypename.end()) { + return factoryByTypename.at(obj->getTypeDescription().typeName)(sceneAdaptor, obj); + } + return UniqueAbstractObjectAdaptor{}; +} + + } // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/src/ramses_adaptor/Gizmos.cpp b/components/libRamsesBase/src/ramses_adaptor/Gizmos.cpp new file mode 100644 index 00000000..33736657 --- /dev/null +++ b/components/libRamsesBase/src/ramses_adaptor/Gizmos.cpp @@ -0,0 +1,312 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "ramses_adaptor/Gizmos.h" + +#include "ramses_adaptor/AbstractSceneAdaptor.h" +#include "ramses_adaptor/BuildOptions.h" +#include "ramses_adaptor/DefaultRamsesObjects.h" +#include "ramses_adaptor/SceneAdaptor.h" +#include "ramses_adaptor/OrthographicCameraAdaptor.h" +#include "ramses_adaptor/PerspectiveCameraAdaptor.h" + +#include "user_types/PerspectiveCamera.h" + +#include "core/MeshCacheInterface.h" + +#include + +namespace raco::ramses_adaptor { + +using namespace raco::ramses_base; + +const char* frustumVertexShader = + R"( +#version 300 es +precision highp float; + +in vec3 a_Position; + +uniform mat4 u_PMatrix; +uniform mat4 u_VMatrix; + +uniform mat4 frustum_proj_matrix; +uniform mat4 frustum_model_matrix; + +void main() { + gl_Position = u_PMatrix * u_VMatrix * frustum_model_matrix * inverse(frustum_proj_matrix) * vec4(a_Position, 1.0); +} +)"; + +const char* frustumFragmentShader = + R"( +#version 300 es +precision highp float; + +out vec4 fragColor; + +uniform vec3 color; + +void main() { + fragColor = vec4(color, 0.2); +} +)"; + + +ramses_base::RamsesMeshNode GizmoTriad::createGizmoMeshnode(ramses::Scene* scene, RamsesGizmoMeshBuffers& buffers, glm::vec3 color, float alpha, bool invisible) { + ramses::EffectDescription effectDescription{}; + effectDescription.setVertexShader(flatColorVertexShader); + effectDescription.setFragmentShader(flatColorFragmentShader); + effectDescription.setUniformSemantic("u_MVPMatrix", ramses::EEffectUniformSemantic::ModelViewProjectionMatrix); + + auto effect = ramses_base::ramsesEffect(scene, effectDescription, {}, {0, 0}); + auto appearance = ramses_base::ramsesAppearance(scene, effect, {0, 0}); + (*appearance)->setDepthFunction(ramses::EDepthFunc::LessEqual); + (*appearance)->setCullingMode(ramses::ECullMode::Disabled); + + if (invisible) { + (*appearance)->setColorWriteMask(false, false, false, false); + } + + ramsesSetUniform(**appearance, "u_color", color); + ramsesSetUniform(**appearance, "u_alpha", alpha); + + auto geometry = ramsesGeometry(scene, effect, {0, 0}); + geometry->setIndices(buffers.indices); + + ramses::AttributeInput inputPosition = (*appearance)->getEffect().findAttributeInput(core::MeshData::ATTRIBUTE_POSITION).value(); + geometry->addAttributeBuffer(inputPosition, buffers.vertices); + + auto meshNode = ramsesMeshNode(scene, {0, 0}); + meshNode->setGeometry(geometry); + meshNode->setAppearance(appearance); + + return meshNode; +} + +ramses_base::RamsesMeshNode GizmoTriad::createFrustumMeshnode(ramses::Scene* scene, RamsesGizmoMeshBuffers& buffers, glm::vec3 color, float alpha) { + ramses::EffectDescription effectDescription{}; + effectDescription.setVertexShader(frustumVertexShader); + effectDescription.setFragmentShader(frustumFragmentShader); + effectDescription.setUniformSemantic("u_VMatrix", ramses::EEffectUniformSemantic::ViewMatrix); + effectDescription.setUniformSemantic("u_PMatrix", ramses::EEffectUniformSemantic::ProjectionMatrix); + + auto effect = ramses_base::ramsesEffect(scene, effectDescription, {}, {0, 0}); + auto appearance = ramses_base::ramsesAppearance(scene, effect, {0, 0}); + + (*appearance)->setDepthFunction(ramses::EDepthFunc::LessEqual); + (*appearance)->setCullingMode(ramses::ECullMode::Disabled); + + (*appearance)->setDepthWrite(ramses::EDepthWrite::Disabled); + (*appearance)->setBlendingOperations(ramses::EBlendOperation::Add, ramses::EBlendOperation::Add); + (*appearance)->setBlendingFactors(ramses::EBlendFactor::SrcAlpha, ramses::EBlendFactor::OneMinusSrcAlpha, ramses::EBlendFactor::One, ramses::EBlendFactor::One); + + auto geometry = ramsesGeometry(scene, effect, {0, 0}); + geometry->setIndices(buffers.indices); + + ramses::AttributeInput inputPosition = (*appearance)->getEffect().findAttributeInput(core::MeshData::ATTRIBUTE_POSITION).value(); + geometry->addAttributeBuffer(inputPosition, buffers.vertices); + + auto meshNode = ramsesMeshNode(scene, {0, 0}); + meshNode->setGeometry(geometry); + meshNode->setAppearance(appearance); + + return meshNode; +} + +GizmoTriad::GizmoTriad(AbstractSceneAdaptor* sceneAdaptor, ramses::Scene* scene, ramses_base::RamsesRenderGroup renderGroup, ramses_base::RamsesRenderGroup transparentRenderGroup, + RamsesGizmoMeshBuffers& buffers, core::SEditorObject node) + : sceneAdaptor_(sceneAdaptor), renderGroup_(renderGroup), renderGroupTransparent_(transparentRenderGroup), node_(node) { + root_ = ramses_base::ramsesNode(scene, {0, 0}); + + std::vector colors{{9.0, 0.2, 0.2}, {0.2, 0.9, 0.2}, {0.2, 0.2, 0.9}}; + + for (int axis = 0; axis < 3; axis++) { + arrow_[axis] = createGizmoMeshnode(scene, buffers, colors[axis]); + (*root_)->addChild(**arrow_[axis]); + renderGroup->addMeshNode(arrow_[axis], axis); + + pickId_[axis] = sceneAdaptor_->getPickId(); + pickObject_[axis] = ramses_base::ramsesPickableObject(sceneAdaptor_->scene(), buffers.triangles, pickId_[axis], sceneAdaptor_->camera()); + if (pickObject_[axis]) { + (**arrow_[axis]).addChild((*pickObject_[axis].get())); + } + } + + if (node->isType() || node->isType()) { + RamsesGizmoMeshBuffers cubeBuffers = createGizmoCube(scene); + frustum_ = createFrustumMeshnode(scene, cubeBuffers, {0.1, 0.1, 0.1}, 0.2); + + transparentRenderGroup->addMeshNode(frustum_, 0); + } + + update(); +} + +GizmoTriad::~GizmoTriad() { + renderGroup_->removeAllRenderables(); + renderGroupTransparent_->removeAllRenderables(); +} + +void GizmoTriad::update() { + auto modelMatrix = sceneAdaptor_->modelMatrix(node_); + glm::vec3 worldOrigin = modelMatrix * glm::vec4(0, 0, 0, 1); + + (*root_)->setTranslation(worldOrigin); + + // rotate individual axes + std::vector axisVecs{{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}}; + + for (int axis = 0; axis < 3; axis++) { + glm::vec3 axisWorld = modelMatrix * glm::vec4(axisVecs[axis], 0.0); + + // find rotate (0,0,1) -> axisWorld + glm::quat rotationQuat(glm::vec3(0, 0, 1), axisWorld); + (**arrow_[axis]).setRotation(rotationQuat); + } + + // Find scaling to make gizmo size appear constant on screen + auto viewMatrix = sceneAdaptor_->cameraController().viewMatrix(); + glm::vec3 originView = viewMatrix * modelMatrix * glm::vec4(0, 0, 0, 1); + float dist = glm::length(originView); + float scale = 0.05 * dist; + (**root_).setScaling({scale, scale, scale}); + + + ramses::Camera* ramsesCamera = nullptr; + if (auto cameraAdaptor = sceneAdaptor_->previewAdaptor()->lookup(node_)) { + ramsesCamera = cameraAdaptor->getRamsesObjectPointer()->get(); + } else if (auto cameraAdaptor = sceneAdaptor_->previewAdaptor()->lookup(node_)) { + ramsesCamera = cameraAdaptor->getRamsesObjectPointer()->get(); + } + if (ramsesCamera) { + glm::mat4 camProjectionMatrix; + glm::mat4 camModelMatrix; + ramsesCamera->getModelMatrix(camModelMatrix); + auto status = ramsesCamera->getProjectionMatrix(camProjectionMatrix); + + ramses::Appearance* appearance = (**frustum_).getAppearance(); + + ramsesSetUniform(*appearance, "color", {0.2, 0.2, 0.2}); + + ramsesSetUniform(*appearance, "frustum_model_matrix", camModelMatrix); + ramsesSetUniform(*appearance, "frustum_proj_matrix", camProjectionMatrix); + } +} + +core::SEditorObject GizmoTriad::object() { + return node_; +} + +std::pair GizmoTriad::pickElement(ramses::pickableObjectId_t pickId) { + for (int axis = 0; axis < 3; axis++) { + if (pickId == pickId_[axis]) { + return {axis, PickElement::Axis}; + } + } + return {-1, PickElement::None}; +} + +GizmoTransformation::GizmoTransformation(AbstractSceneAdaptor* sceneAdaptor, ramses::Scene* scene, ramses_base::RamsesRenderGroup renderGroup, ramses_base::RamsesRenderGroup transparentRenderGroup, RamsesGizmoMeshBuffers& axisBuffers, RamsesGizmoMeshBuffers& centralBuffers, core::SEditorObject node, bool enableCentralElement, bool enablePlanes, bool isRotation) + : enablePlanes_(enablePlanes), + GizmoTriad(sceneAdaptor, scene, renderGroup, transparentRenderGroup, axisBuffers, node) { + + if (enableCentralElement) { + central_ = createGizmoMeshnode(scene, centralBuffers, {0.4, 0.4, 0.4}); + (**central_).setScaling({0.2, 0.2, 0.2}); + (*root_)->addChild(**central_); + renderGroup->addMeshNode(central_, 7); + + pickIdCentral_ = sceneAdaptor_->getPickId(); + pickObjectCentral_ = ramses_base::ramsesPickableObject(sceneAdaptor_->scene(), centralBuffers.triangles, pickIdCentral_, sceneAdaptor_->camera()); + if (pickObjectCentral_) { + (**central_).addChild(*pickObjectCentral_.get()); + } + } + + if (isRotation) { + central_ = createGizmoMeshnode(scene, centralBuffers, {0.5, 0.5, 0.5}, 0.3, true); + (**central_).setScaling({0.95, 0.95, 0.95}); + (*root_)->addChild(**central_); + renderGroup->addMeshNode(central_, -1); + } + + if (enablePlanes_) { + std::vector colors{{9.0, 0.2, 0.2}, {0.2, 0.9, 0.2}, {0.2, 0.2, 0.9}}; + + RamsesGizmoMeshBuffers planeBuffers = createGizmoQuad(scene); + for (int axis = 0; axis < 3; axis++) { + plane_[axis] = createGizmoMeshnode(scene, planeBuffers, colors[axis]); + (**plane_[axis]).setScaling({0.25, 0.25, 0.25}); + (*root_)->addChild(**plane_[axis]); + renderGroup->addMeshNode(plane_[axis], axis); + + pickIdPlane_[axis] = sceneAdaptor_->getPickId(); + pickObjectPlane_[axis] = ramses_base::ramsesPickableObject(sceneAdaptor_->scene(), planeBuffers.triangles, pickIdPlane_[axis], sceneAdaptor_->camera()); + if (pickObjectPlane_[axis]) { + (**plane_[axis]).addChild((*pickObjectPlane_[axis].get())); + } + } + } + + update(); +} + +void GizmoTransformation::update() { + GizmoTriad::update(); + + if (enablePlanes_) { + auto modelMatrix = sceneAdaptor_->modelMatrix(node_); + + // rotate individual quads + std::vector axisVecs{{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}}; + + for (int axis = 0; axis < 3; axis++) { + glm::vec3 axisWorld1 = glm::normalize(modelMatrix * glm::vec4(axisVecs[(axis + 1) % 3], 0.0)); + glm::vec3 axisWorld2 = glm::normalize(modelMatrix * glm::vec4(axisVecs[(axis + 2) % 3], 0.0)); + glm::vec3 planeNormalWorld = glm::normalize(glm::cross(axisWorld1, axisWorld2)); + + // Note: axisWorld1 and axisWorld2 may not be orthogonal; in that case extracting the euler angles from the matrix + // is qustionable but seems to work anyway in simple cases. + glm::mat3 rotationMat(axisWorld1, axisWorld2, planeNormalWorld); + glm::mat4 m4(rotationMat); + + float rotX, rotY, rotZ; + glm::extractEulerAngleXYZ(m4, rotX, rotY, rotZ); + + (**plane_[axis]).setRotation({glm::degrees(rotX), glm::degrees(rotY), glm::degrees(rotZ)}, ramses::ERotationType::Euler_ZYX); + + glm::vec3 translation = 0.5f * (axisWorld1 + axisWorld2); + (**plane_[axis]).setTranslation(translation); + } + } +} + +std::pair GizmoTransformation::pickElement(ramses::pickableObjectId_t pickId) { + if (pickId == pickIdCentral_) { + return {0, PickElement::Central}; + } + + auto result = GizmoTriad::pickElement(pickId); + if (result.first != -1) { + return result; + } + + if (enablePlanes_) { + for (int plane = 0; plane < 3; plane++) { + if (pickId == pickIdPlane_[plane]) { + return {plane, PickElement::Plane}; + } + } + } + return {-1, PickElement::None}; +} + +} // namespace raco::ramses_adaptor \ No newline at end of file diff --git a/components/libRamsesBase/src/ramses_adaptor/InfiniteGrid.cpp b/components/libRamsesBase/src/ramses_adaptor/InfiniteGrid.cpp new file mode 100644 index 00000000..44d49a4f --- /dev/null +++ b/components/libRamsesBase/src/ramses_adaptor/InfiniteGrid.cpp @@ -0,0 +1,187 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "ramses_adaptor/InfiniteGrid.h" + +#include "ramses_adaptor/utilities.h" + +namespace raco::ramses_adaptor { + +using namespace raco::ramses_base; + +InfiniteGrid::InfiniteGrid(ramses::Scene* scene) + : scene_(scene) { +} + +static const std::string vertexShader = R"( +#version 300 es + +precision highp float; + +uniform mat4 u_VMatrix; +uniform mat4 u_PMatrix; + +out vec3 ray_near; +out vec3 ray_far; + +vec3 unproject(vec3 v) { + vec4 u = inverse(u_VMatrix) * inverse(u_PMatrix) * vec4(v, 1.0); + return u.xyz / u.w; +} + +void main() { + // use this with no geometry: + // - MeshNode::setIndexCount(3) + // - need to set a GeometryBinding but this can be empty + vec3 vertices[3] = vec3[](vec3(-1, -1, 0), vec3(-1, 3, 0), vec3(3, -1, 0)); + + vec3 p_eye = vertices[gl_VertexID]; + + ray_near = unproject(vec3(p_eye.x, p_eye.y, -1.0)); + ray_far = unproject(vec3(p_eye.x, p_eye.y, +1.0)); + + gl_Position = vec4(p_eye, 1.0); +} +)"; + +static const std::string fragmentShader = R"( +#version 300 es + +precision highp float; + +uniform mat4 u_VMatrix; +uniform mat4 u_PMatrix; + +uniform float scale; + +uniform int full_grid; + +uniform vec3 origin; +uniform vec3 u,v; +uniform int idx_u, idx_v; + +uniform vec2 enable; + +uniform float axis_color_fac; + +in vec3 ray_near; +in vec3 ray_far; + +out vec4 fragColor; + +void main() { + vec3 normal = normalize(cross(u, v)); + + vec3 ray_dir = ray_far - ray_near; + float t = (dot(origin, normal) - dot(ray_near, normal)) / dot(ray_dir, normal); + vec3 p = ray_near + t * ray_dir; + + mat3 m = mat3(u, v, normal); + mat3 m_inv = inverse(m); + + vec2 uv = (m_inv * (p - origin)).xy / scale; + vec2 fw = fwidth(uv); + + vec2 dist; + if (full_grid == 1) { + vec2 uvf = fract(uv); + dist = min(uvf, 1.0 - uvf) / fw; + } else { + dist = abs(uv) / fw; + } + + // interpolate + // md=0 -> 1.0 + // md=n -> 0.0 + + float lw = 1.5; + vec2 interp = enable.yx * (1.0 - smoothstep(0.0, lw, dist)); + + float cc = 0.5; + float alpha = max(interp.x, interp.y); + vec4 color = vec4(cc, cc, cc, alpha)* float(t > 0.0); + + vec4 color_fac = vec4(axis_color_fac, axis_color_fac, axis_color_fac, 1.0); + if (abs(uv.x) < lw * fw.x && enable.y == 1.0) { + color_fac[idx_v] = 2.0; + } else if (abs(uv.y) < lw * fw.y && enable.x == 1.0) { + color_fac[idx_u] = 2.0; + } else if (full_grid == 0) { + color_fac = vec4(0, 0, 0, 1.0); + } + color *= color_fac; + + // Fadeout grid based on distance relative to far plane in eye coordinates: + vec4 vtmp = inverse(u_PMatrix) * vec4(0.0, 0.0, 1.0, 1.0); + float fardist = - vtmp.z / vtmp.w; + vec4 p_eye = u_VMatrix * vec4(p, 1.0); + float dfrac = length(p_eye.xz) / fardist; + float fac = max(0.0, 1.0 - 2.0 * dfrac); + + fragColor = color * fac; + + vec4 p_clip = u_PMatrix * u_VMatrix * vec4(p, 1.0); + float depth_ndc = p_clip.z/p_clip.w; + gl_FragDepth = gl_DepthRange.near + gl_DepthRange.diff * (depth_ndc + 1.0)/2.0; +} +)"; + +void InfiniteGrid::setup(ramses_base::RamsesRenderPass renderPass, bool depthTesting, float axisColorFac, int renderOrder) { + renderGroup_ = ramsesRenderGroup(scene_, {0, 0}); + renderPass->addRenderGroup(renderGroup_, renderOrder); + + ramses::EffectDescription effectDescription{}; + auto status = effectDescription.setVertexShader(vertexShader.c_str()); + status = effectDescription.setFragmentShader(fragmentShader.c_str()); + status = effectDescription.setUniformSemantic("u_PMatrix", ramses::EEffectUniformSemantic::ProjectionMatrix); + status = effectDescription.setUniformSemantic("u_VMatrix", ramses::EEffectUniformSemantic::ViewMatrix); + effect_ = ramsesEffect(scene_, effectDescription, {}, {0, 0}); + appearance_ = ramsesAppearance(scene_, effect_, {0, 0}); + + (*appearance_)->setDepthWrite(ramses::EDepthWrite::Disabled); + if (!depthTesting) { + (*appearance_)->setDepthFunction(ramses::EDepthFunc::Always); + } + (*appearance_)->setCullingMode(ramses::ECullMode::Disabled); + (*appearance_)->setBlendingOperations(ramses::EBlendOperation::Add, ramses::EBlendOperation::Add); + + ramsesSetUniform(**appearance_, "scale", scale_); + ramsesSetUniform(**appearance_, "axis_color_fac", axisColorFac); + + geometry_ = ramsesGeometry(scene_, effect_, {0, 0}); + + meshNode_ = ramsesMeshNode(scene_, {0, 0}); + meshNode_->setGeometry(geometry_); + meshNode_->setAppearance(appearance_); + meshNode_->get()->setIndexCount(3); + + renderGroup_->addMeshNode(meshNode_, 0); +} + +void InfiniteGrid::enable(glm::vec3 origin, glm::vec3 u, glm::vec3 v, int idx_u, int idx_v, bool full_grid, glm::vec2 enable) { + ramsesSetUniform(**appearance_, "full_grid", full_grid ? 1 : 0); + ramsesSetUniform(**appearance_, "origin", origin); + ramsesSetUniform(**appearance_, "u", u); + ramsesSetUniform(**appearance_, "v", v); + ramsesSetUniform(**appearance_, "idx_u", idx_u); + ramsesSetUniform(**appearance_, "idx_v", idx_v); + ramsesSetUniform(**appearance_, "enable", enable); +} + +void InfiniteGrid::disable() { + ramsesSetUniform(**appearance_, "enable", glm::vec2(0.0, 0.0)); +} + +void InfiniteGrid::setScale(float scale) { + scale_ = scale; + ramsesSetUniform(**appearance_, "scale", scale_); +} + +} // namespace raco::ramses_adaptor \ No newline at end of file diff --git a/components/libRamsesBase/src/ramses_adaptor/LinkAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/LinkAdaptor.cpp index 8bc4f221..b0b6595d 100644 --- a/components/libRamsesBase/src/ramses_adaptor/LinkAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/LinkAdaptor.cpp @@ -22,7 +22,7 @@ namespace raco::ramses_adaptor { namespace { -LinkAdaptor::UniqueEngineLink createEngineLink(rlogic::LogicEngine* engine, const rlogic::Property& origin, const rlogic::Property& dest, bool isWeak) { +LinkAdaptor::UniqueEngineLink createEngineLink(ramses::LogicEngine* engine, ramses::Property& origin, ramses::Property& dest, bool isWeak) { if (isWeak ? engine->linkWeak(origin, dest) : engine->link(origin, dest)) { LOG_TRACE(log_system::RAMSES_ADAPTOR, "Create LogicEngine link: {}:{}->{}:{}", fmt::ptr(&origin), origin.getName(), fmt::ptr(&dest), dest.getName()); return {new LinkAdaptor::EngineLink{&origin, &dest}, [engine](LinkAdaptor::EngineLink* link) { @@ -93,7 +93,8 @@ void LinkAdaptor::connectHelper(const core::ValueHandle& start, const core::Valu if (startPropOpt) { auto startProp = startPropOpt.value(); if (auto startAdaptor = sceneAdaptor_->lookupAdaptor(startProp.object())) { - if (auto startEngineProp = dynamic_cast(startAdaptor)->getProperty(startProp.propertyNames())) { + const auto& names = startProp.propertyNames(); + if (auto startEngineProp = dynamic_cast(startAdaptor)->getProperty({names.begin(), names.end()})) { if (auto endAdaptor = sceneAdaptor_->lookupAdaptor(editorLink_.end.object())) { if (auto endEngineProp = dynamic_cast(endAdaptor)->getProperty(end.getPropertyNamesVector())) { if (auto engineLink = createEngineLink(&sceneAdaptor_->logicEngine(), *startEngineProp, *endEngineProp, isWeak)) { diff --git a/components/libRamsesBase/src/ramses_adaptor/LuaInterfaceAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/LuaInterfaceAdaptor.cpp index 19ca5a46..033b228d 100644 --- a/components/libRamsesBase/src/ramses_adaptor/LuaInterfaceAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/LuaInterfaceAdaptor.cpp @@ -9,12 +9,12 @@ */ #include "ramses_adaptor/LuaInterfaceAdaptor.h" -#include "ramses_adaptor/LuaScriptModuleAdaptor.h" -#include "utils/FileUtils.h" #include "core/PrefabOperations.h" #include "core/Queries.h" -#include "user_types/PrefabInstance.h" +#include "ramses_adaptor/LuaScriptModuleAdaptor.h" #include "user_types/LuaScript.h" +#include "user_types/PrefabInstance.h" +#include "utils/FileUtils.h" namespace raco::ramses_adaptor { @@ -47,19 +47,15 @@ LuaInterfaceAdaptor::LuaInterfaceAdaptor(SceneAdaptor* sceneAdaptor, std::shared tagDirty(); recreateStatus_ = true; })}, - linksLifecycleSubscription_{sceneAdaptor_->dispatcher()->registerOnLinksLifeCycle( - [this](const core::LinkDescriptor& link) { + linksLifecycleSubscription_{sceneAdaptor_->dispatcher()->registerOnLinksLifeCycle([this](const core::LinkDescriptor& link) { if (sceneAdaptor_->optimizeForExport() && (link.start.object() == editorObject_ || link.end.object() == editorObject_)) { tagDirty(); recreateStatus_ = true; - } - }, - [this](const core::LinkDescriptor& link) { + } }, [this](const core::LinkDescriptor& link) { if (sceneAdaptor_->optimizeForExport() && (link.start.object() == editorObject_ || link.end.object() == editorObject_)) { tagDirty(); recreateStatus_ = true; - } - })}, + } })}, linkValidityChangeSubscription_{sceneAdaptor_->dispatcher()->registerOnLinkValidityChange([this](const core::LinkDescriptor& link) { if (sceneAdaptor_->optimizeForExport() && (link.start.object() == editorObject_ || link.end.object() == editorObject_)) { tagDirty(); @@ -82,13 +78,13 @@ void LuaInterfaceAdaptor::setupParentSubscription() { } } -void LuaInterfaceAdaptor::getLogicNodes(std::vector& logicNodes) const { +void LuaInterfaceAdaptor::getLogicNodes(std::vector& logicNodes) const { if (ramsesInterface_) { logicNodes.push_back(ramsesInterface_.get()); } } -const rlogic::Property* LuaInterfaceAdaptor::getProperty(const std::vector& names) { +ramses::Property* LuaInterfaceAdaptor::getProperty(const std::vector& names) { if (ramsesInterface_ && names.size() >= 1 && names[0] == "inputs") { return ILogicPropertyProvider::getPropertyRecursive(ramsesInterface_->getInputs(), names, 1); } @@ -103,9 +99,8 @@ void LuaInterfaceAdaptor::onRuntimeError(core::Errors& errors, std::string const errors.addError(core::ErrorCategory::RAMSES_LOGIC_RUNTIME, level, valueHandle, message); } - std::string LuaInterfaceAdaptor::generateRamsesObjectName() const { - auto prefabInstOuter = raco::core::PrefabOperations::findOuterContainingPrefabInstance(editorObject_); + auto prefabInstOuter = core::PrefabOperations::findOuterContainingPrefabInstance(editorObject_); if (prefabInstOuter) { if (prefabInstOuter == parent_) { return parent_->objectName() + "." + editorObject_->objectName(); @@ -120,12 +115,12 @@ bool LuaInterfaceAdaptor::sync(core::Errors* errors) { ObjectAdaptor::sync(errors); if (recreateStatus_) { - auto interfaceText = utils::file::read(raco::core::PathQueries::resolveUriPropertyToAbsolutePath(sceneAdaptor_->project(), {editorObject_, &user_types::LuaInterface::uri_})); + auto interfaceText = utils::file::read(core::PathQueries::resolveUriPropertyToAbsolutePath(sceneAdaptor_->project(), {editorObject_, &user_types::LuaInterface::uri_})); LOG_TRACE(log_system::RAMSES_ADAPTOR, "{}: {}", generateRamsesObjectName(), interfaceText); ramsesInterface_.reset(); - auto linksStarting = raco::core::Queries::getLinksConnectedToObject(sceneAdaptor_->project(), editorObject_, true, false); - auto linksEnding = raco::core::Queries::getLinksConnectedToObject(sceneAdaptor_->project(), editorObject_, false, true); + auto linksStarting = core::Queries::getLinksConnectedToObject(sceneAdaptor_->project(), editorObject_, true, false); + auto linksEnding = core::Queries::getLinksConnectedToObject(sceneAdaptor_->project(), editorObject_, false, true); bool validStartingLinks = std::any_of(linksStarting.begin(), linksStarting.end(), [](core::SLink link) { return link->isValid(); @@ -135,35 +130,32 @@ bool LuaInterfaceAdaptor::sync(core::Errors* errors) { }); if (!interfaceText.empty() && (!sceneAdaptor_->optimizeForExport() || validStartingLinks && !validEndingLinks)) { - - if (sceneAdaptor_->featureLevel() >= 5) { - std::vector modules; - auto luaConfig = raco::ramses_base::createLuaConfig(editorObject_->stdModules_->activeModules()); - if (!sceneAdaptor_->optimizeForExport()) { - luaConfig.enableDebugLogFunctions(); - } - const auto& moduleDeps = editorObject_->luaModules_.asTable(); - for (auto i = 0; i < moduleDeps.size(); ++i) { - if (auto moduleRef = moduleDeps.get(i)->asRef()) { - auto moduleAdaptor = sceneAdaptor_->lookup(moduleRef); - if (auto module = moduleAdaptor->module()) { - modules.emplace_back(module); - luaConfig.addDependency(moduleDeps.name(i), *module); - } + std::vector modules; + auto luaConfig = ramses_base::createLuaConfig(editorObject_->stdModules_->activeModules()); + if (!sceneAdaptor_->optimizeForExport()) { + luaConfig.enableDebugLogFunctions(); + } + const auto& moduleDeps = editorObject_->luaModules_.asTable(); + for (auto i = 0; i < moduleDeps.size(); ++i) { + if (auto moduleRef = moduleDeps.get(i)->asRef()) { + auto moduleAdaptor = sceneAdaptor_->lookup(moduleRef); + if (auto module = moduleAdaptor->module()) { + modules.emplace_back(module); + luaConfig.addDependency(moduleDeps.name(i), *module); } } - - ramsesInterface_ = raco::ramses_base::ramsesLuaInterface(&sceneAdaptor_->logicEngine(), interfaceText, luaConfig, modules, generateRamsesObjectName(), editorObject_->objectIDAsRamsesLogicID()); - } else { - ramsesInterface_ = raco::ramses_base::ramsesLuaInterface(&sceneAdaptor_->logicEngine(), interfaceText, generateRamsesObjectName(), editorObject_->objectIDAsRamsesLogicID()); } + + ramsesInterface_ = ramses_base::ramsesLuaInterface(&sceneAdaptor_->logicEngine(), interfaceText, luaConfig, modules, generateRamsesObjectName(), editorObject_->objectIDAsRamsesLogicID()); } } if (ramsesInterface_) { core::ValueHandle luaInputs{editorObject_, &user_types::LuaInterface::inputs_}; auto success = setLuaInputInEngine(ramsesInterface_->getInputs(), luaInputs); - LOG_WARNING_IF(log_system::RAMSES_ADAPTOR, !success, "Script set properties failed: {}", LogicEngineErrors{sceneAdaptor_->logicEngine()}); + if (!success) { + LOG_WARNING(log_system::RAMSES_ADAPTOR, "Script set properties failed: {}", sceneAdaptor_->scene()->getRamsesClient().getRamsesFramework().getLastError().value().message); + } } tagDirty(false); @@ -176,12 +168,12 @@ std::vector LuaInterfaceAdaptor::getExportInformation() const return {}; } - if (raco::core::Queries::getLinksConnectedToObject(sceneAdaptor_->project(), editorObject_, true, false).empty() || - !raco::core::Queries::getLinksConnectedToObject(sceneAdaptor_->project(), editorObject_, false, true).empty()) { + if (core::Queries::getLinksConnectedToObject(sceneAdaptor_->project(), editorObject_, true, false).empty() || + !core::Queries::getLinksConnectedToObject(sceneAdaptor_->project(), editorObject_, false, true).empty()) { return {}; } - return {ExportInformation{"LuaInterface", ramsesInterface_->getName().data()}}; + return {ExportInformation{"LuaInterface", ramsesInterface_->getName()}}; } } // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/src/ramses_adaptor/LuaScriptAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/LuaScriptAdaptor.cpp index e16b751b..b6333fed 100644 --- a/components/libRamsesBase/src/ramses_adaptor/LuaScriptAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/LuaScriptAdaptor.cpp @@ -12,7 +12,6 @@ #include "ramses_adaptor/LuaScriptModuleAdaptor.h" #include "ramses_adaptor/SceneAdaptor.h" #include "ramses_adaptor/utilities.h" -#include "ramses_base/LogicEngineFormatter.h" #include "ramses_base/Utils.h" #include "user_types/PrefabInstance.h" #include "utils/FileUtils.h" @@ -49,7 +48,7 @@ LuaScriptAdaptor::LuaScriptAdaptor(SceneAdaptor* sceneAdaptor, std::shared_ptr& logicNodes) const { +void LuaScriptAdaptor::getLogicNodes(std::vector& logicNodes) const { logicNodes.push_back(rlogicLuaScript()); } @@ -88,12 +87,12 @@ bool LuaScriptAdaptor::sync(core::Errors* errors) { ObjectAdaptor::sync(errors); if (recreateStatus_) { - auto scriptContent = utils::file::read(raco::core::PathQueries::resolveUriPropertyToAbsolutePath(sceneAdaptor_->project(), {editorObject_, &user_types::LuaScript::uri_})); + auto scriptContent = utils::file::read(core::PathQueries::resolveUriPropertyToAbsolutePath(sceneAdaptor_->project(), {editorObject_, &user_types::LuaScript::uri_})); LOG_TRACE(log_system::RAMSES_ADAPTOR, "{}: {}", generateRamsesObjectName(), scriptContent); luaScript_.reset(); if (!scriptContent.empty()) { - std::vector modules; - auto luaConfig = raco::ramses_base::createLuaConfig(editorObject_->stdModules_->activeModules()); + std::vector modules; + auto luaConfig = ramses_base::createLuaConfig(editorObject_->stdModules_->activeModules()); if (!sceneAdaptor_->optimizeForExport()) { luaConfig.enableDebugLogFunctions(); } @@ -107,14 +106,16 @@ bool LuaScriptAdaptor::sync(core::Errors* errors) { } } } - luaScript_ = raco::ramses_base::ramsesLuaScript(&sceneAdaptor_->logicEngine(), scriptContent, luaConfig, modules, generateRamsesObjectName(), editorObject_->objectIDAsRamsesLogicID()); + luaScript_ = ramses_base::ramsesLuaScript(&sceneAdaptor_->logicEngine(), scriptContent, luaConfig, modules, generateRamsesObjectName(), editorObject_->objectIDAsRamsesLogicID()); } } if (luaScript_) { core::ValueHandle luaInputs{editorObject_, &user_types::LuaScript::inputs_}; auto success = setLuaInputInEngine(luaScript_->getInputs(), luaInputs); - LOG_WARNING_IF(log_system::RAMSES_ADAPTOR, !success, "Script set properties failed: {}", LogicEngineErrors{sceneAdaptor_->logicEngine()}); + if (!success) { + LOG_WARNING(log_system::RAMSES_ADAPTOR, "Script set properties failed: {}", sceneAdaptor_->scene()->getRamsesClient().getRamsesFramework().getLastError().value().message); + } } tagDirty(false); @@ -129,9 +130,9 @@ void LuaScriptAdaptor::readDataFromEngine(core::DataChangeRecorder &recorder) { } } -const rlogic::Property* LuaScriptAdaptor::getProperty(const std::vector& names) { +ramses::Property* LuaScriptAdaptor::getProperty(const std::vector& names) { if (luaScript_ && names.size() >= 1) { - const rlogic::Property* prop{names.at(0) == "inputs" ? luaScript_->getInputs() : luaScript_->getOutputs()}; + ramses::Property* prop{names.at(0) == "inputs" ? luaScript_->getInputs() : luaScript_->getOutputs()}; return ILogicPropertyProvider::getPropertyRecursive(prop, names, 1); } return nullptr; @@ -150,7 +151,7 @@ std::vector LuaScriptAdaptor::getExportInformation() const { return {}; } - return {ExportInformation{"LuaScript", luaScript_->getName().data()}}; + return {ExportInformation{"LuaScript", luaScript_->getName()}}; } } // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/src/ramses_adaptor/LuaScriptModuleAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/LuaScriptModuleAdaptor.cpp index bb347afc..5082e9ac 100644 --- a/components/libRamsesBase/src/ramses_adaptor/LuaScriptModuleAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/LuaScriptModuleAdaptor.cpp @@ -11,13 +11,12 @@ #include "ramses_adaptor/SceneAdaptor.h" #include "ramses_adaptor/utilities.h" -#include "ramses_base/LogicEngineFormatter.h" #include "user_types/PrefabInstance.h" #include "utils/FileUtils.h" namespace raco::ramses_adaptor { -LuaScriptModuleAdaptor::LuaScriptModuleAdaptor(SceneAdaptor* sceneAdaptor, raco::user_types::SLuaScriptModule editorObject) +LuaScriptModuleAdaptor::LuaScriptModuleAdaptor(SceneAdaptor* sceneAdaptor, user_types::SLuaScriptModule editorObject) : UserTypeObjectAdaptor{sceneAdaptor, editorObject}, nameSubscription_{sceneAdaptor_->dispatcher()->registerOn({editorObject_, &user_types::LuaScriptModule::objectName_}, [this]() { tagDirty(); @@ -35,11 +34,11 @@ bool LuaScriptModuleAdaptor::sync(core::Errors* errors) { if (editorObject_->isValid()) { const auto& scriptContents = editorObject_->currentScriptContents(); - auto luaConfig = raco::ramses_base::createLuaConfig(editorObject_->stdModules_->activeModules()); + auto luaConfig = ramses_base::createLuaConfig(editorObject_->stdModules_->activeModules()); if (!sceneAdaptor_->optimizeForExport()) { luaConfig.enableDebugLogFunctions(); } - module_ = raco::ramses_base::ramsesLuaModule(scriptContents, &sceneAdaptor_->logicEngine(), luaConfig, editorObject_->objectName(), editorObject_->objectIDAsRamsesLogicID()); + module_ = ramses_base::ramsesLuaModule(scriptContents, &sceneAdaptor_->logicEngine(), luaConfig, editorObject_->objectName(), editorObject_->objectIDAsRamsesLogicID()); assert(module_ != nullptr); } else { module_.reset(); @@ -58,7 +57,7 @@ std::vector LuaScriptModuleAdaptor::getExportInformation() co return {}; } - return {ExportInformation{"LuaScriptModule", module_->getName().data()}}; + return {ExportInformation{"LuaScriptModule", module_->getName()}}; } } // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/src/ramses_adaptor/MaterialAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/MaterialAdaptor.cpp index 35dc29d1..ae1b43b9 100644 --- a/components/libRamsesBase/src/ramses_adaptor/MaterialAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/MaterialAdaptor.cpp @@ -18,6 +18,7 @@ #include "ramses_adaptor/SceneAdaptor.h" #include "ramses_adaptor/TextureExternalAdaptor.h" #include "ramses_adaptor/TextureSamplerAdaptor.h" +#include "ramses_adaptor/utilities.h" #include "ramses_base/Utils.h" #include "user_types/Material.h" #include "user_types/RenderBuffer.h" @@ -38,11 +39,11 @@ constexpr const char* emptyFragmentShader = precision mediump float;\n\ void main() {}"; -raco::ramses_base::RamsesEffect MaterialAdaptor::createEffect(SceneAdaptor* sceneAdaptor) { +ramses_base::RamsesEffect MaterialAdaptor::createEffect(SceneAdaptor* sceneAdaptor) { ramses::EffectDescription effectDescription{}; effectDescription.setVertexShader(emptyVertexShader); effectDescription.setFragmentShader(emptyFragmentShader); - return raco::ramses_base::ramsesEffect(sceneAdaptor->scene(), effectDescription); + return ramses_base::ramsesEffect(sceneAdaptor->scene(), effectDescription, {}, {0, 0}); } MaterialAdaptor::MaterialAdaptor(SceneAdaptor* sceneAdaptor, user_types::SMaterial material) @@ -65,7 +66,7 @@ bool MaterialAdaptor::isValid() { bool MaterialAdaptor::sync(core::Errors* errors) { errors->removeIf([this](core::ErrorItem const& error) { auto handle = error.valueHandle(); - auto uniformsHandle = raco::core::ValueHandle(editorObject(), &raco::user_types::Material::uniforms_); + auto uniformsHandle = core::ValueHandle(editorObject(), &user_types::Material::uniforms_); return uniformsHandle.contains(handle); }); @@ -78,40 +79,40 @@ bool MaterialAdaptor::sync(core::Errors* errors) { std::string const vertexShader{user_types::Material::loadShader(sceneAdaptor_->project(), {editorObject(), &user_types::Material::uriVertex_})}; std::string const fragmentShader{user_types::Material::loadShader(sceneAdaptor_->project(), {editorObject(), &user_types::Material::uriFragment_})}; std::string const geometryShader{user_types::Material::loadShader(sceneAdaptor_->project(), {editorObject(), &user_types::Material::uriGeometry_})}; - std::string const shaderDefines = utils::file::read(raco::core::PathQueries::resolveUriPropertyToAbsolutePath(sceneAdaptor_->project(), {editorObject(), &user_types::Material::uriDefines_})); - auto const effectDescription = raco::ramses_base::createEffectDescription(vertexShader, geometryShader, fragmentShader, shaderDefines); - reset(raco::ramses_base::ramsesEffect(sceneAdaptor_->scene(), *effectDescription)); + std::string const shaderDefines = utils::file::read(core::PathQueries::resolveUriPropertyToAbsolutePath(sceneAdaptor_->project(), {editorObject(), &user_types::Material::uriDefines_})); + auto const effectDescription = ramses_base::createEffectDescription(vertexShader, geometryShader, fragmentShader, shaderDefines); + reset(ramses_base::ramsesEffect(sceneAdaptor_->scene(), *effectDescription, {}, editorObject_->objectIDAsRamsesLogicID())); } else { reset(createEffect(sceneAdaptor_)); } - appearance_ = raco::ramses_base::ramsesAppearance(sceneAdaptor_->scene(), getRamsesObjectPointer()); + appearance_ = ramses_base::ramsesAppearance(sceneAdaptor_->scene(), getRamsesObjectPointer(), editorObject_->objectIDAsRamsesLogicID()); (*appearance_)->setName(std::string(this->editorObject()->objectName() + "_Appearance").c_str()); // Only create appearance binding and set uniforms & blend options if we are using a valid shader but not if // we are using the empty default shaders. if (editorObject()->isShaderValid()) { + appearanceBinding_ = ramses_base::ramsesAppearanceBinding(*appearance_->get(), &sceneAdaptor_->logicEngine(), editorObject()->objectName() + "_AppearanceBinding", editorObject_->objectIDAsRamsesLogicID()); + core::ValueHandle optionsHandle = {editorObject(), &user_types::Material::options_}; core::ValueHandle uniformsHandle = {editorObject(), &user_types::Material::uniforms_}; - updateAppearance(errors, sceneAdaptor_, appearance_, optionsHandle, uniformsHandle); - - appearanceBinding_ = raco::ramses_base::ramsesAppearanceBinding(*appearance_->get(), &sceneAdaptor_->logicEngine(), editorObject()->objectName() + "_AppearanceBinding", editorObject_->objectIDAsRamsesLogicID()); + updateAppearance(errors, sceneAdaptor_, appearance_, *editorObject()->options_, optionsHandle, uniformsHandle); } tagDirty(false); return true; } -void MaterialAdaptor::getLogicNodes(std::vector& logicNodes) const { +void MaterialAdaptor::getLogicNodes(std::vector& logicNodes) const { if (appearanceBinding_) { logicNodes.push_back(appearanceBinding_.get()); } } -const rlogic::Property* MaterialAdaptor::getProperty(const std::vector& names) { +ramses::Property* MaterialAdaptor::getProperty(const std::vector& names) { if (appearanceBinding_ && names.size() > 1 && names[0] == "uniforms") { - auto ramsesPropNames = ramses_base::getRamsesUniformPropertyNames(core::ValueHandle(editorObject(), &raco::user_types::Material::uniforms_), names, 1); - return ILogicPropertyProvider::getPropertyRecursive(appearanceBinding_->getInputs(), ramsesPropNames, 0); + auto ramsesPropNames = ramses_base::getRamsesUniformPropertyNames(core::ValueHandle(editorObject(), &user_types::Material::uniforms_), names, 1); + return ILogicPropertyProvider::getPropertyRecursive(appearanceBinding_->getInputs(), {ramsesPropNames.begin(), ramsesPropNames.end()}, 0); } return nullptr; } @@ -134,165 +135,104 @@ std::vector MaterialAdaptor::getExportInformation() const { } if (appearanceBinding_ != nullptr) { - result.emplace_back("AppearanceBinding", appearanceBinding_->getName().data()); + result.emplace_back("AppearanceBinding", appearanceBinding_->getName()); } return result; } -template -std::vector flattenUniformArrayOfVector(const core::ValueHandle& handle, int numComponents) { - std::vector values; +template +std::vector getArrayData(const core::ValueHandle& handle) { + std::vector result; for (size_t index = 0; index < handle.size(); index++) { - for (size_t component = 0; component < numComponents; component++) { - values.emplace_back(handle[index][component].as()); - } + result.emplace_back(RamsesType(handle[index].as())); } - return values; + return result; } inline void setUniform(core::Errors* errors, SceneAdaptor* sceneAdaptor, ramses::Appearance* appearance, const core::ValueHandle& valueHandle, const std::string& uniformEngineName, - std::vector newSamplers, - std::vector newSamplersMS, - std::vector newSamplersExternal) { - - ramses::UniformInput input; - appearance->getEffect().findUniformInput(uniformEngineName.c_str(), input); + std::vector newSamplers, + std::vector newSamplersMS, + std::vector newSamplersExternal) { - auto engineTypeAnno = valueHandle.query(); + ramses::UniformInput input = appearance->getEffect().findUniformInput(uniformEngineName.c_str()).value(); + + auto engineTypeAnno = valueHandle.query(); switch (engineTypeAnno->type()) { + case core::EnginePrimitive::Bool: + appearance->setInputValue(input, valueHandle.as()); + break; + case core::EnginePrimitive::Double: - appearance->setInputValueFloat(input, valueHandle.as()); + appearance->setInputValue(input, valueHandle.as()); break; case core::EnginePrimitive::Int32: case core::EnginePrimitive::UInt16: case core::EnginePrimitive::UInt32: - appearance->setInputValueInt32(input, static_cast(valueHandle.as())); + appearance->setInputValue(input, static_cast(valueHandle.as())); break; case core::EnginePrimitive::Vec2f: - appearance->setInputValueVector2f(input, valueHandle[0].as(), valueHandle[1].as()); + appearance->setInputValue(input, ramses::vec2f(valueHandle[0].as(), valueHandle[1].as())); break; case core::EnginePrimitive::Vec3f: - appearance->setInputValueVector3f(input, valueHandle[0].as(), valueHandle[1].as(), valueHandle[2].as()); + appearance->setInputValue(input, ramses::vec3f(valueHandle[0].as(), valueHandle[1].as(), valueHandle[2].as())); break; case core::EnginePrimitive::Vec4f: - appearance->setInputValueVector4f(input, valueHandle[0].as(), valueHandle[1].as(), valueHandle[2].as(), valueHandle[3].as()); + appearance->setInputValue(input, ramses::vec4f(valueHandle[0].as(), valueHandle[1].as(), valueHandle[2].as(), valueHandle[3].as())); break; case core::EnginePrimitive::Vec2i: - appearance->setInputValueVector2i(input, static_cast(valueHandle[0].as()), static_cast(valueHandle[1].as())); + appearance->setInputValue(input, ramses::vec2i(valueHandle[0].as(), valueHandle[1].as())); break; case core::EnginePrimitive::Vec3i: - appearance->setInputValueVector3i(input, static_cast(valueHandle[0].as()), static_cast(valueHandle[1].as()), static_cast(valueHandle[2].as())); + appearance->setInputValue(input, ramses::vec3i(valueHandle[0].as(), valueHandle[1].as(), valueHandle[2].as())); break; case core::EnginePrimitive::Vec4i: - appearance->setInputValueVector4i(input, static_cast(valueHandle[0].as()), static_cast(valueHandle[1].as()), static_cast(valueHandle[2].as()), static_cast(valueHandle[3].as())); + appearance->setInputValue(input, ramses::vec4i(valueHandle[0].as(), valueHandle[1].as(), valueHandle[2].as(), valueHandle[3].as())); break; - case core::EnginePrimitive::Array: { - assert(valueHandle.size() >= 1); - - auto elementAnno = valueHandle[0].query(); - switch (elementAnno->type()) { - case core::EnginePrimitive::Double: { - std::vector values; - for (size_t index = 0; index < valueHandle.size(); index++) { - values.emplace_back(valueHandle[index].as()); - } - appearance->setInputValueFloat(input, values.size(), values.data()); - break; - } - - case core::EnginePrimitive::Int32: - case core::EnginePrimitive::UInt16: - case core::EnginePrimitive::UInt32: { - std::vector values; - for (size_t index = 0; index < valueHandle.size(); index++) { - values.emplace_back(valueHandle[index].as()); - } - appearance->setInputValueInt32(input, values.size(), values.data()); - break; - } - - case core::EnginePrimitive::Vec2f: { - auto values{flattenUniformArrayOfVector(valueHandle, 2)}; - appearance->setInputValueVector2f(input, valueHandle.size(), values.data()); - break; - } - - case core::EnginePrimitive::Vec3f: { - auto values{flattenUniformArrayOfVector(valueHandle, 3)}; - appearance->setInputValueVector3f(input, valueHandle.size(), values.data()); - break; - } - - case core::EnginePrimitive::Vec4f: { - auto values{flattenUniformArrayOfVector(valueHandle, 4)}; - appearance->setInputValueVector4f(input, valueHandle.size(), values.data()); - break; - } - - case core::EnginePrimitive::Vec2i: { - auto values{flattenUniformArrayOfVector(valueHandle, 2)}; - appearance->setInputValueVector2i(input, valueHandle.size(), values.data()); - break; - } - - case core::EnginePrimitive::Vec3i: { - auto values{flattenUniformArrayOfVector(valueHandle, 3)}; - appearance->setInputValueVector3i(input, valueHandle.size(), values.data()); - break; - } - - case core::EnginePrimitive::Vec4i: { - auto values{flattenUniformArrayOfVector(valueHandle, 4)}; - appearance->setInputValueVector4i(input, valueHandle.size(), values.data()); - break; - } - - default: - break; - } - } break; + case core::EnginePrimitive::Array: + // no-op since arrays of primitive type are now set via the binding, see setUniformRecursive below. + break; - case raco::core::EnginePrimitive::TextureSampler2DMS: { + case core::EnginePrimitive::TextureSampler2DMS: { if (auto buffer = valueHandle.asTypedRef()) { if (auto adaptor = sceneAdaptor->lookup(buffer)) { if (auto samplerMS = adaptor->getRamsesObjectPointer()) { appearance->setInputTexture(input, *samplerMS); newSamplersMS.emplace_back(samplerMS); } else { - errors->addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::ERROR, valueHandle, "Sampler for this RenderBufferMS not available."); + errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, valueHandle, "Sampler for this RenderBufferMS not available."); } } } else { - errors->addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::ERROR, valueHandle, "RenderBufferMS needed for this uniform."); + errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, valueHandle, "RenderBufferMS needed for this uniform."); } } break; - case raco::core::EnginePrimitive::TextureSamplerExternal: { + case core::EnginePrimitive::TextureSamplerExternal: { if (auto texture = valueHandle.asTypedRef()) { if (auto adaptor = sceneAdaptor->lookup(texture)) { if (auto sampler = adaptor->getRamsesObjectPointer()) { appearance->setInputTexture(input, *sampler); newSamplersExternal.emplace_back(sampler); } else { - errors->addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::ERROR, valueHandle, "Sampler for this TextureExternal not available."); + errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, valueHandle, "Sampler for this TextureExternal not available."); } } } else { - errors->addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::ERROR, valueHandle, "TextureExternal needed for this uniform."); + errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, valueHandle, "TextureExternal needed for this uniform."); } } break; - case raco::core::EnginePrimitive::TextureSampler2D: { - raco::ramses_base::RamsesTextureSampler sampler = nullptr; + case core::EnginePrimitive::TextureSampler2D: { + ramses_base::RamsesTextureSampler sampler = nullptr; if (auto texture = valueHandle.asTypedRef()) { if (auto adaptor = sceneAdaptor->lookup(texture)) { sampler = adaptor->getRamsesObjectPointer(); @@ -301,11 +241,11 @@ inline void setUniform(core::Errors* errors, SceneAdaptor* sceneAdaptor, ramses: if (auto adaptor = sceneAdaptor->lookup(buffer)) { sampler = adaptor->getRamsesObjectPointer(); if (!sampler) { - errors->addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::ERROR, valueHandle, "Sampler for this RenderBuffer not available."); + errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, valueHandle, "Sampler for this RenderBuffer not available."); } } } else { - errors->addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::ERROR, valueHandle, "Texture or RenderBuffer needed for this uniform."); + errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, valueHandle, "Texture or RenderBuffer needed for this uniform."); } if (sampler) { appearance->setInputTexture(input, *sampler); @@ -313,7 +253,7 @@ inline void setUniform(core::Errors* errors, SceneAdaptor* sceneAdaptor, ramses: } } break; - case raco::core::EnginePrimitive::TextureSamplerCube: { + case core::EnginePrimitive::TextureSamplerCube: { if (auto texture = valueHandle.asTypedRef()) { if (auto adaptor = sceneAdaptor->lookup(texture)) { if (auto sampler = adaptor->getRamsesObjectPointer()) { @@ -322,7 +262,7 @@ inline void setUniform(core::Errors* errors, SceneAdaptor* sceneAdaptor, ramses: } } } else { - errors->addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::ERROR, valueHandle, "CubeMap needed for this uniform."); + errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, valueHandle, "CubeMap needed for this uniform."); } } break; @@ -332,9 +272,9 @@ inline void setUniform(core::Errors* errors, SceneAdaptor* sceneAdaptor, ramses: } inline void setUniformRecursive(core::Errors* errors, SceneAdaptor* sceneAdaptor, ramses::Appearance* appearance, const core::ValueHandle& uniformContainerHandle, const core::ValueHandle& handle, - std::vector newSamplers, - std::vector newSamplersMS, - std::vector newSamplersExternal) { + std::vector newSamplers, + std::vector newSamplersMS, + std::vector newSamplersExternal) { auto engineTypeAnno = handle.query(); switch (engineTypeAnno->type()) { case core::EnginePrimitive::Struct: @@ -350,7 +290,11 @@ inline void setUniformRecursive(core::Errors* errors, SceneAdaptor* sceneAdaptor setUniformRecursive(errors, sceneAdaptor, appearance, uniformContainerHandle, handle[index], newSamplers, newSamplersMS, newSamplersExternal); } } else { - setUniform(errors, sceneAdaptor, appearance, handle, ramses_base::getRamsesUniformPropertyName(uniformContainerHandle, handle), newSamplers, newSamplersMS, newSamplersExternal); + // uniform arrays of primitive type must be set via the AppearanceBinding since the binding + // will perform an atomic update of the entire array if even a single array element changed by a link. + auto adaptor = sceneAdaptor->lookupAdaptor(handle.rootObject()); + auto prop = dynamic_cast(adaptor)->getProperty(handle.getPropertyNamesVector()); + setLuaInputInEngine(prop, handle); } } break; @@ -360,56 +304,68 @@ inline void setUniformRecursive(core::Errors* errors, SceneAdaptor* sceneAdaptor } } -void updateAppearance(core::Errors* errors, SceneAdaptor* sceneAdaptor, raco::ramses_base::RamsesAppearance appearance, const core::ValueHandle& optionsHandle, const core::ValueHandle& uniformsHandle) { - auto colorOp = static_cast(optionsHandle.get("blendOperationColor").as()); - auto alphaOp = static_cast(optionsHandle.get("blendOperationAlpha").as()); +void updateAppearance(core::Errors* errors, SceneAdaptor* sceneAdaptor, ramses_base::RamsesAppearance appearance, user_types::BlendOptions& options, const core::ValueHandle& optionsHandle, const core::ValueHandle& uniformsHandle) { + auto colorOp = static_cast(*options.blendOperationColor_); + auto alphaOp = static_cast(*options.blendOperationAlpha_); if (colorOp == user_types::EBlendOperation::Disabled && alphaOp != user_types::EBlendOperation::Disabled) { - errors->addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::ERROR, optionsHandle.get("blendOperationAlpha"), + errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, optionsHandle.get("blendOperationAlpha"), "Inconsistent Blend Operation settings: Color disabled while Alpha is not."); } else { errors->removeError(optionsHandle.get("blendOperationAlpha")); } if (colorOp != user_types::EBlendOperation::Disabled && alphaOp == user_types::EBlendOperation::Disabled) { - errors->addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::ERROR, optionsHandle.get("blendOperationColor"), + errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, optionsHandle.get("blendOperationColor"), "Inconsistent Blend Operation settings: Alpha disabled while Color is not."); } else { errors->removeError(optionsHandle.get("blendOperationColor")); } - setDepthWrite(appearance->get(), optionsHandle.get("depthwrite")); - setDepthFunction(appearance->get(), optionsHandle.get("depthFunction")); - setBlendMode(appearance->get(), optionsHandle); - setBlendColor(appearance->get(), optionsHandle.get("blendColor")); - setCullMode(appearance->get(), optionsHandle.get("cullmode")); + (*appearance)->setDepthWrite(*options.depthwrite_ ? ramses::EDepthWrite::Enabled : ramses::EDepthWrite::Disabled); + auto ramsesDepthFunc = ramses_base::enumerationTranslationsDepthFunc.at(static_cast(*options.depthFunction_)); + (*appearance)->setDepthFunction(ramsesDepthFunc); - auto stencilOptionsHandle = optionsHandle.get("stencilOptions"); - (*appearance)->setStencilFunction( - static_cast(stencilOptionsHandle.get("stencilFunc").asInt()), - std::clamp(stencilOptionsHandle.get("stencilRef").asInt(), 0, 255), - std::clamp(stencilOptionsHandle.get("stencilMask").asInt(), 0, 255)); + auto ramsesColorOp = ramses_base::enumerationTranslationsBlendOperation.at(static_cast(*options.blendOperationColor_)); + auto ramsesAlphaOp = ramses_base::enumerationTranslationsBlendOperation.at(static_cast(*options.blendOperationAlpha_)); + (*appearance)->setBlendingOperations(ramsesColorOp, ramsesAlphaOp); + auto ramsesSrcColor = ramses_base::enumerationTranslationsBlendFactor.at(static_cast(*options.blendFactorSrcColor_)); + auto ramsesDestColor = ramses_base::enumerationTranslationsBlendFactor.at(static_cast(*options.blendFactorDestColor_)); + auto ramsesSrcAlpha = ramses_base::enumerationTranslationsBlendFactor.at(static_cast(*options.blendFactorSrcAlpha_)); + auto ramsesDestAlpha = ramses_base::enumerationTranslationsBlendFactor.at(static_cast(*options.blendFactorDestAlpha_)); + (*appearance)->setBlendingFactors(ramsesSrcColor, ramsesDestColor, ramsesSrcAlpha, ramsesDestAlpha); + + (*appearance)->setBlendingColor(ramses::vec4f(*options.blendColor_->x, *options.blendColor_->y, *options.blendColor_->z, *options.blendColor_->w)); + + auto ramsesCullMode = ramses_base::enumerationTranslationsCullMode.at(static_cast(*options.cullmode_)); + (*appearance)->setCullingMode(ramsesCullMode); + + const auto& stencilOptions = *options.stencilOptions_; + (*appearance)->setStencilFunction( + static_cast(*stencilOptions.stencilFunc_), + std::clamp(*stencilOptions.stencilRef_, 0, 255), + std::clamp(*stencilOptions.stencilMask_, 0, 255)); (*appearance)->setStencilOperation( - static_cast(stencilOptionsHandle.get("stencilOpStencilFail").asInt()), - static_cast(stencilOptionsHandle.get("stencilOpDepthFail").asInt()), - static_cast(stencilOptionsHandle.get("stencilOpDepthSucc").asInt())); + static_cast(*stencilOptions.stencilOpStencilFail_), + static_cast(*stencilOptions.stencilOpDepthFail_), + static_cast(*stencilOptions.stencilOpDepthSucc_)); - auto scissorOptionsHandle = optionsHandle.get("scissorOptions"); + const auto& scissorOptions = *options.scissorOptions_; (*appearance)->setScissorTest( - (scissorOptionsHandle.get("scissorEnable").asBool() ? ramses::EScissorTest_Enabled : ramses::EScissorTest_Disabled), - scissorOptionsHandle.get("scissorRegion").get("offsetX").asInt(), - scissorOptionsHandle.get("scissorRegion").get("offsetY").asInt(), - scissorOptionsHandle.get("scissorRegion").get("width").asInt(), - scissorOptionsHandle.get("scissorRegion").get("height").asInt()); + (*scissorOptions.scissorEnable_ ? ramses::EScissorTest::Enabled : ramses::EScissorTest::Disabled), + *scissorOptions.scissorRegion_->offsetX_, + *scissorOptions.scissorRegion_->offsetY_, + *scissorOptions.scissorRegion_->width_, + *scissorOptions.scissorRegion_->height_); (*appearance)->setColorWriteMask( - optionsHandle.get("colorWriteMask").get("red").asBool(), - optionsHandle.get("colorWriteMask").get("green").asBool(), - optionsHandle.get("colorWriteMask").get("blue").asBool(), - optionsHandle.get("colorWriteMask").get("alpha").asBool()); - - std::vector newSamplers; - std::vector newSamplersMS; - std::vector newSamplersExternal; + *options.colorWriteMask_->red_, + *options.colorWriteMask_->green_, + *options.colorWriteMask_->blue_, + *options.colorWriteMask_->alpha_); + + std::vector newSamplers; + std::vector newSamplersMS; + std::vector newSamplersExternal; for (size_t i{0}; i < uniformsHandle.size(); i++) { setUniformRecursive(errors, sceneAdaptor, appearance->get(), uniformsHandle, uniformsHandle[i], newSamplers, newSamplersMS, newSamplersExternal); diff --git a/components/libRamsesBase/src/ramses_adaptor/MeshAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/MeshAdaptor.cpp index b423efd4..d5ff1bc9 100644 --- a/components/libRamsesBase/src/ramses_adaptor/MeshAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/MeshAdaptor.cpp @@ -30,7 +30,7 @@ MeshAdaptor::MeshAdaptor(SceneAdaptor* sceneAdaptor, user_types::SMesh mesh) })} { } -raco::ramses_base::RamsesArrayResource MeshAdaptor::indicesPtr() { +ramses_base::RamsesArrayResource MeshAdaptor::indicesPtr() { return indices_; } @@ -48,17 +48,12 @@ bool MeshAdaptor::sync(core::Errors* errors) { if (isValid()) { auto mesh = editorObject_->meshData(); auto indices = mesh->getIndices(); - indices_ = ramsesArrayResource(sceneAdaptor_->scene(), ramses::EDataType::UInt32, static_cast(indices.size()), indices.data()); - indices_->setName(std::string(this->editorObject_->objectName() + "_MeshIndexData").c_str()); - + indices_ = ramsesArrayResource(sceneAdaptor_->scene(), indices, std::string(this->editorObject_->objectName() + "_MeshIndexData").c_str()); for (uint32_t i{0}; i < mesh->numAttributes(); i++) { auto name = mesh->attribName(i); - auto type = mesh->attribDataType(i); - auto buffer = mesh->attribBuffer(i); - auto elementCount = mesh->attribElementCount(i); - vertexDataMap_[name] = ramsesArrayResource(sceneAdaptor_->scene(), convert(type), elementCount, buffer); - vertexDataMap_[name]->setName(std::string(this->editorObject_->objectName() + "_MeshVertexData_" + name).c_str()); + std::string attribName = this->editorObject_->objectName() + "_MeshVertexData_" + name; + vertexDataMap_[name] = arrayResourceFromAttribute(sceneAdaptor_->scene(), mesh, i, attribName); } } else { vertexDataMap_.clear(); @@ -78,7 +73,7 @@ std::vector MeshAdaptor::getExportInformation() const { result.emplace_back(indices_.get()->getType(), indices_->getName()); for (const auto& item : vertexDataMap_) { - result.emplace_back(ramses::ERamsesObjectType_ArrayResource, item.second->getName()); + result.emplace_back(ramses::ERamsesObjectType::ArrayResource, item.second->getName()); } return result; diff --git a/components/libRamsesBase/src/ramses_adaptor/MeshNodeAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/MeshNodeAdaptor.cpp index c1393e0e..b03f1d42 100644 --- a/components/libRamsesBase/src/ramses_adaptor/MeshNodeAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/MeshNodeAdaptor.cpp @@ -18,7 +18,7 @@ namespace raco::ramses_adaptor { MeshNodeAdaptor::MeshNodeAdaptor(SceneAdaptor* sceneAdaptor, user_types::SMeshNode node) - : SpatialAdaptor{sceneAdaptor, node, raco::ramses_base::ramsesMeshNode(sceneAdaptor->scene())}, + : SpatialAdaptor{sceneAdaptor, node, ramses_base::ramsesMeshNode(sceneAdaptor->scene(), node->objectIDAsRamsesLogicID())}, meshSubscription_{ sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{node, &user_types::MeshNode::mesh_}, [this]() { tagDirty(); @@ -105,11 +105,11 @@ MaterialAdaptor* MeshNodeAdaptor::materialAdaptor(size_t index) { return nullptr; } -const raco::ramses_base::RamsesAppearance& MeshNodeAdaptor::privateAppearance() const { +const ramses_base::RamsesAppearance& MeshNodeAdaptor::privateAppearance() const { return privateAppearance_; } -const raco::ramses_base::RamsesAppearanceBinding& MeshNodeAdaptor::appearanceBinding() const { +const ramses_base::RamsesAppearanceBinding& MeshNodeAdaptor::appearanceBinding() const { return appearanceBinding_; } @@ -117,7 +117,7 @@ const raco::ramses_base::RamsesAppearanceBinding& MeshNodeAdaptor::appearanceBin bool MeshNodeAdaptor::sync(core::Errors* errors) { errors->removeIf([this](core::ErrorItem const& error) { auto handle = error.valueHandle(); - auto materialsHandle = raco::core::ValueHandle(editorObject(), &raco::user_types::MeshNode::materials_); + auto materialsHandle = core::ValueHandle(editorObject(), &user_types::MeshNode::materials_); return materialsHandle.contains(handle); }); @@ -129,9 +129,7 @@ bool MeshNodeAdaptor::sync(core::Errors* errors) { syncMaterials(errors); syncMeshObject(); - if (sceneAdaptor_->featureLevel() >= rlogic::EFeatureLevel::EFeatureLevel_05) { - meshNodeBinding_ = ramses_base::ramsesMeshNodeBinding(getRamsesObjectPointer(), &sceneAdaptor_->logicEngine(), editorObject()->objectName() + "_MeshNodeBinding" , editorObject()->objectIDAsRamsesLogicID()); - } + meshNodeBinding_ = ramses_base::ramsesMeshNodeBinding(getRamsesObjectPointer(), &sceneAdaptor_->logicEngine(), editorObject()->objectName() + "_MeshNodeBinding" , editorObject()->objectIDAsRamsesLogicID()); tagDirty(false); return true; @@ -152,30 +150,31 @@ void MeshNodeAdaptor::syncMaterial(core::Errors* errors, size_t index) { if (vertexData.find("a_Normal") != vertexData.end()) { haveMeshNormals = true; } + } else { + haveMeshNormals = true; } appearanceBinding_.reset(); privateAppearance_.reset(); if (auto materialAdapt = materialAdaptor(index)) { - LOG_TRACE(raco::log_system::RAMSES_ADAPTOR, "using materialAdaptor (valid)"); + LOG_TRACE(log_system::RAMSES_ADAPTOR, "using materialAdaptor (valid)"); if (editorObject()->materialPrivate(index)) { - privateAppearance_ = raco::ramses_base::ramsesAppearance(sceneAdaptor_->scene(), materialAdapt->getRamsesObjectPointer()); + privateAppearance_ = ramses_base::ramsesAppearance(sceneAdaptor_->scene(), materialAdapt->getRamsesObjectPointer(), editorObject_->objectIDAsRamsesLogicID()); currentAppearance_ = privateAppearance_; + appearanceBinding_ = ramses_base::ramsesAppearanceBinding(*privateAppearance_->get(), &sceneAdaptor_->logicEngine(), editorObject()->objectName() + "_AppearanceBinding", editorObject_->objectIDAsRamsesLogicID()); + core::ValueHandle optionsHandle = editorObject()->getMaterialOptionsHandle(index); core::ValueHandle uniformsHandle = editorObject()->getUniformContainerHandle(index); - updateAppearance(errors, sceneAdaptor_, privateAppearance_, optionsHandle, uniformsHandle); + updateAppearance(errors, sceneAdaptor_, privateAppearance_, *editorObject()->getOptions(index), optionsHandle, uniformsHandle); (*privateAppearance_)->setName(std::string(this->editorObject()->objectName() + "_Appearance").c_str()); - - appearanceBinding_ = raco::ramses_base::ramsesAppearanceBinding(*privateAppearance_->get(), &sceneAdaptor_->logicEngine(), editorObject()->objectName() + "_AppearanceBinding", editorObject_->objectIDAsRamsesLogicID()); - } else { currentAppearance_ = materialAdapt->appearance(); } } else { - LOG_TRACE(raco::log_system::RAMSES_ADAPTOR, "using materialAdaptor (invalid)"); + LOG_TRACE(log_system::RAMSES_ADAPTOR, "using materialAdaptor (invalid)"); currentAppearance_ = sceneAdaptor_->defaultAppearance(haveMeshNormals); } @@ -183,40 +182,43 @@ void MeshNodeAdaptor::syncMaterial(core::Errors* errors, size_t index) { } void MeshNodeAdaptor::syncMeshObject() { - auto geometryBinding = raco::ramses_base::ramsesGeometryBinding(sceneAdaptor_->scene(), currentAppearance_->effect()); - (*geometryBinding)->setName(std::string(this->editorObject()->objectName() + "_GeometryBinding").c_str()); + auto geometry = ramses_base::ramsesGeometry(sceneAdaptor_->scene(), currentAppearance_->effect(), editorObject()->objectIDAsRamsesLogicID()); + (*geometry)->setName(std::string(this->editorObject()->objectName() + "_Geometry").c_str()); if (MeshAdaptor* meshAdapt = meshAdaptor()) { - LOG_TRACE(raco::log_system::RAMSES_ADAPTOR, "using meshAdaptor"); + LOG_TRACE(log_system::RAMSES_ADAPTOR, "using meshAdaptor"); auto vertexData = meshAdapt->vertexData(); for (uint32_t i = 0; i < currentAppearance_->effect()->getAttributeInputCount(); i++) { - ramses::AttributeInput attribInput; - currentAppearance_->effect()->getAttributeInput(i, attribInput); + ramses::AttributeInput attribInput = currentAppearance_->effect()->getAttributeInput(i).value(); std::string attribName = attribInput.getName(); auto it = vertexData.find(attribName); if (it != vertexData.end()) { - geometryBinding->addAttributeBuffer(attribInput, it->second); + geometry->addAttributeBuffer(attribInput, it->second); } else { - LOG_ERROR(raco::log_system::RAMSES_ADAPTOR, "Attrribute mismatch in MeshNode '{}': attribute '{}' required by Material '{}' not found in Mesh '{}'.", editorObject()->objectName(), attribName, material(0)->objectName(), mesh()->objectName()); + LOG_ERROR(log_system::RAMSES_ADAPTOR, "Attrribute mismatch in MeshNode '{}': attribute '{}' required by Material '{}' not found in Mesh '{}'.", editorObject()->objectName(), attribName, material(0)->objectName(), mesh()->objectName()); } } - geometryBinding->setIndices(meshAdapt->indicesPtr()); + geometry->setIndices(meshAdapt->indicesPtr()); } else { - LOG_TRACE(raco::log_system::RAMSES_ADAPTOR, "using defaultMesh"); - ramses::AttributeInput input; - (*currentAppearance_)->getEffect().findAttributeInput("a_Position", input); - geometryBinding->addAttributeBuffer(input, sceneAdaptor_->defaultVertices()); - geometryBinding->setIndices(sceneAdaptor_->defaultIndices()); + LOG_TRACE(log_system::RAMSES_ADAPTOR, "using defaultMesh"); + int index = *editorObject()->instanceCount_ == -1 ? 1 : 0; + ramses::AttributeInput inputVertices = (*currentAppearance_)->getEffect().findAttributeInput(core::MeshData::ATTRIBUTE_POSITION).value(); + geometry->addAttributeBuffer(inputVertices, sceneAdaptor_->defaultVertices(index)); + + ramses::AttributeInput inputNormals = (*currentAppearance_)->getEffect().findAttributeInput(core::MeshData::ATTRIBUTE_NORMAL).value(); + geometry->addAttributeBuffer(inputNormals, sceneAdaptor_->defaultNormals(index)); + + geometry->setIndices(sceneAdaptor_->defaultIndices(index)); } - ramsesObject().setGeometryBinding(geometryBinding); + ramsesObject().setGeometry(geometry); } -void MeshNodeAdaptor::getLogicNodes(std::vector& logicNodes) const { +void MeshNodeAdaptor::getLogicNodes(std::vector& logicNodes) const { SpatialAdaptor::getLogicNodes(logicNodes); if (appearanceBinding_) { logicNodes.push_back(appearanceBinding_.get()); @@ -227,13 +229,13 @@ void MeshNodeAdaptor::getLogicNodes(std::vector& logicNodes) } } -const rlogic::Property* MeshNodeAdaptor::getProperty(const std::vector& names) { +ramses::Property* MeshNodeAdaptor::getProperty(const std::vector& names) { if (names.size() > 1) { if (appearanceBinding_) { // Remove the first 3 nesting levels of the handle: materials/slot #/uniforms container: core::ValueHandle uniformContainerHandle = editorObject()->getUniformContainerHandle(0); auto ramsesPropNames = ramses_base::getRamsesUniformPropertyNames(uniformContainerHandle, names, 3); - return ILogicPropertyProvider::getPropertyRecursive(appearanceBinding_->getInputs(), ramsesPropNames, 0); + return ILogicPropertyProvider::getPropertyRecursive(appearanceBinding_->getInputs(), {ramsesPropNames.begin(), ramsesPropNames.end()}, 0); } return nullptr; } else if (names.size() == 1 && names[0] == "instanceCount") { @@ -247,24 +249,24 @@ const rlogic::Property* MeshNodeAdaptor::getProperty(const std::vector MeshNodeAdaptor::getExportInformation() const { auto result = std::vector(); if (getRamsesObjectPointer() != nullptr) { - result.emplace_back(ramses::ERamsesObjectType_MeshNode, ramsesObject().getName()); - result.emplace_back(ramses::ERamsesObjectType_GeometryBinding, fmt::format("{}_GeometryBinding", ramsesObject().getName())); + result.emplace_back(ramses::ERamsesObjectType::MeshNode, ramsesObject().getName()); + result.emplace_back(ramses::ERamsesObjectType::Geometry, fmt::format("{}_Geometry", ramsesObject().getName())); } if (nodeBinding() != nullptr) { - result.emplace_back("NodeBinding", nodeBinding()->getName().data()); + result.emplace_back("NodeBinding", nodeBinding()->getName()); } if (privateAppearance_ != nullptr) { - result.emplace_back(ramses::ERamsesObjectType_Appearance, privateAppearance_->get()->getName()); + result.emplace_back(ramses::ERamsesObjectType::Appearance, privateAppearance_->get()->getName()); } if (appearanceBinding_ != nullptr) { - result.emplace_back("AppearanceBinding", appearanceBinding_->getName().data()); + result.emplace_back("AppearanceBinding", appearanceBinding_->getName()); } if (meshNodeBinding_ != nullptr) { - result.emplace_back("MeshNodeBinding", meshNodeBinding_->getName().data()); + result.emplace_back("MeshNodeBinding", meshNodeBinding_->getName()); } return result; diff --git a/components/libRamsesBase/src/ramses_adaptor/NodeAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/NodeAdaptor.cpp index 04707d47..07df195c 100644 --- a/components/libRamsesBase/src/ramses_adaptor/NodeAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/NodeAdaptor.cpp @@ -12,16 +12,16 @@ namespace raco::ramses_adaptor { NodeAdaptor::NodeAdaptor(SceneAdaptor* sceneAdaptor, user_types::SNode node) - : SpatialAdaptor{sceneAdaptor, node, raco::ramses_base::ramsesNode(sceneAdaptor->scene())} {} + : SpatialAdaptor{sceneAdaptor, node, ramses_base::ramsesNode(sceneAdaptor->scene(), node->objectIDAsRamsesLogicID())} {} std::vector NodeAdaptor::getExportInformation() const { auto result = std::vector(); if (getRamsesObjectPointer() != nullptr) { - result.emplace_back(ramses::ERamsesObjectType_Node, ramsesObject().getName()); + result.emplace_back(ramses::ERamsesObjectType::Node, ramsesObject().getName()); } - if (nodeBinding() != nullptr){ - result.emplace_back("NodeBinding", nodeBinding()->getName().data()); + if (nodeBinding() != nullptr) { + result.emplace_back("NodeBinding", nodeBinding()->getName()); } return result; diff --git a/components/libRamsesBase/src/ramses_adaptor/OrthographicCameraAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/OrthographicCameraAdaptor.cpp index 586481b3..dd8d923a 100644 --- a/components/libRamsesBase/src/ramses_adaptor/OrthographicCameraAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/OrthographicCameraAdaptor.cpp @@ -18,8 +18,8 @@ namespace raco::ramses_adaptor { OrthographicCameraAdaptor::OrthographicCameraAdaptor(SceneAdaptor* sceneAdaptor, std::shared_ptr editorObject) - : SpatialAdaptor(sceneAdaptor, editorObject, raco::ramses_base::ramsesOrthographicCamera(sceneAdaptor->scene())), - cameraBinding_{raco::ramses_base::ramsesCameraBinding(this->getRamsesObjectPointer(), &sceneAdaptor->logicEngine(), editorObject_->objectIDAsRamsesLogicID(), false)}, + : SpatialAdaptor(sceneAdaptor, editorObject, ramses_base::ramsesOrthographicCamera(sceneAdaptor->scene(), editorObject->objectIDAsRamsesLogicID())), + cameraBinding_{ramses_base::ramsesCameraBinding(this->getRamsesObjectPointer(), &sceneAdaptor->logicEngine(), editorObject_->objectIDAsRamsesLogicID(), false)}, viewportSubscription_{sceneAdaptor->dispatcher()->registerOnChildren({editorObject, &user_types::OrthographicCamera::viewport_}, [this](auto) { tagDirty(); })}, @@ -47,12 +47,12 @@ bool OrthographicCameraAdaptor::sync(core::Errors* errors) { return true; } -void OrthographicCameraAdaptor::getLogicNodes(std::vector& logicNodes) const { +void OrthographicCameraAdaptor::getLogicNodes(std::vector& logicNodes) const { SpatialAdaptor::getLogicNodes(logicNodes); logicNodes.push_back(cameraBinding_.get()); } -const rlogic::Property* OrthographicCameraAdaptor::getProperty(const std::vector& propertyNamesVector) +ramses::Property* OrthographicCameraAdaptor::getProperty(const std::vector& propertyNamesVector) { if (auto p = BaseCameraAdaptorHelpers::getProperty(cameraBinding_.get(), propertyNamesVector)) { return p; @@ -63,22 +63,22 @@ const rlogic::Property* OrthographicCameraAdaptor::getProperty(const std::vector return SpatialAdaptor::getProperty(propertyNamesVector); } -raco::ramses_base::RamsesCameraBinding OrthographicCameraAdaptor::cameraBinding() { +ramses_base::RamsesCameraBinding OrthographicCameraAdaptor::cameraBinding() { return cameraBinding_; } std::vector OrthographicCameraAdaptor::getExportInformation() const { auto result = std::vector(); if (getRamsesObjectPointer() != nullptr) { - result.emplace_back(ramses::ERamsesObjectType_OrthographicCamera, ramsesObject().getName()); + result.emplace_back(ramses::ERamsesObjectType::OrthographicCamera, ramsesObject().getName()); } if (nodeBinding() != nullptr) { - result.emplace_back("NodeBinding", nodeBinding()->getName().data()); + result.emplace_back("NodeBinding", nodeBinding()->getName()); } if (cameraBinding_) { - result.emplace_back("CameraBinding", cameraBinding_->getName().data()); + result.emplace_back("CameraBinding", cameraBinding_->getName()); } return result; diff --git a/components/libRamsesBase/src/ramses_adaptor/PerspectiveCameraAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/PerspectiveCameraAdaptor.cpp index 17183fee..bb93d342 100644 --- a/components/libRamsesBase/src/ramses_adaptor/PerspectiveCameraAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/PerspectiveCameraAdaptor.cpp @@ -19,7 +19,7 @@ namespace raco::ramses_adaptor { PerspectiveCameraAdaptor::PerspectiveCameraAdaptor(SceneAdaptor* sceneAdaptor, std::shared_ptr editorObject) - : SpatialAdaptor(sceneAdaptor, editorObject, raco::ramses_base::ramsesPerspectiveCamera(sceneAdaptor->scene())), + : SpatialAdaptor(sceneAdaptor, editorObject, ramses_base::ramsesPerspectiveCamera(sceneAdaptor->scene(), editorObject->objectIDAsRamsesLogicID())), viewportSubscription_{sceneAdaptor->dispatcher()->registerOnChildren({editorObject, &user_types::PerspectiveCamera::viewport_}, [this](auto) { tagDirty(); @@ -34,7 +34,7 @@ PerspectiveCameraAdaptor::~PerspectiveCameraAdaptor() { bool PerspectiveCameraAdaptor::sync(core::Errors* errors) { SpatialAdaptor::sync(errors); - if (*editorObject_->frustumType_ == static_cast(raco::user_types::EFrustumType::Aspect_FieldOfView)) { + if (*editorObject_->frustumType_ == static_cast(user_types::EFrustumType::Aspect_FieldOfView)) { (*ramsesObject()).setFrustum( static_cast(editorObject()->frustum_->get("fieldOfView")->asDouble()), static_cast(editorObject()->frustum_->get("aspectRatio")->asDouble()), @@ -49,7 +49,7 @@ bool PerspectiveCameraAdaptor::sync(core::Errors* errors) { static_cast(editorObject()->frustum_->get("nearPlane")->asDouble()), static_cast(editorObject()->frustum_->get("farPlane")->asDouble())); } - cameraBinding_ = raco::ramses_base::ramsesCameraBinding(getRamsesObjectPointer(), &sceneAdaptor_->logicEngine(), editorObject_->objectIDAsRamsesLogicID(), *editorObject_->frustumType_ == static_cast(raco::user_types::EFrustumType::Planes)); + cameraBinding_ = ramses_base::ramsesCameraBinding(getRamsesObjectPointer(), &sceneAdaptor_->logicEngine(), editorObject_->objectIDAsRamsesLogicID(), *editorObject_->frustumType_ == static_cast(user_types::EFrustumType::Planes)); BaseCameraAdaptorHelpers::sync(editorObject(), ramsesObject().get(), cameraBinding_.get(), errors); @@ -62,7 +62,7 @@ bool PerspectiveCameraAdaptor::sync(core::Errors* errors) { return true; } -const rlogic::Property* PerspectiveCameraAdaptor::getProperty(const std::vector& propertyNamesVector) { +ramses::Property* PerspectiveCameraAdaptor::getProperty(const std::vector& propertyNamesVector) { if (auto p = BaseCameraAdaptorHelpers::getProperty(cameraBinding_.get(), propertyNamesVector)) { return p; } @@ -72,27 +72,27 @@ const rlogic::Property* PerspectiveCameraAdaptor::getProperty(const std::vector< return SpatialAdaptor::getProperty(propertyNamesVector); } -void PerspectiveCameraAdaptor::getLogicNodes(std::vector& logicNodes) const { +void PerspectiveCameraAdaptor::getLogicNodes(std::vector& logicNodes) const { SpatialAdaptor::getLogicNodes(logicNodes); logicNodes.push_back(cameraBinding_.get()); } -raco::ramses_base::RamsesCameraBinding PerspectiveCameraAdaptor::cameraBinding() { +ramses_base::RamsesCameraBinding PerspectiveCameraAdaptor::cameraBinding() { return cameraBinding_; } std::vector PerspectiveCameraAdaptor::getExportInformation() const { auto result = std::vector(); if (getRamsesObjectPointer() != nullptr) { - result.emplace_back(ramses::ERamsesObjectType_PerspectiveCamera, ramsesObject().getName()); + result.emplace_back(ramses::ERamsesObjectType::PerspectiveCamera, ramsesObject().getName()); } if (nodeBinding() != nullptr) { - result.emplace_back("NodeBinding", nodeBinding()->getName().data()); + result.emplace_back("NodeBinding", nodeBinding()->getName()); } if (cameraBinding_) { - result.emplace_back("CameraBinding", cameraBinding_->getName().data()); + result.emplace_back("CameraBinding", cameraBinding_->getName()); } return result; diff --git a/components/libRamsesBase/src/ramses_adaptor/RenderBufferAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/RenderBufferAdaptor.cpp index 13fefbbf..648bebb1 100644 --- a/components/libRamsesBase/src/ramses_adaptor/RenderBufferAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/RenderBufferAdaptor.cpp @@ -48,20 +48,19 @@ bool RenderBufferAdaptor::sync(core::Errors* errors) { auto format = static_cast(*editorObject()->format_); ramses::ERenderBufferFormat ramsesFormat = ramses_base::enumerationTranslationRenderBufferFormat.at(format); - ramses::ERenderBufferType type = raco::ramses_base::ramsesRenderBufferTypeFromFormat(ramsesFormat); bool allValid = true; - uint32_t clippedWidth = raco::ramses_base::clipAndCheckIntProperty({editorObject_, &raco::user_types::RenderBuffer::width_}, errors, &allValid); - uint32_t clippedHeight = raco::ramses_base::clipAndCheckIntProperty({editorObject_, &raco::user_types::RenderBuffer::height_}, errors, &allValid); + uint32_t clippedWidth = ramses_base::clipAndCheckIntProperty({editorObject_, &user_types::RenderBuffer::width_}, errors, &allValid); + uint32_t clippedHeight = ramses_base::clipAndCheckIntProperty({editorObject_, &user_types::RenderBuffer::height_}, errors, &allValid); if (allValid) { - buffer_ = raco::ramses_base::ramsesRenderBuffer(sceneAdaptor_->scene(), + buffer_ = ramses_base::ramsesRenderBuffer(sceneAdaptor_->scene(), clippedWidth, clippedHeight, - type, ramsesFormat, - ramses::ERenderBufferAccessMode_ReadWrite, + ramses::ERenderBufferAccessMode::ReadWrite, 0U, - (editorObject()->objectName() + "_Buffer").c_str()); + (editorObject()->objectName() + "_Buffer").c_str(), + editorObject_->objectIDAsRamsesLogicID()); } if (buffer_) { @@ -81,22 +80,27 @@ bool RenderBufferAdaptor::sync(core::Errors* errors) { auto magSamplMethod = static_cast(*editorObject()->magSamplingMethod_); auto ramsesMagSamplMethod = ramses_base::enumerationTranslationTextureSamplingMethod.at(magSamplMethod); - if (type == ramses::ERenderBufferType_Color) { + if (ramsesFormat == ramses::ERenderBufferFormat::Depth24 || ramsesFormat == ramses::ERenderBufferFormat::Depth24_Stencil8 || + ramsesFormat == ramses::ERenderBufferFormat::Depth16 || ramsesFormat == ramses::ERenderBufferFormat::Depth32) { + textureSampler = ramses_base::ramsesTextureSampler(sceneAdaptor_->scene(), + ramses::ETextureAddressMode::Clamp, + ramses::ETextureAddressMode::Clamp, + ramses::ETextureSamplingMethod::Nearest, + ramses::ETextureSamplingMethod::Nearest, + buffer_, + 1, + {}, + editorObject()->objectIDAsRamsesLogicID()); + } else { textureSampler = ramses_base::ramsesTextureSampler(sceneAdaptor_->scene(), ramsesWrapUMode, ramsesWrapVMode, ramsesMinSamplMethod, ramsesMagSamplMethod, buffer_, - (*editorObject()->anisotropy_ >= 1 ? *editorObject()->anisotropy_ : 1)); - } else { - textureSampler = ramses_base::ramsesTextureSampler(sceneAdaptor_->scene(), - ramses::ETextureAddressMode_Clamp, - ramses::ETextureAddressMode_Clamp, - ramses::ETextureSamplingMethod_Nearest, - ramses::ETextureSamplingMethod_Nearest, - buffer_, - 1); + (*editorObject()->anisotropy_ >= 1 ? *editorObject()->anisotropy_ : 1), + {}, + editorObject()->objectIDAsRamsesLogicID()); } reset(std::move(textureSampler)); diff --git a/components/libRamsesBase/src/ramses_adaptor/RenderBufferMSAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/RenderBufferMSAdaptor.cpp index 9e6e14fd..ba445ace 100644 --- a/components/libRamsesBase/src/ramses_adaptor/RenderBufferMSAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/RenderBufferMSAdaptor.cpp @@ -36,7 +36,7 @@ bool RenderBufferMSAdaptor::sync(core::Errors* errors) { buffer_.reset(); auto sampleCount = *editorObject()->sampleCount_; - if (sampleCount < raco::user_types::RenderBufferMS::SAMPLE_COUNT_MIN || sampleCount > raco::user_types::RenderBufferMS::SAMPLE_COUNT_MAX) { + if (sampleCount < user_types::RenderBufferMS::SAMPLE_COUNT_MIN || sampleCount > user_types::RenderBufferMS::SAMPLE_COUNT_MAX) { reset(nullptr); tagDirty(false); return true; @@ -44,24 +44,23 @@ bool RenderBufferMSAdaptor::sync(core::Errors* errors) { auto format = static_cast(*editorObject()->format_); ramses::ERenderBufferFormat ramsesFormat = ramses_base::enumerationTranslationRenderBufferFormat.at(format); - ramses::ERenderBufferType type = raco::ramses_base::ramsesRenderBufferTypeFromFormat(ramsesFormat); bool allValid = true; - uint32_t clippedWidth = raco::ramses_base::clipAndCheckIntProperty({editorObject_, &raco::user_types::RenderBufferMS::width_}, errors, &allValid); - uint32_t clippedHeight = raco::ramses_base::clipAndCheckIntProperty({editorObject_, &raco::user_types::RenderBufferMS::height_}, errors, &allValid); + uint32_t clippedWidth = ramses_base::clipAndCheckIntProperty({editorObject_, &user_types::RenderBufferMS::width_}, errors, &allValid); + uint32_t clippedHeight = ramses_base::clipAndCheckIntProperty({editorObject_, &user_types::RenderBufferMS::height_}, errors, &allValid); if (allValid) { - buffer_ = raco::ramses_base::ramsesRenderBuffer(sceneAdaptor_->scene(), + buffer_ = ramses_base::ramsesRenderBuffer(sceneAdaptor_->scene(), clippedWidth, clippedHeight, - type, ramsesFormat, - ramses::ERenderBufferAccessMode_ReadWrite, + ramses::ERenderBufferAccessMode::ReadWrite, sampleCount, - (editorObject()->objectName() + "_BufferMS").c_str()); + (editorObject()->objectName() + "_BufferMS").c_str(), + editorObject_->objectIDAsRamsesLogicID()); } if (buffer_) { - auto textureSampler = ramses_base::ramsesTextureSamplerMS(sceneAdaptor_->scene(), buffer_, (editorObject()->objectName() + "_TextureSamplerMS").c_str()); + auto textureSampler = ramses_base::ramsesTextureSamplerMS(sceneAdaptor_->scene(), buffer_, (editorObject()->objectName() + "_TextureSamplerMS").c_str(), editorObject()->objectIDAsRamsesLogicID()); reset(std::move(textureSampler)); } else { reset(nullptr); diff --git a/components/libRamsesBase/src/ramses_adaptor/RenderLayerAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/RenderLayerAdaptor.cpp index a5a5731a..d337d208 100644 --- a/components/libRamsesBase/src/ramses_adaptor/RenderLayerAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/RenderLayerAdaptor.cpp @@ -22,7 +22,7 @@ namespace raco::ramses_adaptor { RenderLayerAdaptor::RenderLayerAdaptor(SceneAdaptor* sceneAdaptor, std::shared_ptr editorObject) - : TypedObjectAdaptor(sceneAdaptor, editorObject, raco::ramses_base::ramsesRenderGroup(sceneAdaptor->scene())), + : TypedObjectAdaptor(sceneAdaptor, editorObject, ramses_base::ramsesRenderGroup(sceneAdaptor->scene(), editorObject->objectIDAsRamsesLogicID())), subscriptions_{sceneAdaptor->dispatcher()->registerOnObjectsLifeCycle([this](SEditorObject obj) { tagDirty(); }, [this](SEditorObject obj) { tagDirty(); }), sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderLayer::objectName_}, [this]() { tagDirty(); }), sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderLayer::renderableTags_}, [this]() { tagDirty(); }), @@ -48,7 +48,7 @@ void RenderLayerAdaptor::buildRenderGroup(core::Errors* errors) { std::vector topLevelNodes; std::vector layers; for (auto const& child : sceneAdaptor_->project().instances()) { - if (!child->getParent() && child->as()) { + if (!child->getParent() && child->as()) { topLevelNodes.emplace_back(child); } if (auto layer = child->as()) { @@ -58,11 +58,11 @@ void RenderLayerAdaptor::buildRenderGroup(core::Errors* errors) { std::set materialTags{editorObject()->materialFilterTags()}; - raco::user_types::ERenderLayerOrder sortOrder = static_cast(*editorObject()->sortOrder_); - bool sceneGraphOrder = sortOrder == raco::user_types::ERenderLayerOrder::SceneGraph; + user_types::ERenderLayerOrder sortOrder = static_cast(*editorObject()->sortOrder_); + bool sceneGraphOrder = sortOrder == user_types::ERenderLayerOrder::SceneGraph; int32_t orderIndex = 0; - rlogic::RamsesRenderGroupBindingElements bindingElements; + ramses::RenderGroupBindingElements bindingElements; std::vector nestedGroups; for (size_t index = 0; index < editorObject()->renderableTags_->size(); index++) { @@ -77,7 +77,7 @@ void RenderLayerAdaptor::buildRenderGroup(core::Errors* errors) { container = getRamsesObjectPointer(); } else { orderIndex = editorObject()->renderableTags_->get(index)->asInt(); - container = raco::ramses_base::ramsesRenderGroup(sceneAdaptor_->scene()); + container = ramses_base::ramsesRenderGroup(sceneAdaptor_->scene(), editorObject()->objectIDAsRamsesLogicID()); container->setName((editorObject()->objectName() + "." + renderableTag).c_str()); } @@ -91,7 +91,7 @@ void RenderLayerAdaptor::buildRenderGroup(core::Errors* errors) { } } - if (!sceneGraphOrder && this->sceneAdaptor_->featureLevel() >= rlogic::EFeatureLevel::EFeatureLevel_03 && !getRamsesObjectPointer()->empty()) { + if (!sceneGraphOrder && !getRamsesObjectPointer()->empty()) { binding_ = ramses_base::ramsesRenderGroupBinding(&sceneAdaptor_->logicEngine(), getRamsesObjectPointer(), bindingElements, nestedGroups, editorObject()->objectName() + "_Binding", editorObject()->objectIDAsRamsesLogicID()); @@ -104,7 +104,7 @@ void RenderLayerAdaptor::buildRenderableOrder(core::Errors* errors, ramses_base: bool currentActive = parentActive || core::Queries::hasObjectTag(obj->as(), tag); if (currentActive) { - if (obj->isType()) { + if (obj->isType()) { if (core::Queries::isMeshNodeInMaterialFilter(obj->as(), materialFilterTags, materialFilterExclusive)) { auto adaptor = sceneAdaptor_->lookup(obj); if (sceneGraphOrder) { @@ -112,7 +112,7 @@ void RenderLayerAdaptor::buildRenderableOrder(core::Errors* errors, ramses_base: if (ramsesObject().getMeshNodeOrder(adaptor->getRamsesObjectPointer()) != orderIndex) { const auto errorMsg = fmt::format("Mesh node '{}' has been added to render layer '{}' more than once with different priorities.", obj->objectName(), editorObject()->objectName()); errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::WARNING, {editorObject()->shared_from_this(), &user_types::RenderLayer::renderableTags_}, errorMsg); - LOG_WARNING(raco::log_system::RAMSES_ADAPTOR, errorMsg); + LOG_WARNING(log_system::RAMSES_ADAPTOR, errorMsg); } } else { container->addMeshNode(adaptor->getRamsesObjectPointer(), orderIndex); @@ -123,7 +123,7 @@ void RenderLayerAdaptor::buildRenderableOrder(core::Errors* errors, ramses_base: })) { const auto errorMsg = fmt::format("Mesh node '{}' has been added to render layer '{}' via multiple tags.", obj->objectName(), editorObject()->objectName()); errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, {editorObject()->shared_from_this(), &user_types::RenderLayer::renderableTags_}, errorMsg); - LOG_ERROR(raco::log_system::RAMSES_ADAPTOR, errorMsg); + LOG_ERROR(log_system::RAMSES_ADAPTOR, errorMsg); } else { container->addMeshNode(adaptor->getRamsesObjectPointer(), orderIndex); } @@ -173,13 +173,13 @@ void RenderLayerAdaptor::addNestedLayers(core::Errors* errors, ramses_base::Rams if (sceneGraphOrder) { const auto errorMsg = fmt::format("Render layer '{}' is using ordering by 'Scene Graph' but contains render layers. The render layers will be ignored.", editorObject()->objectName()); errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, {editorObject()->shared_from_this(), &user_types::RenderLayer::sortOrder_}, errorMsg); - LOG_ERROR(raco::log_system::RAMSES_ADAPTOR, errorMsg); + LOG_ERROR(log_system::RAMSES_ADAPTOR, errorMsg); return; } if (containsLayer(layers, layer, editorObject())) { const auto errorMsg = fmt::format("Render layer '{}' contains itself.", editorObject()->objectName()); errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::WARNING, {editorObject()->shared_from_this(), &user_types::RenderLayer::renderableTags_}, errorMsg); - LOG_WARNING(raco::log_system::RAMSES_ADAPTOR, errorMsg); + LOG_WARNING(log_system::RAMSES_ADAPTOR, errorMsg); } else { if (auto adaptor = sceneAdaptor_->lookup(layer); adaptor != nullptr) { if (sceneGraphOrder) { @@ -187,7 +187,7 @@ void RenderLayerAdaptor::addNestedLayers(core::Errors* errors, ramses_base::Rams if (ramsesObject().getRenderGroupOrder(adaptor->getRamsesObjectPointer()) != orderIndex) { const auto errorMsg = fmt::format("Render layer '{}' has been added to render layer '{}' more than once with different priorities.", layer->objectName(), editorObject()->objectName()); errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::WARNING, {editorObject()->shared_from_this(), &user_types::RenderLayer::renderableTags_}, errorMsg); - LOG_WARNING(raco::log_system::RAMSES_ADAPTOR, errorMsg); + LOG_WARNING(log_system::RAMSES_ADAPTOR, errorMsg); } } else { container->addRenderGroup(adaptor->getRamsesObjectPointer(), orderIndex); @@ -198,7 +198,7 @@ void RenderLayerAdaptor::addNestedLayers(core::Errors* errors, ramses_base::Rams })) { const auto errorMsg = fmt::format("Render layer '{}' has been added to render layer '{}' via multiple tags.", layer->objectName(), editorObject()->objectName()); errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, {editorObject()->shared_from_this(), &user_types::RenderLayer::renderableTags_}, errorMsg); - LOG_ERROR(raco::log_system::RAMSES_ADAPTOR, errorMsg); + LOG_ERROR(log_system::RAMSES_ADAPTOR, errorMsg); } else { container->addRenderGroup(adaptor->getRamsesObjectPointer(), orderIndex); } @@ -221,16 +221,16 @@ std::vector RenderLayerAdaptor::getExportInformation() const return {}; } - return {ExportInformation{ramses::ERamsesObjectType_RenderGroup, getRamsesObjectPointer()->getName()}}; + return {ExportInformation{ramses::ERamsesObjectType::RenderGroup, getRamsesObjectPointer()->getName()}}; } -void RenderLayerAdaptor::getLogicNodes(std::vector& logicNodes) const { +void RenderLayerAdaptor::getLogicNodes(std::vector& logicNodes) const { if (binding_) { logicNodes.push_back(binding_.get()); } } -const rlogic::Property* RenderLayerAdaptor::getProperty(const std::vector& propertyNamesVector) { +ramses::Property* RenderLayerAdaptor::getProperty(const std::vector& propertyNamesVector) { if (binding_ && propertyNamesVector.size() >= 2) { return binding_->getInputs()->getChild("renderOrders")->getChild(propertyNamesVector[1]); } diff --git a/components/libRamsesBase/src/ramses_adaptor/RenderPassAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/RenderPassAdaptor.cpp index a60462da..ba202529 100644 --- a/components/libRamsesBase/src/ramses_adaptor/RenderPassAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/RenderPassAdaptor.cpp @@ -22,20 +22,14 @@ namespace raco::ramses_adaptor { RenderPassAdaptor::RenderPassAdaptor(SceneAdaptor* sceneAdaptor, std::shared_ptr editorObject) : TypedObjectAdaptor(sceneAdaptor, editorObject, {}), - subscriptions_{sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderPass::target_}, [this]() { + subscriptions_{ + sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderPass::target_}, [this]() { tagDirty(); }), sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderPass::camera_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderPass::layer0_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderPass::layer1_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderPass::layer2_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderPass::layer3_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderPass::layer4_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderPass::layer5_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderPass::layer6_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderPass::layer7_}, [this]() { tagDirty(); }), + sceneAdaptor->dispatcher()->registerOnChildren(core::ValueHandle{editorObject, &user_types::RenderPass::layers_}, [this](auto) { tagDirty(); }), sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderPass::enabled_}, [this]() { tagDirty(); }), @@ -69,14 +63,18 @@ bool RenderPassAdaptor::sync(core::Errors* errors) { if (auto target = *editorObject()->target_) { if (auto targetAdaptor = sceneAdaptor_->lookup(target)) { ramsesTarget = targetAdaptor->getRamsesObjectPointer(); - if (ramsesTarget == nullptr) { - // ramsesTarget == nullptr can only happen if the RamsesTarget is invalid (e. g. because render buffers don't match in size). - // Only reset render pass in this case and do not render anything. - validTarget = false; - const auto errorMsg = fmt::format("Render pass '{}' is not rendered due to invalid render target '{}'", editorObject()->objectName(), target->objectName()); - LOG_WARNING(raco::log_system::RAMSES_ADAPTOR, errorMsg); - errors->addError(core::ErrorCategory::PARSING, core::ErrorLevel::WARNING, {editorObject()->shared_from_this()}, errorMsg); - } + } + if (auto targetAdaptor = sceneAdaptor_->lookup(target)) { + ramsesTarget = targetAdaptor->getRamsesObjectPointer(); + } + + if (ramsesTarget == nullptr) { + // ramsesTarget == nullptr can only happen if the RamsesTarget is invalid (e. g. because render buffers don't match in size). + // Only reset render pass in this case and do not render anything. + validTarget = false; + const auto errorMsg = fmt::format("Render pass '{}' is not rendered due to invalid render target '{}'", editorObject()->objectName(), target->objectName()); + LOG_WARNING(log_system::RAMSES_ADAPTOR, errorMsg); + errors->addError(core::ErrorCategory::PARSING, core::ErrorLevel::WARNING, {editorObject()->shared_from_this()}, errorMsg); } } @@ -84,12 +82,12 @@ bool RenderPassAdaptor::sync(core::Errors* errors) { if (validTarget && camera) { if (auto perspCamera = camera->as()) { if (auto cameraAdaptor = sceneAdaptor_->lookup(perspCamera)) { - auto newRamsesObject = ramses_base::ramsesRenderPass(sceneAdaptor_->scene(), cameraAdaptor->getRamsesObjectPointer(), ramsesTarget, editorObject()->objectName().c_str()); + auto newRamsesObject = ramses_base::ramsesRenderPass(sceneAdaptor_->scene(), cameraAdaptor->getRamsesObjectPointer(), ramsesTarget, editorObject()->objectName().c_str(), editorObject_->objectIDAsRamsesLogicID()); reset(std::move(newRamsesObject)); } } else if (auto orthoCamera = camera->as()) { if (auto cameraAdaptor = sceneAdaptor_->lookup(orthoCamera)) { - auto newRamsesObject = ramses_base::ramsesRenderPass(sceneAdaptor_->scene(), cameraAdaptor->getRamsesObjectPointer(), ramsesTarget, editorObject()->objectName().c_str()); + auto newRamsesObject = ramses_base::ramsesRenderPass(sceneAdaptor_->scene(), cameraAdaptor->getRamsesObjectPointer(), ramsesTarget, editorObject()->objectName().c_str(), editorObject_->objectIDAsRamsesLogicID()); reset(std::move(newRamsesObject)); } } @@ -100,63 +98,44 @@ bool RenderPassAdaptor::sync(core::Errors* errors) { if (getRamsesObjectPointer()) { ramsesObject().removeAllRenderGroups(); - auto layers = { - *editorObject().get()->layer0_, - *editorObject().get()->layer1_, - *editorObject().get()->layer2_, - *editorObject().get()->layer3_, - *editorObject().get()->layer4_, - *editorObject().get()->layer5_, - *editorObject().get()->layer6_, - *editorObject().get()->layer7_ - }; - - for (auto layer : layers) { + for (auto layer : editorObject()->layers_->asVector()) { if (auto layerAdaptor = sceneAdaptor_->lookup(layer)) { ramsesObject().addRenderGroup(layerAdaptor->getRamsesObjectPointer()); } } (*ramsesObject()).setEnabled(*editorObject()->enabled_); - if (this->sceneAdaptor_->featureLevel() >= rlogic::EFeatureLevel::EFeatureLevel_02) { - (*ramsesObject()).setRenderOnce(*editorObject()->renderOnce_); - } + (*ramsesObject()).setRenderOnce(*editorObject()->renderOnce_); (*ramsesObject()).setRenderOrder(*editorObject()->renderOrder_); - (*ramsesObject()).setClearColor( - *editorObject()->clearColor_->x, - *editorObject()->clearColor_->y, - *editorObject()->clearColor_->z, - *editorObject()->clearColor_->w); + (*ramsesObject()).setClearColor({*editorObject()->clearColor_->x, *editorObject()->clearColor_->y, *editorObject()->clearColor_->z, *editorObject()->clearColor_->w}); if (ramsesTarget != nullptr) { (*ramsesObject()).setClearFlags( - (*editorObject()->enableClearColor_ ? ramses::EClearFlags_Color : 0) | - (*editorObject()->enableClearDepth_ ? ramses::EClearFlags_Depth : 0) | - (*editorObject()->enableClearStencil_ ? ramses::EClearFlags_Stencil : 0)); + (*editorObject()->enableClearColor_ ? ramses::EClearFlag::Color : ramses::EClearFlag::None) | + (*editorObject()->enableClearDepth_ ? ramses::EClearFlag::Depth : ramses::EClearFlag::None) | + (*editorObject()->enableClearStencil_ ? ramses::EClearFlag::Stencil : ramses::EClearFlag::None)); } else { // Force no clear flags for a render pass rendering to the default framebuffer. // Otherwise the scene validation on export complains that the clear flags // will have no effect. - (*ramsesObject()).setClearFlags(ramses::EClearFlags_None); + (*ramsesObject()).setClearFlags(ramses::EClearFlag::None); } - if (this->sceneAdaptor_->featureLevel() >= rlogic::EFeatureLevel::EFeatureLevel_02) { - binding_ = raco::ramses_base::ramsesRenderPassBinding(*ramsesObject(), &sceneAdaptor_->logicEngine(), editorObject()->objectName() + "_Binding", editorObject()->objectIDAsRamsesLogicID()); - } + binding_ = ramses_base::ramsesRenderPassBinding(*ramsesObject(), &sceneAdaptor_->logicEngine(), editorObject()->objectName() + "_Binding", editorObject()->objectIDAsRamsesLogicID()); } tagDirty(false); return true; } -void RenderPassAdaptor::getLogicNodes(std::vector& logicNodes) const { +void RenderPassAdaptor::getLogicNodes(std::vector& logicNodes) const { if (binding_) { logicNodes.push_back(binding_.get()); } } -const rlogic::Property* RenderPassAdaptor::getProperty(const std::vector& propertyNamesVector) { +ramses::Property* RenderPassAdaptor::getProperty(const std::vector& propertyNamesVector) { if (binding_ && propertyNamesVector.size() >= 1) { return binding_->getInputs()->getChild(propertyNamesVector[0]); } @@ -174,11 +153,11 @@ void RenderPassAdaptor::onRuntimeError(core::Errors& errors, std::string const& std::vector RenderPassAdaptor::getExportInformation() const { auto result = std::vector(); if (getRamsesObjectPointer() != nullptr) { - result.emplace_back(ramses::ERamsesObjectType_RenderPass, getRamsesObjectPointer()->getName()); + result.emplace_back(ramses::ERamsesObjectType::RenderPass, getRamsesObjectPointer()->getName()); } if (binding_ != nullptr) { - result.emplace_back("RenderPassBinding", binding_->getName().data()); + result.emplace_back("RenderPassBinding", binding_->getName()); } return result; diff --git a/components/libRamsesBase/src/ramses_adaptor/RenderTargetAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/RenderTargetAdaptor.cpp index 05430402..dc399b57 100644 --- a/components/libRamsesBase/src/ramses_adaptor/RenderTargetAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/RenderTargetAdaptor.cpp @@ -13,41 +13,25 @@ #include "ramses_adaptor/RenderBufferMSAdaptor.h" #include "ramses_base/RamsesHandles.h" - namespace raco::ramses_adaptor { - -RenderTargetAdaptor::RenderTargetAdaptor(SceneAdaptor* sceneAdaptor, std::shared_ptr editorObject) - : TypedObjectAdaptor(sceneAdaptor, editorObject, {}), - subscriptions_{sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderTarget::buffer0_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderTarget::buffer1_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderTarget::buffer2_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderTarget::buffer3_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderTarget::buffer4_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderTarget::buffer5_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderTarget::buffer6_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderTarget::buffer7_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderTarget::bufferMS0_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderTarget::bufferMS1_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderTarget::bufferMS2_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderTarget::bufferMS3_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderTarget::bufferMS4_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderTarget::bufferMS5_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderTarget::bufferMS6_}, [this]() { tagDirty(); }), - sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject, &user_types::RenderTarget::bufferMS7_}, [this]() { tagDirty(); })} { + +template +RenderTargetAdaptorT::RenderTargetAdaptorT(SceneAdaptor* sceneAdaptor, std::shared_ptr editorObject) + : TypedObjectAdaptor(sceneAdaptor, editorObject, {}), + subscription_{sceneAdaptor->dispatcher()->registerOnChildren(core::ValueHandle{editorObject, &RenderTargetClass::buffers_}, [this](auto) { this->tagDirty(); })} { } -template -bool RenderTargetAdaptor::collectBuffers(std::vector& buffers, const std::initializer_list& userTypeBuffers, ramses::RenderTargetDescription& rtDesc, core::Errors* errors) { +template +bool RenderTargetAdaptorT::collectBuffers(std::vector& buffers, const std::vector>& userTypeBuffers, ramses::RenderTargetDescription& rtDesc, core::Errors* errors) { bool hasEmptySlots = false; for (int bufferSlotIndex = 0; bufferSlotIndex < userTypeBuffers.size(); ++bufferSlotIndex) { const auto& buffer = userTypeBuffers.begin()[bufferSlotIndex]; - if (auto adaptor = sceneAdaptor_->lookup(buffer)) { + if (auto adaptor = this->sceneAdaptor_->template lookup(buffer)) { if (auto ramsesBuffer = adaptor->buffer()) { - auto status = rtDesc.addRenderBuffer(*ramsesBuffer); - if (status != ramses::StatusOK) { - LOG_ERROR(raco::log_system::RAMSES_ADAPTOR, rtDesc.getStatusMessage(status)); - errors->addError(core::ErrorCategory::PARSING, core::ErrorLevel::ERROR, {editorObject()->shared_from_this()}, - rtDesc.getStatusMessage(status)); + if (!rtDesc.addRenderBuffer(*ramsesBuffer)) { + auto errorMsg = this->sceneAdaptor_->scene()->getRamsesClient().getRamsesFramework().getLastError().value().message; + LOG_ERROR(log_system::RAMSES_ADAPTOR, errorMsg); + errors->addError(core::ErrorCategory::PARSING, core::ErrorLevel::ERROR, {this->editorObject()->shared_from_this()}, errorMsg); } else { hasEmptySlots = buffers.size() != bufferSlotIndex; buffers.emplace_back(ramsesBuffer); @@ -58,33 +42,13 @@ bool RenderTargetAdaptor::collectBuffers(std::vectorremoveError({editorObject()}); +template +bool RenderTargetAdaptorT::sync(core::Errors* errors) { + errors->removeError({this->editorObject()}); std::vector buffers; - std::vector buffersMS; ramses::RenderTargetDescription rtDesc; - std::initializer_list usertypebuffers = { - *editorObject().get()->user_types::RenderTarget::buffer0_, - *editorObject().get()->user_types::RenderTarget::buffer1_, - *editorObject().get()->user_types::RenderTarget::buffer2_, - *editorObject().get()->user_types::RenderTarget::buffer3_, - *editorObject().get()->user_types::RenderTarget::buffer4_, - *editorObject().get()->user_types::RenderTarget::buffer5_, - *editorObject().get()->user_types::RenderTarget::buffer6_, - *editorObject().get()->user_types::RenderTarget::buffer7_}; - - std::initializer_list usertypebuffersMS = { - *editorObject().get()->user_types::RenderTarget::bufferMS0_, - *editorObject().get()->user_types::RenderTarget::bufferMS1_, - *editorObject().get()->user_types::RenderTarget::bufferMS2_, - *editorObject().get()->user_types::RenderTarget::bufferMS3_, - *editorObject().get()->user_types::RenderTarget::bufferMS4_, - *editorObject().get()->user_types::RenderTarget::bufferMS5_, - *editorObject().get()->user_types::RenderTarget::bufferMS6_, - *editorObject().get()->user_types::RenderTarget::bufferMS7_}; - // We cannot have any empty slots before color buffers in Ramses - // the RenderTargetDescription::addRenderBuffer does not allow for it. // But if we only add valid render buffers to the list of render buffers, @@ -93,53 +57,37 @@ bool RenderTargetAdaptor::sync(core::Errors* errors) { // This is a Ramses bug - see https://github.com/bmwcarit/ramses/issues/52 // If that occurs, refuse to create the render target to avoid any surprises for the user. - bool haveNormalBuffers = std::any_of(usertypebuffers.begin(), usertypebuffers.end(), [](auto object) { - return object != nullptr; - }); - bool haveMSBuffers = std::any_of(usertypebuffersMS.begin(), usertypebuffersMS.end(), [](auto object) { - return object != nullptr; - }); - - if (haveNormalBuffers && haveMSBuffers) { - auto errorMsg = fmt::format("Cannot create render target '{}' - all buffers need to be either single-sample or multi-sample only.", editorObject()->objectName()); - reset(nullptr); - LOG_ERROR(raco::log_system::RAMSES_ADAPTOR, errorMsg); - errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, {editorObject()}, errorMsg); - - tagDirty(false); - return true; - } - - bool hasEmptySlotsNormal = collectBuffers(buffers, usertypebuffers, rtDesc, errors); - bool hasEmptySlotsMS = collectBuffers(buffersMS, usertypebuffersMS, rtDesc, errors); - bool hasEmptySlots = hasEmptySlotsNormal || hasEmptySlotsMS; - - buffers.insert(buffers.end(), buffersMS.begin(), buffersMS.end()); + auto userTypeBuffers = this->editorObject()->buffers_->template asVector>(); + bool hasEmptySlots = collectBuffers(buffers, userTypeBuffers, rtDesc, errors); if (!buffers.empty() && !hasEmptySlots) { - reset(ramses_base::ramsesRenderTarget(sceneAdaptor_->scene(), rtDesc, buffers)); - } else if (!errors->hasError({editorObject()})) { + this->reset(ramses_base::ramsesRenderTarget(this->sceneAdaptor_->scene(), rtDesc, buffers, this->editorObject()->objectIDAsRamsesLogicID())); + } else if (!errors->hasError({this->editorObject()})) { std::string errorMsg; if (buffers.empty()) { - errorMsg = fmt::format("Cannot create render target '{}' - its first buffer is not set or not valid.", editorObject()->objectName()); + errorMsg = fmt::format("Cannot create render target '{}' - its first buffer is not set or not valid.", this->editorObject()->objectName()); } else { - errorMsg = fmt::format("Cannot create render target '{}' - all buffers in it must be consecutive and valid buffers.", editorObject()->objectName()); + errorMsg = fmt::format("Cannot create render target '{}' - all buffers in it must be consecutive and valid buffers.", this->editorObject()->objectName()); } - reset(nullptr); - LOG_ERROR(raco::log_system::RAMSES_ADAPTOR, errorMsg); - errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, {editorObject()}, errorMsg); + this->reset(nullptr); + LOG_ERROR(log_system::RAMSES_ADAPTOR, errorMsg); + errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, {this->editorObject()}, errorMsg); } - tagDirty(false); + this->tagDirty(false); return true; } -std::vector RenderTargetAdaptor::getExportInformation() const { - if (getRamsesObjectPointer() == nullptr) { +template +std::vector RenderTargetAdaptorT::getExportInformation() const { + if (this->getRamsesObjectPointer() == nullptr) { return {}; } - return {ExportInformation{ramsesObject().getType(), ramsesObject().getName()}}; + return {ExportInformation{this->ramsesObject().getType(), this->ramsesObject().getName()}}; } +template class RenderTargetAdaptorT; +template class RenderTargetAdaptorT; + }; // namespace raco::ramses_adaptor \ No newline at end of file diff --git a/components/libRamsesBase/src/ramses_adaptor/SceneAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/SceneAdaptor.cpp index e0df860c..57c95938 100644 --- a/components/libRamsesBase/src/ramses_adaptor/SceneAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/SceneAdaptor.cpp @@ -17,6 +17,7 @@ #include "core/Queries.h" #include "ramses_adaptor/AnchorPointAdaptor.h" #include "ramses_adaptor/AnimationAdaptor.h" +#include "ramses_adaptor/DefaultRamsesObjects.h" #include "ramses_adaptor/Factories.h" #include "ramses_adaptor/LuaScriptAdaptor.h" #include "ramses_adaptor/ObjectAdaptor.h" @@ -42,75 +43,29 @@ namespace raco::ramses_adaptor { using namespace raco::ramses_base; -inline RamsesEffect createDefaultEffect(ramses::Scene* scene, bool withNormals) { - ramses::EffectDescription effectDescription{}; - effectDescription.setVertexShader(withNormals ? defaultVertexShaderWithNormals : defaultVertexShader); - effectDescription.setFragmentShader(withNormals ? defaultFragmentShaderWithNormals : defaultFragmentShader); - effectDescription.setUniformSemantic("mvpMatrix", ramses::EEffectUniformSemantic::ModelViewProjectionMatrix); - return ramsesEffect(scene, effectDescription, (withNormals) ? defaultEffectWithNormalsName : defaultEffectName); -} - -inline RamsesArrayResource createDefaultIndexDataBuffer(ramses::Scene* scene) { - static std::vector indices{ - // front - 0, 1, 2, - 2, 3, 0, - // right - 1, 5, 6, - 6, 2, 1, - // back - 7, 6, 5, - 5, 4, 7, - // left - 4, 0, 3, - 3, 7, 4, - // bottom - 4, 5, 1, - 1, 0, 4, - // top - 3, 2, 6, - 6, 7, 3}; - return ramsesArrayResource(scene, ramses::EDataType::UInt32, static_cast(indices.size()), indices.data(), defaultIndexDataBufferName); -} - -inline RamsesArrayResource createDefaultVertexDataBuffer(ramses::Scene* scene) { - static std::vector vertices{ - // front - -1.0f, -1.0f, 1.0f, - 1.0f, -1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, - -1.0f, 1.0f, 1.0f, - // back - -1.0f, -1.0f, -1.0f, - 1.0f, -1.0f, -1.0f, - 1.0f, 1.0f, -1.0f, - -1.0f, 1.0f, -1.0f}; - return ramsesArrayResource(scene, ramses::EDataType::Vector3F, static_cast(vertices.size()), vertices.data(), defaultVertexDataBufferName); -} - -SceneAdaptor::SceneAdaptor(ramses::RamsesClient* client, ramses_base::LogicEngine* logicEngine, ramses::sceneId_t id, Project* project, components::SDataChangeDispatcher dispatcher, core::Errors* errors, bool optimizeForExport) +SceneAdaptor::SceneAdaptor(ramses::RamsesClient* client, ramses::sceneId_t id, Project* project, components::SDataChangeDispatcher dispatcher, core::Errors* errors, bool optimizeForExport) : client_{client}, - logicEngine_{logicEngine}, project_(project), scene_{ramsesScene(id, client_)}, + logicEngine_{ramses_base::BaseEngineBackend::UniqueLogicEngine(scene_->createLogicEngine(), [this](ramses::LogicEngine* logicEngine) { scene_->destroy(*logicEngine); })}, subscription_{dispatcher->registerOnObjectsLifeCycle([this](SEditorObject obj) { createAdaptor(obj); }, [this](SEditorObject obj) { removeAdaptor(obj); })}, childrenSubscription_(dispatcher->registerOnPropertyChange("children", [this](core::ValueHandle handle) { - adaptorStatusDirty_ = true; - })), + adaptorStatusDirty_ = true; + })), linksLifecycle_{dispatcher->registerOnLinksLifeCycle( - [this](const core::LinkDescriptor& link) { createLink(link); }, + [this](const core::LinkDescriptor& link) { createLink(link); }, [this](const core::LinkDescriptor& link) { removeLink(link); })}, linkValidityChangeSub_{dispatcher->registerOnLinkValidityChange( [this](const core::LinkDescriptor& link) { changeLinkValidity(link, link.isValid); })}, dispatcher_{dispatcher}, errors_{errors}, - optimizeForExport_(optimizeForExport) { + optimizeForExport_(optimizeForExport) { for (const SEditorObject& obj : project_->instances()) { createAdaptor(obj); } - dispatcher_->registerBulkChangeCallback([this](const core::SEditorObjectSet& changedObjects) { + dispatcher_->addBulkChangeCallback(id.getValue(), [this](const core::SEditorObjectSet& changedObjects) { performBulkEngineUpdate(changedObjects); }); @@ -123,11 +78,11 @@ SceneAdaptor::SceneAdaptor(ramses::RamsesClient* client, ramses_base::LogicEngin performBulkEngineUpdate(initialBulkUpdate); scene_->flush(); - scene_->publish(); + scene_->publish(ramses::EScenePublicationMode::LocalAndRemote); } SceneAdaptor::~SceneAdaptor() { - dispatcher_->resetBulkChangeCallback(); + dispatcher_->removeBulkChangeCallback(sceneId().getValue()); } ramses::Scene* SceneAdaptor::scene() { @@ -157,8 +112,8 @@ void SceneAdaptor::removeAdaptor(SEditorObject obj) { auto adaptorWasLogicProvider = dynamic_cast(lookupAdaptor(obj)) != nullptr; adaptors_.erase(obj); deleteUnusedDefaultResources(); - if (adaptorWasLogicProvider) { - updateRuntimeErrorList(); + if (adaptorWasLogicProvider && lastErrorObject_ == obj) { + clearRuntimeError(); } dependencyGraph_.clear(); } @@ -173,51 +128,32 @@ bool SceneAdaptor::optimizeForExport() const { return optimizeForExport_; } -rlogic::EFeatureLevel SceneAdaptor::featureLevel() const { - return logicEngine_->getFeatureLevel(); +ramses::EFeatureLevel SceneAdaptor::featureLevel() const { + return client_->getRamsesFramework().getFeatureLevel(); } -void SceneAdaptor::updateRuntimeErrorList() { - auto logicEngineErrors = logicEngine().getErrors(); - if (logicEngineErrors.empty()) { - errors_->removeIf([](const core::ErrorItem& errorItem) { - return errorItem.category() == core::ErrorCategory::RAMSES_LOGIC_RUNTIME; - }); - - return; - } - - // Avoid having to search the entire list of errors for each instance and O(N*M) complexity - std::sort(logicEngineErrors.begin(), logicEngineErrors.end(), [](rlogic::ErrorData const& e1, rlogic::ErrorData const& e2) { - return e1.object < e2.object; - }); +void SceneAdaptor::updateRuntimeError(const ramses::Issue& issue) { std::unordered_set logicProvidersWithoutRuntimeError; - std::string runtimeErrorObjectNames; + std::string runtimeErrorObjectName; + lastErrorObject_ = nullptr; + for (const auto& instance : project().instances()) { if (auto logicProvider = dynamic_cast(lookupAdaptor(instance))) { - std::vector logicNodes; + std::vector logicNodes; logicProvider->getLogicNodes(logicNodes); - rlogic::ErrorData const* runtimeError = nullptr; - for (auto logicNode : logicNodes) { - auto const itRuntimeErrorForScript = std::lower_bound(logicEngineErrors.begin(), logicEngineErrors.end(), logicNode, [](rlogic::ErrorData const& e, rlogic::LogicNode* s) { - return e.object < s; - }); - if (itRuntimeErrorForScript != logicEngineErrors.end() && itRuntimeErrorForScript->object == logicNode) { - runtimeError = &*itRuntimeErrorForScript; - break; - } - } - if (runtimeError != nullptr) { - runtimeErrorObjectNames.append("\n'" + instance->objectName() + "'"); + + if (std::find(logicNodes.begin(), logicNodes.end(), issue.object) != logicNodes.end()) { + runtimeErrorObjectName = instance->objectName(); // keep the old runtime error message if it is identical to the new message to prevent unnecessary error regeneration in the UI if (errors_->hasError(instance)) { auto instError = errors_->getError(instance); - if (instError.category() == core::ErrorCategory::RAMSES_LOGIC_RUNTIME && instError.message() != runtimeError->message) { + if (instError.category() == core::ErrorCategory::RAMSES_LOGIC_RUNTIME && instError.message() != issue.message) { errors_->removeError(instance); } } - logicProvider->onRuntimeError(*errors_, runtimeError->message, core::ErrorLevel::ERROR); + lastErrorObject_ = instance; + logicProvider->onRuntimeError(*errors_, issue.message, core::ErrorLevel::ERROR); } else { logicProvidersWithoutRuntimeError.emplace(logicProvider); } @@ -225,7 +161,7 @@ void SceneAdaptor::updateRuntimeErrorList() { } // keep the old runtime error info message if it is identical to the new message to prevent unnecessary error regeneration in the UI - auto ramsesLogicErrorFoundMsg = fmt::format("Ramses logic engine detected a runtime error in{}\nBe aware that some Lua script outputs and/or linked properties might not have been updated.", runtimeErrorObjectNames); + auto ramsesLogicErrorFoundMsg = fmt::format("Ramses logic engine detected a runtime error in '{}'.\nBe aware that some Lua script outputs and/or linked properties might not have been updated.", runtimeErrorObjectName); errors_->removeIf([this, &ramsesLogicErrorFoundMsg, &logicProvidersWithoutRuntimeError](const core::ErrorItem& errorItem) { if (auto logicProvider = dynamic_cast(lookupAdaptor(errorItem.valueHandle().rootObject()))) { return logicProvidersWithoutRuntimeError.count(logicProvider) == 1 && errorItem.category() == core::ErrorCategory::RAMSES_LOGIC_RUNTIME && errorItem.message() != ramsesLogicErrorFoundMsg; @@ -238,6 +174,13 @@ void SceneAdaptor::updateRuntimeErrorList() { } } +void SceneAdaptor::clearRuntimeError() { + lastErrorObject_ = nullptr; + errors_->removeIf([](const core::ErrorItem& errorItem) { + return errorItem.category() == core::ErrorCategory::RAMSES_LOGIC_RUNTIME; + }); +} + void SceneAdaptor::deleteUnusedDefaultResources() { // Resource use count is 1 => it is stored in the scene but not used by any MeshNodeAdaptor // - delete the resource as to not get unnecessarily exported. @@ -247,23 +190,27 @@ void SceneAdaptor::deleteUnusedDefaultResources() { if (defaultAppearanceWithNormals_.use_count() == 1) { defaultAppearanceWithNormals_.reset(); } - if (defaultEffect_.use_count() == 1) { - defaultEffect_.reset(); + if (defaultIndices_[0].use_count() == 1) { + defaultIndices_[0].reset(); + } + if (defaultIndices_[1].use_count() == 1) { + defaultIndices_[1].reset(); } - if (defaultEffectWithNormals_.use_count() == 1) { - defaultEffectWithNormals_.reset(); + if (defaultVertices_[0].use_count() == 1) { + defaultVertices_[0].reset(); } - if (defaultIndices_.use_count() == 1) { - defaultIndices_.reset(); + if (defaultVertices_[1].use_count() == 1) { + defaultVertices_[1].reset(); } - if (defaultVertices_.use_count() == 1) { - defaultVertices_.reset(); + if (defaultNormals_[0].use_count() == 1) { + defaultNormals_[0].reset(); + } + if (defaultNormals_[1].use_count() == 1) { + defaultNormals_[1].reset(); } } void SceneAdaptor::readDataFromEngine(core::DataChangeRecorder& recorder) { - updateRuntimeErrorList(); - for (const auto& [endObjecttID, linkMap] : links_.linksByEnd_) { for (const auto& [link, adaptor] : linkMap) { adaptor->readDataFromEngine(recorder); @@ -309,7 +256,7 @@ ramses::RamsesClient* SceneAdaptor::client() { return client_; } -ramses_base::LogicEngine& SceneAdaptor::logicEngine() { +ramses::LogicEngine& SceneAdaptor::logicEngine() { return *logicEngine_; } @@ -322,35 +269,32 @@ const SRamsesAdaptorDispatcher SceneAdaptor::dispatcher() const { } const RamsesAppearance SceneAdaptor::defaultAppearance(bool withMeshNormals) { - if (withMeshNormals) { - if (!defaultEffectWithNormals_) { - defaultEffectWithNormals_ = createDefaultEffect(scene_.get(), true); - defaultAppearanceWithNormals_ = raco::ramses_base::ramsesAppearance(scene(), defaultEffectWithNormals_); - (*defaultAppearanceWithNormals_)->setName(defaultAppearanceWithNormalsName); - } - return defaultAppearanceWithNormals_; + ramses_base::RamsesAppearance& appearance = withMeshNormals ? defaultAppearanceWithNormals_ : defaultAppearance_; + if (!appearance) { + appearance = createDefaultAppearance(scene_.get(), withMeshNormals, false, false); } + return appearance; +} - if (!defaultEffect_) { - defaultEffect_ = createDefaultEffect(scene_.get(), false); - defaultAppearance_ = raco::ramses_base::ramsesAppearance(scene(), defaultEffect_); - (*defaultAppearance_)->setName(defaultAppearanceName); +const RamsesArrayResource SceneAdaptor::defaultVertices(int index) { + if (!defaultVertices_[index]) { + defaultVertices_[index] = index == 1 ? createCatVertexDataBuffer(scene_.get()) : createCubeVertexDataBuffer(scene_.get()); } - return defaultAppearance_; + return defaultVertices_[index]; } -const RamsesArrayResource SceneAdaptor::defaultVertices() { - if (!defaultVertices_) { - defaultVertices_ = createDefaultVertexDataBuffer(scene_.get()); +const RamsesArrayResource SceneAdaptor::defaultNormals(int index) { + if (!defaultNormals_[index]) { + defaultNormals_[index] = index == 1 ? createCatNormalDataBuffer(scene_.get()) : createCubeNormalDataBuffer(scene_.get()); } - return defaultVertices_; + return defaultNormals_[index]; } -const RamsesArrayResource SceneAdaptor::defaultIndices() { - if (!defaultIndices_) { - defaultIndices_ = createDefaultIndexDataBuffer(scene_.get()); +const RamsesArrayResource SceneAdaptor::defaultIndices(int index) { + if (!defaultIndices_[index]) { + defaultIndices_[index] = index == 1 ? createCatIndexDataBuffer(scene_.get()) : createCubeIndexDataBuffer(scene_.get()); } - return defaultIndices_; + return defaultIndices_[index]; } ObjectAdaptor* SceneAdaptor::lookupAdaptor(const core::SEditorObject& editorObject) const { @@ -364,51 +308,12 @@ ObjectAdaptor* SceneAdaptor::lookupAdaptor(const core::SEditorObject& editorObje return nullptr; } -raco::core::Project& SceneAdaptor::project() const { +core::Project& SceneAdaptor::project() const { return *project_; } -void SceneAdaptor::depthFirstSearch(data_storage::ReflectionInterface* object, DependencyNode& item, SEditorObjectSet const& instances, SEditorObjectSet& sortedObjs, std::vector& outSorted) { - for (size_t index = 0; index < object->size(); index++) { - auto v = (*object)[index]; - switch (v->type()) { - case data_storage::PrimitiveType::Ref: { - auto refValue = v->asRef(); - if (refValue && instances.find(refValue) != instances.end()) { - depthFirstSearch(refValue, instances, sortedObjs, outSorted); - item.referencedObjects.insert(refValue); - } - break; - } - case data_storage::PrimitiveType::Table: - depthFirstSearch(&v->asTable(), item, instances, sortedObjs, outSorted); - break; - } - } -} - -void SceneAdaptor::depthFirstSearch(SEditorObject object, SEditorObjectSet const& instances, SEditorObjectSet& sortedObjs, std::vector& outSorted) { - using namespace raco::core; - - if (sortedObjs.find(object) != sortedObjs.end()) { - return; - } - - DependencyNode item; - item.object = object; - depthFirstSearch(object.get(), item, instances, sortedObjs, outSorted); - - outSorted.emplace_back(item); - sortedObjs.insert(item.object); -} - void SceneAdaptor::rebuildSortedDependencyGraph(SEditorObjectSet const& objects) { - dependencyGraph_.clear(); - dependencyGraph_.reserve(objects.size()); - SEditorObjectSet sortedObjs; - for (auto obj : objects) { - depthFirstSearch(obj, objects, sortedObjs, dependencyGraph_); - } + dependencyGraph_ = buildSortedDependencyGraph(objects); } void SceneAdaptor::performBulkEngineUpdate(const core::SEditorObjectSet& changedObjects) { @@ -442,9 +347,9 @@ void SceneAdaptor::performBulkEngineUpdate(const core::SEditorObjectSet& changed return error.valueHandle().isRefToProp(&user_types::RenderPass::renderOrder_) || error.valueHandle().isRefToProp(&user_types::BlitPass::renderOrder_); }); - std::map> orderIndices; + std::map> orderIndices; for (auto const& obj : project_->instances()) { - if (obj->isType() || obj->isType()) { + if (obj->isType() || obj->isType()) { int order = obj->get("renderOrder")->asInt(); orderIndices[order].emplace_back(obj); } diff --git a/components/libRamsesBase/src/ramses_adaptor/SceneBackend.cpp b/components/libRamsesBase/src/ramses_adaptor/SceneBackend.cpp index 6845ea55..abd9c46d 100644 --- a/components/libRamsesBase/src/ramses_adaptor/SceneBackend.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/SceneBackend.cpp @@ -9,16 +9,16 @@ */ #include "ramses_adaptor/SceneBackend.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "ramses_base/RamsesFormatter.h" #include "ramses_base/BaseEngineBackend.h" @@ -37,14 +37,14 @@ ramses::RamsesClient* SceneBackend::client() const { return &engine_.client(); } -ramses_base::LogicEngine* SceneBackend::logicEngine() const { - return &engine_.logicEngine(); +ramses::LogicEngine* SceneBackend::logicEngine() const { + return &scene_->logicEngine(); } -void SceneBackend::setScene(Project* project, core::Errors *errors, bool optimizeForExport) { +void SceneBackend::setScene(Project* project, core::Errors* errors, bool optimizeForExport, ramses::sceneId_t sceneId) { scene_.reset(); - scene_ = std::make_unique(client(), logicEngine(), toSceneId(*project->settings()->sceneId_), project, dispatcher_, errors, optimizeForExport); + scene_ = std::make_unique(client(), sceneId, project, dispatcher_, errors, optimizeForExport); } ramses::sceneId_t SceneBackend::toSceneId(int i) { @@ -63,10 +63,14 @@ ramses::sceneId_t SceneBackend::currentSceneId() const { return scene_ ? scene_->sceneId() : ramses::sceneId_t::Invalid(); } -const ramses::Scene* SceneBackend::currentScene() const { +ramses::Scene* SceneBackend::currentScene() const { return scene_->scene(); } +std::optional SceneBackend::getLastError() { + return scene_->scene()->getRamsesClient().getRamsesFramework().getLastError(); +} + void SceneBackend::flush() { if (scene_) { scene_->scene()->flush(); @@ -79,79 +83,62 @@ void SceneBackend::readDataFromEngine(core::DataChangeRecorder& recorder) { } } -bool SceneBackend::discardLogicEngineMessage(std::string_view message) { +bool SceneBackend::discardRamsesMessage(std::string_view message) { if (message.find("has unlinked output") != std::string::npos) { return true; } - if (message.find("has no ingoing links! Node should be deleted or properly linked!") != std::string::npos) { + if (message.find("has no incoming links! Node should be deleted or properly linked!") != std::string::npos) { return true; } if (message.find("has no outgoing links! Node should be deleted or properly linked!") != std::string::npos) { return true; } - return false; -} - - -std::vector SceneBackend::logicEngineFilteredValidation() const { - std::vector filteredWarnings; - std::vector warnings = logicEngine()->validate(); - - for (auto& warning : warnings) { - if (!SceneBackend::discardLogicEngineMessage(warning.message)) { - filteredWarnings.emplace_back(warning); - } + if (message.find("rendergroup does not contain any meshes") != std::string::npos) { + return true; } - return filteredWarnings; + if (message.find("Unused [uniform]") != std::string::npos || + message.find("Unused [in]") != std::string::npos || + message.find("Unused [out]") != std::string::npos) { + return true; + } + return false; } - std::string SceneBackend::ramsesFilteredValidationReport(core::ErrorLevel minLevel) const { - auto report = currentScene()->getValidationReport(minLevel == core::ErrorLevel::ERROR ? ramses::EValidationSeverity_Error : ramses::EValidationSeverity_Warning); + ramses::ValidationReport report; + currentScene()->validate(report); - std::istringstream stream(report); - std::string line; std::string filtered; - while (std::getline(stream, line)) { - if (line.find("rendergroup does not contain any meshes") != std::string::npos) { - continue; - } - // The next two are a workaround for a ramses bug: remove eventually - if (line.find("There is no valid content source set in TextureSampler") != std::string::npos) { + + for (const auto& issue : report.getIssues()) { + if (issue.type == ramses::EIssueType::Warning && minLevel == core::ErrorLevel::ERROR) { continue; } - if (line.find("RenderBuffer") != std::string::npos) { + + if (discardRamsesMessage(issue.message)) { continue; } - filtered.append(line).append("\n"); + + filtered.append(fmt::format("{}: {} '{}': {}\n", + issue.type == ramses::EIssueType::Warning ? "WARNING" : "ERROR", + issue.object->getType(), issue.object->getName(), issue.message)); } return filtered; } core::ErrorLevel SceneBackend::sceneValid() const { - auto status = currentScene()->validate(); - if (status != ramses::StatusOK) { - std::string msg = currentScene()->getStatusMessage(status); - if (msg == "Validation error" && !ramsesFilteredValidationReport(core::ErrorLevel::ERROR).empty()) { - return core::ErrorLevel::ERROR; - } else if (msg == "Validation warning" && !ramsesFilteredValidationReport(core::ErrorLevel::WARNING).empty()) { - return core::ErrorLevel::WARNING; - } - } - if (!logicEngineFilteredValidation().empty()) { + ramses::ValidationReport report; + currentScene()->validate(report); + if (report.hasError() && !ramsesFilteredValidationReport(core::ErrorLevel::ERROR).empty()) { return core::ErrorLevel::ERROR; + } else if (report.hasIssue() && !ramsesFilteredValidationReport(core::ErrorLevel::WARNING).empty()) { + return core::ErrorLevel::WARNING; } return core::ErrorLevel::NONE; } std::string SceneBackend::getValidationReport(core::ErrorLevel minLevel) const { - auto logicErrors = logicEngineFilteredValidation(); - std::string logicErrorMessages; - for (const auto& logicError : logicErrors) { - logicErrorMessages.append(logicError.message).append("\n"); - } - - return ramsesFilteredValidationReport(minLevel) + logicErrorMessages; + return ramsesFilteredValidationReport(minLevel); } uint64_t SceneBackend::currentSceneIdValue() const { @@ -159,27 +146,27 @@ uint64_t SceneBackend::currentSceneIdValue() const { } namespace { -ramses::Node* getParent(ramses::RamsesObject* obj) { - if (auto node{dynamic_cast(obj)}) { - return node->getParent(); + const ramses::Node* getParent(ramses::RamsesObject* obj) { + if (auto node{ dynamic_cast(obj) }) { + return node->getParent(); + } + return nullptr; } - return nullptr; -} } // namespace std::vector SceneBackend::getSceneItemDescriptions() const { - ramses::SceneObjectIterator it{*scene_->scene()}; + ramses::SceneObjectIterator it{ *scene_->scene() }; std::vector ramsesObjects{}; while (auto object = it.getNext()) { - if (object->isOfType(ramses::ERamsesObjectType_Node)) { + if (object->isOfType(ramses::ERamsesObjectType::Node)) { if (!getParent(object)) { // If we hit a root parent we separatly iterate over it - ramses::SceneGraphIterator graphIt{*ramses::RamsesUtils::TryConvert(*object), ramses::ETreeTraversalStyle_BreadthFirst}; + ramses::SceneGraphIterator graphIt{ *object->as(), ramses::ETreeTraversalStyle::BreadthFirst }; while (auto node = graphIt.getNext()) { ramsesObjects.push_back(node); } } - } else { + } else if (!object->isOfType(ramses::ERamsesObjectType::LogicEngine)) { ramsesObjects.push_back(object); } } @@ -188,7 +175,7 @@ std::vector SceneBackend::getSceneItemDescriptions( std::map parents{}; for (const auto object : ramsesObjects) { - ramses::RamsesObject* ramsesParent = getParent(object); + const ramses::RamsesObject* ramsesParent = getParent(object); int parentIndex = ramsesParent ? parents[ramsesParent] : -1; sceneItems.emplace_back(fmt::format("{}", object->getType()), object->getName(), parentIndex); parents[object] = static_cast(sceneItems.size() - 1); @@ -218,72 +205,72 @@ std::vector SceneBackend::getSceneItemDescriptions( sceneItems[appIdx].parentIndex_ = meshnodeIdx; } - auto geometryBinding = meshnode->getGeometryBinding(); - auto geomIdx = parents[geometryBinding]; + auto geometry = meshnode->getGeometry(); + auto geomIdx = parents[geometry]; sceneItems[geomIdx].parentIndex_ = meshnodeIdx; } } - for (const auto* module : logicEngine()->getCollection()) { - sceneItems.emplace_back("LuaScriptModule", module->getName().data(), -1); + for (const auto* module : logicEngine()->getCollection()) { + sceneItems.emplace_back("LuaScriptModule", module->getName(), -1); } - for (const auto* script : logicEngine()->getCollection()) { - sceneItems.emplace_back("LuaScript", script->getName().data(), -1); + for (const auto* script : logicEngine()->getCollection()) { + sceneItems.emplace_back("LuaScript", script->getName(), -1); } - for (const auto* interface: logicEngine()->getCollection()) { - sceneItems.emplace_back("LuaInterface", interface->getName().data(), -1); + for (const auto* interface: logicEngine()->getCollection()) { + sceneItems.emplace_back("LuaInterface", interface->getName(), -1); } - for (const auto* dataArray : logicEngine()->getCollection()) { - sceneItems.emplace_back("DataArray", dataArray->getName().data(), -1); + for (const auto* dataArray : logicEngine()->getCollection()) { + sceneItems.emplace_back("DataArray", dataArray->getName(), -1); } - for (const auto* animation : logicEngine()->getCollection()) { - sceneItems.emplace_back("Animation", animation->getName().data(), -1); + for (const auto* animation : logicEngine()->getCollection()) { + sceneItems.emplace_back("Animation", animation->getName(), -1); } - for (const auto* binding : logicEngine()->getCollection()) { + for (const auto* binding : logicEngine()->getCollection()) { auto parentIdx = parents[&binding->getRamsesAppearance()]; - sceneItems.emplace_back("AppearanceBinding", binding->getName().data(), parentIdx); + sceneItems.emplace_back("AppearanceBinding", binding->getName(), parentIdx); } - for (const auto* binding : logicEngine()->getCollection()) { + for (const auto* binding : logicEngine()->getCollection()) { auto parentIdx = parents[&binding->getRamsesNode()]; - sceneItems.emplace_back("NodeBinding", binding->getName().data(), parentIdx); + sceneItems.emplace_back("NodeBinding", binding->getName(), parentIdx); } - for (const auto* binding : logicEngine()->getCollection()) { + for (const auto* binding : logicEngine()->getCollection()) { auto parentIdx = parents[&binding->getRamsesMeshNode()]; - sceneItems.emplace_back("MeshNodeBinding", binding->getName().data(), parentIdx); + sceneItems.emplace_back("MeshNodeBinding", binding->getName(), parentIdx); } - for (const auto* binding : logicEngine()->getCollection()) { + for (const auto* binding : logicEngine()->getCollection()) { auto parentIdx = parents[&binding->getRamsesCamera()]; - sceneItems.emplace_back("CameraBinding", binding->getName().data(), parentIdx); + sceneItems.emplace_back("CameraBinding", binding->getName(), parentIdx); } - for (const auto* binding : logicEngine()->getCollection()) { + for (const auto* binding : logicEngine()->getCollection()) { auto parentIdx = parents[&binding->getRamsesRenderPass()]; - sceneItems.emplace_back("RenderPassBinding", binding->getName().data(), parentIdx); + sceneItems.emplace_back("RenderPassBinding", binding->getName(), parentIdx); } - for (const auto* timer : logicEngine()->getCollection()) { - sceneItems.emplace_back("Timer", timer->getName().data(), -1); + for (const auto* timer : logicEngine()->getCollection()) { + sceneItems.emplace_back("Timer", timer->getName(), -1); } - for (const auto* anchorPoint : logicEngine()->getCollection()) { - sceneItems.emplace_back("AnchorPoint", anchorPoint->getName().data(), -1); + for (const auto* anchorPoint : logicEngine()->getCollection()) { + sceneItems.emplace_back("AnchorPoint", anchorPoint->getName(), -1); } - for (const auto* binding : logicEngine()->getCollection()) { + for (const auto* binding : logicEngine()->getCollection()) { auto parentIdx = parents[&binding->getRamsesRenderGroup()]; - sceneItems.emplace_back("RenderGroupBinding", binding->getName().data(), parentIdx); + sceneItems.emplace_back("RenderGroupBinding", binding->getName(), parentIdx); } - for (const auto* skin : logicEngine()->getCollection()) { - sceneItems.emplace_back("SkinBinding", skin->getName().data(), -1); + for (const auto* skin : logicEngine()->getCollection()) { + sceneItems.emplace_back("SkinBinding", skin->getName(), -1); } return sceneItems; diff --git a/components/libRamsesBase/src/ramses_adaptor/SkinAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/SkinAdaptor.cpp index ed5825ef..7d0e4bc8 100644 --- a/components/libRamsesBase/src/ramses_adaptor/SkinAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/SkinAdaptor.cpp @@ -18,7 +18,7 @@ namespace raco::ramses_adaptor { -SkinAdaptor::SkinAdaptor(SceneAdaptor* sceneAdaptor, raco::user_types::SSkin skin) +SkinAdaptor::SkinAdaptor(SceneAdaptor* sceneAdaptor, user_types::SSkin skin) : UserTypeObjectAdaptor(sceneAdaptor, skin), subscriptions_{ sceneAdaptor->dispatcher()->registerOn(core::ValueHandle{editorObject(), &user_types::Skin::objectName_}, [this]() { tagDirty(); }), @@ -33,12 +33,12 @@ bool SkinAdaptor::sync(core::Errors* errors) { skinBindings_.clear(); - std::vector jointBindings; - const auto& jointsTable = editorObject()->joints_.asTable(); + std::vector jointBindings; + const auto& jointsArray = editorObject()->joints_; bool emptySlots = false; - for (auto index = 0; index < jointsTable.size(); index++) { - auto node = jointsTable.get(index)->asRef(); - raco::ramses_base::RamsesNodeBinding nodeBinding = lookupNodeBinding(sceneAdaptor_, node); + for (auto index = 0; index < jointsArray->size(); index++) { + auto node = **jointsArray->get(index); + ramses_base::RamsesNodeBinding nodeBinding = lookupNodeBinding(sceneAdaptor_, node); if (nodeBinding) { if (index != jointBindings.size()) { emptySlots = true; @@ -54,13 +54,13 @@ bool SkinAdaptor::sync(core::Errors* errors) { if (data) { if (emptySlots) { std::string errorMsg = fmt::format("Cannot create Skin '{}': all joints nodes must be consecutive and valid nodes", editorObject()->objectName()); - LOG_ERROR(raco::log_system::RAMSES_ADAPTOR, errorMsg); + LOG_ERROR(log_system::RAMSES_ADAPTOR, errorMsg); errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, {editorObject()}, errorMsg); } else { std::vector targetAdaptors; - const auto& targetsTable = editorObject()->targets_.asTable(); - for (auto index = 0; index < targetsTable.size(); index++) { - auto meshnode = targetsTable.get(index)->asRef(); + const auto& targetsArray = editorObject()->targets_; + for (auto index = 0; index < targetsArray->size(); index++) { + auto meshnode = **targetsArray->get(index); auto meshNodeAdaptor = sceneAdaptor_->lookup(meshnode); if (meshNodeAdaptor) { targetAdaptors.emplace_back(meshNodeAdaptor); @@ -73,24 +73,23 @@ bool SkinAdaptor::sync(core::Errors* errors) { const auto meshNodeAdaptor = targetAdaptors[index]; if (auto appearance = meshNodeAdaptor->privateAppearance()) { if (auto appearanceBinding = meshNodeAdaptor->appearanceBinding()) { - ramses::UniformInput uniform; - (*appearance)->getEffect().findUniformInput(raco::core::SkinData::INV_BIND_MATRICES_UNIFORM_NAME, uniform); + ramses::UniformInput uniform = (*appearance)->getEffect().findUniformInput(core::SkinData::INV_BIND_MATRICES_UNIFORM_NAME).value(); std::string name = targetAdaptors.size() == 1 ? editorObject()->objectName() : fmt::format("{}_SkinBinding_{}", editorObject()->objectName(), index); auto skinBinding = ramses_base::ramsesSkinBinding(&sceneAdaptor_->logicEngine(), jointBindings, data->inverseBindMatrices, appearanceBinding, uniform, name, editorObject()->objectIDAsRamsesLogicID()); if (skinBinding) { skinBindings_.emplace_back(skinBinding); } else { - errorMessages.emplace_back(sceneAdaptor_->logicEngine().getErrors().at(0).message); + errorMessages.emplace_back(sceneAdaptor_->scene()->getRamsesClient().getRamsesFramework().getLastError().value().message); } } else { std::string errorMsg = fmt::format("Cannot create Skin '{}': private material of the meshnode '{}' doesn't have a valid AppearanceBinding", editorObject()->objectName(), meshNodeAdaptor->editorObject()->objectName()); - LOG_ERROR(raco::log_system::RAMSES_ADAPTOR, errorMsg); + LOG_ERROR(log_system::RAMSES_ADAPTOR, errorMsg); errorMessages.emplace_back(errorMsg); } } else { std::string errorMsg = fmt::format("Cannot create Skin '{}': meshnode '{}' must have a valid private material", editorObject()->objectName(), meshNodeAdaptor->editorObject()->objectName()); - LOG_ERROR(raco::log_system::RAMSES_ADAPTOR, errorMsg); + LOG_ERROR(log_system::RAMSES_ADAPTOR, errorMsg); errorMessages.emplace_back(errorMsg); } } @@ -104,7 +103,7 @@ bool SkinAdaptor::sync(core::Errors* errors) { } else { std::string errorMsg = fmt::format("Cannot create Skin '{}': no meshnodes selected", editorObject()->objectName()); - LOG_ERROR(raco::log_system::RAMSES_ADAPTOR, errorMsg); + LOG_ERROR(log_system::RAMSES_ADAPTOR, errorMsg); errors->addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, {editorObject()}, errorMsg); } } @@ -117,7 +116,7 @@ bool SkinAdaptor::sync(core::Errors* errors) { std::vector SkinAdaptor::getExportInformation() const { std::vector info; for (auto binding : skinBindings_) { - info.emplace_back(ExportInformation{"SkinBinding", binding->getName().data()}); + info.emplace_back(ExportInformation{"SkinBinding", binding->getName()}); } return info; } diff --git a/components/libRamsesBase/src/ramses_adaptor/TextureExternalAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/TextureExternalAdaptor.cpp index fccf4412..3ff3b987 100644 --- a/components/libRamsesBase/src/ramses_adaptor/TextureExternalAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/TextureExternalAdaptor.cpp @@ -34,7 +34,7 @@ bool TextureExternalAdaptor::sync(core::Errors* errors) { auto magSamplMethod = static_cast(*editorObject()->magSamplingMethod_); auto ramsesMagSamplMethod = ramses_base::enumerationTranslationTextureSamplingMethod.at(magSamplMethod); - reset(ramsesTextureSamplerExternal(sceneAdaptor_->scene(), ramsesMinSamplMethod, ramsesMagSamplMethod)); + reset(ramsesTextureSamplerExternal(sceneAdaptor_->scene(), ramsesMinSamplMethod, ramsesMagSamplMethod, {}, editorObject()->objectIDAsRamsesLogicID())); tagDirty(false); return true; diff --git a/components/libRamsesBase/src/ramses_adaptor/TextureSamplerAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/TextureSamplerAdaptor.cpp index 2e1a817f..45bef45e 100644 --- a/components/libRamsesBase/src/ramses_adaptor/TextureSamplerAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/TextureSamplerAdaptor.cpp @@ -17,7 +17,7 @@ #include "utils/FileUtils.h" #include #include -#include +#include namespace raco::ramses_adaptor { @@ -60,14 +60,14 @@ bool TextureSamplerAdaptor::sync(core::Errors* errors) { errors->removeError({editorObject()->shared_from_this()}); errors->removeError({editorObject()->shared_from_this(), &user_types::Texture::textureFormat_}); - raco::ramses_base::PngDecodingInfo decodingInfo; + ramses_base::PngDecodingInfo decodingInfo; textureData_ = nullptr; std::string uri = editorObject()->uri_.asString(); if (!uri.empty()) { // do not clear errors here, this is done earlier in Texture textureData_ = createTexture(errors, decodingInfo); if (!textureData_) { - LOG_ERROR(raco::log_system::RAMSES_ADAPTOR, "Texture '{}': Couldn't load png file from '{}'", editorObject()->objectName(), uri); + LOG_ERROR(log_system::RAMSES_ADAPTOR, "Texture '{}': Couldn't load png file from '{}'", editorObject()->objectName(), uri); errors->addError(core::ErrorCategory::PARSING, core::ErrorLevel::ERROR, {editorObject()->shared_from_this(), &user_types::Texture::uri_}, "Image file could not be loaded."); } } @@ -109,7 +109,9 @@ bool TextureSamplerAdaptor::sync(core::Errors* errors) { ramsesMinSamplMethod, ramsesMagSamplMethod, textureData_, - (*editorObject()->anisotropy_ >= 1 ? *editorObject()->anisotropy_ : 1)); + (*editorObject()->anisotropy_ >= 1 ? *editorObject()->anisotropy_ : 1), + {}, + editorObject()->objectIDAsRamsesLogicID()); reset(std::move(textureSampler)); } else { reset(nullptr); @@ -157,16 +159,17 @@ RamsesTexture2D TextureSamplerAdaptor::createTexture(core::Errors* errors, PngDe if (*editorObject()->flipTexture_) { flipDecodedPicture(rawMipData, ramsesTextureFormatToChannelAmount(swizzleTextureFormat), decodingInfo.width * std::pow(0.5, i), decodingInfo.height * std::pow(0.5, i), decodingInfo.bitdepth); } - mipDatas.emplace_back(static_cast(rawMipData.size()), rawMipData.data()); + mipDatas.emplace_back(reinterpret_cast(rawMipData.data()), reinterpret_cast(rawMipData.data()) + rawMipData.size()); } - return ramsesTexture2D(sceneAdaptor_->scene(), swizzleTextureFormat, decodingInfo.width, decodingInfo.height, *editorObject()->mipmapLevel_, mipDatas.data(), *editorObject()->generateMipmaps_, swizzle, ramses::ResourceCacheFlag_DoNotCache, nullptr); + return ramsesTexture2D(sceneAdaptor_->scene(), swizzleTextureFormat, decodingInfo.width, decodingInfo.height, mipDatas, *editorObject()->generateMipmaps_, swizzle, {}, editorObject()->objectIDAsRamsesLogicID()); } RamsesTexture2D TextureSamplerAdaptor::getFallbackTexture() { auto& data = getFallbackTextureData(*editorObject()->flipTexture_); - ramses::MipLevelData mipLevelData(static_cast(data.size()), data.data()); - ramses::Texture2D* textureData = sceneAdaptor_->scene()->createTexture2D(ramses::ETextureFormat::RGBA8, FALLBACK_TEXTURE_SIZE_PX, FALLBACK_TEXTURE_SIZE_PX, 1, &mipLevelData, false, {}, ramses::ResourceCacheFlag_DoNotCache, nullptr); + std::vector mipDatas; + mipDatas.emplace_back(reinterpret_cast(data.data()), reinterpret_cast(data.data()) + data.size()); + ramses::Texture2D* textureData = sceneAdaptor_->scene()->createTexture2D(ramses::ETextureFormat::RGBA8, FALLBACK_TEXTURE_SIZE_PX, FALLBACK_TEXTURE_SIZE_PX, mipDatas, false, {}, {}); return {textureData, createRamsesObjectDeleter(sceneAdaptor_->scene())}; } diff --git a/components/libRamsesBase/src/ramses_adaptor/TimerAdaptor.cpp b/components/libRamsesBase/src/ramses_adaptor/TimerAdaptor.cpp index 5661a3f0..ccd4e625 100644 --- a/components/libRamsesBase/src/ramses_adaptor/TimerAdaptor.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/TimerAdaptor.cpp @@ -16,9 +16,9 @@ namespace raco::ramses_adaptor { using namespace raco::ramses_base; -TimerAdaptor::TimerAdaptor(SceneAdaptor* sceneAdaptor, raco::user_types::STimer timer) +TimerAdaptor::TimerAdaptor(SceneAdaptor* sceneAdaptor, user_types::STimer timer) : UserTypeObjectAdaptor{sceneAdaptor, timer}, - timerNode_{raco::ramses_base::ramsesTimer(&sceneAdaptor_->logicEngine(), editorObject_->objectName(), editorObject_->objectIDAsRamsesLogicID())}, + timerNode_{ramses_base::ramsesTimer(&sceneAdaptor_->logicEngine(), editorObject_->objectName(), editorObject_->objectIDAsRamsesLogicID())}, dirtySubscription_{ sceneAdaptor->dispatcher()->registerOnPreviewDirty(editorObject_, [this]() { tagDirty(); })}, nameSubscription_{ @@ -26,11 +26,11 @@ TimerAdaptor::TimerAdaptor(SceneAdaptor* sceneAdaptor, raco::user_types::STimer inputSubscription_{ sceneAdaptor->dispatcher()->registerOnChildren(core::ValueHandle{editorObject_, &user_types::Timer::inputs_}, [this](auto) { tagDirty(); })} {} -void TimerAdaptor::getLogicNodes(std::vector& logicNodes) const { +void TimerAdaptor::getLogicNodes(std::vector& logicNodes) const { logicNodes.emplace_back(timerNode_.get()); } -const rlogic::Property* TimerAdaptor::getProperty(const std::vector& propertyNamesVector) { +ramses::Property* TimerAdaptor::getProperty(const std::vector& propertyNamesVector) { if (timerNode_) { const auto& propGroup = propertyNamesVector.front(); if (propGroup == "inputs") { @@ -54,7 +54,7 @@ bool TimerAdaptor::sync(core::Errors* errors) { errors->removeError({editorObject_->shared_from_this()}); if (timerNode_->getName() != editorObject_->objectName()) { - timerNode_ = raco::ramses_base::ramsesTimer(&sceneAdaptor_->logicEngine(), editorObject_->objectName(), editorObject_->objectIDAsRamsesLogicID()); + timerNode_ = ramses_base::ramsesTimer(&sceneAdaptor_->logicEngine(), editorObject_->objectName(), editorObject_->objectIDAsRamsesLogicID()); } timerNode_->getInputs()->getChild("ticker_us")->set(editorObject_->inputs_->get("ticker_us")->asInt64()); @@ -73,7 +73,7 @@ std::vector TimerAdaptor::getExportInformation() const { return {}; } - return {ExportInformation{"Timer", timerNode_->getName().data()}}; + return {ExportInformation{"Timer", timerNode_->getName()}}; } }; // namespace raco::ramses_adaptor diff --git a/components/libRamsesBase/src/ramses_adaptor/utilities.cpp b/components/libRamsesBase/src/ramses_adaptor/utilities.cpp index 28c061dc..16c0a3b5 100644 --- a/components/libRamsesBase/src/ramses_adaptor/utilities.cpp +++ b/components/libRamsesBase/src/ramses_adaptor/utilities.cpp @@ -15,6 +15,8 @@ #include "ramses_adaptor/OrthographicCameraAdaptor.h" #include "ramses_adaptor/PerspectiveCameraAdaptor.h" +#include "core/MeshCacheInterface.h" + namespace raco::ramses_adaptor { raco::ramses_base::RamsesNodeBinding lookupNodeBinding(const SceneAdaptor* sceneAdaptor, core::SEditorObject node) { @@ -30,4 +32,63 @@ raco::ramses_base::RamsesNodeBinding lookupNodeBinding(const SceneAdaptor* scene return {}; } +void depthFirstSearch(core::SEditorObject object, core::SEditorObjectSet const& instances, core::SEditorObjectSet& sortedObjs, std::vector& outSorted); + +void depthFirstSearch(data_storage::ReflectionInterface* object, DependencyNode& item, core::SEditorObjectSet const& instances, core::SEditorObjectSet& sortedObjs, std::vector& outSorted) { + for (size_t index = 0; index < object->size(); index++) { + auto v = (*object)[index]; + if (v->type() == data_storage::PrimitiveType::Ref) { + auto refValue = v->asRef(); + if (refValue && instances.find(refValue) != instances.end()) { + depthFirstSearch(refValue, instances, sortedObjs, outSorted); + item.referencedObjects.insert(refValue); + } + } else if (data_storage::hasTypeSubstructure(v->type())) { + depthFirstSearch(&v->getSubstructure(), item, instances, sortedObjs, outSorted); + } + } +} + +void depthFirstSearch(core::SEditorObject object, core::SEditorObjectSet const& instances, core::SEditorObjectSet& sortedObjs, std::vector& outSorted) { + using namespace raco::core; + + if (sortedObjs.find(object) != sortedObjs.end()) { + return; + } + + DependencyNode item; + item.object = object; + depthFirstSearch(object.get(), item, instances, sortedObjs, outSorted); + + outSorted.emplace_back(item); + sortedObjs.insert(item.object); +} + +std::vector buildSortedDependencyGraph(core::SEditorObjectSet const& objects) { + std::vector graph; + graph.reserve(objects.size()); + core::SEditorObjectSet sortedObjs; + for (auto obj : objects) { + depthFirstSearch(obj, objects, sortedObjs, graph); + } + return graph; +} + +ramses_base::RamsesArrayResource arrayResourceFromAttribute(ramses::Scene* scene, core::SharedMeshData mesh, int attribIndex, std::string_view name) { + auto buffer = mesh->attribBuffer(attribIndex); + auto elementCount = mesh->attribElementCount(attribIndex); + + switch (mesh->attribDataType(attribIndex)) { + case core::MeshData::VertexAttribDataType::VAT_Float: + return ramses_base::ramsesArrayResource(scene, elementCount, reinterpret_cast(buffer), name); + case core::MeshData::VertexAttribDataType::VAT_Float2: + return ramses_base::ramsesArrayResource(scene, elementCount, reinterpret_cast(buffer), name); + case core::MeshData::VertexAttribDataType::VAT_Float3: + return ramses_base::ramsesArrayResource(scene, elementCount, reinterpret_cast(buffer), name); + case core::MeshData::VertexAttribDataType::VAT_Float4: + return ramses_base::ramsesArrayResource(scene, elementCount, reinterpret_cast(buffer), name); + } + return {}; +} + } // namespace raco::ramses_adaptor \ No newline at end of file diff --git a/components/libRamsesBase/src/ramses_base/BaseEngineBackend.cpp b/components/libRamsesBase/src/ramses_base/BaseEngineBackend.cpp index 31c30cfd..38cbbcbd 100644 --- a/components/libRamsesBase/src/ramses_base/BaseEngineBackend.cpp +++ b/components/libRamsesBase/src/ramses_base/BaseEngineBackend.cpp @@ -14,52 +14,78 @@ namespace raco::ramses_base { +const ramses::EFeatureLevel BaseEngineBackend::minFeatureLevel = ramses::EFeatureLevel::EFeatureLevel_01; + +// TODO if the maxFeatureLevel increases beyond 1 we need to create and/or check tests +// - feature level downgrade tests +// - python api: in pyt_general.py -> test_load_raco_2x_feature_levels + +const ramses::EFeatureLevel BaseEngineBackend::maxFeatureLevel = ramses::EFeatureLevel::EFeatureLevel_01; + const std::string BaseEngineBackend::featureLevelDescriptions = -R"(1 - LogicEngine v1.0.3 -2 - LogicEngine v1.1.0 - - Added AnchorPoint - - Added RamsesRenderPassBinding - - Added 'enabled' input property to RamsesNodeBinding - - Added createRamsesCameraBindingWithFrustumPlanes -3 - LogicEngine v1.2.0 - - Added RenderGroupBinding -4 - LogicEngine v1.3.0 - - Added SkinBinding -5 - LogicEngine v1.4.0 - - Added support for LuaModules in LuaInterfaces - - Added MeshNodeBinding +R"(1 - Ramses v28.0.0 )"; -BaseEngineBackend::BaseEngineBackend( - rlogic::EFeatureLevel featureLevel, - const ramses::RamsesFrameworkConfig& frameworkConfig, - const char* applicationName) - : framework_{frameworkConfig}, - logicEngine_(std::make_unique(featureLevel)), - client_{framework_.createClient(applicationName), [=](ramses::RamsesClient* c) { framework_.destroyClient(*c); }}, - scene_{client_->createScene(BuildOptions::internalSceneId), [this](ramses::Scene* scene) { client_->destroy(*scene); }}, + +ramses::RamsesFrameworkConfig& BaseEngineBackend::defaultRamsesFrameworkConfig() { + // The feature level used here is just a placeholder. The real featureLevel is set in BaseEngineBackend::setup. + static ramses::RamsesFrameworkConfig config(BaseEngineBackend::minFeatureLevel); + config.setLogLevel("RAPI", ramses::ELogLevel::Trace); + config.setLogLevel("RPER", ramses::ELogLevel::Off); + config.setLogLevel("RRND", ramses::ELogLevel::Debug); + config.setLogLevel("RFRA", ramses::ELogLevel::Off); + config.setLogLevel("RCOM", ramses::ELogLevel::Info); + config.setLogLevelConsole(ramses::ELogLevel::Off); + config.setPeriodicLogInterval(std::chrono::seconds(0)); + return config; +} + +BaseEngineBackend::BaseEngineBackend(const ramses::RamsesFrameworkConfig& frameworkConfig, const char* applicationName) + : frameworkConfig_(frameworkConfig), + applicationName_(applicationName), coreInterface_{this} { } BaseEngineBackend::~BaseEngineBackend() { - if (framework_.isConnected()) { - framework_.disconnect(); + reset(); +} + +void BaseEngineBackend::reset() { + coreInterface_.clearModuleCache(); + if (framework_ && framework_->isConnected()) { + framework_->disconnect(); } + + logicEngine_.reset(); + scene_.reset(); + client_.reset(); + + framework_.reset(); +} + +void BaseEngineBackend::setup(ramses::EFeatureLevel featureLevel) { + ramses::RamsesFrameworkConfig config(frameworkConfig_); + config.setFeatureLevel(featureLevel); + framework_ = std::make_unique(config); + + client_ = UniqueClient(framework_->createClient(applicationName_.c_str()), [this](ramses::RamsesClient* c) { framework_->destroyClient(*c); }); + scene_ = UniqueScene(client_->createScene(BuildOptions::internalSceneId), [this](ramses::Scene* scene) { client_->destroy(*scene); }); + logicEngine_ = UniqueLogicEngine(scene_->createLogicEngine(), [this](ramses::LogicEngine* logicEngine) { scene_->destroy(*logicEngine); }); } + bool BaseEngineBackend::connect() { - LOG_INFO(raco::log_system::RAMSES_BACKEND, "LogicEngine feature level = {}.", static_cast(getFeatureLevel())); - if (framework_.connect() != ramses::StatusOK) { - LOG_ERROR(raco::log_system::RAMSES_BACKEND, "Connection to ramses::RamsesFramework failed."); + if (!framework_->connect()) { + LOG_ERROR(log_system::RAMSES_BACKEND, "Connection to ramses::RamsesFramework failed."); return true; } else { - LOG_INFO(raco::log_system::RAMSES_BACKEND, "Connection to ramses::RamsesFramework successful."); + LOG_INFO(log_system::RAMSES_BACKEND, "Connection to ramses::RamsesFramework successful."); return false; } } ramses::RamsesFramework& BaseEngineBackend::framework() { - return framework_; + return *framework_; } ramses::Scene& BaseEngineBackend::internalScene() { @@ -70,24 +96,34 @@ ramses::RamsesClient& BaseEngineBackend::client() { return *client_.get(); } -LogicEngine& BaseEngineBackend::logicEngine() { - return *logicEngine_; +core::EngineInterface* BaseEngineBackend::coreInterface() { + return &coreInterface_; } -raco::core::EngineInterface* BaseEngineBackend::coreInterface() { - return &coreInterface_; +ramses::LogicEngine* BaseEngineBackend::logicEngine() { + return logicEngine_.get(); } -void BaseEngineBackend::setFeatureLevel(rlogic::EFeatureLevel newFeatureLevel) { - if (getFeatureLevel() != newFeatureLevel) { - logicEngine_ = std::make_unique(newFeatureLevel); - LOG_INFO(raco::log_system::RAMSES_BACKEND, "LogicEngine feature level = {}.", static_cast(getFeatureLevel())); - } +ramses::sceneId_t BaseEngineBackend::abstractSceneId() { + return BuildOptions::abstractSceneId; } -rlogic::EFeatureLevel BaseEngineBackend::getFeatureLevel() { - return logicEngine_->getFeatureLevel(); +ramses::EFeatureLevel BaseEngineBackend::featureLevel() const { + return featureLevel_; } +void BaseEngineBackend::setFeatureLevel(ramses::EFeatureLevel newFeatureLevel) { + if (!framework_ || featureLevel_ != newFeatureLevel) { + reset(); + + setup(newFeatureLevel); + + // Connect needs to be called after the renderer is created + // Additonally there can only be one renderer per framework + connect(); + + featureLevel_ = newFeatureLevel; + } +} } // namespace raco::ramses_base diff --git a/components/libRamsesBase/src/ramses_base/CoreInterfaceImpl.cpp b/components/libRamsesBase/src/ramses_base/CoreInterfaceImpl.cpp index 58c1cd83..e5270649 100644 --- a/components/libRamsesBase/src/ramses_base/CoreInterfaceImpl.cpp +++ b/components/libRamsesBase/src/ramses_base/CoreInterfaceImpl.cpp @@ -22,29 +22,29 @@ #include "user_types/Enumerations.h" #include "user_types/LuaScriptModule.h" -#include -#include -#include -#include +#include +#include +#include +#include namespace raco::ramses_base { namespace { -void fillLuaScriptInterface(std::vector& interface, const rlogic::Property* property) { - static const std::map typeMap = { - {rlogic::EPropertyType::Float, raco::core::EnginePrimitive::Double}, - {rlogic::EPropertyType::Vec2f, raco::core::EnginePrimitive::Vec2f}, - {rlogic::EPropertyType::Vec3f, raco::core::EnginePrimitive::Vec3f}, - {rlogic::EPropertyType::Vec4f, raco::core::EnginePrimitive::Vec4f}, - {rlogic::EPropertyType::Int32, raco::core::EnginePrimitive::Int32}, - {rlogic::EPropertyType::Int64, raco::core::EnginePrimitive::Int64}, - {rlogic::EPropertyType::Vec2i, raco::core::EnginePrimitive::Vec2i}, - {rlogic::EPropertyType::Vec3i, raco::core::EnginePrimitive::Vec3i}, - {rlogic::EPropertyType::Vec4i, raco::core::EnginePrimitive::Vec4i}, - {rlogic::EPropertyType::String, raco::core::EnginePrimitive::String}, - {rlogic::EPropertyType::Bool, raco::core::EnginePrimitive::Bool}, - {rlogic::EPropertyType::Struct, raco::core::EnginePrimitive::Struct}, - {rlogic::EPropertyType::Array, raco::core::EnginePrimitive::Array}}; +void fillLuaScriptInterface(std::vector& interface, const ramses::Property* property) { + static const std::map typeMap = { + {ramses::EPropertyType::Float, core::EnginePrimitive::Double}, + {ramses::EPropertyType::Vec2f, core::EnginePrimitive::Vec2f}, + {ramses::EPropertyType::Vec3f, core::EnginePrimitive::Vec3f}, + {ramses::EPropertyType::Vec4f, core::EnginePrimitive::Vec4f}, + {ramses::EPropertyType::Int32, core::EnginePrimitive::Int32}, + {ramses::EPropertyType::Int64, core::EnginePrimitive::Int64}, + {ramses::EPropertyType::Vec2i, core::EnginePrimitive::Vec2i}, + {ramses::EPropertyType::Vec3i, core::EnginePrimitive::Vec3i}, + {ramses::EPropertyType::Vec4i, core::EnginePrimitive::Vec4i}, + {ramses::EPropertyType::String, core::EnginePrimitive::String}, + {ramses::EPropertyType::Bool, core::EnginePrimitive::Bool}, + {ramses::EPropertyType::Struct, core::EnginePrimitive::Struct}, + {ramses::EPropertyType::Array, core::EnginePrimitive::Array}}; interface.reserve(property->getChildCount()); for (int i{0}; i < property->getChildCount(); i++) { auto child{property->getChild(i)}; @@ -59,18 +59,22 @@ void fillLuaScriptInterface(std::vector& interfac } } // namespace -CoreInterfaceImpl::CoreInterfaceImpl(BaseEngineBackend* backend) : backend_{backend}, logicEngine_(std::make_unique()) {} +CoreInterfaceImpl::CoreInterfaceImpl(BaseEngineBackend* backend) : backend_{backend} {} -bool CoreInterfaceImpl::parseShader(const std::string& vertexShader, const std::string& geometryShader, const std::string& fragmentShader, const std::string& shaderDefines, raco::core::PropertyInterfaceList& outUniforms, raco::core::PropertyInterfaceList& outAttributes, std::string& outError) { - return raco::ramses_base::parseShaderText(backend_->internalScene(), vertexShader, geometryShader, fragmentShader, shaderDefines, outUniforms, outAttributes, outError); +ramses::LogicEngine* CoreInterfaceImpl::logicEngine() { + return backend_->logicEngine(); } -std::tuple CoreInterfaceImpl::createFullLuaConfig(const std::vector& stdModules, const raco::data_storage::Table& modules) { - rlogic::LuaConfig luaConfig = createLuaConfig(stdModules); +bool CoreInterfaceImpl::parseShader(const std::string& vertexShader, const std::string& geometryShader, const std::string& fragmentShader, const std::string& shaderDefines, core::PropertyInterfaceList& outUniforms, core::PropertyInterfaceList& outAttributes, std::string& outError) { + return ramses_base::parseShaderText(backend_->internalScene(), vertexShader, geometryShader, fragmentShader, shaderDefines, outUniforms, outAttributes, outError); +} + +std::tuple CoreInterfaceImpl::createFullLuaConfig(const std::vector& stdModules, const data_storage::Table& modules) { + ramses::LuaConfig luaConfig = createLuaConfig(stdModules); for (auto i = 0; i < modules.size(); ++i) { if (auto moduleRef = modules.get(i)->asRef()) { - const auto module = moduleRef->as(); + const auto module = moduleRef->as(); if (module->isValid()) { auto it = cachedModules_.find(module); assert(it != cachedModules_.end()); @@ -90,15 +94,15 @@ std::tuple CoreInterfaceImpl::createFullLuaConfig(const return {luaConfig, true}; } -bool CoreInterfaceImpl::parseLuaScript(const std::string& luaScript, const std::string& scriptName, const std::vector& stdModules, const raco::data_storage::Table& modules, raco::core::PropertyInterfaceList& outInputs, raco::core::PropertyInterfaceList& outOutputs, std::string& outError) { +bool CoreInterfaceImpl::parseLuaScript(const std::string& luaScript, const std::string& scriptName, const std::vector& stdModules, const data_storage::Table& modules, core::PropertyInterfaceList& outInputs, core::PropertyInterfaceList& outOutputs, std::string& outError) { auto [luaConfig, valid] = createFullLuaConfig(stdModules, modules); if (!valid) { return false; } - const auto script = logicEngine_->createLuaScript(luaScript, luaConfig, scriptName); + const auto script = logicEngine()->createLuaScript(luaScript, luaConfig, scriptName); if (!script) { - outError = logicEngine_->getErrors().at(0).message; + outError = logicEngine()->getScene().getRamsesClient().getRamsesFramework().getLastError().value().message; return false; } @@ -108,32 +112,24 @@ bool CoreInterfaceImpl::parseLuaScript(const std::string& luaScript, const std:: if (const auto outputs = script->getOutputs()) { fillLuaScriptInterface(outOutputs, outputs); } - auto status = logicEngine_->destroy(*script); + auto status = logicEngine()->destroy(*script); if (!status) { - LOG_ERROR(raco::log_system::RAMSES_BACKEND, "Deleting LogicEngine object failed: {}", LogicEngineErrors{*logicEngine_}); + auto error = logicEngine()->getScene().getRamsesClient().getRamsesFramework().getLastError().value(); + LOG_ERROR(log_system::RAMSES_BACKEND, "Deleting LogicEngine object failed: {}", error.message); } return true; } -bool CoreInterfaceImpl::parseLuaInterface(const std::string& interfaceText, const std::vector& stdModules, const raco::data_storage::Table& modules, bool useModules, PropertyInterfaceList& outInputs, std::string& outError) { - rlogic::LuaInterface* interface = nullptr; - if (useModules) { - // New style creation function: must supply modules if interface text contains modules() statement - // used at feature level >= 5 - auto [luaConfig, valid] = createFullLuaConfig(stdModules, modules); - if (!valid) { - return false; - } - - interface =logicEngine_->createLuaInterface(interfaceText, "Stage::Preprocess", luaConfig); - } else { - // Old style creation function: doesn't generate error if interface text contains modules() statement - // used at feature level < 5 - interface =logicEngine_->createLuaInterface(interfaceText, "Stage::Preprocess"); +bool CoreInterfaceImpl::parseLuaInterface(const std::string& interfaceText, const std::vector& stdModules, const data_storage::Table& modules, PropertyInterfaceList& outInputs, std::string& outError) { + auto [luaConfig, valid] = createFullLuaConfig(stdModules, modules); + if (!valid) { + return false; } + ramses::LuaInterface* interface = logicEngine()->createLuaInterface(interfaceText, "Stage::Preprocess", luaConfig); + if (!interface) { - outError =logicEngine_->getErrors().at(0).message; + outError = logicEngine()->getScene().getRamsesClient().getRamsesFramework().getLastError().value().message; return false; } @@ -141,27 +137,28 @@ bool CoreInterfaceImpl::parseLuaInterface(const std::string& interfaceText, cons fillLuaScriptInterface(outInputs, inputs); } - auto status =logicEngine_->destroy(*interface); + auto status = logicEngine()->destroy(*interface); if (!status) { - LOG_ERROR(raco::log_system::RAMSES_BACKEND, "Deleting LogicEngine object failed: {}", LogicEngineErrors{backend_->logicEngine()}); + auto error = logicEngine()->getScene().getRamsesClient().getRamsesFramework().getLastError().value(); + LOG_ERROR(log_system::RAMSES_BACKEND, "Deleting LogicEngine object failed: {}", error.message); } return true; } -bool CoreInterfaceImpl::parseLuaScriptModule(raco::core::SEditorObject object, const std::string& luaScriptModule, const std::string& moduleName, const std::vector& stdModules, std::string& outError) { - rlogic::LuaConfig tempConfig = createLuaConfig(stdModules); +bool CoreInterfaceImpl::parseLuaScriptModule(core::SEditorObject object, const std::string& luaScriptModule, const std::string& moduleName, const std::vector& stdModules, std::string& outError) { + ramses::LuaConfig tempConfig = createLuaConfig(stdModules); - if (auto tempModule = raco::ramses_base::ramsesLuaModule(luaScriptModule, logicEngine_.get(), tempConfig, moduleName, object->objectIDAsRamsesLogicID())) { + if (auto tempModule = ramses_base::ramsesLuaModule(luaScriptModule, logicEngine(), tempConfig, moduleName, object->objectIDAsRamsesLogicID())) { cachedModules_[object] = tempModule; return true; } else { - outError = logicEngine_->getErrors().at(0).message; + outError = logicEngine()->getScene().getRamsesClient().getRamsesFramework().getLastError().value().message; cachedModules_.erase(object); return false; } } -void CoreInterfaceImpl::removeModuleFromCache(raco::core::SCEditorObject object) { +void CoreInterfaceImpl::removeModuleFromCache(core::SCEditorObject object) { cachedModules_.erase(object); } @@ -171,28 +168,28 @@ void CoreInterfaceImpl::clearModuleCache() { bool CoreInterfaceImpl::extractLuaDependencies(const std::string& luaScript, std::vector& moduleList, std::string& outError) { auto callback = [&moduleList](const std::string& module) { moduleList.emplace_back(module); }; - auto extractStatus = backend_->logicEngine().extractLuaDependencies(luaScript, callback); + auto extractStatus = logicEngine()->extractLuaDependencies(luaScript, callback); if (!extractStatus) { - outError = backend_->logicEngine().getErrors().at(0).message; + outError = logicEngine()->getScene().getRamsesClient().getRamsesFramework().getLastError().value().message; } return extractStatus; } -std::string CoreInterfaceImpl::luaNameForPrimitiveType(raco::core::EnginePrimitive engineType) const { - static const std::unordered_map nameMap = - {{raco::core::EnginePrimitive::Bool, "Bool"}, - {raco::core::EnginePrimitive::Int32, "Int32"}, - {raco::core::EnginePrimitive::Int64, "Int64"}, - {raco::core::EnginePrimitive::Double, "Float"}, - {raco::core::EnginePrimitive::String, "String"}, - {raco::core::EnginePrimitive::Vec2f, "Vec2f"}, - {raco::core::EnginePrimitive::Vec3f, "Vec3f"}, - {raco::core::EnginePrimitive::Vec4f, "Vec4f"}, - {raco::core::EnginePrimitive::Vec2i, "Vec2i"}, - {raco::core::EnginePrimitive::Vec3i, "Vec3i"}, - {raco::core::EnginePrimitive::Vec4i, "Vec4i"}, - {raco::core::EnginePrimitive::Struct, "Struct"}, - {raco::core::EnginePrimitive::Array, "Array"}}; +std::string CoreInterfaceImpl::luaNameForPrimitiveType(core::EnginePrimitive engineType) const { + static const std::unordered_map nameMap = + {{core::EnginePrimitive::Bool, "Bool"}, + {core::EnginePrimitive::Int32, "Int32"}, + {core::EnginePrimitive::Int64, "Int64"}, + {core::EnginePrimitive::Double, "Float"}, + {core::EnginePrimitive::String, "String"}, + {core::EnginePrimitive::Vec2f, "Vec2f"}, + {core::EnginePrimitive::Vec3f, "Vec3f"}, + {core::EnginePrimitive::Vec4f, "Vec4f"}, + {core::EnginePrimitive::Vec2i, "Vec2i"}, + {core::EnginePrimitive::Vec3i, "Vec3i"}, + {core::EnginePrimitive::Vec4i, "Vec4i"}, + {core::EnginePrimitive::Struct, "Struct"}, + {core::EnginePrimitive::Array, "Array"}}; auto it = nameMap.find(engineType); if (it != nameMap.end()) { diff --git a/components/libRamsesBase/src/ramses_base/EnumerationTranslations.cpp b/components/libRamsesBase/src/ramses_base/EnumerationTranslations.cpp index 347291ee..00ea0818 100644 --- a/components/libRamsesBase/src/ramses_base/EnumerationTranslations.cpp +++ b/components/libRamsesBase/src/ramses_base/EnumerationTranslations.cpp @@ -12,59 +12,59 @@ namespace raco::ramses_base { std::map enumerationTranslationsCullMode{ - {user_types::ECullMode::Disabled, ramses::ECullMode_Disabled}, - {user_types::ECullMode::FrontFacing, ramses::ECullMode_FrontFacing}, - {user_types::ECullMode::BackFacing, ramses::ECullMode_BackFacing}, - {user_types::ECullMode::FrontAndBackFacing, ramses::ECullMode_FrontAndBackFacing}}; + {user_types::ECullMode::Disabled, ramses::ECullMode::Disabled}, + {user_types::ECullMode::FrontFacing, ramses::ECullMode::FrontFacing}, + {user_types::ECullMode::BackFacing, ramses::ECullMode::BackFacing}, + {user_types::ECullMode::FrontAndBackFacing, ramses::ECullMode::FrontAndBackFacing}}; std::map enumerationTranslationsBlendOperation{ - {user_types::EBlendOperation::Disabled, ramses::EBlendOperation_Disabled}, - {user_types::EBlendOperation::Add, ramses::EBlendOperation_Add}, - {user_types::EBlendOperation::Subtract, ramses::EBlendOperation_Subtract}, - {user_types::EBlendOperation::ReverseSubtract, ramses::EBlendOperation_ReverseSubtract}, - {user_types::EBlendOperation::Min, ramses::EBlendOperation_Min}, - {user_types::EBlendOperation::Max, ramses::EBlendOperation_Max}}; + {user_types::EBlendOperation::Disabled, ramses::EBlendOperation::Disabled}, + {user_types::EBlendOperation::Add, ramses::EBlendOperation::Add}, + {user_types::EBlendOperation::Subtract, ramses::EBlendOperation::Subtract}, + {user_types::EBlendOperation::ReverseSubtract, ramses::EBlendOperation::ReverseSubtract}, + {user_types::EBlendOperation::Min, ramses::EBlendOperation::Min}, + {user_types::EBlendOperation::Max, ramses::EBlendOperation::Max}}; std::map enumerationTranslationsBlendFactor{ - {user_types::EBlendFactor::Zero, ramses::EBlendFactor_Zero}, - {user_types::EBlendFactor::One, ramses::EBlendFactor_One}, - {user_types::EBlendFactor::SrcAlpha, ramses::EBlendFactor_SrcAlpha}, - {user_types::EBlendFactor::OneMinusSrcAlpha, ramses::EBlendFactor_OneMinusSrcAlpha}, - {user_types::EBlendFactor::DstAlpha, ramses::EBlendFactor_DstAlpha}, - {user_types::EBlendFactor::OneMinusDstAlpha, ramses::EBlendFactor_OneMinusDstAlpha}, - {user_types::EBlendFactor::SrcColor, ramses::EBlendFactor_SrcColor}, - {user_types::EBlendFactor::OneMinusSrcColor, ramses::EBlendFactor_OneMinusSrcColor}, - {user_types::EBlendFactor::DstColor, ramses::EBlendFactor_DstColor}, - {user_types::EBlendFactor::OneMinusDstColor, ramses::EBlendFactor_OneMinusDstColor}, - {user_types::EBlendFactor::ConstColor, ramses::EBlendFactor_ConstColor}, - {user_types::EBlendFactor::OneMinusConstColor, ramses::EBlendFactor_OneMinusConstColor}, - {user_types::EBlendFactor::ConstAlpha, ramses::EBlendFactor_ConstAlpha}, - {user_types::EBlendFactor::OneMinusConstAlpha, ramses::EBlendFactor_OneMinusConstAlpha}, - {user_types::EBlendFactor::AlphaSaturate, ramses::EBlendFactor_AlphaSaturate}}; + {user_types::EBlendFactor::Zero, ramses::EBlendFactor::Zero}, + {user_types::EBlendFactor::One, ramses::EBlendFactor::One}, + {user_types::EBlendFactor::SrcAlpha, ramses::EBlendFactor::SrcAlpha}, + {user_types::EBlendFactor::OneMinusSrcAlpha, ramses::EBlendFactor::OneMinusSrcAlpha}, + {user_types::EBlendFactor::DstAlpha, ramses::EBlendFactor::DstAlpha}, + {user_types::EBlendFactor::OneMinusDstAlpha, ramses::EBlendFactor::OneMinusDstAlpha}, + {user_types::EBlendFactor::SrcColor, ramses::EBlendFactor::SrcColor}, + {user_types::EBlendFactor::OneMinusSrcColor, ramses::EBlendFactor::OneMinusSrcColor}, + {user_types::EBlendFactor::DstColor, ramses::EBlendFactor::DstColor}, + {user_types::EBlendFactor::OneMinusDstColor, ramses::EBlendFactor::OneMinusDstColor}, + {user_types::EBlendFactor::ConstColor, ramses::EBlendFactor::ConstColor}, + {user_types::EBlendFactor::OneMinusConstColor, ramses::EBlendFactor::OneMinusConstColor}, + {user_types::EBlendFactor::ConstAlpha, ramses::EBlendFactor::ConstAlpha}, + {user_types::EBlendFactor::OneMinusConstAlpha, ramses::EBlendFactor::OneMinusConstAlpha}, + {user_types::EBlendFactor::AlphaSaturate, ramses::EBlendFactor::AlphaSaturate}}; std::map enumerationTranslationsDepthFunc{ - {user_types::EDepthFunc::Disabled, ramses::EDepthFunc_Disabled}, - {user_types::EDepthFunc::Greater, ramses::EDepthFunc_Greater}, - {user_types::EDepthFunc::GreaterEqual, ramses::EDepthFunc_GreaterEqual}, - {user_types::EDepthFunc::Less, ramses::EDepthFunc_Less}, - {user_types::EDepthFunc::LessEqual, ramses::EDepthFunc_LessEqual}, - {user_types::EDepthFunc::Equal, ramses::EDepthFunc_Equal}, - {user_types::EDepthFunc::NotEqual, ramses::EDepthFunc_NotEqual}, - {user_types::EDepthFunc::Always, ramses::EDepthFunc_Always}, - {user_types::EDepthFunc::Never, ramses::EDepthFunc_Never}}; + {user_types::EDepthFunc::Disabled, ramses::EDepthFunc::Disabled}, + {user_types::EDepthFunc::Greater, ramses::EDepthFunc::Greater}, + {user_types::EDepthFunc::GreaterEqual, ramses::EDepthFunc::GreaterEqual}, + {user_types::EDepthFunc::Less, ramses::EDepthFunc::Less}, + {user_types::EDepthFunc::LessEqual, ramses::EDepthFunc::LessEqual}, + {user_types::EDepthFunc::Equal, ramses::EDepthFunc::Equal}, + {user_types::EDepthFunc::NotEqual, ramses::EDepthFunc::NotEqual}, + {user_types::EDepthFunc::Always, ramses::EDepthFunc::Always}, + {user_types::EDepthFunc::Never, ramses::EDepthFunc::Never}}; std::map enumerationTranslationTextureAddressMode{ - {user_types::ETextureAddressMode::Clamp, ramses::ETextureAddressMode_Clamp}, - {user_types::ETextureAddressMode::Repeat, ramses::ETextureAddressMode_Repeat}, - {user_types::ETextureAddressMode::Mirror, ramses::ETextureAddressMode_Mirror}}; + {user_types::ETextureAddressMode::Clamp, ramses::ETextureAddressMode::Clamp}, + {user_types::ETextureAddressMode::Repeat, ramses::ETextureAddressMode::Repeat}, + {user_types::ETextureAddressMode::Mirror, ramses::ETextureAddressMode::Mirror}}; std::map enumerationTranslationTextureSamplingMethod{ - {user_types::ETextureSamplingMethod::Nearest, ramses::ETextureSamplingMethod_Nearest}, - {user_types::ETextureSamplingMethod::Linear, ramses::ETextureSamplingMethod_Linear}, - {user_types::ETextureSamplingMethod::Nearest_MipMapNearest, ramses::ETextureSamplingMethod_Nearest_MipMapNearest}, - {user_types::ETextureSamplingMethod::Nearest_MipMapLinear, ramses::ETextureSamplingMethod_Nearest_MipMapLinear}, - {user_types::ETextureSamplingMethod::Linear_MipMapNearest, ramses::ETextureSamplingMethod_Linear_MipMapNearest}, - {user_types::ETextureSamplingMethod::Linear_MipMapLinear, ramses::ETextureSamplingMethod_Linear_MipMapLinear}}; + {user_types::ETextureSamplingMethod::Nearest, ramses::ETextureSamplingMethod::Nearest}, + {user_types::ETextureSamplingMethod::Linear, ramses::ETextureSamplingMethod::Linear}, + {user_types::ETextureSamplingMethod::Nearest_MipMapNearest, ramses::ETextureSamplingMethod::Nearest_MipMapNearest}, + {user_types::ETextureSamplingMethod::Nearest_MipMapLinear, ramses::ETextureSamplingMethod::Nearest_MipMapLinear}, + {user_types::ETextureSamplingMethod::Linear_MipMapNearest, ramses::ETextureSamplingMethod::Linear_MipMapNearest}, + {user_types::ETextureSamplingMethod::Linear_MipMapLinear, ramses::ETextureSamplingMethod::Linear_MipMapLinear}}; std::map enumerationTranslationTextureFormat{ {user_types::ETextureFormat::R8, ramses::ETextureFormat::R8}, @@ -77,21 +77,23 @@ std::map enumerationTranslat {user_types::ETextureFormat::SRGB8_ALPHA8, ramses::ETextureFormat::SRGB8_ALPHA8}}; std::map enumerationTranslationRenderBufferFormat{ - {user_types::ERenderBufferFormat::RGBA4, ramses::ERenderBufferFormat_RGBA4}, - {user_types::ERenderBufferFormat::R8, ramses::ERenderBufferFormat_R8}, - {user_types::ERenderBufferFormat::RG8, ramses::ERenderBufferFormat_RG8}, - {user_types::ERenderBufferFormat::RGB8, ramses::ERenderBufferFormat_RGB8}, - {user_types::ERenderBufferFormat::RGBA8, ramses::ERenderBufferFormat_RGBA8}, - {user_types::ERenderBufferFormat::R16F, ramses::ERenderBufferFormat_R16F}, - {user_types::ERenderBufferFormat::R32F, ramses::ERenderBufferFormat_R32F}, - {user_types::ERenderBufferFormat::RG16F, ramses::ERenderBufferFormat_RG16F}, - {user_types::ERenderBufferFormat::RG32F, ramses::ERenderBufferFormat_RG32F}, - {user_types::ERenderBufferFormat::RGB16F, ramses::ERenderBufferFormat_RGB16F}, - {user_types::ERenderBufferFormat::RGB32F, ramses::ERenderBufferFormat_RGB32F}, - {user_types::ERenderBufferFormat::RGBA16F, ramses::ERenderBufferFormat_RGBA16F}, - {user_types::ERenderBufferFormat::RGBA32F, ramses::ERenderBufferFormat_RGBA32F}, + {user_types::ERenderBufferFormat::RGBA4, ramses::ERenderBufferFormat::RGBA4}, + {user_types::ERenderBufferFormat::R8, ramses::ERenderBufferFormat::R8}, + {user_types::ERenderBufferFormat::RG8, ramses::ERenderBufferFormat::RG8}, + {user_types::ERenderBufferFormat::RGB8, ramses::ERenderBufferFormat::RGB8}, + {user_types::ERenderBufferFormat::RGBA8, ramses::ERenderBufferFormat::RGBA8}, + {user_types::ERenderBufferFormat::R16F, ramses::ERenderBufferFormat::R16F}, + {user_types::ERenderBufferFormat::R32F, ramses::ERenderBufferFormat::R32F}, + {user_types::ERenderBufferFormat::RG16F, ramses::ERenderBufferFormat::RG16F}, + {user_types::ERenderBufferFormat::RG32F, ramses::ERenderBufferFormat::RG32F}, + {user_types::ERenderBufferFormat::RGB16F, ramses::ERenderBufferFormat::RGB16F}, + {user_types::ERenderBufferFormat::RGB32F, ramses::ERenderBufferFormat::RGB32F}, + {user_types::ERenderBufferFormat::RGBA16F, ramses::ERenderBufferFormat::RGBA16F}, + {user_types::ERenderBufferFormat::RGBA32F, ramses::ERenderBufferFormat::RGBA32F}, - {user_types::ERenderBufferFormat::Depth24, ramses::ERenderBufferFormat_Depth24}, - {user_types::ERenderBufferFormat::Depth24_Stencil8, ramses::ERenderBufferFormat_Depth24_Stencil8}}; + {user_types::ERenderBufferFormat::Depth24, ramses::ERenderBufferFormat::Depth24}, + {user_types::ERenderBufferFormat::Depth24_Stencil8, ramses::ERenderBufferFormat::Depth24_Stencil8}, + {user_types::ERenderBufferFormat::Depth16, ramses::ERenderBufferFormat::Depth16}, + {user_types::ERenderBufferFormat::Depth32, ramses::ERenderBufferFormat::Depth32}}; } // namespace raco::ramses_base diff --git a/components/libRamsesBase/src/ramses_base/HeadlessEngineBackend.cpp b/components/libRamsesBase/src/ramses_base/HeadlessEngineBackend.cpp index a41d6368..7ccdd1c0 100644 --- a/components/libRamsesBase/src/ramses_base/HeadlessEngineBackend.cpp +++ b/components/libRamsesBase/src/ramses_base/HeadlessEngineBackend.cpp @@ -11,18 +11,8 @@ namespace raco::ramses_base { -ramses::RamsesFrameworkConfig& ramsesFrameworkConfig() noexcept { - char const* argv[] = {"RamsesComposer.exe", - "--log-level-contexts-filter", "trace:RAPI,off:RPER,debug:RRND,off:RFRA,off:RDSM,info:RCOM", - "--log-level-console", "warn", - "--log-level-dlt", "warn"}; - static ramses::RamsesFrameworkConfig config(sizeof(argv) / sizeof(argv[0]), argv); - return config; -} - -HeadlessEngineBackend::HeadlessEngineBackend(rlogic::EFeatureLevel featureLevel) - : BaseEngineBackend{featureLevel, ramsesFrameworkConfig()} { - connect(); +HeadlessEngineBackend::HeadlessEngineBackend(const ramses::RamsesFrameworkConfig& frameworkConfig) + : BaseEngineBackend(frameworkConfig) { } } // namespace raco::ramses_base diff --git a/components/libRamsesBase/src/ramses_base/Utils.cpp b/components/libRamsesBase/src/ramses_base/Utils.cpp index 492182f7..802c1f47 100644 --- a/components/libRamsesBase/src/ramses_base/Utils.cpp +++ b/components/libRamsesBase/src/ramses_base/Utils.cpp @@ -12,7 +12,6 @@ #include "data_storage/Table.h" #include "lodepng.h" #include "ramses_adaptor/SceneBackend.h" -#include "ramses_base/LogicEngine.h" #include "ramses_base/RamsesHandles.h" #include "ramses_base/EnumerationTranslations.h" #include "user_types/CubeMap.h" @@ -21,12 +20,13 @@ #include "utils/FileUtils.h" #include "utils/MathUtils.h" #include "core/CoreFormatter.h" -#include -#include -#include -#include -#include -#include + +#include +#include +#include +#include +#include +#include #include #include @@ -161,29 +161,30 @@ std::map defaultUniformSemantics = {"uCameraPosition", ramses::EEffectUniformSemantic::CameraWorldPosition}, {"uResolution", ramses::EEffectUniformSemantic::DisplayBufferResolution}}; -static std::map shaderTypeMap = { - {ramses::EEffectInputDataType_Int32, raco::core::EnginePrimitive::Int32}, - {ramses::EEffectInputDataType_UInt16, raco::core::EnginePrimitive::UInt16}, - {ramses::EEffectInputDataType_UInt32, raco::core::EnginePrimitive::UInt32}, - {ramses::EEffectInputDataType_Float, raco::core::EnginePrimitive::Double}, - - {ramses::EEffectInputDataType_Vector2F, raco::core::EnginePrimitive::Vec2f}, - {ramses::EEffectInputDataType_Vector3F, raco::core::EnginePrimitive::Vec3f}, - {ramses::EEffectInputDataType_Vector4F, raco::core::EnginePrimitive::Vec4f}, - - {ramses::EEffectInputDataType_Vector2I, raco::core::EnginePrimitive::Vec2i}, - {ramses::EEffectInputDataType_Vector3I, raco::core::EnginePrimitive::Vec3i}, - {ramses::EEffectInputDataType_Vector4I, raco::core::EnginePrimitive::Vec4i}, - - //{ramses::EEffectInputDataType_Matrix22F, }, - //{ramses::EEffectInputDataType_Matrix33F, }, - //{ramses::EEffectInputDataType_Matrix44F, }, - - {ramses::EEffectInputDataType_TextureSampler2D, raco::core::EnginePrimitive::TextureSampler2D}, - {ramses::EEffectInputDataType_TextureSampler2DMS, raco::core::EnginePrimitive::TextureSampler2DMS}, - {ramses::EEffectInputDataType_TextureSampler3D, raco::core::EnginePrimitive::TextureSampler3D}, - {ramses::EEffectInputDataType_TextureSamplerCube, raco::core::EnginePrimitive::TextureSamplerCube}, - {ramses::EEffectInputDataType_TextureSamplerExternal, raco::core::EnginePrimitive::TextureSamplerExternal} +static std::map shaderTypeMap = { + {ramses::EDataType::Bool, core::EnginePrimitive::Bool}, + {ramses::EDataType::Int32, core::EnginePrimitive::Int32}, + {ramses::EDataType::UInt16, core::EnginePrimitive::UInt16}, + {ramses::EDataType::UInt32, core::EnginePrimitive::UInt32}, + {ramses::EDataType::Float, core::EnginePrimitive::Double}, + + {ramses::EDataType::Vector2F, core::EnginePrimitive::Vec2f}, + {ramses::EDataType::Vector3F, core::EnginePrimitive::Vec3f}, + {ramses::EDataType::Vector4F, core::EnginePrimitive::Vec4f}, + + {ramses::EDataType::Vector2I, core::EnginePrimitive::Vec2i}, + {ramses::EDataType::Vector3I, core::EnginePrimitive::Vec3i}, + {ramses::EDataType::Vector4I, core::EnginePrimitive::Vec4i}, + + //{ramses::EDataType::Matrix22F, }, + //{ramses::EDataType::Matrix33F, }, + //{ramses::EDataType::Matrix44F, }, + + {ramses::EDataType::TextureSampler2D, core::EnginePrimitive::TextureSampler2D}, + {ramses::EDataType::TextureSampler2DMS, core::EnginePrimitive::TextureSampler2DMS}, + {ramses::EDataType::TextureSampler3D, core::EnginePrimitive::TextureSampler3D}, + {ramses::EDataType::TextureSamplerCube, core::EnginePrimitive::TextureSamplerCube}, + {ramses::EDataType::TextureSamplerExternal, core::EnginePrimitive::TextureSamplerExternal} }; std::unique_ptr createEffectDescription(const std::string &vertexShader, const std::string &geometryShader, const std::string &fragmentShader, const std::string &shaderDefines) { @@ -214,7 +215,7 @@ std::unique_ptr createEffectDescription(const std::st } -std::vector getRamsesUniformPropertyNames(core::ValueHandle uniformContainerHandle, const std::vector &propertyNames, size_t startIndex) { +std::vector getRamsesUniformPropertyNames(core::ValueHandle uniformContainerHandle, const std::vector &propertyNames, size_t startIndex) { std::string propName; core::ValueHandle handle = uniformContainerHandle; for (size_t index = startIndex; index < propertyNames.size(); index++) { @@ -234,9 +235,16 @@ std::vector getRamsesUniformPropertyNames(core::ValueHandle uniform // ramses uniform name: array[index].member ++index; assert(index < propertyNames.size()); - auto arrayIndex = std::stoi(propertyNames[index]) - 1; - handle = handle[arrayIndex]; - propName += fmt::format("{}[{}].", currentName, arrayIndex); + + int arrayIndex; + auto [ptr, error] = std::from_chars(propertyNames[index].data(), propertyNames[index].data() + propertyNames[index].size(), arrayIndex); + if (error == std::errc() && arrayIndex > 0) { + arrayIndex--; + handle = handle[arrayIndex]; + propName += fmt::format("{}[{}].", currentName, arrayIndex); + } else { + throw std::runtime_error("Invalid property name."); + } } else { // note: array of array is not possible so this must be a primitive type // propertyNames may or may not include the index into the array as final element, @@ -246,7 +254,7 @@ std::vector getRamsesUniformPropertyNames(core::ValueHandle uniform return {propName}; } else { assert(index == propertyNames.size() - 2); - return {propName, propertyNames[index + 1]}; + return {propName, std::string(propertyNames[index + 1])}; } } } break; @@ -261,7 +269,7 @@ std::string getRamsesUniformPropertyName(core::ValueHandle uniformContainerHandl return getRamsesUniformPropertyNames(uniformContainerHandle, uniformHandle.getPropertyNamesVector(), uniformContainerHandle.depth())[0]; } -void buildUniformRecursive(std::string uniformName, raco::core::PropertyInterfaceList &uniforms, raco::core::EnginePrimitive type, uint32_t elementCount, std::string& outError) { +void buildUniformRecursive(std::string uniformName, core::PropertyInterfaceList &uniforms, core::EnginePrimitive type, uint32_t elementCount, std::string& outError) { auto dotPos = uniformName.find('.'); auto bracketPos = uniformName.find('['); @@ -274,7 +282,7 @@ void buildUniformRecursive(std::string uniformName, raco::core::PropertyInterfac auto it = std::find_if(uniforms.begin(), uniforms.end(), [structName](auto item) { return structName == item.name; }); - raco::core::PropertyInterface &interface = it == uniforms.end() ? uniforms.emplace_back(structName, raco::core::EnginePrimitive::Struct) : *it; + core::PropertyInterface &interface = it == uniforms.end() ? uniforms.emplace_back(structName, core::EnginePrimitive::Struct) : *it; buildUniformRecursive(memberName, interface.children, type, elementCount, outError); @@ -290,22 +298,22 @@ void buildUniformRecursive(std::string uniformName, raco::core::PropertyInterfac auto it = std::find_if(uniforms.begin(), uniforms.end(), [arrayName](auto item) { return arrayName == item.name; }); - raco::core::PropertyInterface &interface = it == uniforms.end() ? uniforms.emplace_back(arrayName, raco::core::EnginePrimitive::Array) : *it; + core::PropertyInterface &interface = it == uniforms.end() ? uniforms.emplace_back(arrayName, core::EnginePrimitive::Array) : *it; // The index in the uniform name starts at 0 int index = stoi(indexStr); assert(index <= interface.children.size()); if (index == interface.children.size()) { - interface.children.emplace_back(std::string(), raco::core::EnginePrimitive::Struct); + interface.children.emplace_back(std::string(), core::EnginePrimitive::Struct); } - raco::core::PropertyInterface &element = interface.children[index]; + core::PropertyInterface &element = interface.children[index]; buildUniformRecursive(rest, element.children, type, elementCount, outError); } } else { // scalar if (elementCount > 1) { - if (type >= core::EnginePrimitive::Int32 && type <= core::EnginePrimitive::Vec4i) { - uniforms.emplace_back(raco::core::PropertyInterface::makeArrayOf(uniformName, type, elementCount)); + if (type >= core::EnginePrimitive::Bool && type <= core::EnginePrimitive::Vec4i) { + uniforms.emplace_back(core::PropertyInterface::makeArrayOf(uniformName, type, elementCount)); } else { outError += fmt::format("Uniform '{}' has unsupported array element type '{}'", uniformName, type); } @@ -315,17 +323,16 @@ void buildUniformRecursive(std::string uniformName, raco::core::PropertyInterfac } } -bool parseShaderText(ramses::Scene &scene, const std::string &vertexShader, const std::string &geometryShader, const std::string &fragmentShader, const std::string &shaderDefines, raco::core::PropertyInterfaceList &outUniforms, raco::core::PropertyInterfaceList &outAttributes, std::string &outError) { +bool parseShaderText(ramses::Scene &scene, const std::string &vertexShader, const std::string &geometryShader, const std::string &fragmentShader, const std::string &shaderDefines, core::PropertyInterfaceList &outUniforms, core::PropertyInterfaceList &outAttributes, std::string &outError) { outUniforms.clear(); outAttributes.clear(); auto description = createEffectDescription(vertexShader, geometryShader, fragmentShader, shaderDefines); - ramses::Effect *effect = scene.createEffect(*description, ramses::ResourceCacheFlag_DoNotCache, "glsl shader"); + ramses::Effect *effect = scene.createEffect(*description, "glsl shader"); bool success = false; if (effect) { uint32_t numUniforms = effect->getUniformInputCount(); for (uint32_t i{0}; i < numUniforms; i++) { - ramses::UniformInput uniform; - effect->getUniformInput(i, uniform); + ramses::UniformInput uniform = effect->getUniformInput(i).value(); if (uniform.getSemantics() == ramses::EEffectUniformSemantic::Invalid) { if (shaderTypeMap.find(uniform.getDataType()) != shaderTypeMap.end()) { auto engineType = shaderTypeMap[uniform.getDataType()]; @@ -333,7 +340,7 @@ bool parseShaderText(ramses::Scene &scene, const std::string &vertexShader, cons } else { // mat4 uniforms are needed for skinning: they will be set directly by the LogicEngine // so we don't need to expose but they shouldn't generate errors either: - if (uniform.getDataType() != ramses::EEffectInputDataType_Matrix44F) { + if (uniform.getDataType() != ramses::EDataType::Matrix44F) { outError += std::string(uniform.getName()) + " has unsupported type"; } } @@ -342,8 +349,7 @@ bool parseShaderText(ramses::Scene &scene, const std::string &vertexShader, cons uint32_t numAttributes = effect->getAttributeInputCount(); for (uint32_t i{0}; i < numAttributes; i++) { - ramses::AttributeInput attrib; - effect->getAttributeInput(i, attrib); + ramses::AttributeInput attrib = effect->getAttributeInput(i).value(); if (shaderTypeMap.find(attrib.getDataType()) != shaderTypeMap.end()) { outAttributes.emplace_back(std::string(attrib.getName()), shaderTypeMap[attrib.getDataType()]); } else { @@ -359,21 +365,21 @@ bool parseShaderText(ramses::Scene &scene, const std::string &vertexShader, cons return success; } -rlogic::LuaConfig defaultLuaConfig() { - rlogic::LuaConfig config; - config.addStandardModuleDependency(rlogic::EStandardModule::All); +ramses::LuaConfig defaultLuaConfig() { + ramses::LuaConfig config; + config.addStandardModuleDependency(ramses::EStandardModule::All); return config; } -rlogic::LuaConfig createLuaConfig(const std::vector &stdModules) { - rlogic::LuaConfig config; +ramses::LuaConfig createLuaConfig(const std::vector &stdModules) { + ramses::LuaConfig config; - std::map stdModuleMap = { - {"base", rlogic::EStandardModule::Base}, - {"string", rlogic::EStandardModule::String}, - {"table", rlogic::EStandardModule::Table}, - {"math", rlogic::EStandardModule::Math}, - {"debug", rlogic::EStandardModule::Debug}}; + std::map stdModuleMap = { + {"base", ramses::EStandardModule::Base}, + {"string", ramses::EStandardModule::String}, + {"table", ramses::EStandardModule::Table}, + {"math", ramses::EStandardModule::Math}, + {"debug", ramses::EStandardModule::Debug}}; for (const auto &moduleName : stdModules) { auto it = stdModuleMap.find(moduleName); @@ -388,40 +394,10 @@ ramses::RamsesVersion getRamsesVersion() { return ramses::GetRamsesVersion(); } -rlogic::RamsesLogicVersion getLogicEngineVersion() { - return rlogic::GetRamsesLogicVersion(); -} - std::string getRamsesVersionString() { return getRamsesVersion().string; } -std::string getLogicEngineVersionString() { - return std::string(getLogicEngineVersion().string); -} - -rlogic::ELogMessageType toLogicLogLevel(spdlog::level::level_enum level) { - using namespace spdlog::level; - using namespace rlogic; - - switch (level) { - case level_enum::trace: - return ELogMessageType::Trace; - case level_enum::debug: - return ELogMessageType::Debug; - case level_enum::info: - return ELogMessageType::Info; - case level_enum::warn: - return ELogMessageType::Warn; - case level_enum::err: - return ELogMessageType::Error; - case level_enum::critical: - return ELogMessageType::Fatal; - default: - return ELogMessageType::Off; - } -} - ramses::ELogLevel toRamsesLogLevel(spdlog::level::level_enum level) { using namespace spdlog::level; using namespace ramses; @@ -466,55 +442,74 @@ spdlog::level::level_enum toSpdLogLevel(ramses::ELogLevel level) { } } -spdlog::level::level_enum toSpdLogLevel(rlogic::ELogMessageType level) { - using namespace spdlog::level; - using namespace rlogic; - - switch (level) { - case ELogMessageType::Trace: - return level_enum::trace; - case ELogMessageType::Debug: - return level_enum::debug; - case ELogMessageType::Info: - return level_enum::info; - case ELogMessageType::Warn: - return level_enum::warn; - case ELogMessageType::Error: - return level_enum::err; - case ELogMessageType::Fatal: - return level_enum::critical; +spdlog::level::level_enum getLevelFromArg(const QString &arg) { + bool logLevelValid; + int logLevel = arg.toInt(&logLevelValid); + spdlog::level::level_enum spdLogLevel; + switch (logLevelValid ? logLevel : -1) { + case 0: + return spdlog::level::level_enum::off; + case 1: + return spdlog::level::level_enum::critical; + case 2: + return spdlog::level::level_enum::err; + case 3: + return spdlog::level::level_enum::warn; + case 4: + return spdlog::level::level_enum::info; + case 5: + return spdlog::level::level_enum::debug; + case 6: + return spdlog::level::level_enum::trace; default: - return level_enum::off; + LOG_WARNING(log_system::COMMON, "Invalid Log Level: \"{}\". Continuing with verbose log output.", arg.toStdString().c_str()); + return spdlog::level::level_enum::trace; } } -void installRamsesLogHandler(bool enableTrace) { - ramses::RamsesFramework::SetConsoleLogLevel(ramses::ELogLevel::Off); - ramses::RamsesFramework::SetLogHandler([enableTrace](ramses::ELogLevel level, const std::string &context, const std::string &message) { - if (!enableTrace && level == ramses::ELogLevel::Trace) { - return; - } - - SPDLOG_LOGGER_CALL(raco::log_system::get(raco::log_system::RAMSES), toSpdLogLevel(level), message); - }); +ramses::ELogLevel getRamsesLogLevelFromArg(const QString& arg) { + return toRamsesLogLevel(getLevelFromArg(arg)); } -void installLogicLogHandler() { - rlogic::Logger::SetDefaultLogging(false); - rlogic::Logger::SetLogHandler( - [](rlogic::ELogMessageType level, std::string_view message) { - if (!ramses_adaptor::SceneBackend::discardLogicEngineMessage(message)) { - SPDLOG_LOGGER_CALL(raco::log_system::get(raco::log_system::RAMSES_LOGIC), toSpdLogLevel(level), message); - } - }); +void addRamseFrameworkOptions(QCommandLineParser &parser) { + QCommandLineOption RFRALogLevelOption(QStringList() << "RFRA", "Ramses Framework Log Level.", "rcli-log-level", "0"); + QCommandLineOption RCLILogLevelOption(QStringList() << "RCLI", "Ramses Client Log Level.", "rfra-log-level", "0"); + QCommandLineOption RRNDLogLevelOption(QStringList() << "RRND", "Ramses Renderer Log Level.", "rrnd-log-level", "5"); + QCommandLineOption RPERLogLevelOption(QStringList() << "RPER", "Ramses Periodic Log Level.", "rper-log-level", "0"); + QCommandLineOption RTXTLogLevelOption(QStringList() << "RTXT", "Ramses Text Log Level.", "rtxt-log-level", "0"); + + QCommandLineOption RCOMLogLevelOption(QStringList() << "RCOM", "Ramses Communictation Log Level.", "rcom-log-level", "4"); + QCommandLineOption RPROLogLevelOption(QStringList() << "RPRO", "Ramses Profiling Log Level.", "rpro-log-level", "0"); + + QCommandLineOption RAPILogLevelOption(QStringList() << "RAPI", "Ramses HLAPI Client Log Level.", "rapi-log-level", "6"); + QCommandLineOption RAPRLogLevelOption(QStringList() << "RAPR", "Ramses HLAPI Renderer Log Level.", "rapr-log-level", "0"); + + parser.addOption(RFRALogLevelOption); + parser.addOption(RCLILogLevelOption); + parser.addOption(RRNDLogLevelOption); + parser.addOption(RPERLogLevelOption); + parser.addOption(RTXTLogLevelOption); + parser.addOption(RCOMLogLevelOption); + parser.addOption(RPROLogLevelOption); + parser.addOption(RAPILogLevelOption); + parser.addOption(RAPRLogLevelOption); } -void setRamsesLogLevel(spdlog::level::level_enum level) { - ramses::RamsesFramework::SetConsoleLogLevel(toRamsesLogLevel(level)); +std::vector ramsesLogCategories() { + return {"RFRA", "RCLI", "RRND", "RPER", "RTXT", "RCOM", "RPRO", "RAPI", "RAPR"}; } -void setLogicLogLevel(spdlog::level::level_enum level) { - rlogic::Logger::SetLogVerbosityLimit(toLogicLogLevel(level)); +void installRamsesLogHandler(bool enableTrace) { + ramses::RamsesFramework::SetLogHandler([enableTrace](ramses::ELogLevel level, std::string_view context, std::string_view message) { + if (!enableTrace && level == ramses::ELogLevel::Trace) { + return; + } + if (!ramses_adaptor::SceneBackend::discardRamsesMessage(message)) { + // TODO(ramses28) this is bad since it makes a copy of the context string_view + // we do this since the string_view is not null terminated but we need a null-terminated string here. + (log_system::get(log_system::RAMSES))->log(spdlog::source_loc{__FILE__, __LINE__, std::string{context}.c_str()}, toSpdLogLevel(level), message); + } + }); } std::string pngColorTypeToString(int colorType) { @@ -536,11 +531,11 @@ std::string pngColorTypeToString(int colorType) { PngCompatibilityInfo validateTextureColorTypeAndBitDepth(ramses::ETextureFormat selectedTextureFormat, int colorType, int bitdepth) { if (colorType != LCT_PALETTE && bitdepth != 8 && bitdepth != 16) { - return {"Invalid bit depth (only 8 or 16 bits allowed).", raco::core::ErrorLevel::ERROR, false}; + return {"Invalid bit depth (only 8 or 16 bits allowed).", core::ErrorLevel::ERROR, false}; } else if (bitdepth == 8 && (selectedTextureFormat == ramses::ETextureFormat::R16F || selectedTextureFormat == ramses::ETextureFormat::RG16F || selectedTextureFormat == ramses::ETextureFormat::RGB16F || selectedTextureFormat == ramses::ETextureFormat::RGBA16F)) { - return {"Invalid texture format for bit depth (only 8-bit-based formats allowed).", raco::core::ErrorLevel::ERROR, false}; + return {"Invalid texture format for bit depth (only 8-bit-based formats allowed).", core::ErrorLevel::ERROR, false}; } else if (bitdepth == 16 && (selectedTextureFormat != ramses::ETextureFormat::R16F && selectedTextureFormat != ramses::ETextureFormat::RG16F && selectedTextureFormat != ramses::ETextureFormat::RGB16F && selectedTextureFormat != ramses::ETextureFormat::RGBA16F)) { - return {"Invalid texture format for bit depth (only 16-bit-based formats allowed).", raco::core::ErrorLevel::ERROR, false}; + return {"Invalid texture format for bit depth (only 16-bit-based formats allowed).", core::ErrorLevel::ERROR, false}; } static std::map, std::set> validTextureFormats = { @@ -557,10 +552,10 @@ PngCompatibilityInfo validateTextureColorTypeAndBitDepth(ramses::ETextureFormat std::pair pngFormat = {static_cast (colorType), bitdepth}; auto validTextureFormatIt = validTextureFormats.find(pngFormat); if (validTextureFormatIt == validTextureFormats.end()) { - return {"Invalid PNG color type.", raco::core::ErrorLevel::ERROR, false}; + return {"Invalid PNG color type.", core::ErrorLevel::ERROR, false}; } if (validTextureFormatIt->second.find(selectedTextureFormat) != validTextureFormatIt->second.end()) { - return {"", raco::core::ErrorLevel::NONE, false}; + return {"", core::ErrorLevel::NONE, false}; } static std::map, std::set> downConvertableTextureFormats = { @@ -575,13 +570,13 @@ PngCompatibilityInfo validateTextureColorTypeAndBitDepth(ramses::ETextureFormat auto downConvertableTextureFormat = downConvertableTextureFormats[pngFormat].find(selectedTextureFormat); if (downConvertableTextureFormat != downConvertableTextureFormats[pngFormat].end()) { - return {fmt::format("Selected format {} is not equal to PNG color type {} - image will be converted.", ramsesTextureFormatToString(selectedTextureFormat), pngColorTypeToString(colorType)), raco::core::ErrorLevel::INFORMATION, true}; + return {fmt::format("Selected format {} is not equal to PNG color type {} - image will be converted.", ramsesTextureFormatToString(selectedTextureFormat), pngColorTypeToString(colorType)), core::ErrorLevel::INFORMATION, true}; } - return {fmt::format("Selected format {} is not equal to PNG color type {} - empty channels will be created.", ramsesTextureFormatToString(selectedTextureFormat), pngColorTypeToString(colorType)), raco::core::ErrorLevel::WARNING, true}; + return {fmt::format("Selected format {} is not equal to PNG color type {} - empty channels will be created.", ramsesTextureFormatToString(selectedTextureFormat), pngColorTypeToString(colorType)), core::ErrorLevel::WARNING, true}; } std::string ramsesTextureFormatToString(ramses::ETextureFormat textureFormat) { - return std::string(ramses::getTextureFormatString(textureFormat)).substr(strlen("ETextureFormat_")); + return std::string(ramses::toString(textureFormat)).substr(strlen("ETextureFormat_")); } int ramsesTextureFormatToChannelAmount(ramses::ETextureFormat textureFormat) { @@ -609,7 +604,7 @@ void normalize16BitColorData(std::vector &data) { assert(data.size() % 2 == 0); for (auto i = 0; i < data.size(); i += 2) { - auto dataHalfFloat = raco::utils::math::twoBytesToHalfFloat(data[i], data[i + 1]); + auto dataHalfFloat = utils::math::twoBytesToHalfFloat(data[i], data[i + 1]); data[i] = dataHalfFloat; data[i + 1] = dataHalfFloat >> 8; } @@ -638,8 +633,8 @@ std::vector decodeMipMapData(core::Errors *errors, core::Project unsigned int curWidth; unsigned int curHeight; - std::string pngPath = raco::core::PathQueries::resolveUriPropertyToAbsolutePath(project, {obj, {uriPropName}}); - auto rawBinaryData = raco::utils::file::readBinary(pngPath); + std::string pngPath = core::PathQueries::resolveUriPropertyToAbsolutePath(project, {obj, {uriPropName}}); + auto rawBinaryData = utils::file::readBinary(pngPath); lodepng::State pngImportState; pngImportState.decoder.color_convert = false; lodepng_inspect(&curWidth, &curHeight, &pngImportState, rawBinaryData.data(), rawBinaryData.size()); @@ -673,17 +668,17 @@ std::vector decodeMipMapData(core::Errors *errors, core::Project : lodepng::decode(data, curWidth, curHeight, pngImportState, rawBinaryData); if (ret != 0) { - if (raco::utils::file::isGitLfsPlaceholderFile(pngPath)) { - LOG_ERROR(raco::log_system::RAMSES_ADAPTOR, "{} '{}': Couldn't load png file from '{}'. Git LFS placeholder file detected.", obj->getTypeDescription().typeName, obj->objectName(), uri); + if (utils::file::isGitLfsPlaceholderFile(pngPath)) { + LOG_ERROR(log_system::RAMSES_ADAPTOR, "{} '{}': Couldn't load png file from '{}'. Git LFS placeholder file detected.", obj->getTypeDescription().typeName, obj->objectName(), uri); errors->addError(core::ErrorCategory::PARSING, core::ErrorLevel::ERROR, {obj->shared_from_this(), {uriPropName}}, "Image file could not be loaded, Git LFS placeholder file detected."); } else { - LOG_ERROR(raco::log_system::RAMSES_ADAPTOR, "{} '{}': Couldn't load png file from '{}'", obj->getTypeDescription().typeName, obj->objectName(), uri); + LOG_ERROR(log_system::RAMSES_ADAPTOR, "{} '{}': Couldn't load png file from '{}'", obj->getTypeDescription().typeName, obj->objectName(), uri); errors->addError(core::ErrorCategory::PARSING, core::ErrorLevel::ERROR, {obj->shared_from_this(), {uriPropName}}, "Image file could not be loaded."); } return {}; } else { - if (&obj->getTypeDescription() == &raco::user_types::CubeMap::typeDescription && curWidth != curHeight) { - LOG_ERROR(raco::log_system::RAMSES_ADAPTOR, "CubeMap '{}': non-square image '{}' for '{}'", obj->objectName(), uri, uriPropName); + if (&obj->getTypeDescription() == &user_types::CubeMap::typeDescription && curWidth != curHeight) { + LOG_ERROR(log_system::RAMSES_ADAPTOR, "CubeMap '{}': non-square image '{}' for '{}'", obj->objectName(), uri, uriPropName); errors->addError(core::ErrorCategory::PARSING, core::ErrorLevel::ERROR, {obj->shared_from_this(), {uriPropName}}, fmt::format("Non-square image size {}x{}", curWidth, curHeight)); return {}; @@ -702,7 +697,7 @@ std::vector decodeMipMapData(core::Errors *errors, core::Project int expectedHeight = decodingInfo.height * std::pow(0.5, level - 1); if (curWidth != expectedWidth || expectedHeight != expectedHeight) { - LOG_ERROR(raco::log_system::RAMSES_ADAPTOR, "Texture '{}': incompatible image sizes", obj->objectName()); + LOG_ERROR(log_system::RAMSES_ADAPTOR, "Texture '{}': incompatible image sizes", obj->objectName()); auto errorMsg = (decodingInfo.width == -1) ? "Level 1 mipmap not defined" : fmt::format("Incompatible image size {}x{}, expected is {}x{}", curWidth, curHeight, expectedWidth, expectedHeight); @@ -716,9 +711,9 @@ std::vector decodeMipMapData(core::Errors *errors, core::Project return {}; } - if (textureFormatCompatInfo.errorLvl != raco::core::ErrorLevel::NONE) { + if (textureFormatCompatInfo.errorLvl != core::ErrorLevel::NONE) { errors->addError(core::ErrorCategory::PARSING, textureFormatCompatInfo.errorLvl, {obj->shared_from_this(), {uriPropName}}, textureFormatCompatInfo.errorMsg); - if (textureFormatCompatInfo.errorLvl == raco::core::ErrorLevel::ERROR) { + if (textureFormatCompatInfo.errorLvl == core::ErrorLevel::ERROR) { return {}; } } else { @@ -726,17 +721,17 @@ std::vector decodeMipMapData(core::Errors *errors, core::Project } if (decodingInfo.bitdepth == 16) { - raco::ramses_base::normalize16BitColorData(data); + ramses_base::normalize16BitColorData(data); } else if (pngColorType != LCT_GREY_ALPHA && decodingInfo.convertedPngFormat == ramses::ETextureFormat::RG8) { - data = raco::ramses_base::generateColorDataWithoutBlueChannel(data); + data = ramses_base::generateColorDataWithoutBlueChannel(data); } } return data; } -int clipAndCheckIntProperty(const raco::core::ValueHandle value, core::Errors *errors, bool *allValid) { - auto range = value.constValueRef()->query>(); +int clipAndCheckIntProperty(const core::ValueHandle value, core::Errors *errors, bool *allValid) { + auto range = value.constValueRef()->query>(); int clippedValue = std::min(std::max(*range->min_, value.asInt()), *range->max_); if (clippedValue != value.asInt()) { @@ -749,28 +744,6 @@ int clipAndCheckIntProperty(const raco::core::ValueHandle value, core::Errors *e return clippedValue; } -ramses::ERenderBufferType ramsesRenderBufferTypeFromFormat(ramses::ERenderBufferFormat format) { - using namespace ramses; - std::map bufferTypeFromFormat = { - {ERenderBufferFormat_RGBA4, ERenderBufferType_Color}, - {ERenderBufferFormat_R8, ERenderBufferType_Color}, - {ERenderBufferFormat_RG8, ERenderBufferType_Color}, - {ERenderBufferFormat_RGB8, ERenderBufferType_Color}, - {ERenderBufferFormat_RGBA8, ERenderBufferType_Color}, - {ERenderBufferFormat_R16F, ERenderBufferType_Color}, - {ERenderBufferFormat_R32F, ERenderBufferType_Color}, - {ERenderBufferFormat_RG16F, ERenderBufferType_Color}, - {ERenderBufferFormat_RG32F, ERenderBufferType_Color}, - {ERenderBufferFormat_RGB16F, ERenderBufferType_Color}, - {ERenderBufferFormat_RGB32F, ERenderBufferType_Color}, - {ERenderBufferFormat_RGBA16F, ERenderBufferType_Color}, - {ERenderBufferFormat_RGBA32F, ERenderBufferType_Color}, - {ERenderBufferFormat_Depth24, ERenderBufferType_Depth}, - {ERenderBufferFormat_Depth24_Stencil8, ERenderBufferType_DepthStencil}}; - - return bufferTypeFromFormat.at(format); -} - std::tuple ramsesTextureFormatToSwizzleInfo(int colorType, ramses::ETextureFormat textureFormat) { struct SwizzleInfo { std::string colorInfo_; // Format textual description diff --git a/components/libRamsesBase/tests/AdaptorTestUtils.h b/components/libRamsesBase/tests/AdaptorTestUtils.h index ad083bfd..221b7419 100644 --- a/components/libRamsesBase/tests/AdaptorTestUtils.h +++ b/components/libRamsesBase/tests/AdaptorTestUtils.h @@ -13,65 +13,60 @@ template void checkUniformScalar(const ramses::Appearance* appearance, const std::string& name, const T value) { - ramses::UniformInput input; - if constexpr (std::is_same::value) { + ramses::UniformInput input = appearance->getEffect().findUniformInput(name.c_str()).value(); + if constexpr (std::is_same::value) { + bool bvalue; + appearance->getInputValue(input, bvalue); + EXPECT_EQ(bvalue, value); + } + else if constexpr (std::is_same::value) { int32_t ivalue; - appearance->getEffect().findUniformInput(name.c_str(), input); - appearance->getInputValueInt32(input, ivalue); + appearance->getInputValue(input, ivalue); EXPECT_EQ(ivalue, value); } else if constexpr (std::is_same::value) { float fvalue; - appearance->getEffect().findUniformInput(name.c_str(), input); - appearance->getInputValueFloat(input, fvalue); + appearance->getInputValue(input, fvalue); EXPECT_EQ(fvalue, value); } else if constexpr (std::is_same>::value) { - std::array value2f; - appearance->getEffect().findUniformInput(name.c_str(), input); - appearance->getInputValueVector2f(input, value2f[0], value2f[1]); - EXPECT_EQ(value2f, value); + ramses::vec2f value2f; + appearance->getInputValue(input, value2f); + EXPECT_EQ(value2f, glm::vec2(value[0], value[1])); } else if constexpr (std::is_same>::value) { - std::array value3f; - appearance->getEffect().findUniformInput(name.c_str(), input); - appearance->getInputValueVector3f(input, value3f[0], value3f[1], value3f[2]); - EXPECT_EQ(value3f, value); + ramses::vec3f value3f; + appearance->getInputValue(input, value3f); + EXPECT_EQ(value3f, glm::vec3(value[0], value[1], value[2])); } else if constexpr (std::is_same>::value) { - std::array value4f; - appearance->getEffect().findUniformInput(name.c_str(), input); - appearance->getInputValueVector4f(input, value4f[0], value4f[1], value4f[2], value4f[3]); - EXPECT_EQ(value4f, value); + ramses::vec4f value4f; + appearance->getInputValue(input, value4f); + EXPECT_EQ(value4f, glm::vec4(value[0], value[1], value[2], value[3])); } else if constexpr (std::is_same>::value) { - std::array value2i; - appearance->getEffect().findUniformInput(name.c_str(), input); - appearance->getInputValueVector2i(input, value2i[0], value2i[1]); - EXPECT_EQ(value2i, value); + ramses::vec2i value2i; + appearance->getInputValue(input, value2i); + EXPECT_EQ(value2i, glm::ivec2(value[0], value[1])); } else if constexpr (std::is_same>::value) { - std::array value3i; - appearance->getEffect().findUniformInput(name.c_str(), input); - appearance->getInputValueVector3i(input, value3i[0], value3i[1], value3i[2]); - EXPECT_EQ(value3i, value); + ramses::vec3i value3i; + appearance->getInputValue(input, value3i); + EXPECT_EQ(value3i, glm::ivec3(value[0], value[1], value[2])); } else if constexpr (std::is_same>::value) { - std::array value4i; - appearance->getEffect().findUniformInput(name.c_str(), input); - appearance->getInputValueVector4i(input, value4i[0], value4i[1], value4i[2], value4i[3]); - EXPECT_EQ(value4i, value); + ramses::vec4i value4i; + appearance->getInputValue(input, value4i); + EXPECT_EQ(value4i, glm::ivec4(value[0], value[1], value[2], value[3])); } else if constexpr (std::is_same::value) { const ramses::TextureSampler* u_sampler_texture; - EXPECT_EQ(ramses::StatusOK, appearance->getEffect().findUniformInput(name.c_str(), input)); - EXPECT_EQ(ramses::StatusOK, appearance->getInputTexture(input, u_sampler_texture)); + EXPECT_TRUE(appearance->getInputTexture(input, u_sampler_texture)); EXPECT_EQ(u_sampler_texture, value); } else if constexpr (std::is_same::value) { const ramses::TextureSamplerMS* u_sampler_texture; - EXPECT_EQ(ramses::StatusOK, appearance->getEffect().findUniformInput(name.c_str(), input)); - EXPECT_EQ(ramses::StatusOK, appearance->getInputTextureMS(input, u_sampler_texture)); + EXPECT_TRUE(appearance->getInputTextureMS(input, u_sampler_texture)); EXPECT_EQ(u_sampler_texture, value); } else { @@ -80,11 +75,13 @@ void checkUniformScalar(const ramses::Appearance* appearance, const std::string& } template -void checkUniformScalar(const raco::core::ValueHandle& handle, const ramses::Appearance* appearance, const std::string& name, const T value) { +void checkUniformScalar(const core::ValueHandle& handle, const ramses::Appearance* appearance, const std::string& name, const T value) { using namespace raco; checkUniformScalar(appearance, name, value); - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { + EXPECT_EQ(handle.asBool(), value); + } else if constexpr (std::is_same::value) { EXPECT_EQ(handle.asInt(), value); } else if constexpr (std::is_same::value) { EXPECT_EQ(handle.asDouble(), value); @@ -108,54 +105,51 @@ void checkUniformScalar(const raco::core::ValueHandle& handle, const ramses::App template void checkUniformVector(const ramses::Appearance* appearance, const std::string& name, int index, const T& value) { - ramses::UniformInput input; - if constexpr (std::is_same::value) { + ramses::UniformInput input = appearance->getEffect().findUniformInput(name.c_str()).value(); + if constexpr (std::is_same::value) { + std::array ivalue; + appearance->getInputValue(input, length, ivalue.data()); + EXPECT_EQ(ivalue[index], value) << fmt::format(" Property name '{}' index = {}", name, index); + } + else if constexpr (std::is_same::value) { std::array ivalue; - appearance->getEffect().findUniformInput(name.c_str(), input); - appearance->getInputValueInt32(input, length, ivalue.data()); - EXPECT_EQ(ivalue[index], value); + appearance->getInputValue(input, length, ivalue.data()); + EXPECT_EQ(ivalue[index], value) << fmt::format(" Property name '{}' index = {}", name, index); } else if constexpr (std::is_same::value) { std::array fvalue; - appearance->getEffect().findUniformInput(name.c_str(), input); - appearance->getInputValueFloat(input, length, fvalue.data()); - EXPECT_EQ(fvalue[index], value); + appearance->getInputValue(input, length, fvalue.data()); + EXPECT_EQ(fvalue[index], value) << fmt::format(" Property name '{}' index = {}", name, index); } else if constexpr (std::is_same>::value) { - std::array, length> value2f; - appearance->getEffect().findUniformInput(name.c_str(), input); - appearance->getInputValueVector2f(input, length, value2f.data()->data()); - EXPECT_EQ(value2f[index], value); + std::array values; + appearance->getInputValue(input, length, values.data()); + EXPECT_EQ(values[index], glm::vec2(value[0], value[1])) << fmt::format(" Property name '{}' index = {}", name, index); } else if constexpr (std::is_same>::value) { - std::array, length> value3f; - appearance->getEffect().findUniformInput(name.c_str(), input); - appearance->getInputValueVector3f(input, length, value3f.data()->data()); - EXPECT_EQ(value3f[index], value); + std::array values; + appearance->getInputValue(input, length, values.data()); + EXPECT_EQ(values[index], glm::vec3(value[0], value[1], value[2])) << fmt::format(" Property name '{}' index = {}", name, index); } else if constexpr (std::is_same>::value) { - std::array, length> value4f; - appearance->getEffect().findUniformInput(name.c_str(), input); - appearance->getInputValueVector4f(input, length, value4f.data()->data()); - EXPECT_EQ(value4f[index], value); + std::array values; + appearance->getInputValue(input, length, values.data()); + EXPECT_EQ(values[index], glm::vec4(value[0], value[1], value[2], value[3])) << fmt::format(" Property name '{}' index = {}", name, index); } else if constexpr (std::is_same>::value) { - std::array, length> value2i; - appearance->getEffect().findUniformInput(name.c_str(), input); - appearance->getInputValueVector2i(input, length, value2i.data()->data()); - EXPECT_EQ(value2i[index], value); + std::array values; + appearance->getInputValue(input, length, values.data()); + EXPECT_EQ(values[index], glm::ivec2(value[0], value[1])) << fmt::format(" Property name '{}' index = {}", name, index); } else if constexpr (std::is_same>::value) { - std::array, length> value3i; - appearance->getEffect().findUniformInput(name.c_str(), input); - appearance->getInputValueVector3i(input, length, value3i.data()->data()); - EXPECT_EQ(value3i[index], value); + std::array values; + appearance->getInputValue(input, length, values.data()); + EXPECT_EQ(values[index], glm::ivec3(value[0], value[1], value[2])) << fmt::format(" Property name '{}' index = {}", name, index); } else if constexpr (std::is_same>::value) { - std::array, length> value4i; - appearance->getEffect().findUniformInput(name.c_str(), input); - appearance->getInputValueVector4i(input, length, value4i.data()->data()); - EXPECT_EQ(value4i[index], value); + std::array values; + appearance->getInputValue(input, length, values.data()); + EXPECT_EQ(values[index], glm::ivec4(value[0], value[1], value[2], value[3])) << fmt::format(" Property name '{}' index = {}", name, index); } else { EXPECT_TRUE(false); diff --git a/components/libRamsesBase/tests/AnimationAdaptor_test.cpp b/components/libRamsesBase/tests/AnimationAdaptor_test.cpp index 394c7932..36d354a8 100644 --- a/components/libRamsesBase/tests/AnimationAdaptor_test.cpp +++ b/components/libRamsesBase/tests/AnimationAdaptor_test.cpp @@ -20,12 +20,6 @@ using namespace raco::user_types; class AnimationAdaptorTest : public RamsesBaseFixture<> {}; -class AnimationAdaptorTest_FL3 : public RamsesBaseFixture<> { -public: - AnimationAdaptorTest_FL3() : RamsesBaseFixture(false, static_cast(3)) {} -}; - - TEST_F(AnimationAdaptorTest, animNode_Creation) { auto anim = context.createObject(Animation::typeDescription.typeName, "Animation Name"); auto animChannel = context.createObject(AnimationChannel::typeDescription.typeName, "Animation Sampler Name"); @@ -33,15 +27,15 @@ TEST_F(AnimationAdaptorTest, animNode_Creation) { dispatch(); std::string uriPath{(test_path() / "meshes" / "InterpolationTest" / "InterpolationTest.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); dispatch(); - context.set({animChannel, &raco::user_types::AnimationChannel::animationIndex_}, 4); - context.set({anim, {"animationChannels", "Channel 0"}}, animChannel); + context.set({animChannel, &user_types::AnimationChannel::animationIndex_}, 4); + context.set(ValueHandle(anim, &Animation::animationChannels_)[0], animChannel); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Name"), nullptr); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Name"), nullptr); } TEST_F(AnimationAdaptorTest, animNode_Deletion) { @@ -51,19 +45,19 @@ TEST_F(AnimationAdaptorTest, animNode_Deletion) { dispatch(); std::string uriPath{(test_path() / "meshes" / "InterpolationTest" / "InterpolationTest.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); dispatch(); - context.set({animChannel, &raco::user_types::AnimationChannel::animationIndex_}, 4); - context.set({anim, {"animationChannels", "Channel 0"}}, animChannel); + context.set({animChannel, &user_types::AnimationChannel::animationIndex_}, 4); + context.set(ValueHandle(anim, &Animation::animationChannels_)[0], animChannel); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); - context.set({anim, {"animationChannels", "Channel 0"}}, SEditorObject{}); + context.set(ValueHandle(anim, &Animation::animationChannels_)[0], SEditorObject()); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); } TEST_F(AnimationAdaptorTest, animNode_animName) { @@ -73,19 +67,19 @@ TEST_F(AnimationAdaptorTest, animNode_animName) { dispatch(); std::string uriPath{(test_path() / "meshes" / "InterpolationTest" / "InterpolationTest.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); dispatch(); - context.set({animChannel, &raco::user_types::AnimationChannel::animationIndex_}, 4); - context.set({anim, {"animationChannels", "Channel 0"}}, animChannel); + context.set({animChannel, &user_types::AnimationChannel::animationIndex_}, 4); + context.set(ValueHandle(anim, &Animation::animationChannels_)[0], animChannel); dispatch(); context.set({anim, {"objectName"}}, "Changed"); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); - ASSERT_EQ(sceneContext.logicEngine().getCollection().begin()->getUserId(), anim->objectIDAsRamsesLogicID()); - ASSERT_NE(select(sceneContext.logicEngine(), "Changed"), nullptr); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); + ASSERT_EQ(sceneContext.logicEngine().getCollection().begin()->getUserId(), anim->objectIDAsRamsesLogicID()); + ASSERT_NE(select(sceneContext.logicEngine(), "Changed"), nullptr); } TEST_F(AnimationAdaptorTest, prefab_noAnimNode) { @@ -95,11 +89,11 @@ TEST_F(AnimationAdaptorTest, prefab_noAnimNode) { dispatch(); std::string uriPath{(test_path() / "meshes" / "InterpolationTest" / "InterpolationTest.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); dispatch(); - context.set({animChannel, &raco::user_types::AnimationChannel::animationIndex_}, 4); - context.set({anim, {"animationChannels", "Channel 0"}}, animChannel); + context.set({animChannel, &user_types::AnimationChannel::animationIndex_}, 4); + context.set(ValueHandle(anim, &Animation::animationChannels_)[0], animChannel); dispatch(); context.set({anim, {"objectName"}}, "Changed"); @@ -111,7 +105,7 @@ TEST_F(AnimationAdaptorTest, prefab_noAnimNode) { commandInterface.moveScenegraphChildren({anim}, prefab); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); } TEST_F(AnimationAdaptorTest, animNode_multiple_channels) { @@ -119,43 +113,45 @@ TEST_F(AnimationAdaptorTest, animNode_multiple_channels) { auto animChannel1 = context.createObject(AnimationChannel::typeDescription.typeName, "Animation Sampler Name 1"); auto animChannel2 = context.createObject(AnimationChannel::typeDescription.typeName, "Animation Sampler Name 2"); auto animChannel3 = context.createObject(AnimationChannel::typeDescription.typeName, "Animation Sampler Name 3"); + ValueHandle channelsHandle(anim, &Animation::animationChannels_); + context.resizeArray(channelsHandle, 3); dispatch(); std::string uriPath{(test_path() / "meshes" / "InterpolationTest" / "InterpolationTest.gltf").string()}; - commandInterface.set({animChannel1, &raco::user_types::AnimationChannel::uri_}, uriPath); - commandInterface.set({animChannel2, &raco::user_types::AnimationChannel::uri_}, uriPath); - commandInterface.set({animChannel3, &raco::user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel1, &user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel2, &user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel3, &user_types::AnimationChannel::uri_}, uriPath); dispatch(); - context.set({animChannel1, &raco::user_types::AnimationChannel::animationIndex_}, 4); - context.set({animChannel2, &raco::user_types::AnimationChannel::animationIndex_}, 2); - context.set({animChannel3, &raco::user_types::AnimationChannel::animationIndex_}, 3); + context.set({animChannel1, &user_types::AnimationChannel::animationIndex_}, 4); + context.set({animChannel2, &user_types::AnimationChannel::animationIndex_}, 2); + context.set({animChannel3, &user_types::AnimationChannel::animationIndex_}, 3); - context.set({anim, {"animationChannels", "Channel 0"}}, animChannel1); + context.set(channelsHandle[0], animChannel1); dispatch(); - context.set({anim, {"animationChannels", "Channel 1"}}, animChannel2); + context.set(channelsHandle[1], animChannel2); dispatch(); - context.set({anim, {"animationChannels", "Channel 2"}}, animChannel3); + context.set(channelsHandle[2], animChannel3); dispatch(); ASSERT_EQ(anim->get("outputs")->asTable().size(), 3); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name 1.keyframes"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name 1.keyframes")->getUserId(), animChannel1->objectIDAsRamsesLogicID()); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name 1.timestamps"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name 1.timestamps")->getUserId(), animChannel1->objectIDAsRamsesLogicID()); - - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name 2.keyframes"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name 2.keyframes")->getUserId(), animChannel2->objectIDAsRamsesLogicID()); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name 2.timestamps"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name 2.timestamps")->getUserId(), animChannel2->objectIDAsRamsesLogicID()); - - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name 3.keyframes"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name 3.keyframes")->getUserId(), animChannel3->objectIDAsRamsesLogicID()); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name 3.timestamps"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name 3.timestamps")->getUserId(), animChannel3->objectIDAsRamsesLogicID()); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name 1.keyframes"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name 1.keyframes")->getUserId(), animChannel1->objectIDAsRamsesLogicID()); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name 1.timestamps"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name 1.timestamps")->getUserId(), animChannel1->objectIDAsRamsesLogicID()); + + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name 2.keyframes"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name 2.keyframes")->getUserId(), animChannel2->objectIDAsRamsesLogicID()); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name 2.timestamps"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name 2.timestamps")->getUserId(), animChannel2->objectIDAsRamsesLogicID()); + + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name 3.keyframes"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name 3.keyframes")->getUserId(), animChannel3->objectIDAsRamsesLogicID()); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name 3.timestamps"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name 3.timestamps")->getUserId(), animChannel3->objectIDAsRamsesLogicID()); } TEST_F(AnimationAdaptorTest, afterSync_dataArrays_get_cleaned_up) { @@ -165,29 +161,29 @@ TEST_F(AnimationAdaptorTest, afterSync_dataArrays_get_cleaned_up) { dispatch(); std::string uriPath{(test_path() / "meshes" / "InterpolationTest" / "InterpolationTest.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); dispatch(); - context.set({animChannel, &raco::user_types::AnimationChannel::animationIndex_}, 4); - context.set({anim, {"animationChannels", "Channel 0"}}, animChannel); + context.set({animChannel, &user_types::AnimationChannel::animationIndex_}, 4); + context.set(ValueHandle(anim, &Animation::animationChannels_)[0], animChannel); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 4); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes"), nullptr); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps"), nullptr); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentIn"), nullptr); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentOut"), nullptr); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 4); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes"), nullptr); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps"), nullptr); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentIn"), nullptr); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentOut"), nullptr); // moving from cubic to non-cubic anim: tangent data arrays should be deallocated - context.set({animChannel, &raco::user_types::AnimationChannel::animationIndex_}, 3); + context.set({animChannel, &user_types::AnimationChannel::animationIndex_}, 3); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 2); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes"), nullptr); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentIn"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentOut"), nullptr); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 2); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes"), nullptr); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentIn"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentOut"), nullptr); } TEST_F(AnimationAdaptorTest, link_animation_to_node) { @@ -197,23 +193,22 @@ TEST_F(AnimationAdaptorTest, link_animation_to_node) { dispatch(); std::string uriPath{(test_path() / "meshes" / "InterpolationTest" / "InterpolationTest.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); dispatch(); - commandInterface.set({anim, {"animationChannels", "Channel 0"}}, animChannel); + context.set(ValueHandle(anim, &Animation::animationChannels_)[0], animChannel); dispatch(); auto ramsesNode = select(*sceneContext.scene(), "Node"); - float x, y, z; - - ramsesNode->getTranslation(x, y, z); - EXPECT_EQ(x, 0.0); + glm::vec3 v; + ramsesNode->getTranslation(v); + EXPECT_EQ(v.x, 0.0); commandInterface.addLink({anim, {"outputs", "Ch0.Animation Sampler Name"}}, {node, {"translation"}}); dispatch(); - ramsesNode->getTranslation(x, y, z); - EXPECT_EQ(x, 1.0); + ramsesNode->getTranslation(v); + EXPECT_EQ(v.x, 1.0); } TEST_F(AnimationAdaptorTest, component_type_array_valid) { @@ -221,26 +216,13 @@ TEST_F(AnimationAdaptorTest, component_type_array_valid) { auto animChannel = context.createObject(AnimationChannel::typeDescription.typeName, "Animation Sampler Name"); std::string uriPath{(test_path() / "meshes" / "AnimatedMorphCube" / "AnimatedMorphCube.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); dispatch(); - context.set({anim, {"animationChannels", "Channel 0"}}, animChannel); + context.set(ValueHandle(anim, &Animation::animationChannels_)[0], animChannel); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Name"), nullptr); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Name"), nullptr); } -TEST_F(AnimationAdaptorTest_FL3, component_type_array_invalid_fl3) { - auto anim = context.createObject(Animation::typeDescription.typeName, "Animation Name"); - auto animChannel = context.createObject(AnimationChannel::typeDescription.typeName, "Animation Sampler Name"); - - std::string uriPath{(test_path() / "meshes" / "AnimatedMorphCube" / "AnimatedMorphCube.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); - dispatch(); - - context.set({anim, {"animationChannels", "Channel 0"}}, animChannel); - dispatch(); - - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); -} diff --git a/components/libRamsesBase/tests/AnimationChannelAdaptor_test.cpp b/components/libRamsesBase/tests/AnimationChannelAdaptor_test.cpp index c4669c13..bf7ae8e5 100644 --- a/components/libRamsesBase/tests/AnimationChannelAdaptor_test.cpp +++ b/components/libRamsesBase/tests/AnimationChannelAdaptor_test.cpp @@ -17,17 +17,12 @@ using namespace raco::user_types; class AnimationChannelAdaptorTest : public RamsesBaseFixture<> {}; -class AnimationChannelAdaptorTest_FL3 : public RamsesBaseFixture<> { -public: - AnimationChannelAdaptorTest_FL3() : RamsesBaseFixture(false, static_cast(3)) {} -}; - TEST_F(AnimationChannelAdaptorTest, defaultConstruction) { auto animChannel = context.createObject(AnimationChannel::typeDescription.typeName, "Animation Sampler Name"); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); } TEST_F(AnimationChannelAdaptorTest, validAnim_validSampler_dataArrays) { @@ -36,14 +31,14 @@ TEST_F(AnimationChannelAdaptorTest, validAnim_validSampler_dataArrays) { dispatch(); std::string uriPath{(test_path() / "meshes" / "CesiumMilkTruck" / "CesiumMilkTruck.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 2); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes")->getUserId(), animChannel->objectIDAsRamsesLogicID()); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps")->getUserId(), animChannel->objectIDAsRamsesLogicID()); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 2); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes")->getUserId(), animChannel->objectIDAsRamsesLogicID()); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps")->getUserId(), animChannel->objectIDAsRamsesLogicID()); } TEST_F(AnimationChannelAdaptorTest, validAnim_validSampler_dataArrays_rename_obj) { @@ -52,17 +47,17 @@ TEST_F(AnimationChannelAdaptorTest, validAnim_validSampler_dataArrays_rename_obj dispatch(); std::string uriPath{(test_path() / "meshes" / "CesiumMilkTruck" / "CesiumMilkTruck.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); dispatch(); context.set({animChannel, {"objectName"}}, std::string("Changed")); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 2); - ASSERT_NE(select(sceneContext.logicEngine(), "Changed.keyframes"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Changed.keyframes")->getUserId(), animChannel->objectIDAsRamsesLogicID()); - ASSERT_NE(select(sceneContext.logicEngine(), "Changed.timestamps"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Changed.timestamps")->getUserId(), animChannel->objectIDAsRamsesLogicID()); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 2); + ASSERT_NE(select(sceneContext.logicEngine(), "Changed.keyframes"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Changed.keyframes")->getUserId(), animChannel->objectIDAsRamsesLogicID()); + ASSERT_NE(select(sceneContext.logicEngine(), "Changed.timestamps"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Changed.timestamps")->getUserId(), animChannel->objectIDAsRamsesLogicID()); } TEST_F(AnimationChannelAdaptorTest, validAnim_validSampler_animAssigned_dataArrays_rename_obj) { @@ -71,21 +66,21 @@ TEST_F(AnimationChannelAdaptorTest, validAnim_validSampler_animAssigned_dataArra dispatch(); std::string uriPath{(test_path() / "meshes" / "CesiumMilkTruck" / "CesiumMilkTruck.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); dispatch(); auto anim = context.createObject(Animation::typeDescription.typeName, "Animation Name"); - context.set({anim, {"animationChannels", "Channel 0"}}, animChannel); + context.set(ValueHandle(anim, {"animationChannels"})[0], animChannel); dispatch(); context.set({animChannel, {"objectName"}}, std::string("Changed")); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 2); - ASSERT_NE(select(sceneContext.logicEngine(), "Changed.keyframes"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Changed.keyframes")->getUserId(), animChannel->objectIDAsRamsesLogicID()); - ASSERT_NE(select(sceneContext.logicEngine(), "Changed.timestamps"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Changed.timestamps")->getUserId(), animChannel->objectIDAsRamsesLogicID()); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 2); + ASSERT_NE(select(sceneContext.logicEngine(), "Changed.keyframes"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Changed.keyframes")->getUserId(), animChannel->objectIDAsRamsesLogicID()); + ASSERT_NE(select(sceneContext.logicEngine(), "Changed.timestamps"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Changed.timestamps")->getUserId(), animChannel->objectIDAsRamsesLogicID()); } TEST_F(AnimationChannelAdaptorTest, validAnim_invalidSampler_noDataArrays) { @@ -94,13 +89,13 @@ TEST_F(AnimationChannelAdaptorTest, validAnim_invalidSampler_noDataArrays) { dispatch(); std::string uriPath{(test_path() / "meshes" / "CesiumMilkTruck" / "CesiumMilkTruck.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); dispatch(); - context.set({animChannel, &raco::user_types::AnimationChannel::samplerIndex_}, -1); + context.set({animChannel, &user_types::AnimationChannel::samplerIndex_}, -1); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); } TEST_F(AnimationChannelAdaptorTest, invalidAnim_invalidSampler_noDataArrays) { @@ -109,13 +104,13 @@ TEST_F(AnimationChannelAdaptorTest, invalidAnim_invalidSampler_noDataArrays) { dispatch(); std::string uriPath{(test_path() / "meshes" / "CesiumMilkTruck" / "CesiumMilkTruck.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); dispatch(); - context.set({animChannel, &raco::user_types::AnimationChannel::animationIndex_}, -1); + context.set({animChannel, &user_types::AnimationChannel::animationIndex_}, -1); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); } TEST_F(AnimationChannelAdaptorTest, noAnim_noDataArrays) { @@ -124,10 +119,10 @@ TEST_F(AnimationChannelAdaptorTest, noAnim_noDataArrays) { dispatch(); std::string uriPath{(test_path() / "meshes" / "Duck.glb").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); } TEST_F(AnimationChannelAdaptorTest, interpolationTest_dynamicDataArrays) { @@ -136,37 +131,37 @@ TEST_F(AnimationChannelAdaptorTest, interpolationTest_dynamicDataArrays) { dispatch(); std::string uriPath{(test_path() / "meshes" / "InterpolationTest" / "InterpolationTest.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); dispatch(); - context.set({animChannel, &raco::user_types::AnimationChannel::animationIndex_}, 4); + context.set({animChannel, &user_types::AnimationChannel::animationIndex_}, 4); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 4); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes")->getUserId(), animChannel->objectIDAsRamsesLogicID()); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 4); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes")->getUserId(), animChannel->objectIDAsRamsesLogicID()); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps")->getUserId(), animChannel->objectIDAsRamsesLogicID()); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps")->getUserId(), animChannel->objectIDAsRamsesLogicID()); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentIn"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentIn")->getUserId(), animChannel->objectIDAsRamsesLogicID()); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentIn"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentIn")->getUserId(), animChannel->objectIDAsRamsesLogicID()); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentOut"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentOut")->getUserId(), animChannel->objectIDAsRamsesLogicID()); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentOut"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentOut")->getUserId(), animChannel->objectIDAsRamsesLogicID()); - context.set({animChannel, &raco::user_types::AnimationChannel::animationIndex_}, 3); + context.set({animChannel, &user_types::AnimationChannel::animationIndex_}, 3); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 2); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes")->getUserId(), animChannel->objectIDAsRamsesLogicID()); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 2); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes")->getUserId(), animChannel->objectIDAsRamsesLogicID()); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps")->getUserId(), animChannel->objectIDAsRamsesLogicID()); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps")->getUserId(), animChannel->objectIDAsRamsesLogicID()); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentIn"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentOut"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentIn"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.tangentOut"), nullptr); } @@ -177,18 +172,18 @@ TEST_F(AnimationChannelAdaptorTest, mesh_baked_flag_true_anim_data_gets_imported dispatch(); std::string uriPath{(test_path() / "meshes" / "InterpolationTest" / "InterpolationTest.gltf").string()}; - commandInterface.set({mesh, &raco::user_types::Mesh::uri_}, uriPath); + commandInterface.set({mesh, &user_types::Mesh::uri_}, uriPath); dispatch(); - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 2); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes")->getUserId(), animChannel->objectIDAsRamsesLogicID()); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 2); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes")->getUserId(), animChannel->objectIDAsRamsesLogicID()); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps")->getUserId(), animChannel->objectIDAsRamsesLogicID()); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps")->getUserId(), animChannel->objectIDAsRamsesLogicID()); } TEST_F(AnimationChannelAdaptorTest, component_type_array_valid) { @@ -197,24 +192,12 @@ TEST_F(AnimationChannelAdaptorTest, component_type_array_valid) { dispatch(); std::string uriPath{(test_path() / "meshes" / "AnimatedMorphCube" / "AnimatedMorphCube.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 2); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes")->getUserId(), animChannel->objectIDAsRamsesLogicID()); - ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps")->getUserId(), animChannel->objectIDAsRamsesLogicID()); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 2); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.keyframes")->getUserId(), animChannel->objectIDAsRamsesLogicID()); + ASSERT_NE(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Animation Sampler Name.timestamps")->getUserId(), animChannel->objectIDAsRamsesLogicID()); } - -TEST_F(AnimationChannelAdaptorTest_FL3, component_type_array_invalid_fl3) { - auto animChannel = context.createObject(AnimationChannel::typeDescription.typeName, "Animation Sampler Name"); - - dispatch(); - - std::string uriPath{(test_path() / "meshes" / "AnimatedMorphCube" / "AnimatedMorphCube.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); - dispatch(); - - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); -} \ No newline at end of file diff --git a/components/libRamsesBase/tests/BlitPassAdaptor_test.cpp b/components/libRamsesBase/tests/BlitPassAdaptor_test.cpp index 65f46ddb..1dba51d0 100644 --- a/components/libRamsesBase/tests/BlitPassAdaptor_test.cpp +++ b/components/libRamsesBase/tests/BlitPassAdaptor_test.cpp @@ -23,7 +23,7 @@ TEST_F(BlitPassAdaptorTest, defaultConstruction) { dispatch(); - auto blitPasses{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_BlitPass)}; + auto blitPasses{select(*sceneContext.scene(), ramses::ERamsesObjectType::BlitPass)}; ASSERT_EQ(blitPasses.size(), 0); } @@ -33,11 +33,11 @@ TEST_F(BlitPassAdaptorTest, validBlitPass_BlitPassObj_sourceSingleSample_targetS auto targetRenderBuffer = context.createObject(RenderBuffer::typeDescription.typeName, "RenderBuffer"); dispatch(); - context.set({blitPass, &raco::user_types::BlitPass::sourceRenderBuffer_}, sourceRenderBuffer); - context.set({blitPass, &raco::user_types::BlitPass::targetRenderBuffer_}, targetRenderBuffer); + context.set({blitPass, &user_types::BlitPass::sourceRenderBuffer_}, sourceRenderBuffer); + context.set({blitPass, &user_types::BlitPass::targetRenderBuffer_}, targetRenderBuffer); dispatch(); - auto blitPasses{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_BlitPass)}; + auto blitPasses{select(*sceneContext.scene(), ramses::ERamsesObjectType::BlitPass)}; ASSERT_EQ(blitPasses.size(), 1); } @@ -47,11 +47,11 @@ TEST_F(BlitPassAdaptorTest, validBlitPass_BlitPassObj_sourceMultiSample_targetMu auto targetRenderBuffer = context.createObject(RenderBufferMS::typeDescription.typeName, "RenderBufferMS"); dispatch(); - context.set({blitPass, &raco::user_types::BlitPass::sourceRenderBufferMS_}, sourceRenderBuffer); - context.set({blitPass, &raco::user_types::BlitPass::targetRenderBufferMS_}, targetRenderBuffer); + context.set({blitPass, &user_types::BlitPass::sourceRenderBufferMS_}, sourceRenderBuffer); + context.set({blitPass, &user_types::BlitPass::targetRenderBufferMS_}, targetRenderBuffer); dispatch(); - auto blitPasses{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_BlitPass)}; + auto blitPasses{select(*sceneContext.scene(), ramses::ERamsesObjectType::BlitPass)}; ASSERT_EQ(blitPasses.size(), 1); } @@ -61,11 +61,11 @@ TEST_F(BlitPassAdaptorTest, validBlitPass_BlitPassObj_sourceSingleSample_targetM auto targetRenderBuffer = context.createObject(RenderBufferMS::typeDescription.typeName, "RenderBufferMS"); dispatch(); - context.set({blitPass, &raco::user_types::BlitPass::sourceRenderBuffer_}, sourceRenderBuffer); - context.set({blitPass, &raco::user_types::BlitPass::targetRenderBufferMS_}, targetRenderBuffer); + context.set({blitPass, &user_types::BlitPass::sourceRenderBuffer_}, sourceRenderBuffer); + context.set({blitPass, &user_types::BlitPass::targetRenderBufferMS_}, targetRenderBuffer); dispatch(); - auto blitPasses{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_BlitPass)}; + auto blitPasses{select(*sceneContext.scene(), ramses::ERamsesObjectType::BlitPass)}; ASSERT_EQ(blitPasses.size(), 1); } @@ -75,11 +75,11 @@ TEST_F(BlitPassAdaptorTest, validBlitPass_BlitPassObj_sourceMultiSample_targetSi auto targetRenderBuffer = context.createObject(RenderBuffer::typeDescription.typeName, "RenderBuffer"); dispatch(); - context.set({blitPass, &raco::user_types::BlitPass::sourceRenderBufferMS_}, sourceRenderBuffer); - context.set({blitPass, &raco::user_types::BlitPass::targetRenderBuffer_}, targetRenderBuffer); + context.set({blitPass, &user_types::BlitPass::sourceRenderBufferMS_}, sourceRenderBuffer); + context.set({blitPass, &user_types::BlitPass::targetRenderBuffer_}, targetRenderBuffer); dispatch(); - auto blitPasses{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_BlitPass)}; + auto blitPasses{select(*sceneContext.scene(), ramses::ERamsesObjectType::BlitPass)}; ASSERT_EQ(blitPasses.size(), 1); } @@ -91,13 +91,13 @@ TEST_F(BlitPassAdaptorTest, validBlitPass_BlitPassObj_all_refs_filled) { auto targetRenderBufferMS = context.createObject(RenderBufferMS::typeDescription.typeName, "RenderBufferMS"); dispatch(); - context.set({blitPass, &raco::user_types::BlitPass::sourceRenderBuffer_}, sourceRenderBuffer); - context.set({blitPass, &raco::user_types::BlitPass::targetRenderBuffer_}, targetRenderBuffer); - context.set({blitPass, &raco::user_types::BlitPass::sourceRenderBufferMS_}, sourceRenderBufferMS); - context.set({blitPass, &raco::user_types::BlitPass::targetRenderBufferMS_}, targetRenderBufferMS); + context.set({blitPass, &user_types::BlitPass::sourceRenderBuffer_}, sourceRenderBuffer); + context.set({blitPass, &user_types::BlitPass::targetRenderBuffer_}, targetRenderBuffer); + context.set({blitPass, &user_types::BlitPass::sourceRenderBufferMS_}, sourceRenderBufferMS); + context.set({blitPass, &user_types::BlitPass::targetRenderBufferMS_}, targetRenderBufferMS); dispatch(); - auto blitPasses{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_BlitPass)}; + auto blitPasses{select(*sceneContext.scene(), ramses::ERamsesObjectType::BlitPass)}; ASSERT_EQ(blitPasses.size(), 1); } @@ -107,21 +107,21 @@ TEST_F(BlitPassAdaptorTest, validBlitPass_BlitPassObj_invalidate) { auto targetRenderBuffer = context.createObject(RenderBuffer::typeDescription.typeName, "RenderBuffer"); dispatch(); - context.set({blitPass, &raco::user_types::BlitPass::sourceRenderBuffer_}, sourceRenderBuffer); - context.set({blitPass, &raco::user_types::BlitPass::targetRenderBuffer_}, targetRenderBuffer); + context.set({blitPass, &user_types::BlitPass::sourceRenderBuffer_}, sourceRenderBuffer); + context.set({blitPass, &user_types::BlitPass::targetRenderBuffer_}, targetRenderBuffer); dispatch(); - context.set({blitPass, &raco::user_types::BlitPass::width_}, 600); + context.set({blitPass, &user_types::BlitPass::width_}, 600); dispatch(); - auto blitPasses{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_BlitPass)}; + auto blitPasses{select(*sceneContext.scene(), ramses::ERamsesObjectType::BlitPass)}; ASSERT_EQ(blitPasses.size(), 1); ASSERT_TRUE(context.errors().hasError(blitPass)); - context.set({blitPass, &raco::user_types::BlitPass::width_}, 256); + context.set({blitPass, &user_types::BlitPass::width_}, 256); dispatch(); - blitPasses = select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_BlitPass); + blitPasses = select(*sceneContext.scene(), ramses::ERamsesObjectType::BlitPass); ASSERT_EQ(blitPasses.size(), 1); ASSERT_FALSE(context.errors().hasError(blitPass)); } @@ -132,19 +132,19 @@ TEST_F(BlitPassAdaptorTest, validBlitPass_nameChange) { auto targetRenderBuffer = context.createObject(RenderBuffer::typeDescription.typeName, "RenderBuffer"); dispatch(); - context.set({blitPass, &raco::user_types::BlitPass::sourceRenderBuffer_}, sourceRenderBuffer); - context.set({blitPass, &raco::user_types::BlitPass::targetRenderBuffer_}, targetRenderBuffer); + context.set({blitPass, &user_types::BlitPass::sourceRenderBuffer_}, sourceRenderBuffer); + context.set({blitPass, &user_types::BlitPass::targetRenderBuffer_}, targetRenderBuffer); dispatch(); - auto blitPasses{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_BlitPass)}; + auto blitPasses{select(*sceneContext.scene(), ramses::ERamsesObjectType::BlitPass)}; ASSERT_EQ(blitPasses.size(), 1); - ASSERT_STREQ(blitPasses.front()->getName(), "MyBlitPass"); + ASSERT_TRUE(blitPasses.front()->getName() == "MyBlitPass"); - context.set({blitPass, &raco::user_types::BlitPass::objectName_}, std::string("BlitPassRenamed")); + context.set({blitPass, &user_types::BlitPass::objectName_}, std::string("BlitPassRenamed")); dispatch(); - blitPasses = select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_BlitPass); + blitPasses = select(*sceneContext.scene(), ramses::ERamsesObjectType::BlitPass); ASSERT_EQ(blitPasses.size(), 1); - ASSERT_STREQ(blitPasses.front()->getName(), "BlitPassRenamed"); + ASSERT_TRUE(blitPasses.front()->getName() == "BlitPassRenamed"); } \ No newline at end of file diff --git a/components/libRamsesBase/tests/CubeMapAdaptor_test.cpp b/components/libRamsesBase/tests/CubeMapAdaptor_test.cpp index 4e78666d..6655eef8 100644 --- a/components/libRamsesBase/tests/CubeMapAdaptor_test.cpp +++ b/components/libRamsesBase/tests/CubeMapAdaptor_test.cpp @@ -11,44 +11,45 @@ #include "RamsesBaseFixture.h" #include "ramses_adaptor/CubeMapAdaptor.h" +#include "user_types/Enumerations.h" -#include +using user_types::ETextureFormat; class CubeMapAdaptorFixture : public RamsesBaseFixture<> { public: - void assertLevel1Errors(raco::core::SEditorObject cubemap, raco::core::ErrorLevel level) { - if (level == raco::core::ErrorLevel::NONE) { - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::uriBack_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::uriBottom_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::uriFront_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::uriLeft_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::uriRight_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::uriTop_})); + void assertLevel1Errors(core::SEditorObject cubemap, core::ErrorLevel level) { + if (level == core::ErrorLevel::NONE) { + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::uriBack_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::uriBottom_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::uriFront_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::uriLeft_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::uriRight_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::uriTop_})); } else { - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::uriBack_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::uriBack_}).level(), level); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::uriBack_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::uriBack_}).level(), level); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::uriBottom_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::uriBottom_}).level(), level); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::uriBottom_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::uriBottom_}).level(), level); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::uriFront_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::uriFront_}).level(), level); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::uriFront_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::uriFront_}).level(), level); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::uriLeft_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::uriLeft_}).level(), level); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::uriLeft_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::uriLeft_}).level(), level); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::uriRight_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::uriRight_}).level(), level); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::uriRight_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::uriRight_}).level(), level); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::uriTop_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::uriTop_}).level(), level); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::uriTop_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::uriTop_}).level(), level); } } - void checkTextureFormats(raco::core::SEditorObject cubemap, const std::map& formats) { + void checkTextureFormats(core::SEditorObject cubemap, const std::map& formats) { for (const auto& [format, level] : formats) { - commandInterface.set({cubemap, &raco::user_types::CubeMap::textureFormat_}, static_cast(format)); + commandInterface.set({cubemap, &user_types::CubeMap::textureFormat_}, static_cast(format)); dispatch(); assertLevel1Errors(cubemap, level); } @@ -56,576 +57,576 @@ class CubeMapAdaptorFixture : public RamsesBaseFixture<> { }; TEST_F(CubeMapAdaptorFixture, cubeMapGenerationAtMultipleLevels) { - auto cubeMap = create("Cubemap"); + auto cubeMap = create("Cubemap"); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "blue_1024.png").string()); dispatch(); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level2uriBack_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level2uriBottom_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level2uriFront_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level2uriLeft_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level2uriRight_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level2uriTop_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level2uriBack_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level2uriBottom_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level2uriFront_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level2uriLeft_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level2uriRight_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level2uriTop_}, (test_path() / "images" / "green_512.png").string()); dispatch(); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level3uriBack_}, (test_path() / "images" / "yellow_256.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level3uriBottom_}, (test_path() / "images" / "yellow_256.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level3uriFront_}, (test_path() / "images" / "yellow_256.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level3uriLeft_}, (test_path() / "images" / "yellow_256.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level3uriRight_}, (test_path() / "images" / "yellow_256.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level3uriTop_}, (test_path() / "images" / "yellow_256.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level3uriBack_}, (test_path() / "images" / "yellow_256.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level3uriBottom_}, (test_path() / "images" / "yellow_256.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level3uriFront_}, (test_path() / "images" / "yellow_256.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level3uriLeft_}, (test_path() / "images" / "yellow_256.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level3uriRight_}, (test_path() / "images" / "yellow_256.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level3uriTop_}, (test_path() / "images" / "yellow_256.png").string()); dispatch(); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level4uriBack_}, (test_path() / "images" / "red_128.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level4uriBottom_}, (test_path() / "images" / "red_128.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level4uriFront_}, (test_path() / "images" / "red_128.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level4uriLeft_}, (test_path() / "images" / "red_128.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level4uriRight_}, (test_path() / "images" / "red_128.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level4uriTop_}, (test_path() / "images" / "red_128.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level4uriBack_}, (test_path() / "images" / "red_128.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level4uriBottom_}, (test_path() / "images" / "red_128.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level4uriFront_}, (test_path() / "images" / "red_128.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level4uriLeft_}, (test_path() / "images" / "red_128.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level4uriRight_}, (test_path() / "images" / "red_128.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level4uriTop_}, (test_path() / "images" / "red_128.png").string()); dispatch(); - auto cubeMapStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_TextureSampler)}; + auto cubeMapStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::TextureSampler)}; ASSERT_EQ(cubeMapStuff.size(), 1); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::mipmapLevel_}, 2); + commandInterface.set({cubeMap, &user_types::CubeMap::mipmapLevel_}, 2); dispatch(); - cubeMapStuff = select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_TextureSampler); + cubeMapStuff = select(*sceneContext.scene(), ramses::ERamsesObjectType::TextureSampler); ASSERT_EQ(cubeMapStuff.size(), 1); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::mipmapLevel_}, 3); + commandInterface.set({cubeMap, &user_types::CubeMap::mipmapLevel_}, 3); dispatch(); - cubeMapStuff = select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_TextureSampler); + cubeMapStuff = select(*sceneContext.scene(), ramses::ERamsesObjectType::TextureSampler); ASSERT_EQ(cubeMapStuff.size(), 1); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::mipmapLevel_}, 4); + commandInterface.set({cubeMap, &user_types::CubeMap::mipmapLevel_}, 4); dispatch(); - cubeMapStuff = select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_TextureSampler); + cubeMapStuff = select(*sceneContext.scene(), ramses::ERamsesObjectType::TextureSampler); ASSERT_EQ(cubeMapStuff.size(), 1); } TEST_F(CubeMapAdaptorFixture, wrongMipMapLevelImageSizes) { - auto cubeMap = create("Cubemap"); + auto cubeMap = create("Cubemap"); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::mipmapLevel_}, 4); + commandInterface.set({cubeMap, &user_types::CubeMap::mipmapLevel_}, 4); dispatch(); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "blue_1024.png").string()); dispatch(); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level2uriBack_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level2uriBottom_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level2uriFront_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level2uriLeft_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level2uriRight_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level2uriTop_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level2uriBack_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level2uriBottom_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level2uriFront_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level2uriLeft_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level2uriRight_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level2uriTop_}, (test_path() / "images" / "blue_1024.png").string()); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level2uriBack_})); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level2uriBottom_})); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level2uriFront_})); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level2uriLeft_})); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level2uriRight_})); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level2uriTop_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level2uriBack_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level2uriBottom_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level2uriFront_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level2uriLeft_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level2uriRight_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level2uriTop_})); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level3uriBack_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level3uriBottom_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level3uriFront_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level3uriLeft_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level3uriRight_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level3uriTop_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level3uriBack_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level3uriBottom_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level3uriFront_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level3uriLeft_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level3uriRight_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level3uriTop_}, (test_path() / "images" / "blue_1024.png").string()); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level3uriBack_})); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level3uriBottom_})); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level3uriFront_})); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level3uriLeft_})); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level3uriRight_})); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level3uriTop_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level3uriBack_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level3uriBottom_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level3uriFront_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level3uriLeft_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level3uriRight_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level3uriTop_})); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level4uriBack_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level4uriBottom_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level4uriFront_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level4uriLeft_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level4uriRight_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level4uriTop_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level4uriBack_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level4uriBottom_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level4uriFront_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level4uriLeft_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level4uriRight_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level4uriTop_}, (test_path() / "images" / "blue_1024.png").string()); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level4uriBack_})); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level4uriBottom_})); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level4uriFront_})); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level4uriLeft_})); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level4uriRight_})); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level4uriTop_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level4uriBack_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level4uriBottom_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level4uriFront_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level4uriLeft_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level4uriRight_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level4uriTop_})); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::mipmapLevel_}, 3); + commandInterface.set({cubeMap, &user_types::CubeMap::mipmapLevel_}, 3); dispatch(); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level4uriBack_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level4uriBottom_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level4uriFront_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level4uriLeft_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level4uriRight_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level4uriTop_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level4uriBack_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level4uriBottom_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level4uriFront_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level4uriLeft_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level4uriRight_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level4uriTop_})); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::mipmapLevel_}, 2); + commandInterface.set({cubeMap, &user_types::CubeMap::mipmapLevel_}, 2); dispatch(); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level3uriBack_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level3uriBottom_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level3uriFront_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level3uriLeft_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level3uriRight_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level3uriTop_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level3uriBack_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level3uriBottom_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level3uriFront_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level3uriLeft_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level3uriRight_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level3uriTop_})); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::mipmapLevel_}, 1); + commandInterface.set({cubeMap, &user_types::CubeMap::mipmapLevel_}, 1); dispatch(); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level2uriBack_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level2uriBottom_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level2uriFront_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level2uriLeft_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level2uriRight_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::level2uriTop_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level2uriBack_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level2uriBottom_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level2uriFront_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level2uriLeft_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level2uriRight_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::level2uriTop_})); } TEST_F(CubeMapAdaptorFixture, ramsesAutoMipMapGenerationWarningPersistsAfterChangingURI) { - auto cubeMap = create("Cubemap"); + auto cubeMap = create("Cubemap"); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::generateMipmaps_}, true); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::mipmapLevel_}, 2); + commandInterface.set({cubeMap, &user_types::CubeMap::generateMipmaps_}, true); + commandInterface.set({cubeMap, &user_types::CubeMap::mipmapLevel_}, 2); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::mipmapLevel_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::mipmapLevel_})); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "blue_1024.png").string()); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::mipmapLevel_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::mipmapLevel_})); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level2uriBack_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level2uriBottom_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level2uriFront_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level2uriLeft_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level2uriRight_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::level2uriTop_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level2uriBack_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level2uriBottom_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level2uriFront_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level2uriLeft_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level2uriRight_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubeMap, &user_types::CubeMap::level2uriTop_}, (test_path() / "images" / "green_512.png").string()); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::mipmapLevel_})); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::mipmapLevel_})); } TEST_F(CubeMapAdaptorFixture, textureFormat8BitPalette) { - auto cubemap = create("cubemap"); - - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "text-back-palette.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "text-back-palette.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "text-back-palette.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "text-back-palette.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "text-back-palette.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "text-back-palette.png").string()); - dispatch(); - - checkTextureFormats(cubemap, {{ramses::ETextureFormat::R8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RG8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RGB8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RGBA8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RGB16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::SRGB8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::SRGB8_ALPHA8, raco::core::ErrorLevel::INFORMATION}}); + auto cubemap = create("cubemap"); + + commandInterface.set({cubemap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "text-back-palette.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "text-back-palette.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "text-back-palette.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "text-back-palette.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "text-back-palette.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "text-back-palette.png").string()); + dispatch(); + + checkTextureFormats(cubemap, {{ETextureFormat::R8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RG8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RGB8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RGBA8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RGB16F, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA16F, core::ErrorLevel::ERROR}, + {ETextureFormat::SRGB8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::SRGB8_ALPHA8, core::ErrorLevel::INFORMATION}}); } TEST_F(CubeMapAdaptorFixture, textureFormatR8) { - auto cubemap = create("cubemap"); - - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512_gray.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512_gray.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_gray.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512_gray.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512_gray.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512_gray.png").string()); - dispatch(); - - checkTextureFormats(cubemap, {{ramses::ETextureFormat::R8, raco::core::ErrorLevel::NONE}, - {ramses::ETextureFormat::RG8, raco::core::ErrorLevel::WARNING}, - {ramses::ETextureFormat::RGB8, raco::core::ErrorLevel::WARNING}, - {ramses::ETextureFormat::RGBA8, raco::core::ErrorLevel::WARNING}, - {ramses::ETextureFormat::RGB16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::SRGB8, raco::core::ErrorLevel::WARNING}, - {ramses::ETextureFormat::SRGB8_ALPHA8, raco::core::ErrorLevel::WARNING}}); + auto cubemap = create("cubemap"); + + commandInterface.set({cubemap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512_gray.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512_gray.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_gray.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512_gray.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512_gray.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512_gray.png").string()); + dispatch(); + + checkTextureFormats(cubemap, {{ETextureFormat::R8, core::ErrorLevel::NONE}, + {ETextureFormat::RG8, core::ErrorLevel::WARNING}, + {ETextureFormat::RGB8, core::ErrorLevel::WARNING}, + {ETextureFormat::RGBA8, core::ErrorLevel::WARNING}, + {ETextureFormat::RGB16F, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA16F, core::ErrorLevel::ERROR}, + {ETextureFormat::SRGB8, core::ErrorLevel::WARNING}, + {ETextureFormat::SRGB8_ALPHA8, core::ErrorLevel::WARNING}}); } TEST_F(CubeMapAdaptorFixture, textureFormatRG16) { - auto cubemap = create("cubemap"); - - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512_gray_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512_gray_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_gray_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512_gray_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512_gray_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512_gray_16f.png").string()); - dispatch(); - - checkTextureFormats(cubemap, {{ramses::ETextureFormat::R8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RG8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGB8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGB16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::SRGB8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::SRGB8_ALPHA8, raco::core::ErrorLevel::ERROR}}); + auto cubemap = create("cubemap"); + + commandInterface.set({cubemap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512_gray_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512_gray_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_gray_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512_gray_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512_gray_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512_gray_16f.png").string()); + dispatch(); + + checkTextureFormats(cubemap, {{ETextureFormat::R8, core::ErrorLevel::ERROR}, + {ETextureFormat::RG8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGB8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGB16F, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA16F, core::ErrorLevel::ERROR}, + {ETextureFormat::SRGB8, core::ErrorLevel::ERROR}, + {ETextureFormat::SRGB8_ALPHA8, core::ErrorLevel::ERROR}}); } TEST_F(CubeMapAdaptorFixture, textureFormatRG8) { - auto cubemap = create("cubemap"); - - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512_gray_alpha.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512_gray_alpha.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_gray_alpha.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512_gray_alpha.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512_gray_alpha.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512_gray_alpha.png").string()); - dispatch(); - - checkTextureFormats(cubemap, {{ramses::ETextureFormat::R8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RG8, raco::core::ErrorLevel::NONE}, - {ramses::ETextureFormat::RGB8, raco::core::ErrorLevel::WARNING}, - {ramses::ETextureFormat::RGBA8, raco::core::ErrorLevel::WARNING}, - {ramses::ETextureFormat::RGB16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::SRGB8, raco::core::ErrorLevel::WARNING}, - {ramses::ETextureFormat::SRGB8_ALPHA8, raco::core::ErrorLevel::WARNING}}); + auto cubemap = create("cubemap"); + + commandInterface.set({cubemap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512_gray_alpha.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512_gray_alpha.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_gray_alpha.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512_gray_alpha.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512_gray_alpha.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512_gray_alpha.png").string()); + dispatch(); + + checkTextureFormats(cubemap, {{ETextureFormat::R8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RG8, core::ErrorLevel::NONE}, + {ETextureFormat::RGB8, core::ErrorLevel::WARNING}, + {ETextureFormat::RGBA8, core::ErrorLevel::WARNING}, + {ETextureFormat::RGB16F, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA16F, core::ErrorLevel::ERROR}, + {ETextureFormat::SRGB8, core::ErrorLevel::WARNING}, + {ETextureFormat::SRGB8_ALPHA8, core::ErrorLevel::WARNING}}); } TEST_F(CubeMapAdaptorFixture, textureFormatRGB8) { - auto cubemap = create("cubemap"); - - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "text-back.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "text-back.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "text-back.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "text-back.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "text-back.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "text-back.png").string()); - dispatch(); - - checkTextureFormats(cubemap, {{ramses::ETextureFormat::R8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RG8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RGB8, raco::core::ErrorLevel::NONE}, - {ramses::ETextureFormat::RGBA8, raco::core::ErrorLevel::WARNING}, - {ramses::ETextureFormat::RGB16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::SRGB8, raco::core::ErrorLevel::NONE}, - {ramses::ETextureFormat::SRGB8_ALPHA8, raco::core::ErrorLevel::WARNING}}); + auto cubemap = create("cubemap"); + + commandInterface.set({cubemap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "text-back.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "text-back.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "text-back.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "text-back.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "text-back.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "text-back.png").string()); + dispatch(); + + checkTextureFormats(cubemap, {{ETextureFormat::R8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RG8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RGB8, core::ErrorLevel::NONE}, + {ETextureFormat::RGBA8, core::ErrorLevel::WARNING}, + {ETextureFormat::RGB16F, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA16F, core::ErrorLevel::ERROR}, + {ETextureFormat::SRGB8, core::ErrorLevel::NONE}, + {ETextureFormat::SRGB8_ALPHA8, core::ErrorLevel::WARNING}}); } TEST_F(CubeMapAdaptorFixture, textureFormatRGBA8) { - auto cubemap = create("cubemap"); - - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512.png").string()); - dispatch(); - - checkTextureFormats(cubemap, {{ramses::ETextureFormat::R8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RG8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RGB8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RGBA8, raco::core::ErrorLevel::NONE}, - {ramses::ETextureFormat::RGB16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::SRGB8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::SRGB8_ALPHA8, raco::core::ErrorLevel::NONE}}); + auto cubemap = create("cubemap"); + + commandInterface.set({cubemap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512.png").string()); + dispatch(); + + checkTextureFormats(cubemap, {{ETextureFormat::R8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RG8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RGB8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RGBA8, core::ErrorLevel::NONE}, + {ETextureFormat::RGB16F, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA16F, core::ErrorLevel::ERROR}, + {ETextureFormat::SRGB8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::SRGB8_ALPHA8, core::ErrorLevel::NONE}}); } TEST_F(CubeMapAdaptorFixture, textureFormatRGB16) { - auto cubemap = create("cubemap"); - - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512_16f_no_alpha.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512_16f_no_alpha.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_16f_no_alpha.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512_16f_no_alpha.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512_16f_no_alpha.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512_16f_no_alpha.png").string()); - dispatch(); - - checkTextureFormats(cubemap, {{ramses::ETextureFormat::R8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RG8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGB8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGB16F, raco::core::ErrorLevel::NONE}, - {ramses::ETextureFormat::RGBA16F, raco::core::ErrorLevel::WARNING}, - {ramses::ETextureFormat::SRGB8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::SRGB8_ALPHA8, raco::core::ErrorLevel::ERROR}}); + auto cubemap = create("cubemap"); + + commandInterface.set({cubemap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512_16f_no_alpha.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512_16f_no_alpha.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_16f_no_alpha.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512_16f_no_alpha.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512_16f_no_alpha.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512_16f_no_alpha.png").string()); + dispatch(); + + checkTextureFormats(cubemap, {{ETextureFormat::R8, core::ErrorLevel::ERROR}, + {ETextureFormat::RG8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGB8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGB16F, core::ErrorLevel::NONE}, + {ETextureFormat::RGBA16F, core::ErrorLevel::WARNING}, + {ETextureFormat::SRGB8, core::ErrorLevel::ERROR}, + {ETextureFormat::SRGB8_ALPHA8, core::ErrorLevel::ERROR}}); } TEST_F(CubeMapAdaptorFixture, textureFormatRGBA16From16i) { - auto cubemap = create("cubemap"); - - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512_16i.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512_16i.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_16i.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512_16i.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512_16i.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512_16i.png").string()); - dispatch(); - - checkTextureFormats(cubemap, {{ramses::ETextureFormat::R8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RG8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGB8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGB16F, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RGBA16F, raco::core::ErrorLevel::NONE}, - {ramses::ETextureFormat::SRGB8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::SRGB8_ALPHA8, raco::core::ErrorLevel::ERROR}}); + auto cubemap = create("cubemap"); + + commandInterface.set({cubemap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512_16i.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512_16i.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_16i.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512_16i.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512_16i.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512_16i.png").string()); + dispatch(); + + checkTextureFormats(cubemap, {{ETextureFormat::R8, core::ErrorLevel::ERROR}, + {ETextureFormat::RG8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGB8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGB16F, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RGBA16F, core::ErrorLevel::NONE}, + {ETextureFormat::SRGB8, core::ErrorLevel::ERROR}, + {ETextureFormat::SRGB8_ALPHA8, core::ErrorLevel::ERROR}}); } TEST_F(CubeMapAdaptorFixture, textureFormatRGBA16From16f) { - auto cubemap = create("cubemap"); - - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512_16f.png").string()); - dispatch(); - - checkTextureFormats(cubemap, {{ramses::ETextureFormat::R8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RG8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGB8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGB16F, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RGBA16F, raco::core::ErrorLevel::NONE}, - {ramses::ETextureFormat::SRGB8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::SRGB8_ALPHA8, raco::core::ErrorLevel::ERROR}}); + auto cubemap = create("cubemap"); + + commandInterface.set({cubemap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512_16f.png").string()); + dispatch(); + + checkTextureFormats(cubemap, {{ETextureFormat::R8, core::ErrorLevel::ERROR}, + {ETextureFormat::RG8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGB8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGB16F, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RGBA16F, core::ErrorLevel::NONE}, + {ETextureFormat::SRGB8, core::ErrorLevel::ERROR}, + {ETextureFormat::SRGB8_ALPHA8, core::ErrorLevel::ERROR}}); } TEST_F(CubeMapAdaptorFixture, textureFormatChangeValidToInvalid) { - auto cubemap = create("cubemap"); + auto cubemap = create("cubemap"); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512_16f.png").string()); dispatch(); // RGBA16 - commandInterface.set({cubemap, &raco::user_types::CubeMap::textureFormat_}, static_cast(ramses::ETextureFormat::RGBA16F)); + commandInterface.set({cubemap, &user_types::CubeMap::textureFormat_}, static_cast(ETextureFormat::RGBA16F)); dispatch(); - assertLevel1Errors(cubemap, raco::core::ErrorLevel::NONE); + assertLevel1Errors(cubemap, core::ErrorLevel::NONE); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512.png").string()); dispatch(); - assertLevel1Errors(cubemap, raco::core::ErrorLevel::ERROR); + assertLevel1Errors(cubemap, core::ErrorLevel::ERROR); // R8 - commandInterface.set({cubemap, &raco::user_types::CubeMap::textureFormat_}, static_cast(ramses::ETextureFormat::R8)); + commandInterface.set({cubemap, &user_types::CubeMap::textureFormat_}, static_cast(ETextureFormat::R8)); dispatch(); - assertLevel1Errors(cubemap, raco::core::ErrorLevel::INFORMATION); + assertLevel1Errors(cubemap, core::ErrorLevel::INFORMATION); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512_16f.png").string()); dispatch(); - assertLevel1Errors(cubemap, raco::core::ErrorLevel::ERROR); + assertLevel1Errors(cubemap, core::ErrorLevel::ERROR); // RGBA16 - commandInterface.set({cubemap, &raco::user_types::CubeMap::textureFormat_}, static_cast(ramses::ETextureFormat::RGBA16F)); + commandInterface.set({cubemap, &user_types::CubeMap::textureFormat_}, static_cast(ETextureFormat::RGBA16F)); dispatch(); - assertLevel1Errors(cubemap, raco::core::ErrorLevel::NONE); + assertLevel1Errors(cubemap, core::ErrorLevel::NONE); } TEST_F(CubeMapAdaptorFixture, textureBitdepthDifferentInSameLevel) { - auto cubemap = create("cubemap"); + auto cubemap = create("cubemap"); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512_16f.png").string()); dispatch(); // RGBA16 - commandInterface.set({cubemap, &raco::user_types::CubeMap::textureFormat_}, static_cast(ramses::ETextureFormat::RGBA16F)); + commandInterface.set({cubemap, &user_types::CubeMap::textureFormat_}, static_cast(ETextureFormat::RGBA16F)); dispatch(); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::textureFormat_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::textureFormat_})); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512.png").string()); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::uriFront_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::uriFront_}).level(), raco::core::ErrorLevel::ERROR); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::uriFront_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::uriFront_}).level(), core::ErrorLevel::ERROR); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_16f.png").string()); dispatch(); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::uriFront_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::uriFront_})); } TEST_F(CubeMapAdaptorFixture, textureBitdepthDifferentInOtherLevel) { - auto cubemap = create("cubemap"); + auto cubemap = create("cubemap"); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "blue_1024_16i.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "blue_1024_16i.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "blue_1024_16i.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "blue_1024_16i.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "blue_1024_16i.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "blue_1024_16i.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "blue_1024_16i.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "blue_1024_16i.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "blue_1024_16i.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "blue_1024_16i.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "blue_1024_16i.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "blue_1024_16i.png").string()); dispatch(); // RGBA16 - commandInterface.set({cubemap, &raco::user_types::CubeMap::textureFormat_}, static_cast(ramses::ETextureFormat::RGBA16F)); + commandInterface.set({cubemap, &user_types::CubeMap::textureFormat_}, static_cast(ETextureFormat::RGBA16F)); dispatch(); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::textureFormat_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::textureFormat_})); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriBack_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriBottom_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriFront_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriLeft_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriRight_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriTop_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::mipmapLevel_}, 2); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriBack_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriBottom_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriFront_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriLeft_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriRight_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriTop_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::mipmapLevel_}, 2); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriBack_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::level2uriBack_}).level(), raco::core::ErrorLevel::ERROR); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriBack_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::level2uriBack_}).level(), core::ErrorLevel::ERROR); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriBottom_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::level2uriBottom_}).level(), raco::core::ErrorLevel::ERROR); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriBottom_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::level2uriBottom_}).level(), core::ErrorLevel::ERROR); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriFront_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::level2uriFront_}).level(), raco::core::ErrorLevel::ERROR); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriFront_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::level2uriFront_}).level(), core::ErrorLevel::ERROR); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriLeft_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::level2uriLeft_}).level(), raco::core::ErrorLevel::ERROR); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriLeft_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::level2uriLeft_}).level(), core::ErrorLevel::ERROR); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriRight_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::level2uriRight_}).level(), raco::core::ErrorLevel::ERROR); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriRight_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::level2uriRight_}).level(), core::ErrorLevel::ERROR); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriTop_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::level2uriTop_}).level(), raco::core::ErrorLevel::ERROR); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriTop_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::level2uriTop_}).level(), core::ErrorLevel::ERROR); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriBack_}, (test_path() / "images" / "green_512_16i.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriBottom_}, (test_path() / "images" / "green_512_16i.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriFront_}, (test_path() / "images" / "green_512_16i.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriLeft_}, (test_path() / "images" / "green_512_16i.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriRight_}, (test_path() / "images" / "green_512_16i.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriTop_}, (test_path() / "images" / "green_512_16i.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriBack_}, (test_path() / "images" / "green_512_16i.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriBottom_}, (test_path() / "images" / "green_512_16i.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriFront_}, (test_path() / "images" / "green_512_16i.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriLeft_}, (test_path() / "images" / "green_512_16i.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriRight_}, (test_path() / "images" / "green_512_16i.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriTop_}, (test_path() / "images" / "green_512_16i.png").string()); dispatch(); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriBack_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriBottom_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriFront_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriLeft_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriRight_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriTop_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriBack_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriBottom_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriFront_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriLeft_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriRight_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriTop_})); } TEST_F(CubeMapAdaptorFixture, textureFormatDifferentInSameLevel) { - auto cubemap = create("cubemap"); + auto cubemap = create("cubemap"); - commandInterface.set({cubemap, &raco::user_types::CubeMap::textureFormat_}, static_cast(ramses::ETextureFormat::RGBA8)); + commandInterface.set({cubemap, &user_types::CubeMap::textureFormat_}, static_cast(ETextureFormat::RGBA8)); dispatch(); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "green_512.png").string()); dispatch(); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_gray.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512_gray.png").string()); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::uriFront_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::uriFront_}).level(), raco::core::ErrorLevel::WARNING); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::uriFront_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::uriFront_}).level(), core::ErrorLevel::WARNING); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "green_512.png").string()); dispatch(); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::uriFront_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::uriFront_})); } TEST_F(CubeMapAdaptorFixture, textureFormatDifferentInOtherLevel) { - auto cubemap = create("cubemap"); + auto cubemap = create("cubemap"); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBack_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriBottom_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriFront_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriLeft_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriRight_}, (test_path() / "images" / "blue_1024.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::uriTop_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBack_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriBottom_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriFront_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriLeft_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriRight_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::uriTop_}, (test_path() / "images" / "blue_1024.png").string()); dispatch(); // RGBA8 - commandInterface.set({cubemap, &raco::user_types::CubeMap::textureFormat_}, static_cast(ramses::ETextureFormat::RGBA8)); + commandInterface.set({cubemap, &user_types::CubeMap::textureFormat_}, static_cast(ETextureFormat::RGBA8)); dispatch(); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriBack_}, (test_path() / "images" / "green_512_gray.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriBottom_}, (test_path() / "images" / "green_512_gray.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriFront_}, (test_path() / "images" / "green_512_gray.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriLeft_}, (test_path() / "images" / "green_512_gray.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriRight_}, (test_path() / "images" / "green_512_gray.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriTop_}, (test_path() / "images" / "green_512_gray.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::mipmapLevel_}, 2); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriBack_}, (test_path() / "images" / "green_512_gray.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriBottom_}, (test_path() / "images" / "green_512_gray.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriFront_}, (test_path() / "images" / "green_512_gray.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriLeft_}, (test_path() / "images" / "green_512_gray.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriRight_}, (test_path() / "images" / "green_512_gray.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriTop_}, (test_path() / "images" / "green_512_gray.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::mipmapLevel_}, 2); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriBack_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::level2uriBack_}).level(), raco::core::ErrorLevel::WARNING); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriBack_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::level2uriBack_}).level(), core::ErrorLevel::WARNING); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriBottom_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::level2uriBottom_}).level(), raco::core::ErrorLevel::WARNING); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriBottom_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::level2uriBottom_}).level(), core::ErrorLevel::WARNING); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriFront_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::level2uriFront_}).level(), raco::core::ErrorLevel::WARNING); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriFront_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::level2uriFront_}).level(), core::ErrorLevel::WARNING); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriLeft_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::level2uriLeft_}).level(), raco::core::ErrorLevel::WARNING); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriLeft_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::level2uriLeft_}).level(), core::ErrorLevel::WARNING); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriRight_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::level2uriRight_}).level(), raco::core::ErrorLevel::WARNING); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriRight_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::level2uriRight_}).level(), core::ErrorLevel::WARNING); - ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriTop_})); - ASSERT_EQ(commandInterface.errors().getError({cubemap, &raco::user_types::CubeMap::level2uriTop_}).level(), raco::core::ErrorLevel::WARNING); + ASSERT_TRUE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriTop_})); + ASSERT_EQ(commandInterface.errors().getError({cubemap, &user_types::CubeMap::level2uriTop_}).level(), core::ErrorLevel::WARNING); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriBack_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriBottom_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriFront_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriLeft_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriRight_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({cubemap, &raco::user_types::CubeMap::level2uriTop_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriBack_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriBottom_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriFront_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriLeft_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriRight_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({cubemap, &user_types::CubeMap::level2uriTop_}, (test_path() / "images" / "green_512.png").string()); dispatch(); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriBack_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriBottom_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriFront_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriLeft_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriRight_})); - ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &raco::user_types::CubeMap::level2uriTop_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriBack_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriBottom_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriFront_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriLeft_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriRight_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubemap, &user_types::CubeMap::level2uriTop_})); } \ No newline at end of file diff --git a/components/libRamsesBase/tests/EngineInterface_test.cpp b/components/libRamsesBase/tests/EngineInterface_test.cpp index 335dadf8..59458fba 100644 --- a/components/libRamsesBase/tests/EngineInterface_test.cpp +++ b/components/libRamsesBase/tests/EngineInterface_test.cpp @@ -12,7 +12,7 @@ #include using namespace raco::ramses_base; -using raco::core::EnginePrimitive; +using core::EnginePrimitive; class EngineInterfaceTest : public RamsesBaseFixture<> {}; @@ -29,9 +29,9 @@ function run(IN,OUT) end )"; std::string error; - raco::core::PropertyInterfaceList in; - raco::core::PropertyInterfaceList out; - raco::data_storage::Table modules; + core::PropertyInterfaceList in; + core::PropertyInterfaceList out; + data_storage::Table modules; backend.coreInterface()->parseLuaScript(script, "myScript", {}, modules, in, out, error); EXPECT_EQ(1, in.size()); @@ -61,9 +61,9 @@ function run(IN,OUT) end )"; std::string error; - raco::core::PropertyInterfaceList in; - raco::core::PropertyInterfaceList out; - raco::data_storage::Table modules; + core::PropertyInterfaceList in; + core::PropertyInterfaceList out; + data_storage::Table modules; backend.coreInterface()->parseLuaScript(script, "myScript", {}, modules, in, out, error); EXPECT_EQ(1, in.size()); diff --git a/components/libRamsesBase/tests/LinkAdaptor_test.cpp b/components/libRamsesBase/tests/LinkAdaptor_test.cpp index 92caca4f..4c17e559 100644 --- a/components/libRamsesBase/tests/LinkAdaptor_test.cpp +++ b/components/libRamsesBase/tests/LinkAdaptor_test.cpp @@ -27,21 +27,25 @@ using namespace raco::user_types; class LinkAdaptorFixture : public RamsesBaseFixture<> { public: - void checkRamsesTranslation(const ramses::Node& node, const std::array& value) { - EXPECT_EQ(Translation::from(node), value); + void checkRamsesTranslation(const ramses::Node& node, const glm::vec3& value) { + EXPECT_EQ(getRamsesTranslation(&node), value); } - void checkRamsesNodeTranslation(const std::string& name, const std::array& value) { + void checkRamsesNodeTranslation(const std::string& name, const glm::vec3& value) { auto ramsesNode = select(*sceneContext.scene(), name.c_str()); EXPECT_TRUE(ramsesNode != nullptr); checkRamsesTranslation(*ramsesNode, value); } + + ramses::LogicEngine& logicEngine() { + return sceneContext.logicEngine(); + } }; TEST_F(LinkAdaptorFixture, linkCreationOneLink) { - const auto luaScript{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; - const auto node{context.createObject(raco::user_types::Node::typeDescription.typeName, "node", "node_id")}; - raco::utils::file::write((test_path() / "lua_script.lua").string(), R"( + const auto luaScript{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; + const auto node{context.createObject(user_types::Node::typeDescription.typeName, "node", "node_id")}; + utils::file::write((test_path() / "lua_script.lua").string(), R"( function interface(IN,OUT) IN.x = Type:Float() OUT.translation = Type:Vec3f() @@ -53,24 +57,24 @@ end context.set({luaScript, {"uri"}}, (test_path() / "lua_script.lua").string()); auto link = context.addLink({luaScript, {"outputs", "translation"}}, {node, {"translation"}}); - ASSERT_NO_FATAL_FAILURE(dispatch()); + ASSERT_TRUE(dispatch()); checkRamsesNodeTranslation("node", {0.0, 0.0, 0.0}); - EXPECT_EQ(backend.logicEngine().getPropertyLinks().size(), 1); + EXPECT_EQ(logicEngine().getPropertyLinks().size(), 1); context.set({luaScript, {"inputs", "x"}}, 5.0); - ASSERT_NO_FATAL_FAILURE(dispatch()); + ASSERT_TRUE(dispatch()); checkRamsesNodeTranslation("node", {5.0, 0.0, 0.0}); - EXPECT_EQ(backend.logicEngine().getPropertyLinks().size(), 1); + EXPECT_EQ(logicEngine().getPropertyLinks().size(), 1); } #if (!defined (__linux__)) // awaitPreviewDirty does not work in Linux as expected. See RAOS-692 TEST_F(LinkAdaptorFixture, linkWorksIfScriptContentChanges) { - const auto luaScript{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; - const auto node{context.createObject(raco::user_types::Node::typeDescription.typeName, "node", "node_id")}; - raco::utils::file::write((test_path() / "lua_script.lua").string(), R"( + const auto luaScript{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; + const auto node{context.createObject(user_types::Node::typeDescription.typeName, "node", "node_id")}; + utils::file::write((test_path() / "lua_script.lua").string(), R"( function interface(IN,OUT) IN.x = Type:Float() OUT.translation = Type:Vec3f() @@ -82,17 +86,17 @@ end context.set({luaScript, {"uri"}}, (test_path() / "lua_script.lua").string()); auto link = context.addLink({luaScript, {"outputs", "translation"}}, {node, {"translation"}}); - ASSERT_NO_FATAL_FAILURE(dispatch()); + ASSERT_TRUE(dispatch()); checkRamsesNodeTranslation("node", {0.0, 0.0, 0.0}); - EXPECT_EQ(backend.logicEngine().getPropertyLinks().size(), 1); + EXPECT_EQ(logicEngine().getPropertyLinks().size(), 1); context.set({luaScript, {"inputs", "x"}}, 5.0); - ASSERT_NO_FATAL_FAILURE(dispatch()); + ASSERT_TRUE(dispatch()); checkRamsesNodeTranslation("node", {5.0, 0.0, 0.0}); - EXPECT_EQ(backend.logicEngine().getPropertyLinks().size(), 1); + EXPECT_EQ(logicEngine().getPropertyLinks().size(), 1); - raco::utils::file::write((test_path() / "lua_script.lua").string(), R"( + utils::file::write((test_path() / "lua_script.lua").string(), R"( function interface(IN,OUT) IN.x = Type:Float() OUT.translation = Type:Vec3f() @@ -104,16 +108,16 @@ end EXPECT_TRUE(raco::awaitPreviewDirty(recorder, luaScript)); - ASSERT_NO_FATAL_FAILURE(dispatch()); + ASSERT_TRUE(dispatch()); checkRamsesNodeTranslation("node", {5.0, 5.0, 0.0}); - EXPECT_EQ(backend.logicEngine().getPropertyLinks().size(), 1); + EXPECT_EQ(logicEngine().getPropertyLinks().size(), 1); } #endif TEST_F(LinkAdaptorFixture, linkUnlinkLink) { - const auto luaScript{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; - const auto node{context.createObject(raco::user_types::Node::typeDescription.typeName, "node", "node_id")}; - raco::utils::file::write((test_path() / "lua_script.lua").string(), R"( + const auto luaScript{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; + const auto node{context.createObject(user_types::Node::typeDescription.typeName, "node", "node_id")}; + utils::file::write((test_path() / "lua_script.lua").string(), R"( function interface(IN,OUT) IN.x = Type:Float() OUT.translation = Type:Vec3f() @@ -123,37 +127,37 @@ function run(IN,OUT) end )"); context.set({luaScript, {"uri"}}, (test_path() / "lua_script.lua").string()); - ASSERT_NO_FATAL_FAILURE(dispatch()); + ASSERT_TRUE(dispatch()); context.set({luaScript, {"inputs", "x"}}, 5.0); - ASSERT_NO_FATAL_FAILURE(dispatch()); + ASSERT_TRUE(dispatch()); checkRamsesNodeTranslation("node", {0.0, 0.0, 0.0}); - EXPECT_EQ(backend.logicEngine().getPropertyLinks().size(), 0); + EXPECT_EQ(logicEngine().getPropertyLinks().size(), 0); auto link = context.addLink({luaScript, {"outputs", "translation"}}, {node, {"translation"}}); - ASSERT_NO_FATAL_FAILURE(dispatch()); + ASSERT_TRUE(dispatch()); checkRamsesNodeTranslation("node", {5.0, 0.0, 0.0}); - EXPECT_EQ(backend.logicEngine().getPropertyLinks().size(), 1); + EXPECT_EQ(logicEngine().getPropertyLinks().size(), 1); context.removeLink(link->endProp()); context.set({luaScript, {"inputs", "x"}}, 10.0); - ASSERT_NO_FATAL_FAILURE(dispatch()); + ASSERT_TRUE(dispatch()); checkRamsesNodeTranslation("node", {5.0, 0.0, 0.0}); - EXPECT_EQ(backend.logicEngine().getPropertyLinks().size(), 0); + EXPECT_EQ(logicEngine().getPropertyLinks().size(), 0); link = context.addLink({luaScript, {"outputs", "translation"}}, {node, {"translation"}}); - ASSERT_NO_FATAL_FAILURE(dispatch()); + ASSERT_TRUE(dispatch()); checkRamsesNodeTranslation("node", {10.0, 0.0, 0.0}); - EXPECT_EQ(backend.logicEngine().getPropertyLinks().size(), 1); + EXPECT_EQ(logicEngine().getPropertyLinks().size(), 1); } TEST_F(LinkAdaptorFixture, linkStruct) { - const auto luaScriptOut{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script_out", "lua_script_out_id")}; - const auto luaScriptIn{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script_in", "lua_script_in_id")}; - raco::utils::file::write((test_path() / "lua_script_out.lua").string(), R"( + const auto luaScriptOut{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script_out", "lua_script_out_id")}; + const auto luaScriptIn{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script_in", "lua_script_in_id")}; + utils::file::write((test_path() / "lua_script_out.lua").string(), R"( function interface(IN,OUT) IN.x = Type:Float() OUT.a = { @@ -167,7 +171,7 @@ function run(IN,OUT) end )"); context.set({luaScriptOut, {"uri"}}, (test_path() / "lua_script_out.lua").string()); - raco::utils::file::write((test_path() / "lua_script_in.lua").string(), R"( + utils::file::write((test_path() / "lua_script_in.lua").string(), R"( function interface(IN,OUT) OUT.a = Type:Float() OUT.b = Type:Float() @@ -182,19 +186,17 @@ function run(IN,OUT) end )"); context.set({luaScriptIn, {"uri"}}, (test_path() / "lua_script_in.lua").string()); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); auto link = context.addLink({luaScriptOut, {"outputs", "a"}}, {luaScriptIn, {"inputs","a"}}); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); } TEST_F(LinkAdaptorFixture, linkQuaternion) { - const auto luaScriptOut{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script_out", "lua_script_out_id")}; - const auto node{context.createObject(raco::user_types::Node::typeDescription.typeName, "node", "node_id")}; + const auto luaScriptOut{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script_out", "lua_script_out_id")}; + const auto node{context.createObject(user_types::Node::typeDescription.typeName, "node", "node_id")}; - raco::utils::file::write((test_path() / "lua_script_out.lua").string(), R"( + utils::file::write((test_path() / "lua_script_out.lua").string(), R"( function interface(IN,OUT) IN.x = Type:Vec4f() OUT.x = Type:Vec4f() @@ -204,33 +206,30 @@ function run(IN,OUT) end )"); context.set({luaScriptOut, {"uri"}}, (test_path() / "lua_script_out.lua").string()); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); context.addLink({luaScriptOut, {"outputs", "x"}}, {node, {"rotation"}}); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); context.set({luaScriptOut, {"inputs", "x", "x"}}, 0.3); context.set({luaScriptOut, {"inputs", "x", "y"}}, -0.3); context.set({luaScriptOut, {"inputs", "x", "z"}}, 1.0); context.set({luaScriptOut, {"inputs", "x", "w"}}, -1.0); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); - auto nodeBinding = backend.logicEngine().findByName("node_NodeBinding"); - ASSERT_EQ(nodeBinding->getRotationType(), rlogic::ERotationType::Quaternion); + auto nodeBinding = logicEngine().findObject("node_NodeBinding"); + ASSERT_EQ(nodeBinding->getRotationType(), ramses::ERotationType::Quaternion); auto rotationProperty = nodeBinding->getInputs()->getChild("rotation"); - ASSERT_EQ(rotationProperty->getType(), rlogic::EPropertyType::Vec4f); - auto rotationArray = rotationProperty->get(); - ASSERT_EQ(rotationArray, rlogic::vec4f({0.3, -0.3, 1.0, -1.0})); + ASSERT_EQ(rotationProperty->getType(), ramses::EPropertyType::Vec4f); + auto rotationArray = rotationProperty->get(); + ASSERT_EQ(rotationArray, ramses::vec4f({0.3, -0.3, 1.0, -1.0})); } TEST_F(LinkAdaptorFixture, linkEulerAfterQuaternion) { - const auto luaScriptOut{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script_out", "lua_script_out_id")}; - const auto node{context.createObject(raco::user_types::Node::typeDescription.typeName, "node", "node_id")}; + const auto luaScriptOut{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script_out", "lua_script_out_id")}; + const auto node{context.createObject(user_types::Node::typeDescription.typeName, "node", "node_id")}; - raco::utils::file::write((test_path() / "lua_script_out.lua").string(), R"( + utils::file::write((test_path() / "lua_script_out.lua").string(), R"( function interface(IN,OUT) IN.vec4 = Type:Vec4f() IN.vec3 = Type:Vec3f() @@ -243,12 +242,10 @@ function run(IN,OUT) end )"); context.set({luaScriptOut, {"uri"}}, (test_path() / "lua_script_out.lua").string()); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); context.addLink({luaScriptOut, {"outputs", "vec4"}}, {node, {"rotation"}}); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); context.set({luaScriptOut, {"inputs", "vec4", "x"}}, 0.3); context.set({luaScriptOut, {"inputs", "vec4", "y"}}, -0.3); @@ -257,26 +254,24 @@ end context.set({luaScriptOut, {"inputs", "vec3", "x"}}, 90.0); context.set({luaScriptOut, {"inputs", "vec3", "y"}}, 180.0); context.set({luaScriptOut, {"inputs", "vec3", "z"}}, 270.0); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); context.addLink({luaScriptOut, {"outputs", "vec3"}}, {node, {"rotation"}}); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); - auto nodeBinding = backend.logicEngine().findByName("node_NodeBinding"); - ASSERT_NE(nodeBinding->getRotationType(), rlogic::ERotationType::Quaternion); + auto nodeBinding = logicEngine().findObject("node_NodeBinding"); + ASSERT_NE(nodeBinding->getRotationType(), ramses::ERotationType::Quaternion); auto rotationProperty = nodeBinding->getInputs()->getChild("rotation"); - ASSERT_EQ(rotationProperty->getType(), rlogic::EPropertyType::Vec3f); - auto rotationArray = rotationProperty->get(); - ASSERT_EQ(rotationArray, rlogic::vec3f({90, 180, 270})); + ASSERT_EQ(rotationProperty->getType(), ramses::EPropertyType::Vec3f); + auto rotationArray = rotationProperty->get(); + ASSERT_EQ(rotationArray, ramses::vec3f({90, 180, 270})); } TEST_F(LinkAdaptorFixture, linkQuaternionAfterEuler) { - const auto luaScriptOut{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script_out", "lua_script_out_id")}; - const auto node{context.createObject(raco::user_types::Node::typeDescription.typeName, "node", "node_id")}; + const auto luaScriptOut{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script_out", "lua_script_out_id")}; + const auto node{context.createObject(user_types::Node::typeDescription.typeName, "node", "node_id")}; - raco::utils::file::write((test_path() / "lua_script_out.lua").string(), R"( + utils::file::write((test_path() / "lua_script_out.lua").string(), R"( function interface(IN,OUT) IN.vec4 = Type:Vec4f() IN.vec3 = Type:Vec3f() @@ -289,12 +284,10 @@ function run(IN,OUT) end )"); context.set({luaScriptOut, {"uri"}}, (test_path() / "lua_script_out.lua").string()); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); context.addLink({luaScriptOut, {"outputs", "vec3"}}, {node, {"rotation"}}); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); context.set({luaScriptOut, {"inputs", "vec4", "x"}}, 0.3); context.set({luaScriptOut, {"inputs", "vec4", "y"}}, -0.3); @@ -303,26 +296,24 @@ end context.set({luaScriptOut, {"inputs", "vec3", "x"}}, 90.0); context.set({luaScriptOut, {"inputs", "vec3", "y"}}, 180.0); context.set({luaScriptOut, {"inputs", "vec3", "z"}}, 270.0); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); context.addLink({luaScriptOut, {"outputs", "vec4"}}, {node, {"rotation"}}); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); - auto nodeBinding = backend.logicEngine().findByName("node_NodeBinding"); - ASSERT_EQ(nodeBinding->getRotationType(), rlogic::ERotationType::Quaternion); + auto nodeBinding = logicEngine().findObject("node_NodeBinding"); + ASSERT_EQ(nodeBinding->getRotationType(), ramses::ERotationType::Quaternion); auto rotationProperty = nodeBinding->getInputs()->getChild("rotation"); - ASSERT_EQ(rotationProperty->getType(), rlogic::EPropertyType::Vec4f); - auto rotationArray = rotationProperty->get(); - ASSERT_EQ(rotationArray, rlogic::vec4f({0.3, -0.3, 1.0, -1.0})); + ASSERT_EQ(rotationProperty->getType(), ramses::EPropertyType::Vec4f); + auto rotationArray = rotationProperty->get(); + ASSERT_EQ(rotationArray, ramses::vec4f({0.3, -0.3, 1.0, -1.0})); } TEST_F(LinkAdaptorFixture, linkQuaternionToEulerByURIChange) { - const auto luaScriptOut{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script_out", "lua_script_out_id")}; - const auto node{context.createObject(raco::user_types::Node::typeDescription.typeName, "node", "node_id")}; + const auto luaScriptOut{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script_out", "lua_script_out_id")}; + const auto node{context.createObject(user_types::Node::typeDescription.typeName, "node", "node_id")}; - raco::utils::file::write((test_path() / "lua_script_out1.lua").string(), R"( + utils::file::write((test_path() / "lua_script_out1.lua").string(), R"( function interface(IN,OUT) IN.vec = Type:Vec4f() OUT.vec = Type:Vec4f() @@ -332,7 +323,7 @@ function run(IN,OUT) end )"); - raco::utils::file::write((test_path() / "lua_script_out2.lua").string(), R"( + utils::file::write((test_path() / "lua_script_out2.lua").string(), R"( function interface(IN,OUT) IN.vec = Type:Vec3f() OUT.vec = Type:Vec3f() @@ -342,26 +333,23 @@ function run(IN,OUT) end )"); context.set({luaScriptOut, {"uri"}}, (test_path() / "lua_script_out1.lua").string()); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); context.addLink({luaScriptOut, {"outputs", "vec"}}, {node, {"rotation"}}); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); context.set({luaScriptOut, {"uri"}}, (test_path() / "lua_script_out2.lua").string()); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); - auto nodeBinding = backend.logicEngine().findByName("node_NodeBinding"); - ASSERT_NE(nodeBinding->getRotationType(), rlogic::ERotationType::Quaternion); + auto nodeBinding = logicEngine().findObject("node_NodeBinding"); + ASSERT_NE(nodeBinding->getRotationType(), ramses::ERotationType::Quaternion); } TEST_F(LinkAdaptorFixture, linkEulerToQuaternionByURIChange) { - const auto luaScriptOut{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script_out", "lua_script_out_id")}; - const auto node{context.createObject(raco::user_types::Node::typeDescription.typeName, "node", "node_id")}; + const auto luaScriptOut{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script_out", "lua_script_out_id")}; + const auto node{context.createObject(user_types::Node::typeDescription.typeName, "node", "node_id")}; - raco::utils::file::write((test_path() / "lua_script_out1.lua").string(), R"( + utils::file::write((test_path() / "lua_script_out1.lua").string(), R"( function interface(IN,OUT) IN.vec = Type:Vec4f() OUT.vec = Type:Vec4f() @@ -371,7 +359,7 @@ function run(IN,OUT) end )"); - raco::utils::file::write((test_path() / "lua_script_out2.lua").string(), R"( + utils::file::write((test_path() / "lua_script_out2.lua").string(), R"( function interface(IN,OUT) IN.vec = Type:Vec3f() OUT.vec = Type:Vec3f() @@ -381,26 +369,23 @@ function run(IN,OUT) end )"); context.set({luaScriptOut, {"uri"}}, (test_path() / "lua_script_out2.lua").string()); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); context.addLink({luaScriptOut, {"outputs", "vec"}}, {node, {"rotation"}}); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); context.set({luaScriptOut, {"uri"}}, (test_path() / "lua_script_out1.lua").string()); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); - auto nodeBinding = backend.logicEngine().findByName("node_NodeBinding"); - ASSERT_EQ(nodeBinding->getRotationType(), rlogic::ERotationType::Quaternion); + auto nodeBinding = logicEngine().findObject("node_NodeBinding"); + ASSERT_EQ(nodeBinding->getRotationType(), ramses::ERotationType::Quaternion); } TEST_F(LinkAdaptorFixture, linkQuaternionStaysAfterTranslationLinkRemoval) { - const auto luaScriptOut{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script_out", "lua_script_out_id")}; - const auto node{context.createObject(raco::user_types::Node::typeDescription.typeName, "node", "node_id")}; + const auto luaScriptOut{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script_out", "lua_script_out_id")}; + const auto node{context.createObject(user_types::Node::typeDescription.typeName, "node", "node_id")}; - raco::utils::file::write((test_path() / "lua_script_out1.lua").string(), R"( + utils::file::write((test_path() / "lua_script_out1.lua").string(), R"( function interface(IN,OUT) IN.vec = Type:Vec4f() OUT.vec = Type:Vec4f() @@ -413,32 +398,28 @@ function run(IN,OUT) end )"); context.set({luaScriptOut, {"uri"}}, (test_path() / "lua_script_out1.lua").string()); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); context.addLink({luaScriptOut, {"outputs", "vec"}}, {node, {"rotation"}}); context.addLink({luaScriptOut, {"outputs", "transl"}}, {node, {"translation"}}); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); context.set({luaScriptOut, {"uri"}}, (test_path() / "lua_script_out1.lua").string()); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); - context.removeLink(raco::core::ValueHandle{node, {"translation"}}.getDescriptor()); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + context.removeLink(core::ValueHandle{node, {"translation"}}.getDescriptor()); + ASSERT_TRUE(dispatch()); - auto nodeBinding = backend.logicEngine().findByName("node_NodeBinding"); - ASSERT_EQ(nodeBinding->getRotationType(), rlogic::ERotationType::Quaternion); + auto nodeBinding = logicEngine().findObject("node_NodeBinding"); + ASSERT_EQ(nodeBinding->getRotationType(), ramses::ERotationType::Quaternion); } TEST_F(LinkAdaptorFixture, linkQuaternionChangeToEulerAfterInvalidLinkIsValid) { - const auto luaScriptOut{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script_out", "lua_script_out_id")}; - const auto node{context.createObject(raco::user_types::Node::typeDescription.typeName, "node", "node_id")}; + const auto luaScriptOut{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script_out", "lua_script_out_id")}; + const auto node{context.createObject(user_types::Node::typeDescription.typeName, "node", "node_id")}; - raco::utils::file::write((test_path() / "lua_script_out1.lua").string(), R"( + utils::file::write((test_path() / "lua_script_out1.lua").string(), R"( function interface(IN,OUT) IN.vec = Type:Vec4f() OUT.vec = Type:Vec4f() @@ -450,7 +431,7 @@ end )"); - raco::utils::file::write((test_path() / "lua_script_out1b.lua").string(), R"( + utils::file::write((test_path() / "lua_script_out1b.lua").string(), R"( function interface(IN,OUT) IN.vec_b = Type:Vec4f() OUT.vec_b = Type:Vec4f() @@ -462,7 +443,7 @@ end )"); - raco::utils::file::write((test_path() / "lua_script_out2.lua").string(), R"( + utils::file::write((test_path() / "lua_script_out2.lua").string(), R"( function interface(IN,OUT) IN.vec = Type:Vec3f() OUT.vec = Type:Vec3f() @@ -474,33 +455,29 @@ end )"); context.set({luaScriptOut, {"uri"}}, (test_path() / "lua_script_out1.lua").string()); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); context.addLink({luaScriptOut, {"outputs", "vec"}}, {node, {"rotation"}}); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); context.set({luaScriptOut, {"uri"}}, (test_path() / "lua_script_out1b.lua").string()); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); ASSERT_FALSE((*commandInterface.project()->links().begin())->isValid()); - auto nodeBinding = backend.logicEngine().findByName("node_NodeBinding"); - ASSERT_NE(nodeBinding->getRotationType(), rlogic::ERotationType::Quaternion); + auto nodeBinding = logicEngine().findObject("node_NodeBinding"); + ASSERT_NE(nodeBinding->getRotationType(), ramses::ERotationType::Quaternion); context.set({luaScriptOut, {"uri"}}, (test_path() / "lua_script_out2.lua").string()); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); ASSERT_TRUE((*commandInterface.project()->links().begin())->isValid()); - nodeBinding = backend.logicEngine().findByName("node_NodeBinding"); - ASSERT_NE(nodeBinding->getRotationType(), rlogic::ERotationType::Quaternion); + nodeBinding = logicEngine().findObject("node_NodeBinding"); + ASSERT_NE(nodeBinding->getRotationType(), ramses::ERotationType::Quaternion); } TEST_F(LinkAdaptorFixture, linkQuaternionChangeInvalidToValid) { - const auto luaScriptOut{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script_out", "lua_script_out_id")}; - const auto node{context.createObject(raco::user_types::Node::typeDescription.typeName, "node", "node_id")}; + const auto luaScriptOut{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script_out", "lua_script_out_id")}; + const auto node{context.createObject(user_types::Node::typeDescription.typeName, "node", "node_id")}; - raco::utils::file::write((test_path() / "lua_script_out1.lua").string(), R"( + utils::file::write((test_path() / "lua_script_out1.lua").string(), R"( function interface(IN,OUT) IN.vec = Type:Vec4f() OUT.vec = Type:Vec4f() @@ -512,7 +489,7 @@ end )"); - raco::utils::file::write((test_path() / "lua_script_out1b.lua").string(), R"( + utils::file::write((test_path() / "lua_script_out1b.lua").string(), R"( function interface(IN,OUT) IN.vec_b = Type:Vec4f() OUT.vec_b = Type:Vec4f() @@ -526,26 +503,22 @@ end context.set({luaScriptOut, {"uri"}}, (test_path() / "lua_script_out1.lua").string()); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); context.addLink({luaScriptOut, {"outputs", "vec"}}, {node, {"rotation"}}); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); context.set({luaScriptOut, {"uri"}}, (test_path() / "lua_script_out1b.lua").string()); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); ASSERT_FALSE((*commandInterface.project()->links().begin())->isValid()); - auto nodeBinding = backend.logicEngine().findByName("node_NodeBinding"); - ASSERT_NE(nodeBinding->getRotationType(), rlogic::ERotationType::Quaternion); + auto nodeBinding = logicEngine().findObject("node_NodeBinding"); + ASSERT_NE(nodeBinding->getRotationType(), ramses::ERotationType::Quaternion); context.set({luaScriptOut, {"uri"}}, (test_path() / "lua_script_out1.lua").string()); - ASSERT_NO_FATAL_FAILURE(dispatch()); - ASSERT_TRUE(backend.logicEngine().update()); + ASSERT_TRUE(dispatch()); ASSERT_TRUE((*commandInterface.project()->links().begin())->isValid()); - nodeBinding = backend.logicEngine().findByName("node_NodeBinding"); - ASSERT_EQ(nodeBinding->getRotationType(), rlogic::ERotationType::Quaternion); + nodeBinding = logicEngine().findObject("node_NodeBinding"); + ASSERT_EQ(nodeBinding->getRotationType(), ramses::ERotationType::Quaternion); } TEST_F(LinkAdaptorFixture, link_weak) { @@ -570,8 +543,8 @@ end ASSERT_TRUE(dispatch()); - auto startEngineObj = select(sceneContext.logicEngine(), "start"); - auto endEngineObj = select(sceneContext.logicEngine(), "end"); + auto startEngineObj = select(sceneContext.logicEngine(), "start"); + auto endEngineObj = select(sceneContext.logicEngine(), "end"); ASSERT_EQ(startEngineObj->getInputs()->getChild("x")->get(), 2.0); ASSERT_EQ(startEngineObj->getInputs()->getChild("y")->get(), 4.0); @@ -601,13 +574,13 @@ end commandInterface.addLink({lua, {"outputs", "v"}}, {child, {"translation"}}); ASSERT_TRUE(dispatch()); - EXPECT_EQ(backend.logicEngine().getPropertyLinks().size(), 1); + EXPECT_EQ(logicEngine().getPropertyLinks().size(), 1); commandInterface.moveScenegraphChildren({node}, prefab); ASSERT_TRUE(dispatch()); - EXPECT_EQ(backend.logicEngine().getPropertyLinks().size(), 0); + EXPECT_EQ(logicEngine().getPropertyLinks().size(), 0); commandInterface.moveScenegraphChildren({node}, nullptr); ASSERT_TRUE(dispatch()); - EXPECT_EQ(backend.logicEngine().getPropertyLinks().size(), 1); + EXPECT_EQ(logicEngine().getPropertyLinks().size(), 1); } diff --git a/components/libRamsesBase/tests/LinkOptimization_test.cpp b/components/libRamsesBase/tests/LinkOptimization_test.cpp index e13d5925..5148007a 100644 --- a/components/libRamsesBase/tests/LinkOptimization_test.cpp +++ b/components/libRamsesBase/tests/LinkOptimization_test.cpp @@ -106,23 +106,23 @@ TEST_F(LuaLinkOptimizationFixture, link_opt_level_up) { commandInterface.set({ start, {"inputs", "string"} }, std::string("asdf")); dispatch(); - auto startEngineObject = select(sceneContext.logicEngine(), std::string("start").c_str()); - auto midEngineObject = select(sceneContext.logicEngine(), std::string("mid").c_str()); - auto endEngineObject = select(sceneContext.logicEngine(), std::string("end").c_str()); + auto startEngineObject = select(sceneContext.logicEngine(), std::string("start").c_str()); + auto midEngineObject = select(sceneContext.logicEngine(), std::string("mid").c_str()); + auto endEngineObject = select(sceneContext.logicEngine(), std::string("end").c_str()); ASSERT_TRUE(startEngineObject == nullptr); ASSERT_TRUE(midEngineObject == nullptr); ASSERT_TRUE(endEngineObject != nullptr); ASSERT_EQ(endEngineObject->getInputs()->getChild("float")->get(), 0.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2f")->get().value()[1], 0.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3f")->get().value()[2], 0.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4f")->get().value()[3], 0.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2f")->get().value()[1], 0.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3f")->get().value()[2], 0.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4f")->get().value()[3], 0.0); ASSERT_EQ(endEngineObject->getInputs()->getChild("integer")->get(), 0); ASSERT_EQ(endEngineObject->getInputs()->getChild("integer64")->get(), int64_t{ 0 }); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2i")->get().value()[1], 0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3i")->get().value()[2], 0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4i")->get().value()[3], 0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2i")->get().value()[1], 0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3i")->get().value()[2], 0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4i")->get().value()[3], 0); ASSERT_EQ(endEngineObject->getInputs()->getChild("bool")->get(), false); ASSERT_EQ(endEngineObject->getInputs()->getChild("string")->get(), std::string()); @@ -135,23 +135,23 @@ TEST_F(LuaLinkOptimizationFixture, link_opt_level_up) { dispatch(); - startEngineObject = select(sceneContext.logicEngine(), std::string("start").c_str()); - midEngineObject = select(sceneContext.logicEngine(), std::string("mid").c_str()); - endEngineObject = select(sceneContext.logicEngine(), std::string("end").c_str()); + startEngineObject = select(sceneContext.logicEngine(), std::string("start").c_str()); + midEngineObject = select(sceneContext.logicEngine(), std::string("mid").c_str()); + endEngineObject = select(sceneContext.logicEngine(), std::string("end").c_str()); ASSERT_TRUE(startEngineObject != nullptr); ASSERT_TRUE(midEngineObject == nullptr); ASSERT_TRUE(endEngineObject != nullptr); ASSERT_EQ(endEngineObject->getInputs()->getChild("float")->get(), 1.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2f")->get().value()[1], 2.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3f")->get().value()[2], 3.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4f")->get().value()[3], 4.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2f")->get().value()[1], 2.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3f")->get().value()[2], 3.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4f")->get().value()[3], 4.0); ASSERT_EQ(endEngineObject->getInputs()->getChild("integer")->get(), 5); ASSERT_EQ(endEngineObject->getInputs()->getChild("integer64")->get(), int64_t{ 6 }); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2i")->get().value()[1], 7); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3i")->get().value()[2], 8); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4i")->get().value()[3], 9); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2i")->get().value()[1], 7); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3i")->get().value()[2], 8); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4i")->get().value()[3], 9); ASSERT_EQ(endEngineObject->getInputs()->getChild("bool")->get(), true); ASSERT_EQ(endEngineObject->getInputs()->getChild("string")->get(), std::string("asdf")); @@ -178,23 +178,23 @@ TEST_F(LuaLinkOptimizationFixture, link_opt_level_same) { commandInterface.set({ start, {"inputs", "string"} }, std::string("asdf")); dispatch(); - auto startEngineObject = select(sceneContext.logicEngine(), std::string("start").c_str()); - auto midEngineObject = select(sceneContext.logicEngine(), std::string("mid").c_str()); - auto endEngineObject = select(sceneContext.logicEngine(), std::string("end").c_str()); + auto startEngineObject = select(sceneContext.logicEngine(), std::string("start").c_str()); + auto midEngineObject = select(sceneContext.logicEngine(), std::string("mid").c_str()); + auto endEngineObject = select(sceneContext.logicEngine(), std::string("end").c_str()); ASSERT_TRUE(startEngineObject == nullptr); ASSERT_TRUE(midEngineObject == nullptr); ASSERT_TRUE(endEngineObject != nullptr); ASSERT_EQ(endEngineObject->getInputs()->getChild("float")->get(), 0.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2f")->get().value()[1], 0.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3f")->get().value()[2], 0.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4f")->get().value()[3], 0.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2f")->get().value()[1], 0.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3f")->get().value()[2], 0.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4f")->get().value()[3], 0.0); ASSERT_EQ(endEngineObject->getInputs()->getChild("integer")->get(), 0); ASSERT_EQ(endEngineObject->getInputs()->getChild("integer64")->get(), int64_t{ 0 }); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2i")->get().value()[1], 0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3i")->get().value()[2], 0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4i")->get().value()[3], 0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2i")->get().value()[1], 0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3i")->get().value()[2], 0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4i")->get().value()[3], 0); ASSERT_EQ(endEngineObject->getInputs()->getChild("bool")->get(), false); ASSERT_EQ(endEngineObject->getInputs()->getChild("string")->get(), std::string()); @@ -207,24 +207,24 @@ TEST_F(LuaLinkOptimizationFixture, link_opt_level_same) { dispatch(); - startEngineObject = select(sceneContext.logicEngine(), std::string("start").c_str()); - midEngineObject = select(sceneContext.logicEngine(), std::string("mid").c_str()); - endEngineObject = select(sceneContext.logicEngine(), std::string("end").c_str()); + startEngineObject = select(sceneContext.logicEngine(), std::string("start").c_str()); + midEngineObject = select(sceneContext.logicEngine(), std::string("mid").c_str()); + endEngineObject = select(sceneContext.logicEngine(), std::string("end").c_str()); ASSERT_TRUE(startEngineObject != nullptr); ASSERT_TRUE(midEngineObject == nullptr); ASSERT_TRUE(endEngineObject != nullptr); ASSERT_EQ(endEngineObject->getInputs()->getChild("float")->get(), 1.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2f")->get().value()[1], 2.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3f")->get().value()[2], 3.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4f")->get().value()[3], 4.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2f")->get().value()[1], 2.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3f")->get().value()[2], 3.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4f")->get().value()[3], 4.0); ASSERT_EQ(endEngineObject->getInputs()->getChild("integer")->get(), 5); ASSERT_EQ(endEngineObject->getInputs()->getChild("integer64")->get(), int64_t{ 6 }); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2i")->get().value()[1], 7); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3i")->get().value()[2], 8); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4i")->get().value()[3], 9); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2i")->get().value()[1], 7); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3i")->get().value()[2], 8); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4i")->get().value()[3], 9); ASSERT_EQ(endEngineObject->getInputs()->getChild("bool")->get(), true); ASSERT_EQ(endEngineObject->getInputs()->getChild("string")->get(), std::string("asdf")); @@ -243,10 +243,10 @@ TEST_F(LuaLinkOptimizationFixture, link_opt_level_down) { commandInterface.set({ start_b, {"inputs", "float"} }, 2.0); dispatch(); - auto startAEngineObject = select(sceneContext.logicEngine(), std::string("start_a").c_str()); - auto startBEngineObject = select(sceneContext.logicEngine(), std::string("start_b").c_str()); - auto midEngineObject = select(sceneContext.logicEngine(), std::string("mid").c_str()); - auto endEngineObject = select(sceneContext.logicEngine(), std::string("end").c_str()); + auto startAEngineObject = select(sceneContext.logicEngine(), std::string("start_a").c_str()); + auto startBEngineObject = select(sceneContext.logicEngine(), std::string("start_b").c_str()); + auto midEngineObject = select(sceneContext.logicEngine(), std::string("mid").c_str()); + auto endEngineObject = select(sceneContext.logicEngine(), std::string("end").c_str()); ASSERT_TRUE(startAEngineObject == nullptr); ASSERT_TRUE(startBEngineObject == nullptr); ASSERT_TRUE(midEngineObject == nullptr); @@ -258,10 +258,10 @@ TEST_F(LuaLinkOptimizationFixture, link_opt_level_down) { dispatch(); - startAEngineObject = select(sceneContext.logicEngine(), std::string("start_a").c_str()); - startBEngineObject = select(sceneContext.logicEngine(), std::string("start_b").c_str()); - midEngineObject = select(sceneContext.logicEngine(), std::string("mid").c_str()); - endEngineObject = select(sceneContext.logicEngine(), std::string("end").c_str()); + startAEngineObject = select(sceneContext.logicEngine(), std::string("start_a").c_str()); + startBEngineObject = select(sceneContext.logicEngine(), std::string("start_b").c_str()); + midEngineObject = select(sceneContext.logicEngine(), std::string("mid").c_str()); + endEngineObject = select(sceneContext.logicEngine(), std::string("end").c_str()); ASSERT_TRUE(startAEngineObject != nullptr); ASSERT_TRUE(startBEngineObject != nullptr); ASSERT_TRUE(midEngineObject == nullptr); diff --git a/components/libRamsesBase/tests/LuaInterfaceAdaptor_test.cpp b/components/libRamsesBase/tests/LuaInterfaceAdaptor_test.cpp index b45b8234..4a5b72f9 100644 --- a/components/libRamsesBase/tests/LuaInterfaceAdaptor_test.cpp +++ b/components/libRamsesBase/tests/LuaInterfaceAdaptor_test.cpp @@ -64,7 +64,7 @@ TEST_F(LuaInterfaceAdaptorFixture, defaultConstruction) { dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); } @@ -77,7 +77,7 @@ invalid interface definition auto interface = create_lua_interface("interface", interfaceFile); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); } TEST_F(LuaInterfaceAdaptorFixture, invalid_in_interface) { @@ -91,7 +91,7 @@ end auto interface = create_lua_interface("interface", interfaceFile); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); } TEST_F(LuaInterfaceAdaptorFixture, valid_text) { @@ -99,9 +99,9 @@ TEST_F(LuaInterfaceAdaptorFixture, valid_text) { auto interface = create_lua_interface("interface", interfaceFile); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); - auto engineObject = select(sceneContext.logicEngine(), std::string("interface").c_str()); + auto engineObject = select(sceneContext.logicEngine(), std::string("interface").c_str()); ASSERT_TRUE(engineObject != nullptr); ASSERT_EQ(engineObject->getUserId(), interface->objectIDAsRamsesLogicID()); } @@ -116,15 +116,15 @@ TEST_F(LuaInterfaceAdaptorFixture, name_prefab_inst) { dispatch(); - auto engineObj = select(sceneContext.logicEngine(), "inst.interface"); + auto engineObj = select(sceneContext.logicEngine(), "inst.interface"); ASSERT_TRUE(engineObj != nullptr); commandInterface.set({inst, &PrefabInstance::objectName_}, std::string("asdf")); dispatch(); - engineObj = select(sceneContext.logicEngine(), "inst.interface"); + engineObj = select(sceneContext.logicEngine(), "inst.interface"); ASSERT_TRUE(engineObj == nullptr); - engineObj = select(sceneContext.logicEngine(), "asdf.interface"); + engineObj = select(sceneContext.logicEngine(), "asdf.interface"); ASSERT_TRUE(engineObj != nullptr); } @@ -143,15 +143,15 @@ TEST_F(LuaInterfaceAdaptorFixture, name_prefab_inst_nested) { dispatch(); - auto engineObject = select(sceneContext.logicEngine(), std::string("interface-" + intf_nested->objectID()).c_str()); + auto engineObject = select(sceneContext.logicEngine(), std::string("interface-" + intf_nested->objectID()).c_str()); ASSERT_TRUE(engineObject != nullptr); //commandInterface.set({inst, &PrefabInstance::template_}, prefab); //dispatch(); - //engineObject = select(sceneContext.logicEngine(), std::string("interface-" + intf_nested->objectID()).c_str()); + //engineObject = select(sceneContext.logicEngine(), std::string("interface-" + intf_nested->objectID()).c_str()); //ASSERT_TRUE(engineObject == nullptr); - //engineObject = select(sceneContext.logicEngine(), "inst.interface"); + //engineObject = select(sceneContext.logicEngine(), "inst.interface"); //ASSERT_TRUE(engineObject != nullptr); } @@ -161,17 +161,17 @@ TEST_F(LuaInterfaceAdaptorFixture, change_name) { dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); - auto engineObject = select(sceneContext.logicEngine(), std::string("interface").c_str()); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); + auto engineObject = select(sceneContext.logicEngine(), std::string("interface").c_str()); ASSERT_TRUE(engineObject != nullptr); ASSERT_EQ(engineObject->getUserId(), interface->objectIDAsRamsesLogicID()); commandInterface.set({interface, &LuaInterface::objectName_}, std::string("newName")); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); - ASSERT_EQ(select(sceneContext.logicEngine(), std::string("interface").c_str()), nullptr); - engineObject = select(sceneContext.logicEngine(), std::string("newName").c_str()); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); + ASSERT_EQ(select(sceneContext.logicEngine(), std::string("interface").c_str()), nullptr); + engineObject = select(sceneContext.logicEngine(), std::string("newName").c_str()); ASSERT_TRUE(engineObject != nullptr); ASSERT_EQ(engineObject->getUserId(), interface->objectIDAsRamsesLogicID()); } @@ -181,18 +181,18 @@ TEST_F(LuaInterfaceAdaptorFixture, change_property_value) { auto interface = create_lua_interface("interface", interfaceFile); dispatch(); - auto engineObject = select(sceneContext.logicEngine(), std::string("interface").c_str()); + auto engineObject = select(sceneContext.logicEngine(), std::string("interface").c_str()); ASSERT_EQ(engineObject->getInputs()->getChild("float")->get(), 0.0); - ASSERT_EQ(engineObject->getInputs()->getChild("vector2f")->get().value()[1], 0.0); - ASSERT_EQ(engineObject->getInputs()->getChild("vector3f")->get().value()[2], 0.0); - ASSERT_EQ(engineObject->getInputs()->getChild("vector4f")->get().value()[3], 0.0); + ASSERT_EQ(engineObject->getInputs()->getChild("vector2f")->get().value()[1], 0.0); + ASSERT_EQ(engineObject->getInputs()->getChild("vector3f")->get().value()[2], 0.0); + ASSERT_EQ(engineObject->getInputs()->getChild("vector4f")->get().value()[3], 0.0); ASSERT_EQ(engineObject->getInputs()->getChild("integer")->get(), 0); ASSERT_EQ(engineObject->getInputs()->getChild("integer64")->get(), int64_t{0}); - ASSERT_EQ(engineObject->getInputs()->getChild("vector2i")->get().value()[1], 0); - ASSERT_EQ(engineObject->getInputs()->getChild("vector3i")->get().value()[2], 0); - ASSERT_EQ(engineObject->getInputs()->getChild("vector4i")->get().value()[3], 0); + ASSERT_EQ(engineObject->getInputs()->getChild("vector2i")->get().value()[1], 0); + ASSERT_EQ(engineObject->getInputs()->getChild("vector3i")->get().value()[2], 0); + ASSERT_EQ(engineObject->getInputs()->getChild("vector4i")->get().value()[3], 0); ASSERT_EQ(engineObject->getInputs()->getChild("bool")->get(), false); ASSERT_EQ(engineObject->getInputs()->getChild("string")->get(), std::string()); @@ -212,30 +212,30 @@ TEST_F(LuaInterfaceAdaptorFixture, change_property_value) { dispatch(); // check inputs ASSERT_EQ(engineObject->getInputs()->getChild("float")->get(), 1.0); - ASSERT_EQ(engineObject->getInputs()->getChild("vector2f")->get().value()[1], 2.0); - ASSERT_EQ(engineObject->getInputs()->getChild("vector3f")->get().value()[2], 3.0); - ASSERT_EQ(engineObject->getInputs()->getChild("vector4f")->get().value()[3], 4.0); + ASSERT_EQ(engineObject->getInputs()->getChild("vector2f")->get().value()[1], 2.0); + ASSERT_EQ(engineObject->getInputs()->getChild("vector3f")->get().value()[2], 3.0); + ASSERT_EQ(engineObject->getInputs()->getChild("vector4f")->get().value()[3], 4.0); ASSERT_EQ(engineObject->getInputs()->getChild("integer")->get(), 5); ASSERT_EQ(engineObject->getInputs()->getChild("integer64")->get(), int64_t{6}); - ASSERT_EQ(engineObject->getInputs()->getChild("vector2i")->get().value()[1], 7); - ASSERT_EQ(engineObject->getInputs()->getChild("vector3i")->get().value()[2], 8); - ASSERT_EQ(engineObject->getInputs()->getChild("vector4i")->get().value()[3], 9); + ASSERT_EQ(engineObject->getInputs()->getChild("vector2i")->get().value()[1], 7); + ASSERT_EQ(engineObject->getInputs()->getChild("vector3i")->get().value()[2], 8); + ASSERT_EQ(engineObject->getInputs()->getChild("vector4i")->get().value()[3], 9); ASSERT_EQ(engineObject->getInputs()->getChild("bool")->get(), true); ASSERT_EQ(engineObject->getInputs()->getChild("string")->get(), std::string("asdf")); // check outputs ASSERT_EQ(engineObject->getOutputs()->getChild("float")->get(), 1.0); - ASSERT_EQ(engineObject->getOutputs()->getChild("vector2f")->get().value()[1], 2.0); - ASSERT_EQ(engineObject->getOutputs()->getChild("vector3f")->get().value()[2], 3.0); - ASSERT_EQ(engineObject->getOutputs()->getChild("vector4f")->get().value()[3], 4.0); + ASSERT_EQ(engineObject->getOutputs()->getChild("vector2f")->get().value()[1], 2.0); + ASSERT_EQ(engineObject->getOutputs()->getChild("vector3f")->get().value()[2], 3.0); + ASSERT_EQ(engineObject->getOutputs()->getChild("vector4f")->get().value()[3], 4.0); ASSERT_EQ(engineObject->getOutputs()->getChild("integer")->get(), 5); ASSERT_EQ(engineObject->getOutputs()->getChild("integer64")->get(), int64_t{6}); - ASSERT_EQ(engineObject->getOutputs()->getChild("vector2i")->get().value()[1], 7); - ASSERT_EQ(engineObject->getOutputs()->getChild("vector3i")->get().value()[2], 8); - ASSERT_EQ(engineObject->getOutputs()->getChild("vector4i")->get().value()[3], 9); + ASSERT_EQ(engineObject->getOutputs()->getChild("vector2i")->get().value()[1], 7); + ASSERT_EQ(engineObject->getOutputs()->getChild("vector3i")->get().value()[2], 8); + ASSERT_EQ(engineObject->getOutputs()->getChild("vector4i")->get().value()[3], 9); ASSERT_EQ(engineObject->getOutputs()->getChild("bool")->get(), true); ASSERT_EQ(engineObject->getOutputs()->getChild("string")->get(), std::string("asdf")); @@ -251,8 +251,8 @@ TEST_F(LuaInterfaceAdaptorFixture, link_invalid_interface_to_invalid_script) { // test shouldn't crash here dispatch(); - auto ramsesStart = select(sceneContext.logicEngine(), std::string("start").c_str()); - auto ramsesEnd = select(sceneContext.logicEngine(), "end"); + auto ramsesStart = select(sceneContext.logicEngine(), std::string("start").c_str()); + auto ramsesEnd = select(sceneContext.logicEngine(), "end"); EXPECT_EQ(ramsesStart, nullptr); EXPECT_EQ(ramsesEnd, nullptr); @@ -270,8 +270,8 @@ TEST_F(LuaInterfaceAdaptorFixture, link_invalid_interface_to_invalid_interface) // test shouldn't crash here dispatch(); - auto ramsesStart = select(sceneContext.logicEngine(), std::string("start").c_str()); - auto ramsesEnd = select(sceneContext.logicEngine(), std::string("end").c_str()); + auto ramsesStart = select(sceneContext.logicEngine(), std::string("start").c_str()); + auto ramsesEnd = select(sceneContext.logicEngine(), std::string("end").c_str()); EXPECT_EQ(ramsesStart, nullptr); EXPECT_EQ(ramsesEnd, nullptr); @@ -291,8 +291,8 @@ TEST_F(LuaInterfaceAdaptorFixture, link_empty_interface_to_empty_script) { // test shouldn't crash here dispatch(); - auto ramsesStart = select(sceneContext.logicEngine(), std::string("start").c_str()); - auto ramsesEnd = select(sceneContext.logicEngine(), "end"); + auto ramsesStart = select(sceneContext.logicEngine(), std::string("start").c_str()); + auto ramsesEnd = select(sceneContext.logicEngine(), "end"); EXPECT_NE(ramsesStart, nullptr); EXPECT_NE(ramsesEnd, nullptr); @@ -311,8 +311,8 @@ TEST_F(LuaInterfaceAdaptorFixture, link_empty_interface_to_empty_interface) { // test shouldn't crash here dispatch(); - auto ramsesStart = select(sceneContext.logicEngine(), std::string("start").c_str()); - auto ramsesEnd = select(sceneContext.logicEngine(), std::string("end").c_str()); + auto ramsesStart = select(sceneContext.logicEngine(), std::string("start").c_str()); + auto ramsesEnd = select(sceneContext.logicEngine(), std::string("end").c_str()); EXPECT_NE(ramsesStart, nullptr); EXPECT_NE(ramsesEnd, nullptr); @@ -338,21 +338,21 @@ TEST_F(LuaInterfaceAdaptorFixture, link_individual_propagate_values) { commandInterface.set({start, {"inputs", "string"}}, std::string("asdf")); dispatch(); - auto startEngineObject = select(sceneContext.logicEngine(), std::string("start").c_str()); - auto endEngineObject = select(sceneContext.logicEngine(), std::string("end").c_str()); + auto startEngineObject = select(sceneContext.logicEngine(), std::string("start").c_str()); + auto endEngineObject = select(sceneContext.logicEngine(), std::string("end").c_str()); ASSERT_TRUE(startEngineObject != nullptr); ASSERT_TRUE(endEngineObject != nullptr); ASSERT_EQ(endEngineObject->getInputs()->getChild("float")->get(), 0.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2f")->get().value()[1], 0.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3f")->get().value()[2], 0.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4f")->get().value()[3], 0.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2f")->get().value()[1], 0.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3f")->get().value()[2], 0.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4f")->get().value()[3], 0.0); ASSERT_EQ(endEngineObject->getInputs()->getChild("integer")->get(), 0); ASSERT_EQ(endEngineObject->getInputs()->getChild("integer64")->get(), int64_t{0}); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2i")->get().value()[1], 0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3i")->get().value()[2], 0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4i")->get().value()[3], 0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2i")->get().value()[1], 0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3i")->get().value()[2], 0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4i")->get().value()[3], 0); ASSERT_EQ(endEngineObject->getInputs()->getChild("bool")->get(), false); ASSERT_EQ(endEngineObject->getInputs()->getChild("string")->get(), std::string()); @@ -372,15 +372,15 @@ TEST_F(LuaInterfaceAdaptorFixture, link_individual_propagate_values) { dispatch(); ASSERT_EQ(endEngineObject->getInputs()->getChild("float")->get(), 1.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2f")->get().value()[1], 2.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3f")->get().value()[2], 3.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4f")->get().value()[3], 4.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2f")->get().value()[1], 2.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3f")->get().value()[2], 3.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4f")->get().value()[3], 4.0); ASSERT_EQ(endEngineObject->getInputs()->getChild("integer")->get(), 5); ASSERT_EQ(endEngineObject->getInputs()->getChild("integer64")->get(), int64_t{6}); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2i")->get().value()[1], 7); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3i")->get().value()[2], 8); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4i")->get().value()[3], 9); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2i")->get().value()[1], 7); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3i")->get().value()[2], 8); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4i")->get().value()[3], 9); ASSERT_EQ(endEngineObject->getInputs()->getChild("bool")->get(), true); ASSERT_EQ(endEngineObject->getInputs()->getChild("string")->get(), std::string("asdf")); @@ -412,21 +412,21 @@ TEST_F(LuaInterfaceAdaptorFixture, link_container_propagate_values) { commandInterface.set({start, {"inputs", "string"}}, std::string("asdf")); dispatch(); - auto startEngineObject = select(sceneContext.logicEngine(), std::string("start").c_str()); - auto endEngineObject = select(sceneContext.logicEngine(), std::string("end").c_str()); + auto startEngineObject = select(sceneContext.logicEngine(), std::string("start").c_str()); + auto endEngineObject = select(sceneContext.logicEngine(), std::string("end").c_str()); ASSERT_TRUE(startEngineObject != nullptr); ASSERT_TRUE(endEngineObject != nullptr); ASSERT_EQ(endEngineObject->getInputs()->getChild("float")->get(), 0.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2f")->get().value()[1], 0.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3f")->get().value()[2], 0.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4f")->get().value()[3], 0.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2f")->get().value()[1], 0.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3f")->get().value()[2], 0.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4f")->get().value()[3], 0.0); ASSERT_EQ(endEngineObject->getInputs()->getChild("integer")->get(), 0); ASSERT_EQ(endEngineObject->getInputs()->getChild("integer64")->get(), int64_t{0}); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2i")->get().value()[1], 0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3i")->get().value()[2], 0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4i")->get().value()[3], 0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2i")->get().value()[1], 0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3i")->get().value()[2], 0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4i")->get().value()[3], 0); ASSERT_EQ(endEngineObject->getInputs()->getChild("bool")->get(), false); ASSERT_EQ(endEngineObject->getInputs()->getChild("string")->get(), std::string()); @@ -435,15 +435,15 @@ TEST_F(LuaInterfaceAdaptorFixture, link_container_propagate_values) { dispatch(); ASSERT_EQ(endEngineObject->getInputs()->getChild("float")->get(), 1.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2f")->get().value()[1], 2.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3f")->get().value()[2], 3.0); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4f")->get().value()[3], 4.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2f")->get().value()[1], 2.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3f")->get().value()[2], 3.0); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4f")->get().value()[3], 4.0); ASSERT_EQ(endEngineObject->getInputs()->getChild("integer")->get(), 5); ASSERT_EQ(endEngineObject->getInputs()->getChild("integer64")->get(), int64_t{6}); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2i")->get().value()[1], 7); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3i")->get().value()[2], 8); - ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4i")->get().value()[3], 9); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector2i")->get().value()[1], 7); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector3i")->get().value()[2], 8); + ASSERT_EQ(endEngineObject->getInputs()->getChild("vector4i")->get().value()[3], 9); ASSERT_EQ(endEngineObject->getInputs()->getChild("bool")->get(), true); ASSERT_EQ(endEngineObject->getInputs()->getChild("string")->get(), std::string("asdf")); diff --git a/components/libRamsesBase/tests/LuaScriptAdaptor_test.cpp b/components/libRamsesBase/tests/LuaScriptAdaptor_test.cpp index 975d86f9..8c2258ee 100644 --- a/components/libRamsesBase/tests/LuaScriptAdaptor_test.cpp +++ b/components/libRamsesBase/tests/LuaScriptAdaptor_test.cpp @@ -20,10 +20,10 @@ #include "utils/FileUtils.h" using namespace raco; -using raco::ramses_adaptor::LuaScriptAdaptor; -using raco::ramses_adaptor::propertyByNames; -using raco::user_types::SLuaScript; -using raco::user_types::LuaScript; +using ramses_adaptor::LuaScriptAdaptor; +using ramses_adaptor::propertyByNames; +using user_types::SLuaScript; +using user_types::LuaScript; class LuaScriptAdaptorFixture : public RamsesBaseFixture<> {}; @@ -32,7 +32,7 @@ TEST_F(LuaScriptAdaptorFixture, defaultConstruction) { dispatch(); - auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; + auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; ASSERT_TRUE(engineObj == nullptr); } @@ -40,7 +40,7 @@ TEST_F(LuaScriptAdaptorFixture, validScript) { auto luaScript = context.createObject(LuaScript::typeDescription.typeName, "LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) end @@ -51,7 +51,7 @@ end context.set({luaScript, {"uri"}}, uriPath); dispatch(); - auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; + auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; ASSERT_TRUE(engineObj != nullptr); ASSERT_EQ(engineObj->getUserId(), luaScript->objectIDAsRamsesLogicID()); } @@ -68,7 +68,7 @@ end dispatch(); EXPECT_TRUE(commandInterface.errors().hasError({script})); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); } TEST_F(LuaScriptAdaptorFixture, invalid_error_in_interface) { @@ -83,7 +83,7 @@ end dispatch(); EXPECT_TRUE(commandInterface.errors().hasError({script})); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); } TEST_F(LuaScriptAdaptorFixture, innvalid_error_in_run) { @@ -97,14 +97,14 @@ end auto script = create_lua("script", scriptFile); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); } TEST_F(LuaScriptAdaptorFixture, nameChange) { auto luaScript = context.createObject(LuaScript::typeDescription.typeName, "LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) end @@ -116,7 +116,7 @@ end dispatch(); { - auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; + auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; ASSERT_TRUE(engineObj != nullptr); ASSERT_EQ(engineObj->getName(), "LuaScript Name"); ASSERT_EQ(engineObj->getUserId(), luaScript->objectIDAsRamsesLogicID()); @@ -126,7 +126,7 @@ end dispatch(); { - auto engineObj{select(sceneContext.logicEngine(), "Changed")}; + auto engineObj{select(sceneContext.logicEngine(), "Changed")}; ASSERT_TRUE(engineObj != nullptr); ASSERT_EQ(engineObj->getName(), "Changed"); ASSERT_EQ(engineObj->getUserId(), luaScript->objectIDAsRamsesLogicID()); @@ -137,7 +137,7 @@ TEST_F(LuaScriptAdaptorFixture, inInt) { auto luaScript = context.createObject(LuaScript::typeDescription.typeName, "LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) IN.value = Type:Int32() end @@ -150,7 +150,7 @@ end context.set({luaScript, {"inputs", "value"}}, 5); dispatch(); - auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; + auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; ASSERT_EQ(5, engineObj->getInputs()->getChild("value")->get()); } @@ -158,7 +158,7 @@ TEST_F(LuaScriptAdaptorFixture, inFloat) { auto luaScript = context.createObject(LuaScript::typeDescription.typeName, "LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) IN.value = Type:Float() end @@ -171,7 +171,7 @@ end context.set({luaScript, {"inputs", "value"}}, 5.0); dispatch(); - auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; + auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; ASSERT_EQ(5.0f, engineObj->getInputs()->getChild("value")->get()); } @@ -179,7 +179,7 @@ TEST_F(LuaScriptAdaptorFixture, inBool) { auto luaScript = context.createObject(LuaScript::typeDescription.typeName, "LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) IN.value = Type:Bool() end @@ -192,7 +192,7 @@ end context.set({luaScript, {"inputs", "value"}}, true); dispatch(); - auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; + auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; ASSERT_EQ(true, engineObj->getInputs()->getChild("value")->get()); } @@ -200,7 +200,7 @@ TEST_F(LuaScriptAdaptorFixture, inVec2f) { auto luaScript = context.createObject(LuaScript::typeDescription.typeName, "LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) IN.value = Type:Vec2f() end @@ -213,16 +213,16 @@ end context.set({luaScript, {"inputs", "value", "x" }}, 5.0f); dispatch(); - auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; - ASSERT_EQ(5.0f, engineObj->getInputs()->getChild("value")->get().value()[0]); - ASSERT_EQ(0.0f, engineObj->getInputs()->getChild("value")->get().value()[1]); + auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; + ASSERT_EQ(5.0f, engineObj->getInputs()->getChild("value")->get().value()[0]); + ASSERT_EQ(0.0f, engineObj->getInputs()->getChild("value")->get().value()[1]); } TEST_F(LuaScriptAdaptorFixture, inStruct) { auto luaScript = context.createObject(LuaScript::typeDescription.typeName, "LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) IN.value = { a = Type:Float() @@ -237,7 +237,7 @@ end context.set({luaScript, {"inputs", "value", "a"}}, 5.0f); dispatch(); - auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; + auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; ASSERT_EQ(5.0f, propertyByNames(engineObj->getInputs(), "value", "a")->get()); } @@ -245,7 +245,7 @@ TEST_F(LuaScriptAdaptorFixture, inNestedStruct) { auto luaScript = context.createObject(LuaScript::typeDescription.typeName, "LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) local s = { x = Type:Float(), y = Type:Float() } IN.value = { @@ -261,7 +261,7 @@ end context.set({luaScript, {"inputs", "value", "a", "x"}}, 5.0f); dispatch(); - auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; + auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; ASSERT_EQ(5.0f, propertyByNames(engineObj->getInputs(), "value", "a", "x")->get()); } @@ -269,7 +269,7 @@ TEST_F(LuaScriptAdaptorFixture, inVec4f) { auto luaScript = context.createObject(LuaScript::typeDescription.typeName, "LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) IN.value = Type:Vec4f() end @@ -282,8 +282,8 @@ end context.set({luaScript, {"inputs", "value", "x"}}, 5.0f); dispatch(); - auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; - ASSERT_EQ(5.0f, propertyByNames(engineObj->getInputs(), "value")->get()->at(0)); + auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; + ASSERT_EQ(5.0f, propertyByNames(engineObj->getInputs(), "value")->get().value().x); } @@ -291,7 +291,7 @@ TEST_F(LuaScriptAdaptorFixture, outInt) { auto luaScript = context.createObject(LuaScript::typeDescription.typeName, "LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) IN.in_value = Type:Int32() OUT.out_value = Type:Int32() @@ -306,7 +306,7 @@ end context.set({luaScript, {"inputs", "in_value"}}, 5); dispatch(); - auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; + auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; ASSERT_EQ(5, engineObj->getOutputs()->getChild("out_value")->get()); } @@ -314,7 +314,7 @@ TEST_F(LuaScriptAdaptorFixture, outFloat) { auto luaScript = context.createObject(LuaScript::typeDescription.typeName, "LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) IN.in_value = Type:Float() OUT.out_value = Type:Float() @@ -329,7 +329,7 @@ end context.set({luaScript, {"inputs", "in_value"}}, 5.0); dispatch(); - auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; + auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; ASSERT_EQ(5.0f, engineObj->getOutputs()->getChild("out_value")->get()); } @@ -337,7 +337,7 @@ TEST_F(LuaScriptAdaptorFixture, outBool) { auto luaScript = context.createObject(LuaScript::typeDescription.typeName, "LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) IN.in_value = Type:Bool() OUT.out_value = Type:Bool() @@ -352,7 +352,7 @@ end context.set({luaScript, {"inputs", "in_value"}}, true); dispatch(); - auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; + auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; ASSERT_EQ(true, engineObj->getOutputs()->getChild("out_value")->get()); } @@ -360,7 +360,7 @@ TEST_F(LuaScriptAdaptorFixture, outVec2f) { auto luaScript = context.createObject(LuaScript::typeDescription.typeName, "LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) IN.in_value = Type:Vec2f() OUT.out_value = Type:Vec2f() @@ -375,16 +375,16 @@ end context.set({luaScript, {"inputs", "in_value", "x" }}, 5.0f); dispatch(); - auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; - ASSERT_EQ(5.0f, engineObj->getOutputs()->getChild("out_value")->get().value()[0]); - ASSERT_EQ(0.0f,engineObj->getOutputs()->getChild("out_value")->get().value()[1]); + auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; + ASSERT_EQ(5.0f, engineObj->getOutputs()->getChild("out_value")->get().value()[0]); + ASSERT_EQ(0.0f,engineObj->getOutputs()->getChild("out_value")->get().value()[1]); } TEST_F(LuaScriptAdaptorFixture, outStruct) { auto luaScript = context.createObject(LuaScript::typeDescription.typeName, "LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) IN.in_value = { a = Type:Float() @@ -404,7 +404,7 @@ end context.set({luaScript, {"inputs", "in_value", "a"}}, 5.0f); dispatch(); - auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; + auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; ASSERT_EQ(5.0f, propertyByNames(engineObj->getOutputs(), "out_value", "a")->get()); } @@ -412,7 +412,7 @@ TEST_F(LuaScriptAdaptorFixture, outNestedStruct) { auto luaScript = context.createObject(LuaScript::typeDescription.typeName, "LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) local s = { x = Type:Float(), y = Type:Float() } IN.in_value = { @@ -432,7 +432,7 @@ end context.set({luaScript, {"inputs", "in_value", "a", "x"}}, 5.0f); dispatch(); - auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; + auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; ASSERT_EQ(5.0f, propertyByNames(engineObj->getOutputs(), "out_value", "b", "x")->get()); } @@ -440,7 +440,7 @@ TEST_F(LuaScriptAdaptorFixture, outVec4f) { auto luaScript = context.createObject(LuaScript::typeDescription.typeName, "LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) IN.in_value = Type:Vec4f() OUT.out_value = Type:Vec4f() @@ -455,8 +455,8 @@ end context.set({luaScript, {"inputs", "in_value", "x"}}, 5.0f); dispatch(); - auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; - ASSERT_EQ(5.0f, propertyByNames(engineObj->getOutputs(), "out_value")->get()->at(0)); + auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; + ASSERT_EQ(5.0f, propertyByNames(engineObj->getOutputs(), "out_value")->get().value().x); } @@ -464,7 +464,7 @@ TEST_F(LuaScriptAdaptorFixture, keep_global_lua_state) { auto luaScript = create("LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) IN.value = Type:Float() OUT.value = Type:Float() @@ -483,7 +483,7 @@ end context.set({luaScript, {"inputs", "value"}}, 5.0); dispatch(); - auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; + auto engineObj{select(sceneContext.logicEngine(), "LuaScript Name")}; ASSERT_EQ(6.0f, engineObj->getOutputs()->getChild("value")->get()); context.set({luaScript, {"inputs", "value"}}, 2.0); @@ -499,7 +499,7 @@ TEST_F(LuaScriptAdaptorFixture, prefab_instance_top_level_script_engine_name_get auto prefabInst = create("PrefabInstance"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) end @@ -518,38 +518,38 @@ end commandInterface.moveScenegraphChildren({luaScriptTopLevel}, prefab); dispatch(); - auto engineObj{select(sceneContext.logicEngine(), "PrefabInstance.LuaScript Name")}; + auto engineObj{select(sceneContext.logicEngine(), "PrefabInstance.LuaScript Name")}; ASSERT_TRUE(engineObj != nullptr); - ASSERT_EQ(engineObj->getUserId(), prefabInst->children_->asVector().back()->objectIDAsRamsesLogicID()); + ASSERT_EQ(engineObj->getUserId(), prefabInst->children_->asVector().back()->objectIDAsRamsesLogicID()); - engineObj = select(sceneContext.logicEngine(), "PrefabInstance.Child LuaScript Name"); + engineObj = select(sceneContext.logicEngine(), "PrefabInstance.Child LuaScript Name"); ASSERT_TRUE(engineObj == nullptr); - engineObj = select(sceneContext.logicEngine(), "Child LuaScript Name"); + engineObj = select(sceneContext.logicEngine(), "Child LuaScript Name"); ASSERT_TRUE(engineObj != nullptr); - ASSERT_EQ(engineObj->getUserId(), prefabInst->children_->asVector().front()->children_->asVector().front()->objectIDAsRamsesLogicID()); + ASSERT_EQ(engineObj->getUserId(), prefabInst->children_->asVector().front()->children_->asVector().front()->objectIDAsRamsesLogicID()); commandInterface.moveScenegraphChildren({luaScriptTopLevel}, {}); dispatch(); - engineObj = select(sceneContext.logicEngine(), "PrefabInstance.LuaScript Name"); + engineObj = select(sceneContext.logicEngine(), "PrefabInstance.LuaScript Name"); ASSERT_TRUE(engineObj == nullptr); - engineObj = select(sceneContext.logicEngine(), "LuaScript Name"); + engineObj = select(sceneContext.logicEngine(), "LuaScript Name"); ASSERT_TRUE(engineObj != nullptr); ASSERT_EQ(engineObj->getUserId(), luaScriptTopLevel->objectIDAsRamsesLogicID()); commandInterface.moveScenegraphChildren({luaScriptChild}, prefab); dispatch(); - engineObj = select(sceneContext.logicEngine(), "PrefabInstance.Child LuaScript Name"); + engineObj = select(sceneContext.logicEngine(), "PrefabInstance.Child LuaScript Name"); ASSERT_TRUE(engineObj != nullptr); - ASSERT_EQ(engineObj->getUserId(), prefabInst->children_->asVector().back()->objectIDAsRamsesLogicID()); + ASSERT_EQ(engineObj->getUserId(), prefabInst->children_->asVector().back()->objectIDAsRamsesLogicID()); commandInterface.moveScenegraphChildren({luaScriptChild}, node); dispatch(); - engineObj = select(sceneContext.logicEngine(), "PrefabInstance.Child LuaScript Name"); + engineObj = select(sceneContext.logicEngine(), "PrefabInstance.Child LuaScript Name"); ASSERT_TRUE(engineObj == nullptr); } @@ -560,7 +560,7 @@ TEST_F(LuaScriptAdaptorFixture, prefab_instance_top_level_script_engine_name_get auto prefabInst = create("PrefabInstance"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) end @@ -579,12 +579,12 @@ end commandInterface.set({prefabInst, {"objectName"}}, std::string("New PrefabInstance")); dispatch(); - auto engineObj = select(sceneContext.logicEngine(), "PrefabInstance.LuaScript Name"); + auto engineObj = select(sceneContext.logicEngine(), "PrefabInstance.LuaScript Name"); ASSERT_TRUE(engineObj == nullptr); - engineObj = select(sceneContext.logicEngine(), "New PrefabInstance.LuaScript Name"); + engineObj = select(sceneContext.logicEngine(), "New PrefabInstance.LuaScript Name"); ASSERT_TRUE(engineObj != nullptr); - ASSERT_EQ(engineObj->getUserId(), prefabInst->children_->asVector().back()->objectIDAsRamsesLogicID()); + ASSERT_EQ(engineObj->getUserId(), prefabInst->children_->asVector().back()->objectIDAsRamsesLogicID()); } @@ -594,7 +594,7 @@ TEST_F(LuaScriptAdaptorFixture, prefab_instance_top_level_script_engine_name_get auto prefabInst = create("PrefabInstance"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) end @@ -614,9 +614,9 @@ end auto pastedObjs = commandInterface.pasteObjects(copiedObjs); dispatch(); - auto engineObj = select(sceneContext.logicEngine(), "PrefabInstance (1).LuaScript Name"); + auto engineObj = select(sceneContext.logicEngine(), "PrefabInstance (1).LuaScript Name"); ASSERT_TRUE(engineObj != nullptr); - ASSERT_EQ(engineObj->getUserId(), pastedObjs.front()->children_->asVector().back()->objectIDAsRamsesLogicID()); + ASSERT_EQ(engineObj->getUserId(), pastedObjs.front()->children_->asVector().back()->objectIDAsRamsesLogicID()); } @@ -626,7 +626,7 @@ TEST_F(LuaScriptAdaptorFixture, prefab_instance_top_level_script_engine_name_get auto prefabInst = create("PrefabInstance"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) end @@ -648,20 +648,20 @@ end commandInterface.undoStack().undo(); dispatch(); - auto engineObj = select(sceneContext.logicEngine(), "New PrefabInstance.LuaScript Name"); + auto engineObj = select(sceneContext.logicEngine(), "New PrefabInstance.LuaScript Name"); ASSERT_TRUE(engineObj == nullptr); - engineObj = select(sceneContext.logicEngine(), "PrefabInstance.LuaScript Name"); + engineObj = select(sceneContext.logicEngine(), "PrefabInstance.LuaScript Name"); ASSERT_TRUE(engineObj != nullptr); - ASSERT_EQ(engineObj->getUserId(), prefabInst->children_->asVector().back()->objectIDAsRamsesLogicID()); + ASSERT_EQ(engineObj->getUserId(), prefabInst->children_->asVector().back()->objectIDAsRamsesLogicID()); commandInterface.undoStack().redo(); dispatch(); - engineObj = select(sceneContext.logicEngine(), "New PrefabInstance.LuaScript Name"); + engineObj = select(sceneContext.logicEngine(), "New PrefabInstance.LuaScript Name"); ASSERT_TRUE(engineObj != nullptr); - ASSERT_EQ(engineObj->getUserId(), prefabInst->children_->asVector().back()->objectIDAsRamsesLogicID()); + ASSERT_EQ(engineObj->getUserId(), prefabInst->children_->asVector().back()->objectIDAsRamsesLogicID()); - engineObj = select(sceneContext.logicEngine(), "PrefabInstance.LuaScript Name"); + engineObj = select(sceneContext.logicEngine(), "PrefabInstance.LuaScript Name"); ASSERT_TRUE(engineObj == nullptr); } diff --git a/components/libRamsesBase/tests/LuaScriptModuleAdaptor_test.cpp b/components/libRamsesBase/tests/LuaScriptModuleAdaptor_test.cpp index de503b98..43945850 100644 --- a/components/libRamsesBase/tests/LuaScriptModuleAdaptor_test.cpp +++ b/components/libRamsesBase/tests/LuaScriptModuleAdaptor_test.cpp @@ -40,7 +40,7 @@ TEST_F(LuaScriptModuleAdaptorTest, defaultConstruction) { dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); } TEST_F(LuaScriptModuleAdaptorTest, invalidModule) { @@ -49,11 +49,11 @@ TEST_F(LuaScriptModuleAdaptorTest, invalidModule) { dispatch(); auto moduleFile = generateLuaScript("script"); - commandInterface.set({module, &raco::user_types::LuaScriptModule::uri_}, moduleFile); + commandInterface.set({module, &user_types::LuaScriptModule::uri_}, moduleFile); dispatch(); ASSERT_TRUE(commandInterface.errors().hasError(module)); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); } TEST_F(LuaScriptModuleAdaptorTest, validModule) { @@ -62,12 +62,12 @@ TEST_F(LuaScriptModuleAdaptorTest, validModule) { dispatch(); auto moduleFile = generateModule("coalas"); - commandInterface.set({module, &raco::user_types::LuaScriptModule::uri_}, moduleFile); + commandInterface.set({module, &user_types::LuaScriptModule::uri_}, moduleFile); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); - ASSERT_NE(select(sceneContext.logicEngine(), "Module"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Module")->getUserId(), module->objectIDAsRamsesLogicID()); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); + ASSERT_NE(select(sceneContext.logicEngine(), "Module"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Module")->getUserId(), module->objectIDAsRamsesLogicID()); } TEST_F(LuaScriptModuleAdaptorTest, validModule_unassign) { @@ -76,13 +76,13 @@ TEST_F(LuaScriptModuleAdaptorTest, validModule_unassign) { dispatch(); auto moduleFile = generateModule("coalas"); - commandInterface.set({module, &raco::user_types::LuaScriptModule::uri_}, moduleFile); + commandInterface.set({module, &user_types::LuaScriptModule::uri_}, moduleFile); dispatch(); - commandInterface.set({module, &raco::user_types::LuaScriptModule::uri_}, std::string()); + commandInterface.set({module, &user_types::LuaScriptModule::uri_}, std::string()); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); } TEST_F(LuaScriptModuleAdaptorTest, validModule_rename_obj) { @@ -91,15 +91,15 @@ TEST_F(LuaScriptModuleAdaptorTest, validModule_rename_obj) { dispatch(); auto moduleFile = generateModule("coalas"); - commandInterface.set({module, &raco::user_types::LuaScriptModule::uri_}, moduleFile); + commandInterface.set({module, &user_types::LuaScriptModule::uri_}, moduleFile); dispatch(); context.set({module, &LuaScriptModule::objectName_}, std::string("Changed")); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); - ASSERT_NE(select(sceneContext.logicEngine(), "Changed"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Changed")->getUserId(), module->objectIDAsRamsesLogicID()); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); + ASSERT_NE(select(sceneContext.logicEngine(), "Changed"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Changed")->getUserId(), module->objectIDAsRamsesLogicID()); } TEST_F(LuaScriptModuleAdaptorTest, validModule_variousLuaScripts_noModuleCopies) { @@ -107,7 +107,7 @@ TEST_F(LuaScriptModuleAdaptorTest, validModule_variousLuaScripts_noModuleCopies) dispatch(); auto moduleFile = generateModule("coalas"); - commandInterface.set({module, &raco::user_types::LuaScriptModule::uri_}, moduleFile); + commandInterface.set({module, &user_types::LuaScriptModule::uri_}, moduleFile); dispatch(); auto script1 = context.createObject(LuaScript::typeDescription.typeName, "Script1"); @@ -116,9 +116,9 @@ TEST_F(LuaScriptModuleAdaptorTest, validModule_variousLuaScripts_noModuleCopies) auto scriptFile1 = generateLuaScript("script1"); auto scriptFile2 = generateLuaScript("script2"); auto scriptFile3 = generateLuaScript("script3"); - commandInterface.set({script1, &raco::user_types::LuaScript::uri_}, scriptFile1); - commandInterface.set({script2, &raco::user_types::LuaScript::uri_}, scriptFile2); - commandInterface.set({script3, &raco::user_types::LuaScript::uri_}, scriptFile3); + commandInterface.set({script1, &user_types::LuaScript::uri_}, scriptFile1); + commandInterface.set({script2, &user_types::LuaScript::uri_}, scriptFile2); + commandInterface.set({script3, &user_types::LuaScript::uri_}, scriptFile3); dispatch(); @@ -127,6 +127,6 @@ TEST_F(LuaScriptModuleAdaptorTest, validModule_variousLuaScripts_noModuleCopies) commandInterface.set({script3, {"luaModules", "neededModule"}}, module); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); - ASSERT_EQ(select(sceneContext.logicEngine(), "Module")->getUserId(), module->objectIDAsRamsesLogicID()); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); + ASSERT_EQ(select(sceneContext.logicEngine(), "Module")->getUserId(), module->objectIDAsRamsesLogicID()); } diff --git a/components/libRamsesBase/tests/MaterialAdaptorTestBase.h b/components/libRamsesBase/tests/MaterialAdaptorTestBase.h index fa82aef1..cad19b8c 100644 --- a/components/libRamsesBase/tests/MaterialAdaptorTestBase.h +++ b/components/libRamsesBase/tests/MaterialAdaptorTestBase.h @@ -21,17 +21,18 @@ class MaterialAdaptorTestBase : public RamsesBaseFixture<> { public: SCubeMap create_cubemap(const std::string& name, const std::string& relpath) { auto cubeMap = create(name); - commandInterface.set({ cubeMap, &raco::user_types::CubeMap::uriBack_ }, (test_path() / relpath).string()); - commandInterface.set({ cubeMap, &raco::user_types::CubeMap::uriBottom_ }, (test_path() / relpath).string()); - commandInterface.set({ cubeMap, &raco::user_types::CubeMap::uriFront_ }, (test_path() / relpath).string()); - commandInterface.set({ cubeMap, &raco::user_types::CubeMap::uriLeft_ }, (test_path() / relpath).string()); - commandInterface.set({ cubeMap, &raco::user_types::CubeMap::uriRight_ }, (test_path() / relpath).string()); - commandInterface.set({ cubeMap, &raco::user_types::CubeMap::uriTop_ }, (test_path() / relpath).string()); + commandInterface.set({ cubeMap, &user_types::CubeMap::uriBack_ }, (test_path() / relpath).string()); + commandInterface.set({ cubeMap, &user_types::CubeMap::uriBottom_ }, (test_path() / relpath).string()); + commandInterface.set({ cubeMap, &user_types::CubeMap::uriFront_ }, (test_path() / relpath).string()); + commandInterface.set({ cubeMap, &user_types::CubeMap::uriLeft_ }, (test_path() / relpath).string()); + commandInterface.set({ cubeMap, &user_types::CubeMap::uriRight_ }, (test_path() / relpath).string()); + commandInterface.set({ cubeMap, &user_types::CubeMap::uriTop_ }, (test_path() / relpath).string()); return cubeMap; } struct struct_prim { + bool bool_val; int int_val; double float_val; std::array vec2f_val; @@ -43,6 +44,7 @@ class MaterialAdaptorTestBase : public RamsesBaseFixture<> { }; static constexpr struct_prim default_struct_prim_values = { + true, 2, 3.0, {0.0, 4.0}, @@ -52,7 +54,8 @@ class MaterialAdaptorTestBase : public RamsesBaseFixture<> { {0, 0, 8}, {0, 0, 0, 9} }; - void setStructComponents(raco::core::ValueHandle uniformContainerHandle, + void setStructComponents(core::ValueHandle uniformContainerHandle, + bool bool_val, int int_val, double float_val, std::array vec2f_val, @@ -61,6 +64,7 @@ class MaterialAdaptorTestBase : public RamsesBaseFixture<> { std::array vec2i_val, std::array vec3i_val, std::array vec4i_val) { + commandInterface.set(uniformContainerHandle.get("b"), bool_val); commandInterface.set(uniformContainerHandle.get("i"), int_val); commandInterface.set(uniformContainerHandle.get("f"), float_val); @@ -73,19 +77,44 @@ class MaterialAdaptorTestBase : public RamsesBaseFixture<> { commandInterface.set(uniformContainerHandle.get("iv4"), vec4i_val); } - void setStructComponents(raco::core::ValueHandle uniformContainerHandle, const struct_prim& values) { - setStructComponents(uniformContainerHandle, values.int_val, values.float_val, + void setStructComponents(core::ValueHandle uniformContainerHandle, const struct_prim& values) { + setStructComponents(uniformContainerHandle, values.bool_val, values.int_val, values.float_val, values.vec2f_val, values.vec3f_val, values.vec4f_val, values.vec2i_val, values.vec3i_val, values.vec4i_val); } - void linkStructComponents(raco::core::ValueHandle startContainer, raco::core::ValueHandle endContainer) { - for (auto prop : { "i", "f", "v2", "v3", "v4", "iv2", "iv3", "iv4" }) { + + void setStructFloatComponents(core::ValueHandle uniformContainerHandle, + double float_val, + std::array vec2f_val, + std::array vec3f_val, + std::array vec4f_val) { + commandInterface.set(uniformContainerHandle.get("f"), float_val); + + commandInterface.set(uniformContainerHandle.get("v2"), std::array({vec2f_val[0], vec2f_val[1]})); + commandInterface.set(uniformContainerHandle.get("v3"), std::array({vec3f_val[0], vec3f_val[1], vec3f_val[2]})); + commandInterface.set(uniformContainerHandle.get("v4"), std::array({vec4f_val[0], vec4f_val[1], vec4f_val[2], vec4f_val[3]})); + } + + void setStructFloatComponents(core::ValueHandle uniformContainerHandle, const struct_prim& values) { + setStructFloatComponents(uniformContainerHandle, values.float_val, + values.vec2f_val, values.vec3f_val, values.vec4f_val); + } + + void linkStructComponents(core::ValueHandle startContainer, core::ValueHandle endContainer) { + for (auto prop : { "b", "i", "f", "v2", "v3", "v4", "iv2", "iv3", "iv4" }) { + commandInterface.addLink(startContainer.get(prop), endContainer.get(prop)); + } + } + + void linkStructIntComponents(core::ValueHandle startContainer, core::ValueHandle endContainer) { + for (auto prop : {"b", "i", "iv2", "iv3", "iv4"}) { commandInterface.addLink(startContainer.get(prop), endContainer.get(prop)); } } void checkStructComponents(const ramses::Appearance* appearance, std::string uniformBaseName, + bool bool_val, int int_val, double float_val, std::array vec2f_val, @@ -94,6 +123,7 @@ class MaterialAdaptorTestBase : public RamsesBaseFixture<> { std::array vec2i_val, std::array vec3i_val, std::array vec4i_val) { + checkUniformScalar(appearance, uniformBaseName + "b", bool_val); checkUniformScalar(appearance, uniformBaseName + "i", int_val); checkUniformScalar(appearance, uniformBaseName + "f", float_val); @@ -107,12 +137,13 @@ class MaterialAdaptorTestBase : public RamsesBaseFixture<> { } void checkStructComponents(const ramses::Appearance* appearance, std::string uniformBaseName, const struct_prim& values) { - checkStructComponents(appearance, uniformBaseName, values.int_val, values.float_val, + checkStructComponents(appearance, uniformBaseName, values.bool_val, values.int_val, values.float_val, values.vec2f_val, values.vec3f_val, values.vec4f_val, values.vec2i_val, values.vec3i_val, values.vec4i_val); } - void checkStructComponents(const raco::core::ValueHandle handle, const ramses::Appearance* appearance, std::string uniformBaseName, + void checkStructComponents(const core::ValueHandle handle, const ramses::Appearance* appearance, std::string uniformBaseName, + bool bool_val, int int_val, double float_val, std::array vec2f_val, @@ -121,6 +152,7 @@ class MaterialAdaptorTestBase : public RamsesBaseFixture<> { std::array vec2i_val, std::array vec3i_val, std::array vec4i_val) { + checkUniformScalar(handle.get("b"), appearance, uniformBaseName + "b", bool_val); checkUniformScalar(handle.get("i"), appearance, uniformBaseName + "i", int_val); checkUniformScalar(handle.get("f"), appearance, uniformBaseName + "f", float_val); @@ -133,8 +165,8 @@ class MaterialAdaptorTestBase : public RamsesBaseFixture<> { checkUniformScalar>(handle.get("iv4"), appearance, uniformBaseName + "iv4", vec4i_val); } - void checkStructComponents(const raco::core::ValueHandle handle, const ramses::Appearance* appearance, std::string uniformBaseName, const struct_prim& values) { - checkStructComponents(handle, appearance, uniformBaseName, values.int_val, values.float_val, + void checkStructComponents(const core::ValueHandle handle, const ramses::Appearance* appearance, std::string uniformBaseName, const struct_prim& values) { + checkStructComponents(handle, appearance, uniformBaseName, values.bool_val, values.int_val, values.float_val, values.vec2f_val, values.vec3f_val, values.vec4f_val, values.vec2i_val, values.vec3i_val, values.vec4i_val); } diff --git a/components/libRamsesBase/tests/MaterialAdaptor_test.cpp b/components/libRamsesBase/tests/MaterialAdaptor_test.cpp index df531be8..44c8bcd2 100644 --- a/components/libRamsesBase/tests/MaterialAdaptor_test.cpp +++ b/components/libRamsesBase/tests/MaterialAdaptor_test.cpp @@ -25,26 +25,26 @@ using namespace raco::user_types; class MaterialAdaptorTest : public MaterialAdaptorTestBase {}; TEST_F(MaterialAdaptorTest, context_scene_effect_name_change) { - auto node = context.createObject(raco::user_types::Material::typeDescription.typeName, "Material Name"); + auto node = context.createObject(user_types::Material::typeDescription.typeName, "Material Name"); dispatch(); - auto effects{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_Effect)}; + auto effects{select(*sceneContext.scene(), ramses::ERamsesObjectType::Effect)}; EXPECT_EQ(effects.size(), 1); ASSERT_TRUE(isRamsesNameInArray("Material Name", effects)); - auto appearances{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_Appearance)}; + auto appearances{select(*sceneContext.scene(), ramses::ERamsesObjectType::Appearance)}; EXPECT_EQ(appearances.size(), 1); ASSERT_TRUE(isRamsesNameInArray("Material Name_Appearance", appearances)); context.set({node, {"objectName"}}, std::string("Changed")); dispatch(); - effects = select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_Effect); - EXPECT_STREQ("Changed", effects[0]->getName()); + effects = select(*sceneContext.scene(), ramses::ERamsesObjectType::Effect); + EXPECT_TRUE("Changed" == effects[0]->getName()); ASSERT_TRUE(isRamsesNameInArray("Changed", effects)); - appearances = select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_Appearance); + appearances = select(*sceneContext.scene(), ramses::ERamsesObjectType::Appearance); EXPECT_EQ(appearances.size(), 1); ASSERT_TRUE(isRamsesNameInArray("Changed_Appearance", appearances)); } @@ -78,6 +78,7 @@ TEST_F(MaterialAdaptorTest, link_get_scalar_uniforms) { TEST_F(MaterialAdaptorTest, set_get_array_uniforms) { auto material = create_material("mat", "shaders/uniform-array.vert", "shaders/uniform-array.frag"); + commandInterface.set({material, {"uniforms", "bvec", "2"}}, true); commandInterface.set({material, {"uniforms", "ivec", "2"}}, 2); commandInterface.set({material, {"uniforms", "fvec", "3"}}, 3.0); @@ -93,6 +94,7 @@ TEST_F(MaterialAdaptorTest, set_get_array_uniforms) { auto appearance{select(*sceneContext.scene(), "mat_Appearance")}; + checkUniformVector(appearance, "bvec", 1, true); checkUniformVector(appearance, "ivec", 1, 2); checkUniformVector(appearance, "fvec", 2, 3.0); @@ -109,8 +111,21 @@ TEST_F(MaterialAdaptorTest, link_get_array_uniforms_components) { auto material = create_material("mat", "shaders/uniform-array.vert", "shaders/uniform-array.frag"); auto lua = create_lua("lua", "scripts/types-scalar.lua"); - link(lua, {"outputs", "ointeger"}, material, {"uniforms", "ivec", "2"}); - link(lua, {"outputs", "ofloat"}, material, {"uniforms", "fvec", "3"}); + commandInterface.set({material, {"uniforms", "bvec", "2"}}, true); + commandInterface.set({material, {"uniforms", "ivec", "2"}}, 2); + commandInterface.set({material, {"uniforms", "fvec", "3"}}, 3.0); + + commandInterface.set({material, {"uniforms", "avec2", "4", "y"}}, 4.0); + commandInterface.set({material, {"uniforms", "avec3", "5", "z"}}, 5.0); + commandInterface.set({material, {"uniforms", "avec4", "6", "w"}}, 6.0); + + commandInterface.set({material, {"uniforms", "aivec2", "4", "i2"}}, 7); + commandInterface.set({material, {"uniforms", "aivec3", "5", "i3"}}, 8); + commandInterface.set({material, {"uniforms", "aivec4", "6", "i4"}}, 9); + + link(lua, {"outputs", "flag"}, material, {"uniforms", "bvec", "1"}); + link(lua, {"outputs", "ointeger"}, material, {"uniforms", "ivec", "1"}); + link(lua, {"outputs", "ofloat"}, material, {"uniforms", "fvec", "2"}); link(lua, {"outputs", "ovector2f"}, material, {"uniforms", "avec2", "3"}); link(lua, {"outputs", "ovector3f"}, material, {"uniforms", "avec3", "3"}); @@ -129,8 +144,23 @@ TEST_F(MaterialAdaptorTest, link_get_array_uniforms_components) { auto appearance{select(*sceneContext.scene(), "mat_Appearance")}; + // non-linked array components + checkUniformVector(appearance, "bvec", 1, true); checkUniformVector(appearance, "ivec", 1, 2); - checkUniformVector(appearance, "fvec", 2, 1.0); + checkUniformVector(appearance, "fvec", 2, 3.0); + + checkUniformVector, 4>(appearance, "avec2", 3, {0.0, 4.0}); + checkUniformVector, 5>(appearance, "avec3", 4, {0.0, 0.0, 5.0}); + checkUniformVector, 6>(appearance, "avec4", 5, {0.0, 0.0, 0.0, 6.0}); + + checkUniformVector, 4>(appearance, "aivec2", 3, {0, 7}); + checkUniformVector, 5>(appearance, "aivec3", 4, {0, 0, 8}); + checkUniformVector, 6>(appearance, "aivec4", 5, {0, 0, 0, 9}); + + // linked array components + checkUniformVector(appearance, "bvec", 0, true); + checkUniformVector(appearance, "ivec", 0, 2); + checkUniformVector(appearance, "fvec", 1, 1.0); checkUniformVector, 4>(appearance, "avec2", 2, {1.0, 2.0}); checkUniformVector, 5>(appearance, "avec3", 2, {1.0, 2.0, 3.0}); @@ -140,11 +170,13 @@ TEST_F(MaterialAdaptorTest, link_get_array_uniforms_components) { checkUniformVector, 5>(appearance, "aivec3", 2, {1, 2, 3}); checkUniformVector, 6>(appearance, "aivec4", 2, {1, 2, 3, 4}); } + TEST_F(MaterialAdaptorTest, link_get_array_uniforms_array) { auto material = create_material("mat", "shaders/uniform-array.vert", "shaders/uniform-array.frag"); auto interface = create_lua_interface("interface", "scripts/uniform-array.lua"); + link(interface, {"inputs", "bvec"}, material, {"uniforms", "bvec"}); link(interface, {"inputs", "ivec"}, material, {"uniforms", "ivec"}); link(interface, {"inputs", "fvec"}, material, {"uniforms", "fvec"}); @@ -156,6 +188,7 @@ TEST_F(MaterialAdaptorTest, link_get_array_uniforms_array) { link(interface, {"inputs", "aivec3"}, material, {"uniforms", "aivec3"}); link(interface, {"inputs", "aivec4"}, material, {"uniforms", "aivec4"}); + commandInterface.set({interface, {"inputs", "bvec", "2"}}, true); commandInterface.set({interface, {"inputs", "ivec", "2"}}, 2); commandInterface.set({interface, {"inputs", "fvec", "3"}}, 3.0); @@ -171,6 +204,7 @@ TEST_F(MaterialAdaptorTest, link_get_array_uniforms_array) { auto appearance{select(*sceneContext.scene(), "mat_Appearance")}; + checkUniformVector(appearance, "bvec", 1, true); checkUniformVector(appearance, "ivec", 1, 2); checkUniformVector(appearance, "fvec", 2, 3.0); @@ -220,11 +254,11 @@ TEST_F(MaterialAdaptorTest, set_get_sampler_external_uniforms) { auto appearance = select(*sceneContext.scene(), "mat_Appearance"); auto engineTexture = select(*sceneContext.scene(), "texture"); - ramses::UniformInput input; const ramses::TextureSamplerExternal* u_sampler_texture; - EXPECT_EQ(ramses::StatusOK, appearance->getEffect().findUniformInput("utex", input)); - EXPECT_EQ(ramses::StatusOK, appearance->getInputTextureExternal(input, u_sampler_texture)); + auto input = appearance->getEffect().findUniformInput("utex"); + ASSERT_TRUE(input.has_value()); + EXPECT_TRUE(appearance->getInputTextureExternal(input.value(), u_sampler_texture)); EXPECT_EQ(u_sampler_texture, engineTexture); } @@ -269,6 +303,21 @@ TEST_F(MaterialAdaptorTest, link_get_struct_prim_uniforms_link_members) { checkStructComponents({material, {"uniforms", "s_prims"}}, appearance, "s_prims.", default_struct_prim_values); } +TEST_F(MaterialAdaptorTest, link_set_mixed_get_struct_prim_uniforms_link_members) { + auto material = create_material("mat", "shaders/uniform-struct.vert", "shaders/uniform-struct.frag"); + auto interface = create_lua_interface("interface", "scripts/uniform-structs.lua"); + + linkStructIntComponents({interface, {"inputs", "s_prims"}}, {material, {"uniforms", "s_prims"}}); + setStructFloatComponents({material, {"uniforms", "s_prims"}}, default_struct_prim_values); + setStructComponents({interface, {"inputs", "s_prims"}}, default_struct_prim_values); + + dispatch(); + + auto appearance{select(*sceneContext.scene(), "mat_Appearance")}; + + checkStructComponents({material, {"uniforms", "s_prims"}}, appearance, "s_prims.", default_struct_prim_values); +} + TEST_F(MaterialAdaptorTest, set_get_struct_sampler_uniforms) { auto material = create_material("mat", "shaders/uniform-struct.vert", "shaders/uniform-struct.frag"); auto texture = create_texture("texture", "images/DuckCM.png"); @@ -392,12 +441,14 @@ TEST_F(MaterialAdaptorTest, link_get_array_struct_prim_uniforms_link_struct) { auto interface = create_lua_interface("interface", "scripts/uniform-structs.lua"); link(interface, {"inputs", "s_prims"}, material, {"uniforms", "a_s_prims", "2"}); + setStructComponents({material, {"uniforms", "a_s_prims", "1"}}, default_struct_prim_values); setStructComponents({interface, {"inputs", "s_prims"}}, default_struct_prim_values); dispatch(); auto appearance{select(*sceneContext.scene(), "mat_Appearance")}; + checkStructComponents({material, {"uniforms", "a_s_prims", "1"}}, appearance, "a_s_prims[0].", default_struct_prim_values); checkStructComponents({material, {"uniforms", "a_s_prims", "2"}}, appearance, "a_s_prims[1].", default_struct_prim_values); } @@ -444,6 +495,7 @@ TEST_F(MaterialAdaptorTest, set_get_array_struct_sampler_uniforms) { TEST_F(MaterialAdaptorTest, set_get_struct_of_array_of_prim_uniforms) { auto material = create_material("mat", "shaders/uniform-struct.vert", "shaders/uniform-struct.frag"); + commandInterface.set({material, {"uniforms", "s_a_prims", "bvec", "2"}}, true); commandInterface.set({material, {"uniforms", "s_a_prims", "ivec", "2"}}, 2); commandInterface.set({material, {"uniforms", "s_a_prims", "fvec", "3"}}, 3.0); @@ -459,6 +511,7 @@ TEST_F(MaterialAdaptorTest, set_get_struct_of_array_of_prim_uniforms) { auto appearance{select(*sceneContext.scene(), "mat_Appearance")}; + checkUniformVector(appearance, "s_a_prims.bvec", 1, true); checkUniformVector(appearance, "s_a_prims.ivec", 1, 2); checkUniformVector(appearance, "s_a_prims.fvec", 2, 3.0); diff --git a/components/libRamsesBase/tests/MeshAdaptor_test.cpp b/components/libRamsesBase/tests/MeshAdaptor_test.cpp index 7d43d58e..b79a65b7 100644 --- a/components/libRamsesBase/tests/MeshAdaptor_test.cpp +++ b/components/libRamsesBase/tests/MeshAdaptor_test.cpp @@ -16,12 +16,12 @@ class MeshAdaptorTest : public RamsesBaseFixture<> {}; TEST_F(MeshAdaptorTest, context_mesh_name_change) { - auto node = context.createObject(raco::user_types::Mesh::typeDescription.typeName, "Mesh Name"); + auto node = context.createObject(user_types::Mesh::typeDescription.typeName, "Mesh Name"); context.set({node, {"uri"}}, test_path().append("meshes/Duck.glb").string()); dispatch(); - auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_ArrayResource)}; + auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ArrayResource)}; EXPECT_EQ(meshStuff.size(), 4); ASSERT_TRUE(isRamsesNameInArray("Mesh Name_MeshIndexData", meshStuff)); ASSERT_TRUE(isRamsesNameInArray("Mesh Name_MeshVertexData_a_Position", meshStuff)); @@ -31,7 +31,7 @@ TEST_F(MeshAdaptorTest, context_mesh_name_change) { context.set({node, {"objectName"}}, std::string("Changed")); dispatch(); - meshStuff = select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_ArrayResource); + meshStuff = select(*sceneContext.scene(), ramses::ERamsesObjectType::ArrayResource); EXPECT_EQ(meshStuff.size(), 4); ASSERT_TRUE(isRamsesNameInArray("Changed_MeshIndexData", meshStuff)); ASSERT_TRUE(isRamsesNameInArray("Changed_MeshVertexData_a_Position", meshStuff)); @@ -40,40 +40,40 @@ TEST_F(MeshAdaptorTest, context_mesh_name_change) { } TEST_F(MeshAdaptorTest, gltf_without_meshes) { - auto mesh = context.createObject(raco::user_types::Mesh::typeDescription.typeName, "Mesh Name"); - context.set({mesh, &raco::user_types::Mesh::uri_}, test_path().append("meshes/meshless.gltf").string()); + auto mesh = context.createObject(user_types::Mesh::typeDescription.typeName, "Mesh Name"); + context.set({mesh, &user_types::Mesh::uri_}, test_path().append("meshes/meshless.gltf").string()); dispatch(); - auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_ArrayResource)}; + auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ArrayResource)}; EXPECT_EQ(meshStuff.size(), 0); } TEST_F(MeshAdaptorTest, gltf_with_meshes_but_no_mesh_refs_baked) { - auto mesh = context.createObject(raco::user_types::Mesh::typeDescription.typeName, "Mesh Name"); - context.set({mesh, &raco::user_types::Mesh::bakeMeshes_}, true); - context.set({mesh, &raco::user_types::Mesh::uri_}, test_path().append("meshes/meshrefless.gltf").string()); + auto mesh = context.createObject(user_types::Mesh::typeDescription.typeName, "Mesh Name"); + context.set({mesh, &user_types::Mesh::bakeMeshes_}, true); + context.set({mesh, &user_types::Mesh::uri_}, test_path().append("meshes/meshrefless.gltf").string()); dispatch(); - auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_ArrayResource)}; + auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ArrayResource)}; EXPECT_EQ(meshStuff.size(), 0); - ASSERT_EQ(context.errors().getError(mesh).level(), raco::core::ErrorLevel::ERROR); + ASSERT_EQ(context.errors().getError(mesh).level(), core::ErrorLevel::ERROR); } TEST_F(MeshAdaptorTest, gltf_with_meshes_but_no_mesh_refs_unbaked) { - auto mesh = context.createObject(raco::user_types::Mesh::typeDescription.typeName, "Mesh Name"); - context.set({mesh, &raco::user_types::Mesh::bakeMeshes_}, false); - context.set({mesh, &raco::user_types::Mesh::uri_}, test_path().append("meshes/meshrefless.gltf").string()); + auto mesh = context.createObject(user_types::Mesh::typeDescription.typeName, "Mesh Name"); + context.set({mesh, &user_types::Mesh::bakeMeshes_}, false); + context.set({mesh, &user_types::Mesh::uri_}, test_path().append("meshes/meshrefless.gltf").string()); dispatch(); - auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_ArrayResource)}; + auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ArrayResource)}; EXPECT_EQ(meshStuff.size(), 4); ASSERT_TRUE(isRamsesNameInArray("Mesh Name_MeshIndexData", meshStuff)); ASSERT_TRUE(isRamsesNameInArray("Mesh Name_MeshVertexData_a_Position", meshStuff)); ASSERT_TRUE(isRamsesNameInArray("Mesh Name_MeshVertexData_a_Normal", meshStuff)); ASSERT_TRUE(isRamsesNameInArray("Mesh Name_MeshVertexData_a_TextureCoordinate", meshStuff)); - ASSERT_EQ(context.errors().getError(mesh).level(), raco::core::ErrorLevel::INFORMATION); + ASSERT_EQ(context.errors().getError(mesh).level(), core::ErrorLevel::INFORMATION); } \ No newline at end of file diff --git a/components/libRamsesBase/tests/MeshNodeAdaptor_test.cpp b/components/libRamsesBase/tests/MeshNodeAdaptor_test.cpp index cb7aae6e..03a79437 100644 --- a/components/libRamsesBase/tests/MeshNodeAdaptor_test.cpp +++ b/components/libRamsesBase/tests/MeshNodeAdaptor_test.cpp @@ -14,20 +14,21 @@ #include "AdaptorTestUtils.h" #include "MaterialAdaptorTestBase.h" +#include "ramses_adaptor/DefaultRamsesObjects.h" #include "ramses_adaptor/MeshNodeAdaptor.h" #include "ramses_adaptor/SceneAdaptor.h" #include "ramses_adaptor/utilities.h" #include "user_types/RenderBufferMS.h" using namespace raco; -using raco::ramses_adaptor::MeshNodeAdaptor; -using raco::ramses_adaptor::SceneAdaptor; -using raco::user_types::Material; -using raco::user_types::Mesh; -using raco::user_types::MeshNode; -using raco::user_types::RenderBufferMS; -using raco::user_types::SMeshNode; -using raco::user_types::ValueHandle; +using ramses_adaptor::MeshNodeAdaptor; +using ramses_adaptor::SceneAdaptor; +using user_types::Material; +using user_types::Mesh; +using user_types::MeshNode; +using user_types::RenderBufferMS; +using user_types::SMeshNode; +using user_types::ValueHandle; class MeshNodeAdaptorFixture : public MaterialAdaptorTestBase { protected: @@ -43,33 +44,33 @@ class MeshNodeAdaptorFixture : public MaterialAdaptorTestBase { } dispatch(); - auto selectedMeshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_MeshNode)}; - auto geometryBindings{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_GeometryBinding)}; - auto effects{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_Effect)}; - auto appearances{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_Appearance)}; + auto selectedMeshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::MeshNode)}; + auto geometrys{select(*sceneContext.scene(), ramses::ERamsesObjectType::Geometry)}; + auto effects{select(*sceneContext.scene(), ramses::ERamsesObjectType::Effect)}; + auto appearances{select(*sceneContext.scene(), ramses::ERamsesObjectType::Appearance)}; EXPECT_EQ(selectedMeshNodes.size(), MESH_NODE_AMOUNT); - EXPECT_EQ(geometryBindings.size(), MESH_NODE_AMOUNT); + EXPECT_EQ(geometrys.size(), MESH_NODE_AMOUNT); EXPECT_EQ(effects.size(), 1); EXPECT_EQ(appearances.size(), private_material ? MESH_NODE_AMOUNT + 1 : 1); for (int i = 0; i < MESH_NODE_AMOUNT; ++i) { auto ramsesMeshNode = select(*sceneContext.scene(), std::to_string(i).c_str()); - EXPECT_STREQ(std::to_string(i).c_str(), ramsesMeshNode->getName()); + EXPECT_TRUE(std::to_string(i).c_str() == ramsesMeshNode->getName()); EXPECT_TRUE(ramsesMeshNode->getAppearance() != nullptr); if (private_material) { - EXPECT_STREQ((std::to_string(i) + "_Appearance").c_str(), ramsesMeshNode->getAppearance()->getName()); + EXPECT_TRUE((std::to_string(i) + "_Appearance").c_str() == ramsesMeshNode->getAppearance()->getName()); - auto appearanceBinding = select(sceneContext.logicEngine(), std::to_string(i).append("_AppearanceBinding").c_str()); + auto appearanceBinding = select(sceneContext.logicEngine(), std::to_string(i).append("_AppearanceBinding").c_str()); EXPECT_EQ(appearanceBinding->getUserId(), meshNodes[i]->objectIDAsRamsesLogicID()); } else { - EXPECT_STREQ("Material_Appearance", ramsesMeshNode->getAppearance()->getName()); + EXPECT_TRUE("Material_Appearance" == ramsesMeshNode->getAppearance()->getName()); - auto appearanceBinding = select(sceneContext.logicEngine(), "Material_AppearanceBinding"); + auto appearanceBinding = select(sceneContext.logicEngine(), "Material_AppearanceBinding"); EXPECT_EQ(appearanceBinding->getUserId(), material->objectIDAsRamsesLogicID()); } - EXPECT_STREQ("Material", ramsesMeshNode->getAppearance()->getEffect().getName()); - EXPECT_TRUE(ramsesMeshNode->getGeometryBinding() != nullptr); + EXPECT_TRUE("Material" == ramsesMeshNode->getAppearance()->getEffect().getName()); + EXPECT_TRUE(ramsesMeshNode->getGeometry() != nullptr); } } }; @@ -78,12 +79,12 @@ TEST_F(MeshNodeAdaptorFixture, inContext_userType_MeshNode_constructs_ramsesMesh auto meshNode = context.createObject(MeshNode::typeDescription.typeName, "MeshNode Name"); dispatch(); - auto meshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_MeshNode)}; + auto meshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::MeshNode)}; EXPECT_EQ(meshNodes.size(), 1); EXPECT_TRUE(meshNodes[0]->getAppearance() != nullptr); - EXPECT_TRUE(meshNodes[0]->getGeometryBinding() != nullptr); - EXPECT_STREQ("MeshNode Name", meshNodes[0]->getName()); + EXPECT_TRUE(meshNodes[0]->getGeometry() != nullptr); + EXPECT_TRUE("MeshNode Name" == meshNodes[0]->getName()); } TEST_F(MeshNodeAdaptorFixture, inContext_userType_MeshNode_name_change) { @@ -91,20 +92,20 @@ TEST_F(MeshNodeAdaptorFixture, inContext_userType_MeshNode_name_change) { dispatch(); - auto meshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_MeshNode)}; + auto meshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::MeshNode)}; EXPECT_EQ(meshNodes.size(), 1); EXPECT_TRUE(meshNodes[0]->getAppearance() != nullptr); - EXPECT_TRUE(meshNodes[0]->getGeometryBinding() != nullptr); - EXPECT_STREQ("MeshNode Name", meshNodes[0]->getName()); - EXPECT_STREQ(raco::ramses_adaptor::defaultAppearanceName, meshNodes[0]->getAppearance()->getName()); + EXPECT_TRUE(meshNodes[0]->getGeometry() != nullptr); + EXPECT_TRUE("MeshNode Name" == meshNodes[0]->getName()); + EXPECT_TRUE(ramses_adaptor::defaultAppearanceWithNormalsName == meshNodes[0]->getAppearance()->getName()); context.set({meshNode, {"objectName"}}, std::string("Changed")); dispatch(); - EXPECT_STREQ("Changed", meshNodes[0]->getName()); - EXPECT_STREQ(raco::ramses_adaptor::defaultAppearanceName, meshNodes[0]->getAppearance()->getName()); - EXPECT_STREQ("Changed_GeometryBinding", meshNodes[0]->getGeometryBinding()->getName()); + EXPECT_TRUE("Changed" == meshNodes[0]->getName()); + EXPECT_TRUE(ramses_adaptor::defaultAppearanceWithNormalsName == meshNodes[0]->getAppearance()->getName()); + EXPECT_TRUE("Changed_Geometry" == meshNodes[0]->getGeometry()->getName()); } TEST_F(MeshNodeAdaptorFixture, inContext_userType_MeshNode_withEmptyMesh_constructs_ramsesMeshNode) { @@ -113,13 +114,13 @@ TEST_F(MeshNodeAdaptorFixture, inContext_userType_MeshNode_withEmptyMesh_constru context.set(ValueHandle{meshNode}.get("mesh"), mesh); dispatch(); - auto meshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_MeshNode)}; - auto geometryBindings{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_GeometryBinding)}; + auto meshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::MeshNode)}; + auto geometrys{select(*sceneContext.scene(), ramses::ERamsesObjectType::Geometry)}; EXPECT_EQ(meshNodes.size(), 1); EXPECT_TRUE(meshNodes[0]->getAppearance() != nullptr); - EXPECT_TRUE(meshNodes[0]->getGeometryBinding() != nullptr); - EXPECT_STREQ("MeshNode Name", meshNodes[0]->getName()); + EXPECT_TRUE(meshNodes[0]->getGeometry() != nullptr); + EXPECT_TRUE("MeshNode Name" == meshNodes[0]->getName()); } TEST_F(MeshNodeAdaptorFixture, inContext_userType_MeshNode_withEmptyMesh_createdAfterMeshNode_constructs_ramsesMeshNode) { @@ -128,13 +129,13 @@ TEST_F(MeshNodeAdaptorFixture, inContext_userType_MeshNode_withEmptyMesh_created context.set(ValueHandle{meshNode}.get("mesh"), mesh); dispatch(); - auto meshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_MeshNode)}; - auto geometryBindings{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_GeometryBinding)}; + auto meshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::MeshNode)}; + auto geometrys{select(*sceneContext.scene(), ramses::ERamsesObjectType::Geometry)}; EXPECT_EQ(meshNodes.size(), 1); EXPECT_TRUE(meshNodes[0]->getAppearance() != nullptr); - EXPECT_TRUE(meshNodes[0]->getGeometryBinding() != nullptr); - EXPECT_STREQ("MeshNode Name", meshNodes[0]->getName()); + EXPECT_TRUE(meshNodes[0]->getGeometry() != nullptr); + EXPECT_TRUE("MeshNode Name" == meshNodes[0]->getName()); } TEST_F(MeshNodeAdaptorFixture, inContext_userType_MeshNode_withEmptyMaterial_constructs_ramsesMeshNode) { @@ -143,17 +144,17 @@ TEST_F(MeshNodeAdaptorFixture, inContext_userType_MeshNode_withEmptyMaterial_con auto meshnode = create_meshnode("MeshNode", mesh, material); dispatch(); - auto meshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_MeshNode)}; - auto geometryBindings{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_GeometryBinding)}; + auto meshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::MeshNode)}; + auto geometrys{select(*sceneContext.scene(), ramses::ERamsesObjectType::Geometry)}; EXPECT_EQ(meshNodes.size(), 1); - EXPECT_EQ(geometryBindings.size(), 1); + EXPECT_EQ(geometrys.size(), 1); auto ramsesMeshNode = select(*sceneContext.scene(), "MeshNode"); EXPECT_TRUE(ramsesMeshNode->getAppearance() != nullptr); - EXPECT_STREQ(raco::ramses_adaptor::defaultAppearanceWithNormalsName, ramsesMeshNode->getAppearance()->getName()); - EXPECT_STREQ(raco::ramses_adaptor::defaultEffectWithNormalsName, ramsesMeshNode->getAppearance()->getEffect().getName()); - EXPECT_TRUE(ramsesMeshNode->getGeometryBinding() != nullptr); - EXPECT_STREQ("MeshNode", ramsesMeshNode->getName()); + EXPECT_TRUE(ramses_adaptor::defaultAppearanceWithNormalsName == ramsesMeshNode->getAppearance()->getName()); + EXPECT_TRUE(ramses_adaptor::defaultEffectWithNormalsName == ramsesMeshNode->getAppearance()->getEffect().getName()); + EXPECT_TRUE(ramsesMeshNode->getGeometry() != nullptr); + EXPECT_TRUE("MeshNode" == ramsesMeshNode->getName()); } TEST_F(MeshNodeAdaptorFixture, inContext_userType_MeshNode_withMaterial_constructs_ramsesMeshNode) { @@ -174,7 +175,7 @@ TEST_F(MeshNodeAdaptorFixture, inContext_userType_ten_MeshNodes_withSameMaterial TEST_F(MeshNodeAdaptorFixture, inContext_userType_ten_MeshNodes_withSameMaterial_andSameMesh_propertyUnsetting) { constexpr auto MESH_NODE_AMOUNT = 10; - std::array meshNodes; + std::array meshNodes; auto material = create("Material"); auto mesh = create_mesh("Mesh", "meshes/Duck.glb"); @@ -189,14 +190,14 @@ TEST_F(MeshNodeAdaptorFixture, inContext_userType_ten_MeshNodes_withSameMaterial context.deleteObjects({mesh, material}); dispatch(); - auto selectedMeshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_MeshNode)}; - auto geometryBindings{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_GeometryBinding)}; + auto selectedMeshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::MeshNode)}; + auto geometrys{select(*sceneContext.scene(), ramses::ERamsesObjectType::Geometry)}; EXPECT_EQ(selectedMeshNodes.size(), MESH_NODE_AMOUNT); - EXPECT_EQ(geometryBindings.size(), MESH_NODE_AMOUNT); + EXPECT_EQ(geometrys.size(), MESH_NODE_AMOUNT); for (int i = 0; i < MESH_NODE_AMOUNT; ++i) { auto ramsesMeshNode = select(*sceneContext.scene(), std::to_string(i).c_str()); - EXPECT_STREQ(raco::ramses_adaptor::defaultEffectName, ramsesMeshNode->getAppearance()->getEffect().getName()); + EXPECT_TRUE(ramses_adaptor::defaultEffectWithNormalsName == ramsesMeshNode->getAppearance()->getEffect().getName()); // TODO: Compare Ramses mesh with default sceneAdaptor mesh here } } @@ -211,23 +212,23 @@ TEST_F(MeshNodeAdaptorFixture, inContext_userType_MeshNode_dynamicMaterial_const // precondition { auto ramsesMeshNode = select(*sceneContext.scene(), "MeshNode"); - EXPECT_STREQ(raco::ramses_adaptor::defaultEffectWithNormalsName, ramsesMeshNode->getAppearance()->getEffect().getName()); + EXPECT_TRUE(ramses_adaptor::defaultEffectWithNormalsName == ramsesMeshNode->getAppearance()->getEffect().getName()); } context.set({material, {"uriVertex"}}, test_path().append("shaders/basic.vert").string()); context.set({material, {"uriFragment"}}, test_path().append("shaders/basic.frag").string()); dispatch(); - auto meshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_MeshNode)}; - auto geometryBindings{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_GeometryBinding)}; + auto meshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::MeshNode)}; + auto geometrys{select(*sceneContext.scene(), ramses::ERamsesObjectType::Geometry)}; EXPECT_EQ(meshNodes.size(), 1); - EXPECT_EQ(geometryBindings.size(), 1); + EXPECT_EQ(geometrys.size(), 1); auto ramsesMeshNode = select(*sceneContext.scene(), "MeshNode"); EXPECT_TRUE(ramsesMeshNode->getAppearance() != nullptr); - EXPECT_STREQ("Material", ramsesMeshNode->getAppearance()->getEffect().getName()); - EXPECT_TRUE(ramsesMeshNode->getGeometryBinding() != nullptr); - EXPECT_STREQ("MeshNode", ramsesMeshNode->getName()); + EXPECT_TRUE("Material" == ramsesMeshNode->getAppearance()->getEffect().getName()); + EXPECT_TRUE(ramsesMeshNode->getGeometry() != nullptr); + EXPECT_TRUE("MeshNode" == ramsesMeshNode->getName()); } TEST_F(MeshNodeAdaptorFixture, meshnode_switch_mat_shared_to_private) { @@ -239,15 +240,15 @@ TEST_F(MeshNodeAdaptorFixture, meshnode_switch_mat_shared_to_private) { auto ramsesMeshNode = select(*sceneContext.scene(), "MeshNode"); EXPECT_TRUE(ramsesMeshNode->getAppearance() != nullptr); - EXPECT_STREQ("Material_Appearance", ramsesMeshNode->getAppearance()->getName()); - EXPECT_STREQ("Material", ramsesMeshNode->getAppearance()->getEffect().getName()); + EXPECT_TRUE("Material_Appearance" == ramsesMeshNode->getAppearance()->getName()); + EXPECT_TRUE("Material" == ramsesMeshNode->getAppearance()->getEffect().getName()); context.set(meshnode->getMaterialPrivateHandle(0), true); dispatch(); EXPECT_TRUE(ramsesMeshNode->getAppearance() != nullptr); - EXPECT_STREQ("MeshNode_Appearance", ramsesMeshNode->getAppearance()->getName()); - EXPECT_STREQ("Material", ramsesMeshNode->getAppearance()->getEffect().getName()); + EXPECT_TRUE("MeshNode_Appearance" == ramsesMeshNode->getAppearance()->getName()); + EXPECT_TRUE("Material" == ramsesMeshNode->getAppearance()->getEffect().getName()); } TEST_F(MeshNodeAdaptorFixture, meshnode_shared_material_is_unique) { @@ -278,14 +279,14 @@ TEST_F(MeshNodeAdaptorFixture, meshnode_set_depthwrite_mat_private) { auto ramsesMeshNode = select(*sceneContext.scene(), "MeshNode"); EXPECT_TRUE(ramsesMeshNode->getAppearance() != nullptr); - EXPECT_EQ(ramses::EDepthWrite_Enabled, raco::ramses_adaptor::getDepthWriteMode(ramsesMeshNode->getAppearance())); + EXPECT_EQ(ramses::EDepthWrite::Enabled, ramses_adaptor::getDepthWriteMode(ramsesMeshNode->getAppearance())); context.set(meshNode->getMaterialOptionsHandle(0).get("depthwrite"), false); dispatch(); ramsesMeshNode = select(*sceneContext.scene(), "MeshNode"); EXPECT_TRUE(ramsesMeshNode->getAppearance() != nullptr); - EXPECT_EQ(ramses::EDepthWrite_Disabled, raco::ramses_adaptor::getDepthWriteMode(ramsesMeshNode->getAppearance())); + EXPECT_EQ(ramses::EDepthWrite::Disabled, ramses_adaptor::getDepthWriteMode(ramsesMeshNode->getAppearance())); } TEST_F(MeshNodeAdaptorFixture, meshnode_set_depthwrite_mat_shared) { @@ -298,14 +299,14 @@ TEST_F(MeshNodeAdaptorFixture, meshnode_set_depthwrite_mat_shared) { auto ramsesMeshNode = select(*sceneContext.scene(), "MeshNode"); EXPECT_TRUE(ramsesMeshNode->getAppearance() != nullptr); - EXPECT_EQ(ramses::EDepthWrite_Enabled, raco::ramses_adaptor::getDepthWriteMode(ramsesMeshNode->getAppearance())); + EXPECT_EQ(ramses::EDepthWrite::Enabled, ramses_adaptor::getDepthWriteMode(ramsesMeshNode->getAppearance())); context.set({material, {"options", "depthwrite"}}, false); dispatch(); ramsesMeshNode = select(*sceneContext.scene(), "MeshNode"); EXPECT_TRUE(ramsesMeshNode->getAppearance() != nullptr); - EXPECT_EQ(ramses::EDepthWrite_Disabled, raco::ramses_adaptor::getDepthWriteMode(ramsesMeshNode->getAppearance())); + EXPECT_EQ(ramses::EDepthWrite::Disabled, ramses_adaptor::getDepthWriteMode(ramsesMeshNode->getAppearance())); } TEST_F(MeshNodeAdaptorFixture, inContext_userType_MeshNode_materialReset_and_depthWriteDisable) { @@ -318,15 +319,15 @@ TEST_F(MeshNodeAdaptorFixture, inContext_userType_MeshNode_materialReset_and_dep auto ramsesMeshNode = select(*sceneContext.scene(), "MeshNode"); EXPECT_TRUE(ramsesMeshNode->getAppearance() != nullptr); - EXPECT_EQ(ramses::EDepthWrite_Disabled, raco::ramses_adaptor::getDepthWriteMode(ramsesMeshNode->getAppearance())); + EXPECT_EQ(ramses::EDepthWrite::Disabled, ramses_adaptor::getDepthWriteMode(ramsesMeshNode->getAppearance())); context.set(ValueHandle{meshNode}.get("materials")[0].get("material"), core::SEditorObject{}); dispatch(); ramsesMeshNode = select(*sceneContext.scene(), "MeshNode"); EXPECT_TRUE(ramsesMeshNode->getAppearance() != nullptr); - EXPECT_STREQ(raco::ramses_adaptor::defaultEffectWithNormalsName, ramsesMeshNode->getAppearance()->getEffect().getName()); - EXPECT_EQ(ramses::EDepthWrite_Enabled, raco::ramses_adaptor::getDepthWriteMode(ramsesMeshNode->getAppearance())); + EXPECT_TRUE(ramses_adaptor::defaultEffectWithNormalsName == ramsesMeshNode->getAppearance()->getEffect().getName()); + EXPECT_EQ(ramses::EDepthWrite::Enabled, ramses_adaptor::getDepthWriteMode(ramsesMeshNode->getAppearance())); } TEST_F(MeshNodeAdaptorFixture, inContext_userType_MeshNode_multiSampledMaterial_invalidNoCrash) { @@ -452,6 +453,7 @@ TEST_F(MeshNodeAdaptorFixture, set_get_array_uniforms) { context.set(meshnode->getMaterialPrivateHandle(0), true); + commandInterface.set({meshnode, {"materials", "material", "uniforms", "bvec", "2"}}, true); commandInterface.set({meshnode, {"materials", "material", "uniforms", "ivec", "2"}}, 2); commandInterface.set({meshnode, {"materials", "material", "uniforms", "fvec", "3"}}, 3.0); @@ -469,6 +471,7 @@ TEST_F(MeshNodeAdaptorFixture, set_get_array_uniforms) { auto appearance{select(*sceneContext.scene(), "meshnode_Appearance")}; EXPECT_NE(mat_appearance, appearance); + checkUniformVector(appearance, "bvec", 1, true); checkUniformVector(appearance, "ivec", 1, 2); checkUniformVector(appearance, "fvec", 2, 3.0); @@ -481,6 +484,78 @@ TEST_F(MeshNodeAdaptorFixture, set_get_array_uniforms) { checkUniformVector, 6>(appearance, "aivec4", 5, {0, 0, 0, 9}); } + +TEST_F(MeshNodeAdaptorFixture, link_get_array_uniforms) { + auto mesh = create_mesh("mesh", "meshes/Duck.glb"); + auto material = create_material("mat", "shaders/uniform-array.vert", "shaders/uniform-array.frag"); + auto meshnode = create_meshnode("meshnode", mesh, material); + auto lua = create_lua("lua", "scripts/types-scalar.lua"); + + context.set(meshnode->getMaterialPrivateHandle(0), true); + + commandInterface.set({meshnode, {"materials", "material", "uniforms", "bvec", "2"}}, true); + commandInterface.set({meshnode, {"materials", "material", "uniforms", "ivec", "2"}}, 2); + commandInterface.set({meshnode, {"materials", "material", "uniforms", "fvec", "3"}}, 3.0); + + commandInterface.set({meshnode, {"materials", "material", "uniforms", "avec2", "4", "y"}}, 4.0); + commandInterface.set({meshnode, {"materials", "material", "uniforms", "avec3", "5", "z"}}, 5.0); + commandInterface.set({meshnode, {"materials", "material", "uniforms", "avec4", "6", "w"}}, 6.0); + + commandInterface.set({meshnode, {"materials", "material", "uniforms", "aivec2", "4", "i2"}}, 7); + commandInterface.set({meshnode, {"materials", "material", "uniforms", "aivec3", "5", "i3"}}, 8); + commandInterface.set({meshnode, {"materials", "material", "uniforms", "aivec4", "6", "i4"}}, 9); + + link(lua, {"outputs", "flag"}, meshnode, {"materials", "material", "uniforms", "bvec", "1"}); + link(lua, {"outputs", "ointeger"}, meshnode, {"materials", "material", "uniforms", "ivec", "1"}); + link(lua, {"outputs", "ofloat"}, meshnode, {"materials", "material", "uniforms", "fvec", "2"}); + + link(lua, {"outputs", "ovector2f"}, meshnode, {"materials", "material", "uniforms", "avec2", "3"}); + link(lua, {"outputs", "ovector3f"}, meshnode, {"materials", "material", "uniforms", "avec3", "3"}); + link(lua, {"outputs", "ovector4f"}, meshnode, {"materials", "material", "uniforms", "avec4", "3"}); + + link(lua, {"outputs", "ovector2i"}, meshnode, {"materials", "material", "uniforms", "aivec2", "3"}); + link(lua, {"outputs", "ovector3i"}, meshnode, {"materials", "material", "uniforms", "aivec3", "3"}); + link(lua, {"outputs", "ovector4i"}, meshnode, {"materials", "material", "uniforms", "aivec4", "3"}); + + dispatch(); + + commandInterface.set({lua, {"inputs", "integer"}}, 1); + commandInterface.set({lua, {"inputs", "float"}}, 1.0); + + dispatch(); + + auto mat_appearance{select(*sceneContext.scene(), "mat_Appearance")}; + auto appearance{select(*sceneContext.scene(), "meshnode_Appearance")}; + EXPECT_NE(mat_appearance, appearance); + + // non-linked array components + checkUniformVector(appearance, "bvec", 1, true); + checkUniformVector(appearance, "ivec", 1, 2); + checkUniformVector(appearance, "fvec", 2, 3.0); + + checkUniformVector, 4>(appearance, "avec2", 3, {0.0, 4.0}); + checkUniformVector, 5>(appearance, "avec3", 4, {0.0, 0.0, 5.0}); + checkUniformVector, 6>(appearance, "avec4", 5, {0.0, 0.0, 0.0, 6.0}); + + checkUniformVector, 4>(appearance, "aivec2", 3, {0, 7}); + checkUniformVector, 5>(appearance, "aivec3", 4, {0, 0, 8}); + checkUniformVector, 6>(appearance, "aivec4", 5, {0, 0, 0, 9}); + + // linked array components + checkUniformVector(appearance, "bvec", 0, true); + checkUniformVector(appearance, "ivec", 0, 2); + checkUniformVector(appearance, "fvec", 1, 1.0); + + checkUniformVector, 4>(appearance, "avec2", 2, {1.0, 2.0}); + checkUniformVector, 5>(appearance, "avec3", 2, {1.0, 2.0, 3.0}); + checkUniformVector, 6>(appearance, "avec4", 2, {1.0, 2.0, 3.0, 4.0}); + + checkUniformVector, 4>(appearance, "aivec2", 2, {1, 2}); + checkUniformVector, 5>(appearance, "aivec3", 2, {1, 2, 3}); + checkUniformVector, 6>(appearance, "aivec4", 2, {1, 2, 3, 4}); +} + + TEST_F(MeshNodeAdaptorFixture, set_get_struct_prim_uniforms) { auto mesh = create_mesh("mesh", "meshes/Duck.glb"); auto material = create_material("mat", "shaders/uniform-struct.vert", "shaders/uniform-struct.frag"); @@ -539,6 +614,27 @@ TEST_F(MeshNodeAdaptorFixture, link_get_struct_prim_uniforms_members) { checkStructComponents({meshnode, {"materials", "material", "uniforms", "s_prims"}}, appearance, "s_prims.", default_struct_prim_values); } +TEST_F(MeshNodeAdaptorFixture, link_set_mixed_get_struct_prim_uniforms_members) { + auto mesh = create_mesh("mesh", "meshes/Duck.glb"); + auto material = create_material("mat", "shaders/uniform-struct.vert", "shaders/uniform-struct.frag"); + auto meshnode = create_meshnode("meshnode", mesh, material); + auto interface = create_lua_interface("interface", "scripts/uniform-structs.lua"); + + context.set(meshnode->getMaterialPrivateHandle(0), true); + + linkStructIntComponents({interface, {"inputs", "s_prims"}}, {meshnode, {"materials", "material", "uniforms", "s_prims"}}); + setStructFloatComponents({meshnode, {"materials", "material", "uniforms", "s_prims"}}, default_struct_prim_values); + setStructComponents({interface, {"inputs", "s_prims"}}, default_struct_prim_values); + + dispatch(); + + auto mat_appearance{select(*sceneContext.scene(), "mat_Appearance")}; + auto appearance{select(*sceneContext.scene(), "meshnode_Appearance")}; + EXPECT_NE(mat_appearance, appearance); + + checkStructComponents({meshnode, {"materials", "material", "uniforms", "s_prims"}}, appearance, "s_prims.", default_struct_prim_values); +} + TEST_F(MeshNodeAdaptorFixture, set_get_array_struct_prim_uniforms) { auto mesh = create_mesh("mesh", "meshes/Duck.glb"); auto material = create_material("mat", "shaders/uniform-struct.vert", "shaders/uniform-struct.frag"); diff --git a/components/libRamsesBase/tests/NodeAdaptor_test.cpp b/components/libRamsesBase/tests/NodeAdaptor_test.cpp index 3d5a9bab..62ccab34 100644 --- a/components/libRamsesBase/tests/NodeAdaptor_test.cpp +++ b/components/libRamsesBase/tests/NodeAdaptor_test.cpp @@ -14,10 +14,10 @@ #include "user_types/Node.h" using namespace raco; -using raco::ramses_adaptor::NodeAdaptor; -using raco::user_types::Node; -using raco::user_types::SNode; -using raco::core::ValueHandle; +using ramses_adaptor::NodeAdaptor; +using user_types::Node; +using user_types::SNode; +using core::ValueHandle; class NodeAdaptorTest : public RamsesBaseFixture<> {}; @@ -32,9 +32,7 @@ TEST_F(NodeAdaptorTest, constructor_sets_RamsesObject_name) { SNode node{new Node{name}}; NodeAdaptor adaptor{&sceneContext, node}; - const char* ramsesObjectName = adaptor.ramsesObject().getName(); - EXPECT_EQ(sizeof(ramsesObjectName), sizeof(name)); - EXPECT_TRUE(0 == std::memcmp(ramsesObjectName, name, sizeof(ramsesObjectName))); + EXPECT_TRUE(adaptor.ramsesObject().getName() == name); } TEST_F(NodeAdaptorTest, onDataChange_updatesTranslation) { @@ -43,12 +41,8 @@ TEST_F(NodeAdaptorTest, onDataChange_updatesTranslation) { dispatch(); - auto engineNode{select(*sceneContext.scene(), "SomeName")}; - float x, y, z; - engineNode->getTranslation(x, y, z); - EXPECT_EQ(x, 1.0f); - EXPECT_EQ(y, 0.0f); - EXPECT_EQ(z, 0.0f); + auto engineNode{select(*sceneContext.scene(), "SomeName")}; + EXPECT_EQ(ramses_adaptor::getRamsesTranslation(engineNode), glm::vec3(1.0, 0.0, 0.0)); } @@ -57,15 +51,15 @@ TEST_F(NodeAdaptorTest, context_node_name_change) { dispatch(); - auto nodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_Node)}; + auto nodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::Node)}; EXPECT_EQ(nodes.size(), 1); - EXPECT_STREQ("Node Name", nodes[0]->getName()); - EXPECT_EQ(select(sceneContext.logicEngine(), "Node Name_NodeBinding")->getUserId(), node->objectIDAsRamsesLogicID()); + EXPECT_TRUE("Node Name" == nodes[0]->getName()); + EXPECT_EQ(select(sceneContext.logicEngine(), "Node Name_NodeBinding")->getUserId(), node->objectIDAsRamsesLogicID()); context.set({node, {"objectName"}}, std::string("Changed")); dispatch(); - EXPECT_STREQ("Changed", nodes[0]->getName()); - EXPECT_EQ(select(sceneContext.logicEngine(), "Changed_NodeBinding")->getUserId(), node->objectIDAsRamsesLogicID()); + EXPECT_TRUE("Changed" == nodes[0]->getName()); + EXPECT_EQ(select(sceneContext.logicEngine(), "Changed_NodeBinding")->getUserId(), node->objectIDAsRamsesLogicID()); } diff --git a/components/libRamsesBase/tests/OrthographicCameraAdaptor_test.cpp b/components/libRamsesBase/tests/OrthographicCameraAdaptor_test.cpp index b1688aae..f33a30c9 100644 --- a/components/libRamsesBase/tests/OrthographicCameraAdaptor_test.cpp +++ b/components/libRamsesBase/tests/OrthographicCameraAdaptor_test.cpp @@ -14,9 +14,9 @@ #include "user_types/OrthographicCamera.h" using namespace raco; -using raco::core::ValueHandle; -using raco::user_types::LuaScript; -using raco::user_types::OrthographicCamera; +using core::ValueHandle; +using user_types::LuaScript; +using user_types::OrthographicCamera; class OrthographicCameraAdaptorTest : public RamsesBaseFixture<> {}; @@ -24,7 +24,7 @@ class OrthographicCameraAdaptorTest : public RamsesBaseFixture<> {}; auto luaScript = context.createObject(LuaScript::typeDescription.typeName, "LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) IN.in_value = Type:Vec4f() OUT.out_value = Type:Vec4f() @@ -48,7 +48,7 @@ end commandInterface.set({camera, {"frustum", "leftPlane"}}, 7.0); dispatch(); - auto cameras{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_OrthographicCamera)}; + auto cameras{select(*sceneContext.scene(), ramses::ERamsesObjectType::OrthographicCamera)}; ASSERT_EQ(cameras.size(), 1); ASSERT_FLOAT_EQ(cameras.front()->getLeftPlane(), 7.0F); } @@ -57,7 +57,7 @@ end auto camera = commandInterface.createObject(OrthographicCamera::typeDescription.typeName, "Camera"); dispatch(); - auto cameras{select(sceneContext.logicEngine(), "Camera_CameraBinding")}; + auto cameras{select(sceneContext.logicEngine(), "Camera_CameraBinding")}; ASSERT_EQ(cameras->getUserId(), camera->objectIDAsRamsesLogicID()); } @@ -68,6 +68,6 @@ end commandInterface.set({camera, &OrthographicCamera::objectName_}, std::string("Changed")); dispatch(); - auto cameras{select(sceneContext.logicEngine(), "Changed_CameraBinding")}; + auto cameras{select(sceneContext.logicEngine(), "Changed_CameraBinding")}; ASSERT_EQ(cameras->getUserId(), camera->objectIDAsRamsesLogicID()); } \ No newline at end of file diff --git a/components/libRamsesBase/tests/PerspectiveCameraAdaptor_test.cpp b/components/libRamsesBase/tests/PerspectiveCameraAdaptor_test.cpp index 9c257020..57fe4ae1 100644 --- a/components/libRamsesBase/tests/PerspectiveCameraAdaptor_test.cpp +++ b/components/libRamsesBase/tests/PerspectiveCameraAdaptor_test.cpp @@ -14,9 +14,9 @@ #include "user_types/PerspectiveCamera.h" using namespace raco; -using raco::core::ValueHandle; -using raco::user_types::LuaScript; -using raco::user_types::PerspectiveCamera; +using core::ValueHandle; +using user_types::LuaScript; +using user_types::PerspectiveCamera; class PerspectiveCameraAdaptorTest : public RamsesBaseFixture<> {}; @@ -24,7 +24,7 @@ TEST_F(PerspectiveCameraAdaptorTest, quaternion_link_camera_still_active) { auto luaScript = context.createObject(LuaScript::typeDescription.typeName, "LuaScript Name"); std::string uriPath{(test_path() / "script.lua").string()}; - raco::utils::file::write(uriPath, R"( + utils::file::write(uriPath, R"( function interface(IN,OUT) IN.in_value = Type:Vec4f() OUT.out_value = Type:Vec4f() @@ -48,7 +48,7 @@ end commandInterface.set({camera, {"frustum", "aspectRatio"}}, 7.0); dispatch(); - auto cameras{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_PerspectiveCamera)}; + auto cameras{select(*sceneContext.scene(), ramses::ERamsesObjectType::PerspectiveCamera)}; ASSERT_EQ(cameras.size(), 1); ASSERT_FLOAT_EQ(cameras.front()->getAspectRatio(), 7.0F); } @@ -57,7 +57,7 @@ TEST_F(PerspectiveCameraAdaptorTest, bindingID) { auto camera = commandInterface.createObject(PerspectiveCamera::typeDescription.typeName, "Camera"); dispatch(); - auto cameras{select(sceneContext.logicEngine(), "Camera_CameraBinding")}; + auto cameras{select(sceneContext.logicEngine(), "Camera_CameraBinding")}; ASSERT_EQ(cameras->getUserId(), camera->objectIDAsRamsesLogicID()); } @@ -68,6 +68,6 @@ TEST_F(PerspectiveCameraAdaptorTest, bindingID_name_change) { commandInterface.set({camera, &PerspectiveCamera::objectName_}, std::string("Changed")); dispatch(); - auto cameras{select(sceneContext.logicEngine(), "Changed_CameraBinding")}; + auto cameras{select(sceneContext.logicEngine(), "Changed_CameraBinding")}; ASSERT_EQ(cameras->getUserId(), camera->objectIDAsRamsesLogicID()); } \ No newline at end of file diff --git a/components/libRamsesBase/tests/RamsesBaseFixture.h b/components/libRamsesBase/tests/RamsesBaseFixture.h index bab8cacd..556d7880 100644 --- a/components/libRamsesBase/tests/RamsesBaseFixture.h +++ b/components/libRamsesBase/tests/RamsesBaseFixture.h @@ -14,12 +14,12 @@ #include "testing/RacoBaseTest.h" #include "testing/TestEnvironmentCore.h" #include "user_types/UserObjectFactory.h" -#include -#include +#include +#include #include template -inline std::vector select(const ramses::Scene& scene, ramses::ERamsesObjectType type = ramses::ERamsesObjectType_RamsesObject) { +inline std::vector select(const ramses::Scene& scene, ramses::ERamsesObjectType type = ramses::ERamsesObjectType::RamsesObject) { std::vector result{}; auto it = ramses::SceneObjectIterator{scene, type}; while (auto object = it.getNext()) { @@ -35,13 +35,13 @@ inline std::vector select(const ramses::Scene& scene, ramses::ERamsesObjectT } template -inline const T* select(const rlogic::LogicEngine& engine, const char* name) { - return engine.findByName(name); +inline const T* select(const ramses::LogicEngine& engine, const char* name) { + return engine.findObject(name); } template inline const T* select(const ramses::Scene& scene, const char* name) { - auto result = static_cast(scene.findObjectByName(name)); + auto result = scene.findObject(name); EXPECT_TRUE(result != nullptr); return result; } @@ -53,15 +53,15 @@ inline std::vector select_all(const ramses::Scene& scene) template class RamsesBaseFixture : public TestEnvironmentCoreT { public: - using DataChangeDispatcher = raco::components::DataChangeDispatcher; + using DataChangeDispatcher = components::DataChangeDispatcher; - RamsesBaseFixture(bool optimizeForExport = false, rlogic::EFeatureLevel featureLevel = raco::ramses_base::BaseEngineBackend::maxFeatureLevel) - : TestEnvironmentCoreT(&raco::user_types::UserObjectFactory::getInstance(), featureLevel), + RamsesBaseFixture(bool optimizeForExport = false, ramses::EFeatureLevel featureLevel = ramses_base::BaseEngineBackend::maxFeatureLevel) + : TestEnvironmentCoreT(&user_types::UserObjectFactory::getInstance(), featureLevel), dataChangeDispatcher{std::make_shared()}, - sceneContext{&this->backend.client(), &this->backend.logicEngine(), ramses::sceneId_t{1u}, &this->project, dataChangeDispatcher, &this->errors, optimizeForExport} {} + sceneContext{&this->backend.client(), ramses::sceneId_t{1u}, &this->project, dataChangeDispatcher, &this->errors, optimizeForExport} {} std::shared_ptr dataChangeDispatcher; - raco::ramses_adaptor::SceneAdaptor sceneContext; + ramses_adaptor::SceneAdaptor sceneContext; bool dispatch() { auto dataChanges = this->recorder.release(); @@ -73,9 +73,9 @@ class RamsesBaseFixture : public TestEnvironmentCoreT { protected: template - bool isRamsesNameInArray(const char* name, const std::vector& arrayOfArrays) { + bool isRamsesNameInArray(std::string_view name, const std::vector& arrayOfArrays) { return std::find_if(arrayOfArrays.begin(), arrayOfArrays.end(), [name](RamsesType* array) { - return std::strcmp(array->getName(), name) == 0; + return array->getName() == name; }) != arrayOfArrays.end(); }; }; diff --git a/components/libRamsesBase/tests/RamsesLogic_test.cpp b/components/libRamsesBase/tests/RamsesLogic_test.cpp index db904554..f8de608e 100644 --- a/components/libRamsesBase/tests/RamsesLogic_test.cpp +++ b/components/libRamsesBase/tests/RamsesLogic_test.cpp @@ -11,27 +11,45 @@ #include #include +#include "RamsesBaseFixture.h" +#include "testing/RacoBaseTest.h" #include "ramses_base/Utils.h" -#include -#include -#include -#include -#include -#include -#include -#include +#include "ramses_adaptor/utilities.h" + +#include +#include +#include +#include +#include +#include +#include +#include #include /* -* Basic test for third_party dependiences: ramses-logic. -* Should be used to verify stability of dependency. -*/ + * Basic test for third_party dependiences: ramses-logic. + * Should be used to verify stability of dependency. + */ + +using namespace raco::ramses_adaptor; +class RamsesLogicTest : public RacoBaseTest<> { +public: + RamsesLogicTest() + : ramsesFramework(ramses::RamsesFrameworkConfig{ramses::EFeatureLevel::EFeatureLevel_01}), + client(ramsesFramework.createClient("example client")), + scene(client->createScene(ramses::sceneId_t(123u), "some scene")), + logicEngine(*scene->createLogicEngine("logic engine")) { + } -TEST(ramses_logic, repeat_create_destroy_simple_script) { - rlogic::LogicEngine logicEngine; + ramses::RamsesFramework ramsesFramework; + ramses::RamsesClient* client; + ramses::Scene* scene; + ramses::LogicEngine& logicEngine; +}; +TEST_F(RamsesLogicTest, repeat_create_destroy_simple_script) { std::string scriptText = R"( function interface(IN,OUT) OUT.out_float = Type:Float() @@ -47,8 +65,7 @@ end } } -TEST(ramses_logic, relink_scriptToScript) { - rlogic::LogicEngine logicEngine; +TEST_F(RamsesLogicTest, relink_scriptToScript) { auto* outScript = logicEngine.createLuaScript(R"( function interface(IN,OUT) OUT.out_float = Type:Float() @@ -83,11 +100,7 @@ end ASSERT_TRUE(logicEngine.update()); } -TEST(ramses_logic, relink_scriptToNode) { - rlogic::LogicEngine logicEngine; - ramses::RamsesFramework ramsesFramework; - ramses::RamsesClient& client = *ramsesFramework.createClient("example client"); - ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), ramses::SceneConfig(), "some scene"); +TEST_F(RamsesLogicTest, relink_scriptToNode) { ramses::Node* node = scene->createNode("some node"); auto* outScript = logicEngine.createLuaScript(R"( @@ -101,24 +114,24 @@ function run(IN,OUT) end )"); - auto* binding = logicEngine.createRamsesNodeBinding(*node, rlogic::ERotationType::Euler_ZYX, "some node binding"); + auto* binding = logicEngine.createNodeBinding(*node, ramses::ERotationType::Euler_ZYX, "some node binding"); - const rlogic::Property* nodeTranslation {nullptr}; + ramses::Property* nodeTranslation {nullptr}; for (size_t i{0}; i < binding->getInputs()->getChildCount(); i++) { if (binding->getInputs()->getChild(i)->getName() == "translation") { nodeTranslation = binding->getInputs()->getChild(i); } } ASSERT_TRUE(nodeTranslation != nullptr); - const rlogic::Property* scriptOutVec3f {nullptr}; + ramses::Property* scriptOutVec3f {nullptr}; for (size_t i {0}; i < outScript->getOutputs()->getChildCount(); i++) { if (outScript->getOutputs()->getChild(i)->getName() == "out_vec3f") { scriptOutVec3f = outScript->getOutputs()->getChild(i); } } ASSERT_TRUE(scriptOutVec3f != nullptr); - rlogic::Property* scriptInFloat { nullptr }; - for (size_t i {0}; i < outScript->getInputs()->getChildCount(); i++) { + ramses::Property* scriptInFloat{nullptr}; + for (size_t i{0}; i < outScript->getInputs()->getChildCount(); i++) { if (outScript->getInputs()->getChild(i)->getName() == "in_float") { scriptInFloat = outScript->getInputs()->getChild(i); } @@ -129,54 +142,21 @@ end scriptInFloat->set(5.0f); ASSERT_TRUE(logicEngine.update()); - { - float x,y,z; - node->getTranslation(x,y,z); - ASSERT_EQ(5.0f, x); - ASSERT_EQ(0.0f, y); - ASSERT_EQ(0.0f, z); - } + EXPECT_EQ(getRamsesTranslation(node), glm::vec3(5.0, 0.0, 0.0)); ASSERT_TRUE(logicEngine.unlink(*scriptOutVec3f, *nodeTranslation)); scriptInFloat->set(10.0f); ASSERT_TRUE(logicEngine.update()); - { - float x,y,z; - node->getTranslation(x,y,z); - ASSERT_EQ(5.0f, x); - ASSERT_EQ(0.0f, y); - ASSERT_EQ(0.0f, z); - } + EXPECT_EQ(getRamsesTranslation(node), glm::vec3(5.0, 0.0, 0.0)); ASSERT_TRUE(logicEngine.link(*scriptOutVec3f, *nodeTranslation)); ASSERT_TRUE(logicEngine.update()); - { - float x,y,z; - node->getTranslation(x,y,z); - ASSERT_EQ(10.0f, x); - ASSERT_EQ(0.0f, y); - ASSERT_EQ(0.0f, z); - } -} - -std::vector get_node_translation(ramses::Node* node) { - float x, y, z; - node->getTranslation(x, y, z); - return {x, y, z}; + EXPECT_EQ(getRamsesTranslation(node), glm::vec3(10.0, 0.0, 0.0)); } -std::vector get_node_scale(ramses::Node* node) { - float x, y, z; - node->getScaling(x, y, z); - return {x, y, z}; -} -TEST(ramses_logic, linkUnlink_nodeBinding_single) { - rlogic::LogicEngine logicEngine; - ramses::RamsesFramework ramsesFramework; - ramses::RamsesClient& client = *ramsesFramework.createClient("example client"); - ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), ramses::SceneConfig(), "some scene"); +TEST_F(RamsesLogicTest, linkUnlink_nodeBinding_single) { ramses::Node* node = scene->createNode("some node"); auto* outScript = logicEngine.createLuaScript(R"( @@ -190,33 +170,29 @@ function run(IN,OUT) end )"); - auto* binding = logicEngine.createRamsesNodeBinding(*node, rlogic::ERotationType::Euler_ZYX, "some node binding"); + auto* binding = logicEngine.createNodeBinding(*node, ramses::ERotationType::Euler_ZYX, "some node binding"); - const rlogic::Property* nodeTranslation{binding->getInputs()->getChild("translation")}; + ramses::Property* nodeTranslation{binding->getInputs()->getChild("translation")}; ASSERT_TRUE(nodeTranslation != nullptr); - const rlogic::Property* scriptOutVec3f{outScript->getOutputs()->getChild("out_vec3f")}; + ramses::Property* scriptOutVec3f{outScript->getOutputs()->getChild("out_vec3f")}; ASSERT_TRUE(scriptOutVec3f != nullptr); ASSERT_TRUE(logicEngine.link(*scriptOutVec3f, *nodeTranslation)); outScript->getInputs()->getChild("in_float")->set(1.0f); ASSERT_TRUE(logicEngine.update()); - EXPECT_EQ(get_node_translation(node), std::vector({1.0, 0.0, 0.0})); + EXPECT_EQ(getRamsesTranslation(node), glm::vec3(1.0, 0.0, 0.0)); ASSERT_TRUE(logicEngine.unlink(*scriptOutVec3f, *nodeTranslation)); - node->setTranslation(2.0, 3.0, 4.0); - EXPECT_EQ(get_node_translation(node), std::vector({2.0, 3.0, 4.0})); + node->setTranslation({2.0, 3.0, 4.0}); + EXPECT_EQ(getRamsesTranslation(node), glm::vec3(2.0, 3.0, 4.0)); ASSERT_TRUE(logicEngine.update()); - EXPECT_EQ(get_node_translation(node), std::vector({2.0, 3.0, 4.0})); + EXPECT_EQ(getRamsesTranslation(node), glm::vec3(2.0, 3.0, 4.0)); } -TEST(ramses_logic, linkUnlink_nodeBinding_multi) { - rlogic::LogicEngine logicEngine; - ramses::RamsesFramework ramsesFramework; - ramses::RamsesClient& client = *ramsesFramework.createClient("example client"); - ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), ramses::SceneConfig(), "some scene"); +TEST_F(RamsesLogicTest, linkUnlink_nodeBinding_multi) { ramses::Node* node = scene->createNode("some node"); auto* outScript = logicEngine.createLuaScript(R"( @@ -230,13 +206,13 @@ function run(IN,OUT) end )"); - auto* binding = logicEngine.createRamsesNodeBinding(*node, rlogic::ERotationType::Euler_ZYX, "some node binding"); + auto* binding = logicEngine.createNodeBinding(*node, ramses::ERotationType::Euler_ZYX, "some node binding"); - const rlogic::Property* nodeTranslation{binding->getInputs()->getChild("translation")}; + ramses::Property* nodeTranslation{binding->getInputs()->getChild("translation")}; ASSERT_TRUE(nodeTranslation != nullptr); - const rlogic::Property* nodeScale{binding->getInputs()->getChild("scaling")}; + ramses::Property* nodeScale{binding->getInputs()->getChild("scaling")}; ASSERT_TRUE(nodeScale != nullptr); - const rlogic::Property* scriptOutVec3f{outScript->getOutputs()->getChild("out_vec3f")}; + ramses::Property* scriptOutVec3f{outScript->getOutputs()->getChild("out_vec3f")}; ASSERT_TRUE(scriptOutVec3f != nullptr); ASSERT_TRUE(logicEngine.link(*scriptOutVec3f, *nodeTranslation)); @@ -244,24 +220,21 @@ end outScript->getInputs()->getChild("in_float")->set(1.0f); ASSERT_TRUE(logicEngine.update()); - EXPECT_EQ(get_node_translation(node), std::vector({1.0, 0.0, 0.0})); - EXPECT_EQ(get_node_scale(node), std::vector({1.0, 0.0, 0.0})); + EXPECT_EQ(getRamsesTranslation(node), glm::vec3(1.0, 0.0, 0.0)); + EXPECT_EQ(getRamsesScaling(node), glm::vec3(1.0, 0.0, 0.0)); ASSERT_TRUE(logicEngine.unlink(*scriptOutVec3f, *nodeTranslation)); outScript->getInputs()->getChild("in_float")->set(0.5f); - node->setTranslation(2.0, 3.0, 4.0); - EXPECT_EQ(get_node_translation(node), std::vector({2.0, 3.0, 4.0})); + node->setTranslation({2.0, 3.0, 4.0}); + EXPECT_EQ(getRamsesTranslation(node), glm::vec3(2.0, 3.0, 4.0)); + EXPECT_EQ(getRamsesScaling(node), glm::vec3(1.0, 0.0, 0.0)); ASSERT_TRUE(logicEngine.update()); - EXPECT_EQ(get_node_translation(node), std::vector({2.0, 3.0, 4.0})); - EXPECT_EQ(get_node_scale(node), std::vector({0.5, 0.0, 0.0})); + EXPECT_EQ(getRamsesTranslation(node), glm::vec3(2.0, 3.0, 4.0)); + EXPECT_EQ(getRamsesScaling(node), glm::vec3(0.5, 0.0, 0.0)); } -TEST(ramses_logic, unlinkAndDestroy_nodeBinding) { - rlogic::LogicEngine logicEngine; - ramses::RamsesFramework ramsesFramework; - ramses::RamsesClient& client = *ramsesFramework.createClient("example client"); - ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), ramses::SceneConfig(), "some scene"); +TEST_F(RamsesLogicTest, unlinkAndDestroy_nodeBinding) { ramses::Node* node = scene->createNode("some node"); auto* outScript = logicEngine.createLuaScript(R"( @@ -275,11 +248,11 @@ function run(IN,OUT) end )"); - auto* binding = logicEngine.createRamsesNodeBinding(*node, rlogic::ERotationType::Euler_ZYX, "some node binding"); + auto* binding = logicEngine.createNodeBinding(*node, ramses::ERotationType::Euler_ZYX, "some node binding"); - const rlogic::Property* nodeTranslation{binding->getInputs()->getChild("translation")}; + ramses::Property* nodeTranslation{binding->getInputs()->getChild("translation")}; ASSERT_TRUE(nodeTranslation != nullptr); - const rlogic::Property* scriptOutVec3f{outScript->getOutputs()->getChild("out_vec3f")}; + ramses::Property* scriptOutVec3f{outScript->getOutputs()->getChild("out_vec3f")}; ASSERT_TRUE(scriptOutVec3f != nullptr); ASSERT_TRUE(logicEngine.link(*scriptOutVec3f, *nodeTranslation)); @@ -288,11 +261,7 @@ end ASSERT_TRUE(logicEngine.update()); } -TEST(ramses_logic, unlinkAndDestroyScript_multipleLinks) { - rlogic::LogicEngine logicEngine; - ramses::RamsesFramework ramsesFramework; - ramses::RamsesClient& client = *ramsesFramework.createClient("example client"); - ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), ramses::SceneConfig(), "some scene"); +TEST_F(RamsesLogicTest, unlinkAndDestroyScript_multipleLinks) { ramses::Node* node = scene->createNode("some node"); auto* outScript = logicEngine.createLuaScript(R"( @@ -305,15 +274,15 @@ function run(IN,OUT) end )"); - auto* binding = logicEngine.createRamsesNodeBinding(*node, rlogic::ERotationType::Euler_ZYX, "some node binding"); + auto* binding = logicEngine.createNodeBinding(*node, ramses::ERotationType::Euler_ZYX, "some node binding"); - const rlogic::Property* nodeTranslation {binding->getInputs()->getChild("translation")}; - const rlogic::Property* nodeVisibility {binding->getInputs()->getChild("visibility")}; + ramses::Property* nodeTranslation {binding->getInputs()->getChild("translation")}; + ramses::Property* nodeVisibility {binding->getInputs()->getChild("visibility")}; ASSERT_TRUE(nodeTranslation != nullptr); ASSERT_TRUE(nodeVisibility != nullptr); - const rlogic::Property* scriptTranslation {outScript->getOutputs()->getChild("translation")}; - const rlogic::Property* scriptVisiblity{outScript->getOutputs()->getChild("visibility")}; + ramses::Property* scriptTranslation {outScript->getOutputs()->getChild("translation")}; + ramses::Property* scriptVisiblity{outScript->getOutputs()->getChild("visibility")}; ASSERT_TRUE(scriptTranslation != nullptr); ASSERT_TRUE(scriptVisiblity != nullptr); @@ -329,8 +298,7 @@ end ASSERT_TRUE(logicEngine.update()); } -TEST(ramses_logic, arrayOfStruct_linking) { - rlogic::LogicEngine logicEngine; +TEST_F(RamsesLogicTest, arrayOfStruct_linking) { auto scriptContent{ R"( function interface(IN,OUT) @@ -347,8 +315,8 @@ end auto* startScript = logicEngine.createLuaScript(scriptContent); auto* endScript = logicEngine.createLuaScript(scriptContent); - const rlogic::Property* outA{startScript->getOutputs()->getChild("arrayOfStruct")->getChild(0)->getChild("a")}; - const rlogic::Property* inA{endScript->getInputs()->getChild("arrayOfStruct")->getChild(0)->getChild("a")}; + ramses::Property* outA{startScript->getOutputs()->getChild("arrayOfStruct")->getChild(0)->getChild("a")}; + ramses::Property* inA{endScript->getInputs()->getChild("arrayOfStruct")->getChild(0)->getChild("a")}; ASSERT_TRUE(logicEngine.link(*outA, *inA)); ASSERT_TRUE(logicEngine.update()); @@ -360,10 +328,9 @@ end ASSERT_EQ(1.0f, endScript->getOutputs()->getChild("arrayOfStruct")->getChild(0)->getChild("a")->get().value()); } -TEST(ramses_logic, array_linkToComponent) { - rlogic::LogicEngine logicEngine; - auto scriptContentFloatArray { -R"( +TEST_F(RamsesLogicTest, array_linkToComponent) { + auto scriptContentFloatArray{ + R"( function interface(IN,OUT) IN.float_array = Type:Array(5, Type:Float()) OUT.float_array = Type:Array(5, Type:Float()) @@ -372,10 +339,9 @@ end function run(IN,OUT) OUT.float_array = IN.float_array end -)" - }; - auto scriptContentFloat { -R"( +)"}; + auto scriptContentFloat{ + R"( function interface(IN,OUT) IN.float = Type:Float() OUT.float = Type:Float() @@ -384,14 +350,13 @@ end function run(IN,OUT) OUT.float = IN.float end -)" - }; +)"}; auto* startScript = logicEngine.createLuaScript(scriptContentFloat); auto* endScript = logicEngine.createLuaScript(scriptContentFloatArray); - const rlogic::Property* outA{startScript->getOutputs()->getChild("float")}; - const rlogic::Property* inA{endScript->getInputs()->getChild("float_array")->getChild(0)}; + ramses::Property* outA{startScript->getOutputs()->getChild("float")}; + ramses::Property* inA{endScript->getInputs()->getChild("float_array")->getChild(0)}; ASSERT_TRUE(logicEngine.link(*outA, *inA)); ASSERT_TRUE(logicEngine.update()); @@ -401,8 +366,7 @@ end ASSERT_EQ(1.0f, endScript->getInputs()->getChild("float_array")->getChild(0)->get().value()); } -TEST(ramses_logic, standardModules) { - rlogic::LogicEngine logicEngine; +TEST_F(RamsesLogicTest, standardModules) { auto scriptContentFloat{ R"( function interface(IN,OUT) @@ -415,7 +379,7 @@ function run(IN,OUT) end )"}; - auto luaConfig = raco::ramses_base::defaultLuaConfig(); + auto luaConfig = ramses_base::defaultLuaConfig(); auto* script = logicEngine.createLuaScript(scriptContentFloat, luaConfig); const float pi = static_cast(std::acos(-1.0)); @@ -424,8 +388,7 @@ end ASSERT_EQ(-1.0, script->getOutputs()->getChild("float")->get().value()); } -TEST(ramses_logic, weird_crash) { - rlogic::LogicEngine logicEngine; +TEST_F(RamsesLogicTest, weird_crash) { std::string scriptText = R"( function interface(IN,OUT) @@ -484,81 +447,73 @@ end } } -TEST(ramses_logic, node_binding_quaternion_rotation) { - rlogic::LogicEngine logicEngine; - ramses::RamsesFramework ramsesFramework; - ramses::RamsesClient& client = *ramsesFramework.createClient("example client"); - ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), ramses::SceneConfig(), "some scene"); - +TEST_F(RamsesLogicTest, node_binding_quaternion_rotation) { ramses::Node* node = scene->createNode("some node"); - auto* binding = logicEngine.createRamsesNodeBinding(*node, rlogic::ERotationType::Quaternion, "some node binding"); - + auto* binding = logicEngine.createNodeBinding(*node, ramses::ERotationType::Quaternion, "some node binding"); + float delta = 1e-4; float one_over_sqrt_6 = 1.0f / sqrt(6.0f); float one_over_sqrt_2 = 1.0f / sqrt(2.0f); - std::array q{one_over_sqrt_6, one_over_sqrt_6, one_over_sqrt_6, one_over_sqrt_2}; + glm::vec4 q{one_over_sqrt_6, one_over_sqrt_6, one_over_sqrt_6, one_over_sqrt_2}; float norm2 = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; ASSERT_TRUE(std::abs(norm2 - 1.0f) < delta); - - rlogic::Property* nodeRotation{binding->getInputs()->getChild("rotation")}; + + ramses::Property* nodeRotation{binding->getInputs()->getChild("rotation")}; nodeRotation->set(q); logicEngine.update(); - float ramsesModelMatrix[16]; + glm::mat4x4 ramsesModelMatrix; node->getModelMatrix(ramsesModelMatrix); - float refModelMatrix[16]; + glm::mat4x4 refModelMatrix; // m11 - refModelMatrix[0] = 1.0f - 2.0f * (q[1] * q[1] + q[2] * q[2]); + refModelMatrix[0][0] = 1.0f - 2.0f * (q[1] * q[1] + q[2] * q[2]); // m21 - refModelMatrix[1] = 2.0f * (q[0] * q[1] + q[2] * q[3]); + refModelMatrix[0][1] = 2.0f * (q[0] * q[1] + q[2] * q[3]); // m31 - refModelMatrix[2] = 2.0f * (q[0] * q[2] - q[1] * q[3]); + refModelMatrix[0][2] = 2.0f * (q[0] * q[2] - q[1] * q[3]); // m41 - refModelMatrix[3] = 0.0; + refModelMatrix[0][3] = 0.0; // m12 - refModelMatrix[4] = 2.0f * (q[0] * q[1] - q[2] * q[3]); + refModelMatrix[1][0] = 2.0f * (q[0] * q[1] - q[2] * q[3]); // m22 - refModelMatrix[5] = 1.0f - 2.0f * (q[0] * q[0] + q[2] * q[2]); + refModelMatrix[1][1] = 1.0f - 2.0f * (q[0] * q[0] + q[2] * q[2]); // m32 - refModelMatrix[6] = 2.0f * (q[1] * q[2] + q[0] * q[3]); + refModelMatrix[1][2] = 2.0f * (q[1] * q[2] + q[0] * q[3]); // m42 - refModelMatrix[7] = 0.0; + refModelMatrix[1][3] = 0.0; // m13 - refModelMatrix[8] = 2.0f * (q[0] * q[2] + q[1] * q[3]); + refModelMatrix[2][0] = 2.0f * (q[0] * q[2] + q[1] * q[3]); // m23 - refModelMatrix[9] = 2.0f * (q[1] * q[2] - q[0] * q[3]); + refModelMatrix[2][1] = 2.0f * (q[1] * q[2] - q[0] * q[3]); // m33 - refModelMatrix[10] = 1.0f - 2.0f * (q[0] * q[0] + q[1] * q[1]); + refModelMatrix[2][2] = 1.0f - 2.0f * (q[0] * q[0] + q[1] * q[1]); // m43 - refModelMatrix[11] = 0.0; + refModelMatrix[2][3] = 0.0; // m14 .. m44 - refModelMatrix[12] = 0.0; - refModelMatrix[13] = 0.0; - refModelMatrix[14] = 0.0; - refModelMatrix[15] = 1.0; - -// Remove the EXPECT_NONFATAL_FAILURE once the logic engine has been fixed - EXPECT_NONFATAL_FAILURE( - bool comp = true; - for (int i = 0; i < 16; i++) { - if (std::abs(refModelMatrix[i] - ramsesModelMatrix[i]) > delta) { + refModelMatrix[3][0] = 0.0; + refModelMatrix[3][1] = 0.0; + refModelMatrix[3][2] = 0.0; + refModelMatrix[3][3] = 1.0; + + bool comp = true; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + if (std::abs(refModelMatrix[i][j] - ramsesModelMatrix[i][j]) > delta) { comp = false; } - } EXPECT_TRUE(comp); - , - "Value of: comp"); + } + } + EXPECT_TRUE(comp); } -TEST(ramses_logic, interface_using_modules_invalid_arg_FL4_deprecated_create_function) { - rlogic::LogicEngine logicEngine(rlogic::EFeatureLevel::EFeatureLevel_04); - +TEST_F(RamsesLogicTest, interface_using_modules_invalid_arg_pass_no_config) { auto text{ R"( modules(42) @@ -567,12 +522,10 @@ end )"}; auto* interface = logicEngine.createLuaInterface(text, "interface"); - ASSERT_TRUE(interface != nullptr); + ASSERT_TRUE(interface == nullptr); } -TEST(ramses_logic, interface_using_valid_arg_modules_FL4_deprecated_create_function) { - rlogic::LogicEngine logicEngine(rlogic::EFeatureLevel::EFeatureLevel_04); - +TEST_F(RamsesLogicTest, interface_using_valid_arg_modules_pass_no_config) { auto text{ R"( modules("mymodule") @@ -581,12 +534,10 @@ end )"}; auto* interface = logicEngine.createLuaInterface(text, "interface"); - ASSERT_TRUE(interface != nullptr); + ASSERT_TRUE(interface == nullptr); } -TEST(ramses_logic, interface_using_modules_invalid_arg_FL5_deprecated_create_function) { - rlogic::LogicEngine logicEngine(rlogic::EFeatureLevel::EFeatureLevel_05); - +TEST_F(RamsesLogicTest, interface_using_modules_invalid_arg_pass_config) { auto text{ R"( modules(42) @@ -594,13 +545,12 @@ function interface(IN,OUT) end )"}; - auto* interface = logicEngine.createLuaInterface(text, "interface"); - ASSERT_TRUE(interface != nullptr); + ramses::LuaConfig config; + auto* interface = logicEngine.createLuaInterface(text, "interface", config); + ASSERT_TRUE(interface == nullptr); } -TEST(ramses_logic, interface_using_valid_arg_modules_FL5_deprecated_create_function) { - rlogic::LogicEngine logicEngine(rlogic::EFeatureLevel::EFeatureLevel_05); - +TEST_F(RamsesLogicTest, interface_using_valid_arg_modules_pass_config) { auto text{ R"( modules("mymodule") @@ -608,66 +558,70 @@ function interface(IN,OUT) end )"}; - auto* interface = logicEngine.createLuaInterface(text, "interface"); - ASSERT_TRUE(interface != nullptr); + ramses::LuaConfig config; + auto* interface = logicEngine.createLuaInterface(text, "interface", config); + ASSERT_TRUE(interface == nullptr); } -TEST(ramses_logic, interface_using_modules_invalid_arg_FL4_new_create_function) { - rlogic::LogicEngine logicEngine(rlogic::EFeatureLevel::EFeatureLevel_04); +TEST_F(RamsesLogicTest, deserialize_node_binding_enable_visibility) { + std::string ramsesFile = (test_path() / "test.ramses").string(); + client->destroy(*scene); - auto text{ - R"( -modules(42) -function interface(IN,OUT) -end -)"}; + for (bool enabled : {false, true}) { + for (bool visibility : {false, true}) { + ramses::EVisibilityMode mode = enabled ? (visibility ? ramses::EVisibilityMode::Visible : ramses::EVisibilityMode::Invisible) : ramses::EVisibilityMode::Off; - rlogic::LuaConfig config; - auto* interface = logicEngine.createLuaInterface(text, "interface", config); - ASSERT_TRUE(interface == nullptr); -} + { + scene = client->createScene(ramses::sceneId_t(123u), "some scene"); + auto logicEngine = scene->createLogicEngine("logic engine"); -TEST(ramses_logic, interface_using_valid_arg_modules_FL4_new_create_function) { - rlogic::LogicEngine logicEngine(rlogic::EFeatureLevel::EFeatureLevel_04); + ramses::Node* node = scene->createNode("Node"); + auto* binding = logicEngine->createNodeBinding(*node, ramses::ERotationType::Euler_ZYX, "NodeBinding"); - auto text{ - R"( -modules("mymodule") -function interface(IN,OUT) -end -)"}; + ramses::Property* prop_enabled{binding->getInputs()->getChild("enabled")}; + ASSERT_TRUE(prop_enabled != nullptr); - rlogic::LuaConfig config; - auto* interface = logicEngine.createLuaInterface(text, "interface", config); - ASSERT_TRUE(interface == nullptr); -} + ramses::Property* prop_visibility{binding->getInputs()->getChild("visibility")}; + ASSERT_TRUE(prop_visibility != nullptr); -TEST(ramses_logic, interface_using_modules_invalid_arg_FL5_new_create_function) { - rlogic::LogicEngine logicEngine(rlogic::EFeatureLevel::EFeatureLevel_05); + prop_enabled->set(enabled); + prop_visibility->set(visibility); + logicEngine->update(); - auto text{ - R"( -modules(42) -function interface(IN,OUT) -end -)"}; + EXPECT_EQ(node->getVisibility(), mode); + EXPECT_EQ(prop_enabled->get(), enabled); + EXPECT_EQ(prop_visibility->get(), visibility); - rlogic::LuaConfig config; - auto* interface = logicEngine.createLuaInterface(text, "interface", config); - ASSERT_TRUE(interface == nullptr); -} + ramses::SaveFileConfig config; -TEST(ramses_logic, interface_using_valid_arg_modules_FL5_new_create_function) { - rlogic::LogicEngine logicEngine(rlogic::EFeatureLevel::EFeatureLevel_05); + ASSERT_TRUE(scene->saveToFile(ramsesFile.c_str())); - auto text{ - R"( -modules("mymodule") -function interface(IN,OUT) -end -)"}; + client->destroy(*scene); + } - rlogic::LuaConfig config; - auto* interface = logicEngine.createLuaInterface(text, "interface", config); - ASSERT_TRUE(interface == nullptr); + { + scene = client->loadSceneFromFile(ramsesFile); + ASSERT_TRUE(scene != nullptr); + auto logicEngine = select(*scene, "logic engine"); + ASSERT_TRUE(logicEngine != nullptr); + + auto node = select(*scene, "Node"); + ASSERT_TRUE(node != nullptr); + auto binding = select(*logicEngine, "NodeBinding"); + ASSERT_TRUE(binding != nullptr); + + const ramses::Property* prop_enabled{binding->getInputs()->getChild("enabled")}; + ASSERT_TRUE(prop_enabled != nullptr); + + const ramses::Property* prop_visibility{binding->getInputs()->getChild("visibility")}; + ASSERT_TRUE(prop_visibility != nullptr); + + EXPECT_EQ(node->getVisibility(), mode); + EXPECT_EQ(prop_enabled->get().value(), enabled); + ASSERT_EQ(prop_visibility->get().value(), visibility) << fmt::format(" enabled / visibility = {} / {}", enabled, visibility); + + client->destroy(*scene); + } + } + } } diff --git a/components/libRamsesBase/tests/Ramses_test.cpp b/components/libRamsesBase/tests/Ramses_test.cpp index 5be5666e..77f47dd9 100644 --- a/components/libRamsesBase/tests/Ramses_test.cpp +++ b/components/libRamsesBase/tests/Ramses_test.cpp @@ -9,22 +9,21 @@ */ #include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include TEST(ramses, saveToFile_empty) { - ramses::RamsesFramework ramsesFramework; - ramses::RamsesClient& client = *ramsesFramework.createClient("example client"); - ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), ramses::SceneConfig(), "export scene"); - - scene->saveToFile("saveToFile_empty.ramses", false); + ramses::RamsesFramework ramsesFramework{ramses::RamsesFrameworkConfig{ramses::EFeatureLevel::EFeatureLevel_01}}; + ramses::RamsesClient& client = *ramsesFramework.createClient("example client"); + ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), "export scene"); + ASSERT_TRUE(scene->saveToFile("saveToFile_empty.ramses")); ASSERT_TRUE(std::filesystem::remove("saveToFile_empty.ramses")); } @@ -40,66 +39,90 @@ constexpr const char* emptyFragmentShader = void main() {}"; TEST(ramses, saveToFile_withEffect) { - ramses::RamsesFramework ramsesFramework; + ramses::RamsesFramework ramsesFramework{ramses::RamsesFrameworkConfig{ramses::EFeatureLevel::EFeatureLevel_01}}; ramses::RamsesClient& client = *ramsesFramework.createClient("example client"); - ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), ramses::SceneConfig(), "export scene"); + ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), "export scene"); ramses::EffectDescription desc{}; desc.setVertexShader(emptyVertexShader); desc.setFragmentShader(emptyFragmentShader); - ramses::Effect* effect = scene->createEffect(desc, ramses::ResourceCacheFlag_DoNotCache); + ramses::Effect* effect = scene->createEffect(desc); - scene->saveToFile("saveToFile_withEffect.ramses", false); + ASSERT_TRUE(scene->saveToFile("saveToFile_withEffect.ramses")); ASSERT_TRUE(std::filesystem::remove("saveToFile_withEffect.ramses")); } TEST(ramses, saveToFile_destroyNamedEffect) { - ramses::RamsesFramework ramsesFramework; + ramses::RamsesFramework ramsesFramework{ramses::RamsesFrameworkConfig{ramses::EFeatureLevel::EFeatureLevel_01}}; ramses::RamsesClient& client = *ramsesFramework.createClient("example client"); - ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), ramses::SceneConfig(), "export scene"); + ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), "export scene"); ramses::EffectDescription desc{}; desc.setVertexShader(emptyVertexShader); desc.setFragmentShader(emptyFragmentShader); - ramses::Effect* effect = scene->createEffect(desc, ramses::ResourceCacheFlag_DoNotCache); + ramses::Effect* effect = scene->createEffect(desc); effect->setName("Meow"); scene->destroy(*effect); - - scene->saveToFile("saveToFile_destroyNamedEffect.ramses", false); - + ASSERT_TRUE(scene->saveToFile("saveToFile_destroyNamedEffect.ramses")); + ASSERT_TRUE(std::filesystem::remove("saveToFile_destroyNamedEffect.ramses")); } TEST(ramses, saveToFile_renameEffect) { - ramses::RamsesFramework ramsesFramework; + ramses::RamsesFramework ramsesFramework{ramses::RamsesFrameworkConfig{ramses::EFeatureLevel::EFeatureLevel_01}}; ramses::RamsesClient& client = *ramsesFramework.createClient("example client"); - ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), ramses::SceneConfig(), "export scene"); + ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), "export scene"); ramses::EffectDescription desc{}; desc.setVertexShader(emptyVertexShader); desc.setFragmentShader(emptyFragmentShader); - ramses::Effect* effect = scene->createEffect(desc, ramses::ResourceCacheFlag_DoNotCache); + ramses::Effect* effect = scene->createEffect(desc); effect->setName("Meow"); - scene->saveToFile("saveToFile_renameEffect.ramses", false); + ASSERT_TRUE(scene->saveToFile("saveToFile_renameEffect.ramses")); ASSERT_TRUE(std::filesystem::remove("saveToFile_renameEffect.ramses")); } TEST(ramses, saveToFile_destroyEffect) { - ramses::RamsesFramework ramsesFramework; + ramses::RamsesFramework ramsesFramework{ramses::RamsesFrameworkConfig{ramses::EFeatureLevel::EFeatureLevel_01}}; ramses::RamsesClient& client = *ramsesFramework.createClient("example client"); - ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), ramses::SceneConfig(), "export scene"); + ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), "export scene"); ramses::EffectDescription desc{}; desc.setVertexShader(emptyVertexShader); desc.setFragmentShader(emptyFragmentShader); - ramses::Effect* effect = scene->createEffect(desc, ramses::ResourceCacheFlag_DoNotCache); + ramses::Effect* effect = scene->createEffect(desc); scene->destroy(*effect); - scene->saveToFile("saveToFile_destroyEffect.ramses", false); + ASSERT_TRUE(scene->saveToFile("saveToFile_destroyEffect.ramses")); ASSERT_TRUE(std::filesystem::remove("saveToFile_destroyEffect.ramses")); -} \ No newline at end of file +} + +TEST(ramses, log_export) { + static ramses::RamsesFrameworkConfig config(ramses::EFeatureLevel::EFeatureLevel_01); + config.setLogLevel(ramses::ELogLevel::Trace); + ramses::RamsesFramework ramsesFramework{config}; + ramses::RamsesClient& client = *ramsesFramework.createClient("example client"); + ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), "example scene"); + + ramses::SaveFileConfig saveConfig; + saveConfig.setMetadataString(R"({ + "generator" : "test" +})"); + ASSERT_TRUE(scene->saveToFile("saveToFile_empty.ramses", saveConfig)); + ASSERT_TRUE(std::filesystem::remove("saveToFile_empty.ramses")); +} + +TEST(ramses, log_create_node) { + ramses::RamsesFrameworkConfig config{ramses::EFeatureLevel::EFeatureLevel_01}; + config.setLogLevel(ramses::ELogLevel::Trace); + ramses::RamsesFramework ramsesFramework{config}; + ramses::RamsesClient& client = *ramsesFramework.createClient("example client"); + ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), "example scene"); + + scene->createNode("{}"); +} diff --git a/components/libRamsesBase/tests/RenderLayerAdaptor_test.cpp b/components/libRamsesBase/tests/RenderLayerAdaptor_test.cpp index 2b3030f9..949cb611 100644 --- a/components/libRamsesBase/tests/RenderLayerAdaptor_test.cpp +++ b/components/libRamsesBase/tests/RenderLayerAdaptor_test.cpp @@ -15,31 +15,31 @@ #include "user_types/RenderLayer.h" #include "user_types/Enumerations.h" -using raco::user_types::Material; -using raco::user_types::MeshNode; -using raco::user_types::Node; -using raco::user_types::RenderLayer; +using user_types::Material; +using user_types::MeshNode; +using user_types::Node; +using user_types::RenderLayer; class RenderLayerAdaptorTest : public RamsesBaseFixture<> { protected: int32_t getSortOrder(const ramses::RenderGroup& group, const ramses::MeshNode& meshnode) { int32_t order; auto status = group.getMeshNodeOrder(meshnode, order); - EXPECT_EQ(status, ramses::StatusOK); + EXPECT_TRUE(status); return order; } int32_t getGroupSortOrder(const ramses::RenderGroup& group, const ramses::RenderGroup& nestedGroup) { int32_t order; auto status = group.getRenderGroupOrder(nestedGroup, order); - EXPECT_EQ(status, ramses::StatusOK); + EXPECT_TRUE(status); return order; } - void set_renderables(raco::user_types::SRenderLayer layer, const std::vector>& renderables) { + void set_renderables(user_types::SRenderLayer layer, const std::vector>& renderables) { context.removeAllProperties({layer, {"renderableTags"}}); for (int index = 0; index < renderables.size(); index++) { - context.addProperty({layer, {"renderableTags"}}, renderables[index].first, std::make_unique>(renderables[index].second)); + context.addProperty({layer, {"renderableTags"}}, renderables[index].first, std::make_unique>(renderables[index].second)); } } @@ -149,9 +149,9 @@ TEST_F(RenderLayerAdaptorTest, renderables_meshnode_root_add_layer_renderable) { auto engineGroup = select(*sceneContext.scene(), "layer"); ASSERT_FALSE(engineGroup->containsMeshNode(*engineMeshNode)); - ASSERT_TRUE(sceneContext.scene()->findObjectByName("layer.render_main") == nullptr); + ASSERT_TRUE(sceneContext.scene()->findObject("layer.render_main") == nullptr); - context.addProperty({layer, {"renderableTags"}}, "render_main", std::make_unique>(0)); + context.addProperty({layer, {"renderableTags"}}, "render_main", std::make_unique>(0)); dispatch(); auto engineGroupNested = select(*sceneContext.scene(), "layer.render_main"); ASSERT_FALSE(engineGroup->containsMeshNode(*engineMeshNode)); @@ -213,7 +213,7 @@ TEST_F(RenderLayerAdaptorTest, matfilter_toggle_invert) { ASSERT_TRUE(engineGroupNested->containsMeshNode(*engineMeshNode_def)); ASSERT_FALSE(engineGroupNested->containsMeshNode(*engineMeshNode_alt)); - context.set({layer, &raco::user_types::RenderLayer::materialFilterMode_}, static_cast(raco::user_types::ERenderLayerMaterialFilterMode::Exclusive)); + context.set({layer, &user_types::RenderLayer::materialFilterMode_}, static_cast(user_types::ERenderLayerMaterialFilterMode::Exclusive)); dispatch(); engineGroupNested = select(*sceneContext.scene(), "layer.render_main"); @@ -415,7 +415,7 @@ TEST_F(RenderLayerAdaptorTest, matfilter_nested_toggle_invert) { ASSERT_FALSE(engineGroupNested->containsMeshNode(*engineMeshNode_def)); ASSERT_TRUE(engineGroupNested->containsMeshNode(*engineMeshNode_alt)); - context.set({layer, &raco::user_types::RenderLayer::materialFilterMode_}, static_cast(raco::user_types::ERenderLayerMaterialFilterMode::Exclusive)); + context.set({layer, &user_types::RenderLayer::materialFilterMode_}, static_cast(user_types::ERenderLayerMaterialFilterMode::Exclusive)); dispatch(); engineGroupNested = select(*sceneContext.scene(), "layer.render_main"); @@ -541,7 +541,7 @@ TEST_F(RenderLayerAdaptorTest, sortorder_manual) { auto meshnode2 = create("meshnode2", nullptr, {"render_alt"}); auto meshnode3 = create("meshnode3", root); auto layer = create_layer("layer", {}, {{"render_main", 0}, {"render_alt", 1}}); - context.set({layer, {"sortOrder"}}, static_cast(raco::user_types::ERenderLayerOrder::Manual)); + context.set({layer, {"sortOrder"}}, static_cast(user_types::ERenderLayerOrder::Manual)); dispatch(); @@ -594,7 +594,7 @@ TEST_F(RenderLayerAdaptorTest, sortorder_scenegraph) { auto meshnode2 = create("meshnode2", nullptr, {"render_alt"}); auto meshnode3 = create("meshnode3", root); auto layer = create_layer("layer", {}, {{"render_main", 0}, {"render_alt", 1}}); - context.set({layer, {"sortOrder"}}, static_cast(raco::user_types::ERenderLayerOrder::SceneGraph)); + context.set({layer, {"sortOrder"}}, static_cast(user_types::ERenderLayerOrder::SceneGraph)); dispatch(); @@ -602,8 +602,8 @@ TEST_F(RenderLayerAdaptorTest, sortorder_scenegraph) { auto engineMeshNode2 = select(*sceneContext.scene(), "meshnode2"); auto engineMeshNode3 = select(*sceneContext.scene(), "meshnode3"); auto engineGroup = select(*sceneContext.scene(), "layer"); - ASSERT_TRUE(sceneContext.scene()->findObjectByName("layer.render_main") == nullptr); - ASSERT_TRUE(sceneContext.scene()->findObjectByName("layer.render_alt") == nullptr); + ASSERT_TRUE(sceneContext.scene()->findObject("layer.render_main") == nullptr); + ASSERT_TRUE(sceneContext.scene()->findObject("layer.render_alt") == nullptr); ASSERT_TRUE(engineGroup->containsMeshNode(*engineMeshNode1)); ASSERT_TRUE(engineGroup->containsMeshNode(*engineMeshNode2)); @@ -614,8 +614,8 @@ TEST_F(RenderLayerAdaptorTest, sortorder_scenegraph) { set_renderables(layer, {{"render_alt", 0}, {"render_main", 1}}); dispatch(); - ASSERT_TRUE(sceneContext.scene()->findObjectByName("layer.render_main") == nullptr); - ASSERT_TRUE(sceneContext.scene()->findObjectByName("layer.render_alt") == nullptr); + ASSERT_TRUE(sceneContext.scene()->findObject("layer.render_main") == nullptr); + ASSERT_TRUE(sceneContext.scene()->findObject("layer.render_alt") == nullptr); // Priorities are ignored for scene graph sorted render layers. ASSERT_TRUE(engineGroup->containsMeshNode(*engineMeshNode1)); @@ -625,7 +625,7 @@ TEST_F(RenderLayerAdaptorTest, sortorder_scenegraph) { ASSERT_EQ(getSortOrder(*engineGroup, *engineMeshNode2), 3); ASSERT_EQ(getSortOrder(*engineGroup, *engineMeshNode3), 2); - context.set({layer, {"sortOrder"}}, static_cast(raco::user_types::ERenderLayerOrder::Manual)); + context.set({layer, {"sortOrder"}}, static_cast(user_types::ERenderLayerOrder::Manual)); dispatch(); auto engineGroupNested_main = select(*sceneContext.scene(), "layer.render_main"); auto engineGroupNested_alt = select(*sceneContext.scene(), "layer.render_alt"); diff --git a/components/libRamsesBase/tests/Resources_test.cpp b/components/libRamsesBase/tests/Resources_test.cpp index fc7eb853..dcba2b5c 100644 --- a/components/libRamsesBase/tests/Resources_test.cpp +++ b/components/libRamsesBase/tests/Resources_test.cpp @@ -26,18 +26,18 @@ TEST_F(ResourcesAdaptorFixture, texture_name_change) { dispatch(); { - auto engineTextures{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_TextureSampler)}; + auto engineTextures{select(*sceneContext.scene(), ramses::ERamsesObjectType::TextureSampler)}; EXPECT_EQ(engineTextures.size(), 1); - EXPECT_STREQ("texture name", engineTextures[0]->getName()); + EXPECT_TRUE("texture name" == engineTextures[0]->getName()); } context.set({texture, {"objectName"}}, std::string("Changed")); dispatch(); { - auto engineTextures{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_TextureSampler)}; + auto engineTextures{select(*sceneContext.scene(), ramses::ERamsesObjectType::TextureSampler)}; EXPECT_EQ(engineTextures.size(), 1); - EXPECT_STREQ("Changed", engineTextures[0]->getName()); + EXPECT_TRUE("Changed" == engineTextures[0]->getName()); } } @@ -46,9 +46,9 @@ TEST_F(ResourcesAdaptorFixture, texture_info_box) { context.set({texture, {"uri"}}, (test_path() / "images" / "DuckCM.png").string()); dispatch(); - auto infoBoxError = context.errors().getError(raco::core::ValueHandle{texture}); - EXPECT_EQ(infoBoxError.category(), raco::core::ErrorCategory::GENERAL); - EXPECT_EQ(infoBoxError.level(), raco::core::ErrorLevel::INFORMATION); + auto infoBoxError = context.errors().getError(core::ValueHandle{texture}); + EXPECT_EQ(infoBoxError.category(), core::ErrorCategory::GENERAL); + EXPECT_EQ(infoBoxError.level(), core::ErrorLevel::INFORMATION); EXPECT_EQ(infoBoxError.message(), "Texture information\n\nWidth: 512 px\nHeight: 512 px\n\nPNG Bit depth: 8\n\nColor channel flow\nFile -> Ramses -> Shader\nRGBA -> RGBA -> RGBA"); } @@ -62,8 +62,8 @@ TEST_F(ResourcesAdaptorFixture, cube_map_info_box) { context.set({cubemap, {"uriBottom"}}, (test_path() / "images" / "DuckCM.png").string()); dispatch(); - auto infoBoxError = context.errors().getError(raco::core::ValueHandle{cubemap}); - EXPECT_EQ(infoBoxError.category(), raco::core::ErrorCategory::GENERAL); - EXPECT_EQ(infoBoxError.level(), raco::core::ErrorLevel::INFORMATION); + auto infoBoxError = context.errors().getError(core::ValueHandle{cubemap}); + EXPECT_EQ(infoBoxError.category(), core::ErrorCategory::GENERAL); + EXPECT_EQ(infoBoxError.level(), core::ErrorLevel::INFORMATION); EXPECT_EQ(infoBoxError.message(), "CubeMap information\n\nWidth: 512 px\nHeight: 512 px\n\nPNG Bit depth: 8\n\nColor channel flow\nFile -> Ramses -> Shader\nRGBA -> RGBA -> RGBA"); } diff --git a/components/libRamsesBase/tests/SceneContext_test.cpp b/components/libRamsesBase/tests/SceneContext_test.cpp index 7f98a8e0..cd2f5f1e 100644 --- a/components/libRamsesBase/tests/SceneContext_test.cpp +++ b/components/libRamsesBase/tests/SceneContext_test.cpp @@ -9,6 +9,7 @@ */ #include "RamsesBaseFixture.h" +#include "ramses_adaptor/DefaultRamsesObjects.h" #include "user_types/Material.h" #include "user_types/Mesh.h" #include "user_types/MeshNode.h" @@ -18,11 +19,11 @@ #include #include -using raco::ramses_adaptor::SceneAdaptor; -using raco::user_types::Material; -using raco::user_types::Mesh; -using raco::user_types::MeshNode; -using raco::user_types::Node; +using ramses_adaptor::SceneAdaptor; +using user_types::Material; +using user_types::Mesh; +using user_types::MeshNode; +using user_types::Node; class SceneContextTest : public RamsesBaseFixture<> {}; @@ -32,7 +33,7 @@ TEST_F(SceneContextTest, construction_createsSceneWithGivenId) { } TEST_F(SceneContextTest, construction_doesNotCreateDefaultMeshInfo) { - auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_ArrayResource)}; + auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ArrayResource)}; ASSERT_TRUE(meshStuff.empty()); } @@ -40,7 +41,7 @@ TEST_F(SceneContextTest, construction_createSceneWithOneNode) { context.createObject(Node::typeDescription.typeName); dispatch(); - auto sceneNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_Node)}; + auto sceneNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::Node)}; EXPECT_EQ(sceneNodes.size(), 1); } @@ -49,16 +50,16 @@ TEST_F(SceneContextTest, construction_createSceneWithOneMeshNode) { context.createObject(MeshNode::typeDescription.typeName, "MeshName"); dispatch(); - auto sceneMeshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_MeshNode)}; - auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_ArrayResource)}; - auto materialStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_Effect)}; + auto sceneMeshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::MeshNode)}; + auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ArrayResource)}; + auto materialStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::Effect)}; EXPECT_EQ(sceneMeshNodes.size(), 1); - EXPECT_EQ(meshStuff.size(), 2); + EXPECT_EQ(meshStuff.size(), 3); EXPECT_EQ(materialStuff.size(), 1); - EXPECT_TRUE(isRamsesNameInArray(raco::ramses_adaptor::defaultIndexDataBufferName, meshStuff)); - EXPECT_TRUE(isRamsesNameInArray(raco::ramses_adaptor::defaultVertexDataBufferName, meshStuff)); - EXPECT_TRUE(isRamsesNameInArray(raco::ramses_adaptor::defaultEffectName, materialStuff)); + EXPECT_TRUE(isRamsesNameInArray(ramses_adaptor::defaultIndexDataBufferName, meshStuff)); + EXPECT_TRUE(isRamsesNameInArray(ramses_adaptor::defaultVertexDataBufferName, meshStuff)); + EXPECT_TRUE(isRamsesNameInArray(ramses_adaptor::defaultEffectWithNormalsName, materialStuff)); } TEST_F(SceneContextTest, construction_createThenDeleteOneMeshNode) { @@ -68,7 +69,7 @@ TEST_F(SceneContextTest, construction_createThenDeleteOneMeshNode) { context.deleteObjects({meshNode}); dispatch(); - auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_ArrayResource)}; + auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ArrayResource)}; ASSERT_TRUE(meshStuff.empty()); } @@ -79,19 +80,19 @@ TEST_F(SceneContextTest, construction_createMeshNodeWithMesh) { auto mesh = context.createObject(Mesh::typeDescription.typeName, "Mesh"); auto material = context.createObject(Material::typeDescription.typeName, "Material"); - context.set(raco::core::ValueHandle{mesh, {"uri"}}, (test_path() / "meshes/Duck.glb").string()); - context.set(raco::core::ValueHandle{material, {"uriVertex"}}, (test_path() / "shaders/simple_texture.vert").string()); - context.set(raco::core::ValueHandle{material, {"uriFragment"}}, (test_path() / "shaders/simple_texture.frag").string()); + context.set(core::ValueHandle{mesh, {"uri"}}, (test_path() / "meshes/Duck.glb").string()); + context.set(core::ValueHandle{material, {"uriVertex"}}, (test_path() / "shaders/simple_texture.vert").string()); + context.set(core::ValueHandle{material, {"uriFragment"}}, (test_path() / "shaders/simple_texture.frag").string()); context.moveScenegraphChildren({meshNode}, node); - context.set(raco::core::ValueHandle{meshNode, {"mesh"}}, mesh); - context.set(raco::core::ValueHandle{meshNode, {"materials", "material", "material"}}, material); + context.set(core::ValueHandle{meshNode, {"mesh"}}, mesh); + context.set(core::ValueHandle{meshNode, {"materials", "material", "material"}}, material); dispatch(); - auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_ArrayResource)}; - auto materialStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_Effect)}; - auto appearances{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_Appearance)}; + auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ArrayResource)}; + auto materialStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::Effect)}; + auto appearances{select(*sceneContext.scene(), ramses::ERamsesObjectType::Appearance)}; ASSERT_EQ(meshStuff.size(), 4); ASSERT_TRUE(isRamsesNameInArray("Mesh_MeshIndexData", meshStuff)); @@ -111,24 +112,24 @@ TEST_F(SceneContextTest, construction_createOneMeshNodeWithMeshAndOneMeshNodeWit auto meshNode2 = context.createObject(MeshNode::typeDescription.typeName, "Mesh Node2"); auto mesh = context.createObject(Mesh::typeDescription.typeName, "Mesh"); - context.set(raco::core::ValueHandle{mesh, {"uri"}}, (test_path() / "meshes/Duck.glb").string()); + context.set(core::ValueHandle{mesh, {"uri"}}, (test_path() / "meshes/Duck.glb").string()); - context.set(raco::core::ValueHandle{meshNode, {"mesh"}}, mesh); + context.set(core::ValueHandle{meshNode, {"mesh"}}, mesh); dispatch(); - auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_ArrayResource)}; - auto materialStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_Effect)}; + auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ArrayResource)}; + auto materialStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::Effect)}; - ASSERT_EQ(meshStuff.size(), 6); - ASSERT_TRUE(isRamsesNameInArray(raco::ramses_adaptor::defaultIndexDataBufferName, meshStuff)); - ASSERT_TRUE(isRamsesNameInArray(raco::ramses_adaptor::defaultVertexDataBufferName, meshStuff)); + ASSERT_EQ(meshStuff.size(), 7); // duck: position, normal, tex_coord, inex; default: position, normal, index + ASSERT_TRUE(isRamsesNameInArray(ramses_adaptor::defaultIndexDataBufferName, meshStuff)); + ASSERT_TRUE(isRamsesNameInArray(ramses_adaptor::defaultVertexDataBufferName, meshStuff)); + ASSERT_TRUE(isRamsesNameInArray(ramses_adaptor::defaultNormalDataBufferName, meshStuff)); ASSERT_TRUE(isRamsesNameInArray("Mesh_MeshIndexData", meshStuff)); ASSERT_TRUE(isRamsesNameInArray("Mesh_MeshVertexData_a_Position", meshStuff)); ASSERT_TRUE(isRamsesNameInArray("Mesh_MeshVertexData_a_Normal", meshStuff)); ASSERT_TRUE(isRamsesNameInArray("Mesh_MeshVertexData_a_TextureCoordinate", meshStuff)); - ASSERT_EQ(materialStuff.size(), 2); - ASSERT_TRUE(isRamsesNameInArray(raco::ramses_adaptor::defaultEffectName, materialStuff)); - ASSERT_TRUE(isRamsesNameInArray(raco::ramses_adaptor::defaultEffectWithNormalsName, materialStuff)); + ASSERT_EQ(materialStuff.size(), 1); + ASSERT_TRUE(isRamsesNameInArray(ramses_adaptor::defaultEffectWithNormalsName, materialStuff)); } TEST_F(SceneContextTest, construction_createMeshNodeWithMeshThenUnassignMesh) { @@ -137,29 +138,30 @@ TEST_F(SceneContextTest, construction_createMeshNodeWithMeshThenUnassignMesh) { auto mesh = context.createObject(Mesh::typeDescription.typeName, "Mesh"); auto material = context.createObject(Material::typeDescription.typeName, "Material"); - context.set(raco::core::ValueHandle{mesh, {"uri"}}, (test_path() / "meshes/Duck.glb").string()); + context.set(core::ValueHandle{mesh, {"uri"}}, (test_path() / "meshes/Duck.glb").string()); context.moveScenegraphChildren({meshNode}, node); - context.set(raco::core::ValueHandle{meshNode, {"mesh"}}, mesh); - context.set(raco::core::ValueHandle{meshNode, {"materials", "material", "material"}}, material); + context.set(core::ValueHandle{meshNode, {"mesh"}}, mesh); + context.set(core::ValueHandle{meshNode, {"materials", "material", "material"}}, material); dispatch(); - context.set(raco::core::ValueHandle{meshNode, {"mesh"}}, raco::core::SEditorObject{nullptr}); + context.set(core::ValueHandle{meshNode, {"mesh"}}, core::SEditorObject{nullptr}); dispatch(); - auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_ArrayResource)}; - auto materialStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_Effect)}; + auto meshStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ArrayResource)}; + auto materialStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::Effect)}; - ASSERT_EQ(meshStuff.size(), 6); - ASSERT_TRUE(isRamsesNameInArray(raco::ramses_adaptor::defaultIndexDataBufferName, meshStuff)); - ASSERT_TRUE(isRamsesNameInArray(raco::ramses_adaptor::defaultVertexDataBufferName, meshStuff)); + ASSERT_EQ(meshStuff.size(), 7); + ASSERT_TRUE(isRamsesNameInArray(ramses_adaptor::defaultIndexDataBufferName, meshStuff)); + ASSERT_TRUE(isRamsesNameInArray(ramses_adaptor::defaultVertexDataBufferName, meshStuff)); + ASSERT_TRUE(isRamsesNameInArray(ramses_adaptor::defaultNormalDataBufferName, meshStuff)); ASSERT_TRUE(isRamsesNameInArray("Mesh_MeshIndexData", meshStuff)); ASSERT_TRUE(isRamsesNameInArray("Mesh_MeshVertexData_a_Position", meshStuff)); ASSERT_TRUE(isRamsesNameInArray("Mesh_MeshVertexData_a_Normal", meshStuff)); ASSERT_TRUE(isRamsesNameInArray("Mesh_MeshVertexData_a_TextureCoordinate", meshStuff)); ASSERT_EQ(materialStuff.size(), 2); - ASSERT_TRUE(isRamsesNameInArray(raco::ramses_adaptor::defaultEffectName, materialStuff)); + ASSERT_TRUE(isRamsesNameInArray(ramses_adaptor::defaultEffectWithNormalsName, materialStuff)); ASSERT_TRUE(isRamsesNameInArray("Material", materialStuff)); } @@ -169,12 +171,12 @@ TEST_F(SceneContextTest, construction_createSceneWithSimpleHierarchy) { context.moveScenegraphChildren({child}, {parent}); dispatch(); - auto sceneNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_Node)}; - auto sceneMeshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_MeshNode)}; + auto sceneNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::Node)}; + auto sceneMeshNodes{select(*sceneContext.scene(), ramses::ERamsesObjectType::MeshNode)}; EXPECT_EQ(sceneNodes.size(), 1); EXPECT_EQ(sceneMeshNodes.size(), 1); - EXPECT_EQ(sceneMeshNodes.at(0)->getParent(), sceneNodes.at(0)); + EXPECT_EQ(static_cast(sceneMeshNodes.at(0))->getParent(), sceneNodes.at(0)); } TEST_F(SceneContextTest, construction_createSceneWithSimpleHierarchy_reverseNodeCreation) { @@ -183,12 +185,12 @@ TEST_F(SceneContextTest, construction_createSceneWithSimpleHierarchy_reverseNode context.moveScenegraphChildren({child}, {parent}); dispatch(); - auto nodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType_Node)); - auto meshNodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType_MeshNode)); + auto nodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType::Node)); + auto meshNodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType::MeshNode)); EXPECT_EQ(nodeSceneElements.size(), 1); EXPECT_EQ(meshNodeSceneElements.size(), 1); - EXPECT_EQ(meshNodeSceneElements.at(0)->getParent(), nodeSceneElements.at(0)); + EXPECT_EQ(static_cast(meshNodeSceneElements.at(0))->getParent(), nodeSceneElements.at(0)); } TEST_F(SceneContextTest, construction_createSceneWithDeeperHierarchy) { @@ -199,8 +201,8 @@ TEST_F(SceneContextTest, construction_createSceneWithDeeperHierarchy) { context.moveScenegraphChildren({child2}, {child1}); dispatch(); - auto nodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType_Node)); - auto meshNodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType_MeshNode)); + auto nodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType::Node)); + auto meshNodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType::MeshNode)); EXPECT_EQ(nodeSceneElements.size(), 2); EXPECT_EQ(meshNodeSceneElements.size(), 1); @@ -212,9 +214,9 @@ TEST_F(SceneContextTest, construction_createSceneWithDeeperHierarchy) { EXPECT_TRUE(ramsesRoot); // Check hierarchy - EXPECT_EQ(ramsesRoot->getParent(), nullptr); - EXPECT_EQ(ramsesChild1->getParent(), ramsesRoot); - EXPECT_EQ(meshNodeSceneElements[0]->getParent(), ramsesChild1); + EXPECT_EQ(static_cast(ramsesRoot)->getParent(), nullptr); + EXPECT_EQ(static_cast(ramsesChild1)->getParent(), ramsesRoot); + EXPECT_EQ(static_cast(meshNodeSceneElements[0])->getParent(), ramsesChild1); } TEST_F(SceneContextTest, construction_createSceneWithDeeperHierarchy_reverseNodeCreation) { @@ -225,8 +227,8 @@ TEST_F(SceneContextTest, construction_createSceneWithDeeperHierarchy_reverseNode context.moveScenegraphChildren({child2}, {child1}); dispatch(); - auto nodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType_Node)); - auto meshNodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType_MeshNode)); + auto nodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType::Node)); + auto meshNodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType::MeshNode)); EXPECT_EQ(nodeSceneElements.size(), 2); EXPECT_EQ(meshNodeSceneElements.size(), 1); @@ -238,16 +240,16 @@ TEST_F(SceneContextTest, construction_createSceneWithDeeperHierarchy_reverseNode EXPECT_TRUE(ramsesRoot); // Expectation depends on order of ramses::SceneObjectIterator, if this fails also check if this order has not changed - EXPECT_EQ(ramsesRoot->getParent(), nullptr); - EXPECT_EQ(ramsesChild1->getParent(), ramsesRoot); - EXPECT_EQ(meshNodeSceneElements.at(0)->getParent(), ramsesChild1); + EXPECT_EQ(static_cast(ramsesRoot)->getParent(), nullptr); + EXPECT_EQ(static_cast(ramsesChild1)->getParent(), ramsesRoot); + EXPECT_EQ(static_cast(meshNodeSceneElements[0])->getParent(), ramsesChild1); } TEST_F(SceneContextTest, dataChange_dynamicInsert_rootNode) { auto root = context.createObject(Node::typeDescription.typeName); dispatch(); - auto nodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType_Node)); + auto nodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType::Node)); EXPECT_EQ(nodeSceneElements.size(), 1); } @@ -259,12 +261,12 @@ TEST_F(SceneContextTest, dataChange_dynamicInsert_childNode) { context.moveScenegraphChildren({child}, {root}); dispatch(); - auto nodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType_Node)); - auto meshNodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType_MeshNode)); + auto nodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType::Node)); + auto meshNodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType::MeshNode)); EXPECT_EQ(nodeSceneElements.size(), 1); EXPECT_EQ(meshNodeSceneElements.size(), 1); - EXPECT_EQ(static_cast(meshNodeSceneElements.at(0))->getParent(), nodeSceneElements.at(0)); + EXPECT_EQ(static_cast(meshNodeSceneElements.at(0))->getParent(), nodeSceneElements.at(0)); } TEST_F(SceneContextTest, dataChange_dynamicDelete_rootNode) { @@ -288,15 +290,15 @@ TEST_F(SceneContextTest, dataChange_dynamicReparenting_move) { context.moveScenegraphChildren({child}, {parent_2}); dispatch(); - auto nodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType_Node)); - auto meshNodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType_MeshNode)); + auto nodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType::Node)); + auto meshNodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType::MeshNode)); EXPECT_EQ(nodeSceneElements.size(), 2); EXPECT_EQ(meshNodeSceneElements.size(), 1); auto ramsesParent2 = select(*sceneContext.scene(), "Parent 2"); - EXPECT_TRUE(0 == std::memcmp(ramsesParent2->getName(), "Parent 2", sizeof("Parent 2"))); - EXPECT_EQ(static_cast(meshNodeSceneElements.at(0))->getParent(), ramsesParent2); + EXPECT_TRUE(ramsesParent2->getName() == "Parent 2"); + EXPECT_EQ(static_cast(meshNodeSceneElements.at(0))->getParent(), ramsesParent2); } TEST_F(SceneContextTest, dataChange_dynamicReparenting_noParent) { @@ -308,13 +310,13 @@ TEST_F(SceneContextTest, dataChange_dynamicReparenting_noParent) { context.moveScenegraphChildren({child}, {}); dispatch(); - auto nodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType_Node)); - auto meshNodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType_MeshNode)); + auto nodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType::Node)); + auto meshNodeSceneElements(select(*sceneContext.scene(), ramses::ERamsesObjectType::MeshNode)); EXPECT_EQ(nodeSceneElements.size(), 1); EXPECT_EQ(meshNodeSceneElements.size(), 1); - EXPECT_EQ(static_cast(meshNodeSceneElements.at(0))->getParent(), nullptr); + EXPECT_EQ(static_cast(meshNodeSceneElements.at(0))->getParent(), nullptr); } TEST_F(SceneContextTest, construction_createSceneWithDeeperHierarchy_reverseNodeCreation2) { @@ -371,7 +373,7 @@ struct SceneContextParamTestFixture : public RamsesBaseFixture<::testing::TestWi }; TEST_P(SceneContextParamTestFixture, contextCreationOrder_init) { - std::map objects{}; + std::map objects{}; objects[GetParam().typeName(0)] = context.createObject(GetParam().typeName(0)); objects[GetParam().typeName(1)] = context.createObject(GetParam().typeName(1)); @@ -383,18 +385,18 @@ TEST_P(SceneContextParamTestFixture, contextCreationOrder_init) { auto mesh = objects.at(Mesh::typeDescription.typeName); auto material = objects.at(Material::typeDescription.typeName); - context.set(raco::core::ValueHandle{mesh, {"uri"}}, (test_path() / "meshes/Duck.glb").string()); + context.set(core::ValueHandle{mesh, {"uri"}}, (test_path() / "meshes/Duck.glb").string()); context.moveScenegraphChildren({meshNode}, node); - context.set(raco::core::ValueHandle{meshNode, {"mesh"}}, mesh); - context.set(raco::core::ValueHandle{meshNode, {"materials", "material", "material"}}, material); + context.set(core::ValueHandle{meshNode, {"mesh"}}, mesh); + context.set(core::ValueHandle{meshNode, {"materials", "material", "material"}}, material); // should not explode - SceneAdaptor sceneContext{&backend.client(), &backend.logicEngine(), ramses::sceneId_t{2u}, &project, dataChangeDispatcher, &errors}; + SceneAdaptor sceneContext{&backend.client(), ramses::sceneId_t{2u}, &project, dataChangeDispatcher, &errors}; } TEST_P(SceneContextParamTestFixture, contextCreationOrder_dispatch) { - std::map objects{}; + std::map objects{}; objects[GetParam().typeName(0)] = context.createObject(GetParam().typeName(0)); objects[GetParam().typeName(1)] = context.createObject(GetParam().typeName(1)); @@ -406,11 +408,11 @@ TEST_P(SceneContextParamTestFixture, contextCreationOrder_dispatch) { auto mesh = objects.at(Mesh::typeDescription.typeName); auto material = objects.at(Material::typeDescription.typeName); - context.set(raco::core::ValueHandle{mesh, {"uri"}}, (test_path() / "meshes/Duck.glb").string()); + context.set(core::ValueHandle{mesh, {"uri"}}, (test_path() / "meshes/Duck.glb").string()); context.moveScenegraphChildren({meshNode}, node); - context.set(raco::core::ValueHandle{meshNode, {"mesh"}}, mesh); - context.set(raco::core::ValueHandle{meshNode, {"materials", "material", "material"}}, material); + context.set(core::ValueHandle{meshNode, {"mesh"}}, mesh); + context.set(core::ValueHandle{meshNode, {"materials", "material", "material"}}, material); // should not explode dispatch(); diff --git a/components/libRamsesBase/tests/SkinAdaptor_test.cpp b/components/libRamsesBase/tests/SkinAdaptor_test.cpp index eb02d138..dabe63fb 100644 --- a/components/libRamsesBase/tests/SkinAdaptor_test.cpp +++ b/components/libRamsesBase/tests/SkinAdaptor_test.cpp @@ -31,7 +31,7 @@ TEST_F(SkinAdaptorTest, create_success) { EXPECT_FALSE(commandInterface.errors().hasError({skin})); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); } TEST_F(SkinAdaptorTest, error_no_meshnode) { @@ -47,7 +47,7 @@ TEST_F(SkinAdaptorTest, error_no_meshnode) { dispatch(); EXPECT_TRUE(commandInterface.errors().hasError({skin})); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); } TEST_F(SkinAdaptorTest, error_node_missing_end) { @@ -63,7 +63,7 @@ TEST_F(SkinAdaptorTest, error_node_missing_end) { dispatch(); EXPECT_TRUE(commandInterface.errors().hasError({skin})); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); } TEST_F(SkinAdaptorTest, error_node_missing_front) { @@ -79,7 +79,7 @@ TEST_F(SkinAdaptorTest, error_node_missing_front) { dispatch(); EXPECT_TRUE(commandInterface.errors().hasError({skin})); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); } TEST_F(SkinAdaptorTest, error_appearance_public) { @@ -95,5 +95,5 @@ TEST_F(SkinAdaptorTest, error_appearance_public) { dispatch(); EXPECT_TRUE(commandInterface.errors().hasError({skin})); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 0); } diff --git a/components/libRamsesBase/tests/TextureAdaptor_test.cpp b/components/libRamsesBase/tests/TextureAdaptor_test.cpp index c061b30b..a98fb608 100644 --- a/components/libRamsesBase/tests/TextureAdaptor_test.cpp +++ b/components/libRamsesBase/tests/TextureAdaptor_test.cpp @@ -12,18 +12,21 @@ #include "RamsesBaseFixture.h" #include "ramses_adaptor/TextureSamplerAdaptor.h" #include "testing/TestUtil.h" +#include "user_types/Enumerations.h" + +using user_types::ETextureFormat; class TextureAdaptorFixture : public RamsesBaseFixture<> { public: - void checkTextureFormats(raco::core::SEditorObject texture, const std::map& formats) { + void checkTextureFormats(core::SEditorObject texture, const std::map& formats) { for (const auto& [format, level] : formats) { - commandInterface.set({texture, &raco::user_types::Texture::textureFormat_}, static_cast(format)); + commandInterface.set({texture, &user_types::Texture::textureFormat_}, static_cast(format)); dispatch(); - if (level == raco::core::ErrorLevel::NONE) { - ASSERT_FALSE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::uri_})); + if (level == core::ErrorLevel::NONE) { + ASSERT_FALSE(commandInterface.errors().hasError({texture, &user_types::Texture::uri_})); } else { - ASSERT_TRUE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::uri_})); - ASSERT_EQ(commandInterface.errors().getError({texture, &raco::user_types::Texture::uri_}).level(), level); + ASSERT_TRUE(commandInterface.errors().hasError({texture, &user_types::Texture::uri_})); + ASSERT_EQ(commandInterface.errors().getError({texture, &user_types::Texture::uri_}).level(), level); } } } @@ -31,439 +34,439 @@ class TextureAdaptorFixture : public RamsesBaseFixture<> { }; TEST_F(TextureAdaptorFixture, textureFormat8BitPalette) { - auto texture = create("texture"); + auto texture = create("texture"); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "text-back-palette.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "text-back-palette.png").string()); dispatch(); - checkTextureFormats(texture, {{ramses::ETextureFormat::R8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RG8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RGB8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RGBA8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RGB16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::SRGB8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::SRGB8_ALPHA8, raco::core::ErrorLevel::INFORMATION}}); + checkTextureFormats(texture, {{ETextureFormat::R8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RG8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RGB8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RGBA8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RGB16F, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA16F, core::ErrorLevel::ERROR}, + {ETextureFormat::SRGB8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::SRGB8_ALPHA8, core::ErrorLevel::INFORMATION}}); } TEST_F(TextureAdaptorFixture, textureFormatR8) { - auto texture = create("texture"); + auto texture = create("texture"); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "green_512_gray.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "green_512_gray.png").string()); dispatch(); - checkTextureFormats(texture, {{ramses::ETextureFormat::R8, raco::core::ErrorLevel::NONE}, + checkTextureFormats(texture, {{ETextureFormat::R8, core::ErrorLevel::NONE}, // Swizzling results in R8 ramses texture format, being compatible with GRAY image. No warnings expected. - {ramses::ETextureFormat::RG8, raco::core::ErrorLevel::NONE}, - {ramses::ETextureFormat::RGB8, raco::core::ErrorLevel::NONE}, - {ramses::ETextureFormat::RGBA8, raco::core::ErrorLevel::NONE}, + {ETextureFormat::RG8, core::ErrorLevel::NONE}, + {ETextureFormat::RGB8, core::ErrorLevel::NONE}, + {ETextureFormat::RGBA8, core::ErrorLevel::NONE}, // Swizzling results in R16F ramses format. It is incompatible with 8 bit image. - {ramses::ETextureFormat::RGB16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA16F, raco::core::ErrorLevel::ERROR}, + {ETextureFormat::RGB16F, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA16F, core::ErrorLevel::ERROR}, // Swizzling results in R8 ramses texture format, being compatible with GRAY image. No warnings expected. - {ramses::ETextureFormat::SRGB8, raco::core::ErrorLevel::NONE}, - {ramses::ETextureFormat::SRGB8_ALPHA8, raco::core::ErrorLevel::NONE}}); + {ETextureFormat::SRGB8, core::ErrorLevel::NONE}, + {ETextureFormat::SRGB8_ALPHA8, core::ErrorLevel::NONE}}); } TEST_F(TextureAdaptorFixture, textureFormatRG16) { - auto texture = create("texture"); + auto texture = create("texture"); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "green_512_gray_16f.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "green_512_gray_16f.png").string()); dispatch(); - checkTextureFormats(texture, {{ramses::ETextureFormat::R8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RG8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGB8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGB16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::SRGB8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::SRGB8_ALPHA8, raco::core::ErrorLevel::ERROR}}); + checkTextureFormats(texture, {{ETextureFormat::R8, core::ErrorLevel::ERROR}, + {ETextureFormat::RG8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGB8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGB16F, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA16F, core::ErrorLevel::ERROR}, + {ETextureFormat::SRGB8, core::ErrorLevel::ERROR}, + {ETextureFormat::SRGB8_ALPHA8, core::ErrorLevel::ERROR}}); } TEST_F(TextureAdaptorFixture, textureFormatRG8) { - auto texture = create("texture"); + auto texture = create("texture"); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "green_512_gray_alpha.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "green_512_gray_alpha.png").string()); dispatch(); - checkTextureFormats(texture, {{ramses::ETextureFormat::R8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RG8, raco::core::ErrorLevel::NONE}, + checkTextureFormats(texture, {{ETextureFormat::R8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RG8, core::ErrorLevel::NONE}, // Swizzling results in R8 ramses texture format, must be info same as above. - {ramses::ETextureFormat::RGB8, raco::core::ErrorLevel::INFORMATION}, + {ETextureFormat::RGB8, core::ErrorLevel::INFORMATION}, // Swizzling results in RG8 ramses texture format, compatible with image, no errors. - {ramses::ETextureFormat::RGBA8, raco::core::ErrorLevel::NONE}, - {ramses::ETextureFormat::RGB16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA16F, raco::core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA8, core::ErrorLevel::NONE}, + {ETextureFormat::RGB16F, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA16F, core::ErrorLevel::ERROR}, // Swizzling results in R8 ramses texture format, must be info same as above. - {ramses::ETextureFormat::SRGB8, raco::core::ErrorLevel::INFORMATION}, + {ETextureFormat::SRGB8, core::ErrorLevel::INFORMATION}, // Swizzling results in RG8 ramses texture format, compatible with image, no errors. - {ramses::ETextureFormat::SRGB8_ALPHA8, raco::core::ErrorLevel::NONE}}); + {ETextureFormat::SRGB8_ALPHA8, core::ErrorLevel::NONE}}); } TEST_F(TextureAdaptorFixture, textureFormatRGB8) { - auto texture = create("texture"); + auto texture = create("texture"); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "text-back.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "text-back.png").string()); dispatch(); - checkTextureFormats(texture, {{ramses::ETextureFormat::R8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RG8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RGB8, raco::core::ErrorLevel::NONE}, + checkTextureFormats(texture, {{ETextureFormat::R8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RG8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RGB8, core::ErrorLevel::NONE}, // Swizzle format is RGB8, compatible with file, no issues. - {ramses::ETextureFormat::RGBA8, raco::core::ErrorLevel::NONE}, - {ramses::ETextureFormat::RGB16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::SRGB8, raco::core::ErrorLevel::NONE}, + {ETextureFormat::RGBA8, core::ErrorLevel::NONE}, + {ETextureFormat::RGB16F, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA16F, core::ErrorLevel::ERROR}, + {ETextureFormat::SRGB8, core::ErrorLevel::NONE}, // Swizzle format is RGB8, compatible with file, no issues. - {ramses::ETextureFormat::SRGB8_ALPHA8, raco::core::ErrorLevel::NONE}}); + {ETextureFormat::SRGB8_ALPHA8, core::ErrorLevel::NONE}}); } TEST_F(TextureAdaptorFixture, textureFormatRGBA8) { - auto texture = create("texture"); + auto texture = create("texture"); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "green_512.png").string()); dispatch(); - checkTextureFormats(texture, {{ramses::ETextureFormat::R8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RG8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RGB8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RGBA8, raco::core::ErrorLevel::NONE}, - {ramses::ETextureFormat::RGB16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA16F, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::SRGB8, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::SRGB8_ALPHA8, raco::core::ErrorLevel::NONE}}); + checkTextureFormats(texture, {{ETextureFormat::R8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RG8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RGB8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RGBA8, core::ErrorLevel::NONE}, + {ETextureFormat::RGB16F, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA16F, core::ErrorLevel::ERROR}, + {ETextureFormat::SRGB8, core::ErrorLevel::INFORMATION}, + {ETextureFormat::SRGB8_ALPHA8, core::ErrorLevel::NONE}}); } TEST_F(TextureAdaptorFixture, textureFormatRGBA8Flipped) { - auto texture = create("texture"); + auto texture = create("texture"); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({texture, &raco::user_types::Texture::flipTexture_}, true); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({texture, &user_types::Texture::flipTexture_}, true); dispatch(); - commandInterface.set({texture, &raco::user_types::Texture::textureFormat_}, static_cast(ramses::ETextureFormat::RGBA8)); + commandInterface.set({texture, &user_types::Texture::textureFormat_}, static_cast(ETextureFormat::RGBA8)); ASSERT_NO_THROW(dispatch()); - commandInterface.set({texture, &raco::user_types::Texture::textureFormat_}, static_cast(ramses::ETextureFormat::RGB8)); + commandInterface.set({texture, &user_types::Texture::textureFormat_}, static_cast(ETextureFormat::RGB8)); ASSERT_NO_THROW(dispatch()); - commandInterface.set({texture, &raco::user_types::Texture::textureFormat_}, static_cast(ramses::ETextureFormat::RG8)); + commandInterface.set({texture, &user_types::Texture::textureFormat_}, static_cast(ETextureFormat::RG8)); ASSERT_NO_THROW(dispatch()); - commandInterface.set({texture, &raco::user_types::Texture::textureFormat_}, static_cast(ramses::ETextureFormat::R8)); + commandInterface.set({texture, &user_types::Texture::textureFormat_}, static_cast(ETextureFormat::R8)); ASSERT_NO_THROW(dispatch()); - commandInterface.set({texture, &raco::user_types::Texture::textureFormat_}, static_cast(ramses::ETextureFormat::SRGB8)); + commandInterface.set({texture, &user_types::Texture::textureFormat_}, static_cast(ETextureFormat::SRGB8)); ASSERT_NO_THROW(dispatch()); - commandInterface.set({texture, &raco::user_types::Texture::textureFormat_}, static_cast(ramses::ETextureFormat::SRGB8_ALPHA8)); + commandInterface.set({texture, &user_types::Texture::textureFormat_}, static_cast(ETextureFormat::SRGB8_ALPHA8)); ASSERT_NO_THROW(dispatch()); } TEST_F(TextureAdaptorFixture, textureFormatRGB16) { - auto texture = create("texture"); + auto texture = create("texture"); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "green_512_16f_no_alpha.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "green_512_16f_no_alpha.png").string()); dispatch(); - checkTextureFormats(texture, {{ramses::ETextureFormat::R8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RG8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGB8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGB16F, raco::core::ErrorLevel::NONE}, + checkTextureFormats(texture, {{ETextureFormat::R8, core::ErrorLevel::ERROR}, + {ETextureFormat::RG8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGB8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGB16F, core::ErrorLevel::NONE}, // Swizzled format RGB16F is compatible with image data. No warning. - {ramses::ETextureFormat::RGBA16F, raco::core::ErrorLevel::NONE}, - {ramses::ETextureFormat::SRGB8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::SRGB8_ALPHA8, raco::core::ErrorLevel::ERROR}}); + {ETextureFormat::RGBA16F, core::ErrorLevel::NONE}, + {ETextureFormat::SRGB8, core::ErrorLevel::ERROR}, + {ETextureFormat::SRGB8_ALPHA8, core::ErrorLevel::ERROR}}); } TEST_F(TextureAdaptorFixture, textureFormatRGBA16From16i) { - auto texture = create("texture"); + auto texture = create("texture"); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "green_512_16i.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "green_512_16i.png").string()); dispatch(); - checkTextureFormats(texture, {{ramses::ETextureFormat::R8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RG8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGB8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGB16F, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RGBA16F, raco::core::ErrorLevel::NONE}, - {ramses::ETextureFormat::SRGB8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::SRGB8_ALPHA8, raco::core::ErrorLevel::ERROR}}); + checkTextureFormats(texture, {{ETextureFormat::R8, core::ErrorLevel::ERROR}, + {ETextureFormat::RG8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGB8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGB16F, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RGBA16F, core::ErrorLevel::NONE}, + {ETextureFormat::SRGB8, core::ErrorLevel::ERROR}, + {ETextureFormat::SRGB8_ALPHA8, core::ErrorLevel::ERROR}}); } TEST_F(TextureAdaptorFixture, textureFormatRGBA16From16f) { - auto texture = create("texture"); + auto texture = create("texture"); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "green_512_16f.png").string()); dispatch(); - checkTextureFormats(texture, {{ramses::ETextureFormat::R8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RG8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGB8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGBA8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::RGB16F, raco::core::ErrorLevel::INFORMATION}, - {ramses::ETextureFormat::RGBA16F, raco::core::ErrorLevel::NONE}, - {ramses::ETextureFormat::SRGB8, raco::core::ErrorLevel::ERROR}, - {ramses::ETextureFormat::SRGB8_ALPHA8, raco::core::ErrorLevel::ERROR}}); + checkTextureFormats(texture, {{ETextureFormat::R8, core::ErrorLevel::ERROR}, + {ETextureFormat::RG8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGB8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGBA8, core::ErrorLevel::ERROR}, + {ETextureFormat::RGB16F, core::ErrorLevel::INFORMATION}, + {ETextureFormat::RGBA16F, core::ErrorLevel::NONE}, + {ETextureFormat::SRGB8, core::ErrorLevel::ERROR}, + {ETextureFormat::SRGB8_ALPHA8, core::ErrorLevel::ERROR}}); } TEST_F(TextureAdaptorFixture, textureFormatRGBA16Flipped) { - auto texture = create("texture"); + auto texture = create("texture"); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "green_512_16f.png").string()); - commandInterface.set({texture, &raco::user_types::Texture::flipTexture_}, true); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({texture, &user_types::Texture::flipTexture_}, true); dispatch(); - commandInterface.set({texture, &raco::user_types::Texture::textureFormat_}, static_cast(ramses::ETextureFormat::RGBA16F)); + commandInterface.set({texture, &user_types::Texture::textureFormat_}, static_cast(ETextureFormat::RGBA16F)); ASSERT_NO_THROW(dispatch()); - commandInterface.set({texture, &raco::user_types::Texture::textureFormat_}, static_cast(ramses::ETextureFormat::RGB16F)); + commandInterface.set({texture, &user_types::Texture::textureFormat_}, static_cast(ETextureFormat::RGB16F)); ASSERT_NO_THROW(dispatch()); } TEST_F(TextureAdaptorFixture, textureFormatChangeValidToInvalid) { - auto texture = create("texture"); + auto texture = create("texture"); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "green_512_16f.png").string()); dispatch(); // RGBA16 - commandInterface.set({texture, &raco::user_types::Texture::textureFormat_}, static_cast(ramses::ETextureFormat::RGBA16F)); + commandInterface.set({texture, &user_types::Texture::textureFormat_}, static_cast(ETextureFormat::RGBA16F)); dispatch(); - ASSERT_FALSE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::uri_})); + ASSERT_FALSE(commandInterface.errors().hasError({texture, &user_types::Texture::uri_})); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "green_512.png").string()); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::uri_})); - ASSERT_EQ(commandInterface.errors().getError({texture, &raco::user_types::Texture::uri_}).level(), raco::core::ErrorLevel::ERROR); + ASSERT_TRUE(commandInterface.errors().hasError({texture, &user_types::Texture::uri_})); + ASSERT_EQ(commandInterface.errors().getError({texture, &user_types::Texture::uri_}).level(), core::ErrorLevel::ERROR); // R8 - commandInterface.set({texture, &raco::user_types::Texture::textureFormat_}, static_cast(ramses::ETextureFormat::R8)); + commandInterface.set({texture, &user_types::Texture::textureFormat_}, static_cast(ETextureFormat::R8)); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::uri_})); - ASSERT_EQ(commandInterface.errors().getError({texture, &raco::user_types::Texture::uri_}).level(), raco::core::ErrorLevel::INFORMATION); + ASSERT_TRUE(commandInterface.errors().hasError({texture, &user_types::Texture::uri_})); + ASSERT_EQ(commandInterface.errors().getError({texture, &user_types::Texture::uri_}).level(), core::ErrorLevel::INFORMATION); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "green_512_16f.png").string()); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::uri_})); - ASSERT_EQ(commandInterface.errors().getError({texture, &raco::user_types::Texture::uri_}).level(), raco::core::ErrorLevel::ERROR); + ASSERT_TRUE(commandInterface.errors().hasError({texture, &user_types::Texture::uri_})); + ASSERT_EQ(commandInterface.errors().getError({texture, &user_types::Texture::uri_}).level(), core::ErrorLevel::ERROR); // RGBA16 - commandInterface.set({texture, &raco::user_types::Texture::textureFormat_}, static_cast(ramses::ETextureFormat::RGBA16F)); + commandInterface.set({texture, &user_types::Texture::textureFormat_}, static_cast(ETextureFormat::RGBA16F)); dispatch(); - ASSERT_FALSE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::uri_})); + ASSERT_FALSE(commandInterface.errors().hasError({texture, &user_types::Texture::uri_})); } TEST_F(TextureAdaptorFixture, textureGenerationAtMultipleLevels) { - auto texture = create("Texture"); + auto texture = create("Texture"); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "blue_1024.png").string()); dispatch(); - commandInterface.set({texture, &raco::user_types::Texture::level2uri_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({texture, &user_types::Texture::level2uri_}, (test_path() / "images" / "green_512.png").string()); dispatch(); - commandInterface.set({texture, &raco::user_types::Texture::level3uri_}, (test_path() / "images" / "yellow_256.png").string()); + commandInterface.set({texture, &user_types::Texture::level3uri_}, (test_path() / "images" / "yellow_256.png").string()); dispatch(); - commandInterface.set({texture, &raco::user_types::Texture::level4uri_}, (test_path() / "images" / "red_128.png").string()); + commandInterface.set({texture, &user_types::Texture::level4uri_}, (test_path() / "images" / "red_128.png").string()); dispatch(); - auto textureStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_TextureSampler)}; + auto textureStuff{select(*sceneContext.scene(), ramses::ERamsesObjectType::TextureSampler)}; ASSERT_EQ(textureStuff.size(), 1); - commandInterface.set({texture, &raco::user_types::Texture::mipmapLevel_}, 2); + commandInterface.set({texture, &user_types::Texture::mipmapLevel_}, 2); dispatch(); - textureStuff = select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_TextureSampler); + textureStuff = select(*sceneContext.scene(), ramses::ERamsesObjectType::TextureSampler); ASSERT_EQ(textureStuff.size(), 1); - commandInterface.set({texture, &raco::user_types::Texture::mipmapLevel_}, 3); + commandInterface.set({texture, &user_types::Texture::mipmapLevel_}, 3); dispatch(); - textureStuff = select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_TextureSampler); + textureStuff = select(*sceneContext.scene(), ramses::ERamsesObjectType::TextureSampler); ASSERT_EQ(textureStuff.size(), 1); - commandInterface.set({texture, &raco::user_types::Texture::mipmapLevel_}, 4); + commandInterface.set({texture, &user_types::Texture::mipmapLevel_}, 4); dispatch(); - textureStuff = select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_TextureSampler); + textureStuff = select(*sceneContext.scene(), ramses::ERamsesObjectType::TextureSampler); ASSERT_EQ(textureStuff.size(), 1); } TEST_F(TextureAdaptorFixture, textureGenerationAtMultipleLevelsWithFlip) { - auto texture = create("Texture"); + auto texture = create("Texture"); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "blue_1024.png").string()); dispatch(); - commandInterface.set({texture, &raco::user_types::Texture::level2uri_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({texture, &user_types::Texture::level2uri_}, (test_path() / "images" / "green_512.png").string()); dispatch(); - commandInterface.set({texture, &raco::user_types::Texture::level3uri_}, (test_path() / "images" / "yellow_256.png").string()); + commandInterface.set({texture, &user_types::Texture::level3uri_}, (test_path() / "images" / "yellow_256.png").string()); dispatch(); - commandInterface.set({texture, &raco::user_types::Texture::level4uri_}, (test_path() / "images" / "red_128.png").string()); + commandInterface.set({texture, &user_types::Texture::level4uri_}, (test_path() / "images" / "red_128.png").string()); dispatch(); - commandInterface.set({texture, &raco::user_types::Texture::mipmapLevel_}, 4); + commandInterface.set({texture, &user_types::Texture::mipmapLevel_}, 4); dispatch(); - commandInterface.set({texture, &raco::user_types::Texture::flipTexture_}, true); + commandInterface.set({texture, &user_types::Texture::flipTexture_}, true); dispatch(); - auto textureStuff = select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_TextureSampler); + auto textureStuff = select(*sceneContext.scene(), ramses::ERamsesObjectType::TextureSampler); ASSERT_EQ(textureStuff.size(), 1); } TEST_F(TextureAdaptorFixture, wrongMipMapLevelImageSizes) { - auto texture = create("Texture"); + auto texture = create("Texture"); - commandInterface.set({texture, &raco::user_types::Texture::mipmapLevel_}, 4); + commandInterface.set({texture, &user_types::Texture::mipmapLevel_}, 4); dispatch(); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "blue_1024.png").string()); dispatch(); - commandInterface.set({texture, &raco::user_types::Texture::level2uri_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({texture, &user_types::Texture::level2uri_}, (test_path() / "images" / "blue_1024.png").string()); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::level2uri_})); + ASSERT_TRUE(commandInterface.errors().hasError({texture, &user_types::Texture::level2uri_})); - commandInterface.set({texture, &raco::user_types::Texture::level3uri_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({texture, &user_types::Texture::level3uri_}, (test_path() / "images" / "blue_1024.png").string()); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::level3uri_})); + ASSERT_TRUE(commandInterface.errors().hasError({texture, &user_types::Texture::level3uri_})); - commandInterface.set({texture, &raco::user_types::Texture::level4uri_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({texture, &user_types::Texture::level4uri_}, (test_path() / "images" / "blue_1024.png").string()); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::level4uri_})); + ASSERT_TRUE(commandInterface.errors().hasError({texture, &user_types::Texture::level4uri_})); - commandInterface.set({texture, &raco::user_types::Texture::mipmapLevel_}, 3); + commandInterface.set({texture, &user_types::Texture::mipmapLevel_}, 3); dispatch(); - ASSERT_FALSE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::level4uri_})); + ASSERT_FALSE(commandInterface.errors().hasError({texture, &user_types::Texture::level4uri_})); - commandInterface.set({texture, &raco::user_types::Texture::mipmapLevel_}, 2); + commandInterface.set({texture, &user_types::Texture::mipmapLevel_}, 2); dispatch(); - ASSERT_FALSE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::level3uri_})); + ASSERT_FALSE(commandInterface.errors().hasError({texture, &user_types::Texture::level3uri_})); - commandInterface.set({texture, &raco::user_types::Texture::mipmapLevel_}, 1); + commandInterface.set({texture, &user_types::Texture::mipmapLevel_}, 1); dispatch(); - ASSERT_FALSE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::level2uri_})); + ASSERT_FALSE(commandInterface.errors().hasError({texture, &user_types::Texture::level2uri_})); } TEST_F(TextureAdaptorFixture, ramsesAutoMipMapGenerationWarningPersistsAfterChangingURI) { - auto texture = create("Texture"); + auto texture = create("Texture"); - commandInterface.set({texture, &raco::user_types::Texture::generateMipmaps_}, true); - commandInterface.set({texture, &raco::user_types::Texture::mipmapLevel_}, 2); + commandInterface.set({texture, &user_types::Texture::generateMipmaps_}, true); + commandInterface.set({texture, &user_types::Texture::mipmapLevel_}, 2); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::mipmapLevel_})); + ASSERT_TRUE(commandInterface.errors().hasError({texture, &user_types::Texture::mipmapLevel_})); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "blue_1024.png").string()); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::mipmapLevel_})); + ASSERT_TRUE(commandInterface.errors().hasError({texture, &user_types::Texture::mipmapLevel_})); - commandInterface.set({texture, &raco::user_types::Texture::level2uri_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({texture, &user_types::Texture::level2uri_}, (test_path() / "images" / "green_512.png").string()); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::mipmapLevel_})); + ASSERT_TRUE(commandInterface.errors().hasError({texture, &user_types::Texture::mipmapLevel_})); } TEST_F(TextureAdaptorFixture, textureBitdepthDifferentInSameLevel) { - auto texture = create("texture"); + auto texture = create("texture"); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "green_512_16f.png").string()); dispatch(); // RGBA16 - commandInterface.set({texture, &raco::user_types::Texture::textureFormat_}, static_cast(ramses::ETextureFormat::RGBA16F)); + commandInterface.set({texture, &user_types::Texture::textureFormat_}, static_cast(ETextureFormat::RGBA16F)); dispatch(); - ASSERT_FALSE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::textureFormat_})); + ASSERT_FALSE(commandInterface.errors().hasError({texture, &user_types::Texture::textureFormat_})); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "green_512.png").string()); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::uri_})); - ASSERT_EQ(commandInterface.errors().getError({texture, &raco::user_types::Texture::uri_}).level(), raco::core::ErrorLevel::ERROR); + ASSERT_TRUE(commandInterface.errors().hasError({texture, &user_types::Texture::uri_})); + ASSERT_EQ(commandInterface.errors().getError({texture, &user_types::Texture::uri_}).level(), core::ErrorLevel::ERROR); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "green_512_16f.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "green_512_16f.png").string()); dispatch(); - ASSERT_FALSE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::uri_})); + ASSERT_FALSE(commandInterface.errors().hasError({texture, &user_types::Texture::uri_})); } TEST_F(TextureAdaptorFixture, textureBitdepthDifferentInOtherLevel) { - auto texture = create("texture"); + auto texture = create("texture"); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "blue_1024_16i.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "blue_1024_16i.png").string()); dispatch(); // RGBA16 - commandInterface.set({texture, &raco::user_types::Texture::textureFormat_}, static_cast(ramses::ETextureFormat::RGBA16F)); + commandInterface.set({texture, &user_types::Texture::textureFormat_}, static_cast(ETextureFormat::RGBA16F)); dispatch(); - ASSERT_FALSE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::textureFormat_})); + ASSERT_FALSE(commandInterface.errors().hasError({texture, &user_types::Texture::textureFormat_})); - commandInterface.set({texture, &raco::user_types::Texture::level2uri_}, (test_path() / "images" / "green_512.png").string()); - commandInterface.set({texture, &raco::user_types::Texture::mipmapLevel_}, 2); + commandInterface.set({texture, &user_types::Texture::level2uri_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({texture, &user_types::Texture::mipmapLevel_}, 2); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::level2uri_})); - ASSERT_EQ(commandInterface.errors().getError({texture, &raco::user_types::Texture::level2uri_}).level(), raco::core::ErrorLevel::ERROR); + ASSERT_TRUE(commandInterface.errors().hasError({texture, &user_types::Texture::level2uri_})); + ASSERT_EQ(commandInterface.errors().getError({texture, &user_types::Texture::level2uri_}).level(), core::ErrorLevel::ERROR); - commandInterface.set({texture, &raco::user_types::Texture::level2uri_}, (test_path() / "images" / "green_512_16i.png").string()); + commandInterface.set({texture, &user_types::Texture::level2uri_}, (test_path() / "images" / "green_512_16i.png").string()); dispatch(); - ASSERT_FALSE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::level2uri_})); + ASSERT_FALSE(commandInterface.errors().hasError({texture, &user_types::Texture::level2uri_})); } TEST_F(TextureAdaptorFixture, textureFormatDifferentInOtherLevel) { - auto texture = create("texture"); + auto texture = create("texture"); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, (test_path() / "images" / "blue_1024.png").string()); + commandInterface.set({texture, &user_types::Texture::uri_}, (test_path() / "images" / "blue_1024.png").string()); dispatch(); // RGBA8 - commandInterface.set({texture, &raco::user_types::Texture::textureFormat_}, static_cast(ramses::ETextureFormat::RGBA8)); + commandInterface.set({texture, &user_types::Texture::textureFormat_}, static_cast(ETextureFormat::RGBA8)); dispatch(); // R8 - commandInterface.set({texture, &raco::user_types::Texture::level2uri_}, (test_path() / "images" / "green_512_gray.png").string()); - commandInterface.set({texture, &raco::user_types::Texture::mipmapLevel_}, 2); + commandInterface.set({texture, &user_types::Texture::level2uri_}, (test_path() / "images" / "green_512_gray.png").string()); + commandInterface.set({texture, &user_types::Texture::mipmapLevel_}, 2); dispatch(); // Swizzled format is R8, compatible with image. No issues. - ASSERT_FALSE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::level2uri_})); + ASSERT_FALSE(commandInterface.errors().hasError({texture, &user_types::Texture::level2uri_})); // RGBA8 - commandInterface.set({texture, &raco::user_types::Texture::level2uri_}, (test_path() / "images" / "green_512.png").string()); + commandInterface.set({texture, &user_types::Texture::level2uri_}, (test_path() / "images" / "green_512.png").string()); dispatch(); // Swizzled format is RGBA8, matching image format. - ASSERT_FALSE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::level2uri_})); + ASSERT_FALSE(commandInterface.errors().hasError({texture, &user_types::Texture::level2uri_})); } TEST_F(TextureAdaptorFixture, level1UriWarning) { - auto texture = create("texture"); + auto texture = create("texture"); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::uri_})); - ASSERT_EQ(commandInterface.errors().getError({texture, &raco::user_types::Texture::uri_}).level(), raco::core::ErrorLevel::WARNING); + ASSERT_TRUE(commandInterface.errors().hasError({texture, &user_types::Texture::uri_})); + ASSERT_EQ(commandInterface.errors().getError({texture, &user_types::Texture::uri_}).level(), core::ErrorLevel::WARNING); } TEST_F(TextureAdaptorFixture, gitLfsPlaceholderFileInUri) { std::string path = test_path().append("images/gitLfsPlaceholderFile.png").string(); raco::createGitLfsPlaceholderFile(path); - auto texture = create ("texture"); - commandInterface.set({texture, &raco::user_types::Texture::uri_}, path); + auto texture = create ("texture"); + commandInterface.set({texture, &user_types::Texture::uri_}, path); dispatch(); - ASSERT_TRUE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::uri_})); - ASSERT_TRUE(commandInterface.errors().getError({texture, &raco::user_types::Texture::uri_}).message().find("Git LFS Placeholder")); + ASSERT_TRUE(commandInterface.errors().hasError({texture, &user_types::Texture::uri_})); + ASSERT_TRUE(commandInterface.errors().getError({texture, &user_types::Texture::uri_}).message().find("Git LFS Placeholder")); } diff --git a/components/libRamsesBase/tests/TextureExternalAdaptor_test.cpp b/components/libRamsesBase/tests/TextureExternalAdaptor_test.cpp index 8d452900..85bc2130 100644 --- a/components/libRamsesBase/tests/TextureExternalAdaptor_test.cpp +++ b/components/libRamsesBase/tests/TextureExternalAdaptor_test.cpp @@ -16,7 +16,7 @@ class TextureExternalAdaptorFixture : public RamsesBaseFixture<> {}; TEST_F(TextureExternalAdaptorFixture, creation_sets_name) { - auto texture = create("test"); + auto texture = create("test"); dispatch(); @@ -26,21 +26,21 @@ TEST_F(TextureExternalAdaptorFixture, creation_sets_name) { } TEST_F(TextureExternalAdaptorFixture, change_name) { - auto texture = create("test"); + auto texture = create("test"); dispatch(); { - auto engineSamplers{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_TextureSamplerExternal)}; + auto engineSamplers{select(*sceneContext.scene(), ramses::ERamsesObjectType::TextureSamplerExternal)}; EXPECT_EQ(engineSamplers.size(), 1); - EXPECT_STREQ("test", engineSamplers[0]->getName()); + EXPECT_TRUE("test" == engineSamplers[0]->getName()); } - commandInterface.set({texture, &raco::user_types::TextureExternal::objectName_}, std::string("newName")); + commandInterface.set({texture, &user_types::TextureExternal::objectName_}, std::string("newName")); dispatch(); { - auto engineSamplers{select(*sceneContext.scene(), ramses::ERamsesObjectType::ERamsesObjectType_TextureSamplerExternal)}; + auto engineSamplers{select(*sceneContext.scene(), ramses::ERamsesObjectType::TextureSamplerExternal)}; EXPECT_EQ(engineSamplers.size(), 1); - EXPECT_STREQ("newName", engineSamplers[0]->getName()); + EXPECT_TRUE("newName" == engineSamplers[0]->getName()); } } \ No newline at end of file diff --git a/components/libRamsesBase/tests/TimerAdaptor_test.cpp b/components/libRamsesBase/tests/TimerAdaptor_test.cpp index 47ea2a2a..f88ebb6c 100644 --- a/components/libRamsesBase/tests/TimerAdaptor_test.cpp +++ b/components/libRamsesBase/tests/TimerAdaptor_test.cpp @@ -21,8 +21,8 @@ TEST_F(TimerAdaptorTest, defaultConstruction) { dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); - ASSERT_EQ(sceneContext.logicEngine().getCollection().begin()->getUserId(), timer->objectIDAsRamsesLogicID()); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); + ASSERT_EQ(sceneContext.logicEngine().getCollection().begin()->getUserId(), timer->objectIDAsRamsesLogicID()); } TEST_F(TimerAdaptorTest, renaming) { @@ -33,10 +33,10 @@ TEST_F(TimerAdaptorTest, renaming) { context.set({timer, {"objectName"}}, std::string("Changed")); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); - ASSERT_EQ(select(sceneContext.logicEngine(), "Timer"), nullptr); - ASSERT_NE(select(sceneContext.logicEngine(), "Changed"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Changed")->getUserId(), timer->objectIDAsRamsesLogicID()); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); + ASSERT_EQ(select(sceneContext.logicEngine(), "Timer"), nullptr); + ASSERT_NE(select(sceneContext.logicEngine(), "Changed"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Changed")->getUserId(), timer->objectIDAsRamsesLogicID()); } TEST_F(TimerAdaptorTest, multipleTimers) { @@ -46,19 +46,19 @@ TEST_F(TimerAdaptorTest, multipleTimers) { auto timer2 = context.createObject(Timer::typeDescription.typeName, "Timer2"); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 2); - ASSERT_NE(select(sceneContext.logicEngine(), "Timer"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Timer")->getUserId(), timer->objectIDAsRamsesLogicID()); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 2); + ASSERT_NE(select(sceneContext.logicEngine(), "Timer"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Timer")->getUserId(), timer->objectIDAsRamsesLogicID()); - ASSERT_NE(select(sceneContext.logicEngine(), "Timer2"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Timer2")->getUserId(), timer2->objectIDAsRamsesLogicID()); + ASSERT_NE(select(sceneContext.logicEngine(), "Timer2"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Timer2")->getUserId(), timer2->objectIDAsRamsesLogicID()); context.deleteObjects({timer2}); dispatch(); - ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); - ASSERT_NE(select(sceneContext.logicEngine(), "Timer"), nullptr); - ASSERT_EQ(select(sceneContext.logicEngine(), "Timer2"), nullptr); + ASSERT_EQ(sceneContext.logicEngine().getCollection().size(), 1); + ASSERT_NE(select(sceneContext.logicEngine(), "Timer"), nullptr); + ASSERT_EQ(select(sceneContext.logicEngine(), "Timer2"), nullptr); } TEST_F(TimerAdaptorTest, InputZeroOutputNotZero) { diff --git a/components/libRamsesBase/tests/utilities_test.cpp b/components/libRamsesBase/tests/utilities_test.cpp index aae6718d..f801078a 100644 --- a/components/libRamsesBase/tests/utilities_test.cpp +++ b/components/libRamsesBase/tests/utilities_test.cpp @@ -14,30 +14,29 @@ #include "ramses_base/HeadlessEngineBackend.h" #include "user_types/Node.h" -using raco::ramses_adaptor::Rotation; -using raco::ramses_adaptor::Scaling; -using raco::ramses_adaptor::Translation; +using namespace raco::ramses_adaptor; using raco::user_types::Node; +using namespace raco::core; TEST(Rotation, initialSpatialProperties_areEqual) { - raco::ramses_base::HeadlessEngineBackend backend{raco::ramses_base::BaseEngineBackend::maxFeatureLevel}; + raco::ramses_base::HeadlessEngineBackend backend; + backend.setFeatureLevel(raco::ramses_base::BaseEngineBackend::maxFeatureLevel); auto testScene = backend.client().createScene(ramses::sceneId_t{1u}); auto ramsesNode = testScene->createNode(); - auto nodeBinding = backend.logicEngine().createRamsesNodeBinding(*ramsesNode); auto dataNode = std::make_shared(); - EXPECT_EQ(Rotation::from(*ramsesNode), Rotation::from(dataNode)); - EXPECT_EQ(Translation::from(*ramsesNode), Translation::from(dataNode)); - EXPECT_EQ(Scaling::from(*ramsesNode), Scaling::from(dataNode)); + EXPECT_EQ(getRamsesRotation(ramsesNode), getRacoRotation(dataNode)); + EXPECT_EQ(getRamsesTranslation(ramsesNode), getRacoTranslation(dataNode)); + EXPECT_EQ(getRamsesScaling(ramsesNode), getRacoScaling(dataNode)); } TEST(Rotation, spatialProperties_areEqual_afterSync) { - raco::ramses_base::HeadlessEngineBackend backend{raco::ramses_base::BaseEngineBackend::maxFeatureLevel}; + raco::ramses_base::HeadlessEngineBackend backend; + backend.setFeatureLevel(raco::ramses_base::BaseEngineBackend::maxFeatureLevel); auto testScene = backend.client().createScene(ramses::sceneId_t{1u}); auto ramsesNode = testScene->createNode(); - auto nodeBinding = backend.logicEngine().createRamsesNodeBinding(*ramsesNode); auto dataNode = std::make_shared(); dataNode->scaling_->x = 10.0; @@ -50,11 +49,11 @@ TEST(Rotation, spatialProperties_areEqual_afterSync) { dataNode->rotation_->y = -3.0; dataNode->rotation_->z = 77.0; - Rotation::sync(dataNode, *ramsesNode); - Translation::sync(dataNode, *ramsesNode); - Scaling::sync(dataNode, *ramsesNode); + ramsesNode->setTranslation(getRacoTranslation(dataNode)); + ramsesNode->setScaling(getRacoScaling(dataNode)); + ramsesNode->setRotation(getRacoRotation(dataNode), ramses::ERotationType::Euler_XYZ); - EXPECT_EQ(Rotation::from(*ramsesNode), Rotation::from(dataNode)); - EXPECT_EQ(Translation::from(*ramsesNode), Translation::from(dataNode)); - EXPECT_EQ(Scaling::from(*ramsesNode), Scaling::from(dataNode)); + EXPECT_EQ(getRamsesRotation(ramsesNode), getRacoRotation(dataNode)); + EXPECT_EQ(getRamsesTranslation(ramsesNode), getRacoTranslation(dataNode)); + EXPECT_EQ(getRamsesScaling(ramsesNode), getRacoScaling(dataNode)); } diff --git a/datamodel/libCore/CMakeLists.txt b/datamodel/libCore/CMakeLists.txt index 0b6c976a..a3c2f560 100644 --- a/datamodel/libCore/CMakeLists.txt +++ b/datamodel/libCore/CMakeLists.txt @@ -67,6 +67,7 @@ PUBLIC raco::LogSystem raco::Utils Qt5::Core + glm::glm PRIVATE # Linking the user types to the Core causes a circular dependency. # We need to either move the classes needed from UserTypes into the core @@ -82,11 +83,6 @@ endif() add_library(raco::Core ALIAS libCore) -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - # Needed for Ubuntu 18 (GCC 7) - for the experimental file system, "stdc++fs" is required after all other object files. - # See also https://gitlab.kitware.com/cmake/cmake/-/issues/17834 - target_link_libraries(libCore PUBLIC "stdc++fs") -endif() if(PACKAGE_TESTS) add_subdirectory(tests) endif() \ No newline at end of file diff --git a/datamodel/libCore/include/core/BasicAnnotations.h b/datamodel/libCore/include/core/BasicAnnotations.h index 6ce9bd72..70494f96 100644 --- a/datamodel/libCore/include/core/BasicAnnotations.h +++ b/datamodel/libCore/include/core/BasicAnnotations.h @@ -15,7 +15,7 @@ namespace raco::core { template -class RangeAnnotation : public raco::data_storage::AnnotationBase { +class RangeAnnotation : public data_storage::AnnotationBase { public: static const TypeDescriptor typeDescription; TypeDescriptor const& getTypeDescription() const override { @@ -46,10 +46,10 @@ class RangeAnnotation : public raco::data_storage::AnnotationBase { return *max_; } - raco::data_storage::Value min_, max_; + data_storage::Value min_, max_; }; -class DisplayNameAnnotation : public raco::data_storage::AnnotationBase { +class DisplayNameAnnotation : public data_storage::AnnotationBase { public: static inline const TypeDescriptor typeDescription = { "DisplayNameAnnotation", false }; TypeDescriptor const& getTypeDescription() const override { @@ -70,13 +70,13 @@ class DisplayNameAnnotation : public raco::data_storage::AnnotationBase { return *this; } - raco::data_storage::Value name_; + data_storage::Value name_; }; -template<> inline const raco::data_storage::ReflectionInterface::TypeDescriptor raco::core::RangeAnnotation::typeDescription { +template<> inline const data_storage::ReflectionInterface::TypeDescriptor core::RangeAnnotation::typeDescription { "RangeAnnotationDouble", false }; -template<> inline const raco::data_storage::ReflectionInterface::TypeDescriptor raco::core::RangeAnnotation::typeDescription { +template<> inline const data_storage::ReflectionInterface::TypeDescriptor core::RangeAnnotation::typeDescription { "RangeAnnotationInt", false }; diff --git a/datamodel/libCore/include/core/BasicTypes.h b/datamodel/libCore/include/core/BasicTypes.h index 95d262a5..67b6c5bd 100644 --- a/datamodel/libCore/include/core/BasicTypes.h +++ b/datamodel/libCore/include/core/BasicTypes.h @@ -17,9 +17,9 @@ namespace raco::core { -using raco::data_storage::StructBase; -using raco::data_storage::ValueBase; -using raco::data_storage::Property; +using data_storage::StructBase; +using data_storage::ValueBase; +using data_storage::Property; class Vec2f : public StructBase { public: diff --git a/datamodel/libCore/include/core/CodeControlledPropertyModifier.h b/datamodel/libCore/include/core/CodeControlledPropertyModifier.h index c269663f..5a70a41e 100644 --- a/datamodel/libCore/include/core/CodeControlledPropertyModifier.h +++ b/datamodel/libCore/include/core/CodeControlledPropertyModifier.h @@ -27,7 +27,7 @@ class CodeControlledPropertyModifier { } static void setVec2f(const core::ValueHandle& handle, double x, double y, core::DataChangeRecorder& recorder) { - raco::core::Vec2f& v = dynamic_cast(handle.valueRef()->asStruct()); + core::Vec2f& v = dynamic_cast(handle.valueRef()->asStruct()); if (*v.x != x) { v.x = x; @@ -40,7 +40,7 @@ class CodeControlledPropertyModifier { } static void setVec3f(const core::ValueHandle& handle, double x, double y, double z, core::DataChangeRecorder& recorder) { - raco::core::Vec3f& v = dynamic_cast(handle.valueRef()->asStruct()); + core::Vec3f& v = dynamic_cast(handle.valueRef()->asStruct()); if (*v.x != x) { v.x = x; @@ -57,7 +57,7 @@ class CodeControlledPropertyModifier { } static void setVec4f(const core::ValueHandle& handle, double x, double y, double z, double w, core::DataChangeRecorder& recorder) { - raco::core::Vec4f& v = dynamic_cast(handle.valueRef()->asStruct()); + core::Vec4f& v = dynamic_cast(handle.valueRef()->asStruct()); if (*v.x != x) { v.x = x; @@ -78,7 +78,7 @@ class CodeControlledPropertyModifier { } static void setVec2i(const core::ValueHandle& handle, int x, int y, core::DataChangeRecorder& recorder) { - raco::core::Vec2i& v = dynamic_cast(handle.valueRef()->asStruct()); + core::Vec2i& v = dynamic_cast(handle.valueRef()->asStruct()); if (*v.i1_ != x) { v.i1_ = x; @@ -91,7 +91,7 @@ class CodeControlledPropertyModifier { } static void setVec3i(const core::ValueHandle& handle, int x, int y, int z, core::DataChangeRecorder& recorder) { - raco::core::Vec3i& v = dynamic_cast(handle.valueRef()->asStruct()); + core::Vec3i& v = dynamic_cast(handle.valueRef()->asStruct()); if (*v.i1_ != x) { v.i1_ = x; @@ -108,7 +108,7 @@ class CodeControlledPropertyModifier { } static void setVec4i(const core::ValueHandle& handle, int x, int y, int z, int w, core::DataChangeRecorder& recorder) { - raco::core::Vec4i& v = dynamic_cast(handle.valueRef()->asStruct()); + core::Vec4i& v = dynamic_cast(handle.valueRef()->asStruct()); if (*v.i1_ != x) { v.i1_ = x; diff --git a/datamodel/libCore/include/core/CommandInterface.h b/datamodel/libCore/include/core/CommandInterface.h index d9a44fe2..a4569112 100644 --- a/datamodel/libCore/include/core/CommandInterface.h +++ b/datamodel/libCore/include/core/CommandInterface.h @@ -56,6 +56,8 @@ class CommandInterface { EngineInterface& engineInterface() const; UndoStack& undoStack(); + bool canSetHandle(ValueHandle const& handle) const; + bool canSet(ValueHandle const& handle, int const& value) const; // Basic property changes @@ -103,6 +105,17 @@ class CommandInterface { // @param renderableTags tag name -> order index map void setRenderableTags(ValueHandle const& handle, std::vector> const& renderableTags); + /** + * @brief Resize Array property and initialize new entries to empty references. + * + * Properties with a ArraySemanticAnnotation may not be resized since they must not contain empty references. + * + * @param handle Handle for a property of PrimitiveType::Array + * @param newSize New size for array. + */ + void resizeArray(const ValueHandle& handle, size_t newSize); + + // Object creation/deletion SEditorObject createObject(std::string type, std::string name = std::string(), SEditorObject parent = nullptr); @@ -121,7 +134,7 @@ class CommandInterface { size_t moveScenegraphChildren(std::vector const& objects, SEditorObject const& newParent, int insertBeforeIndex = -1); // Calls Context::insertAssetScenegraph and generates a composite undo command. - void insertAssetScenegraph(const raco::core::MeshScenegraph& scenegraph, const std::string& absPath, SEditorObject const& parent); + void insertAssetScenegraph(const core::MeshScenegraph& scenegraph, const std::string& absPath, SEditorObject const& parent); /** * Creates a serialized representation of all given [EditorObject]'s and their appropriate dependencies. @@ -182,11 +195,10 @@ class CommandInterface { void executeCompositeCommand(std::function compositeCommand, const std::string& description); private: - bool canSetHandle(ValueHandle const& handle) const; bool canSetHandle(ValueHandle const& handle, PrimitiveType type) const; - bool checkHandleForSet(ValueHandle const& handle); - bool checkScalarHandleForSet(ValueHandle const& handle, PrimitiveType type); + bool checkHandleForSet(ValueHandle const& handle, bool allowVolatile = false); + bool checkScalarHandleForSet(ValueHandle const& handle, PrimitiveType type, bool allowVolatile = false); static std::string getMergeId(const std::set& handles); diff --git a/datamodel/libCore/include/core/Context.h b/datamodel/libCore/include/core/Context.h index 98efdc19..eb7519b3 100644 --- a/datamodel/libCore/include/core/Context.h +++ b/datamodel/libCore/include/core/Context.h @@ -88,21 +88,36 @@ class BaseContext { // Identical types are dynamically enforced at runtime. void set(ValueHandle const& handle, StructBase const& value); + // Set Array property to array value. + // Type safety of the value array is dynamically enforced at runtime. + void set(ValueHandle const& handle, ArrayBase const& value); + template void set(AnnotationValueHandle const& handle, T const& value); - // Add property to Table + // Add property to Table or Array property + // For an Array property the name is ignored and the type of the newProperty must be the element type of the array. + // For a Table property the name may be empty only if the property carries a ArraySemanticAnnotation. ValueBase* addProperty(const ValueHandle& handle, std::string name, std::unique_ptr&& newProperty, int indexBefore = -1); - // Remove property from Table + // Remove property from a Table or Array property void removeProperty(const ValueHandle& handle, size_t index); void removeProperty(const ValueHandle& handle, const std::string& name); - // Remove all properties from Table + // Remove all properties from a Table or Array property. void removeAllProperties(const ValueHandle &handle); void swapProperties(const ValueHandle& handle, size_t index_1, size_t index_2); + /** + * @brief Resize Array property and initialize new entries to empty references. + * + * @param handle Handle for a property of PrimitiveType::Array + * @param newSize New size for array. + */ + void resizeArray(const ValueHandle& handle, size_t newSize); + + // Object creation/deletion SEditorObject createObject(std::string type, std::string name = std::string(), std::string id = std::string()); @@ -149,7 +164,7 @@ class BaseContext { // Import scenegraph as a hierarchy of EditorObjects and move that scenegraph root noder under parent. // This includes generating Mesh resources, Nodes and MeshNodes as well as searching for already created Materials. // If parent is invalid, the mesh scenegraph root node will be the project's scenegraph root node. - void insertAssetScenegraph(const raco::core::MeshScenegraph& scenegraph, const std::string& absPath, SEditorObject const& parent); + void insertAssetScenegraph(const core::MeshScenegraph& scenegraph, const std::string& absPath, SEditorObject const& parent); // Link operations SLink addLink(const ValueHandle& start, const ValueHandle& end, bool isWeak = false); @@ -158,7 +173,7 @@ class BaseContext { void performExternalFileReload(const std::vector& objects); // @exception ExtrefError - void updateExternalReferences(LoadContext& loadContext); + void updateExternalReferences(LoadContext& loadContext, int fileVersion = -1); void initBrokenLinkErrors(); @@ -177,7 +192,7 @@ class BaseContext { void initLinkValidity(); - static void generateNewObjectIDs(std::vector& newObjects); + static void generateNewObjectIDs(std::vector& newObjects); private: friend class UndoStack; @@ -186,11 +201,11 @@ class BaseContext { friend class PrefabOperations; friend class ExtrefOperations; - void rerootRelativePaths(std::vector& newObjects, raco::serialization::ObjectsDeserialization& deserialization); - bool extrefPasteDiscardObject(SEditorObject editorObject, raco::serialization::ObjectsDeserialization& deserialization); - void adjustExtrefAnnotationsForPaste(std::vector& newObjects, raco::serialization::ObjectsDeserialization& deserialization, bool pasteAsExtref); + void rerootRelativePaths(std::vector& newObjects, serialization::ObjectsDeserialization& deserialization); + bool extrefPasteDiscardObject(SEditorObject editorObject, serialization::ObjectsDeserialization& deserialization); + void adjustExtrefAnnotationsForPaste(std::vector& newObjects, serialization::ObjectsDeserialization& deserialization, bool pasteAsExtref); - static void restoreReferences(const Project& project, std::vector& newObjects, raco::serialization::ObjectsDeserialization& deserialization); + static void restoreReferences(const Project& project, std::vector& newObjects, serialization::ObjectsDeserialization& deserialization); // Should only be used from the Undo system bool deleteWithVolatileSideEffects(Project* project, const SEditorObjectSet& objects, Errors& errors, bool gcExternalProjectMap = true); diff --git a/datamodel/libCore/include/core/CoreAnnotations.h b/datamodel/libCore/include/core/CoreAnnotations.h index 549453f5..10154149 100644 --- a/datamodel/libCore/include/core/CoreAnnotations.h +++ b/datamodel/libCore/include/core/CoreAnnotations.h @@ -20,7 +20,7 @@ namespace raco::core { -class URIAnnotation : public raco::data_storage::AnnotationBase { +class URIAnnotation : public data_storage::AnnotationBase { public: static inline const TypeDescriptor typeDescription = { "URIAnnotation", false }; @@ -63,13 +63,13 @@ class URIAnnotation : public raco::data_storage::AnnotationBase { return filter_.asString() == projectSubdirectoryFilter; } - raco::data_storage::Value filter_; + data_storage::Value filter_; // This is really a PathManager::FolerTypeKey - raco::data_storage::Value folderTypeKey_; + data_storage::Value folderTypeKey_; }; -class HiddenProperty : public raco::data_storage::AnnotationBase { +class HiddenProperty : public data_storage::AnnotationBase { public: static inline const TypeDescriptor typeDescription = { "HiddenProperty", false }; TypeDescriptor const& getTypeDescription() const override { @@ -86,7 +86,7 @@ class HiddenProperty : public raco::data_storage::AnnotationBase { } }; -class ReadOnlyAnnotation : public raco::data_storage::AnnotationBase { +class ReadOnlyAnnotation : public data_storage::AnnotationBase { public: static inline const TypeDescriptor typeDescription = {"ReadOnlyAnnotation", false}; TypeDescriptor const& getTypeDescription() const override { @@ -106,7 +106,7 @@ class ReadOnlyAnnotation : public raco::data_storage::AnnotationBase { // - the properties in the Table have empty property names // - PrimitiveType::Ref properties in the Table must not contain nullptrs. // Instead of setting a reference property to nullptr the property needs to be removed. -class ArraySemanticAnnotation : public raco::data_storage::AnnotationBase { +class ArraySemanticAnnotation : public data_storage::AnnotationBase { public: static inline const TypeDescriptor typeDescription = { "ArraySemanticAnnotation", false }; TypeDescriptor const& getTypeDescription() const override { @@ -127,7 +127,7 @@ class ArraySemanticAnnotation : public raco::data_storage::AnnotationBase { * * Not to be mixed up with UserTagContainerAnnotation */ -class TagContainerAnnotation : public raco::data_storage::AnnotationBase { +class TagContainerAnnotation : public data_storage::AnnotationBase { public: static inline const TypeDescriptor typeDescription = {"TagContainerAnnotation", false}; TypeDescriptor const& getTypeDescription() const override { @@ -146,7 +146,7 @@ class TagContainerAnnotation : public raco::data_storage::AnnotationBase { /** * @brief Marks a Table containing the tags to be rendered by a RenderLayer */ -class RenderableTagContainerAnnotation : public raco::data_storage::AnnotationBase { +class RenderableTagContainerAnnotation : public data_storage::AnnotationBase { public: static inline const TypeDescriptor typeDescription = {"RenderableTagContainerAnnotation", false}; TypeDescriptor const& getTypeDescription() const override { @@ -167,7 +167,7 @@ class RenderableTagContainerAnnotation : public raco::data_storage::AnnotationBa * * The user-defined Tags have no special semantics within RamsesComposer */ -class UserTagContainerAnnotation : public raco::data_storage::AnnotationBase { +class UserTagContainerAnnotation : public data_storage::AnnotationBase { public: static inline const TypeDescriptor typeDescription = {"UserTagContainerAnnotation", false}; TypeDescriptor const& getTypeDescription() const override { @@ -183,7 +183,7 @@ class UserTagContainerAnnotation : public raco::data_storage::AnnotationBase { } }; -class EnumerationAnnotation : public raco::data_storage::AnnotationBase { +class EnumerationAnnotation : public data_storage::AnnotationBase { public: static inline const TypeDescriptor typeDescription = { "EnumerationAnnotation", false }; TypeDescriptor const& getTypeDescription() const override { @@ -204,11 +204,17 @@ class EnumerationAnnotation : public raco::data_storage::AnnotationBase { return *this; } - // This is really a raco::core::EUserTypeEnumerations - raco::data_storage::Value type_; + // This is really a core::EUserTypeEnumerations + data_storage::Value type_; }; -class ExpectEmptyReference : public raco::data_storage::AnnotationBase { +/** + * @brief Customize the behaviour of the reference editor in the property browser. + * + * References properties without this annotation will show a warning color in the editor field if the reference is empty. + * Additionally the text to be shown in the editor field for empty references can be customized. +*/ +class ExpectEmptyReference : public data_storage::AnnotationBase { public: static inline const TypeDescriptor typeDescription = {"EmptyReferenceAllowable", false}; TypeDescriptor const& getTypeDescription() const override { @@ -230,7 +236,7 @@ class ExpectEmptyReference : public raco::data_storage::AnnotationBase { return *this; } - raco::data_storage::Value emptyRefLabel_; + data_storage::Value emptyRefLabel_; }; /** @@ -239,7 +245,7 @@ class ExpectEmptyReference : public raco::data_storage::AnnotationBase { * Property with a feature level higher than the current project feature level must not be exposed to the user, are not readable or * writable from the Python API, and must not be used in the engine backend / adaptor classes. */ -class FeatureLevel : public raco::data_storage::AnnotationBase { +class FeatureLevel : public data_storage::AnnotationBase { public: static inline const TypeDescriptor typeDescription = {"FeatureLevel", false}; TypeDescriptor const& getTypeDescription() const override { @@ -256,7 +262,60 @@ class FeatureLevel : public raco::data_storage::AnnotationBase { return *this; } - raco::data_storage::Value featureLevel_; + data_storage::Value featureLevel_; }; +/** + * @brief Mark a property as an editor-only property that is not part of the persistent data model. + * + * Volatile properties + * - are ignored by undo/redo, prefab update, and external reference update. + * - are not serialized, i.e. they are not written to the project files and ignored by copy/paste. + * - can be set using the CommandInterface as usual, although this will not trigger a Prefab update or generate an undo stack entry. + * - can be changed using the CommandInterface even when the property is linked or read-only. + * - changes will generate DataChangeRecorder entries as for other properties. + * - if a Table/Struct/Array property is tagged as volatile all child properties _must_ be tagged as volatile too. + * this is not checked but undo/prefab/extref/serialization will rely on this. + * + * Volatile properties are used for internal editor-only state needed only at runtime +*/ +class VolatileProperty : public data_storage::AnnotationBase { +public: + static inline const TypeDescriptor typeDescription = {"VolatileProperty", false}; + TypeDescriptor const& getTypeDescription() const override { + return typeDescription; + } + bool serializationRequired() const override { + return false; + } + VolatileProperty(const VolatileProperty& other) : AnnotationBase({}) {} + VolatileProperty() : AnnotationBase({}) {} + + VolatileProperty& operator=(const VolatileProperty& other) { + return *this; + } +}; + + +/** + * @brief Mark a PrimitiveType::Array property as resizable by the user. +*/ +class ResizableArray : public data_storage::AnnotationBase { +public: + static inline const TypeDescriptor typeDescription = {"ResizableArray", false}; + TypeDescriptor const& getTypeDescription() const override { + return typeDescription; + } + bool serializationRequired() const override { + return false; + } + ResizableArray(const ResizableArray& other) : AnnotationBase({}) {} + ResizableArray() : AnnotationBase({}) {} + + ResizableArray& operator=(const ResizableArray& other) { + return *this; + } +}; + + } // namespace raco::data_storage \ No newline at end of file diff --git a/datamodel/libCore/include/core/DynamicEditorObject.h b/datamodel/libCore/include/core/DynamicEditorObject.h index 408dbaa1..c87d74dd 100644 --- a/datamodel/libCore/include/core/DynamicEditorObject.h +++ b/datamodel/libCore/include/core/DynamicEditorObject.h @@ -18,11 +18,11 @@ namespace raco::serialization::proxy { -using raco::data_storage::ValueBase; +using data_storage::ValueBase; class DynamicPropertyInterface { public: - virtual ValueBase* addProperty(std::string const& name, raco::data_storage::PrimitiveType type) = 0; + virtual ValueBase* addProperty(std::string const& name, data_storage::PrimitiveType type) = 0; virtual ValueBase* addProperty(std::string const& name, ValueBase* property, int index_before = -1) = 0; virtual ValueBase* addProperty(std::string const& name, std::unique_ptr&& property, int index_before) = 0; @@ -34,9 +34,11 @@ class DynamicPropertyInterface { template class DynamicPropertyMixin : public DynamicPropertyInterface { public: - raco::data_storage::ValueBase* addProperty(std::string const& name, raco::data_storage::PrimitiveType type) override { + data_storage::ValueBase* addProperty(std::string const& name, data_storage::PrimitiveType type) override { T& asT = static_cast(*this); - assert(asT.get(name) == nullptr); + if (asT.hasProperty(name)) { + throw std::runtime_error(fmt::format("Property already exists.")); + } auto prop = dynamicProperties_.addProperty(name, type); asT.properties_.emplace_back(name, prop); return prop; @@ -44,7 +46,9 @@ class DynamicPropertyMixin : public DynamicPropertyInterface { ValueBase* addProperty(std::string const& name, ValueBase* property, int index_before) override { T& asT = static_cast(*this); - assert(asT.get(name) == nullptr); + if (asT.hasProperty(name)) { + throw std::runtime_error(fmt::format("Property already exists.")); + } auto prop = dynamicProperties_.addProperty(name, property, index_before); asT.properties_.emplace_back(name, prop); return prop; @@ -52,7 +56,9 @@ class DynamicPropertyMixin : public DynamicPropertyInterface { ValueBase* addProperty(std::string const& name, std::unique_ptr&& property, int index_before) override { T& asT = static_cast(*this); - assert(asT.get(name) == nullptr); + if (asT.hasProperty(name)) { + throw std::runtime_error(fmt::format("Property already exists.")); + } auto prop = dynamicProperties_.addProperty(name, std::move(property), index_before); asT.properties_.emplace_back(name, prop); return prop; @@ -60,7 +66,9 @@ class DynamicPropertyMixin : public DynamicPropertyInterface { void removeProperty(std::string const& propertyName) override { T& asT = static_cast(*this); - assert(asT.get(propertyName) != nullptr); + if (!asT.hasProperty(propertyName)) { + throw std::runtime_error(fmt::format("Invalid property.")); + } dynamicProperties_.removeProperty(propertyName); auto it = std::find_if(asT.properties_.begin(), asT.properties_.end(), [&propertyName](auto const& item) { @@ -79,27 +87,35 @@ class DynamicPropertyMixin : public DynamicPropertyInterface { std::unique_ptr extractProperty(std::string const& propertyName) override { T& asT = static_cast(*this); + if (!asT.hasProperty(propertyName)) { + throw std::runtime_error(fmt::format("Invalid property.")); + } auto clonedProp = asT.get(propertyName)->clone({}); removeProperty(propertyName); return clonedProp; } protected: - raco::data_storage::Table dynamicProperties_; + data_storage::Table dynamicProperties_; }; -class DynamicEditorObject : public raco::core::EditorObject, public DynamicPropertyMixin { +class DynamicEditorObject : public core::EditorObject, public DynamicPropertyMixin { public: DynamicEditorObject(std::string name = std::string(), std::string id = std::string()) : EditorObject(name, id) { } friend class DynamicPropertyMixin; + + void resetBackPointers() { + parent_.reset(); + referencesToThis_.clear(); + } }; using SDynamicEditorObject = std::shared_ptr; -class DynamicGenericStruct : public raco::data_storage::StructBase, public DynamicPropertyMixin { +class DynamicGenericStruct : public data_storage::StructBase, public DynamicPropertyMixin { public: DynamicGenericStruct() : StructBase() {} diff --git a/datamodel/libCore/include/core/EditorObject.h b/datamodel/libCore/include/core/EditorObject.h index 1fdcf3b7..c43a033f 100644 --- a/datamodel/libCore/include/core/EditorObject.h +++ b/datamodel/libCore/include/core/EditorObject.h @@ -12,6 +12,7 @@ #include "data_storage/ReflectionInterface.h" #include "data_storage/Value.h" #include "data_storage/Table.h" +#include "data_storage/Array.h" #include "core/BasicAnnotations.h" #include "core/CoreAnnotations.h" #include "core/FileChangeMonitor.h" @@ -22,6 +23,10 @@ #include #include +namespace raco::serialization::proxy { +class DynamicEditorObject; +} + namespace raco::core { using namespace raco::data_storage; @@ -175,7 +180,7 @@ class EditorObject : public ClassWithReflectedMembers, public std::enable_shared // - have unique parent, i.e. can appear only once in tree // - used to model both scenegraph children of nodes and prefab/prefab instance resource // contents (offscreen buffers etc) - Property children_{{}, {}, {}}; + Property, ArraySemanticAnnotation, HiddenProperty> children_{{}, {}, {}}; // Returns the object ID without braces or hyphens in a pair of separated hexadecimal numbers {id[0,15], id[16-31]} std::pair objectIDAsRamsesLogicID() const; @@ -193,7 +198,6 @@ class EditorObject : public ClassWithReflectedMembers, public std::enable_shared void fillPropertyDescription() { properties_.emplace_back("objectID", &objectID_); properties_.emplace_back("objectName", &objectName_); - properties_.emplace_back("userTags", &userTags_); properties_.emplace_back("children", &children_); } @@ -201,8 +205,6 @@ class EditorObject : public ClassWithReflectedMembers, public std::enable_shared Property objectID_{ std::string(), HiddenProperty() }; Property objectName_; - Property userTags_{{}, {}, {}, {}, {"User Tags"}}; - // Used to check back pointers in the unit tests. const std::set>& referencesToThis() const; @@ -212,6 +214,7 @@ class EditorObject : public ClassWithReflectedMembers, public std::enable_shared private: friend class BaseContext; + friend class serialization::proxy::DynamicEditorObject; mutable WEditorObject parent_; diff --git a/datamodel/libCore/include/core/EngineInterface.h b/datamodel/libCore/include/core/EngineInterface.h index bbd760a1..6e4cb828 100644 --- a/datamodel/libCore/include/core/EngineInterface.h +++ b/datamodel/libCore/include/core/EngineInterface.h @@ -124,21 +124,21 @@ class EngineInterface { // Parse shaders using Ramses and return set of uniforms with name and type. // Returns true if shader can be successfully parsed. - virtual bool parseShader(const std::string& vertexShader, const std::string& geometryShader, const std::string& fragmentShader, const std::string& shaderDefines, PropertyInterfaceList& outUniforms, raco::core::PropertyInterfaceList& outAttributes, std::string& error) = 0; + virtual bool parseShader(const std::string& vertexShader, const std::string& geometryShader, const std::string& fragmentShader, const std::string& shaderDefines, PropertyInterfaceList& outUniforms, core::PropertyInterfaceList& outAttributes, std::string& error) = 0; // Parse luascripts using ramses logic and return set of in and out parameters with name and type. // Returns true if script can be successfully parsed. - virtual bool parseLuaScript(const std::string& luaScript, const std::string& scriptName, const std::vector& stdModules, const raco::data_storage::Table& modules, PropertyInterfaceList& outInputs, PropertyInterfaceList& outOutputs, std::string& error) = 0; + virtual bool parseLuaScript(const std::string& luaScript, const std::string& scriptName, const std::vector& stdModules, const data_storage::Table& modules, PropertyInterfaceList& outInputs, PropertyInterfaceList& outOutputs, std::string& error) = 0; // Parse lua interface definition using ramses logic and return set of inout parameters with name and type. // Returns true if script can be successfully parsed. - virtual bool parseLuaInterface(const std::string& luaScript, const std::vector& stdModules, const raco::data_storage::Table& modules, bool useModules, PropertyInterfaceList& outInputs, std::string& error) = 0; + virtual bool parseLuaInterface(const std::string& luaScript, const std::vector& stdModules, const data_storage::Table& modules, PropertyInterfaceList& outInputs, std::string& error) = 0; // Parse luascript module using ramses logic. // Returns true if module can be successfully parsed. - virtual bool parseLuaScriptModule(raco::core::SEditorObject object, const std::string& luaScriptModule, const std::string& moduleName, const std::vector& stdModules, std::string& outError) = 0; + virtual bool parseLuaScriptModule(core::SEditorObject object, const std::string& luaScriptModule, const std::string& moduleName, const std::vector& stdModules, std::string& outError) = 0; - virtual void removeModuleFromCache(raco::core::SCEditorObject object) = 0; + virtual void removeModuleFromCache(core::SCEditorObject object) = 0; virtual void clearModuleCache() = 0; diff --git a/datamodel/libCore/include/core/ExtrefOperations.h b/datamodel/libCore/include/core/ExtrefOperations.h index 178d4617..dedc7c23 100644 --- a/datamodel/libCore/include/core/ExtrefOperations.h +++ b/datamodel/libCore/include/core/ExtrefOperations.h @@ -54,7 +54,7 @@ class ExternalProjectsStoreInterface { class ExtrefOperations { public: // @exception ExtrefError - static void updateExternalObjects(BaseContext& context, Project* project, ExternalProjectsStoreInterface& externalProjectsStore, LoadContext& loadContext); + static void updateExternalObjects(BaseContext& context, Project* project, ExternalProjectsStoreInterface& externalProjectsStore, LoadContext& loadContext, int fileVersion = -1); // Check if an external reference update would fail if the rootObjects would all be in the current project. // diff --git a/datamodel/libCore/include/core/Handles.h b/datamodel/libCore/include/core/Handles.h index 1a7e168c..a5611399 100644 --- a/datamodel/libCore/include/core/Handles.h +++ b/datamodel/libCore/include/core/Handles.h @@ -120,7 +120,9 @@ class ValueHandle { // Extract scalar values directly - // Templated accessor; only works for scalar types: bool, int, int64_t, double, std::string + // Templated accessor + // - works for scalar types: bool, int, int64_t, double, std::string + // - use glm::vec2/3/4 and ivec2/3/4 template parameter to obtain Vec2/3/4f and Vec2/3/4i struct properties template T as() const; bool asBool() const; @@ -164,10 +166,10 @@ class ValueHandle { // Access Table by index as array ValueHandle operator[](size_t) const; - bool hasProperty(std::string name) const; + bool hasProperty(std::string_view name) const; // For class type and Table properties access their members directly - ValueHandle get(std::string propertyName) const; + ValueHandle get(std::string_view propertyName) const; template AnnotationHandle query() const @@ -180,7 +182,7 @@ class ValueHandle { // return last element of property names vector std::string getPropName() const; - std::vector getPropertyNamesVector() const; + std::vector getPropertyNamesVector() const; // Return '/'-separated property path starting at the root object std::string getPropertyPath(bool useObjectID = false) const; @@ -270,9 +272,9 @@ class AnnotationHandle { return annotation_; } - AnnotationValueHandle get(std::string const& name) + AnnotationValueHandle get(std::string_view name) { - return { *this, name }; + return { *this, std::string(name) }; } private: diff --git a/datamodel/libCore/include/core/Link.h b/datamodel/libCore/include/core/Link.h index 3bfa9ece..990de95f 100644 --- a/datamodel/libCore/include/core/Link.h +++ b/datamodel/libCore/include/core/Link.h @@ -14,6 +14,7 @@ #include "data_storage/ReflectionInterface.h" #include "data_storage/Table.h" #include "data_storage/Value.h" +#include "data_storage/Array.h" #include "core/Handles.h" #include "core/PropertyDescriptor.h" @@ -94,13 +95,13 @@ class Link : public ClassWithReflectedMembers { static SLink cloneLinkWithTranslation(const SLink& link, std::function translateRef); - // startProp_ and endProp_ contain Table of unnamed string property denoting the property path + // startProp_ and endProp_ contain Array of string property denoting the property path Value startObject_; - Property startProp_{{}, {}}; + Value> startProp_{{}, {}}; Value endObject_; - Property endProp_{{}, {}}; + Value> endProp_{{}, {}}; Value isValid_{true}; Value isWeak_{false}; diff --git a/datamodel/libCore/include/core/LinkContainer.h b/datamodel/libCore/include/core/LinkContainer.h index d3350815..f41508ef 100644 --- a/datamodel/libCore/include/core/LinkContainer.h +++ b/datamodel/libCore/include/core/LinkContainer.h @@ -53,7 +53,7 @@ struct LinkContainer { // This map contains all links used by the project, // using the link start object ID as the key value, for easier lookup. - // Mostly used for link-related functions in raco::core::Queries. + // Mostly used for link-related functions in core::Queries. std::map> linkStartPoints_; // This map contains all links used by the project, diff --git a/datamodel/libCore/include/core/MeshCacheInterface.h b/datamodel/libCore/include/core/MeshCacheInterface.h index 1fdd60ff..4e200328 100644 --- a/datamodel/libCore/include/core/MeshCacheInterface.h +++ b/datamodel/libCore/include/core/MeshCacheInterface.h @@ -23,21 +23,23 @@ #include #include +#include + namespace raco::core { // Single mesh that can be handed over to Ramses. // May contain only part of an entire file; see MeshCacheEntry. class MeshData { public: - static constexpr const char* ATTRIBUTE_POSITION {"a_Position"}; - static constexpr const char* ATTRIBUTE_NORMAL {"a_Normal"}; - static constexpr const char* ATTRIBUTE_TANGENT {"a_Tangent"}; + static constexpr const char* ATTRIBUTE_POSITION{"a_Position"}; + static constexpr const char* ATTRIBUTE_NORMAL{"a_Normal"}; + static constexpr const char* ATTRIBUTE_TANGENT{"a_Tangent"}; static constexpr const char* ATTRIBUTE_BITANGENT{"a_Bitangent"}; - static constexpr const char* ATTRIBUTE_UVMAP {"a_TextureCoordinate"}; - static constexpr const char* ATTRIBUTE_UVWMAP {"a_TextureCoordinate"}; - static constexpr const char* ATTRIBUTE_COLOR {"a_Color"}; - static constexpr const char* ATTRIBUTE_WEIGHTS {"a_Weights"}; - static constexpr const char* ATTRIBUTE_JOINTS {"a_Joints"}; + static constexpr const char* ATTRIBUTE_UVMAP{"a_TextureCoordinate"}; + static constexpr const char* ATTRIBUTE_UVWMAP{"a_TextureCoordinate"}; + static constexpr const char* ATTRIBUTE_COLOR{"a_Color"}; + static constexpr const char* ATTRIBUTE_WEIGHTS{"a_Weights"}; + static constexpr const char* ATTRIBUTE_JOINTS{"a_Joints"}; struct IndexBufferRangeInfo { uint32_t start; @@ -68,10 +70,17 @@ class MeshData { virtual std::string attribName(int attribIndex) const = 0; //! Size of the attribute buffer in bytes. virtual uint32_t attribDataSize(int attribIndex) const = 0; - virtual uint32_t attribElementCount(int attribIndex) const = 0; + virtual uint32_t attribElementCount(int attribIndex) const = 0; virtual VertexAttribDataType attribDataType(int attribIndex) const = 0; virtual const char* attribBuffer(int attribIndex) const = 0; + /** + * @brief Non-indexed triangle buffer that can be used for picking in ramses. + * + * @return Return vector of vertices forming triangles. Each 3 consecutive entries form one triangle. + */ + virtual const std::vector& triangleBuffer() const = 0; + int attribIndex(const std::string& name) const { for (uint32_t i{0}; i < numAttributes(); i++) { if (name == attribName(i)) { @@ -80,6 +89,23 @@ class MeshData { } return -1; } + + /** + * @brief build non-interleaved triangle buffer from the index and vertex buffer data + */ + static std::vector buildTriangleBuffer(const glm::vec3* vertices, const std::vector& indices) { + std::vector triangleBuffer; + + // Build non-indexed triangle buffer to be used for picking in ramses + auto numTriangles = indices.size() / 3; + for (size_t index = 0; index < numTriangles; index++) { + triangleBuffer.insert(triangleBuffer.end(), + {vertices[indices[3 * index]], + vertices[indices[3 * index + 1]], + vertices[indices[3 * index + 2]]}); + } + return triangleBuffer; + } }; using SharedMeshData = std::shared_ptr; @@ -90,7 +116,7 @@ using SharedMeshData = std::shared_ptr; struct SkinData { static constexpr const char* INV_BIND_MATRICES_UNIFORM_NAME = "u_jointMat"; - std::vector> inverseBindMatrices; + std::vector inverseBindMatrices; size_t numSkins; }; @@ -108,123 +134,22 @@ enum class MeshAnimationInterpolation { // Animation sampler data holder - currently created using MeshCache::getAnimationSamplerData() struct AnimationSamplerData { MeshAnimationInterpolation interpolation; - std::vector input; - std::vector> output; - - EnginePrimitive getOutputComponentType() const { - assert(!output.empty()); - switch (output.front().size()) { - case 1: - return EnginePrimitive::Array; - break; - case 3: - return EnginePrimitive::Vec3f; - break; - case 4: - return EnginePrimitive::Vec4f; - break; - default: - assert(false); - } - return EnginePrimitive::Undefined; - } + EnginePrimitive componentType; - size_t getOutputComponentSize() { - if (output.empty()) { - return 0; - } - if (output.front().size() == 1) { - return output.size() / input.size(); - } - return output.front().size(); - } - - template - std::array, 3> getOutputData() { - // Note: Used to be used for morph targets, but wrong: - static_assert(!std::is_same_v>); - - std::array, 3> outputData; - auto animInterpolationIsCubic = (interpolation == raco::core::MeshAnimationInterpolation::CubicSpline) || (interpolation == raco::core::MeshAnimationInterpolation::CubicSpline_Quaternion); - - auto& tangentInData = outputData[0]; - auto& transformedData = outputData[1]; - auto& tangentOutData = outputData[2]; - - - if (!animInterpolationIsCubic) { - if constexpr (std::is_same_v>) { - // Morph targets: - // output buffer has input.size() * number(morph targets) element vectors of size 1 - // we need to change this in input.size() vector of length number(morph targets) - auto numTargets = output.size() / input.size(); - assert(output.size() % input.size() == 0); - for (size_t i = 0; i < input.size(); i++) { - std::vector vec; - for (size_t target = 0; target < numTargets; target++) { - vec.emplace_back(output[i * numTargets + target][0]); - } - transformedData.emplace_back(vec); - } - } else { - for (const auto& vecfKeyframe : output) { - if constexpr (std::is_same_v>) { - transformedData.push_back({vecfKeyframe[0], vecfKeyframe[1], vecfKeyframe[2]}); - } else if constexpr (std::is_same_v>) { - transformedData.push_back({vecfKeyframe[0], vecfKeyframe[1], vecfKeyframe[2], vecfKeyframe[3]}); - } - } - } - } else { - if constexpr (std::is_same_v>) { - // Morph targets with cubic interpolation - // buffer structure: is a_1 ... a_k v_1 ... v_k b_1 ... b_k - // where 1...k are the morph targets, - // a/b are the in/out tangents, and v are the values - - auto numTargets = output.size() / (3 * input.size()); - assert(output.size() % (3 * input.size()) == 0); - - for (size_t i = 0; i < input.size(); i++) { - std::vector tangentIn; - std::vector value; - std::vector tangentOut; - - for (size_t target = 0; target < numTargets; target++) { - tangentIn.emplace_back(output[(3*i + 0) * numTargets + target][0]); - value.emplace_back(output[(3*i + 1) * numTargets + target][0]); - tangentOut.emplace_back(output[(3*i + 2) * numTargets + target][0]); - } - - tangentInData.push_back(tangentIn); - transformedData.emplace_back(value); - tangentOutData.push_back(tangentOut); - } - - } else { - for (auto i = 0; i < output.size(); i += 3) { - auto& tangentIn = output[i]; - auto& vecfKeyframe = output[i + 1]; - auto& tangentOut = output[i + 2]; - - if constexpr (std::is_same_v>) { - tangentInData.push_back({tangentIn[0], tangentIn[1], tangentIn[2]}); - transformedData.push_back({vecfKeyframe[0], vecfKeyframe[1], vecfKeyframe[2]}); - tangentOutData.push_back({tangentOut[0], tangentOut[1], tangentOut[2]}); - } else if constexpr (std::is_same_v>) { - tangentInData.push_back({tangentIn[0], tangentIn[1], tangentIn[2], tangentIn[3]}); - transformedData.push_back({vecfKeyframe[0], vecfKeyframe[1], vecfKeyframe[2], vecfKeyframe[3]}); - tangentOutData.push_back({tangentOut[0], tangentOut[1], tangentOut[2], tangentOut[3]}); - } - } - } - } + std::vector timeStamps; + + // TODO the supported data types are currently restricted to float types only, + // although the logicengine also allows ints. + std::vector> keyFrames; + std::vector> tangentsIn; + std::vector> tangentsOut; - return outputData; + size_t getOutputComponentSize() { + return keyFrames.front().size(); } }; -using SharedAnimationSamplerData = std::shared_ptr; +using SharedAnimationSamplerData = std::shared_ptr; // Low-level one-to-one mapping of animation channel data delivered by tinyglTF. struct MeshAnimationChannel { @@ -327,7 +252,7 @@ class MeshCache : public FileChangeMonitor { public: virtual ~MeshCache() = default; - virtual SharedMeshData loadMesh(const raco::core::MeshDescriptor& descriptor) = 0; + virtual SharedMeshData loadMesh(const core::MeshDescriptor& descriptor) = 0; virtual const MeshScenegraph* getMeshScenegraph(const std::string& absPath) = 0; virtual std::string getMeshError(const std::string& absPath) = 0; diff --git a/datamodel/libCore/include/core/PathManager.h b/datamodel/libCore/include/core/PathManager.h index 0df0442d..a9b4429e 100644 --- a/datamodel/libCore/include/core/PathManager.h +++ b/datamodel/libCore/include/core/PathManager.h @@ -24,7 +24,7 @@ namespace raco::core { struct PathManager { - using u8path = raco::utils::u8path; + using u8path = utils::u8path; static constexpr const char* DEFAULT_FILENAME = "Unnamed.rca"; static constexpr const char* Q_LAYOUT_FILE_NAME = "layout.ini"; @@ -50,6 +50,8 @@ struct PathManager { static void init(const u8path& executableDirectory, const u8path& appDataDirectory); + static void setDefaultResourceDirectory(const u8path& resourceDirectory); + static u8path executableDirectory(); static u8path defaultBaseDirectory(); @@ -81,11 +83,12 @@ struct PathManager { static void setCachedPath(FolderTypeKeys key, const u8path& path); private: - friend class raco::components::RaCoPreferences; + friend class components::RaCoPreferences; static u8path executableDirectory_; static u8path basePath_; static u8path appDataBasePath_; + static u8path defaultResourceDirectory_; // The default values for the subdirectories are set in RaCoPreferences::load static inline std::map cachedPaths_ = { diff --git a/datamodel/libCore/include/core/PrefabOperations.h b/datamodel/libCore/include/core/PrefabOperations.h index 888302b1..6d2ddcd3 100644 --- a/datamodel/libCore/include/core/PrefabOperations.h +++ b/datamodel/libCore/include/core/PrefabOperations.h @@ -31,10 +31,10 @@ class PrefabOperations { public: static void globalPrefabUpdate(BaseContext& context, bool propagateMissingInterfaceProperties = false); - static raco::user_types::SPrefabInstance findContainingPrefabInstance(SEditorObject object); - static raco::user_types::SPrefabInstance findOuterContainingPrefabInstance(SEditorObject object); + static user_types::SPrefabInstance findContainingPrefabInstance(SEditorObject object); + static user_types::SPrefabInstance findOuterContainingPrefabInstance(SEditorObject object); - static raco::user_types::SPrefab findContainingPrefab(SEditorObject object); + static user_types::SPrefab findContainingPrefab(SEditorObject object); /** * @brief Check if an objects serves as an interface object in a PrefabInstance. @@ -77,10 +77,10 @@ class PrefabOperations { static bool isPrefabInterfaceProperty(const PropertyDescriptor& prop); - static void prefabUpdateOrderDepthFirstSearch(raco::user_types::SPrefab current, std::vector& order); + static void prefabUpdateOrderDepthFirstSearch(user_types::SPrefab current, std::vector& order); private: - static void updatePrefabInstance(BaseContext& context, const raco::user_types::SPrefab& prefab, raco::user_types::SPrefabInstance instance, bool instanceDirty, bool propagateMissingInterfaceProperties); + static void updatePrefabInstance(BaseContext& context, const user_types::SPrefab& prefab, user_types::SPrefabInstance instance, bool instanceDirty, bool propagateMissingInterfaceProperties); }; } // namespace raco::core \ No newline at end of file diff --git a/datamodel/libCore/include/core/ProjectMigration.h b/datamodel/libCore/include/core/ProjectMigration.h index 47607055..a029b98f 100644 --- a/datamodel/libCore/include/core/ProjectMigration.h +++ b/datamodel/libCore/include/core/ProjectMigration.h @@ -101,10 +101,41 @@ namespace raco::serialization { * 53: Added the 'folderTypeKey' property to the URIAnnotation * 54: Added color write mask, stencilOptions, and scissorOptions properties to the BlendOptions struct type. * Added ColorWriteMask, ScissorOptions, and StencilOptions struct types. -*/ + * 55: Conversion of user types from Table and fixed properties to Array properties + * - Change EditorObject::children property from a Table to an Array + * - Converted fixed number of ref properties into Arrays in + * - RenderPass layers properties + * - RenderTarget buffers and bufferMSs properties + * - Converted Tables into Array in + * - AnimationChannel animationChannels property + * - Skin targets and joints properties + * 56: Split RenderTarget into RenderTarget and RenderTargetMS classes and + * change target property in RenderPass from RenderTarget to RenderTargetBase reference type + * 57: Added 'metadata' property to BaseObject + * 58: Removed userTags property from ProjectSettings + * 59: Added ResizableArray annotation to the following properties + * - RenderPass layers + * - RenderTarget & RenderTargeMS buffers + * - Animation animationChannels + * - Skin targets (but not joints) + * 60: Converted Link::startProp and endProp properties from Table to Array + * + * RaCo 2.x file versions + * 2001: follows version 60; first RaCo 2.x file version; + * - feature level reset to Ramses 28 feature level 1: removing feature levels in + * - Skin and AnchorPoint typeDescription + * - LuaInterface: luaModules, stdModules properties: removed FeatureLevel annotation + * - MeshNode::instanceCount reset LinkEndAnnotation + * - Node::enabled: reset LinkEndAnnotation and removed FeatureLevel Annotation + * - PerspectiveCamera::frustumType removed FeatureLevel Annotation + * - RenderPass: + * reset LinkEndAnnotation in enabled, renderOrder, clearColor properties + * reset LinkEndAnnotation and removed FeatureLevel annotation in renderOnce property + * - RenderLayer::renderableTags child properties: reset LinkEndAnnotation + */ -constexpr int RAMSES_PROJECT_FILE_VERSION = 54; +constexpr int RAMSES_PROJECT_FILE_VERSION = 2001; -void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serialization::proxy::ProxyObjectFactory& factory); +void migrateProject(ProjectDeserializationInfoIR& deserializedIR, serialization::proxy::ProxyObjectFactory& factory); } // namespace raco::serialization diff --git a/datamodel/libCore/include/core/ProjectSettings.h b/datamodel/libCore/include/core/ProjectSettings.h index 2479e9c5..45c3d8e7 100644 --- a/datamodel/libCore/include/core/ProjectSettings.h +++ b/datamodel/libCore/include/core/ProjectSettings.h @@ -107,8 +107,8 @@ class ProjectSettings : public EditorObject { Property> sceneId_{123u, DisplayNameAnnotation("Scene Id"), {1, 1024}}; - // Values are the same as in rlogic::EFeatureLevel enum - // See raco::ramses_base::BaseEngineBackend for definitions of min/max feature levels + // Values are the same as in ramses::EFeatureLevel enum + // See ramses_base::BaseEngineBackend for definitions of min/max feature levels Property featureLevel_{1, {"Feature Level"}, {}}; Property viewport_{{{1440, 720}, 0, 4096}, {"Display Size"}}; diff --git a/datamodel/libCore/include/core/ProxyObjectFactory.h b/datamodel/libCore/include/core/ProxyObjectFactory.h index 5856fe27..3d918447 100644 --- a/datamodel/libCore/include/core/ProxyObjectFactory.h +++ b/datamodel/libCore/include/core/ProxyObjectFactory.h @@ -19,22 +19,23 @@ namespace raco::serialization::proxy { using namespace raco::data_storage; -using raco::core::DisplayNameAnnotation; -using raco::core::RangeAnnotation; - -using raco::user_types::EngineTypeAnnotation; -using raco::core::LinkStartAnnotation; -using raco::core::LinkEndAnnotation; -using raco::core::URIAnnotation; -using raco::core::EnumerationAnnotation; -using raco::core::ArraySemanticAnnotation; -using raco::core::HiddenProperty; -using raco::core::TagContainerAnnotation; -using raco::core::UserTagContainerAnnotation; -using raco::core::ExpectEmptyReference; -using raco::core::RenderableTagContainerAnnotation; -using raco::core::FeatureLevel; -using raco::core::ReadOnlyAnnotation; +using core::DisplayNameAnnotation; +using core::RangeAnnotation; + +using user_types::EngineTypeAnnotation; +using core::LinkStartAnnotation; +using core::LinkEndAnnotation; +using core::URIAnnotation; +using core::EnumerationAnnotation; +using core::ArraySemanticAnnotation; +using core::HiddenProperty; +using core::TagContainerAnnotation; +using core::UserTagContainerAnnotation; +using core::ExpectEmptyReference; +using core::RenderableTagContainerAnnotation; +using core::FeatureLevel; +using core::ReadOnlyAnnotation; +using core::ResizableArray; template struct tuple_has_type {}; @@ -44,7 +45,7 @@ struct tuple_has_type> : std::disjunction }; -class ProxyObjectFactory : public raco::core::UserObjectFactoryInterface { +class ProxyObjectFactory : public core::UserObjectFactoryInterface { public: // The ProxyObjectFactory creates all objects and properties that are deserialized. // These are then further used as input to the migration code. @@ -147,7 +148,16 @@ class ProxyObjectFactory : public raco::core::UserObjectFactoryInterface { Property, Property, + // BaseObject + // dynamic: metadata category tables: + Property, + + // Animation + Property, DisplayNameAnnotation>, + Property, DisplayNameAnnotation, ResizableArray>, + // EditorObject + Property, ArraySemanticAnnotation, HiddenProperty>, Property, Property, Property, @@ -204,7 +214,10 @@ class ProxyObjectFactory : public raco::core::UserObjectFactoryInterface { // RenderPass Property, + Property, Property, + Property, DisplayNameAnnotation, ExpectEmptyReference>, + Property, DisplayNameAnnotation, ExpectEmptyReference, ResizableArray>, Property, Property, Property, @@ -218,6 +231,10 @@ class ProxyObjectFactory : public raco::core::UserObjectFactoryInterface { Property, // RenderTarget + Property, DisplayNameAnnotation, ExpectEmptyReference>, + Property, DisplayNameAnnotation, ExpectEmptyReference>, + Property, DisplayNameAnnotation, ExpectEmptyReference, ResizableArray>, + Property, DisplayNameAnnotation, ExpectEmptyReference, ResizableArray>, Property, Property, Property, @@ -241,6 +258,9 @@ class ProxyObjectFactory : public raco::core::UserObjectFactoryInterface { Property, // Skin + Property, DisplayNameAnnotation>, + Property, DisplayNameAnnotation, ResizableArray>, + Property, DisplayNameAnnotation>, Property, // BlendOptions diff --git a/datamodel/libCore/include/core/ProxyTypes.h b/datamodel/libCore/include/core/ProxyTypes.h index 05ce6fa1..721ac208 100644 --- a/datamodel/libCore/include/core/ProxyTypes.h +++ b/datamodel/libCore/include/core/ProxyTypes.h @@ -125,10 +125,18 @@ extern const char renderPassTypeName[]; using RenderPass = Proxy; using SRenderPass = std::shared_ptr; +extern const char renderTargetBaseTypeName[]; +using RenderTargetBase = Proxy; +using SRenderTargetBase = std::shared_ptr; + extern const char renderTargetTypeName[]; -using RenderTarget = Proxy; +using RenderTarget = Proxy; using SRenderTarget = std::shared_ptr; +extern const char renderTargetMSTypeName[]; +using RenderTargetMS = Proxy; +using SRenderTargetMS = std::shared_ptr; + extern const char prefabTypeName[]; using Prefab = Proxy; using SPrefab = std::shared_ptr; diff --git a/datamodel/libCore/include/core/Queries.h b/datamodel/libCore/include/core/Queries.h index a199f850..dcf12008 100644 --- a/datamodel/libCore/include/core/Queries.h +++ b/datamodel/libCore/include/core/Queries.h @@ -89,7 +89,7 @@ namespace Queries { // is changeable in the data model. bool isReadOnly(const Project& project, const ValueHandle& handle, bool linkState = false); - bool isHiddenInPropertyBrowser(const Project& project, const ValueHandle& handle); + bool isHiddenInPropertyBrowser(const Project& project, const ValueHandle& handle, bool isMultiSelect); // Determines whether an object is read-only content of a prefab instance diff --git a/datamodel/libCore/include/core/SceneBackendInterface.h b/datamodel/libCore/include/core/SceneBackendInterface.h index a1dc9b8f..34ccb223 100644 --- a/datamodel/libCore/include/core/SceneBackendInterface.h +++ b/datamodel/libCore/include/core/SceneBackendInterface.h @@ -19,7 +19,7 @@ namespace raco::core { public: struct SceneItemDesc { public: - SceneItemDesc(const std::string& type, const std::string& name, int parentIndex) : type_(type), objectName_(name), parentIndex_(parentIndex) {} + SceneItemDesc(const std::string& type, std::string_view name, int parentIndex) : type_(type), objectName_(name), parentIndex_(parentIndex) {} std::string type_; std::string objectName_; diff --git a/datamodel/libCore/include/core/Serialization.h b/datamodel/libCore/include/core/Serialization.h index 7b6cc295..a89d1784 100644 --- a/datamodel/libCore/include/core/Serialization.h +++ b/datamodel/libCore/include/core/Serialization.h @@ -12,7 +12,9 @@ #include "core/CoreAnnotations.h" #include "core/BasicAnnotations.h" #include "core/BasicTypes.h" +#include "core/UserObjectFactoryInterface.h" #include "data_storage/Value.h" +#include "user_types/UserObjectFactory.h" #include #include @@ -38,10 +40,10 @@ using SDynamicEditorObject = std::shared_ptr; namespace raco::serialization { -using raco::data_storage::ClassWithReflectedMembers; -using raco::data_storage::PrimitiveType; -using raco::data_storage::ReflectionInterface; -using raco::data_storage::ValueBase; +using data_storage::ClassWithReflectedMembers; +using data_storage::PrimitiveType; +using data_storage::ReflectionInterface; +using data_storage::ValueBase; using SReflectionInterface = std::shared_ptr; struct ExternalProjectInfo { @@ -51,22 +53,22 @@ struct ExternalProjectInfo { bool operator==(const ExternalProjectInfo& lhs, const ExternalProjectInfo& rhs); -std::string serializeProperty(const raco::core::Project& project, const raco::data_storage::ValueBase& value); +std::string serializeProperty(const core::Project& project, const data_storage::ValueBase& value); -std::string serializeObjects(const std::vector& objects, const std::vector& rootObjectIDs, const std::vector& links, const std::string& originFolder, const std::string& originFilename, const std::string& originProjectID, const std::string& originProjectName, const std::map& externalProjectsMap, const std::map& originFolders, int featureLevel, bool includeVersionInfo = true); +std::string serializeObjects(const std::vector& objects, const std::vector& rootObjectIDs, const std::vector& links, const std::string& originFolder, const std::string& originFilename, const std::string& originProjectID, const std::string& originProjectName, const std::map& externalProjectsMap, const std::map& originFolders, int featureLevel, bool includeVersionInfo = true); QJsonDocument serializeProject(const std::unordered_map>& fileVersions, int featureLevel, const std::vector& instances, const std::vector& links, const std::map& externalProjectsMap); -using References = std::map; +using References = std::map; struct ObjectDeserialization { - raco::core::SEditorObject object; + core::SEditorObject object; References references; }; struct ObjectsDeserialization { - std::vector objects; + std::vector objects; // object ids of the top-level (no parents) objects std::set rootObjectIDs; - std::vector links; + std::vector links; References references; int featureLevel; std::string originFolder; @@ -100,7 +102,6 @@ inline bool operator==(const DeserializedVersion& lhVersion, const DeserializedV struct ProjectVersionInfo { DeserializedVersion raCoVersion; DeserializedVersion ramsesVersion; - DeserializedVersion ramsesLogicEngineVersion; }; template @@ -119,21 +120,27 @@ struct GenericProjectDeserializationInfo { static constexpr int NO_VERSION = -1; }; -using ProjectDeserializationInfo = GenericProjectDeserializationInfo; -using ProjectDeserializationInfoIR = GenericProjectDeserializationInfo; +using ProjectDeserializationInfo = GenericProjectDeserializationInfo; +using ProjectDeserializationInfoIR = GenericProjectDeserializationInfo; int deserializeFileVersion(const QJsonDocument& document); + +/** + * @brief Returns the migrated feature level from a Json document for a .rca project file. + * + * The return value includes the feature level reset at major versions. +*/ int deserializeFeatureLevel(const QJsonDocument& document); ProjectVersionInfo deserializeProjectVersionInfo(const QJsonDocument& document); -std::unique_ptr deserializeProperty(const raco::core::Project& project, const std::string& json); +std::unique_ptr deserializeProperty(const core::Project& project, const std::string& json); -std::optional deserializeObjects(const std::string& json, bool checkVersionInfo = true); +std::optional deserializeObjects(const std::string& json, bool checkVersionInfo = true, core::UserObjectFactoryInterface& factory = user_types::UserObjectFactory::getInstance()); ProjectDeserializationInfo deserializeProject(const QJsonDocument& jsonDocument, const std::string& filename); -std::map> makeUserTypePropertyMap(); +std::map> makeUserTypePropertyMap(core::UserObjectFactoryInterface& objectFactory = user_types::UserObjectFactory::getInstance()); std::map> makeStructPropertyMap(); std::map> deserializeUserTypePropertyMap(const QVariant& container); @@ -143,7 +150,7 @@ namespace test_helpers { std::string serializeObject(const SReflectionInterface& object, const std::string& projectPath = {}); -ObjectDeserialization deserializeObject(const std::string& json); +ObjectDeserialization deserializeObject(const std::string& json, core::UserObjectFactoryInterface& objectFactory = user_types::UserObjectFactory::getInstance()); } // namespace test_helpers diff --git a/datamodel/libCore/include/core/SerializationKeys.h b/datamodel/libCore/include/core/SerializationKeys.h index d2a8436e..c7be0e23 100644 --- a/datamodel/libCore/include/core/SerializationKeys.h +++ b/datamodel/libCore/include/core/SerializationKeys.h @@ -21,7 +21,6 @@ constexpr const char* VALUE{"value"}; constexpr const char* ANNOTATIONS{"annotations"}; constexpr const char* FILE_VERSION{"fileVersion"}; constexpr const char* RAMSES_VERSION{"ramsesVersion"}; -constexpr const char* RAMSES_LOGIC_ENGINE_VERSION{"logicEngineVersion"}; constexpr const char* RAMSES_COMPOSER_VERSION{"racoVersion"}; constexpr const char* INSTANCES{"instances"}; constexpr const char* EXTERNAL_PROJECTS{"externalProjects"}; diff --git a/datamodel/libCore/include/core/Undo.h b/datamodel/libCore/include/core/Undo.h index d9fea684..dd865fbe 100644 --- a/datamodel/libCore/include/core/Undo.h +++ b/datamodel/libCore/include/core/Undo.h @@ -28,13 +28,14 @@ class UndoHelpers { public: static void updateSingleValue(const ValueBase *src, ValueBase *dest, ValueHandle destHandle, translateRefFunc translateRef, DataChangeRecorder *outChanges, bool invokeHandler); - static void callOnBeforeRemoveReferenceHandler(raco::data_storage::Table *dest, const size_t &index, raco::core::ValueHandle &destHandle); + static void callOnBeforeRemoveReferenceHandler(ReflectionInterface *dest, const size_t &index, core::ValueHandle &destHandle); static void updateEditorObject(const EditorObject *src, SEditorObject dest, translateRefFunc translateRef, excludePropertyPredicateFunc excludeIf, UserObjectFactoryInterface &factory, DataChangeRecorder *outChanges, bool invokeHandler, bool updateObjectAnnotations = true); static void updateMissingTableProperties(const Table *src, Table *dest, ValueHandle destHandle, translateRefFunc translateRef, DataChangeRecorder *outChanges, bool invokeHandler); private: static void updateTableAsArray(const Table *src, Table *dest, ValueHandle destHandle, translateRefFunc translateRef, DataChangeRecorder *outChanges, bool invokeHandler); + static void updateArray(const ArrayBase *src, ArrayBase *dest, ValueHandle destHandle, translateRefFunc translateRef, DataChangeRecorder *outChanges, bool invokeHandle); static void updateStruct(const ClassWithReflectedMembers *src, ClassWithReflectedMembers *dest, ValueHandle destHandle, translateRefFunc translateRef, DataChangeRecorder *outChanges, bool invokeHandler); static void updateTableByName(const Table *src, Table *dest, ValueHandle destHandle, translateRefFunc translateRef, DataChangeRecorder *outChanges, bool invokeHandler); }; @@ -74,6 +75,8 @@ class UndoStack { */ void endCompositeCommand(const std::string &description, bool abort = false); + int depth() const; + // Number of entries on the undo stack size_t size() const; const std::string &description(size_t index) const; diff --git a/datamodel/libCore/src/CommandInterface.cpp b/datamodel/libCore/src/CommandInterface.cpp index 43ab9f36..b8224d25 100644 --- a/datamodel/libCore/src/CommandInterface.cpp +++ b/datamodel/libCore/src/CommandInterface.cpp @@ -80,7 +80,7 @@ bool CommandInterface::canSetHandle(ValueHandle const& handle, PrimitiveType typ } -bool CommandInterface::checkHandleForSet(ValueHandle const& handle) { +bool CommandInterface::checkHandleForSet(ValueHandle const& handle, bool allowVolatile) { if (!handle) { throw std::runtime_error(fmt::format("Invalid property handle")); } @@ -91,18 +91,24 @@ bool CommandInterface::checkHandleForSet(ValueHandle const& handle) { throw std::runtime_error(fmt::format("Property {} inaccessible at feature level {}", handle.getPropertyPath(), project()->featureLevel())); } - if (Queries::isReadOnly(*project(), handle, false)) { - throw std::runtime_error(fmt::format("Property '{}' is read-only", handle.getPropertyPath())); - } - if (Queries::currentLinkState(*project(), handle) != Queries::CurrentLinkState::NOT_LINKED) { - throw std::runtime_error(fmt::format("Property '{}' is linked", handle.getPropertyPath())); + if (handle.query()) { + if (!allowVolatile) { + return false; + } + } else { + if (Queries::isReadOnly(*project(), handle, false)) { + throw std::runtime_error(fmt::format("Property '{}' is read-only", handle.getPropertyPath())); + } + if (Queries::currentLinkState(*project(), handle) != Queries::CurrentLinkState::NOT_LINKED) { + throw std::runtime_error(fmt::format("Property '{}' is linked", handle.getPropertyPath())); + } } - + return true; } -bool CommandInterface::checkScalarHandleForSet(ValueHandle const& handle, PrimitiveType type) { - if (checkHandleForSet(handle)) { +bool CommandInterface::checkScalarHandleForSet(ValueHandle const& handle, PrimitiveType type, bool allowVolatile) { + if (checkHandleForSet(handle, allowVolatile)) { if (handle.type() != type) { throw std::runtime_error(fmt::format("Property '{}' is a '{}' and not a '{}'", handle.getPropertyPath(), handle.type(), getTypeName(type))); } @@ -122,18 +128,20 @@ std::string CommandInterface::getMergeId(const std::set& handles) { } void CommandInterface::set(ValueHandle const& handle, bool const& value) { - if (checkScalarHandleForSet(handle, PrimitiveType::Bool) && handle.asBool() != value) { + if (checkScalarHandleForSet(handle, PrimitiveType::Bool, true) && handle.asBool() != value) { context_->set(handle, value); - PrefabOperations::globalPrefabUpdate(*context_); - undoStack_->push(fmt::format("Set property '{}' to {}", handle.getPropertyPath(), value), - fmt::format("{}", handle.getPropertyPath(true))); + if (!handle.query()) { + PrefabOperations::globalPrefabUpdate(*context_); + undoStack_->push(fmt::format("Set property '{}' to {}", handle.getPropertyPath(), value), + fmt::format("{}", handle.getPropertyPath(true))); + } } } bool CommandInterface::canSet(ValueHandle const& handle, int const& value) const { if (canSetHandle(handle, PrimitiveType::Int)) { - if (auto anno = handle.query()) { - auto description = user_types::enumerationDescription(static_cast(anno->type_.asInt())); + if (auto anno = handle.query()) { + auto description = user_types::enumerationDescription(static_cast(anno->type_.asInt())); if (description.find(value) == description.end()) { return false; } @@ -144,26 +152,28 @@ bool CommandInterface::canSet(ValueHandle const& handle, int const& value) const } void CommandInterface::set(ValueHandle const& handle, int const& value) { - if (checkScalarHandleForSet(handle, PrimitiveType::Int) && handle.asInt() != value) { - if (auto anno = handle.query()) { - auto description = user_types::enumerationDescription(static_cast(anno->type_.asInt())); + if (checkScalarHandleForSet(handle, PrimitiveType::Int, true) && handle.asInt() != value) { + if (auto anno = handle.query()) { + auto description = user_types::enumerationDescription(static_cast(anno->type_.asInt())); if (description.find(value) == description.end()) { throw std::runtime_error(fmt::format("Value '{}' not in enumeration type", value)); } } context_->set(handle, value); - PrefabOperations::globalPrefabUpdate(*context_); - undoStack_->push(fmt::format("Set property '{}' to {}", handle.getPropertyPath(), value), - fmt::format("{}", handle.getPropertyPath(true))); + if (!handle.query()) { + PrefabOperations::globalPrefabUpdate(*context_); + undoStack_->push(fmt::format("Set property '{}' to {}", handle.getPropertyPath(), value), + fmt::format("{}", handle.getPropertyPath(true))); + } } } void CommandInterface::set(const std::set& handles, int value) { if (std::all_of(handles.begin(), handles.end(), [this, value](auto handle) { if (checkScalarHandleForSet(handle, PrimitiveType::Int)) { - if (auto anno = handle.template query()) { - auto description = user_types::enumerationDescription(static_cast(anno->type_.asInt())); + if (auto anno = handle.template query()) { + auto description = user_types::enumerationDescription(static_cast(anno->type_.asInt())); if (description.find(value) == description.end()) { throw std::runtime_error(fmt::format("Value '{}' not in enumeration type", value)); return false; @@ -188,11 +198,13 @@ void CommandInterface::set(const std::set& handles, int value) { } void CommandInterface::set(ValueHandle const& handle, int64_t const& value) { - if (checkScalarHandleForSet(handle, PrimitiveType::Int64) && handle.asInt64() != value) { + if (checkScalarHandleForSet(handle, PrimitiveType::Int64, true) && handle.asInt64() != value) { context_->set(handle, value); - PrefabOperations::globalPrefabUpdate(*context_); - undoStack_->push(fmt::format("Set property '{}' to {}", handle.getPropertyPath(), value), - fmt::format("{}", handle.getPropertyPath(true))); + if (!handle.query()) { + PrefabOperations::globalPrefabUpdate(*context_); + undoStack_->push(fmt::format("Set property '{}' to {}", handle.getPropertyPath(), value), + fmt::format("{}", handle.getPropertyPath(true))); + } } } @@ -215,11 +227,13 @@ void CommandInterface::set(const std::set& handles, int64_t value) } void CommandInterface::set(ValueHandle const& handle, double const& value) { - if (checkScalarHandleForSet(handle, PrimitiveType::Double) && handle.asDouble() != value) { + if (checkScalarHandleForSet(handle, PrimitiveType::Double, true) && handle.asDouble() != value) { context_->set(handle, value); - PrefabOperations::globalPrefabUpdate(*context_); - undoStack_->push(fmt::format("Set property '{}' to {}", handle.getPropertyPath(), value), - fmt::format("{}", handle.getPropertyPath(true))); + if (!handle.query()) { + PrefabOperations::globalPrefabUpdate(*context_); + undoStack_->push(fmt::format("Set property '{}' to {}", handle.getPropertyPath(), value), + fmt::format("{}", handle.getPropertyPath(true))); + } } } @@ -242,14 +256,16 @@ void CommandInterface::set(const std::set& handles, double const& v } void CommandInterface::set(ValueHandle const& handle, std::string const& value) { - if (checkScalarHandleForSet(handle, PrimitiveType::String)) { - auto newValue = handle.query() ? raco::utils::u8path::sanitizePathString(value) : value; + if (checkScalarHandleForSet(handle, PrimitiveType::String, true)) { + auto newValue = handle.query() ? utils::u8path::sanitizePathString(value) : value; if (handle.asString() != newValue) { context_->set(handle, newValue); - PrefabOperations::globalPrefabUpdate(*context_); - undoStack_->push(fmt::format("Set property '{}' to {}", handle.getPropertyPath(), newValue), - fmt::format("{}", handle.getPropertyPath(true))); + if (!handle.query()) { + PrefabOperations::globalPrefabUpdate(*context_); + undoStack_->push(fmt::format("Set property '{}' to {}", handle.getPropertyPath(), newValue), + fmt::format("{}", handle.getPropertyPath(true))); + } } } } @@ -435,8 +451,7 @@ void CommandInterface::setRenderableTags(ValueHandle const& handle, std::vector< data_storage::Table table; for (auto const& p : renderableTags) { - // Note: render order is only linkable starting at feature level 3. - table.addProperty(p.first, new Property(p.second, {3})); + table.addProperty(p.first, new Property(p.second, {})); } if (!(handle.constValueRef()->asTable() == table)) { @@ -449,6 +464,23 @@ void CommandInterface::setRenderableTags(ValueHandle const& handle, std::vector< } +void CommandInterface::resizeArray(const ValueHandle& handle, size_t newSize) { + if (checkScalarHandleForSet(handle, PrimitiveType::Array)) { + if (handle.query()) { + throw std::runtime_error(fmt::format("Property '{}' has an ArraySemanticAnnotation and can't be resized.", handle.getPropertyPath())); + } + if (!handle.query()) { + throw std::runtime_error(fmt::format("Property '{}' is not a resizable array property.", handle.getPropertyPath())); + } + + if (newSize != handle.size()) { + context_->resizeArray(handle, newSize); + PrefabOperations::globalPrefabUpdate(*context_); + undoStack_->push(fmt::format("Resize array property '{}' to size {}.", handle.getPropertyPath(), newSize)); + } + } +} + SEditorObject CommandInterface::createObject(std::string type, std::string name, SEditorObject parent) { if (context_->objectFactory()->isUserCreatable(type, project()->featureLevel())) { if (parent && !project()->isInstance(parent)) { @@ -521,7 +553,7 @@ size_t CommandInterface::moveScenegraphChildren(std::vector const return moveableChildren.size(); } -void CommandInterface::insertAssetScenegraph(const raco::core::MeshScenegraph& scenegraph, const std::string& absPath, SEditorObject const& parent) { +void CommandInterface::insertAssetScenegraph(const core::MeshScenegraph& scenegraph, const std::string& absPath, SEditorObject const& parent) { // TODO error checking: scenegraph is not checked if (parent && !project()->isInstance(parent)) { throw std::runtime_error(fmt::format("insertAssetScenegraph: parent object '{}' not in project", parent->objectName())); @@ -530,7 +562,7 @@ void CommandInterface::insertAssetScenegraph(const raco::core::MeshScenegraph& s context_->insertAssetScenegraph(scenegraph, absPath, parent); PrefabOperations::globalPrefabUpdate(*context_); undoStack_->push(fmt::format("Inserted assets from {}", absPath)); - PathManager::setCachedPath(raco::core::PathManager::FolderTypeKeys::Mesh, raco::utils::u8path(absPath).parent_path().string()); + PathManager::setCachedPath(core::PathManager::FolderTypeKeys::Mesh, utils::u8path(absPath).parent_path().string()); } std::string CommandInterface::copyObjects(const std::vector& objects, bool deepCopy) { @@ -635,6 +667,7 @@ void CommandInterface::removeLink(const PropertyDescriptor& end) { throw std::runtime_error(fmt::format("Link end object '{}' not in project", end.object()->objectName())); } + // Note: link removal from non-existing properties is legal since there may be invalid links ending on non-existing properties. if (auto link = Queries::getLink(*context_->project(), end)) { if (Queries::userCanRemoveLink(*context_->project(), end)) { context_->removeLink(end); diff --git a/datamodel/libCore/src/Context.cpp b/datamodel/libCore/src/Context.cpp index f60d098d..b761caee 100644 --- a/datamodel/libCore/src/Context.cpp +++ b/datamodel/libCore/src/Context.cpp @@ -26,6 +26,7 @@ #include "core/Serialization.h" #include "core/Undo.h" #include "core/UserObjectFactoryInterface.h" +#include "data_storage/Array.h" #include "log_system/log.h" #include "user_types/Animation.h" #include "user_types/AnimationChannel.h" @@ -215,6 +216,23 @@ void BaseContext::setT(ValueHandle const& handle, StructBase const& changeMultiplexer_.recordValueChanged(handle); } +template <> +void BaseContext::setT(ValueHandle const& handle, ArrayBase const& value) { + ValueBase* v = handle.valueRef(); + + callReferenceToThisHandler<&EditorObject::onBeforeRemoveReferenceToThis>(handle); + + v->setArray(value); + + callReferenceToThisHandler<&EditorObject::onAfterAddReferenceToThis>(handle); + + handle.object_->onAfterValueChanged(*this, handle); + + callReferencedObjectChangedHandlers(handle.object_); + + changeMultiplexer_.recordValueChanged(handle); +} + void BaseContext::set(ValueHandle const& handle, bool const& value) { setT(handle, value); } @@ -291,10 +309,19 @@ void BaseContext::set(ValueHandle const& handle, StructBase const& value) { setT(handle, value); } -ValueBase* BaseContext::addProperty(const ValueHandle& handle, std::string name, std::unique_ptr&& newProperty, int indexBefore) { - Table& table{handle.valueRef()->asTable()}; +void BaseContext::set(ValueHandle const& handle, ArrayBase const& value) { + setT(handle, value); +} - ValueBase* newValue = table.addProperty(name, std::move(newProperty), indexBefore); +ValueBase* BaseContext::addProperty(const ValueHandle& handle, std::string name, std::unique_ptr&& newProperty, int indexBefore) { + ValueBase* newValue; + if (handle.type() == PrimitiveType::Table) { + newValue = handle.valueRef()->asTable().addProperty(name, std::move(newProperty), indexBefore); + } else if (handle.type() == PrimitiveType::Array) { + newValue = handle.valueRef()->asArray().addProperty(std::move(newProperty), indexBefore); + } else { + assert(false); + } ValueHandle newHandle = indexBefore == -1 ? handle[handle.size() - 1] : handle[indexBefore]; @@ -319,8 +346,6 @@ ValueBase* BaseContext::addProperty(const ValueHandle& handle, std::string name, } void BaseContext::removeProperty(const ValueHandle& handle, size_t index) { - Table& table{handle.valueRef()->asTable()}; - SEditorObjectSet updateLinkErrors; { @@ -339,7 +364,13 @@ void BaseContext::removeProperty(const ValueHandle& handle, size_t index) { callReferenceToThisHandler<&EditorObject::onBeforeRemoveReferenceToThis>(propHandle); - table.removeProperty(index); + if (handle.type() == PrimitiveType::Table) { + handle.valueRef()->asTable().removeProperty(index); + } else if (handle.type() == PrimitiveType::Array) { + handle.valueRef()->asArray().removeProperty(index); + } else { + assert(false); + } } // We need to update the broken link errors _after_ removing the property since links are only considered @@ -360,8 +391,9 @@ void BaseContext::removeProperty(const ValueHandle& handle, size_t index) { } void BaseContext::removeProperty(const ValueHandle& handle, const std::string& name) { - Table& table{handle.valueRef()->asTable()}; - removeProperty(handle, table.index(name)); + auto index = handle.valueRef()->getSubstructure().index(name); + assert(index != -1); + removeProperty(handle, index); } void BaseContext::removeAllProperties(const ValueHandle& handle) { @@ -379,6 +411,25 @@ void BaseContext::swapProperties(const ValueHandle& handle, size_t index_1, size changeMultiplexer_.recordValueChanged(handle); } +void BaseContext::resizeArray(const ValueHandle& handle, size_t newSize) { + auto& array = handle.valueRef()->asArray(); + auto oldSize = array.size(); + + for (size_t index = newSize; index < oldSize; index++) { + callReferenceToThisHandler<&EditorObject::onBeforeRemoveReferenceToThis>(handle[index]); + } + + array.resize(newSize); + + // grow: no onAfterAddReferenceToThis needed since the new array elements are empty + + handle.object_->onAfterValueChanged(*this, handle); + + callReferencedObjectChangedHandlers(handle.object_); + + changeMultiplexer_.recordValueChanged(handle); +} + namespace { std::vector collectObjectsForCopyOrCutOperations(const std::vector& objects, bool deep) { @@ -432,7 +483,7 @@ std::string BaseContext::copyObjects(const std::vector& objects, auto allObjects{collectObjectsForCopyOrCutOperations(objects, deepCopy)}; auto rootObjectIDs{findRootObjectIDs(allObjects)}; auto originFolders{findOriginFolders(*project_, allObjects)}; - return raco::serialization::serializeObjects(allObjects, + return serialization::serializeObjects(allObjects, rootObjectIDs, collectLinksForCopyOrCutOperation(*project_, allObjects), project_->currentFolder(), @@ -449,7 +500,7 @@ std::string BaseContext::cutObjects(const std::vector& objects, b auto allLinks{collectLinksForCopyOrCutOperation(*project_, allObjects)}; auto rootObjectIDs{findRootObjectIDs(allObjects)}; auto originFolders{findOriginFolders(*project_, allObjects)}; - std::string serialization{raco::serialization::serializeObjects(allObjects, + std::string serialization{serialization::serializeObjects(allObjects, rootObjectIDs, allLinks, project_->currentFolder(), @@ -463,7 +514,7 @@ std::string BaseContext::cutObjects(const std::vector& objects, b return serialization; } -void BaseContext::rerootRelativePaths(std::vector& newObjects, raco::serialization::ObjectsDeserialization& deserialization) { +void BaseContext::rerootRelativePaths(std::vector& newObjects, serialization::ObjectsDeserialization& deserialization) { for (auto object : newObjects) { if (PathQueries::isPathRelativeToCurrentProject(object)) { for (auto property : core::ValueTreeIteratorAdaptor(core::ValueHandle{object})) { @@ -476,11 +527,11 @@ void BaseContext::rerootRelativePaths(std::vector& newObjects, ra } else { originFolder = deserialization.originFolder; } - if (!originFolder.empty() && !uriPath.empty() && raco::utils::u8path(uriPath).is_relative()) { - if (raco::utils::u8path::areSharingSameRoot(originFolder, this->project()->currentPath())) { - property.valueRef()->set(raco::utils::u8path(uriPath).rerootRelativePath(originFolder, this->project()->currentFolder()).string()); + if (!originFolder.empty() && !uriPath.empty() && utils::u8path(uriPath).is_relative()) { + if (utils::u8path::areSharingSameRoot(originFolder, this->project()->currentPath())) { + property.valueRef()->set(utils::u8path(uriPath).rerootRelativePath(originFolder, this->project()->currentFolder()).string()); } else { - property.valueRef()->set(raco::utils::u8path(uriPath).normalizedAbsolutePath(originFolder).string()); + property.valueRef()->set(utils::u8path(uriPath).normalizedAbsolutePath(originFolder).string()); } } } @@ -490,7 +541,7 @@ void BaseContext::rerootRelativePaths(std::vector& newObjects, ra } -bool BaseContext::extrefPasteDiscardObject(SEditorObject editorObject, raco::serialization::ObjectsDeserialization& deserialization) { +bool BaseContext::extrefPasteDiscardObject(SEditorObject editorObject, serialization::ObjectsDeserialization& deserialization) { // filter objects: // - keep only top-level prefabs, top-level lua script and resources if (!Queries::canPasteObjectAsExternalReference(editorObject, deserialization.rootObjectIDs.find(editorObject->objectID()) != deserialization.rootObjectIDs.end())) { @@ -516,7 +567,7 @@ bool BaseContext::extrefPasteDiscardObject(SEditorObject editorObject, raco::ser originProjectID = *anno->projectID_; auto it = deserialization.externalProjectsMap.find(originProjectID); if (it != deserialization.externalProjectsMap.end()) { - originProjectPath = raco::utils::u8path(it->second.path).normalizedAbsolutePath(deserialization.originFolder).string(); + originProjectPath = utils::u8path(it->second.path).normalizedAbsolutePath(deserialization.originFolder).string(); } else { throw ExtrefError("Paste: can't resolve external project path"); } @@ -542,7 +593,7 @@ bool BaseContext::extrefPasteDiscardObject(SEditorObject editorObject, raco::ser return true; } -void BaseContext::adjustExtrefAnnotationsForPaste(std::vector& newObjects, raco::serialization::ObjectsDeserialization& deserialization, bool pasteAsExtref) { +void BaseContext::adjustExtrefAnnotationsForPaste(std::vector& newObjects, serialization::ObjectsDeserialization& deserialization, bool pasteAsExtref) { for (auto& editorObject : newObjects) { if (pasteAsExtref) { if (!editorObject->query()) { @@ -554,7 +605,7 @@ void BaseContext::adjustExtrefAnnotationsForPaste(std::vector& ne auto it = deserialization.externalProjectsMap.find(extProjID); if (it != deserialization.externalProjectsMap.end()) { - project_->addExternalProjectMapping(extProjID, raco::utils::u8path(it->second.path).normalizedAbsolutePath(deserialization.originFolder).string(), it->second.name); + project_->addExternalProjectMapping(extProjID, utils::u8path(it->second.path).normalizedAbsolutePath(deserialization.originFolder).string(), it->second.name); } else { throw ExtrefError("Paste: can't resolve external project path"); } @@ -567,7 +618,7 @@ void BaseContext::adjustExtrefAnnotationsForPaste(std::vector& ne } } -void BaseContext::restoreReferences(const Project& project, std::vector& newObjects, raco::serialization::ObjectsDeserialization& deserialization) { +void BaseContext::restoreReferences(const Project& project, std::vector& newObjects, serialization::ObjectsDeserialization& deserialization) { std::map oldIdToEditorObject{}; for (auto& editorObject : newObjects) { oldIdToEditorObject[editorObject->objectID()] = editorObject; @@ -584,7 +635,7 @@ void BaseContext::restoreReferences(const Project& project, std::vector& newObjects) { +void BaseContext::generateNewObjectIDs(std::vector& newObjects) { // Generate new ids: // Pass 1: everything except PrefabInstance children std::map prefabInstanceIDMap; @@ -612,7 +663,7 @@ void BaseContext::generateNewObjectIDs(std::vector& n } std::vector BaseContext::pasteObjects(const std::string& seralizedObjects, const SEditorObject& target, bool pasteAsExtref) { - auto deserialization_opt{raco::serialization::deserializeObjects(seralizedObjects)}; + auto deserialization_opt{serialization::deserializeObjects(seralizedObjects)}; if (!deserialization_opt) { throw std::runtime_error("Paste Objects: data has invalid format."); } @@ -938,6 +989,10 @@ bool BaseContext::deleteWithVolatileSideEffects(Project* project, const SEditorO } size_t BaseContext::deleteObjects(std::vector const& objects, bool gcExternalProjectMap, bool includeChildren) { + if (objects.empty()) { + return 0; + } + SEditorObjectSet toRemove; if (includeChildren) { toRemove = Queries::collectAllChildren(objects); @@ -1035,22 +1090,26 @@ void BaseContext::moveScenegraphChildren(std::vector const& objec }); } -void BaseContext::insertAssetScenegraph(const raco::core::MeshScenegraph& scenegraph, const std::string& absPath, SEditorObject const& parent) { - auto relativeFilePath = raco::utils::u8path(absPath).normalizedRelativePath(project()->currentFolder()); +void BaseContext::insertAssetScenegraph(const core::MeshScenegraph& scenegraph, const std::string& absPath, SEditorObject const& parent) { + auto relativeFilePath = utils::u8path(absPath).normalizedRelativePath(project()->currentFolder()); std::vector meshScenegraphMeshes; std::vector meshScenegraphNodes; LOG_INFO(log_system::CONTEXT, "Importing all meshes..."); - auto projectMeshes = Queries::filterByTypeName(project()->instances(), {raco::user_types::Mesh::typeDescription.typeName}); + auto projectMeshes = Queries::filterByTypeName(project()->instances(), {user_types::Mesh::typeDescription.typeName}); std::map, SEditorObject> propertiesToMeshMap; std::map, SEditorObject> propertiesToChannelMap; for (const auto& instance : project()->instances()) { - if (instance->as() && !instance->query()) { - propertiesToMeshMap[{instance->get("bakeMeshes")->asBool(), instance->get("meshIndex")->asInt(), instance->get("uri")->asString()}] = instance; - } else if (instance->as() && !instance->query()) { - auto absPath = core::PathQueries::resolveUriPropertyToAbsolutePath(*project_, ValueHandle(instance, &user_types::AnimationChannel::uri_)); - propertiesToChannelMap[{absPath, instance->get("animationIndex")->asInt(), instance->get("samplerIndex")->asInt()}] = instance; + if (!instance->query()) { + if (instance->isType()) { + auto mesh = instance->as(); + propertiesToMeshMap[{*mesh->bakeMeshes_, *mesh->meshIndex_, *mesh->uri_}] = instance; + } else if (instance->isType()) { + auto channel = instance->as(); + auto absPath = core::PathQueries::resolveUriPropertyToAbsolutePath(*project_, ValueHandle(instance, &user_types::AnimationChannel::uri_)); + propertiesToChannelMap[{absPath, *channel->animationIndex_, *channel->samplerIndex_}] = instance; + } } } @@ -1064,12 +1123,11 @@ void BaseContext::insertAssetScenegraph(const raco::core::MeshScenegraph& sceneg auto meshWithSameProperties = propertiesToMeshMap.find({false, static_cast(i), relativeFilePath.string()}); if (meshWithSameProperties == propertiesToMeshMap.end()) { LOG_DEBUG(log_system::CONTEXT, "Did not find existing local Mesh with same properties as asset mesh, creating one instead..."); - auto ¤tSubmesh = meshScenegraphMeshes.emplace_back(createObject(raco::user_types::Mesh::typeDescription.typeName, *scenegraph.meshes[i])); - auto currentSubmeshHandle = ValueHandle{currentSubmesh}; + auto& currentSubmesh = meshScenegraphMeshes.emplace_back(createObject(user_types::Mesh::typeDescription.typeName, *scenegraph.meshes[i])); - set(currentSubmeshHandle.get("bakeMeshes"), false); - set(currentSubmeshHandle.get("meshIndex"), static_cast(i)); - set(currentSubmeshHandle.get("uri"), relativeFilePath.string()); + set({currentSubmesh, &user_types::Mesh::bakeMeshes_}, false); + set({currentSubmesh, &user_types::Mesh::meshIndex_}, static_cast(i)); + set({currentSubmesh, &user_types::Mesh::uri_}, relativeFilePath.string()); } else { LOG_DEBUG(log_system::CONTEXT, "Found existing local Mesh {} with same properties as asset mesh, using this Mesh...", *scenegraph.meshes[i]); meshScenegraphMeshes.emplace_back(meshWithSameProperties->second); @@ -1085,7 +1143,7 @@ void BaseContext::insertAssetScenegraph(const raco::core::MeshScenegraph& sceneg auto meshPath = relativeFilePath.filename().string(); meshPath = project_->findAvailableUniqueName(topLevelObjects.begin(), topLevelObjects.end(), nullptr, meshPath); - auto sceneRootNode = createObject(raco::user_types::Node::typeDescription.typeName, meshPath); + auto sceneRootNode = createObject(user_types::Node::typeDescription.typeName, meshPath); if (parent) { moveScenegraphChildren(core::Queries::filterForMoveableScenegraphChildren(*project(), {sceneRootNode}, parent), parent); } @@ -1103,17 +1161,17 @@ void BaseContext::insertAssetScenegraph(const raco::core::MeshScenegraph& sceneg SEditorObject newNode; if (meshScenegraphNode.subMeshIndices.empty()) { LOG_DEBUG(log_system::CONTEXT, "Found node {} with no submeshes -> creating Node...", meshScenegraphNode.name); - newNode = meshScenegraphNodes.emplace_back(createObject(raco::user_types::Node::typeDescription.typeName, meshScenegraphNode.name)); + newNode = meshScenegraphNodes.emplace_back(createObject(user_types::Node::typeDescription.typeName, meshScenegraphNode.name)); } else { SEditorObject submeshRootNode; if (meshScenegraphNode.subMeshIndices.size() == 1) { LOG_DEBUG(log_system::CONTEXT, "Found node {} with singular submesh -> creating MeshNode...", meshScenegraphNode.name); - newNode = meshScenegraphNodes.emplace_back(createObject(raco::user_types::MeshNode::typeDescription.typeName, meshScenegraphNode.name)); + newNode = meshScenegraphNodes.emplace_back(createObject(user_types::MeshNode::typeDescription.typeName, meshScenegraphNode.name)); submeshRootNode = newNode; } else { LOG_DEBUG(log_system::CONTEXT, "Found node {} with multiple submeshes -> creating MeshNode for each submesh...", meshScenegraphNode.name); - newNode = meshScenegraphNodes.emplace_back(createObject(raco::user_types::Node::typeDescription.typeName, meshScenegraphNode.name)); - submeshRootNode = createObject(raco::user_types::Node::typeDescription.typeName, meshScenegraphNode.name + "_meshnodes"); + newNode = meshScenegraphNodes.emplace_back(createObject(user_types::Node::typeDescription.typeName, meshScenegraphNode.name)); + submeshRootNode = createObject(user_types::Node::typeDescription.typeName, meshScenegraphNode.name + "_meshnodes"); moveScenegraphChildren({submeshRootNode}, newNode); } @@ -1129,7 +1187,7 @@ void BaseContext::insertAssetScenegraph(const raco::core::MeshScenegraph& sceneg if (meshScenegraphNode.subMeshIndices.size() == 1) { submeshNode = newNode; } else { - submeshNode = createObject(raco::user_types::MeshNode::typeDescription.typeName, meshScenegraphNode.name + "_meshnode_" + std::to_string(submeshIndex)); + submeshNode = createObject(user_types::MeshNode::typeDescription.typeName, meshScenegraphNode.name + "_meshnode_" + std::to_string(submeshIndex)); moveScenegraphChildren({submeshNode}, submeshRootNode); } @@ -1138,7 +1196,7 @@ void BaseContext::insertAssetScenegraph(const raco::core::MeshScenegraph& sceneg continue; } - set(ValueHandle{submeshNode}.get("mesh"), meshScenegraphMeshes[assignedSubmeshIndex]); + set({submeshNode, &user_types::MeshNode::mesh_}, meshScenegraphMeshes[assignedSubmeshIndex]); const auto& glTFMaterial = scenegraph.materials[assignedSubmeshIndex]; if (glTFMaterial.has_value()) { @@ -1148,7 +1206,8 @@ void BaseContext::insertAssetScenegraph(const raco::core::MeshScenegraph& sceneg if (foundMaterial && foundMaterial->isType()) { LOG_DEBUG(log_system::CONTEXT, "Found matching material {} in project resources, will reassign current MeshNode material to it", glTFMaterialName); - set(ValueHandle{submeshNode}.get("materials")[0].get("material"), foundMaterial); + + set(submeshNode->as()->getMaterialHandle(0), foundMaterial); } } } @@ -1160,17 +1219,9 @@ void BaseContext::insertAssetScenegraph(const raco::core::MeshScenegraph& sceneg LOG_DEBUG(log_system::CONTEXT, "All nodes traversed."); LOG_DEBUG(log_system::CONTEXT, "Applying scenegraph node transformations..."); - ValueHandle newNodeHandle{newNode}; - - auto transformNode = [this](auto& valueHandle, auto& propertyName, auto& vec3f) { - set(valueHandle.get(propertyName).get("x"), vec3f[0]); - set(valueHandle.get(propertyName).get("y"), vec3f[1]); - set(valueHandle.get(propertyName).get("z"), vec3f[2]); - }; - - transformNode(newNodeHandle, "scaling", meshScenegraphNode.transformations.scale); - transformNode(newNodeHandle, "rotation", meshScenegraphNode.transformations.rotation); - transformNode(newNodeHandle, "translation", meshScenegraphNode.transformations.translation); + set({newNode, &user_types::Node::scaling_}, meshScenegraphNode.transformations.scale); + set({newNode, &user_types::Node::rotation_}, meshScenegraphNode.transformations.rotation); + set({newNode, &user_types::Node::translation_}, meshScenegraphNode.transformations.translation); LOG_DEBUG(log_system::CONTEXT, "All scenegraph node transformations applied."); } LOG_INFO(log_system::CONTEXT, "All scenegraph nodes imported."); @@ -1184,10 +1235,9 @@ void BaseContext::insertAssetScenegraph(const raco::core::MeshScenegraph& sceneg } LOG_INFO(log_system::CONTEXT, "Scenegraph structure restored."); - LOG_INFO(log_system::CONTEXT, "Importing animation samplers..."); std::map> sceneChannels; - for (auto animIndex = 0; animIndex < scenegraph.animationSamplers.size(); ++animIndex) { + for (auto animIndex = 0; animIndex < scenegraph.animationSamplers.size(); ++animIndex) { auto& samplers = scenegraph.animationSamplers[animIndex]; for (auto samplerIndex = 0; samplerIndex < samplers.size(); ++samplerIndex) { auto& meshAnimSampler = scenegraph.animationSamplers.at(animIndex)[samplerIndex]; @@ -1200,15 +1250,14 @@ void BaseContext::insertAssetScenegraph(const raco::core::MeshScenegraph& sceneg auto samplerWithSameProperties = propertiesToChannelMap.find({absPath, animIndex, samplerIndex}); if (samplerWithSameProperties == propertiesToChannelMap.end()) { LOG_DEBUG(log_system::CONTEXT, "Did not find existing local AnimationChannel with same properties as asset animation sampler, creating one instead..."); - auto& sampler = sceneChannels[animIndex].emplace_back(createObject(raco::user_types::AnimationChannel::typeDescription.typeName, fmt::format("{}", *meshAnimSampler))); - set({sampler, {"uri"}}, relativeFilePath.string()); - set({sampler, {"animationIndex"}}, animIndex); - set({sampler, {"samplerIndex"}}, samplerIndex); + auto& sampler = sceneChannels[animIndex].emplace_back(createObject(user_types::AnimationChannel::typeDescription.typeName, fmt::format("{}", *meshAnimSampler))); + set({sampler, &user_types::AnimationChannel::uri_}, relativeFilePath.string()); + set({sampler, &user_types::AnimationChannel::animationIndex_}, animIndex); + set({sampler, &user_types::AnimationChannel::samplerIndex_}, samplerIndex); } else { LOG_DEBUG(log_system::CONTEXT, "Found existing local AnimationChannel '{}' with same properties as asset animation sampler, using this AnimationChannel...", *meshAnimSampler); sceneChannels[animIndex].emplace_back(samplerWithSameProperties->second); } - } } LOG_INFO(log_system::CONTEXT, "Animation samplers imported."); @@ -1224,8 +1273,8 @@ void BaseContext::insertAssetScenegraph(const raco::core::MeshScenegraph& sceneg auto& meshAnim = *scenegraph.animations[animationIndex]; auto samplerSize = scenegraph.animationSamplers.at(animationIndex).size(); - auto& newAnim = scenegraphAnims.emplace_back(createObject(raco::user_types::Animation::typeDescription.typeName, fmt::format("{}", meshAnim.name))); - newAnim->as()->setChannelAmount(samplerSize); + auto& newAnim = scenegraphAnims.emplace_back(createObject(user_types::Animation::typeDescription.typeName, fmt::format("{}", meshAnim.name))); + newAnim->as()->setChannelAmount(samplerSize); moveScenegraphChildren({newAnim}, sceneRootNode); LOG_INFO(log_system::CONTEXT, "Assigning animation samplers to animation '{}'...", meshAnim.name); for (auto samplerIndex = 0; samplerIndex < samplerSize; ++samplerIndex) { @@ -1233,7 +1282,7 @@ void BaseContext::insertAssetScenegraph(const raco::core::MeshScenegraph& sceneg continue; } - set({newAnim, {"animationChannels", fmt::format("Channel {}", samplerIndex)}}, sceneChannels[animationIndex][samplerIndex]); + set(ValueHandle(newAnim, {"animationChannels"})[samplerIndex], sceneChannels[animationIndex][samplerIndex]); LOG_DEBUG(log_system::CONTEXT, "Assigned sampler to anim channel {}", samplerIndex); } LOG_INFO(log_system::CONTEXT, "Samplers assigned.", meshAnim.name); @@ -1247,16 +1296,16 @@ void BaseContext::insertAssetScenegraph(const raco::core::MeshScenegraph& sceneg continue; } - auto &linkEndNode = meshScenegraphNodes[channel.nodeIndex]; + auto& linkEndNode = meshScenegraphNodes[channel.nodeIndex]; ValueHandle linkEndProp; auto& animTargetProp = channel.targetPath; if (animTargetProp == "translation") { - linkEndProp = {linkEndNode, {"translation"}}; + linkEndProp = {linkEndNode, &user_types::Node::translation_}; } else if (animTargetProp == "rotation") { - linkEndProp = {linkEndNode, {"rotation"}}; + linkEndProp = {linkEndNode, &user_types::Node::rotation_}; } else if (animTargetProp == "scale") { - linkEndProp = {linkEndNode, {"scaling"}}; + linkEndProp = {linkEndNode, &user_types::Node::scaling_}; } else if (animTargetProp == "weights") { LOG_WARNING(log_system::CONTEXT, "Animation sampler of animation '{}' at index {} has animation target 'weights' which is unsupported - skipping link...", meshAnim.name, channelIndex); continue; @@ -1278,39 +1327,37 @@ void BaseContext::insertAssetScenegraph(const raco::core::MeshScenegraph& sceneg } LOG_INFO(log_system::CONTEXT, "Animations imported."); - if (project_->featureLevel() >= user_types::Skin::typeDescription.featureLevel) { - for (auto index = 0; index < scenegraph.skins.size(); index++) { - const auto& sceneSkin = scenegraph.skins[index]; - if (!sceneSkin.has_value()) { - LOG_DEBUG(log_system::CONTEXT, "Found disabled skin at index {}, ignoring...", index); - continue; - } + for (auto index = 0; index < scenegraph.skins.size(); index++) { + const auto& sceneSkin = scenegraph.skins[index]; + if (!sceneSkin.has_value()) { + LOG_DEBUG(log_system::CONTEXT, "Found disabled skin at index {}, ignoring...", index); + continue; + } - std::vector targetMeshNodes; - auto targetMeshNode = meshScenegraphNodes[sceneSkin->meshNodeIndex]; - if (targetMeshNode->isType()) { - targetMeshNodes.emplace_back(targetMeshNode); - } else { - auto submeshRootNode = targetMeshNode->children_->get(0)->asRef()->as(); - for (auto child : submeshRootNode->children_->asVector()) { - if (child->isType()) { - targetMeshNodes.emplace_back(child); - } else { - LOG_ERROR(log_system::CONTEXT, "Target child node is not a MeshNode '{}'", child->objectName()); - } + std::vector targetMeshNodes; + auto targetMeshNode = meshScenegraphNodes[sceneSkin->meshNodeIndex]; + if (targetMeshNode->isType()) { + targetMeshNodes.emplace_back(targetMeshNode); + } else { + auto submeshRootNode = targetMeshNode->children_->get(0)->asRef()->as(); + for (auto child : submeshRootNode->children_->asVector()) { + if (child->isType()) { + targetMeshNodes.emplace_back(child); + } else { + LOG_ERROR(log_system::CONTEXT, "Target child node is not a MeshNode '{}'", child->objectName()); } } - if (!targetMeshNodes.empty()) { - auto skinObj = createObject(user_types::Skin::typeDescription.typeName, sceneSkin->name); - set({skinObj, &user_types::Skin::uri_}, relativeFilePath.string()); - skinObj->as()->setupTargetProperties(targetMeshNodes.size()); - moveScenegraphChildren({skinObj}, sceneRootNode); - for (auto index = 0; index < targetMeshNodes.size(); index++) { - set(ValueHandle(skinObj, &user_types::Skin::targets_)[index], targetMeshNodes[index]); - } - for (auto jointIndex = 0; jointIndex < sceneSkin->jointNodeIndices.size(); jointIndex++) { - set(ValueHandle(skinObj, &user_types::Skin::joints_)[jointIndex], meshScenegraphNodes[sceneSkin->jointNodeIndices[jointIndex]]); - } + } + if (!targetMeshNodes.empty()) { + auto skinObj = createObject(user_types::Skin::typeDescription.typeName, sceneSkin->name); + set({skinObj, &user_types::Skin::uri_}, relativeFilePath.string()); + skinObj->as()->setupTargetProperties(targetMeshNodes.size()); + moveScenegraphChildren({skinObj}, sceneRootNode); + for (auto index = 0; index < targetMeshNodes.size(); index++) { + set(ValueHandle(skinObj, &user_types::Skin::targets_)[index], targetMeshNodes[index]); + } + for (auto jointIndex = 0; jointIndex < sceneSkin->jointNodeIndices.size(); jointIndex++) { + set(ValueHandle(skinObj, &user_types::Skin::joints_)[jointIndex], meshScenegraphNodes[sceneSkin->jointNodeIndices[jointIndex]]); } } } @@ -1343,8 +1390,8 @@ void BaseContext::removeLink(const PropertyDescriptor& end) { } } -void BaseContext::updateExternalReferences(LoadContext& loadContext) { - ExtrefOperations::updateExternalObjects(*this, project(), *externalProjectsStore(), loadContext); +void BaseContext::updateExternalReferences(LoadContext& loadContext, int fileVersion) { + ExtrefOperations::updateExternalObjects(*this, project(), *externalProjectsStore(), loadContext, fileVersion); PrefabOperations::globalPrefabUpdate(*this, true); } diff --git a/datamodel/libCore/src/Errors.cpp b/datamodel/libCore/src/Errors.cpp index c08781ee..3c09104b 100644 --- a/datamodel/libCore/src/Errors.cpp +++ b/datamodel/libCore/src/Errors.cpp @@ -14,8 +14,11 @@ namespace raco::core { Errors::Errors(DataChangeRecorder* recorder) noexcept : recorder_{ recorder } {} void Errors::addError(ErrorCategory category, ErrorLevel level, const ValueHandle& handle, const std::string& message) { - errors_[handle.rootObject()][handle] = ErrorItem{category, level, handle, message}; - recorder_->recordErrorChanged(handle); + ErrorItem newError{category, level, handle, message}; + if (!hasError(handle) || !(newError == getError(handle))) { + errors_[handle.rootObject()][handle] = newError; + recorder_->recordErrorChanged(handle); + } } std::string Errors::formatError(const ErrorItem& error) { diff --git a/datamodel/libCore/src/ExtrefOperations.cpp b/datamodel/libCore/src/ExtrefOperations.cpp index a56bd4f9..5b23c40f 100644 --- a/datamodel/libCore/src/ExtrefOperations.cpp +++ b/datamodel/libCore/src/ExtrefOperations.cpp @@ -163,7 +163,7 @@ void ExtrefOperations::precheckExternalReferenceUpdate(Project* project, Externa project->replaceExternalProjectsMappings(extProjectMapCopy); } -void ExtrefOperations::updateExternalObjects(BaseContext& context, Project* project, ExternalProjectsStoreInterface& externalProjectsStore, LoadContext& loadContext) { +void ExtrefOperations::updateExternalObjects(BaseContext& context, Project* project, ExternalProjectsStoreInterface& externalProjectsStore, LoadContext& loadContext, int fileVersion) { // remove project-global errors context.errors().removeError(ValueHandle()); @@ -267,6 +267,59 @@ void ExtrefOperations::updateExternalObjects(BaseContext& context, Project* proj } } + // !!! TODO: remove code below as soon as possible!!! + // + // This code is needed as long as the migration to V56 code is still present. + // We can only remove this once we removed backwards compatibility with files RenderTarget & RenderTargetMS) + // + // Due to the save file optimization an external RenderBuffer may be removed from the saved file although it is + // used in an external RenderTarget. The render buffer references in the RenderTarget will then be absent from the file. + // In principle the external reference update will be able to restore this. + // + // However: the migration code to V56 will create either a RenderTarget or a RenderTargetMS based on the + // render buffers set in the object. If RenderBuffers have been removed from the save file by the optimiation + // the type chosen by the migration may be different than the type the migration will chose if the external project + // is loaded directly. The external reference update will then run into a type mismatch when attempting to restore + // the buffer properties of the RenderTarget which are of the wrong type (normal vs MS). + // The migration code can't make the right decision since the information needed is not present in the file. + // + // Therefore we need the fixup code below which will replace the mismatching RenderTarget/RenderTargetMS with the + // correct type and adjust all the existing references to point to the new object. + // + if (fileVersion != -1 && fileVersion < 56) { + for (auto item : externalObjects) { + auto extObj = item.second.obj; + auto localObj = translateToLocal(extObj); + + auto extType = extObj->serializationTypeName(); + auto localType = localObj->serializationTypeName(); + if ((extType == "RenderTarget" || extType == "RenderTargetMS") && + (localType == "RenderTarget" || localType == "RenderTargetMS") && + localType != extType) { + // Create new object with correct type and make it an external reference: + auto newLocalObj = context.objectFactory()->createObject(extType, extObj->objectName(), extObj->objectID()); + newLocalObj->addAnnotation(std::make_shared(item.second.project->projectID())); + + // Replace all references to the old object by the new object: + auto references = Queries::findAllReferencesTo(*context.project(), {localObj}); + for (const auto& refHandle : references) { + context.set(refHandle, newLocalObj); + } + + context.deleteObjects({localObj}, false, false); + + context.project()->addInstance(newLocalObj); + localChanges.recordCreateObject(newLocalObj); + // this will replace the existing entry in the map: + localObjects[newLocalObj->objectID()] = newLocalObj; + } + } + } + // !!! TODO: remove code until here !!! + + // Update properties for (auto item : externalObjects) { auto extObj = item.second.obj; diff --git a/datamodel/libCore/src/Handles.cpp b/datamodel/libCore/src/Handles.cpp index 3ef50e59..6fd65d58 100644 --- a/datamodel/libCore/src/Handles.cpp +++ b/datamodel/libCore/src/Handles.cpp @@ -12,6 +12,10 @@ #include "core/Iterators.h" #include "core/PropertyDescriptor.h" +#include +#include +#include + namespace raco::core { ValueHandle::ValueHandle(std::shared_ptr object, std::initializer_list names) : ValueHandle(object, std::vector(names)) {} @@ -49,7 +53,8 @@ ValueHandle ValueHandle::translatedHandle(const ValueHandle& handle, std::functi } PropertyDescriptor ValueHandle::getDescriptor() const { - return PropertyDescriptor(object_, getPropertyNamesVector()); + auto propNames = getPropertyNamesVector(); + return PropertyDescriptor(object_, {propNames.begin(), propNames.end()}); } @@ -167,6 +172,60 @@ bool ValueHandle::isVec4i() const { return isStruct(); } +template<> +glm::vec2 ValueHandle::as() const { + if (isVec2f()) { + const auto& vec = asVec2f(); + return {static_cast(*vec.x), static_cast(*vec.y)}; + } + return {}; +} + +template <> +glm::vec3 ValueHandle::as() const { + if (isVec3f()) { + const auto& vec = asVec3f(); + return {static_cast(*vec.x), static_cast(*vec.y), static_cast(*vec.z)}; + } + return {}; +} + +template <> +glm::vec4 ValueHandle::as() const { + if (isVec4f()) { + const auto& vec = asVec4f(); + return {static_cast(*vec.x), static_cast(*vec.y), static_cast(*vec.z), static_cast(*vec.w)}; + } + return {}; +} + +template <> +glm::ivec2 ValueHandle::as() const { + if (isVec2i()) { + const auto& vec = asVec2i(); + return {*vec.i1_, *vec.i2_}; + } + return {}; +} + +template <> +glm::ivec3 ValueHandle::as() const { + if (isVec3i()) { + const auto& vec = asVec3i(); + return {*vec.i1_, *vec.i2_, *vec.i3_}; + } + return {}; +} + +template <> +glm::ivec4 ValueHandle::as() const { + if (isVec4i()) { + const auto& vec = asVec4i(); + return {*vec.i1_, *vec.i2_, *vec.i3_, *vec.i4_}; + } + return {}; +} + size_t ValueHandle::size() const { if (indices_.empty()) { return object_->size(); @@ -188,7 +247,7 @@ ValueHandle ValueHandle::operator[](size_t index) const { return v; } -bool ValueHandle::hasProperty(std::string name) const { +bool ValueHandle::hasProperty(std::string_view name) const { if (indices_.empty()) { return object_->hasProperty(name); } @@ -199,7 +258,7 @@ bool ValueHandle::hasProperty(std::string name) const { return false; } -ValueHandle ValueHandle::get(std::string propertyName) const { +ValueHandle ValueHandle::get(std::string_view propertyName) const { ValueHandle v(object_, indices_); size_t index = object()->index(propertyName); v.indices_.emplace_back(index); @@ -220,9 +279,9 @@ std::string ValueHandle::getPropName() const { throw std::runtime_error("invalid property"); } -std::vector ValueHandle::getPropertyNamesVector() const { +std::vector ValueHandle::getPropertyNamesVector() const { if (!indices_.empty()) { - std::vector result; + std::vector result; ReflectionInterface* o = object_.get(); for (int i = 0; i < indices_.size() - 1; i++) { result.emplace_back(o->name(indices_[i])); @@ -313,8 +372,9 @@ ValueBase* ValueHandle::valueRef() const { } o = &v->getSubstructure(); } - v = (*o)[index]; - if (!v) { + if (index < o->size()) { + v = (*o)[index]; + } else { return nullptr; } } diff --git a/datamodel/libCore/src/PathManager.cpp b/datamodel/libCore/src/PathManager.cpp index 49ef5666..7e20d080 100644 --- a/datamodel/libCore/src/PathManager.cpp +++ b/datamodel/libCore/src/PathManager.cpp @@ -25,17 +25,24 @@ namespace raco::core { -using u8path = raco::utils::u8path; +using u8path = utils::u8path; u8path PathManager::basePath_; u8path PathManager::appDataBasePath_; u8path PathManager::executableDirectory_; +u8path PathManager::defaultResourceDirectory_; void PathManager::init(const u8path& executableDirectory, const u8path& appDataDirectory) { executableDirectory_ = executableDirectory.normalized(); basePath_ = executableDirectory.normalized().parent_path().parent_path(); appDataBasePath_ = appDataDirectory.normalized(); migrateLegacyConfigDirectory(); + + defaultResourceDirectory_ = basePath_ / DEFAULT_PROJECT_SUB_DIRECTORY; +} + +void PathManager::setDefaultResourceDirectory(const u8path& resourceDirectory) { + defaultResourceDirectory_ = resourceDirectory; } u8path PathManager::executableDirectory() { @@ -55,7 +62,7 @@ u8path PathManager::legacyConfigDirectory() { } u8path PathManager::defaultResourceDirectory() { - return defaultBaseDirectory() / DEFAULT_PROJECT_SUB_DIRECTORY; + return defaultResourceDirectory_; } u8path PathManager::logFileDirectory() { @@ -105,15 +112,15 @@ u8path PathManager::defaultProjectFallbackPath() { } QSettings PathManager::layoutSettings() { - return QSettings(raco::core::PathManager::layoutFilePath().string().c_str(), QSettings::IniFormat); + return QSettings(core::PathManager::layoutFilePath().string().c_str(), QSettings::IniFormat); } QSettings PathManager::recentFilesStoreSettings() { - return QSettings(raco::core::PathManager::recentFilesStorePath().string().c_str(), QSettings::IniFormat); + return QSettings(core::PathManager::recentFilesStorePath().string().c_str(), QSettings::IniFormat); } QSettings PathManager::preferenceSettings() { - return QSettings(raco::core::PathManager::preferenceFilePath().string().c_str(), QSettings::IniFormat); + return QSettings(core::PathManager::preferenceFilePath().string().c_str(), QSettings::IniFormat); } const u8path& PathManager::getCachedPath(FolderTypeKeys key, const u8path& fallbackPath) { diff --git a/datamodel/libCore/src/PathQueries.cpp b/datamodel/libCore/src/PathQueries.cpp index 56371a44..9cbff59d 100644 --- a/datamodel/libCore/src/PathQueries.cpp +++ b/datamodel/libCore/src/PathQueries.cpp @@ -20,12 +20,12 @@ namespace raco::core::PathQueries { std::string effectiveExternalProjectID(const Project &project, SEditorObject object) { if (auto prefabInst = PrefabOperations::findContainingPrefabInstance(object)) { if (auto prefab = *prefabInst->template_) { - if (auto anno = prefab->query()) { + if (auto anno = prefab->query()) { return *anno->projectID_; } } } else { - if (auto anno = object->query()) { + if (auto anno = object->query()) { return *anno->projectID_; } } @@ -37,7 +37,7 @@ std::string baseFolderForRelativePath(const Project& project, SEditorObject obje if (!externalProjectID.empty()) { if (project.hasExternalProjectMapping(externalProjectID)) { auto projectPath = project.lookupExternalProjectPath(externalProjectID); - return raco::utils::u8path(projectPath).parent_path().string(); + return utils::u8path(projectPath).parent_path().string(); } return std::string(); } @@ -53,22 +53,22 @@ std::string resolveUriPropertyToAbsolutePath(const Project& project, const Value if (!externalProjectID.empty()) { if (project.hasExternalProjectMapping(externalProjectID)) { auto projectPath = project.lookupExternalProjectPath(externalProjectID); - auto projectFolder = raco::utils::u8path(projectPath).parent_path().string(); - return raco::utils::u8path(uriValue).normalizedAbsolutePath(projectFolder).string(); + auto projectFolder = utils::u8path(projectPath).parent_path().string(); + return utils::u8path(uriValue).normalizedAbsolutePath(projectFolder).string(); } return std::string(); } - return raco::utils::u8path(uriValue).normalizedAbsolutePath(project.currentFolder()).string(); + return utils::u8path(uriValue).normalizedAbsolutePath(project.currentFolder()).string(); } bool isPathRelativeToCurrentProject(const SEditorObject& object) { if (auto prefabInst = PrefabOperations::findContainingPrefabInstance(object)) { if (auto prefab = *prefabInst->template_) { - return prefab->query() == nullptr; + return prefab->query() == nullptr; } } return !object->query(); } -} // namespace raco::core::PathQueries +} // namespace core::PathQueries diff --git a/datamodel/libCore/src/PrefabOperations.cpp b/datamodel/libCore/src/PrefabOperations.cpp index 36dfba55..3503b648 100644 --- a/datamodel/libCore/src/PrefabOperations.cpp +++ b/datamodel/libCore/src/PrefabOperations.cpp @@ -99,8 +99,8 @@ SLink lookupLink(SLink srcLink, const std::map>& de for (const auto& destLink : it->second) { if (transStartObj == *destLink->startObject_ && transEndObj == *destLink->endObject_ && - *srcLink->startProp_ == *destLink->startProp_ && - *srcLink->endProp_ == *destLink->endProp_) { + srcLink->startProp_->compare(*destLink->startProp_) && + srcLink->endProp_->compare(*destLink->endProp_)) { return destLink; } } @@ -223,7 +223,8 @@ void PrefabOperations::updatePrefabInstance(BaseContext& context, const SPrefab& } // Create new prefab instance child objects for children of prefab - std::vector> createdObjects; + std::map createdObjects; + for (auto prefabChild : prefabChildren) { auto it = mapToInstance.find(prefabChild); if (it == mapToInstance.end()) { @@ -233,7 +234,7 @@ void PrefabOperations::updatePrefabInstance(BaseContext& context, const SPrefab& mapToPrefab[newInstChild] = prefabChild; context.project()->addInstance(newInstChild); localChanges.recordCreateObject(newInstChild); - createdObjects.emplace_back(prefabChild, newInstChild); + createdObjects[prefabChild] = newInstChild; // If we add an object we must also update the children property of the scenegraph parent // Normally this property should already be present in the model changes, but @@ -245,7 +246,9 @@ void PrefabOperations::updatePrefabInstance(BaseContext& context, const SPrefab& } // Complete update of the the newly created objects - for (auto [prefabChild, instChild] : createdObjects) { + for (const auto& item: createdObjects) { + auto prefabChild = item.first; + auto instChild = item.second; // Object IDs are never updated and the object name for newly created objects is already correct. UndoHelpers::updateEditorObject( prefabChild.get(), instChild, translateRefFunc, @@ -287,9 +290,7 @@ void PrefabOperations::updatePrefabInstance(BaseContext& context, const SPrefab& } for (const auto& prop : allChangedValues) { if (prop.rootObject() != prefab && prefabChildren.find(prop.rootObject()) != prefabChildren.end()) { - if (std::find_if(createdObjects.begin(), createdObjects.end(), [prop](auto item) { - return prop.rootObject() == item.first; - }) == createdObjects.end()) { + if (createdObjects.find(prop.rootObject()) == createdObjects.end()) { auto it = mapToInstance.find(prop.rootObject()); assert(it != mapToInstance.end()); auto inst = it->second; diff --git a/datamodel/libCore/src/Project.cpp b/datamodel/libCore/src/Project.cpp index b6544936..451c5a32 100644 --- a/datamodel/libCore/src/Project.cpp +++ b/datamodel/libCore/src/Project.cpp @@ -120,7 +120,7 @@ std::string Project::currentFolder() const { } std::string Project::currentPath() const { - return (raco::utils::u8path(currentFolder()) / currentFileName()).string(); + return (utils::u8path(currentFolder()) / currentFileName()).string(); } std::string Project::currentFileName() const { @@ -256,7 +256,7 @@ void Project::addExternalProjectMapping(const std::string& projectID, const std: throw ExtrefError("External reference project loop detected (based on same project path)."); } - auto relPath = raco::utils::u8path(absPath).normalizedRelativePath(currentFolder()).string(); + auto relPath = utils::u8path(absPath).normalizedRelativePath(currentFolder()).string(); auto it = externalProjectsMap_.find(projectID); if (it != externalProjectsMap_.end()) { @@ -303,7 +303,7 @@ bool Project::hasExternalProjectMapping(const std::string& projectID) const { std::string Project::lookupExternalProjectPath(const std::string& projectID) const { auto it = externalProjectsMap_.find(projectID); if (it != externalProjectsMap_.end()) { - return raco::utils::u8path(it->second.path).normalizedAbsolutePath(currentFolder()).string(); + return utils::u8path(it->second.path).normalizedAbsolutePath(currentFolder()).string(); } return std::string(); } @@ -318,13 +318,13 @@ std::string Project::lookupExternalProjectName(const std::string& projectID) con void Project::rerootExternalProjectPaths(const std::string oldFolder, const std::string newFolder) { for (auto& item : externalProjectsMap_) { - item.second.path = raco::utils::u8path(item.second.path).rerootRelativePath(oldFolder, newFolder).string(); + item.second.path = utils::u8path(item.second.path).rerootRelativePath(oldFolder, newFolder).string(); } } bool Project::usesExternalProjectByPath(const std::string& absPath) const { for (auto item : externalProjectsMap_) { - if (raco::utils::u8path(item.second.path).normalizedAbsolutePath(currentFolder()) == absPath) { + if (utils::u8path(item.second.path).normalizedAbsolutePath(currentFolder()) == absPath) { return true; } } diff --git a/datamodel/libCore/src/ProjectMigration.cpp b/datamodel/libCore/src/ProjectMigration.cpp index 19b00125..2cdf1f73 100644 --- a/datamodel/libCore/src/ProjectMigration.cpp +++ b/datamodel/libCore/src/ProjectMigration.cpp @@ -17,6 +17,7 @@ #include "core/Link.h" #include "core/ProxyObjectFactory.h" #include "core/ProxyTypes.h" +#include "data_storage/Array.h" #include "log_system/log.h" @@ -31,14 +32,14 @@ namespace raco::serialization { -void linkReplaceEndIfMatching(raco::core::SLink& link, const std::string& oldProp, const std::vector& newEndProp) { +void linkReplaceEndIfMatching(core::SLink& link, const std::string& oldProp, const std::vector& newEndProp) { if (link->compareEndPropertyNames({oldProp})) { - link->endProp_->set(newEndProp); + link->endProp_->set(newEndProp); } }; template -raco::data_storage::ValueBase* createDynamicProperty_V11(raco::core::EnginePrimitive type) { +data_storage::ValueBase* createDynamicProperty_V11(core::EnginePrimitive type) { using namespace raco::serialization::proxy; using namespace raco::data_storage; using namespace raco::core; @@ -96,7 +97,7 @@ raco::data_storage::ValueBase* createDynamicProperty_V11(raco::core::EnginePrimi } template -raco::data_storage::ValueBase* createDynamicProperty_V36(raco::core::EnginePrimitive type) { +data_storage::ValueBase* createDynamicProperty_V36(core::EnginePrimitive type) { using namespace raco::serialization::proxy; using namespace raco::data_storage; using namespace raco::core; @@ -157,7 +158,7 @@ raco::data_storage::ValueBase* createDynamicProperty_V36(raco::core::EnginePrimi } template -raco::data_storage::ValueBase* createDynamicProperty_V51(core::EnginePrimitive type) { +data_storage::ValueBase* createDynamicProperty_V51(core::EnginePrimitive type) { using namespace raco::serialization::proxy; using namespace raco::data_storage; using namespace raco::core; @@ -224,9 +225,9 @@ raco::data_storage::ValueBase* createDynamicProperty_V51(core::EnginePrimitive t return nullptr; } -raco::data_storage::Table* findItemByValue(raco::data_storage::Table& table, raco::core::SEditorObject obj) { +data_storage::Table* findItemByValue(data_storage::Table& table, core::SEditorObject obj) { for (size_t i{0}; i < table.size(); i++) { - raco::data_storage::Table& item = table.get(i)->asTable(); + data_storage::Table& item = table.get(i)->asTable(); if (item.get(1)->asRef() == obj) { return &item; } @@ -234,10 +235,10 @@ raco::data_storage::Table* findItemByValue(raco::data_storage::Table& table, rac return nullptr; } -void insertPrefabInstancesRecursive(raco::serialization::proxy::SEditorObject inst, std::vector& sortedInstances) { +void insertPrefabInstancesRecursive(serialization::proxy::SEditorObject inst, std::vector& sortedInstances) { if (std::find(sortedInstances.begin(), sortedInstances.end(), inst) == sortedInstances.end()) { if (auto prefab = inst->get("template")->asRef()) { - for (auto prefabChild : raco::core::TreeIteratorAdaptor(prefab)) { + for (auto prefabChild : core::TreeIteratorAdaptor(prefab)) { if (prefabChild->serializationTypeName() == "PrefabInstance") { insertPrefabInstancesRecursive(prefabChild, sortedInstances); } @@ -316,7 +317,7 @@ std::string generateInterfaceTable(const data_storage::Table& table, int depth, return result; } -std::string generateInterfaceScript(raco::serialization::proxy::SEditorObject object) { +std::string generateInterfaceScript(serialization::proxy::SEditorObject object) { return fmt::format(R"___(function interface(INOUT) {} end @@ -327,10 +328,10 @@ end void createInterfaceProperties(const data_storage::Table& scriptTable, data_storage::Table& interfaceTable) { for (size_t i = 0; i < scriptTable.size(); i++) { auto anno = scriptTable.get(i)->query(); - if (raco::core::PropertyInterface::primitiveType(anno->type()) == PrimitiveType::Ref) { + if (core::PropertyInterface::primitiveType(anno->type()) == PrimitiveType::Ref) { interfaceTable.addProperty(scriptTable.name(i), createDynamicProperty_V36<>(anno->type()), -1); } else { - interfaceTable.addProperty(scriptTable.name(i), createDynamicProperty_V36(anno->type()), -1); + interfaceTable.addProperty(scriptTable.name(i), createDynamicProperty_V36(anno->type()), -1); } if (scriptTable.get(i)->type() == PrimitiveType::Table) { @@ -341,14 +342,14 @@ void createInterfaceProperties(const data_storage::Table& scriptTable, data_stor } } -raco::serialization::proxy::SDynamicEditorObject createInterfaceObjectV36(raco::serialization::proxy::ProxyObjectFactory& factory, raco::serialization::ProjectDeserializationInfoIR& deserializedIR, std::vector& createdLinks, raco::serialization::proxy::SDynamicEditorObject& script, std::string& interfaceObjID, const raco::utils::u8path& intfRelPath, const raco::core::SEditorObject& parentObj) { +serialization::proxy::SDynamicEditorObject createInterfaceObjectV36(serialization::proxy::ProxyObjectFactory& factory, serialization::ProjectDeserializationInfoIR& deserializedIR, std::vector& createdLinks, serialization::proxy::SDynamicEditorObject& script, std::string& interfaceObjID, const utils::u8path& intfRelPath, const core::SEditorObject& parentObj) { using namespace raco::serialization::proxy; auto interfaceObj = std::dynamic_pointer_cast(factory.createObject("LuaInterface", script->objectName(), interfaceObjID)); interfaceObj->addProperty("uri", new Property{intfRelPath.string(), {"Lua interface files(*.lua)"}, DisplayNameAnnotation("URI")}, -1); - if (auto anno = script->query()) { - interfaceObj->addAnnotation(std::make_shared(*anno->projectID_)); + if (auto anno = script->query()) { + interfaceObj->addAnnotation(std::make_shared(*anno->projectID_)); } auto newIntfInputs = interfaceObj->addProperty("luaInputs", new Property{{}, DisplayNameAnnotation("Inputs"), {}, {}}, -1); @@ -356,12 +357,12 @@ raco::serialization::proxy::SDynamicEditorObject createInterfaceObjectV36(raco:: deserializedIR.objects.emplace_back(interfaceObj); - auto prop = parentObj->children_->addProperty(PrimitiveType::Ref, -1); + auto prop = parentObj->children_->addProperty(-1); *prop = interfaceObj; - createdLinks.emplace_back(std::make_shared( - raco::core::PropertyDescriptor(interfaceObj, {"luaInputs"}), - raco::core::PropertyDescriptor(script, {"luaInputs"}), + createdLinks.emplace_back(std::make_shared( + core::PropertyDescriptor(interfaceObj, {"luaInputs"}), + core::PropertyDescriptor(script, {"luaInputs"}), true)); { @@ -384,7 +385,7 @@ raco::serialization::proxy::SDynamicEditorObject createInterfaceObjectV36(raco:: return interfaceObj; } -void splitUniformName(std::string uniformName, raco::core::EnginePrimitive componentType, +void splitUniformName(std::string uniformName, core::EnginePrimitive componentType, std::vector& names, std::vector& types) { auto dotPos = uniformName.find('.'); @@ -443,7 +444,7 @@ void replaceUniforms_V51(core::Table& uniforms) { for (int depth = 0; depth < names.size(); depth++) { core::ValueBase* newProp; if (!container->hasProperty(names[depth])) { - newProp = container->addProperty(names[depth], createDynamicProperty_V51(types[depth]), -1); + newProp = container->addProperty(names[depth], createDynamicProperty_V51(types[depth]), -1); } else { newProp = container->get(names[depth]); } @@ -462,6 +463,22 @@ void replaceUniforms_V51(core::Table& uniforms) { } } +/** + * @brief Recreate the EditorObject::parent_ and referencesToThis_ pointers in all objects + * + * Use this after changing the pointer structure of the deserialized objects, i.e. when + * changing any reference properties. + */ +void recreateBackPointers(serialization::ProjectDeserializationInfoIR& deserializedIR) { + for (const auto& obj : deserializedIR.objects) { + obj->resetBackPointers(); + } + for (const auto& obj : deserializedIR.objects) { + obj->onAfterDeserialization(); + } +} + + // Limitations // - Annotations and links are handled as static classes: // we can't change the class definition in a way that prevents deserialization of the old annotation: this means that @@ -471,13 +488,13 @@ void replaceUniforms_V51(core::Table& uniforms) { // - If the need arises to migrate the annotationns we would need to create proxy types for them in the same // way currently done for the Struct PrimitiveTypes. -void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serialization::proxy::ProxyObjectFactory& factory) { +void migrateProject(ProjectDeserializationInfoIR& deserializedIR, serialization::proxy::ProxyObjectFactory& factory) { using namespace raco::data_storage; using namespace raco::serialization::proxy; if (deserializedIR.fileVersion < 2) { auto settingsID = QUuid::createUuid().toString(QUuid::WithoutBraces).toStdString(); - auto settings = std::make_shared("", settingsID); + auto settings = std::make_shared("", settingsID); deserializedIR.objects.emplace_back(settings); } @@ -531,9 +548,9 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ auto* uniforms = &dynObj->get("uniforms")->asTable(); for (size_t i = 0; i < uniforms->size(); i++) { - auto engineType = uniforms->get(i)->query()->type(); - if (raco::core::PropertyInterface::primitiveType(engineType) != PrimitiveType::Ref) { - auto newValue = createDynamicProperty_V11(engineType); + auto engineType = uniforms->get(i)->query()->type(); + if (core::PropertyInterface::primitiveType(engineType) != PrimitiveType::Ref) { + auto newValue = createDynamicProperty_V11(engineType); *newValue = *uniforms->get(i); uniforms->replaceProperty(i, newValue); } @@ -548,7 +565,7 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ auto instanceType = dynObj->serializationTypeName(); if (instanceType == "PerspectiveCamera" || instanceType == "OrthographicCamera") { - auto viewport = new Property{{}, {"Viewport"}, {}}; + auto viewport = new Property{{}, {"Viewport"}, {}}; (*viewport)->addProperty("offsetX", dynObj->extractProperty("viewPortOffsetX"), -1); (*viewport)->addProperty("offsetY", dynObj->extractProperty("viewPortOffsetY"), -1); (*viewport)->addProperty("width", dynObj->extractProperty("viewPortWidth"), -1); @@ -557,7 +574,7 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ } if (instanceType == "PerspectiveCamera") { - auto frustum = new Property{{}, {"Frustum"}, {}}; + auto frustum = new Property{{}, {"Frustum"}, {}}; (*frustum)->addProperty("nearPlane", dynObj->extractProperty("near"), -1); (*frustum)->addProperty("farPlane", dynObj->extractProperty("far"), -1); (*frustum)->addProperty("fieldOfView", dynObj->extractProperty("fov"), -1); @@ -566,7 +583,7 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ } if (instanceType == "OrthographicCamera") { - auto frustum = new Property{{}, {"Frustum"}, {}}; + auto frustum = new Property{{}, {"Frustum"}, {}}; (*frustum)->addProperty("nearPlane", dynObj->extractProperty("near"), -1); (*frustum)->addProperty("farPlane", dynObj->extractProperty("far"), -1); (*frustum)->addProperty("leftPlane", dynObj->extractProperty("left"), -1); @@ -577,7 +594,7 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ } if (instanceType == "Material") { - auto options = new Property{{}, {"Options"}}; + auto options = new Property{{}, {"Options"}}; (*options)->addProperty("blendOperationColor", dynObj->extractProperty("blendOperationColor"), -1); (*options)->addProperty("blendOperationAlpha", dynObj->extractProperty("blendOperationAlpha"), -1); (*options)->addProperty("blendFactorSrcColor", dynObj->extractProperty("blendFactorSrcColor"), -1); @@ -598,7 +615,7 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ Table& matCont = materials.get(i)->asTable(); Table& optionsCont = matCont.get("options")->asTable(); - auto options = new Property{{}, {"Options"}}; + auto options = new Property{{}, {"Options"}}; (*options)->addProperty("blendOperationColor", optionsCont.get("blendOperationColor")->clone({}), -1); (*options)->addProperty("blendOperationAlpha", optionsCont.get("blendOperationAlpha")->clone({}), -1); (*options)->addProperty("blendFactorSrcColor", optionsCont.get("blendFactorSrcColor")->clone({}), -1); @@ -662,9 +679,9 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ auto migrateUniforms = [](Table& uniforms) { for (size_t i = 0; i < uniforms.size(); i++) { - auto engineType = uniforms.get(i)->query()->type(); - if (engineType == raco::core::EnginePrimitive::TextureSampler2D) { - auto newValue = ProxyObjectFactory::staticCreateProperty({}, {engineType}); + auto engineType = uniforms.get(i)->query()->type(); + if (engineType == core::EnginePrimitive::TextureSampler2D) { + auto newValue = ProxyObjectFactory::staticCreateProperty({}, {engineType}); *newValue = uniforms.get(i)->asRef(); uniforms.replaceProperty(i, newValue); } @@ -711,7 +728,7 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ if (instanceType == "Node" || instanceType == "MeshNode" || instanceType == "PrefabInstance") { if (!dynObj->getParent()) { - auto tags = new Property{{}, {}, {}, {"Tags"}}; + auto tags = new Property{{}, {}, {}, {"Tags"}}; tags->set(std::vector({"render_main"})); dynObj->addProperty("tags", tags, -1); } @@ -721,16 +738,16 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ SDynamicEditorObject camera = perspCamera ? perspCamera : orthoCamera; auto layerID = QUuid::createUuid().toString(QUuid::WithoutBraces).toStdString(); - auto mainLayer = std::make_shared("MainRenderLayer", layerID); - auto renderableTagsProp = new Property{{}, {}, {"Renderable Tags"}}; + auto mainLayer = std::make_shared("MainRenderLayer", layerID); + auto renderableTagsProp = new Property{{}, {}, {"Renderable Tags"}}; (*renderableTagsProp)->addProperty("render_main", std::make_unique>(0)); mainLayer->addProperty("renderableTags", renderableTagsProp, -1); - mainLayer->addProperty("sortOrder", new Property{2, {"Render Order"}, raco::core::EUserTypeEnumerations::RenderLayerOrder}, -1); + mainLayer->addProperty("sortOrder", new Property{2, {"Render Order"}, core::EUserTypeEnumerations::RenderLayerOrder}, -1); auto passID = QUuid::createUuid().toString(QUuid::WithoutBraces).toStdString(); - auto mainPass = std::make_shared("MainRenderPass", passID); + auto mainPass = std::make_shared("MainRenderPass", passID); - ValueBase* cameraProp = new Property{{}, {"Camera"}}; + ValueBase* cameraProp = new Property{{}, {"Camera"}}; if (camera) { *cameraProp = camera; } @@ -864,8 +881,8 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ // The old resource folder settings from the RaCoPreferences are transferred into the ProjectSettings // We do not have access to the RaCoPreferences class here, however, we can just parse the ini file directly instead. const std::string projectSubdirectoryFilter = "projectSubDir"; - auto settings = raco::core::PathManager::preferenceSettings(); - auto resourceFolders = new Property{{}, {"Default Resource Folders"}}; + auto settings = core::PathManager::preferenceSettings(); + auto resourceFolders = new Property{{}, {"Default Resource Folders"}}; (*resourceFolders)->addProperty("imageSubdirectory", new Property{settings.value("imageSubdirectory", "images").toString().toStdString(), {"Images"}, {projectSubdirectoryFilter}}, -1); (*resourceFolders)->addProperty("meshSubdirectory", new Property{settings.value("meshSubdirectory", "meshes").toString().toStdString(), {"Meshes"}, {projectSubdirectoryFilter}}, -1); (*resourceFolders)->addProperty("scriptSubdirectory", new Property{settings.value("scriptSubdirectory", "scripts").toString().toStdString(), {"Scripts"}, {projectSubdirectoryFilter}}, -1); @@ -898,9 +915,9 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ if (auto prefabInst = findContainingPrefabInstance(dynObj)) { if (auto prefab = prefabInst->get("template")->asRef()) { - if (prefab->query()) { + if (prefab->query()) { for (size_t propIndex = 0; propIndex < dynObj->size(); propIndex++) { - if (dynObj->get(propIndex)->query()) { + if (dynObj->get(propIndex)->query()) { const auto& propName = dynObj->name(propIndex); SEditorObject prefabObj = dynObj; @@ -916,7 +933,7 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ auto& prefabInstPropValue = dynObj->get(propIndex)->asString(); const auto& prefabPropValue = prefabObj->get(propName)->asString(); if (prefabInstPropValue != prefabPropValue) { - LOG_WARNING(raco::log_system::DESERIALIZATION, "Rewrite URI property '{}.{}': '{}' -> '{}' in project '{}'", + LOG_WARNING(log_system::DESERIALIZATION, "Rewrite URI property '{}.{}': '{}' -> '{}' in project '{}'", dynObj->objectName(), propName, prefabInstPropValue, prefabPropValue, deserializedIR.currentPath); @@ -943,7 +960,10 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ } for (auto instance : sortedInstances) { - const Table& instMapTable = instance->get("mapToInstance")->asTable(); + auto dynInst = std::dynamic_pointer_cast(instance); + + auto oldProp = dynInst->extractProperty("mapToInstance"); + const Table& instMapTable = oldProp->asTable(); for (size_t index = 0; index < instMapTable.size(); index++) { const Table& item = instMapTable.get(index)->asTable(); @@ -952,9 +972,6 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ auto instChildID = EditorObject::XorObjectIDs(prefabChild->objectID(), instance->objectID()); instChild->objectID_ = instChildID; } - - auto dynInst = std::dynamic_pointer_cast(instance); - dynInst->removeProperty("mapToInstance"); } } @@ -1019,7 +1036,7 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ auto oldProp = dynObj->extractProperty("invertMaterialFilter"); // 1 -> Exclusive, 0 -> Inclusive int newValue = oldProp->asBool() ? 1 : 0; - auto newProp = new Property{newValue, {"Material Filter Mode"}, raco::core::EUserTypeEnumerations::RenderLayerMaterialFilterMode}; + auto newProp = new Property{newValue, {"Material Filter Mode"}, core::EUserTypeEnumerations::RenderLayerMaterialFilterMode}; dynObj->addProperty("materialFilterMode", newProp, -1); } } @@ -1046,7 +1063,7 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ auto scriptRelPath = utils::u8path("interfaces"); std::filesystem::create_directories(projectPath / scriptRelPath); - std::vector createdLinks; + std::vector createdLinks; // Prefab pass 1: // Generate file names for the interface script we need to generate @@ -1062,7 +1079,7 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ for (auto child : dynObj->children_->asVector()) { if (child->serializationTypeName() == "LuaScript") { auto prefabScript = std::dynamic_pointer_cast(child); - if (!prefabScript->query()) { + if (!prefabScript->query()) { auto interfaceText = generateInterfaceScript(prefabScript); utils::u8path path(prefabScript->get("uri")->asString()); scriptNameToTextToIDMap[path.stem().string()][interfaceText].insert(prefabScript->objectID()); @@ -1095,14 +1112,14 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ utils::u8path intfRelPath; - if (!prefabScript->query()) { + if (!prefabScript->query()) { auto it = interfacePaths.find(prefabScript->objectID()); assert(it != interfacePaths.end()); intfRelPath = it->second; auto interfaceText = generateInterfaceScript(prefabScript); auto intfAbsPath = projectPath / intfRelPath; - LOG_INFO(raco::log_system::DESERIALIZATION, "Writing generated interface file {} -> {}", prefabScript->objectName(), intfAbsPath.string()); - raco::utils::file::write(intfAbsPath, interfaceText); + LOG_INFO(log_system::DESERIALIZATION, "Writing generated interface file {} -> {}", prefabScript->objectName(), intfAbsPath.string()); + utils::file::write(intfAbsPath, interfaceText); } auto interfaceObjID = EditorObject::XorObjectIDs(prefabScript->objectID(), "00000000-0000-0000-0000-000000000001"); @@ -1143,7 +1160,7 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ std::copy(createdLinks.begin(), createdLinks.end(), std::back_inserter(deserializedIR.links)); for (const auto& obj : deserializedIR.objects) { - auto dynObj = std::dynamic_pointer_cast(obj); + auto dynObj = std::dynamic_pointer_cast(obj); dynObj->onAfterDeserialization(); } } @@ -1167,14 +1184,14 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ if (stringIt != newPropertyStrings.end()) { auto newlinkStartProps = stringIt->second; newlinkStartProps.insert(newlinkStartProps.end(), linkStartProps.begin() + 1, linkStartProps.end()); - link->startProp_->set(newlinkStartProps); + link->startProp_->set(newlinkStartProps); } stringIt = newPropertyStrings.find(linkEndProps.front()); if (stringIt != newPropertyStrings.end()) { auto newlinkEndProps = stringIt->second; newlinkEndProps.insert(newlinkEndProps.end(), linkEndProps.begin() + 1, linkEndProps.end()); - link->endProp_->set(newlinkEndProps); + link->endProp_->set(newlinkEndProps); } } } @@ -1220,7 +1237,7 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ auto linkStartProps = link->startPropertyNamesVector(); if (linkStartProps.at(0) == "animationOutputs") { linkStartProps[0] = "outputs"; - link->startProp_->set(linkStartProps); + link->startProp_->set(linkStartProps); } } @@ -1364,7 +1381,7 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ newLinkEndProps.insert(newLinkEndProps.end(), names.begin(), names.end()); newLinkEndProps.insert(newLinkEndProps.end(), linkEndProps.begin() + numPrefixComponents + 1, linkEndProps.end()); - link->endProp_->set(newLinkEndProps); + link->endProp_->set(newLinkEndProps); } }; @@ -1427,6 +1444,305 @@ void migrateProject(ProjectDeserializationInfoIR& deserializedIR, raco::serializ } } } -} -} // namespace raco::serialization \ No newline at end of file + // File version 55: conversion of user types from Table and fixed properties to Array properties + // Migration of EditorObject::children property from Table -> Array type is done implicitly by the deserialization + // since we can't change the types of EditorObject properties in the migration. + if (deserializedIR.fileVersion < 55) { + for (const auto& dynObj : deserializedIR.objects) { + auto instanceType = dynObj->serializationTypeName(); + + if (instanceType == "RenderPass") { + auto newProperty = dynObj->addProperty("layers", new Property, DisplayNameAnnotation, ExpectEmptyReference>({}, {"Layers"}, {}), -1); + + for (auto propName : {"layer0", "layer1", "layer2", "layer3", "layer4", "layer5", "layer6", "layer7"}) { + if (dynObj->hasProperty(propName)) { + auto oldLayer = dynObj->extractProperty(propName); + *newProperty->asArray().addProperty() = oldLayer->asRef(); + } else { + *newProperty->asArray().addProperty() = SRenderLayer(); + } + } + } + + if (instanceType == "RenderTarget") { + auto newBuffers = dynObj->addProperty("buffers", new Property, DisplayNameAnnotation, ExpectEmptyReference>({}, {"Buffers"}, {}), -1); + for (auto propName : {"buffer0", "buffer1", "buffer2", "buffer3", "buffer4", "buffer5", "buffer6", "buffer7"}) { + if (dynObj->hasProperty(propName)) { + auto oldProp = dynObj->extractProperty(propName); + *newBuffers->asArray().addProperty() = oldProp->asRef(); + } else { + *newBuffers->asArray().addProperty() = SRenderBuffer(); + } + } + + auto newBuffersMS = dynObj->addProperty("buffersMS", new Property, DisplayNameAnnotation, ExpectEmptyReference>({}, {"Buffers (Multisampled)"}, {}), -1); + for (auto propName : {"bufferMS0", "bufferMS1", "bufferMS2", "bufferMS3", "bufferMS4", "bufferMS5", "bufferMS6", "bufferMS7"}) { + if (dynObj->hasProperty(propName)) { + auto oldProp = dynObj->extractProperty(propName); + *newBuffersMS->asArray().addProperty() = oldProp->asRef(); + } else { + *newBuffersMS->asArray().addProperty() = SRenderBufferMS(); + } + } + } + + if (instanceType == "Animation") { + if (dynObj->hasProperty("animationChannels")) { + auto oldChannels = dynObj->extractProperty("animationChannels"); + auto newChannels = dynObj->addProperty("animationChannels", new Property, DisplayNameAnnotation>({}, {"Animation Channels"}), -1); + + Table& oldTable = oldChannels->asTable(); + for (size_t i = 0; i < oldTable.size(); i++) { + *newChannels->asArray().addProperty() = oldTable.get(i)->asRef(); + } + } + } + + if (instanceType == "Skin") { + if (dynObj->hasProperty("targets")) { + auto oldTargets = dynObj->extractProperty("targets"); + auto newTargets = dynObj->addProperty("targets", new Property, DisplayNameAnnotation>({}, {"Target MeshNodes"}), -1); + + Table& oldTable = oldTargets->asTable(); + for (size_t i = 0; i < oldTable.size(); i++) { + *newTargets->asArray().addProperty() = oldTable.get(i)->asRef(); + } + } + + if (dynObj->hasProperty("joints")) { + auto oldJoints = dynObj->extractProperty("joints"); + auto newJoints = dynObj->addProperty("joints", new Property, DisplayNameAnnotation>({}, {"Joint Nodes"}), -1); + + Table& oldTable = oldJoints->asTable(); + for (size_t i = 0; i < oldTable.size(); i++) { + *newJoints->asArray().addProperty() = oldTable.get(i)->asRef(); + } + } + } + } + } + + // File version 56 : Split RenderTarget into RenderTarget and RenderTargetMS classes + if (deserializedIR.fileVersion < 56) { + std::vector toRemove; + + // Pass 1: change type of RenderPass target property + for (const auto& dynObj : deserializedIR.objects) { + if (dynObj->serializationTypeName() == "RenderPass") { + if (dynObj->hasProperty("target")) { + auto oldProp = dynObj->extractProperty("target"); + auto newProp = dynObj->addProperty("target", new Property({}, {"Target"}, {"Default Framebuffer"}), -1); + *newProp = *oldProp; + } + } + } + + // Pass 2: split RenderTargets + // if this creates mew RenderTargMS objects the RenderPasses target properties must be changed, but we can't do this in + // a single pass since we need to change the target property type before we can set it to a RenderTargetMS. + + // Iterate over copy of the objects since we create additional objects leading to iterator invalidation otherwise. + auto objectsCopy = deserializedIR.objects; + for (const auto& dynObj : objectsCopy) { + if (dynObj->serializationTypeName() == "RenderTarget") { + bool hasNormalBuffers = false; + bool hasMSBuffers = false; + if (dynObj->hasProperty("buffers")) { + auto array_ptr = dynamic_cast*>(&dynObj->get("buffers")->asArray()); + auto buffers = array_ptr->asVector(); + hasNormalBuffers = std::any_of(buffers.begin(), buffers.end(), [](auto object) { + return object != nullptr; + }); + } + + if (dynObj->hasProperty("buffersMS")) { + auto array_ptr = dynamic_cast*>(&dynObj->get("buffersMS")->asArray()); + auto buffers = array_ptr->asVector(); + hasMSBuffers = std::any_of(buffers.begin(), buffers.end(), [](auto object) { + return object != nullptr; + }); + } + + if (!hasMSBuffers && dynObj->hasProperty("buffersMS")) { + dynObj->removeProperty("buffersMS"); + } + + if (hasNormalBuffers && hasMSBuffers && dynObj->hasProperty("buffersMS")) { + dynObj->removeProperty("buffersMS"); + deserializedIR.migrationObjWarnings[dynObj->objectID()] = fmt::format("RenderTarget object '{}' has both non-empty buffer and bufferMS properties: it will be converted to a RenderTarget losing the bufferMS properties.", dynObj->objectName()); + } + + // !!! Wrong !!! + // The save file optimization may have removed buffer references if the RenderTarget is an external reference. + // In this case the check below may be wrong, i.e. different than without the save file optimization. + // Since the information needed to make the correct decision is not present in the file we can't make + // the right choice here in all cases. + // Instead the external reference update itself contains fixup code for this case. + + if (!hasNormalBuffers && hasMSBuffers) { + // Replace the object by a RenderTargetMS with same object id and property values + auto targetMS = std::dynamic_pointer_cast(factory.createObject("RenderTargetMS", dynObj->objectName(), dynObj->objectID())); + + if (auto anno = dynObj->query()) { + targetMS->addAnnotation(std::make_shared(*anno->projectID_)); + } + + if (dynObj->hasProperty("userTags")) { + targetMS->addProperty("userTags", dynObj->extractProperty("userTags"), -1); + } + + targetMS->addProperty("buffers", dynObj->extractProperty("buffersMS"), -1); + + deserializedIR.objects.emplace_back(targetMS); + toRemove.emplace_back(dynObj); + + // Point references to the RenderTarget to the new RenderTargetMS instead: + for (auto wobj : dynObj->referencesToThis()) { + if (auto obj = wobj.lock()) { + assert(obj->serializationTypeName() == "RenderPass"); + if (obj->hasProperty("target")) { + *obj->get("target") = targetMS; + } + } + } + } + } + } + + for (auto obj : toRemove) { + auto it = std::find(deserializedIR.objects.begin(), deserializedIR.objects.end(), obj); + assert(it != deserializedIR.objects.end()); + deserializedIR.objects.erase(it); + } + + // We need to update the back and parent pointers since we change the pointer structure above: + recreateBackPointers(deserializedIR); + } + + // File version 58: Removed userTags property from ProjectSettings + if (deserializedIR.fileVersion < 58) { + for (const auto& dynObj : deserializedIR.objects) { + if (dynObj->serializationTypeName() == "ProjectSettings") { + if (dynObj->hasProperty("userTags")) { + dynObj->removeProperty("userTags"); + } + } + } + } + + if (deserializedIR.fileVersion < 59) { + for (const auto& dynObj : deserializedIR.objects) { + auto instanceType = dynObj->serializationTypeName(); + + if (instanceType == "RenderPass") { + if (dynObj->hasProperty("layers")) { + auto oldProp = dynObj->extractProperty("layers"); + auto newProp = dynObj->addProperty("layers", new Property, DisplayNameAnnotation, ExpectEmptyReference, ResizableArray>({}, {"Layers"}, {}, {}), -1); + *newProp = *oldProp; + } + } + + if (instanceType == "RenderTarget") { + if (dynObj->hasProperty("buffers")) { + auto oldProp = dynObj->extractProperty("buffers"); + auto newProp = dynObj->addProperty("buffers", new Property, DisplayNameAnnotation, ExpectEmptyReference, ResizableArray>({}, {"Buffers"}, {}, {}), -1); + *newProp = *oldProp; + } + } + + if (instanceType == "RenderTargetMS") { + if (dynObj->hasProperty("buffers")) { + auto oldProp = dynObj->extractProperty("buffers"); + auto newProp = dynObj->addProperty("buffers", new Property, DisplayNameAnnotation, ExpectEmptyReference, ResizableArray>({}, {"Buffers"}, {}, {}), -1); + *newProp = *oldProp; + } + } + + if (instanceType == "Animation") { + if (dynObj->hasProperty("animationChannels")) { + auto oldProp = dynObj->extractProperty("animationChannels"); + auto newProp = dynObj->addProperty("animationChannels", new Property, DisplayNameAnnotation, ResizableArray>({}, {"Animation Channels"}, {}), -1); + *newProp = *oldProp; + } + } + + if (instanceType == "Skin") { + if (dynObj->hasProperty("targets")) { + auto oldProp = dynObj->extractProperty("targets"); + auto newProp = dynObj->addProperty("targets", new Property, DisplayNameAnnotation, ResizableArray>({}, {"Target MeshNodes"}, {}), -1); + *newProp = *oldProp; + } + } + } + } + + // Migration from version 60 -> 2001 (RaCo 2.x) + // - feature level reset + if (deserializedIR.fileVersion > 60 && deserializedIR.fileVersion < 2001) { + throw std::runtime_error("non-migratable file version"); + } + if (deserializedIR.fileVersion <= 60) { + for (const auto& dynObj : deserializedIR.objects) { + auto instanceType = dynObj->serializationTypeName(); + + // reset ProjectSettings feature level to 1 + if (instanceType == "ProjectSettings") { + if (dynObj->hasProperty("featureLevel")) { + *dynObj->get("featureLevel") = 1; + } + } + + // remove FeatureLevel annotation from Node::enabled property + if (instanceType == "Node" || instanceType == "MeshNode" || instanceType == "PerspectiveCamera" || instanceType == "OrthographicCamera" || instanceType == "PrefabInstance") { + if (dynObj->hasProperty("enabled")) { + auto oldProp = dynObj->extractProperty("enabled"); + dynObj->addProperty("enabled", new Property{oldProp->asBool(), DisplayNameAnnotation("Enabled"), {}}, -1); + } + } + + // remove FeatureLevel annotation from PerspectiveCamera::frustumType property + if (instanceType == "PerspectiveCamera") { + if (dynObj->hasProperty("frustumType")) { + auto oldProp = dynObj->extractProperty("frustumType"); + dynObj->addProperty("frustumType", new Property{oldProp->asInt(), {"Frustum Type"}, {core::EUserTypeEnumerations::FrustumType}}, -1); + } + } + + // remove FeatureLevel annotation from RenderPass::renderOnce property + if (instanceType == "RenderPass") { + if (dynObj->hasProperty("renderOnce")) { + auto oldProp = dynObj->extractProperty("renderOnce"); + dynObj->addProperty("renderOnce", new Property{oldProp->asBool(), {"Render Once"}, {}}, -1); + } + } + + // remove FeatureLevel annotation from LuaInterface luaModules and stdModules properties + if (instanceType == "LuaInterface") { + if (dynObj->hasProperty("luaModules")) { + auto oldProp = dynObj->extractProperty("luaModules"); + auto newProp = dynObj->addProperty("luaModules", new Property{{}, DisplayNameAnnotation("Modules")}, -1); + *newProp = *oldProp; + } + if (dynObj->hasProperty("stdModules")) { + auto oldProp = dynObj->extractProperty("stdModules"); + auto newProp = dynObj->addProperty("stdModules", new Property{{}, {"Standard Modules"}}, -1); + *newProp = *oldProp; + } + } + + // reset feature level in LinkEndAnnotation of renderableTags child properties to 1 + if (instanceType == "RenderLayer") { + if (dynObj->hasProperty("renderableTags")) { + auto& tags = dynObj->get("renderableTags")->asTable(); + for (size_t i = 0; i < tags.size(); i++) { + auto anno = tags.get(i)->query(); + anno->featureLevel_ = 1; + } + } + } + } + } +} + +} // namespace raco::serialization diff --git a/datamodel/libCore/src/PropertyDescriptor.cpp b/datamodel/libCore/src/PropertyDescriptor.cpp index 61edccf9..bf233994 100644 --- a/datamodel/libCore/src/PropertyDescriptor.cpp +++ b/datamodel/libCore/src/PropertyDescriptor.cpp @@ -28,7 +28,7 @@ std::string PropertyDescriptor::getPropertyPath(bool useObjectID) const { } std::string PropertyDescriptor::getFullPropertyPath() const { - auto hierarchyPath = raco::core::Queries::getFullObjectHierarchyPath(object_->getParent()); + auto hierarchyPath = core::Queries::getFullObjectHierarchyPath(object_->getParent()); if (!hierarchyPath.empty()) { hierarchyPath.append("/"); } diff --git a/datamodel/libCore/src/ProxyObjectFactory.cpp b/datamodel/libCore/src/ProxyObjectFactory.cpp index addeaa41..c33440b6 100644 --- a/datamodel/libCore/src/ProxyObjectFactory.cpp +++ b/datamodel/libCore/src/ProxyObjectFactory.cpp @@ -84,6 +84,7 @@ namespace raco::serialization::proxy { RenderBufferMS, RenderLayer, RenderTarget, + RenderTargetMS, RenderPass, Skin, Timer diff --git a/datamodel/libCore/src/ProxyTypes.cpp b/datamodel/libCore/src/ProxyTypes.cpp index 0156d7d7..551092fd 100644 --- a/datamodel/libCore/src/ProxyTypes.cpp +++ b/datamodel/libCore/src/ProxyTypes.cpp @@ -34,7 +34,9 @@ const char renderBufferTypeName[] = "RenderBuffer"; const char renderBufferMSTypeName[] = "RenderBufferMS"; const char renderLayerTypeName[] = "RenderLayer"; const char renderPassTypeName[] = "RenderPass"; +const char renderTargetBaseTypeName[] = "RenderTargetBase"; const char renderTargetTypeName[] = "RenderTarget"; +const char renderTargetMSTypeName[] = "RenderTargetMS"; const char prefabTypeName[] = "Prefab"; const char prefabInstanceTypeName[] = "PrefabInstance"; const char scissorOptionsTypeName[] = "ScissorOptions"; diff --git a/datamodel/libCore/src/Queries.cpp b/datamodel/libCore/src/Queries.cpp index 3d423645..257c2c8c 100644 --- a/datamodel/libCore/src/Queries.cpp +++ b/datamodel/libCore/src/Queries.cpp @@ -26,6 +26,7 @@ #include "user_types/PrefabInstance.h" #include "user_types/RenderPass.h" #include "user_types/Skin.h" +#include "user_types/Texture.h" #include "user_types/Timer.h" #include @@ -381,7 +382,7 @@ bool Queries::isChildHandle(const ValueHandle& handle) { } TagType Queries::getHandleTagType(const ValueHandle& handle) { - if (handle.isRefToProp(&EditorObject::userTags_)) { + if (handle.isRefToProp(&user_types::BaseObject::userTags_)) { return TagType::UserTags; } if (handle.rootObject()->isType()) { @@ -483,7 +484,11 @@ bool Queries::isReadOnly(const Project& project, const ValueHandle& handle, bool } -bool Queries::isHiddenInPropertyBrowser(const Project& project, const ValueHandle& handle) { +bool Queries::isHiddenInPropertyBrowser(const Project& project, const ValueHandle& handle, bool isMultiSelect) { + if (handle.isRefToProp(&user_types::Texture::preview_) && !isMultiSelect) { + return false; + } + if (handle.query() || handle.query() || handle.query()) { return false; } @@ -683,12 +688,12 @@ std::vector Queries::getLinksConnectedToObject(const Project& project, co namespace { void getLinksConnectedToObjectsHelper( - const std::map>& linkStartPoints, - const std::map>& linkEndPoints, + const std::map>& linkStartPoints, + const std::map>& linkEndPoints, const std::string& propertyObjID, bool includeStarting, bool includeEnding, - std::map>& result) { + std::map>& result) { if (includeStarting) { auto linkIt = linkStartPoints.find(propertyObjID); @@ -821,11 +826,11 @@ bool isStructureLinkCompatible(const ReflectionInterface* left, const Reflection for (int i = 0; i < left->size(); i++) { auto name = left->name(i); - const ValueBase* lval = left->get(name); - const ValueBase* rval = right->get(name); - if (!rval) { + if (!right->hasProperty(name)) { return false; } + const ValueBase* lval = left->get(name); + const ValueBase* rval = right->get(name); if (!isSameEnginePrimitiveType(lval, rval)) { return false; @@ -929,7 +934,8 @@ bool Queries::linkWouldBeValid(const Project& project, const PropertyDescriptor& } bool Queries::userCanCreateLink(const Project& project, const ValueHandle& start, const ValueHandle& end, bool isWeak) { - return Queries::linkWouldBeAllowed(project, start.getDescriptor(), end.getDescriptor(), isWeak) && + return start && end && + Queries::linkWouldBeAllowed(project, start.getDescriptor(), end.getDescriptor(), isWeak) && Queries::linkWouldBeValid(project, start.getDescriptor(), end.getDescriptor()) && !Queries::isReadOnly(project, end, true); } diff --git a/datamodel/libCore/src/Queries_Tags.cpp b/datamodel/libCore/src/Queries_Tags.cpp index 9b3f79ca..bc46a01d 100644 --- a/datamodel/libCore/src/Queries_Tags.cpp +++ b/datamodel/libCore/src/Queries_Tags.cpp @@ -68,7 +68,7 @@ bool Queries::isMeshNodeInMaterialFilter(user_types::SMeshNode const& obj, std:: bool matFilterDiscarded = false; if (!materialFilterTags.empty()) { - auto meshnode = obj->as(); + auto meshnode = obj->as(); auto material = meshnode->getMaterial(0); if (!material && !materialFilterExclusive) { diff --git a/datamodel/libCore/src/Serialization.cpp b/datamodel/libCore/src/Serialization.cpp index 6e0457ea..4ab5dba6 100644 --- a/datamodel/libCore/src/Serialization.cpp +++ b/datamodel/libCore/src/Serialization.cpp @@ -9,6 +9,8 @@ */ #include "core/Serialization.h" +#include "data_storage/Array.h" + #include "core/DynamicEditorObject.h" #include "core/EditorObject.h" #include "core/Link.h" @@ -17,8 +19,6 @@ #include "core/ProjectMigrationToV23.h" #include "core/ProxyObjectFactory.h" #include "core/SerializationKeys.h" -#include "core/UserObjectFactoryInterface.h" -#include "user_types/UserObjectFactory.h" #include "core/CommandInterface.h" #include "data_storage/Table.h" @@ -41,7 +41,7 @@ bool operator==(const ExternalProjectInfo& lhs, const ExternalProjectInfo& rhs) return lhs.path == rhs.path && lhs.name == rhs.name; } -std::optional resolveReferenceId(const raco::data_storage::ValueBase& value) { +std::optional resolveReferenceId(const data_storage::ValueBase& value) { if (auto ref = value.asRef()) { return ref->objectID(); } else { @@ -53,9 +53,11 @@ std::optional resolveReferenceId(const raco::data_storage::ValueBas namespace { +using namespace raco; + QJsonObject serializeTypedObject(const ReflectionInterface& object); -SReflectionInterface deserializeTypedObject(const QJsonObject& jsonObject, const raco::core::UserObjectFactoryInterface& factory, References& references); +SReflectionInterface deserializeTypedObject(const QJsonObject& jsonObject, const core::UserObjectFactoryInterface& factory, References& references); /** * Serialize a value base to it's primitive json counterpart. This function also maps references to the associated id via `resolveReferenceId`. @@ -95,7 +97,7 @@ void deserializePrimitiveValue(const QJsonValue& jsonValue, ValueBase& value, Re break; case PrimitiveType::Double: value = jsonValue.toDouble(); - break; + break; case PrimitiveType::Int: value = jsonValue.toInt(); break; @@ -117,7 +119,7 @@ void deserializePrimitiveValue(const QJsonValue& jsonValue, ValueBase& value, Re } /** Serializations of annotations need to be handled separately. This is the only case where we require to serialize a typed object within a typed property. */ -std::optional serializeAnnotations(const std::vector& annotations, bool dynamicallyTyped) { +std::optional serializeAnnotations(const std::vector& annotations, bool dynamicallyTyped) { QJsonArray jsonArray{}; for (auto anno : annotations) { if (anno->serializationRequired() || dynamicallyTyped) { @@ -131,13 +133,13 @@ std::optional serializeAnnotations(const std::vector>& structPropTypesMap, bool dynamicallyTyped); -void deserializeArrayProperties(const QJsonArray& properties, ReflectionInterface& arrayInterface, References& references, const raco::core::UserObjectFactoryInterface& factory, const std::map>& structPropTypesMap, bool dynamicallyType); +void deserializeObjectProperties(const QJsonObject& properties, ReflectionInterface& objectInterface, References& references, const core::UserObjectFactoryInterface& factory, const std::map>& structPropTypesMap, bool dynamicallyTyped); +void deserializeArrayProperties(const QJsonArray& properties, ReflectionInterface& arrayInterface, References& references, const core::UserObjectFactoryInterface& factory, const std::map>& structPropTypesMap, bool dynamicallyType); /** Deserializes result of `serializeAnnotations` from `annotations` into the annotations of the given `value`. */ -void deserializeAnnotations(const QJsonArray& annotations, const ValueBase& value, References& references, const raco::core::UserObjectFactoryInterface& factory, const std::map>& structPropTypesMap) { +void deserializeAnnotations(const QJsonArray& annotations, const ValueBase& value, References& references, const core::UserObjectFactoryInterface& factory, const std::map>& structPropTypesMap) { for (const auto& annotation : annotations) { - auto it = std::find_if(value.baseAnnotationPtrs().begin(), value.baseAnnotationPtrs().end(), [&annotation](const raco::data_storage::AnnotationBase* annoBase) { + auto it = std::find_if(value.baseAnnotationPtrs().begin(), value.baseAnnotationPtrs().end(), [&annotation](const data_storage::AnnotationBase* annoBase) { return annoBase->getTypeDescription().typeName == annotation[keys::TYPENAME].toString().toStdString(); }); deserializeObjectProperties(annotation[keys::PROPERTIES].toObject(), **it, references, factory, structPropTypesMap, false); @@ -156,13 +158,13 @@ std::optional serializeObjectAnnotations(const ClassWithReflectedMem } } -std::shared_ptr deserializeSingleObjectAnnotation(const QJsonObject& jsonObject, const raco::core::UserObjectFactoryInterface& factory, const std::map>& structPropTypesMap, References& references) { +std::shared_ptr deserializeSingleObjectAnnotation(const QJsonObject& jsonObject, const core::UserObjectFactoryInterface& factory, const std::map>& structPropTypesMap, References& references) { auto object{factory.createAnnotation(jsonObject[keys::TYPENAME].toString().toStdString())}; deserializeObjectProperties(jsonObject[keys::PROPERTIES].toObject(), *object.get(), references, factory, structPropTypesMap, false); return object; } -void deserializeObjectAnnotations(const QJsonArray& annotations, ClassWithReflectedMembers* object, References& references, const raco::core::UserObjectFactoryInterface& factory, const std::map>& structPropTypesMap) { +void deserializeObjectAnnotations(const QJsonArray& annotations, ClassWithReflectedMembers* object, References& references, const core::UserObjectFactoryInterface& factory, const std::map>& structPropTypesMap) { for (const auto& annotation : annotations) { auto deserializedAnno = deserializeSingleObjectAnnotation(annotation.toObject(), factory, structPropTypesMap, references); object->addAnnotation(deserializedAnno); @@ -178,6 +180,10 @@ std::optional serializeArrayProperties(const ReflectionInterface& ar * @return a QJsonValue which seralize the given `value`, based on the type of the `value` the returned QJsonValue can either be an Object, Array or an actual Value. */ std::optional serializeValueBase(const ValueBase& value, bool dynamicallyTyped = false) { + if (value.query()) { + return {}; + } + bool childrenDynamicallyTyped{value.type() == PrimitiveType::Table}; bool valueIsClassType{hasTypeSubstructure(value.type())}; auto annotations{serializeAnnotations(value.baseAnnotationPtrs(), dynamicallyTyped)}; @@ -188,7 +194,7 @@ std::optional serializeValueBase(const ValueBase& value, bool dynami jsonObject.insert(keys::TYPENAME, value.typeName().c_str()); if (valueIsClassType) { - if (value.query()) { + if (value.type() == PrimitiveType::Array || value.query()) { if (auto properties{serializeArrayProperties(value.getSubstructure(), childrenDynamicallyTyped)}) { jsonObject.insert(keys::PROPERTIES, properties.value()); } @@ -215,7 +221,7 @@ std::optional serializeValueBase(const ValueBase& value, bool dynami return {}; } else if (valueIsClassType) { // We have a statically known class type which can be immediately seralized - if (value.query()) { + if (value.type() == PrimitiveType::Array) { return serializeArrayProperties(value.getSubstructure(), false); } else { return serializeObjectProperties(value.getSubstructure(), false); @@ -228,13 +234,13 @@ std::optional serializeValueBase(const ValueBase& value, bool dynami -void createMissingProperties(const std::map& propTypeMap, ReflectionInterface& object, const raco::core::UserObjectFactoryInterface& factory) { +void createMissingProperties(const std::map& propTypeMap, ReflectionInterface& object, const core::UserObjectFactoryInterface& factory) { auto intf = dynamic_cast(&object); for (const auto& [propertyName, typeName] : propTypeMap) { if (!object.hasProperty(propertyName)) { - if (raco::data_storage::isPrimitiveTypeName(typeName)) { - intf->addProperty(propertyName, raco::data_storage::toPrimitiveType(typeName)); + if (data_storage::isPrimitiveTypeName(typeName)) { + intf->addProperty(propertyName, data_storage::toPrimitiveType(typeName)); } else { // typeName: REF::Material intf->addProperty(propertyName, factory.createValue(typeName)); @@ -243,13 +249,13 @@ void createMissingProperties(const std::map& propTypeM } } -void createMissingProperties(const QJsonArray& order, const QJsonObject& jsonObject, raco::data_storage::Table& table, const raco::core::UserObjectFactoryInterface& factory) { +void createMissingProperties(const QJsonArray& order, const QJsonObject& jsonObject, data_storage::Table& table, const core::UserObjectFactoryInterface& factory) { for (const auto& qPropertyName : order) { const std::string propertyName{qPropertyName.toString().toStdString()}; if (!table.hasProperty(propertyName)) { const std::string typeName{jsonObject[qPropertyName.toString()].toObject()[keys::TYPENAME].toString().toStdString()}; - if (raco::data_storage::isPrimitiveTypeName(typeName)) { - table.addProperty(propertyName, raco::data_storage::toPrimitiveType(typeName)); + if (data_storage::isPrimitiveTypeName(typeName)) { + table.addProperty(propertyName, data_storage::toPrimitiveType(typeName)); } else { // typeName: REF::Material table.addProperty(propertyName, factory.createValue(typeName)); @@ -258,12 +264,12 @@ void createMissingProperties(const QJsonArray& order, const QJsonObject& jsonObj } } -void createMissingProperties(const QJsonArray& jsonArray, raco::data_storage::Table& table, const raco::core::UserObjectFactoryInterface& factory) { +void createMissingProperties(const QJsonArray& jsonArray, data_storage::Table& table, const core::UserObjectFactoryInterface& factory) { for (size_t i{0}; i < jsonArray.size(); i++) { - if (!table[i]) { + if (i >= table.size()) { const std::string typeName{jsonArray[static_cast(i)].toObject()[keys::TYPENAME].toString().toStdString()}; - if (raco::data_storage::isPrimitiveTypeName(typeName)) { - table.addProperty(raco::data_storage::toPrimitiveType(typeName)); + if (data_storage::isPrimitiveTypeName(typeName)) { + table.addProperty(data_storage::toPrimitiveType(typeName)); } else { table.addProperty(factory.createValue(typeName)); } @@ -271,8 +277,13 @@ void createMissingProperties(const QJsonArray& jsonArray, raco::data_storage::Ta } } +void createMissingProperties(const QJsonArray& jsonArray, ArrayBase& array) { + array.resize(jsonArray.size()); +} + + /** Deserializes result of `serializeValueBase` from `property` into the given `value`. */ -void deserializeValueBase(const QJsonValue& property, ValueBase& value, References& references, const raco::core::UserObjectFactoryInterface& factory, const std::map>& structPropTypesMap, bool dynamicallyTyped = false) { +void deserializeValueBase(const QJsonValue& property, ValueBase& value, References& references, const core::UserObjectFactoryInterface& factory, const std::map>& structPropTypesMap, bool dynamicallyTyped = false) { bool childrenDynamicallyTyped{value.type() == PrimitiveType::Table}; auto valueIsClassType{hasTypeSubstructure(value.type())}; auto hasAnnotations{property.isObject() && property.toObject().keys().contains(keys::ANNOTATIONS)}; @@ -283,6 +294,8 @@ void deserializeValueBase(const QJsonValue& property, ValueBase& value, Referenc if (propertyAsObject[keys::PROPERTIES].isArray()) { if (value.type() == PrimitiveType::Table) { createMissingProperties(propertyAsObject[keys::PROPERTIES].toArray(), value.asTable(), factory); + } else if (value.type() == PrimitiveType::Array) { + createMissingProperties(propertyAsObject[keys::PROPERTIES].toArray(), value.asArray()); } deserializeArrayProperties(propertyAsObject[keys::PROPERTIES].toArray(), value.getSubstructure(), references, factory, structPropTypesMap, childrenDynamicallyTyped); } else { @@ -301,7 +314,22 @@ void deserializeValueBase(const QJsonValue& property, ValueBase& value, Referenc deserializeAnnotations(propertyAsObject[keys::ANNOTATIONS].toArray(), value, references, factory, structPropTypesMap); } } else if (valueIsClassType) { - if (property.isArray()) { + if (value.type() == PrimitiveType::Array && value.asArray().elementType() == PrimitiveType::String && !property.isArray()) { + // Special case: migration of Link::startProp and endProp properties from Table (<= V59) to Array (>= V60) + auto propertyAsObject{property.toObject()}; + createMissingProperties(propertyAsObject[keys::PROPERTIES].toArray(), value.asArray()); + deserializeArrayProperties(propertyAsObject[keys::PROPERTIES].toArray(), value.getSubstructure(), references, factory, structPropTypesMap, true); + } else if (value.type() == PrimitiveType::Array && value.asArray().elementType() == PrimitiveType::Ref && !property.isArray()) { + // special case: migration of EditorObject::children_ property from Table up to file version 54 + // to Array starting from file version 55: + // Since we can't use normal migration code for the EditorObject properties we need to correctly recognize the Table + // structure in V54 and deserialize it to the Array property present in the current EditorObject: + auto propertyAsObject{property.toObject()}; + createMissingProperties(propertyAsObject[keys::PROPERTIES].toArray(), value.asArray()); + deserializeArrayProperties(propertyAsObject[keys::PROPERTIES].toArray(), value.getSubstructure(), references, factory, structPropTypesMap, true); + } else if (property.isArray()) { + assert(value.type() == PrimitiveType::Array); + createMissingProperties(property.toArray(), value.asArray()); deserializeArrayProperties(property.toArray(), value.getSubstructure(), references, factory, structPropTypesMap, false); } else { if (value.type() == PrimitiveType::Struct) { @@ -337,9 +365,9 @@ std::optional serializeArrayProperties(const ReflectionInterface& ar } /** Deserializes result of `serializeArrayProperties` from `properties` into the given `interface`. */ -void deserializeArrayProperties(const QJsonArray& properties, ReflectionInterface& arrayInterface, References& references, const raco::core::UserObjectFactoryInterface& factory, const std::map>& structPropTypesMap, bool dynamicallyTyped = false) { +void deserializeArrayProperties(const QJsonArray& properties, ReflectionInterface& arrayInterface, References& references, const core::UserObjectFactoryInterface& factory, const std::map>& structPropTypesMap, bool dynamicallyTyped = false) { for (size_t i{0}; i < properties.size(); i++) { - deserializeValueBase(properties[static_cast(i)].toObject(), *arrayInterface.get(i), references, factory, structPropTypesMap, dynamicallyTyped); + deserializeValueBase(properties[static_cast(i)], *arrayInterface.get(i), references, factory, structPropTypesMap, dynamicallyTyped); } } @@ -364,18 +392,18 @@ std::optional serializeObjectProperties(const ReflectionInterface& } /** Deserializes result of `serializeObjectProperties` from `properties` into the given `interface`. */ -void deserializeObjectProperties(const QJsonObject& properties, ReflectionInterface& objectInterface, References& references, const raco::core::UserObjectFactoryInterface& factory, const std::map>& structPropTypesMap, bool dynamicallyTyped = false) { +void deserializeObjectProperties(const QJsonObject& properties, ReflectionInterface& objectInterface, References& references, const core::UserObjectFactoryInterface& factory, const std::map>& structPropTypesMap, bool dynamicallyTyped = false) { for (const auto& qPropertyName : properties.keys()) { std::string name = qPropertyName.toStdString(); - ValueBase& value = *objectInterface.get(objectInterface.index(name)); - if (&value != nullptr) { - deserializeValueBase(properties[qPropertyName], value, references, factory, structPropTypesMap, dynamicallyTyped); + if (objectInterface.hasProperty(name)) { + deserializeValueBase(properties[qPropertyName], *objectInterface.get(name), references, factory, structPropTypesMap, dynamicallyTyped); } else { - LOG_WARNING(raco::log_system::DESERIALIZATION, "Dropping unsupported or deprecated property {}", name); + LOG_WARNING(log_system::DESERIALIZATION, "Dropping unsupported or deprecated property {}", name); } } } + /** * We have some form of C++ Object. Either an EditorObject or an Annotation. * @return QJsonObject of form e.g.: { "typeName": "MeshNode", "properties": { ... } } @@ -404,23 +432,23 @@ QJsonObject serializeTypedObject(const ReflectionInterface& object) { * @return an Object created by the `factory` for the given `jsonObject`. */ -SReflectionInterface deserializeTypedObject(const QJsonObject& jsonObject, raco::core::UserObjectFactoryInterface& factory, References& references, const std::map>& typesPropTypesMap, const std::map>& structPropTypesMap) { +SReflectionInterface deserializeTypedObject(const QJsonObject& jsonObject, core::UserObjectFactoryInterface& factory, References& references, const std::map>& typesPropTypesMap, const std::map>& structPropTypesMap) { auto typeName = jsonObject[keys::TYPENAME].toString().toStdString(); - SReflectionInterface object; - if (typeName == raco::core::Link::typeDescription.typeName) { - object = std::make_shared(); + SReflectionInterface object; + if (typeName == core::Link::typeDescription.typeName) { + object = std::make_shared(); } else { object = factory.createObject(typeName); } if (jsonObject.keys().contains(keys::ANNOTATIONS)) { deserializeObjectAnnotations(jsonObject[keys::ANNOTATIONS].toArray(), - std::dynamic_pointer_cast(object).get(), + std::dynamic_pointer_cast(object).get(), references, factory, structPropTypesMap); } - - if (typeName != raco::core::Link::typeDescription.typeName) { + + if (typeName != core::Link::typeDescription.typeName) { createMissingProperties(typesPropTypesMap.at(typeName), *object, factory); } deserializeObjectProperties(jsonObject[keys::PROPERTIES].toObject(), *object, references, factory, structPropTypesMap); @@ -437,13 +465,13 @@ DeserializedVersion deserializeVersionNumber(const QJsonDocument& document, cons DeserializedVersion version = {ProjectDeserializationInfo::NO_VERSION, ProjectDeserializationInfo::NO_VERSION, ProjectDeserializationInfo::NO_VERSION}; if (document[jsonVersionKey].isUndefined()) { - LOG_WARNING(raco::log_system::DESERIALIZATION, "{} version is not saved in project file", whichVersion); + LOG_WARNING(log_system::DESERIALIZATION, "{} version is not saved in project file", whichVersion); } else { auto deserializedVersionNums = document[jsonVersionKey].toArray(); if (deserializedVersionNums.size() < 3) { - LOG_WARNING(raco::log_system::DESERIALIZATION, "{} version has not been saved correctly in project file - not enough version values", whichVersion); + LOG_WARNING(log_system::DESERIALIZATION, "{} version has not been saved correctly in project file - not enough version values", whichVersion); } else if (deserializedVersionNums.size() > 3) { - LOG_WARNING(raco::log_system::DESERIALIZATION, "{} version has not been saved correctly in project file - too many version values", whichVersion); + LOG_WARNING(log_system::DESERIALIZATION, "{} version has not been saved correctly in project file - too many version values", whichVersion); } std::array versionNums {&version.major, &version.minor, &version.patch}; @@ -452,7 +480,7 @@ DeserializedVersion deserializeVersionNumber(const QJsonDocument& document, cons } } - LOG_INFO(raco::log_system::DESERIALIZATION, "{} version from project file is {}.{}.{}", whichVersion, version.major, version.minor, version.patch); + LOG_INFO(log_system::DESERIALIZATION, "{} version from project file is {}.{}.{}", whichVersion, version.major, version.minor, version.patch); return version; }; @@ -501,18 +529,20 @@ QMap serializeUserTypePropertyMap(const std::map; +using translateRefFunc = std::function; -void convertObjectPropertiesIRToUser(const ReflectionInterface& dynObj, ReflectionInterface& userObj, translateRefFunc translateRef, raco::core::UserObjectFactoryInterface& factory); -void convertTablePropertiesIRToUser(const Table& src, Table& dest, translateRefFunc translateRef, raco::core::UserObjectFactoryInterface& factory); +void convertObjectPropertiesIRToUser(const ReflectionInterface& dynObj, ReflectionInterface& userObj, translateRefFunc translateRef, core::UserObjectFactoryInterface& factory); +void convertTablePropertiesIRToUser(const Table& src, Table& dest, translateRefFunc translateRef, core::UserObjectFactoryInterface& factory); +void convertArrayPropertiesIRToUser(const ArrayBase& src, ArrayBase& dest, translateRefFunc translateRef, core::UserObjectFactoryInterface& factory); -void convertPropertyAnnotationsIRToUser(const ValueBase& dynProp, ValueBase& userProp, translateRefFunc translateRef, raco::core::UserObjectFactoryInterface& factory, bool dynamicallyTyped) { + +void convertPropertyAnnotationsIRToUser(const ValueBase& dynProp, ValueBase& userProp, translateRefFunc translateRef, core::UserObjectFactoryInterface& factory, bool dynamicallyTyped) { for (auto srcAnno : dynProp.baseAnnotationPtrs()) { - auto it = std::find_if(userProp.baseAnnotationPtrs().begin(), userProp.baseAnnotationPtrs().end(), [srcAnno](const raco::data_storage::AnnotationBase* destAnno) { + auto it = std::find_if(userProp.baseAnnotationPtrs().begin(), userProp.baseAnnotationPtrs().end(), [srcAnno](const data_storage::AnnotationBase* destAnno) { return destAnno->getTypeDescription().typeName == srcAnno->getTypeDescription().typeName; }); if (it != userProp.baseAnnotationPtrs().end() && @@ -522,9 +552,11 @@ void convertPropertyAnnotationsIRToUser(const ValueBase& dynProp, ValueBase& use } } -void convertValueBaseIRToUser(const ValueBase& dynProp, ValueBase& userProp, translateRefFunc translateRef, raco::core::UserObjectFactoryInterface& factory, bool dynamicallyTyped = false) { +void convertValueBaseIRToUser(const ValueBase& dynProp, ValueBase& userProp, translateRefFunc translateRef, core::UserObjectFactoryInterface& factory, bool dynamicallyTyped = false) { if (userProp.type() == PrimitiveType::Table) { convertTablePropertiesIRToUser(dynProp.asTable(), userProp.asTable(), translateRef, factory); + } else if (userProp.type() == PrimitiveType::Array) { + convertArrayPropertiesIRToUser(dynProp.asArray(), userProp.asArray(), translateRef, factory); } else if (hasTypeSubstructure(userProp.type())) { convertObjectPropertiesIRToUser(dynProp.getSubstructure(), userProp.getSubstructure(), translateRef, factory); } else if (userProp.type() == PrimitiveType::Ref) { @@ -536,12 +568,12 @@ void convertValueBaseIRToUser(const ValueBase& dynProp, ValueBase& userProp, tra convertPropertyAnnotationsIRToUser(dynProp, userProp, translateRef, factory, dynamicallyTyped); } -void convertTablePropertiesIRToUser(const Table& src, Table& dest, translateRefFunc translateRef, raco::core::UserObjectFactoryInterface& factory) { +void convertTablePropertiesIRToUser(const Table& src, Table& dest, translateRefFunc translateRef, core::UserObjectFactoryInterface& factory) { for (size_t i = 0; i < src.size(); i++) { auto propName = src.name(i); auto typeName = src.get(i)->typeName(); - if (raco::data_storage::isPrimitiveTypeName(typeName)) { - dest.addProperty(propName, raco::data_storage::toPrimitiveType(typeName)); + if (data_storage::isPrimitiveTypeName(typeName)) { + dest.addProperty(propName, data_storage::toPrimitiveType(typeName)); } else { dest.addProperty(propName, factory.createValue(typeName)); } @@ -549,7 +581,14 @@ void convertTablePropertiesIRToUser(const Table& src, Table& dest, translateRefF } } -void convertObjectPropertiesIRToUser(const ReflectionInterface& dynObj, ReflectionInterface& userObj, translateRefFunc translateRef, raco::core::UserObjectFactoryInterface& factory) { +void convertArrayPropertiesIRToUser(const ArrayBase& src, ArrayBase& dest, translateRefFunc translateRef, core::UserObjectFactoryInterface& factory) { + dest.resize(src.size()); + for (size_t i = 0; i < src.size(); i++) { + convertValueBaseIRToUser(*src.get(i), *dest.get(i), translateRef, factory, true); + } +} + +void convertObjectPropertiesIRToUser(const ReflectionInterface& dynObj, ReflectionInterface& userObj, translateRefFunc translateRef, core::UserObjectFactoryInterface& factory) { for (size_t i = 0; i < dynObj.size(); i++) { auto propName = dynObj.name(i); convertValueBaseIRToUser(*dynObj.get(i), *userObj.get(propName), translateRef, factory); @@ -557,7 +596,7 @@ void convertObjectPropertiesIRToUser(const ReflectionInterface& dynObj, Reflecti } void convertObjectAnnotationsIRToUser(const ClassWithReflectedMembers& dynObj, ClassWithReflectedMembers& userObj, translateRefFunc translateRef, - raco::core::UserObjectFactoryInterface& factory) { + core::UserObjectFactoryInterface& factory) { for (auto anno : dynObj.annotations()) { auto userAnno = factory.createAnnotation(anno->getTypeDescription().typeName); userObj.addAnnotation(userAnno); @@ -567,17 +606,17 @@ void convertObjectAnnotationsIRToUser(const ClassWithReflectedMembers& dynObj, C } ProjectDeserializationInfo ConvertFromIRToUserTypes(const ProjectDeserializationInfoIR& deserializedIR) { - auto& userFactory{raco::user_types::UserObjectFactory::getInstance()}; + auto& userFactory{user_types::UserObjectFactory::getInstance()}; // dynamic -> static object translationB ProjectDeserializationInfo result; result.versionInfo = deserializedIR.versionInfo; - + result.migrationObjWarnings = deserializedIR.migrationObjWarnings; result.externalProjectsMap = deserializedIR.externalProjectsMap; - std::map instanceMap; + std::map instanceMap; for (const auto& obj : deserializedIR.objects) { - auto dynObj = std::dynamic_pointer_cast(obj); + auto dynObj = std::dynamic_pointer_cast(obj); auto objectID = *dynObj->objectID_; auto typeName = dynObj->getTypeDescription().typeName; @@ -596,11 +635,11 @@ ProjectDeserializationInfo ConvertFromIRToUserTypes(const ProjectDeserialization }; for (const auto& irLink : deserializedIR.links) { - result.links.emplace_back(raco::core::Link::cloneLinkWithTranslation(std::dynamic_pointer_cast(irLink), translateRef)); + result.links.emplace_back(core::Link::cloneLinkWithTranslation(std::dynamic_pointer_cast(irLink), translateRef)); } for (const auto& obj : deserializedIR.objects) { - auto dynObj = std::dynamic_pointer_cast(obj); + auto dynObj = std::dynamic_pointer_cast(obj); auto userObj = instanceMap[dynObj->objectID()]; convertObjectPropertiesIRToUser(*dynObj, *userObj, translateRef, userFactory); @@ -623,24 +662,25 @@ std::string ObjectsDeserialization::originPath() const { return (std::filesystem::path(originFolder) / originFileName).generic_string(); } -ObjectDeserialization test_helpers::deserializeObject(const std::string& json) { - auto& factory{user_types::UserObjectFactory::getInstance()}; +ObjectDeserialization test_helpers::deserializeObject(const std::string& json, core::UserObjectFactoryInterface& factory) { References references{}; return { std::dynamic_pointer_cast(deserializeTypedObject(QJsonDocument::fromJson(json.c_str()).object(), factory, references)), references}; } -std::map> makeUserTypePropertyMap() { - auto& userFactory{user_types::UserObjectFactory::getInstance()}; +std::map> makeUserTypePropertyMap(core::UserObjectFactoryInterface& objectFactory) { std::map> typesPropTypesMap; - for (const auto& [name, desc] : userFactory.getTypes()) { - auto obj = userFactory.createObject(name); + for (const auto& [name, desc] : objectFactory.getTypes()) { + auto obj = objectFactory.createObject(name); std::map propTypeMap; for (size_t i = 0; i < obj->size(); i++) { + if (obj->get(i)->query()) { + continue; + } auto propName = obj->name(i); auto propType = obj->get(i)->typeName(); propTypeMap[propName] = propType; @@ -652,7 +692,7 @@ std::map> makeUserTypePropertyMa } std::map> makeStructPropertyMap() { - auto& userFactory{raco::user_types::UserObjectFactory::getInstance()}; + auto& userFactory{user_types::UserObjectFactory::getInstance()}; std::map> structPropTypesMap; @@ -685,7 +725,7 @@ std::map> deserializeUserTypePro return typesPropTypeMap; } -std::string serializeProperty(const core::Project& project, const raco::data_storage::ValueBase& value) { +std::string serializeProperty(const core::Project& project, const data_storage::ValueBase& value) { auto base = serializeValueBase(value, true); if (base.has_value()) { QJsonObject result; @@ -725,18 +765,18 @@ std::unique_ptr deserializeProperty(const core::Project& project, con return nullptr; } - auto factory = raco::user_types::UserObjectFactory::getInstance(); + auto factory = user_types::UserObjectFactory::getInstance(); auto typeName = object[keys::TYPENAME].toString().toStdString(); auto value = std::unique_ptr(factory.createValue(typeName)); References references; - deserializeValueBase(object, *value, references, raco::user_types::UserObjectFactory::getInstance(), makeStructPropertyMap(), true); + deserializeValueBase(object, *value, references, user_types::UserObjectFactory::getInstance(), makeStructPropertyMap(), true); for (const auto& pair : references) { auto obj = project.getInstanceByID(pair.second); if (obj.get() == nullptr) { - LOG_WARNING(raco::log_system::DESERIALIZATION, "Load: referenced object not found: {}", pair.second); + LOG_WARNING(log_system::DESERIALIZATION, "Load: referenced object not found: {}", pair.second); } else { *pair.first = obj; } @@ -745,7 +785,7 @@ std::unique_ptr deserializeProperty(const core::Project& project, con return value; } -std::string serializeObjects(const std::vector& objects, const std::vector& rootObjectIDs, const std::vector& links, const std::string& originFolder, const std::string& originFilename, const std::string& originProjectID, const std::string& originProjectName, const std::map& externalProjectsMap, const std::map& originFolders, int featureLevel, bool includeVersionInfo) { +std::string serializeObjects(const std::vector& objects, const std::vector& rootObjectIDs, const std::vector& links, const std::string& originFolder, const std::string& originFilename, const std::string& originProjectID, const std::string& originProjectName, const std::map& externalProjectsMap, const std::map& originFolders, int featureLevel, bool includeVersionInfo) { QJsonObject result{}; if (includeVersionInfo) { @@ -792,8 +832,7 @@ std::string serializeObjects(const std::vector& objec return QJsonDocument{result}.toJson().toStdString(); } -std::optional deserializeObjects(const std::string& json, bool checkVersionInfo) { - auto& factory{user_types::UserObjectFactory::getInstance()}; +std::optional deserializeObjects(const std::string& json, bool checkVersionInfo, core::UserObjectFactoryInterface& factory) { ObjectsDeserialization result{}; auto document{QJsonDocument::fromJson(json.c_str())}; if (document.isNull()) { @@ -843,7 +882,7 @@ std::optional deserializeObjects(const std::string& json result.objects.push_back(deserializedObject); } for (const auto& linkJson : container.value(keys::LINKS).toArray()) { - auto deserializedLink = std::dynamic_pointer_cast(deserializeTypedObject(linkJson.toObject(), factory, result.references)); + auto deserializedLink = std::dynamic_pointer_cast(deserializeTypedObject(linkJson.toObject(), factory, result.references)); result.links.push_back(deserializedLink); } return result; @@ -854,11 +893,9 @@ QJsonDocument serializeProject(const std::unordered_map(deserializeTypedObject(instance.toObject(), factory, references, userPropTypeMap, structTypeMap)); + auto obj = std::dynamic_pointer_cast(deserializeTypedObject(instance.toObject(), factory, references, userPropTypeMap, structTypeMap)); deserializedProjectInfo.objects.push_back(obj); } const auto links = migratedJson[keys::LINKS].toArray(); deserializedProjectInfo.links.reserve(links.size()); for (const auto& linkJson: links) { - auto link = std::dynamic_pointer_cast(deserializeTypedObject(linkJson.toObject(), factory, references, userPropTypeMap, structTypeMap)); + auto link = std::dynamic_pointer_cast(deserializeTypedObject(linkJson.toObject(), factory, references, userPropTypeMap, structTypeMap)); deserializedProjectInfo.links.push_back(link); } // Restore references - std::map instanceMap; + std::map instanceMap; for (auto& d : deserializedProjectInfo.objects) { - auto obj = std::dynamic_pointer_cast(d); + auto obj = std::dynamic_pointer_cast(d); instanceMap[obj->objectID()] = obj; } for (const auto& pair : references) { if (instanceMap.find(pair.second) != instanceMap.end()) { *pair.first = instanceMap.at(pair.second); } else { - LOG_WARNING(raco::log_system::DESERIALIZATION, "Load: referenced object not found: {}", pair.second); + LOG_WARNING(log_system::DESERIALIZATION, "Load: referenced object not found: {}", pair.second); } } for (const auto& obj : deserializedProjectInfo.objects) { - auto dynObj = std::dynamic_pointer_cast(obj); + auto dynObj = std::dynamic_pointer_cast(obj); dynObj->onAfterDeserialization(); } @@ -960,13 +1001,18 @@ ProjectDeserializationInfoIR deserializeProjectToIR(const QJsonDocument& documen } ProjectDeserializationInfo deserializeProject(const QJsonDocument& document, const std::string& filename) { - auto deserializedIR{deserializeProjectToIR(document, filename)}; - - // run new migration code - auto& factory{raco::serialization::proxy::ProxyObjectFactory::getInstance()}; - migrateProject(deserializedIR, factory); + try { + auto deserializedIR{deserializeProjectToIR(document, filename)}; + + // run new migration code + auto& factory{serialization::proxy::ProxyObjectFactory::getInstance()}; + migrateProject(deserializedIR, factory); - return ConvertFromIRToUserTypes(deserializedIR); + return ConvertFromIRToUserTypes(deserializedIR); + } catch (std::exception&) { + throw std::runtime_error(fmt::format("Project file format invalid.")); + } + return {}; } } // namespace raco::serialization diff --git a/datamodel/libCore/src/TagDataCache.cpp b/datamodel/libCore/src/TagDataCache.cpp index 5003407b..ab245713 100644 --- a/datamodel/libCore/src/TagDataCache.cpp +++ b/datamodel/libCore/src/TagDataCache.cpp @@ -62,12 +62,9 @@ void TagDataCache::initCache(std::string_view referencingProperty, std::string_v addReferencingObject(tag, instance); } } - core::ValueHandle referencingPropHandle{referencingObject, {std::string(referencingProperty)}}; } - if (tagType == TagType::UserTags || core::Queries::isUserTypeInTypeList(instance, TaggedObjectTypeList{})) { - core::Table const& tagContainer = instance->get(std::string(tagProperty))->asTable(); - for (auto tagIndex = 0; tagIndex < tagContainer.size(); ++tagIndex) { - std::string const& tag = tagContainer.get(tagIndex)->asString(); + if ((tagType == TagType::UserTags || core::Queries::isUserTypeInTypeList(instance, TaggedObjectTypeList{})) && instance->hasProperty(std::string(tagProperty))) { + for (const auto& tag : instance->get(std::string(tagProperty))->asTable().asVector()) { addTaggedObject(tag, instance); } } @@ -112,8 +109,7 @@ std::set TagDataCache::allRenderPassesForObjectWithTags } while (!newLayers.empty()); auto rps = core::Queries::filterByType(project_->instances()); for (auto const& rp : rps) { - auto rprls = {rp->layer0_.asRef(), rp->layer1_.asRef(), rp->layer2_.asRef(), rp->layer3_.asRef(), - rp->layer4_.asRef(), rp->layer5_.asRef(), rp->layer6_.asRef(), rp->layer7_.asRef()}; + auto rprls = rp->layers_->asVector(); const bool isRenderPassUsingTags = std::any_of(rprls.begin(), rprls.end(), [&layers = std::as_const(allLayers), obj](user_types::SEditorObject const& rl) { return rl != nullptr && (rl == obj || layers.find(rl->as()) != layers.end()); }); diff --git a/datamodel/libCore/src/Undo.cpp b/datamodel/libCore/src/Undo.cpp index d904e5ac..85b7ae18 100644 --- a/datamodel/libCore/src/Undo.cpp +++ b/datamodel/libCore/src/Undo.cpp @@ -20,6 +20,7 @@ #include "data_storage/ReflectionInterface.h" #include "data_storage/Table.h" #include "data_storage/Value.h" +#include "data_storage/Array.h" #include @@ -28,6 +29,10 @@ namespace raco::core { using namespace raco::data_storage; void UndoHelpers::updateSingleValue(const ValueBase *src, ValueBase *dest, ValueHandle destHandle, translateRefFunc translateRef, DataChangeRecorder *outChanges, bool invokeHandler) { + if (dest->query()) { + return; + } + PrimitiveType type = src->type(); bool changed = false; if (type == PrimitiveType::Ref) { @@ -52,6 +57,11 @@ void UndoHelpers::updateSingleValue(const ValueBase *src, ValueBase *dest, Value } else { updateTableByName(&src->asTable(), &dest->asTable(), destHandle, translateRef, outChanges, invokeHandler); } + } else if (type == PrimitiveType::Array) { + assert(ValueBase::classesEqual(*src, *dest)); + updateArray(&src->asArray(), &dest->asArray(), destHandle, translateRef, outChanges, invokeHandler); + // Assume annotation data doesn't contain Ref type properties. + dest->copyAnnotationData(*src); } else if (type == PrimitiveType::Struct) { assert(ValueBase::classesEqual(*src, *dest)); updateStruct(&src->asStruct(), &dest->asStruct(), destHandle, translateRef, outChanges, invokeHandler); @@ -67,7 +77,7 @@ void UndoHelpers::updateSingleValue(const ValueBase *src, ValueBase *dest, Value } } -void UndoHelpers::callOnBeforeRemoveReferenceHandler(raco::data_storage::Table *dest, const size_t &index, raco::core::ValueHandle &destHandle) { +void UndoHelpers::callOnBeforeRemoveReferenceHandler(ReflectionInterface *dest, const size_t &index, core::ValueHandle &destHandle) { auto oldValue = dest->get(index); if (oldValue->type() == PrimitiveType::Ref) { if (auto oldObj = oldValue->asRef()) { @@ -106,6 +116,32 @@ void UndoHelpers::updateTableAsArray(const Table *src, Table *dest, ValueHandle } } +void UndoHelpers::updateArray(const ArrayBase* src, ArrayBase* dest, ValueHandle destHandle, translateRefFunc translateRef, DataChangeRecorder* outChanges, bool invokeHandler) { + bool changed = false; + if (ReflectionInterface::compare(*src, *dest, translateRef)) { + return; + } + + if (invokeHandler && destHandle) { + for (size_t index{0}; index < dest->size(); index++) { + UndoHelpers::callOnBeforeRemoveReferenceHandler(dest, index, destHandle); + } + } + if (dest->size() > 0) { + dest->resize(0); + changed = true; + } + + for (size_t index{0}; index < src->size(); index++) { + dest->addProperty(src->get(index)->clone(&translateRef)); + changed = true; + } + + if (changed && outChanges && destHandle) { + outChanges->recordValueChanged(destHandle); + } +} + void UndoHelpers::updateStruct(const ClassWithReflectedMembers *src, ClassWithReflectedMembers *dest, ValueHandle destHandle, translateRefFunc translateRef, DataChangeRecorder *outChanges, bool invokeHandler) { for (size_t index{0}; index < src->size(); index++) { std::string name = src->name(index); @@ -199,7 +235,7 @@ void UndoHelpers::updateEditorObject(const EditorObject *src, SEditorObject dest for (size_t index = 0; index < src->size(); index++) { std::string name = src->name(index); assert(dest->hasProperty(name)); - if (!excludeIf(name)) { + if (!excludeIf(name) && !dest->query()) { assert(ValueBase::classesEqual(*dest->get(name), *src->get(name))); UndoHelpers::updateSingleValue(src->get(name), dest->get(name), ValueHandle(dest, {index}), translateRef, outChanges, invokeHandler); @@ -476,6 +512,10 @@ void UndoStack::endCompositeCommand(const std::string &description, bool abort) } } +int UndoStack::depth() const { + return depth_; +} + size_t UndoStack::size() const { return stack_.size(); } diff --git a/datamodel/libCore/tests/CMakeLists.txt b/datamodel/libCore/tests/CMakeLists.txt index 2e23bcd2..bf570ecf 100644 --- a/datamodel/libCore/tests/CMakeLists.txt +++ b/datamodel/libCore/tests/CMakeLists.txt @@ -108,7 +108,9 @@ raco_package_add_test_resources( expectations/LuaScriptWithAnnotatedDouble.json expectations/LuaScriptWithURI.json expectations/LuaScriptLinkedToNode.json + expectations/Arrays.json + testData/cube.gltf testData/duck.glb testData/in-float.lua testData/in-struct.lua @@ -116,6 +118,8 @@ raco_package_add_test_resources( testData/in-specific-prop-names.lua testData/float.lua testData/ToyCar.gltf + testData/basic.vert + testData/basic.frag testData/uniform-types-vert.glsl testData/uniform-types-frag.glsl testData/simple_texture.frag @@ -170,6 +174,15 @@ raco_package_add_test_resources( migrationTestData/V51.rca migrationTestData/V51_link_vec_struct.rca migrationTestData/V52.rca + migrationTestData/V54.rca + migrationTestData/V54-rendertarget-base.rca + migrationTestData/V54-rendertarget-extref.rca + migrationTestData/V54-rendertarget-extref-keepalive.rca + migrationTestData/V55.rca + migrationTestData/V57.rca + migrationTestData/V58.rca + migrationTestData/V59.rca + migrationTestData/V60.rca migrationTestData/version-current.rca ) add_compile_definitions(libSerialization_test PRIVATE CMAKE_CURRENT_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/datamodel/libCore/tests/CommandInterface_test.cpp b/datamodel/libCore/tests/CommandInterface_test.cpp index a93d4a15..b08910df 100644 --- a/datamodel/libCore/tests/CommandInterface_test.cpp +++ b/datamodel/libCore/tests/CommandInterface_test.cpp @@ -362,6 +362,19 @@ TEST_F(CommandInterfaceTest, set_fail_prefab_instance_child) { EXPECT_THROW(commandInterface.set({inst_node, &Node::visibility_}, false), std::runtime_error); } +TEST_F(CommandInterfaceTest, set_volatile_prefab_instance_child) { + auto prefab = create("prefab"); + auto node = create("node", prefab); + + auto inst = create_prefabInstance("inst", prefab); + auto inst_node = inst->children_->get(0)->asRef()->as(); + + EXPECT_EQ(*inst_node->editorVisibility_, true); + + commandInterface.set({inst_node, &Node::editorVisibility_}, false); + EXPECT_EQ(*inst_node->editorVisibility_, false); +} + TEST_F(CommandInterfaceTest, set_int_fail_invalid_enum) { auto material = create("mat"); @@ -515,7 +528,7 @@ TEST_F(CommandInterfaceTest, move_fail_insertion_index_invalid_to_root) { EXPECT_THROW(commandInterface.moveScenegraphChildren({node1}, nullptr, 3), std::runtime_error); } -TEST_F(CommandInterfaceTest, addLink_fail_no_start) { +TEST_F(CommandInterfaceTest, addLink_fail_no_start_object) { auto node = create("node"); auto lua = create_lua("lua", "scripts/types-scalar.lua"); @@ -523,7 +536,7 @@ TEST_F(CommandInterfaceTest, addLink_fail_no_start) { EXPECT_THROW(commandInterface.addLink({lua, {"outputs", "ovector3f"}}, {node, {"translation"}}), std::runtime_error); } -TEST_F(CommandInterfaceTest, addLink_fail_no_end) { +TEST_F(CommandInterfaceTest, addLink_fail_no_end_object) { auto node = create("node"); auto lua = create_lua("lua", "scripts/types-scalar.lua"); @@ -531,6 +544,21 @@ TEST_F(CommandInterfaceTest, addLink_fail_no_end) { EXPECT_THROW(commandInterface.addLink({lua, {"outputs", "ovector3f"}}, {node, {"translation"}}), std::runtime_error); } + +TEST_F(CommandInterfaceTest, addLink_fail_no_start_property) { + auto node = create("node"); + auto lua = create_lua("lua", "scripts/types-scalar.lua"); + + EXPECT_THROW(commandInterface.addLink({lua, {"translation"}}, {node, {"translation"}}), std::runtime_error); +} + +TEST_F(CommandInterfaceTest, addLink_fail_no_end_property) { + auto node = create("node"); + auto lua = create_lua("lua", "scripts/types-scalar.lua"); + + EXPECT_THROW(commandInterface.addLink({lua, {"outputs", "ovector3f"}}, {node, {"inputs", "float"}}), std::runtime_error); +} + TEST_F(CommandInterfaceTest, addLink_fail_loop) { auto lua = create_lua("lua", "scripts/types-scalar.lua"); EXPECT_THROW(commandInterface.addLink({lua, {"outputs", "ofloat"}}, {lua, {"inputs", "float"}}), std::runtime_error); @@ -603,8 +631,8 @@ TEST_F(CommandInterfaceTest, removeLink_fail_end_object_readonly) { auto node = create("node", prefab); auto inst = create_prefabInstance("inst", prefab); - auto inst_node = raco::select(inst->children_->asVector(), "node"); - auto inst_lua = raco::select(inst->children_->asVector(), "lua"); + auto inst_node = raco::select(inst->children_->asVector(), "node"); + auto inst_lua = raco::select(inst->children_->asVector(), "lua"); auto [sprop, eprop] = link(lua, {"outputs", "ovector3f"}, node, {"translation"}); EXPECT_THROW(commandInterface.removeLink({inst_node, {"translation"}}), std::runtime_error); @@ -666,4 +694,34 @@ TEST_F(CommandInterfaceTest, paste_invalid_json) { )___"; EXPECT_THROW(commandInterface.pasteObjects(data, nullptr), std::runtime_error); -} \ No newline at end of file +} + +TEST_F(CommandInterfaceTest, array_resize_fail_no_array) { + auto obj = create("obj"); + EXPECT_THROW(commandInterface.resizeArray({obj, &ObjectWithArrays::table_}, 2), std::runtime_error); +} + +TEST_F(CommandInterfaceTest, array_resize_fail_array_semantic_anno) { + auto obj = create("obj"); + EXPECT_THROW(commandInterface.resizeArray({obj, &ObjectWithArrays::array_ref_array_semantic_}, 2), std::runtime_error); +} + +TEST_F(CommandInterfaceTest, array_resize_fail_editorobject_children) { + auto obj = create("node"); + EXPECT_THROW(commandInterface.resizeArray({obj, &EditorObject::children_}, 2), std::runtime_error); +} + +TEST_F(CommandInterfaceTest, array_resize_fail_not_resizable) { + auto obj = create("obj"); + EXPECT_THROW(commandInterface.resizeArray({obj, &ObjectWithArrays::array_ref_}, 2), std::runtime_error); +} + +TEST_F(CommandInterfaceTest, array_resize_grow) { + auto obj = create("obj"); + + commandInterface.resizeArray({obj, &ObjectWithArrays::array_ref_resizable_}, 2); + + EXPECT_EQ(obj->array_ref_resizable_->size(), 2); + EXPECT_EQ(**obj->array_ref_resizable_->get(0), nullptr); + EXPECT_EQ(**obj->array_ref_resizable_->get(1), nullptr); +} diff --git a/datamodel/libCore/tests/Context_test.cpp b/datamodel/libCore/tests/Context_test.cpp index 0bcd8dd6..8ac4a4ca 100644 --- a/datamodel/libCore/tests/Context_test.cpp +++ b/datamodel/libCore/tests/Context_test.cpp @@ -100,7 +100,7 @@ void print_recursive(ValueHandle& handle, unsigned level = 0) { TEST_F(ContextTest, Complex) { std::shared_ptr script{new MockLuaScript("foo")}; - EXPECT_EQ(script->size(), 6); + EXPECT_EQ(script->size(), 5); double val = *ValueHandle(script, &MockLuaScript::inputs_).get("in_array_struct")[1].get("bar").asVec3f().y; EXPECT_EQ(val, 0); @@ -113,9 +113,10 @@ TEST_F(ContextTest, Complex) { TEST_F(ContextTest, rendertarget_set_remove_multi_ref) { auto buffer = create("buffer"); auto target = create("target"); + context.resizeArray({target, &RenderTarget::buffers_}, 2); - ValueHandle buffer_0_handle{target, &RenderTarget::buffer0_}; - ValueHandle buffer_1_handle{target, &RenderTarget::buffer1_}; + ValueHandle buffer_0_handle{target, {"buffers", "1"}}; + ValueHandle buffer_1_handle{target, {"buffers", "2"}}; EXPECT_EQ(buffer->referencesToThis().size(), 0); @@ -723,7 +724,7 @@ TEST_F(ContextTest, pasteInvalidJsonSchema) { TEST_F(ContextTest, copyAndPasteKeepAbsolutePath) { auto absoluteDuckPath{(test_path() / "testData" / "Duck.glb").string()}; - const auto sMesh{context.createObject(raco::user_types::Mesh::typeDescription.typeName, "mesh", "mesh_id")}; + const auto sMesh{context.createObject(user_types::Mesh::typeDescription.typeName, "mesh", "mesh_id")}; auto uri{absoluteDuckPath}; context.set({sMesh, {"uri"}}, uri); @@ -743,7 +744,7 @@ TEST_F(ContextTest, copyAndPasteTurnRelativePathFromDifferentDriveToAbsolute) { context.project()->setCurrentPath((test_path() / "proj.file").string()); auto absoluteDuckPath{(test_path() / "testData" / "Duck.glb").string()}; std::string relativeDuckPath{"testData/Duck.glb"}; - const auto sMesh{context.createObject(raco::user_types::Mesh::typeDescription.typeName, "mesh", "mesh_id")}; + const auto sMesh{context.createObject(user_types::Mesh::typeDescription.typeName, "mesh", "mesh_id")}; context.set({sMesh, {"uri"}}, relativeDuckPath); auto clipboardContent = context.copyObjects({sMesh}); @@ -757,14 +758,14 @@ TEST_F(ContextTest, copyAndPasteTurnRelativePathFromDifferentDriveToAbsolute) { TEST_F(ContextTest, copyAndPasteRerootRelativePathHierarchyDown) { context.project()->setCurrentPath((test_path() / "proj.file").string()); auto relativeDuckPath{(test_relative_path() / "testData" / "Duck.glb").string()}; - const auto sMesh{context.createObject(raco::user_types::Mesh::typeDescription.typeName, "mesh", "mesh_id")}; + const auto sMesh{context.createObject(user_types::Mesh::typeDescription.typeName, "mesh", "mesh_id")}; auto uri{relativeDuckPath}; context.set({sMesh, {"uri"}}, uri); auto clipboardContent = context.copyObjects({ sMesh }); context.project()->setCurrentPath((test_path() / "newProject" / "proj.file").string()); auto pasteResult = context.pasteObjects(clipboardContent); - auto newRelativeDuckPath{raco::utils::u8path("..") / relativeDuckPath}; + auto newRelativeDuckPath{utils::u8path("..") / relativeDuckPath}; ASSERT_EQ(pasteResult.front()->get("uri")->asString(), newRelativeDuckPath); } @@ -772,14 +773,14 @@ TEST_F(ContextTest, copyAndPasteRerootRelativePathHierarchyDown) { TEST_F(ContextTest, copyAndPasteRerootRelativePathHierarchyUp) { context.project()->setCurrentPath((test_path() / "newProject" / "proj.file").string()); auto relativeDuckPath{(test_relative_path() / "testData" / "Duck.glb").string()}; - const auto sMesh{context.createObject(raco::user_types::Mesh::typeDescription.typeName, "mesh", "mesh_id")}; + const auto sMesh{context.createObject(user_types::Mesh::typeDescription.typeName, "mesh", "mesh_id")}; auto uri{relativeDuckPath}; context.set({sMesh, {"uri"}}, uri); auto clipboardContent = context.copyObjects({ sMesh }); context.project()->setCurrentPath((test_path() / "proj.file").string()); auto pasteResult = context.pasteObjects(clipboardContent); - auto newRelativeDuckPath{raco::utils::u8path("newProject") / relativeDuckPath}; + auto newRelativeDuckPath{utils::u8path("newProject") / relativeDuckPath}; ASSERT_EQ(pasteResult.front()->get("uri")->asString(), newRelativeDuckPath); } @@ -965,7 +966,7 @@ TEST_F(ContextTest, cutAndPasteNodeUniqueName) { TEST_F(ContextTest, queryLinkConnectedToObjectsReturnsNoDuplicateLinks) { auto objs{raco::createLinkedScene(context, test_relative_path())}; - auto totalLinks = raco::core::Queries::getLinksConnectedToObjects( + auto totalLinks = core::Queries::getLinksConnectedToObjects( *context.project(), SEditorObjectSet{context.project()->instances().begin(), context.project()->instances().end()}, true, true); ASSERT_EQ(totalLinks.size(), 1); @@ -1047,7 +1048,7 @@ end auto mock = context.createObject(ObjectWithTableProperty::typeDescription.typeName, "mock"); - raco::data_storage::Table tags; + data_storage::Table tags; tags.addProperty("main", new Property(1, {})); context.set({mock, &ObjectWithTableProperty::renderableTags_}, tags); @@ -1073,10 +1074,10 @@ TEST_F(ContextTest, move_scenegraph_removes_incoming_ref) { auto camera = context.createObject(PerspectiveCamera::typeDescription.typeName, "camera"); auto renderpass = context.createObject(RenderPass::typeDescription.typeName, "renderpass"); context.set({renderpass, &RenderPass::camera_}, camera); - ASSERT_EQ(raco::core::ValueHandle(renderpass, &RenderPass::camera_).asRef(), camera); + ASSERT_EQ(core::ValueHandle(renderpass, &RenderPass::camera_).asRef(), camera); context.moveScenegraphChildren({camera}, prefab); - ASSERT_EQ(raco::core::ValueHandle(renderpass, &RenderPass::camera_).asRef(), SEditorObject()); + ASSERT_EQ(core::ValueHandle(renderpass, &RenderPass::camera_).asRef(), SEditorObject()); } TEST_F(ContextTest, move_scenegraph_removes_incoming_ref_to_child) { @@ -1086,10 +1087,10 @@ TEST_F(ContextTest, move_scenegraph_removes_incoming_ref_to_child) { context.moveScenegraphChildren({camera}, node); auto renderpass = context.createObject(RenderPass::typeDescription.typeName, "renderpass"); context.set({renderpass, &RenderPass::camera_}, camera); - ASSERT_EQ(raco::core::ValueHandle(renderpass, &RenderPass::camera_).asRef(), camera); + ASSERT_EQ(core::ValueHandle(renderpass, &RenderPass::camera_).asRef(), camera); context.moveScenegraphChildren({node}, prefab); - ASSERT_EQ(raco::core::ValueHandle(renderpass, &RenderPass::camera_).asRef(), SEditorObject()); + ASSERT_EQ(core::ValueHandle(renderpass, &RenderPass::camera_).asRef(), SEditorObject()); } TEST_F(ContextTest, move_scenegraph_removes_outgoing_ref) { @@ -1097,10 +1098,10 @@ TEST_F(ContextTest, move_scenegraph_removes_outgoing_ref) { auto meshNode = context.createObject(MeshNode::typeDescription.typeName, "meshNode"); auto skin = context.createObject(Skin::typeDescription.typeName, "skin"); context.set(ValueHandle(skin, &Skin::targets_)[0], meshNode); - ASSERT_EQ(raco::core::ValueHandle(skin, &Skin::targets_)[0].asRef(), meshNode); + ASSERT_EQ(core::ValueHandle(skin, &Skin::targets_)[0].asRef(), meshNode); context.moveScenegraphChildren({skin}, prefab); - ASSERT_EQ(raco::core::ValueHandle(skin, &Skin::targets_)[0].asRef(), SEditorObject()); + ASSERT_EQ(core::ValueHandle(skin, &Skin::targets_)[0].asRef(), SEditorObject()); } TEST_F(ContextTest, move_scenegraph_removes_outgoing_ref_from_child) { @@ -1110,10 +1111,10 @@ TEST_F(ContextTest, move_scenegraph_removes_outgoing_ref_from_child) { auto skin = context.createObject(Skin::typeDescription.typeName, "skin"); context.moveScenegraphChildren({skin}, node); context.set(ValueHandle(skin, &Skin::targets_)[0], meshNode); - ASSERT_EQ(raco::core::ValueHandle(skin, &Skin::targets_)[0].asRef(), meshNode); + ASSERT_EQ(core::ValueHandle(skin, &Skin::targets_)[0].asRef(), meshNode); context.moveScenegraphChildren({node}, prefab); - ASSERT_EQ(raco::core::ValueHandle(skin, &Skin::targets_)[0].asRef(), SEditorObject()); + ASSERT_EQ(core::ValueHandle(skin, &Skin::targets_)[0].asRef(), SEditorObject()); } TEST_F(ContextTest, move_scenegraph_keeps_outgoing_ref) { @@ -1121,20 +1122,20 @@ TEST_F(ContextTest, move_scenegraph_keeps_outgoing_ref) { auto meshNode = context.createObject(MeshNode::typeDescription.typeName, "meshNode"); auto mesh = context.createObject(Mesh::typeDescription.typeName, "mesh"); context.set({meshNode, &MeshNode::mesh_}, mesh); - ASSERT_EQ(raco::core::ValueHandle(meshNode, &MeshNode::mesh_).asRef(), mesh); + ASSERT_EQ(core::ValueHandle(meshNode, &MeshNode::mesh_).asRef(), mesh); context.moveScenegraphChildren({meshNode}, prefab); - ASSERT_EQ(raco::core::ValueHandle(meshNode, &MeshNode::mesh_).asRef(), mesh); + ASSERT_EQ(core::ValueHandle(meshNode, &MeshNode::mesh_).asRef(), mesh); } TEST_F(ContextTest, move_scenegraph_breaks_ref_loop) { auto meshNode = context.createObject(MeshNode::typeDescription.typeName, "meshNode"); auto skin = context.createObject(Skin::typeDescription.typeName, "skin"); context.set(ValueHandle(skin, &Skin::targets_)[0], meshNode); - ASSERT_EQ(raco::core::ValueHandle(skin, &Skin::targets_)[0].asRef(), meshNode); + ASSERT_EQ(core::ValueHandle(skin, &Skin::targets_)[0].asRef(), meshNode); context.moveScenegraphChildren({skin}, meshNode); - ASSERT_EQ(raco::core::ValueHandle(skin, &Skin::targets_)[0].asRef(), SEditorObject()); + ASSERT_EQ(core::ValueHandle(skin, &Skin::targets_)[0].asRef(), SEditorObject()); } TEST_F(ContextTest, valid_refs_skin_to_node_loop) { @@ -1146,7 +1147,128 @@ TEST_F(ContextTest, valid_refs_skin_to_node_loop) { context.moveScenegraphChildren({skin_child}, meshNode); context.set(ValueHandle(skin_child, &Skin::targets_)[0], meshNode); - ASSERT_TRUE(raco::core::Queries::findAllValidReferenceTargets(project, ValueHandle(skin_child, &Skin::targets_)[0]).empty()); - ASSERT_EQ(raco::core::Queries::findAllValidReferenceTargets(project, ValueHandle(skin_toplevel, &Skin::targets_)[0]), + ASSERT_TRUE(core::Queries::findAllValidReferenceTargets(project, ValueHandle(skin_child, &Skin::targets_)[0]).empty()); + ASSERT_EQ(core::Queries::findAllValidReferenceTargets(project, ValueHandle(skin_toplevel, &Skin::targets_)[0]), std::vector({meshNode})); -} \ No newline at end of file +} + +TEST_F(ContextTest, set_array_ref_type_mismatch) { + auto node_1 = create("node1"); + auto node_2 = create("node2"); + + Array aref_nodes; + *aref_nodes.addProperty() = node_1; + *aref_nodes.addProperty() = node_2; + + auto obj = create("obj"); + ValueHandle arrayHandle{obj, &ObjectWithArrays::array_ref_}; + + EXPECT_THROW(context.set(arrayHandle, aref_nodes), std::runtime_error); +} + +TEST_F(ContextTest, delete_objects_removes_tableArray_properties) { + auto refTarget = create("foo"); + auto refSource = create("sourceObject"); + + context.addProperty({refSource, &ObjectWithTableProperty::t_}, "ref", std::make_unique>(refTarget)); + context.addProperty({refSource, &ObjectWithTableProperty::array_} , "ref", std::make_unique>(refTarget)); + + EXPECT_EQ(refSource->array_->size(), 1); + EXPECT_EQ(refSource->array_->get(0)->asRef(), refTarget); + + EXPECT_EQ(refSource->t_->size(), 1); + EXPECT_EQ(refSource->t_->get(0)->asRef(), refTarget); + + context.deleteObjects({refTarget}); + + EXPECT_EQ(refSource->array_->size(), 0); + + EXPECT_EQ(refSource->t_->size(), 1); + EXPECT_EQ(refSource->t_->get(0)->asRef(), nullptr); +} + +TEST_F(ContextTest, delete_objects_removes_array_properties) { + auto node_1 = create("node1"); + auto node_2 = create("node2"); + + Array aref_nodes; + *aref_nodes.addProperty() = node_1; + *aref_nodes.addProperty() = node_2; + + auto obj = create("obj"); + + context.set({obj, &ObjectWithArrays::array_ref_} , aref_nodes); + context.set({obj, &ObjectWithArrays::array_ref_array_semantic_} , aref_nodes); + + EXPECT_TRUE(*obj->array_ref_ == aref_nodes); + EXPECT_TRUE(*obj->array_ref_array_semantic_ == aref_nodes); + + context.deleteObjects({node_2}); + + EXPECT_EQ(obj->array_ref_->size(), 2); + EXPECT_EQ(**obj->array_ref_->get(0), node_1); + EXPECT_EQ(**obj->array_ref_->get(1), nullptr); + + EXPECT_EQ(obj->array_ref_array_semantic_->size(), 1); + EXPECT_EQ(**obj->array_ref_array_semantic_->get(0), node_1); +} + +TEST_F(ContextTest, resize_array_grow) { + auto node_1 = create("node1"); + + Array aref_nodes; + *aref_nodes.addProperty() = node_1; + + auto obj = create("obj"); + + context.set({obj, &ObjectWithArrays::array_ref_}, aref_nodes); + EXPECT_TRUE(*obj->array_ref_ == aref_nodes); + + ASSERT_EQ(node_1->referencesToThis().size(), 1); + EXPECT_EQ(node_1->referencesToThis().count(obj), 1); + + EXPECT_EQ(obj->array_ref_->size(), 1); + EXPECT_EQ(**obj->array_ref_->get(0), node_1); + + context.resizeArray({ obj, &ObjectWithArrays::array_ref_ }, 2); + + ASSERT_EQ(node_1->referencesToThis().size(), 1); + EXPECT_EQ(node_1->referencesToThis().count(obj), 1); + + EXPECT_EQ(obj->array_ref_->size(), 2); + EXPECT_EQ(**obj->array_ref_->get(0), node_1); + EXPECT_EQ(**obj->array_ref_->get(1), nullptr); +} + + +TEST_F(ContextTest, resize_array_shrink) { + auto node_1 = create("node1"); + auto node_2 = create("node2"); + + Array aref_nodes; + *aref_nodes.addProperty() = node_1; + *aref_nodes.addProperty() = node_2; + + auto obj = create("obj"); + + context.set({obj, &ObjectWithArrays::array_ref_}, aref_nodes); + EXPECT_TRUE(*obj->array_ref_ == aref_nodes); + + ASSERT_EQ(node_1->referencesToThis().size(), 1); + EXPECT_EQ(node_1->referencesToThis().count(obj), 1); + ASSERT_EQ(node_2->referencesToThis().size(), 1); + EXPECT_EQ(node_2->referencesToThis().count(obj), 1); + + EXPECT_EQ(obj->array_ref_->size(), 2); + EXPECT_EQ(**obj->array_ref_->get(0), node_1); + EXPECT_EQ(**obj->array_ref_->get(1), node_2); + + context.resizeArray({obj, &ObjectWithArrays::array_ref_}, 1); + + ASSERT_EQ(node_1->referencesToThis().size(), 1); + EXPECT_EQ(node_1->referencesToThis().count(obj), 1); + ASSERT_EQ(node_2->referencesToThis().size(), 0); + + EXPECT_EQ(obj->array_ref_->size(), 1); + EXPECT_EQ(**obj->array_ref_->get(0), node_1); +} diff --git a/datamodel/libCore/tests/Datamodel_test.cpp b/datamodel/libCore/tests/Datamodel_test.cpp index c8992560..e599daa8 100644 --- a/datamodel/libCore/tests/Datamodel_test.cpp +++ b/datamodel/libCore/tests/Datamodel_test.cpp @@ -41,7 +41,7 @@ TEST_F(DataModelTest, check_user_type_property_annotations) { } if (value->query()) { - EXPECT_TRUE(value->type() == PrimitiveType::Table) << fmt::format("{}:{} has ArraySemanticAnnotation but is not of type Table", name, object->name(index)); + EXPECT_TRUE(value->type() == PrimitiveType::Table || value->type() == PrimitiveType::Array) << fmt::format("{}:{} has ArraySemanticAnnotation but is not of type Table or Array", name, object->name(index)); } if (value->query()) { @@ -57,7 +57,7 @@ TEST_F(DataModelTest, check_user_type_property_annotations) { } if (value->query()) { - EXPECT_TRUE(value->type() == PrimitiveType::Ref) << fmt::format("{}:{} has ExpectEmptyReference but is not of type Ref", name, object->name(index)); + EXPECT_TRUE(value->type() == PrimitiveType::Ref || value->type() == PrimitiveType::Array && value->asArray().elementType() == PrimitiveType::Ref) << fmt::format("{}:{} has ExpectEmptyReference but is not of type Ref or Array", name, object->name(index)); } // These rules ensure that checking the feature level in the LinkEndAnnotation is sufficient to ensure linkability. diff --git a/datamodel/libCore/tests/Deserialization_test.cpp b/datamodel/libCore/tests/Deserialization_test.cpp index 7632c594..afbc8090 100644 --- a/datamodel/libCore/tests/Deserialization_test.cpp +++ b/datamodel/libCore/tests/Deserialization_test.cpp @@ -26,22 +26,32 @@ using namespace raco::user_types; struct DeserializationTest : public TestEnvironmentCore { + DeserializationTest() : TestEnvironmentCore(&TestObjectFactory::getInstance()) { + } + + serialization::ObjectDeserialization deserializeObject(const std::string& fileName) { + return serialization::test_helpers::deserializeObject(utils::file::read(test_path() / "expectations" / fileName), *context.objectFactory()); + } + + std::optional deserializeObjects(const std::string& fileName) { + return serialization::deserializeObjects(utils::file::read(test_path() / "expectations" / fileName), false, *context.objectFactory()); + } }; TEST_F(DeserializationTest, deserializeNode) { - auto result = raco::serialization::test_helpers::deserializeObject(raco::utils::file::read((test_path() / "expectations" / "Node.json").string())); + auto result = serialization::test_helpers::deserializeObject(utils::file::read((test_path() / "expectations" / "Node.json").string())); - ASSERT_EQ(raco::user_types::Node::typeDescription.typeName, result.object->getTypeDescription().typeName); + ASSERT_EQ(user_types::Node::typeDescription.typeName, result.object->getTypeDescription().typeName); SNode sNode{std::dynamic_pointer_cast(result.object)}; ASSERT_EQ(sNode->objectID(), "node_id"); ASSERT_EQ(sNode->objectName(), "node"); - ASSERT_EQ(100.0, *sNode->scaling_->z.staticQuery>().max_); + ASSERT_EQ(100.0, *sNode->scaling_->z.staticQuery>().max_); } TEST_F(DeserializationTest, deserializeNodeRotated) { - auto result = raco::serialization::test_helpers::deserializeObject( - raco::utils::file::read((test_path() / "expectations" / "NodeRotated.json").string())); - ASSERT_EQ(raco::user_types::Node::typeDescription.typeName, result.object->getTypeDescription().typeName); + auto result = serialization::test_helpers::deserializeObject( + utils::file::read((test_path() / "expectations" / "NodeRotated.json").string())); + ASSERT_EQ(user_types::Node::typeDescription.typeName, result.object->getTypeDescription().typeName); SNode sNode{std::dynamic_pointer_cast(result.object)}; ASSERT_EQ(*sNode->rotation_->x, 90.0); ASSERT_EQ(*sNode->rotation_->y, -90.0); @@ -49,19 +59,19 @@ TEST_F(DeserializationTest, deserializeNodeRotated) { } TEST_F(DeserializationTest, deserializeNodeWithAnnotations) { - auto result = raco::serialization::test_helpers::deserializeObject( - raco::utils::file::read((test_path() / "expectations" / "NodeWithAnnotations.json").string())); - ASSERT_EQ(raco::user_types::Node::typeDescription.typeName, result.object->getTypeDescription().typeName); + auto result = serialization::test_helpers::deserializeObject( + utils::file::read((test_path() / "expectations" / "NodeWithAnnotations.json").string())); + ASSERT_EQ(user_types::Node::typeDescription.typeName, result.object->getTypeDescription().typeName); SNode sNode{std::dynamic_pointer_cast(result.object)}; - auto anno = sNode->query(); + auto anno = sNode->query(); ASSERT_TRUE(anno != nullptr); ASSERT_EQ(*anno->projectID_, std::string("base_id")); } TEST_F(DeserializationTest, deserializeMeshNodeWithMesh) { - auto result = raco::serialization::test_helpers::deserializeObject( - raco::utils::file::read((test_path() / "expectations" / "MeshNodeWithMesh.json").string())); - ASSERT_EQ(raco::user_types::MeshNode::typeDescription.typeName, result.object->getTypeDescription().typeName); + auto result = serialization::test_helpers::deserializeObject( + utils::file::read((test_path() / "expectations" / "MeshNodeWithMesh.json").string())); + ASSERT_EQ(user_types::MeshNode::typeDescription.typeName, result.object->getTypeDescription().typeName); SMeshNode sMeshNode{std::dynamic_pointer_cast(result.object)}; ASSERT_EQ(1, result.references.size()); ASSERT_EQ(result.references.at(&sMeshNode->mesh_), "mesh_id"); @@ -69,26 +79,26 @@ TEST_F(DeserializationTest, deserializeMeshNodeWithMesh) { } TEST_F(DeserializationTest, deserializeNodeWithMeshNode) { - auto result = raco::serialization::test_helpers::deserializeObject( - raco::utils::file::read((test_path() / "expectations" / "NodeWithChildMeshNode.json").string())); - ASSERT_EQ(raco::user_types::Node::typeDescription.typeName, result.object->getTypeDescription().typeName); + auto result = serialization::test_helpers::deserializeObject( + utils::file::read((test_path() / "expectations" / "NodeWithChildMeshNode.json").string())); + ASSERT_EQ(user_types::Node::typeDescription.typeName, result.object->getTypeDescription().typeName); SNode sNode{std::dynamic_pointer_cast(result.object)}; ASSERT_EQ(1, result.references.size()); } TEST_F(DeserializationTest, deserializeMesh) { - auto result = raco::serialization::test_helpers::deserializeObject( - raco::utils::file::read((test_path() / "expectations" / "Mesh.json").string())); - ASSERT_EQ(raco::user_types::Mesh::typeDescription.typeName, result.object->getTypeDescription().typeName); + auto result = serialization::test_helpers::deserializeObject( + utils::file::read((test_path() / "expectations" / "Mesh.json").string())); + ASSERT_EQ(user_types::Mesh::typeDescription.typeName, result.object->getTypeDescription().typeName); SMesh sMesh{std::dynamic_pointer_cast(result.object)}; ASSERT_EQ(0, result.references.size()); ASSERT_EQ(1, sMesh->materialNames_->size()); } TEST_F(DeserializationTest, deserializeLuaScript) { - auto result = raco::serialization::test_helpers::deserializeObject( - raco::utils::file::read((test_path() / "expectations" / "LuaScript.json").string())); - ASSERT_EQ(raco::user_types::LuaScript::typeDescription.typeName, result.object->getTypeDescription().typeName); + auto result = serialization::test_helpers::deserializeObject( + utils::file::read((test_path() / "expectations" / "LuaScript.json").string())); + ASSERT_EQ(user_types::LuaScript::typeDescription.typeName, result.object->getTypeDescription().typeName); SLuaScript sLuaScript{std::dynamic_pointer_cast(result.object)}; ASSERT_EQ(0, result.references.size()); ASSERT_EQ(0, sLuaScript->inputs_->size()); @@ -96,108 +106,104 @@ TEST_F(DeserializationTest, deserializeLuaScript) { } TEST_F(DeserializationTest, deserializeLuaScriptInStruct) { - auto result = raco::serialization::test_helpers::deserializeObject( - raco::utils::file::read((test_path() / "expectations" / "LuaScriptInStruct.json").string())); - ASSERT_EQ(raco::user_types::LuaScript::typeDescription.typeName, result.object->getTypeDescription().typeName); + auto result = serialization::test_helpers::deserializeObject( + utils::file::read((test_path() / "expectations" / "LuaScriptInStruct.json").string())); + ASSERT_EQ(user_types::LuaScript::typeDescription.typeName, result.object->getTypeDescription().typeName); SLuaScript sLuaScript{std::dynamic_pointer_cast(result.object)}; ASSERT_EQ(0, result.references.size()); ASSERT_EQ(1, sLuaScript->inputs_->size()); - ASSERT_EQ(raco::data_storage::PrimitiveType::Double, sLuaScript->inputs_->get(0)->asTable().get(0)->type()); - ASSERT_EQ(raco::data_storage::PrimitiveType::Double, sLuaScript->inputs_->get(0)->asTable().get(1)->type()); + ASSERT_EQ(data_storage::PrimitiveType::Double, sLuaScript->inputs_->get(0)->asTable().get(0)->type()); + ASSERT_EQ(data_storage::PrimitiveType::Double, sLuaScript->inputs_->get(0)->asTable().get(1)->type()); ASSERT_EQ(0, sLuaScript->outputs_->size()); } TEST_F(DeserializationTest, deserializeLuaScriptInSpecificPropNames) { - auto result = raco::serialization::test_helpers::deserializeObject( - raco::utils::file::read((test_path() / "expectations" / "LuaScriptSpecificPropNames.json").string())); - ASSERT_EQ(raco::user_types::LuaScript::typeDescription.typeName, result.object->getTypeDescription().typeName); + auto result = serialization::test_helpers::deserializeObject( + utils::file::read((test_path() / "expectations" / "LuaScriptSpecificPropNames.json").string())); + ASSERT_EQ(user_types::LuaScript::typeDescription.typeName, result.object->getTypeDescription().typeName); SLuaScript sLuaScript{std::dynamic_pointer_cast(result.object)}; } TEST_F(DeserializationTest, deserializeLuaScriptWithRefToUserTypeWithAnnotation) { - auto result = raco::serialization::test_helpers::deserializeObject( - raco::utils::file::read((test_path() / "expectations" / "LuaScriptWithRefToUserTypeWithAnnotation.json").string())); - ASSERT_EQ(raco::user_types::LuaScript::typeDescription.typeName, result.object->getTypeDescription().typeName); + auto result = serialization::test_helpers::deserializeObject( + utils::file::read((test_path() / "expectations" / "LuaScriptWithRefToUserTypeWithAnnotation.json").string())); + ASSERT_EQ(user_types::LuaScript::typeDescription.typeName, result.object->getTypeDescription().typeName); SLuaScript sLuaScript{std::dynamic_pointer_cast(result.object)}; auto* property{sLuaScript->inputs_->get(sLuaScript->inputs_->index("ref"))}; ASSERT_EQ("Texture::EngineTypeAnnotation", property->typeName()); ASSERT_EQ(1, property->baseAnnotationPtrs().size()); - ASSERT_TRUE(property->dynamicQuery() != nullptr); - ASSERT_EQ(static_cast(raco::core::EnginePrimitive::TextureSampler2D), *property->query()->engineType_); + ASSERT_TRUE(property->dynamicQuery() != nullptr); + ASSERT_EQ(static_cast(core::EnginePrimitive::TextureSampler2D), *property->query()->engineType_); } TEST_F(DeserializationTest, deserializeLuaScriptWithURI) { - auto result = raco::serialization::test_helpers::deserializeObject( - raco::utils::file::read((test_path() / "expectations" / "LuaScriptWithURI.json").string())); - ASSERT_EQ(raco::user_types::LuaScript::typeDescription.typeName, result.object->getTypeDescription().typeName); + auto result = serialization::test_helpers::deserializeObject( + utils::file::read((test_path() / "expectations" / "LuaScriptWithURI.json").string())); + ASSERT_EQ(user_types::LuaScript::typeDescription.typeName, result.object->getTypeDescription().typeName); SLuaScript sLuaScript{std::dynamic_pointer_cast(result.object)}; auto* property{sLuaScript->inputs_->get(sLuaScript->inputs_->index("uri"))}; ASSERT_EQ("String::URIAnnotation", property->typeName()); ASSERT_EQ(1, property->baseAnnotationPtrs().size()); - ASSERT_TRUE(property->dynamicQuery() != nullptr); + ASSERT_TRUE(property->dynamicQuery() != nullptr); } TEST_F(DeserializationTest, deserializeLuaScriptWithAnnotatedDouble) { - auto result = raco::serialization::test_helpers::deserializeObject( - raco::utils::file::read((test_path() / "expectations" / "LuaScriptWithAnnotatedDouble.json").string())); - ASSERT_EQ(raco::user_types::LuaScript::typeDescription.typeName, result.object->getTypeDescription().typeName); + auto result = serialization::test_helpers::deserializeObject( + utils::file::read((test_path() / "expectations" / "LuaScriptWithAnnotatedDouble.json").string())); + ASSERT_EQ(user_types::LuaScript::typeDescription.typeName, result.object->getTypeDescription().typeName); SLuaScript sLuaScript{std::dynamic_pointer_cast(result.object)}; auto* property = sLuaScript->inputs_->get(sLuaScript->inputs_->index("double")); - ASSERT_EQ("Double", *property->query()->name_); - ASSERT_EQ(-10.0, *property->query>()->min_); - ASSERT_EQ(10.0, *property->query>()->max_); + ASSERT_EQ("Double", *property->query()->name_); + ASSERT_EQ(-10.0, *property->query>()->min_); + ASSERT_EQ(10.0, *property->query>()->max_); } TEST_F(DeserializationTest, deserializeVersionArray) { - using raco::serialization::ProjectDeserializationInfo; + using serialization::ProjectDeserializationInfo; QJsonObject fakeProjectJSON; - auto compareVersionValues = [this, &fakeProjectJSON](raco::serialization::DeserializedVersion&& expectedRamsesVer, raco::serialization::DeserializedVersion&& expectedLogicEngineVer, raco::serialization::DeserializedVersion&& expectedRaCoVer) { + auto compareVersionValues = [this, &fakeProjectJSON](serialization::DeserializedVersion&& expectedRamsesVer, serialization::DeserializedVersion&& expectedRaCoVer) { QJsonDocument fakeProjectJSONFile(fakeProjectJSON); - auto versionInfo = raco::serialization::deserializeProjectVersionInfo(fakeProjectJSONFile); + auto versionInfo = serialization::deserializeProjectVersionInfo(fakeProjectJSONFile); ASSERT_TRUE(versionInfo.ramsesVersion == expectedRamsesVer); - ASSERT_TRUE(versionInfo.ramsesLogicEngineVersion == expectedLogicEngineVer); ASSERT_TRUE(versionInfo.raCoVersion == expectedRaCoVer); }; compareVersionValues( - {ProjectDeserializationInfo::NO_VERSION, ProjectDeserializationInfo::NO_VERSION, ProjectDeserializationInfo::NO_VERSION}, {ProjectDeserializationInfo::NO_VERSION, ProjectDeserializationInfo::NO_VERSION, ProjectDeserializationInfo::NO_VERSION}, {ProjectDeserializationInfo::NO_VERSION, ProjectDeserializationInfo::NO_VERSION, ProjectDeserializationInfo::NO_VERSION}); - fakeProjectJSON[raco::serialization::keys::RAMSES_VERSION] = QJsonArray{1}; - fakeProjectJSON[raco::serialization::keys::RAMSES_LOGIC_ENGINE_VERSION] = QJsonArray{1, 2, 3}; - fakeProjectJSON[raco::serialization::keys::RAMSES_COMPOSER_VERSION] = QJsonArray{99, 1, 3, 5}; + fakeProjectJSON[serialization::keys::RAMSES_VERSION] = QJsonArray{1}; + fakeProjectJSON[serialization::keys::RAMSES_COMPOSER_VERSION] = QJsonArray{99, 1, 3, 5}; compareVersionValues( {1, ProjectDeserializationInfo::NO_VERSION, ProjectDeserializationInfo::NO_VERSION}, - {1, 2, 3}, {99, 1, 3}); } TEST_F(DeserializationTest, deserializeObjects_luaScriptLinkedToNode_outputsAreDeserialized) { - auto result = raco::serialization::deserializeObjects( - raco::utils::file::read((test_path() / "expectations" / "LuaScriptLinkedToNode.json").string()), false); + auto result = serialization::deserializeObjects( + utils::file::read((test_path() / "expectations" / "LuaScriptLinkedToNode.json").string()), false); ASSERT_TRUE(result.has_value()); - raco::user_types::SLuaScript sScript{ raco::select(result->objects)}; + user_types::SLuaScript sScript{ raco::select(result->objects)}; ASSERT_EQ(3, sScript->outputs_->size()); } TEST_F(DeserializationTest, deserializeObjects_luaScriptLinkedToNode) { - auto result = raco::serialization::deserializeObjects( - raco::utils::file::read((test_path() / "expectations" / "LuaScriptLinkedToNode.json").string()), false); + auto result = serialization::deserializeObjects( + utils::file::read((test_path() / "expectations" / "LuaScriptLinkedToNode.json").string()), false); ASSERT_TRUE(result.has_value()); - std::vector objects{}; + std::vector objects{}; objects.reserve(result->objects.size()); for (auto& i : result->objects) { - objects.push_back(std::dynamic_pointer_cast(i)); + objects.push_back(std::dynamic_pointer_cast(i)); } for (auto& ref : result->references) { - *ref.first = *std::find_if(objects.begin(), objects.end(), [&ref](const raco::core::SEditorObject& obj) { + *ref.first = *std::find_if(objects.begin(), objects.end(), [&ref](const core::SEditorObject& obj) { return obj->objectID() == ref.second; }); } @@ -206,15 +212,57 @@ TEST_F(DeserializationTest, deserializeObjects_luaScriptLinkedToNode) { ASSERT_EQ(1, result->links.size()); ASSERT_EQ(2, result->references.size()); - auto sLink{std::dynamic_pointer_cast(result->links.at(0))}; - raco::user_types::SLuaScript sLuaScript{raco::select(result->objects)}; - raco::user_types::SNode sNode{raco::select(result->objects)}; + auto sLink{std::dynamic_pointer_cast(result->links.at(0))}; + user_types::SLuaScript sLuaScript{raco::select(result->objects)}; + user_types::SNode sNode{raco::select(result->objects)}; - raco::core::PropertyDescriptor startProp {sLuaScript, {"outputs", "translation"}}; + core::PropertyDescriptor startProp {sLuaScript, {"outputs", "translation"}}; EXPECT_EQ(startProp, sLink->startProp()); - raco::core::PropertyDescriptor endProp{sNode, {"translation"}}; + core::PropertyDescriptor endProp{sNode, {"translation"}}; EXPECT_EQ(endProp, sLink->endProp()); std::set refRootObjectIDs{"node_id", "lua_script_id"}; EXPECT_EQ(result->rootObjectIDs, refRootObjectIDs); -} \ No newline at end of file +} + +TEST_F(DeserializationTest, deserializeArrays) { + auto result = deserializeObjects("Arrays.json"); + ASSERT_TRUE(result.has_value()); + + for (auto& ref : result->references) { + *ref.first = *std::find_if(result->objects.begin(), result->objects.end(), [&ref](const core::SEditorObject& obj) { + return obj->objectID() == ref.second; + }); + } + + auto obj = raco::select(result->objects); + auto node_1 = raco::select(result->objects, "node_1"); + auto node_2 = raco::select(result->objects, "node_2"); + ASSERT_TRUE(obj != nullptr); + ASSERT_TRUE(node_1 != nullptr); + ASSERT_TRUE(node_2 != nullptr); + + auto& array = obj->table_->get("array")->asArray(); + auto& nested = obj->table_->get("nested")->asArray(); + EXPECT_EQ(array.size(), 2); + EXPECT_EQ(nested.size(), 2); + for (size_t outer = 0; outer < 2; outer++) { + EXPECT_EQ(array.get(outer)->asDouble(), outer); + EXPECT_EQ(**obj->array_double_->get(outer), outer); + + EXPECT_EQ(nested.get(outer)->asArray().size(), 3); + for (size_t inner = 0; inner < 3; inner++) { + EXPECT_EQ(**(*obj->array_array_double_->get(outer))->get(inner), outer + static_cast(inner) / 10.0); + EXPECT_EQ(nested.get(outer)->asArray().get(inner)->asDouble(), outer + static_cast(inner) / 10.0); + } + } + + EXPECT_EQ(obj->array_ref_->size(), 2); + EXPECT_EQ(**obj->array_ref_->get(0), node_1); + EXPECT_EQ(**obj->array_ref_->get(1), node_2); + + auto& array_ref = obj->table_->get("array_ref")->asArray(); + EXPECT_EQ(array_ref.size(), 2); + EXPECT_EQ(array_ref.get(0)->asRef(), node_1); + EXPECT_EQ(array_ref.get(1)->asRef(), node_2); +} diff --git a/datamodel/libCore/tests/ExternalReference_test.cpp b/datamodel/libCore/tests/ExternalReference_test.cpp index a2ec2294..c06f9adc 100644 --- a/datamodel/libCore/tests/ExternalReference_test.cpp +++ b/datamodel/libCore/tests/ExternalReference_test.cpp @@ -48,7 +48,7 @@ using raco::application::RaCoApplicationLaunchSettings; class ExtrefTest : public RacoBaseTest<> { public: - void checkLinks(const std::vector &refLinks) { + void checkLinks(const std::vector &refLinks) { RacoBaseTest::checkLinks(*project, refLinks); } @@ -87,20 +87,20 @@ class ExtrefTest : public RacoBaseTest<> { return meshnode; } - SLuaScript create_lua(const std::string &name, const std::string &relpath, raco::core::SEditorObject parent = nullptr) { + SLuaScript create_lua(const std::string &name, const std::string &relpath, core::SEditorObject parent = nullptr) { auto lua = create(name, parent); cmd->set({lua, {"uri"}}, (test_path() / relpath).string()); return lua; } - SLuaScript create_lua(const std::string &name, const TextFile &file, raco::core::SEditorObject parent = nullptr) { + SLuaScript create_lua(const std::string &name, const TextFile &file, core::SEditorObject parent = nullptr) { auto lua = create(name, parent); cmd->set({lua, {"uri"}}, static_cast(file)); return lua; } - SPrefabInstance create_prefabInstance(const std::string &name, raco::user_types::SPrefab prefab, raco::user_types::SEditorObject parent = nullptr) { - auto inst = create(name, parent); + SPrefabInstance create_prefabInstance(const std::string &name, user_types::SPrefab prefab, user_types::SEditorObject parent = nullptr) { + auto inst = create(name, parent); cmd->set({inst, &PrefabInstance::template_}, prefab); return inst; } @@ -133,11 +133,11 @@ class ExtrefTest : public RacoBaseTest<> { SEditorObject findLocal(const std::string &name) { EXPECT_EQ(1, std::count_if(project->instances().begin(), project->instances().end(), [name](SEditorObject obj) { - return obj->objectName() == name && !obj->query(); + return obj->objectName() == name && !obj->query(); })); auto it = std::find_if(project->instances().begin(), project->instances().end(), [name](SEditorObject obj) { - return obj->objectName() == name && !obj->query(); + return obj->objectName() == name && !obj->query(); }); return *it; } @@ -146,12 +146,12 @@ class ExtrefTest : public RacoBaseTest<> { std::shared_ptr findExt(const std::string &name, const std::string &projectID = std::string()) { SEditorObject editorObj = nullptr; for (const auto obj : project->instances()) { - if (obj->objectName() == name && obj->query()) { + if (obj->objectName() == name && obj->query()) { editorObj = obj; } } EXPECT_TRUE(editorObj != nullptr); - auto anno = editorObj->query(); + auto anno = editorObj->query(); EXPECT_TRUE(anno != nullptr); if (!projectID.empty()) { EXPECT_EQ(*anno->projectID_, projectID); @@ -178,8 +178,8 @@ class ExtrefTest : public RacoBaseTest<> { }); } - raco::ramses_base::HeadlessEngineBackend backend{raco::ramses_base::BaseEngineBackend::maxFeatureLevel}; - + ramses_base::HeadlessEngineBackend backend; + RaCoApplication *app; Project *project; CommandInterface *cmd; @@ -1450,7 +1450,7 @@ TEST_F(ExtrefTest, filecopy_update_fail_nested_same_object) { cmd->set({meshnode, {"mesh"}}, mesh); }); - EXPECT_THROW(updateComposite(compositePathName, [this]() {}), raco::core::ExtrefError); + EXPECT_THROW(updateComposite(compositePathName, [this]() {}), core::ExtrefError); } TEST_F(ExtrefTest, filecopy_update_fail_nested_different_object) { @@ -1498,7 +1498,7 @@ TEST_F(ExtrefTest, filecopy_update_fail_nested_different_object) { cmd->set({meshnode, {"mesh"}}, mesh); }); - EXPECT_THROW(updateComposite(compositePathName, [this]() {}), raco::core::ExtrefError); + EXPECT_THROW(updateComposite(compositePathName, [this]() {}), core::ExtrefError); } TEST_F(ExtrefTest, nesting_create_loop_fail) { @@ -2016,7 +2016,7 @@ TEST_F(ExtrefTest, paste_reroot_lua_uri_with_link_down) { auto node = create("prefab_node", prefab); auto lua = create("prefab_lua", prefab); - raco::utils::file::write((test_path() / "subdir/script.lua").string(), R"( + utils::file::write((test_path() / "subdir/script.lua").string(), R"( function interface(IN,OUT) IN.v = Type:Vec3f() OUT.v = Type:Vec3f() @@ -2066,7 +2066,7 @@ TEST_F(ExtrefTest, prefab_link_quaternion_in_prefab) { setupBase(basePathName1, [this, basePathName1]() { project->setCurrentPath(basePathName1); - raco::utils::file::write((test_path() / "script.lua").string(), R"( + utils::file::write((test_path() / "script.lua").string(), R"( function interface(IN,OUT) IN.v = Type:Vec4f() OUT.v = Type:Vec4f() @@ -2118,9 +2118,9 @@ TEST_F(ExtrefTest, animation_channel_data_gets_propagated) { auto anim = create("anim"); auto animChannel = findExt("animCh"); - cmd->set({anim, {"animationChannels", "Channel 0"}}, animChannel); + cmd->set(ValueHandle(anim, {"animationChannels"})[0], animChannel); - ASSERT_EQ(anim->get("animationChannels")->asTable()[0]->asRef(), animChannel); + ASSERT_EQ(**anim->animationChannels_->get(0), animChannel); }); } @@ -2137,7 +2137,7 @@ TEST_F(ExtrefTest, animation_in_extref_prefab_gets_propagated) { cmd->moveScenegraphChildren({animNode}, prefab); auto animChannel = create_animationchannel("animCh", "meshes/InterpolationTest/InterpolationTest.gltf"); - cmd->set({anim, {"animationChannels", "Channel 0"}}, animChannel); + cmd->set(ValueHandle(anim, {"animationChannels"})[0], animChannel); }); setupBase(basePathName2, [this, basePathName1]() { @@ -2146,7 +2146,7 @@ TEST_F(ExtrefTest, animation_in_extref_prefab_gets_propagated) { auto anim = findExt("anim"); auto animChannel = findExt("animCh"); - ASSERT_EQ(anim->get("animationChannels")->asTable()[0]->asRef(), animChannel); + ASSERT_EQ(**anim->animationChannels_->get(0), animChannel); }); } @@ -2633,57 +2633,59 @@ TEST_F(ExtrefTest, feature_level_upgrade_composite) { basePathName, [this]() { auto prefab = create("prefab"); }, - "base", 1); + "base", ramses_base::BaseEngineBackend::minFeatureLevel); setupComposite( basePathName, compositePathName, {"prefab"}, [this]() { auto prefab = findExt("prefab"); auto inst = create_prefabInstance("inst", prefab); }, - "composite", 1); + "composite", ramses_base::BaseEngineBackend::minFeatureLevel); updateBase(basePathName, [this]() { - EXPECT_EQ(project->featureLevel(), 1); + EXPECT_EQ(project->featureLevel(), ramses_base::BaseEngineBackend::minFeatureLevel); auto prefab = find("prefab"); auto node = create("node", prefab); }); updateComposite( compositePathName, [this]() { - EXPECT_EQ(project->featureLevel(), 2); + EXPECT_EQ(project->featureLevel(), ramses_base::BaseEngineBackend::maxFeatureLevel); }, - 2); + ramses_base::BaseEngineBackend::maxFeatureLevel); } TEST_F(ExtrefTest, feature_level_upgrade_base) { - auto basePathName{(test_path() / "base.rca").string()}; - auto compositePathName{(test_path() / "composite.rca").string()}; - - setupBase( - basePathName, [this]() { - auto prefab = create("prefab"); - }, - "base", 1); - - setupComposite( - basePathName, compositePathName, {"prefab"}, [this]() { - auto prefab = findExt("prefab"); - auto inst = create_prefabInstance("inst", prefab); - }, - "composite", 1); - - updateBase( - basePathName, [this]() {}, 2); - - EXPECT_THROW(updateComposite( - compositePathName, [this]() {}, 1), - raco::core::ExtrefError); - - updateComposite( - compositePathName, [this]() { - EXPECT_EQ(project->featureLevel(), 2); - }, - 2); + if (ramses_base::BaseEngineBackend::minFeatureLevel < ramses_base::BaseEngineBackend::maxFeatureLevel) { + auto basePathName{(test_path() / "base.rca").string()}; + auto compositePathName{(test_path() / "composite.rca").string()}; + + setupBase( + basePathName, [this]() { + auto prefab = create("prefab"); + }, + "base", ramses_base::BaseEngineBackend::minFeatureLevel); + + setupComposite( + basePathName, compositePathName, {"prefab"}, [this]() { + auto prefab = findExt("prefab"); + auto inst = create_prefabInstance("inst", prefab); + }, + "composite", ramses_base::BaseEngineBackend::minFeatureLevel); + + updateBase( + basePathName, [this]() {}, ramses_base::BaseEngineBackend::maxFeatureLevel); + + EXPECT_THROW(updateComposite( + compositePathName, [this]() {}, ramses_base::BaseEngineBackend::minFeatureLevel), + core::ExtrefError); + + updateComposite( + compositePathName, [this]() { + EXPECT_EQ(project->featureLevel(), ramses_base::BaseEngineBackend::maxFeatureLevel); + }, + ramses_base::BaseEngineBackend::maxFeatureLevel); + } } TEST_F(ExtrefTest, extref_paste_from_orig_and_save_as_with_new_id_copy) { diff --git a/datamodel/libCore/tests/Handle_test.cpp b/datamodel/libCore/tests/Handle_test.cpp index 90b8ca4c..31558964 100644 --- a/datamodel/libCore/tests/Handle_test.cpp +++ b/datamodel/libCore/tests/Handle_test.cpp @@ -87,7 +87,7 @@ TEST(HandleTests, Node) ValueHandle h = n[i]; propNames.emplace_back(h.getPropName()); } - std::vector refPropNames { "objectID", "objectName", "userTags", "children", "tags", "visibility", "enabled", "translation", "rotation", "scaling" }; + std::vector refPropNames{"objectID", "objectName", "children", "userTags", "metaData", "tags", "visibility", "enabled", "translation", "rotation", "scaling", "editorVisibility"}; EXPECT_EQ(propNames, refPropNames); ValueHandle n_rot = n.get("rotation"); diff --git a/datamodel/libCore/tests/Iterator_test.cpp b/datamodel/libCore/tests/Iterator_test.cpp index a1da3e9b..0c15731a 100644 --- a/datamodel/libCore/tests/Iterator_test.cpp +++ b/datamodel/libCore/tests/Iterator_test.cpp @@ -41,7 +41,7 @@ TEST(IteratorTest, ObjectTree) { } EXPECT_EQ(children, std::vector({node})); - ValueBase* prop = node->children_->addProperty(PrimitiveType::Ref); + ValueBase* prop = node->children_->addProperty(); *prop = child_a; children.clear(); @@ -76,8 +76,9 @@ TEST(IteratorTest, Property) { std::vector refHandles{ {node, {"objectID"}}, {node, {"objectName"}}, - {node, {"userTags"}}, {node, {"children"}}, + {node, {"userTags"}}, + {node, {"metaData"}}, {node, {"tags"}}, {node, {"visibility"}}, {node, {"enabled"}}, @@ -92,7 +93,8 @@ TEST(IteratorTest, Property) { {node, {"scaling"}}, {node, {"scaling", "x"}}, {node, {"scaling", "y"}}, - {node, {"scaling", "z"}}}; + {node, {"scaling", "z"}}, + {node, {"editorVisibility"}}}; EXPECT_EQ(handles, refHandles); handles.clear(); diff --git a/datamodel/libCore/tests/Link_test.cpp b/datamodel/libCore/tests/Link_test.cpp index 89b5d7cd..8d18130d 100644 --- a/datamodel/libCore/tests/Link_test.cpp +++ b/datamodel/libCore/tests/Link_test.cpp @@ -37,6 +37,7 @@ #include #include +using namespace raco; using namespace raco::core; using namespace raco::user_types; @@ -1248,7 +1249,7 @@ TEST_F(LinkTest, restore_meshnode_uniform_switching_shared) { TEST_F(LinkTest, lua_to_quaternion) { auto luaScript = create_lua("base", "scripts/types-scalar.lua"); - auto node = create("node", nullptr); + auto node = create("node", nullptr); auto [sprop, eprop] = link(luaScript, {"outputs", "ovector4f"}, node, {"rotation"}); checkLinks({{sprop, eprop, true}}); @@ -1256,7 +1257,7 @@ TEST_F(LinkTest, lua_to_quaternion) { TEST_F(LinkTest, lua_to_euler_after_quaternion) { auto luaScript = create_lua("base", "scripts/types-scalar.lua"); - auto node = create("node", nullptr); + auto node = create("node", nullptr); auto [sprop, eprop] = link(luaScript, {"outputs", "ovector4f"}, node, {"rotation"}); auto [sprop2, eprop2] = link(luaScript, {"outputs", "ovector3f"}, node, {"rotation"}); @@ -1264,8 +1265,8 @@ TEST_F(LinkTest, lua_to_euler_after_quaternion) { } TEST_F(LinkTest, remove_link_keeps_value_with_undo_redo) { - raco::ramses_base::HeadlessEngineBackend backend{raco::ramses_base::BaseEngineBackend::maxFeatureLevel}; - raco::application::RaCoApplication app{backend}; + ramses_base::HeadlessEngineBackend backend; + application::RaCoApplication app{backend}; auto& cmd = *app.activeRaCoProject().commandInterface(); auto start = create_lua(cmd, "lua_start", "scripts/SimpleScript.lua"); @@ -1307,8 +1308,8 @@ TEST_F(LinkTest, remove_link_keeps_value_with_undo_redo) { TEST_F(LinkTest, break_link_keeps_value_with_undo_redo) { - raco::ramses_base::HeadlessEngineBackend backend{raco::ramses_base::BaseEngineBackend::maxFeatureLevel}; - raco::application::RaCoApplication app{backend}; + ramses_base::HeadlessEngineBackend backend; + application::RaCoApplication app{backend}; auto& cmd = *app.activeRaCoProject().commandInterface(); auto start = create_lua(cmd, "lua_start", "scripts/SimpleScript.lua"); @@ -1349,8 +1350,8 @@ TEST_F(LinkTest, break_link_keeps_value_with_undo_redo) { } TEST_F(LinkTest, break_link_remove_child_prop_keeps_value_with_undo_redo) { - raco::ramses_base::HeadlessEngineBackend backend{raco::ramses_base::BaseEngineBackend::maxFeatureLevel}; - raco::application::RaCoApplication app{backend}; + ramses_base::HeadlessEngineBackend backend; + application::RaCoApplication app{backend}; auto& cmd = *app.activeRaCoProject().commandInterface(); TextFile script_1 = makeFile("script-1.lua", @@ -1437,8 +1438,8 @@ TEST_F(LinkTest, dont_crash_when_object_is_deleted_after_property_with_link_was_ } TEST_F(LinkTest, timer_link) { - raco::ramses_base::HeadlessEngineBackend backend{raco::ramses_base::BaseEngineBackend::maxFeatureLevel}; - raco::application::RaCoApplication app{backend}; + ramses_base::HeadlessEngineBackend backend; + application::RaCoApplication app{backend}; auto& cmd = *app.activeRaCoProject().commandInterface(); TextFile script = makeFile("script.lua", @@ -1486,8 +1487,8 @@ end } TEST_F(LinkTest, timer_link_to_input) { - raco::ramses_base::HeadlessEngineBackend backend{raco::ramses_base::BaseEngineBackend::maxFeatureLevel}; - raco::application::RaCoApplication app{backend}; + ramses_base::HeadlessEngineBackend backend; + application::RaCoApplication app{backend}; auto& cmd = *app.activeRaCoProject().commandInterface(); TextFile script = makeFile("script.lua", @@ -1521,8 +1522,8 @@ end } TEST_F(LinkTest, timer_link_different_type) { - raco::ramses_base::HeadlessEngineBackend backend{raco::ramses_base::BaseEngineBackend::maxFeatureLevel}; - raco::application::RaCoApplication app{backend}; + ramses_base::HeadlessEngineBackend backend; + application::RaCoApplication app{backend}; auto& cmd = *app.activeRaCoProject().commandInterface(); TextFile script = makeFile("script.lua", diff --git a/datamodel/libCore/tests/PathManager_test.cpp b/datamodel/libCore/tests/PathManager_test.cpp index 78d0eba9..5448ca41 100644 --- a/datamodel/libCore/tests/PathManager_test.cpp +++ b/datamodel/libCore/tests/PathManager_test.cpp @@ -17,8 +17,8 @@ using namespace raco::core; class PathManagerTest : public RacoBaseTest<> { public: - raco::utils::u8path test_relative_path() const override { - return raco::utils::u8path{test_suite_name()} / test_case_name() / u8"滴滴启动纽交所退市 äüöß"; + utils::u8path test_relative_path() const override { + return utils::u8path{test_suite_name()} / test_case_name() / u8"滴滴启动纽交所退市 äüöß"; } }; @@ -31,10 +31,10 @@ TEST_F(PathManagerTest, MigrationOldConfigfilesDoIfNewNotPresent) { std::filesystem::create_directories(programPath); std::filesystem::create_directories(legacyConfigFiles); - auto layout = raco::utils::u8path(makeFile("configfiles/layout.ini", "")); - auto preferences = raco::utils::u8path(makeFile("configfiles/preferences.ini", "")); - auto log1 = raco::utils::u8path(makeFile("configfiles/log1.log", "")); - auto log2 = raco::utils::u8path(makeFile("configfiles/log2.log", "")); + auto layout = utils::u8path(makeFile("configfiles/layout.ini", "")); + auto preferences = utils::u8path(makeFile("configfiles/preferences.ini", "")); + auto log1 = utils::u8path(makeFile("configfiles/log1.log", "")); + auto log2 = utils::u8path(makeFile("configfiles/log2.log", "")); ASSERT_FALSE(appDataPath.existsDirectory()); ASSERT_TRUE(legacyConfigFiles.existsDirectory()); @@ -67,10 +67,10 @@ TEST_F(PathManagerTest, MigrationOldConfigfilesDoIfNewPresentEmptyFolder) { std::filesystem::create_directories(programPath); std::filesystem::create_directories(legacyConfigFiles); - auto layout = raco::utils::u8path(makeFile("configfiles/layout.ini", "")); - auto preferences = raco::utils::u8path(makeFile("configfiles/preferences.ini", "")); - auto log1 = raco::utils::u8path(makeFile("configfiles/log1.log", "")); - auto log2 = raco::utils::u8path(makeFile("configfiles/log2.log", "")); + auto layout = utils::u8path(makeFile("configfiles/layout.ini", "")); + auto preferences = utils::u8path(makeFile("configfiles/preferences.ini", "")); + auto log1 = utils::u8path(makeFile("configfiles/log1.log", "")); + auto log2 = utils::u8path(makeFile("configfiles/log2.log", "")); ASSERT_TRUE(appDataPath.existsDirectory()); ASSERT_TRUE(legacyConfigFiles.existsDirectory()); @@ -106,10 +106,10 @@ TEST_F(PathManagerTest, MigrationOldConfigfilesDoNotIfNewAlreadyPresent) { makeFile("AppData/custom.ini", ""); - auto layout = raco::utils::u8path(makeFile("configfiles/layout.ini", "")); - auto preferences = raco::utils::u8path(makeFile("configfiles/preferences.ini", "")); - auto log1 = raco::utils::u8path(makeFile("configfiles/log1.log", "")); - auto log2 = raco::utils::u8path(makeFile("configfiles/log2.log", "")); + auto layout = utils::u8path(makeFile("configfiles/layout.ini", "")); + auto preferences = utils::u8path(makeFile("configfiles/preferences.ini", "")); + auto log1 = utils::u8path(makeFile("configfiles/log1.log", "")); + auto log2 = utils::u8path(makeFile("configfiles/log2.log", "")); ASSERT_TRUE(appDataPath.existsDirectory()); ASSERT_TRUE(legacyConfigFiles.existsDirectory()); diff --git a/datamodel/libCore/tests/Prefab_test.cpp b/datamodel/libCore/tests/Prefab_test.cpp index effe9667..f07b0a71 100644 --- a/datamodel/libCore/tests/Prefab_test.cpp +++ b/datamodel/libCore/tests/Prefab_test.cpp @@ -537,7 +537,7 @@ TEST_F(PrefabTest, delete_prefab_with_node_with_meshnode_while_instance_exists) } TEST_F(PrefabTest, update_inst_from_prefab_after_remove_link) { - raco::ramses_base::HeadlessEngineBackend backend{raco::ramses_base::BaseEngineBackend::maxFeatureLevel}; + ramses_base::HeadlessEngineBackend backend; raco::application::RaCoApplication app{backend}; auto& cmd = *app.activeRaCoProject().commandInterface(); @@ -661,7 +661,7 @@ end // Use context here to perform prefab update only after both operations are complete context.moveScenegraphChildren({meshnode}, prefab); context.deleteObjects({node}); - raco::core::PrefabOperations::globalPrefabUpdate(context); + core::PrefabOperations::globalPrefabUpdate(context); EXPECT_EQ(inst->children_->size(), 2); inst_meshnode = raco::select(inst->children_->asVector()); @@ -922,7 +922,7 @@ TEST_F(PrefabTest, ref_invalid_outside_to_rw_inside_prefab_instance) { auto meshnode_inst = inst->children_->asVector().front(); ASSERT_TRUE(meshnode_inst != nullptr); - auto refTargets = raco::core::Queries::findAllValidReferenceTargets(*cmd.project(), ValueHandle(skin, &Skin::targets_)[0]); + auto refTargets = core::Queries::findAllValidReferenceTargets(*cmd.project(), ValueHandle(skin, &Skin::targets_)[0]); ASSERT_TRUE(refTargets.empty()); } @@ -933,17 +933,17 @@ TEST_F(PrefabTest, objects_in_prefab_not_refable_outside_prefab) { commandInterface.moveScenegraphChildren({camera}, prefab); auto renderPass = create("pass"); - auto refTargets = raco::core::Queries::findAllValidReferenceTargets(*commandInterface.project(), {renderPass, &raco::user_types::RenderPass::camera_}); + auto refTargets = core::Queries::findAllValidReferenceTargets(*commandInterface.project(), {renderPass, &user_types::RenderPass::camera_}); ASSERT_TRUE(refTargets.empty()); - ASSERT_THROW(commandInterface.set({renderPass, &raco::user_types::RenderPass::camera_}, camera), std::runtime_error); - ASSERT_EQ(raco::core::ValueHandle(renderPass, &raco::user_types::RenderPass::camera_).asRef(), SEditorObject()); + ASSERT_THROW(commandInterface.set({renderPass, &user_types::RenderPass::camera_}, camera), std::runtime_error); + ASSERT_EQ(core::ValueHandle(renderPass, &user_types::RenderPass::camera_).asRef(), SEditorObject()); auto inst = create("inst"); commandInterface.set({inst, &PrefabInstance::template_}, prefab); auto cameraInst = inst->children_->asVector().front(); - refTargets = raco::core::Queries::findAllValidReferenceTargets(*commandInterface.project(), {renderPass, &raco::user_types::RenderPass::camera_}); + refTargets = core::Queries::findAllValidReferenceTargets(*commandInterface.project(), {renderPass, &user_types::RenderPass::camera_}); ASSERT_EQ(refTargets, std::vector{cameraInst}); } @@ -952,21 +952,21 @@ TEST_F(PrefabTest, objects_in_prefab_not_refable_when_moved_into_prefab) { auto camera = create("camera"); auto renderPass = create("pass"); - auto refTargets = raco::core::Queries::findAllValidReferenceTargets(*commandInterface.project(), {renderPass, &raco::user_types::RenderPass::camera_}); + auto refTargets = core::Queries::findAllValidReferenceTargets(*commandInterface.project(), {renderPass, &user_types::RenderPass::camera_}); ASSERT_EQ(refTargets, std::vector{camera}); - commandInterface.set({renderPass, &raco::user_types::RenderPass::camera_}, camera); - ASSERT_EQ(raco::core::ValueHandle(renderPass, &raco::user_types::RenderPass::camera_).asRef(), camera); + commandInterface.set({renderPass, &user_types::RenderPass::camera_}, camera); + ASSERT_EQ(core::ValueHandle(renderPass, &user_types::RenderPass::camera_).asRef(), camera); commandInterface.moveScenegraphChildren({camera}, prefab); - ASSERT_EQ(raco::core::ValueHandle(renderPass, &raco::user_types::RenderPass::camera_).asRef(), SEditorObject()); + ASSERT_EQ(core::ValueHandle(renderPass, &user_types::RenderPass::camera_).asRef(), SEditorObject()); auto inst = create("inst"); commandInterface.set({inst, &PrefabInstance::template_}, prefab); auto cameraInst = inst->children_->asVector().front(); - commandInterface.set({renderPass, &raco::user_types::RenderPass::camera_}, cameraInst); + commandInterface.set({renderPass, &user_types::RenderPass::camera_}, cameraInst); - ASSERT_EQ(raco::core::ValueHandle(renderPass, &raco::user_types::RenderPass::camera_).asRef(), cameraInst); + ASSERT_EQ(core::ValueHandle(renderPass, &user_types::RenderPass::camera_).asRef(), cameraInst); } @@ -976,18 +976,18 @@ TEST_F(PrefabTest, objects_outside_prefab_refable_inside_prefab) { commandInterface.moveScenegraphChildren({meshNode}, prefab); auto mesh = create("mesh"); - auto refTargets = raco::core::Queries::findAllValidReferenceTargets(*commandInterface.project(), {meshNode, &raco::user_types::MeshNode::mesh_}); + auto refTargets = core::Queries::findAllValidReferenceTargets(*commandInterface.project(), {meshNode, &user_types::MeshNode::mesh_}); ASSERT_EQ(refTargets, std::vector{mesh}); - commandInterface.set({meshNode, &raco::user_types::MeshNode::mesh_}, mesh); - ASSERT_EQ(raco::core::ValueHandle(meshNode, &raco::user_types::MeshNode::mesh_).asRef(), mesh); + commandInterface.set({meshNode, &user_types::MeshNode::mesh_}, mesh); + ASSERT_EQ(core::ValueHandle(meshNode, &user_types::MeshNode::mesh_).asRef(), mesh); } TEST_F(PrefabTest, prefab_is_valid_ref_target_for_prefabinstance) { auto prefab = create("prefab"); auto inst = create("inst"); - auto refTargets = raco::core::Queries::findAllValidReferenceTargets(*commandInterface.project(), {inst, &raco::user_types::PrefabInstance::template_}); + auto refTargets = core::Queries::findAllValidReferenceTargets(*commandInterface.project(), {inst, &user_types::PrefabInstance::template_}); ASSERT_EQ(refTargets, std::vector{prefab}); } @@ -1011,7 +1011,7 @@ TEST_F(PrefabTest, link_strong_to_weak_transition) { // Use context here to perform prefab update only after both operations are complete context.removeLink({end, {"inputs", "float"}}); context.addLink(ValueHandle{start, {"outputs", "ofloat"}}, ValueHandle{end, {"inputs", "float"}}, true); - raco::core::PrefabOperations::globalPrefabUpdate(context); + core::PrefabOperations::globalPrefabUpdate(context); checkLinks({{{start, {"outputs", "ofloat"}}, {end, {"inputs", "float"}}, true, true}, {{inst_start, {"outputs", "ofloat"}}, {inst_end, {"inputs", "float"}}, true, true}}); @@ -1041,7 +1041,7 @@ TEST_F(PrefabTest, link_strong_valid_to_weak_invalid_transition) { context.removeLink({end, {"inputs", "float"}}); context.addLink(ValueHandle{start, {"outputs", "ofloat"}}, ValueHandle{end, {"inputs", "float"}}, true); context.set(ValueHandle{end, {"uri"}}, (test_path() / "scripts/SimpleScript.lua").string()); - raco::core::PrefabOperations::globalPrefabUpdate(context); + core::PrefabOperations::globalPrefabUpdate(context); checkLinks({{{start, {"outputs", "ofloat"}}, {end, {"inputs", "float"}}, false, true}, {{inst_start, {"outputs", "ofloat"}}, {inst_end, {"inputs", "float"}}, false, true}}); @@ -1052,7 +1052,7 @@ TEST_F(PrefabTest, link_strong_valid_to_weak_invalid_transition) { TEST_F(PrefabTest, prefab_update_from_optimized_saved_file) { - raco::ramses_base::HeadlessEngineBackend backend{raco::ramses_base::BaseEngineBackend::maxFeatureLevel}; + ramses_base::HeadlessEngineBackend backend; std::string root_id; std::string node_id; @@ -1120,3 +1120,19 @@ TEST_F(PrefabTest, prefab_update_from_optimized_saved_file) { EXPECT_EQ(count_id_func(project, lua_id), 1); } } + + +TEST_F(PrefabTest, set_volatile_not_propagated) { + auto prefab = create("prefab"); + auto node = create("node", prefab); + auto inst = create_prefabInstance("inst", prefab); + auto inst_node = inst->children_->get(0)->asRef()->as(); + + EXPECT_EQ(*node->editorVisibility_, true); + EXPECT_EQ(*inst_node->editorVisibility_, true); + + commandInterface.set({node, &Node::editorVisibility_}, false); + + EXPECT_EQ(*node->editorVisibility_, false); + EXPECT_EQ(*inst_node->editorVisibility_, true); +} diff --git a/datamodel/libCore/tests/ProjectMigration_test.cpp b/datamodel/libCore/tests/ProjectMigration_test.cpp index f2803e27..d0507cc1 100644 --- a/datamodel/libCore/tests/ProjectMigration_test.cpp +++ b/datamodel/libCore/tests/ProjectMigration_test.cpp @@ -10,6 +10,7 @@ #include "core/Queries.h" #include "core/DynamicEditorObject.h" +#include "core/ExternalReferenceAnnotation.h" #include "core/ProjectMigration.h" #include "core/ProjectMigrationToV23.h" #include "core/ProxyObjectFactory.h" @@ -49,17 +50,17 @@ using namespace raco::core; const char testName_old[] = "Test"; const char testName_new[] = "Test"; -static_assert(!std::is_same, raco::serialization::proxy::Proxy>::value); +static_assert(!std::is_same, serialization::proxy::Proxy>::value); struct MigrationTest : public TestEnvironmentCore { - raco::ramses_base::HeadlessEngineBackend backend{raco::ramses_base::BaseEngineBackend::maxFeatureLevel}; + ramses_base::HeadlessEngineBackend backend; raco::application::RaCoApplication application{backend}; // Check if the property types coming out of the migration code agree with the types // in the current version of the user types. // Failure indicates missing migration code. - void checkPropertyTypes(const raco::serialization::ProjectDeserializationInfoIR& deserializedIR) { - auto userTypesPropMap = raco::serialization::makeUserTypePropertyMap(); + void checkPropertyTypes(const serialization::ProjectDeserializationInfoIR& deserializedIR) { + auto userTypesPropMap = serialization::makeUserTypePropertyMap(); for (const auto obj : deserializedIR.objects) { const auto& typesMap = userTypesPropMap.at(obj->getTypeDescription().typeName); @@ -78,16 +79,16 @@ struct MigrationTest : public TestEnvironmentCore { EXPECT_TRUE(file.open(QIODevice::ReadOnly | QIODevice::Text)); auto document{QJsonDocument::fromJson(file.readAll())}; file.close(); - auto fileVersion{raco::serialization::deserializeFileVersion(document)}; - EXPECT_TRUE(fileVersion <= raco::serialization::RAMSES_PROJECT_FILE_VERSION); + auto fileVersion{serialization::deserializeFileVersion(document)}; + EXPECT_TRUE(fileVersion <= serialization::RAMSES_PROJECT_FILE_VERSION); if (outFileVersion) { *outFileVersion = fileVersion; } // Perform deserialization to IR and migration by hand to check output of migration code: - auto deserializedIR{raco::serialization::deserializeProjectToIR(document, filename.toStdString())}; - auto& factory{raco::serialization::proxy::ProxyObjectFactory::getInstance()}; - raco::serialization::migrateProject(deserializedIR, factory); + auto deserializedIR{serialization::deserializeProjectToIR(document, filename.toStdString())}; + auto& factory{serialization::proxy::ProxyObjectFactory::getInstance()}; + serialization::migrateProject(deserializedIR, factory); checkPropertyTypes(deserializedIR); LoadContext loadContext; @@ -108,13 +109,13 @@ TEST_F(MigrationTest, migrate_from_V1) { TEST_F(MigrationTest, migrate_from_V9) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V9.rca").string())); - auto p = std::dynamic_pointer_cast(raco::core::Queries::findByName(racoproject->project()->instances(), "PerspectiveCamera")); + auto p = std::dynamic_pointer_cast(core::Queries::findByName(racoproject->project()->instances(), "PerspectiveCamera")); ASSERT_EQ(p->viewport_->offsetX_.asInt(), 1); ASSERT_EQ(p->viewport_->offsetY_.asInt(), 1); ASSERT_EQ(p->viewport_->width_.asInt(), 1441); ASSERT_EQ(p->viewport_->height_.asInt(), 721); - auto o = std::dynamic_pointer_cast(raco::core::Queries::findByName(racoproject->project()->instances(), "OrthographicCamera")); + auto o = std::dynamic_pointer_cast(core::Queries::findByName(racoproject->project()->instances(), "OrthographicCamera")); ASSERT_EQ(o->viewport_->offsetX_.asInt(), 2); ASSERT_EQ(o->viewport_->offsetY_.asInt(), 2); ASSERT_EQ(o->viewport_->width_.asInt(), 1442); @@ -124,7 +125,7 @@ TEST_F(MigrationTest, migrate_from_V9) { TEST_F(MigrationTest, migrate_from_V10) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V10.rca").string())); - auto meshnode = raco::core::Queries::findByName(racoproject->project()->instances(), "MeshNode")->as(); + auto meshnode = core::Queries::findByName(racoproject->project()->instances(), "MeshNode")->as(); ASSERT_TRUE(meshnode != nullptr); auto options = meshnode->getMaterialOptionsHandle(0); @@ -136,17 +137,17 @@ TEST_F(MigrationTest, migrate_from_V10) { ASSERT_TRUE(meshnode->getMaterialPrivateHandle(0)); ASSERT_TRUE(meshnode->getMaterialPrivateHandle(0).asBool()); - auto material = raco::core::Queries::findByName(racoproject->project()->instances(), "Material")->as(); + auto material = core::Queries::findByName(racoproject->project()->instances(), "Material")->as(); ASSERT_TRUE(material != nullptr); ASSERT_TRUE(material->uniforms_->size() > 0); for (size_t i = 0; i < material->uniforms_->size(); i++) { - auto engineType = material->uniforms_->get(i)->query()->type(); - bool hasLinkAnno = material->uniforms_->get(i)->query() != nullptr; - ASSERT_TRUE((raco::core::PropertyInterface::primitiveType(engineType) != raco::data_storage::PrimitiveType::Ref) == hasLinkAnno); + auto engineType = material->uniforms_->get(i)->query()->type(); + bool hasLinkAnno = material->uniforms_->get(i)->query() != nullptr; + ASSERT_TRUE((core::PropertyInterface::primitiveType(engineType) != data_storage::PrimitiveType::Ref) == hasLinkAnno); } - ValueHandle uniforms{material, &raco::user_types::Material::uniforms_}; + ValueHandle uniforms{material, &user_types::Material::uniforms_}; ASSERT_EQ(uniforms.get("scalar").asDouble(), 42.0); ASSERT_EQ(uniforms.get("count_").asInt(), 42); ASSERT_EQ(*uniforms.get("vec").asVec3f().x, 0.1); @@ -157,7 +158,7 @@ TEST_F(MigrationTest, migrate_from_V10) { TEST_F(MigrationTest, migrate_from_V12) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V12.rca").string())); - auto pcam = raco::core::Queries::findByName(racoproject->project()->instances(), "PerspectiveCamera")->as(); + auto pcam = core::Queries::findByName(racoproject->project()->instances(), "PerspectiveCamera")->as(); ASSERT_EQ(*pcam->viewport_->offsetX_, 1); ASSERT_EQ(*pcam->viewport_->offsetY_, 3); // linked ASSERT_EQ(*pcam->viewport_->width_, 1441); @@ -168,7 +169,7 @@ TEST_F(MigrationTest, migrate_from_V12) { ASSERT_EQ(pcam->frustum_->get("fieldOfView")->asDouble(), 36.0); ASSERT_EQ(pcam->frustum_->get("aspectRatio")->asDouble(), 3.0); - auto ocam = raco::core::Queries::findByName(racoproject->project()->instances(), "OrthographicCamera")->as(); + auto ocam = core::Queries::findByName(racoproject->project()->instances(), "OrthographicCamera")->as(); ASSERT_EQ(*ocam->viewport_->offsetX_, 2); ASSERT_EQ(*ocam->viewport_->offsetY_, 3); // linked ASSERT_EQ(*ocam->viewport_->width_, 1442); @@ -181,51 +182,51 @@ TEST_F(MigrationTest, migrate_from_V12) { ASSERT_EQ(*ocam->frustum_->bottom_, -8.0); ASSERT_EQ(*ocam->frustum_->top_, 12.0); - auto material = raco::core::Queries::findByName(racoproject->project()->instances(), "Material")->as(); - ASSERT_EQ(*material->options_->blendOperationColor_, ramses::EBlendOperation_Max); - ASSERT_EQ(*material->options_->blendOperationAlpha_, ramses::EBlendOperation_Add); + auto material = core::Queries::findByName(racoproject->project()->instances(), "Material")->as(); + ASSERT_EQ(*material->options_->blendOperationColor_, static_cast(user_types::EBlendOperation::Max)); + ASSERT_EQ(*material->options_->blendOperationAlpha_, static_cast(user_types::EBlendOperation::Add)); - ASSERT_EQ(*material->options_->blendFactorSrcColor_, ramses::EBlendFactor_One); - ASSERT_EQ(*material->options_->blendFactorDestColor_, ramses::EBlendFactor_AlphaSaturate); - ASSERT_EQ(*material->options_->blendFactorSrcAlpha_, ramses::EBlendFactor_Zero); - ASSERT_EQ(*material->options_->blendFactorDestAlpha_, ramses::EBlendFactor_AlphaSaturate); + ASSERT_EQ(*material->options_->blendFactorSrcColor_, static_cast(user_types::EBlendFactor::One)); + ASSERT_EQ(*material->options_->blendFactorDestColor_, static_cast(user_types::EBlendFactor::AlphaSaturate)); + ASSERT_EQ(*material->options_->blendFactorSrcAlpha_, static_cast(user_types::EBlendFactor::Zero)); + ASSERT_EQ(*material->options_->blendFactorDestAlpha_, static_cast(user_types::EBlendFactor::AlphaSaturate)); ASSERT_EQ(*material->options_->depthwrite_, false); - ASSERT_EQ(*material->options_->depthFunction_, ramses::EDepthFunc_Never); - ASSERT_EQ(*material->options_->cullmode_, ramses::ECullMode_FrontAndBackFacing); + ASSERT_EQ(*material->options_->depthFunction_, static_cast(user_types::EDepthFunc::Never)); + ASSERT_EQ(*material->options_->cullmode_, static_cast(user_types::ECullMode::FrontAndBackFacing)); ASSERT_EQ(*material->options_->blendColor_->x, 1.0); ASSERT_EQ(*material->options_->blendColor_->y, 2.0); ASSERT_EQ(*material->options_->blendColor_->z, 3.0); ASSERT_EQ(*material->options_->blendColor_->w, 4.0); - auto meshnode = raco::core::Queries::findByName(racoproject->project()->instances(), "MeshNode")->as(); - auto options = dynamic_cast(&meshnode->materials_->get(0)->asTable().get("options")->asStruct()); + auto meshnode = core::Queries::findByName(racoproject->project()->instances(), "MeshNode")->as(); + auto options = dynamic_cast(&meshnode->materials_->get(0)->asTable().get("options")->asStruct()); - ASSERT_EQ(*options->blendOperationColor_, ramses::EBlendOperation_Add); - ASSERT_EQ(*options->blendOperationAlpha_, ramses::EBlendOperation_Max); + ASSERT_EQ(*options->blendOperationColor_, static_cast(user_types::EBlendOperation::Add)); + ASSERT_EQ(*options->blendOperationAlpha_, static_cast(user_types::EBlendOperation::Max)); - ASSERT_EQ(*options->blendFactorSrcColor_, ramses::EBlendFactor_AlphaSaturate); - ASSERT_EQ(*options->blendFactorDestColor_, ramses::EBlendFactor_One); - ASSERT_EQ(*options->blendFactorSrcAlpha_, ramses::EBlendFactor_AlphaSaturate); - ASSERT_EQ(*options->blendFactorDestAlpha_, ramses::EBlendFactor_Zero); + ASSERT_EQ(*options->blendFactorSrcColor_, static_cast(user_types::EBlendFactor::AlphaSaturate)); + ASSERT_EQ(*options->blendFactorDestColor_, static_cast(user_types::EBlendFactor::One)); + ASSERT_EQ(*options->blendFactorSrcAlpha_, static_cast(user_types::EBlendFactor::AlphaSaturate)); + ASSERT_EQ(*options->blendFactorDestAlpha_, static_cast(user_types::EBlendFactor::Zero)); ASSERT_EQ(*options->depthwrite_, false); - ASSERT_EQ(*options->depthFunction_, ramses::EDepthFunc_Never); - ASSERT_EQ(*options->cullmode_, ramses::ECullMode_FrontAndBackFacing); + ASSERT_EQ(*options->depthFunction_, static_cast(user_types::EDepthFunc::Never)); + ASSERT_EQ(*options->cullmode_, static_cast(user_types::ECullMode::FrontAndBackFacing)); ASSERT_EQ(*options->blendColor_->x, 4.0); ASSERT_EQ(*options->blendColor_->y, 3.0); ASSERT_EQ(*options->blendColor_->z, 2.0); ASSERT_EQ(*options->blendColor_->w, 1.0); - auto meshnode_no_mesh = raco::core::Queries::findByName(racoproject->project()->instances(), "meshnode_no_mesh")->as(); + auto meshnode_no_mesh = core::Queries::findByName(racoproject->project()->instances(), "meshnode_no_mesh")->as(); ASSERT_EQ(meshnode_no_mesh->materials_->size(), 0); - auto meshnode_mesh_no_mat = raco::core::Queries::findByName(racoproject->project()->instances(), "meshnode_mesh_no_mat")->as(); + auto meshnode_mesh_no_mat = core::Queries::findByName(racoproject->project()->instances(), "meshnode_mesh_no_mat")->as(); ASSERT_EQ(meshnode_mesh_no_mat->materials_->size(), 1); - auto lua = raco::core::Queries::findByName(racoproject->project()->instances(), "LuaScript")->as(); + auto lua = core::Queries::findByName(racoproject->project()->instances(), "LuaScript")->as(); checkLinks(*racoproject->project(), {{{lua, {"outputs", "int"}}, {pcam, {"viewport", "offsetY"}}}, {{lua, {"outputs", "float"}}, {pcam, {"frustum", "nearPlane"}}}, {{lua, {"outputs", "int"}}, {ocam, {"viewport", "offsetY"}}}, @@ -235,35 +236,35 @@ TEST_F(MigrationTest, migrate_from_V12) { TEST_F(MigrationTest, migrate_from_V13) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V13.rca").string())); - auto textureNotFlipped = raco::core::Queries::findByName(racoproject->project()->instances(), "DuckTextureNotFlipped")->as(); + auto textureNotFlipped = core::Queries::findByName(racoproject->project()->instances(), "DuckTextureNotFlipped")->as(); ASSERT_FALSE(*textureNotFlipped->flipTexture_); - auto textureFlipped = raco::core::Queries::findByName(racoproject->project()->instances(), "DuckTextureFlipped")->as(); + auto textureFlipped = core::Queries::findByName(racoproject->project()->instances(), "DuckTextureFlipped")->as(); ASSERT_TRUE(*textureFlipped->flipTexture_); } TEST_F(MigrationTest, migrate_from_V14) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V14.rca").string())); - auto camera = raco::core::Queries::findByName(racoproject->project()->instances(), "PerspectiveCamera")->as(); - auto renderpass = raco::core::Queries::findByName(racoproject->project()->instances(), "MainRenderPass")->as(); + auto camera = core::Queries::findByName(racoproject->project()->instances(), "PerspectiveCamera")->as(); + auto renderpass = core::Queries::findByName(racoproject->project()->instances(), "MainRenderPass")->as(); ASSERT_EQ(*renderpass->camera_, camera); - auto texture = raco::core::Queries::findByName(racoproject->project()->instances(), "Texture")->as(); - auto mat_no_tex = raco::core::Queries::findByName(racoproject->project()->instances(), "mat_no_tex")->as(); - auto mat_with_tex = raco::core::Queries::findByName(racoproject->project()->instances(), "mat_with_tex")->as(); + auto texture = core::Queries::findByName(racoproject->project()->instances(), "Texture")->as(); + auto mat_no_tex = core::Queries::findByName(racoproject->project()->instances(), "mat_no_tex")->as(); + auto mat_with_tex = core::Queries::findByName(racoproject->project()->instances(), "mat_with_tex")->as(); ASSERT_EQ(mat_no_tex->uniforms_->get("u_Tex")->asRef(), nullptr); ASSERT_EQ(mat_with_tex->uniforms_->get("u_Tex")->asRef(), texture); - auto buffer = create("buffer"); + auto buffer = create("buffer"); ASSERT_TRUE(mat_no_tex->uniforms_->get("u_Tex")->canSetRef(texture)); ASSERT_TRUE(mat_with_tex->uniforms_->get("u_Tex")->canSetRef(texture)); ASSERT_TRUE(mat_no_tex->uniforms_->get("u_Tex")->canSetRef(buffer)); ASSERT_TRUE(mat_with_tex->uniforms_->get("u_Tex")->canSetRef(buffer)); - auto meshnode_no_tex = raco::core::Queries::findByName(racoproject->project()->instances(), "meshnode_no_tex")->as(); - auto meshnode_with_tex = raco::core::Queries::findByName(racoproject->project()->instances(), "meshnode_with_tex")->as(); + auto meshnode_no_tex = core::Queries::findByName(racoproject->project()->instances(), "meshnode_no_tex")->as(); + auto meshnode_with_tex = core::Queries::findByName(racoproject->project()->instances(), "meshnode_with_tex")->as(); ASSERT_EQ(meshnode_no_tex->getUniformContainer(0)->get("u_Tex")->asRef(), nullptr); ASSERT_EQ(meshnode_with_tex->getUniformContainer(0)->get("u_Tex")->asRef(), texture); @@ -277,25 +278,25 @@ TEST_F(MigrationTest, migrate_from_V14) { TEST_F(MigrationTest, migrate_from_V14b) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V14b.rca").string())); - auto camera = raco::core::Queries::findByName(racoproject->project()->instances(), "OrthographicCamera")->as(); - auto renderpass = raco::core::Queries::findByName(racoproject->project()->instances(), "MainRenderPass")->as(); + auto camera = core::Queries::findByName(racoproject->project()->instances(), "OrthographicCamera")->as(); + auto renderpass = core::Queries::findByName(racoproject->project()->instances(), "MainRenderPass")->as(); ASSERT_EQ(*renderpass->camera_, camera); - auto texture = raco::core::Queries::findByName(racoproject->project()->instances(), "Texture")->as(); - auto mat_no_tex = raco::core::Queries::findByName(racoproject->project()->instances(), "mat_no_tex")->as(); - auto mat_with_tex = raco::core::Queries::findByName(racoproject->project()->instances(), "mat_with_tex")->as(); + auto texture = core::Queries::findByName(racoproject->project()->instances(), "Texture")->as(); + auto mat_no_tex = core::Queries::findByName(racoproject->project()->instances(), "mat_no_tex")->as(); + auto mat_with_tex = core::Queries::findByName(racoproject->project()->instances(), "mat_with_tex")->as(); ASSERT_EQ(mat_no_tex->uniforms_->get("u_Tex")->asRef(), nullptr); ASSERT_EQ(mat_with_tex->uniforms_->get("u_Tex")->asRef(), texture); - auto buffer = create("buffer"); + auto buffer = create("buffer"); ASSERT_TRUE(mat_no_tex->uniforms_->get("u_Tex")->canSetRef(texture)); ASSERT_TRUE(mat_with_tex->uniforms_->get("u_Tex")->canSetRef(texture)); ASSERT_TRUE(mat_no_tex->uniforms_->get("u_Tex")->canSetRef(buffer)); ASSERT_TRUE(mat_with_tex->uniforms_->get("u_Tex")->canSetRef(buffer)); - auto meshnode_no_tex = raco::core::Queries::findByName(racoproject->project()->instances(), "meshnode_no_tex")->as(); - auto meshnode_with_tex = raco::core::Queries::findByName(racoproject->project()->instances(), "meshnode_with_tex")->as(); + auto meshnode_no_tex = core::Queries::findByName(racoproject->project()->instances(), "meshnode_no_tex")->as(); + auto meshnode_with_tex = core::Queries::findByName(racoproject->project()->instances(), "meshnode_with_tex")->as(); ASSERT_EQ(meshnode_no_tex->getUniformContainer(0)->get("u_Tex")->asRef(), nullptr); ASSERT_EQ(meshnode_with_tex->getUniformContainer(0)->get("u_Tex")->asRef(), texture); @@ -309,24 +310,24 @@ TEST_F(MigrationTest, migrate_from_V14b) { TEST_F(MigrationTest, migrate_from_V14c) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V14c.rca").string())); - auto renderpass = raco::core::Queries::findByName(racoproject->project()->instances(), "MainRenderPass")->as(); + auto renderpass = core::Queries::findByName(racoproject->project()->instances(), "MainRenderPass")->as(); ASSERT_EQ(*renderpass->camera_, nullptr); - auto texture = raco::core::Queries::findByName(racoproject->project()->instances(), "Texture")->as(); - auto mat_no_tex = raco::core::Queries::findByName(racoproject->project()->instances(), "mat_no_tex")->as(); - auto mat_with_tex = raco::core::Queries::findByName(racoproject->project()->instances(), "mat_with_tex")->as(); + auto texture = core::Queries::findByName(racoproject->project()->instances(), "Texture")->as(); + auto mat_no_tex = core::Queries::findByName(racoproject->project()->instances(), "mat_no_tex")->as(); + auto mat_with_tex = core::Queries::findByName(racoproject->project()->instances(), "mat_with_tex")->as(); ASSERT_EQ(mat_no_tex->uniforms_->get("u_Tex")->asRef(), nullptr); ASSERT_EQ(mat_with_tex->uniforms_->get("u_Tex")->asRef(), texture); - auto buffer = create("buffer"); + auto buffer = create("buffer"); ASSERT_TRUE(mat_no_tex->uniforms_->get("u_Tex")->canSetRef(texture)); ASSERT_TRUE(mat_with_tex->uniforms_->get("u_Tex")->canSetRef(texture)); ASSERT_TRUE(mat_no_tex->uniforms_->get("u_Tex")->canSetRef(buffer)); ASSERT_TRUE(mat_with_tex->uniforms_->get("u_Tex")->canSetRef(buffer)); - auto meshnode_no_tex = raco::core::Queries::findByName(racoproject->project()->instances(), "meshnode_no_tex")->as(); - auto meshnode_with_tex = raco::core::Queries::findByName(racoproject->project()->instances(), "meshnode_with_tex")->as(); + auto meshnode_no_tex = core::Queries::findByName(racoproject->project()->instances(), "meshnode_no_tex")->as(); + auto meshnode_with_tex = core::Queries::findByName(racoproject->project()->instances(), "meshnode_with_tex")->as(); ASSERT_EQ(meshnode_no_tex->getUniformContainer(0)->get("u_Tex")->asRef(), nullptr); ASSERT_EQ(meshnode_with_tex->getUniformContainer(0)->get("u_Tex")->asRef(), texture); @@ -340,12 +341,12 @@ TEST_F(MigrationTest, migrate_from_V14c) { TEST_F(MigrationTest, migrate_from_V16) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V16.rca").string())); - auto renderlayeropt = raco::core::Queries::findByName(racoproject->project()->instances(), "RenderLayerOptimized")->as(); - ASSERT_EQ(renderlayeropt->sortOrder_.asInt(), static_cast(raco::user_types::ERenderLayerOrder::Manual)); - auto renderlayermanual = raco::core::Queries::findByName(racoproject->project()->instances(), "RenderLayerManual")->as(); - ASSERT_EQ(renderlayermanual->sortOrder_.asInt(), static_cast(raco::user_types::ERenderLayerOrder::Manual)); - auto renderlayerscenegraph = raco::core::Queries::findByName(racoproject->project()->instances(), "RenderLayerSceneGraph")->as(); - ASSERT_EQ(renderlayerscenegraph->sortOrder_.asInt(), static_cast(raco::user_types::ERenderLayerOrder::SceneGraph)); + auto renderlayeropt = core::Queries::findByName(racoproject->project()->instances(), "RenderLayerOptimized")->as(); + ASSERT_EQ(renderlayeropt->sortOrder_.asInt(), static_cast(user_types::ERenderLayerOrder::Manual)); + auto renderlayermanual = core::Queries::findByName(racoproject->project()->instances(), "RenderLayerManual")->as(); + ASSERT_EQ(renderlayermanual->sortOrder_.asInt(), static_cast(user_types::ERenderLayerOrder::Manual)); + auto renderlayerscenegraph = core::Queries::findByName(racoproject->project()->instances(), "RenderLayerSceneGraph")->as(); + ASSERT_EQ(renderlayerscenegraph->sortOrder_.asInt(), static_cast(user_types::ERenderLayerOrder::SceneGraph)); } TEST_F(MigrationTest, migrate_from_V18) { @@ -378,7 +379,7 @@ TEST_F(MigrationTest, migrate_from_V21_custom_paths) { std::string scriptSubdirectory = "spts"; std::string shaderSubdirectory = "shds"; - auto preferencesFile = raco::core::PathManager::preferenceFilePath(); + auto preferencesFile = core::PathManager::preferenceFilePath(); if (preferencesFile.exists()) { std::filesystem::remove(preferencesFile); } @@ -410,10 +411,10 @@ TEST_F(MigrationTest, migrate_from_V21_custom_paths) { TEST_F(MigrationTest, migrate_from_V23) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V23.rca").string())); - auto prefab = raco::core::Queries::findByName(racoproject->project()->instances(), "Prefab")->as(); - auto inst = raco::core::Queries::findByName(racoproject->project()->instances(), "PrefabInstance")->as(); - auto prefab_node = prefab->children_->asVector()[0]->as(); - auto inst_node = inst->children_->asVector()[0]->as(); + auto prefab = core::Queries::findByName(racoproject->project()->instances(), "Prefab")->as(); + auto inst = core::Queries::findByName(racoproject->project()->instances(), "PrefabInstance")->as(); + auto prefab_node = prefab->children_->asVector()[0]->as(); + auto inst_node = inst->children_->asVector()[0]->as(); EXPECT_EQ(inst_node->objectID(), EditorObject::XorObjectIDs(prefab_node->objectID(), inst->objectID())); } @@ -421,8 +422,8 @@ TEST_F(MigrationTest, migrate_from_V23) { TEST_F(MigrationTest, migrate_from_V29) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V29.rca").string())); - auto animation = raco::core::Queries::findByName(racoproject->project()->instances(), "Animation")->as(); - auto lua = raco::core::Queries::findByName(racoproject->project()->instances(), "LuaScript")->as(); + auto animation = core::Queries::findByName(racoproject->project()->instances(), "Animation")->as(); + auto lua = core::Queries::findByName(racoproject->project()->instances(), "LuaScript")->as(); EXPECT_TRUE(lua->outputs_->hasProperty("flag")); EXPECT_EQ(racoproject->project()->links().size(), 0); @@ -435,11 +436,11 @@ TEST_F(MigrationTest, migrate_from_V29) { TEST_F(MigrationTest, migrate_V29_to_V33) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V29_tags.rca").string())); - auto node = raco::core::Queries::findByName(racoproject->project()->instances(), "Node")->as(); - auto mat_front = raco::core::Queries::findByName(racoproject->project()->instances(), "mat_front")->as(); - auto mat_back = raco::core::Queries::findByName(racoproject->project()->instances(), "mat_back")->as(); + auto node = core::Queries::findByName(racoproject->project()->instances(), "Node")->as(); + auto mat_front = core::Queries::findByName(racoproject->project()->instances(), "mat_front")->as(); + auto mat_back = core::Queries::findByName(racoproject->project()->instances(), "mat_back")->as(); - auto renderlayermanual = raco::core::Queries::findByName(racoproject->project()->instances(), "RenderLayerManual")->as(); + auto renderlayermanual = core::Queries::findByName(racoproject->project()->instances(), "RenderLayerManual")->as(); EXPECT_EQ(node->tags_->asVector(), std::vector({"render_main"})); @@ -459,31 +460,31 @@ TEST_F(MigrationTest, migrate_V30_to_V34) { // So we use a V29 file instead. auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V29_renderlayer.rca").string())); - auto layer_excl = raco::core::Queries::findByName(racoproject->project()->instances(), "layer_exclusive")->as(); - auto layer_incl = raco::core::Queries::findByName(racoproject->project()->instances(), "layer_inclusive")->as(); + auto layer_excl = core::Queries::findByName(racoproject->project()->instances(), "layer_exclusive")->as(); + auto layer_incl = core::Queries::findByName(racoproject->project()->instances(), "layer_inclusive")->as(); - EXPECT_EQ(*layer_excl->materialFilterMode_, static_cast(raco::user_types::ERenderLayerMaterialFilterMode::Exclusive)); - EXPECT_EQ(*layer_incl->materialFilterMode_, static_cast(raco::user_types::ERenderLayerMaterialFilterMode::Inclusive)); + EXPECT_EQ(*layer_excl->materialFilterMode_, static_cast(user_types::ERenderLayerMaterialFilterMode::Exclusive)); + EXPECT_EQ(*layer_incl->materialFilterMode_, static_cast(user_types::ERenderLayerMaterialFilterMode::Inclusive)); } TEST_F(MigrationTest, migrate_from_V35) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V35.rca").string())); - auto prefab = raco::core::Queries::findByName(racoproject->project()->instances(), "Prefab")->as(); - auto inst = raco::core::Queries::findByName(racoproject->project()->instances(), "PrefabInstance")->as(); - auto global_lua = raco::core::Queries::findByName(racoproject->project()->instances(), "global_control")->as(); + auto prefab = core::Queries::findByName(racoproject->project()->instances(), "Prefab")->as(); + auto inst = core::Queries::findByName(racoproject->project()->instances(), "PrefabInstance")->as(); + auto global_lua = core::Queries::findByName(racoproject->project()->instances(), "global_control")->as(); - auto prefab_lua_types = raco::select(prefab->children_->asVector(), "types-scalar"); - auto prefab_int_types = raco::select(prefab->children_->asVector(), "types-scalar"); - auto prefab_int_array = raco::select(prefab->children_->asVector(), "array"); + auto prefab_lua_types = raco::select(prefab->children_->asVector(), "types-scalar"); + auto prefab_int_types = raco::select(prefab->children_->asVector(), "types-scalar"); + auto prefab_int_array = raco::select(prefab->children_->asVector(), "array"); EXPECT_EQ(prefab_int_types->inputs_->get("float")->asDouble(), 1.0); EXPECT_EQ(prefab_int_types->inputs_->get("integer")->asInt(), 2); EXPECT_EQ(prefab_int_types->inputs_->get("integer64")->asInt64(), 3); - auto inst_lua_types = raco::select(inst->children_->asVector(), "types-scalar"); - auto inst_int_types = raco::select(inst->children_->asVector(), "types-scalar"); - auto inst_int_array = raco::select(inst->children_->asVector(), "array"); + auto inst_lua_types = raco::select(inst->children_->asVector(), "types-scalar"); + auto inst_int_types = raco::select(inst->children_->asVector(), "types-scalar"); + auto inst_int_array = raco::select(inst->children_->asVector(), "array"); EXPECT_EQ(inst_int_types->objectID(), EditorObject::XorObjectIDs(prefab_int_types->objectID(), inst->objectID())); @@ -505,19 +506,19 @@ TEST_F(MigrationTest, migrate_from_V35) { TEST_F(MigrationTest, migrate_from_V35_extref) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V35_extref.rca").string())); - auto prefab = raco::core::Queries::findByName(racoproject->project()->instances(), "Prefab")->as(); - auto inst = raco::core::Queries::findByName(racoproject->project()->instances(), "PrefabInstance")->as(); - auto global_lua = raco::core::Queries::findByName(racoproject->project()->instances(), "global_control")->as(); + auto prefab = core::Queries::findByName(racoproject->project()->instances(), "Prefab")->as(); + auto inst = core::Queries::findByName(racoproject->project()->instances(), "PrefabInstance")->as(); + auto global_lua = core::Queries::findByName(racoproject->project()->instances(), "global_control")->as(); - auto prefab_lua_types = raco::select(prefab->children_->asVector(), "types-scalar"); - auto prefab_int_types = raco::select(prefab->children_->asVector(), "types-scalar"); + auto prefab_lua_types = raco::select(prefab->children_->asVector(), "types-scalar"); + auto prefab_int_types = raco::select(prefab->children_->asVector(), "types-scalar"); EXPECT_EQ(prefab_int_types->inputs_->get("float")->asDouble(), 1.0); EXPECT_EQ(prefab_int_types->inputs_->get("integer")->asInt(), 2); EXPECT_EQ(prefab_int_types->inputs_->get("integer64")->asInt64(), 3); - auto inst_lua_types = raco::select(inst->children_->asVector(), "types-scalar"); - auto inst_int_types = raco::select(inst->children_->asVector(), "types-scalar"); + auto inst_lua_types = raco::select(inst->children_->asVector(), "types-scalar"); + auto inst_int_types = raco::select(inst->children_->asVector(), "types-scalar"); EXPECT_EQ(inst_int_types->objectID(), EditorObject::XorObjectIDs(prefab_int_types->objectID(), inst->objectID())); @@ -534,12 +535,12 @@ TEST_F(MigrationTest, migrate_from_V35_extref_nested) { application.switchActiveRaCoProject(QString::fromStdString((test_path() / "migrationTestData" / "V35_extref_nested.rca").string()), {}); auto racoproject = &application.activeRaCoProject(); - auto prefab = raco::core::Queries::findByName(racoproject->project()->instances(), "Prefab")->as(); - auto inst = raco::core::Queries::findByName(racoproject->project()->instances(), "PrefabInstance")->as(); - auto global_lua = raco::core::Queries::findByName(racoproject->project()->instances(), "global_control")->as(); + auto prefab = core::Queries::findByName(racoproject->project()->instances(), "Prefab")->as(); + auto inst = core::Queries::findByName(racoproject->project()->instances(), "PrefabInstance")->as(); + auto global_lua = core::Queries::findByName(racoproject->project()->instances(), "global_control")->as(); - auto prefab_lua_types = raco::select(prefab->children_->asVector(), "types-scalar"); - auto prefab_int_types = raco::select(prefab->children_->asVector(), "types-scalar"); + auto prefab_lua_types = raco::select(prefab->children_->asVector(), "types-scalar"); + auto prefab_int_types = raco::select(prefab->children_->asVector(), "types-scalar"); EXPECT_EQ(prefab_int_types->inputs_->get("float")->asDouble(), 1.0); EXPECT_EQ(prefab_int_types->inputs_->get("integer")->asInt(), 2); @@ -547,9 +548,9 @@ TEST_F(MigrationTest, migrate_from_V35_extref_nested) { auto inst_nested = Queries::findByName(inst->children_->asVector(), "inst_nested"); - auto inst_lua_types = raco::select(inst_nested->children_->asVector(), "types-scalar"); - auto inst_int_types = raco::select(inst_nested->children_->asVector(), "types-scalar"); - auto inst_int_array = raco::select(inst_nested->children_->asVector(), "array"); + auto inst_lua_types = raco::select(inst_nested->children_->asVector(), "types-scalar"); + auto inst_int_types = raco::select(inst_nested->children_->asVector(), "types-scalar"); + auto inst_int_array = raco::select(inst_nested->children_->asVector(), "array"); EXPECT_EQ(inst_int_types->objectID(), EditorObject::XorObjectIDs(prefab_int_types->objectID(), inst_nested->objectID())); @@ -570,38 +571,38 @@ TEST_F(MigrationTest, migrate_from_V39) { auto instances = racoproject->project()->instances(); const auto DELTA = 0.001; - auto luascript = raco::core::Queries::findByName(instances, "LuaScript"); + auto luascript = core::Queries::findByName(instances, "LuaScript"); ASSERT_NE(ValueHandle(luascript, {"inputs", "integer64"}).asInt64(), int64_t{0}); - auto luascript1 = raco::core::Queries::findByName(instances, "LuaScript (1)"); + auto luascript1 = core::Queries::findByName(instances, "LuaScript (1)"); ASSERT_NEAR(ValueHandle(luascript1, {"inputs", "vector3f", "x"}).asDouble(), 0.54897, DELTA); ASSERT_NEAR(ValueHandle(luascript1, {"inputs", "vector3f", "y"}).asDouble(), 1.09794, DELTA); ASSERT_NEAR(ValueHandle(luascript1, {"inputs", "vector3f", "z"}).asDouble(), 3.0, DELTA); - auto luainterface = raco::core::Queries::findByName(instances, "LuaInterface"); + auto luainterface = core::Queries::findByName(instances, "LuaInterface"); ASSERT_EQ(ValueHandle(luainterface, {"inputs", "integer"}).asInt(), 2); - auto luainterface1 = raco::core::Queries::findByName(instances, "LuaInterface (1)"); + auto luainterface1 = core::Queries::findByName(instances, "LuaInterface (1)"); ASSERT_EQ(ValueHandle(luainterface1, {"inputs", "integer"}).asInt(), 2); - auto luascript2 = raco::core::Queries::findByName(instances, "LuaScript (2)"); + auto luascript2 = core::Queries::findByName(instances, "LuaScript (2)"); ASSERT_NEAR(ValueHandle(luascript2, {"outputs", "ovector3f", "x"}).asDouble(), 0.53866, DELTA); ASSERT_NEAR(ValueHandle(luascript2, {"outputs", "ovector3f", "y"}).asDouble(), 1.07732, DELTA); ASSERT_NEAR(ValueHandle(luascript2, {"outputs", "ovector3f", "z"}).asDouble(), 3.0, DELTA); - auto node = raco::core::Queries::findByName(instances, "Node"); + auto node = core::Queries::findByName(instances, "Node"); ASSERT_TRUE(ValueHandle(node, {"visibility"}).asBool()); ASSERT_NEAR(ValueHandle(node, {"scaling", "x"}).asDouble(), 0.54897, DELTA); ASSERT_NEAR(ValueHandle(node, {"scaling", "y"}).asDouble(), 1.09794, DELTA); ASSERT_NEAR(ValueHandle(node, {"scaling", "z"}).asDouble(), 3.0, DELTA); - auto meshNode = raco::core::Queries::findByName(instances, "MeshNode"); + auto meshNode = core::Queries::findByName(instances, "MeshNode"); ASSERT_TRUE(ValueHandle(meshNode, {"visibility"}).asBool()); ASSERT_NEAR(ValueHandle(meshNode, {"scaling", "x"}).asDouble(), 0.54897, DELTA); ASSERT_NEAR(ValueHandle(meshNode, {"scaling", "y"}).asDouble(), 1.09794, DELTA); ASSERT_NEAR(ValueHandle(meshNode, {"scaling", "z"}).asDouble(), 3.0, DELTA); - auto timer = raco::core::Queries::findByName(instances, "Timer"); + auto timer = core::Queries::findByName(instances, "Timer"); ASSERT_EQ(ValueHandle(timer, {"inputs", "ticker_us"}).asInt64(), int64_t{0}); ASSERT_NE(ValueHandle(timer, {"outputs", "ticker_us"}).asInt64(), int64_t{0}); @@ -616,8 +617,8 @@ TEST_F(MigrationTest, migrate_from_V40) { auto racoproject = &application.activeRaCoProject(); auto instances = racoproject->project()->instances(); - auto node = raco::core::Queries::findByName(instances, "Node"); - auto animation = raco::core::Queries::findByName(instances, "Animation"); + auto node = core::Queries::findByName(instances, "Node"); + auto animation = core::Queries::findByName(instances, "Animation"); checkLinks(*racoproject->project(), {{{animation, {"outputs", "Ch0.AnimationChannel"}}, {node, {"translation"}}, true}}); } @@ -625,8 +626,8 @@ TEST_F(MigrationTest, migrate_from_V40) { TEST_F(MigrationTest, migrate_from_V41) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V41.rca").string())); - auto start = raco::core::Queries::findByName(racoproject->project()->instances(), "start")->as(); - auto end = raco::core::Queries::findByName(racoproject->project()->instances(), "end")->as(); + auto start = core::Queries::findByName(racoproject->project()->instances(), "start")->as(); + auto end = core::Queries::findByName(racoproject->project()->instances(), "end")->as(); checkLinks(*racoproject->project(), {{{start, {"outputs", "ofloat"}}, {end, {"inputs", "float"}}, true, false}}); } @@ -634,7 +635,7 @@ TEST_F(MigrationTest, migrate_from_V41) { TEST_F(MigrationTest, migrate_to_V43) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V41.rca").string())); - auto settings = raco::core::Queries::findByName(racoproject->project()->instances(), "V41")->as(); + auto settings = core::Queries::findByName(racoproject->project()->instances(), "V41")->as(); EXPECT_FALSE(settings->hasProperty("enableTimerFlag")); EXPECT_FALSE(settings->hasProperty("runTimer")); @@ -643,14 +644,14 @@ TEST_F(MigrationTest, migrate_to_V43) { TEST_F(MigrationTest, migrate_from_V43) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V43.rca").string())); - auto pcam = raco::core::Queries::findByName(racoproject->project()->instances(), "PerspectiveCamera")->as(); + auto pcam = core::Queries::findByName(racoproject->project()->instances(), "PerspectiveCamera")->as(); ASSERT_EQ(pcam->frustum_->get("nearPlane")->asDouble(), 0.2); ASSERT_EQ(pcam->frustum_->get("farPlane")->asDouble(), 42.0); // linked ASSERT_EQ(pcam->frustum_->get("fieldOfView")->asDouble(), 4.0); ASSERT_EQ(pcam->frustum_->get("aspectRatio")->asDouble(), 5.0); - auto renderpass = raco::core::Queries::findByName(racoproject->project()->instances(), "RenderPass")->as(); + auto renderpass = core::Queries::findByName(racoproject->project()->instances(), "RenderPass")->as(); EXPECT_EQ(*renderpass->enabled_, false); EXPECT_EQ(*renderpass->renderOrder_, 7); @@ -659,39 +660,41 @@ TEST_F(MigrationTest, migrate_from_V43) { EXPECT_EQ(*renderpass->clearColor_->z, 3.0); EXPECT_EQ(*renderpass->clearColor_->w, 4.0); - auto lua = raco::core::Queries::findByName(racoproject->project()->instances(), "LuaScript")->as(); + auto lua = core::Queries::findByName(racoproject->project()->instances(), "LuaScript")->as(); checkLinks(*racoproject->project(), {{{{lua, {"outputs", "float"}}, {pcam, {"frustum", "farPlane"}}}}}); } TEST_F(MigrationTest, migrate_from_V44) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V44.rca").string())); - auto layer = raco::core::Queries::findByName(racoproject->project()->instances(), "MainRenderLayer")->as(); + auto layer = core::Queries::findByName(racoproject->project()->instances(), "MainRenderLayer")->as(); auto anno_red = layer->renderableTags_->get("red")->query(); EXPECT_TRUE(anno_red != nullptr); - EXPECT_EQ(*anno_red->featureLevel_, 3); + // migration to V2001 reset feature level to 1 + EXPECT_EQ(*anno_red->featureLevel_, 1); auto anno_green = layer->renderableTags_->get("green")->query(); EXPECT_TRUE(anno_green != nullptr); - EXPECT_EQ(*anno_green->featureLevel_, 3); + // migration to V2001 reset feature level to 1 + EXPECT_EQ(*anno_green->featureLevel_, 1); } TEST_F(MigrationTest, migrate_from_V45) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V45.rca").string())); - auto perspCamera = raco::core::Queries::findByName(racoproject->project()->instances(), "PerspectiveCamera")->as(); + auto perspCamera = core::Queries::findByName(racoproject->project()->instances(), "PerspectiveCamera")->as(); EXPECT_EQ(*perspCamera->viewport_->get("width")->query>()->min_, 1); EXPECT_EQ(*perspCamera->viewport_->get("height")->query>()->min_, 1); - auto orthoCamera = raco::core::Queries::findByName(racoproject->project()->instances(), "OrthographicCamera")->as(); + auto orthoCamera = core::Queries::findByName(racoproject->project()->instances(), "OrthographicCamera")->as(); EXPECT_EQ(*orthoCamera->viewport_->get("width")->query>()->min_, 1); EXPECT_EQ(*orthoCamera->viewport_->get("height")->query>()->min_, 1); - auto renderTarget = raco::core::Queries::findByName(racoproject->project()->instances(), "RenderTarget")->as(); + auto renderTarget = core::Queries::findByName(racoproject->project()->instances(), "RenderTarget")->as(); - EXPECT_TRUE(renderTarget->buffer0_.query() != nullptr); + EXPECT_TRUE(renderTarget->buffers_.query() != nullptr); } TEST_F(MigrationTest, migrate_from_V50) { @@ -699,26 +702,26 @@ TEST_F(MigrationTest, migrate_from_V50) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V50.rca").string())); - auto intf_scalar = raco::core::Queries::findByName(racoproject->project()->instances(), "intf-scalar")->as(); - auto intf_array = raco::core::Queries::findByName(racoproject->project()->instances(), "intf-array")->as(); - auto intf_struct = raco::core::Queries::findByName(racoproject->project()->instances(), "intf-struct")->as(); + auto intf_scalar = core::Queries::findByName(racoproject->project()->instances(), "intf-scalar")->as(); + auto intf_array = core::Queries::findByName(racoproject->project()->instances(), "intf-array")->as(); + auto intf_struct = core::Queries::findByName(racoproject->project()->instances(), "intf-struct")->as(); - auto texture = raco::core::Queries::findByName(racoproject->project()->instances(), "texture"); + auto texture = core::Queries::findByName(racoproject->project()->instances(), "texture"); - auto node = raco::core::Queries::findByName(racoproject->project()->instances(), "Node"); - auto meshnode_no_mat = raco::core::Queries::findByName(racoproject->project()->instances(), "meshnode_no_mat"); + auto node = core::Queries::findByName(racoproject->project()->instances(), "Node"); + auto meshnode_no_mat = core::Queries::findByName(racoproject->project()->instances(), "meshnode_no_mat"); - auto mat_scalar = raco::core::Queries::findByName(racoproject->project()->instances(), "mat_scalar")->as(); + auto mat_scalar = core::Queries::findByName(racoproject->project()->instances(), "mat_scalar")->as(); EXPECT_EQ(ValueHandle(mat_scalar, {"uniforms", "i"}).asInt(), 2); checkVec2iValue(ValueHandle(mat_scalar, {"uniforms", "iv2"}), {1, 2}); - auto mat_array_link_array = raco::core::Queries::findByName(racoproject->project()->instances(), "mat_array_link_array")->as(); + auto mat_array_link_array = core::Queries::findByName(racoproject->project()->instances(), "mat_array_link_array")->as(); EXPECT_EQ(ValueHandle(mat_array_link_array, {"uniforms", "ivec", "1"}).asInt(), 1); EXPECT_EQ(ValueHandle(mat_array_link_array, {"uniforms", "ivec", "2"}).asInt(), 2); - auto mat_array_link_member = raco::core::Queries::findByName(racoproject->project()->instances(), "mat_array_link_member")->as(); + auto mat_array_link_member = core::Queries::findByName(racoproject->project()->instances(), "mat_array_link_member")->as(); - auto mat_struct = raco::core::Queries::findByName(racoproject->project()->instances(), "mat_struct")->as(); + auto mat_struct = core::Queries::findByName(racoproject->project()->instances(), "mat_struct")->as(); EXPECT_EQ(ValueHandle(mat_struct, {"uniforms", "s_prims", "i"}).asInt(), 42); checkVec2iValue(ValueHandle(mat_struct, {"uniforms", "s_prims", "iv2"}), {1, 2}); @@ -742,17 +745,17 @@ TEST_F(MigrationTest, migrate_from_V50) { checkVec2iValue(ValueHandle(mat_struct, {"uniforms", "s_a_prims", "aivec2", "2"}), {3, 4}); - auto meshnode_mat_scalar = raco::core::Queries::findByName(racoproject->project()->instances(), "meshnode_mat_scalar"); + auto meshnode_mat_scalar = core::Queries::findByName(racoproject->project()->instances(), "meshnode_mat_scalar"); EXPECT_EQ(ValueHandle(meshnode_mat_scalar, {"materials", "material", "uniforms", "i"}).asInt(), 2); checkVec2iValue(ValueHandle(meshnode_mat_scalar, {"materials", "material", "uniforms", "iv2"}), {1, 2}); - auto meshnode_mat_array_link_array = raco::core::Queries::findByName(racoproject->project()->instances(), "meshnode_mat_array_link_array"); + auto meshnode_mat_array_link_array = core::Queries::findByName(racoproject->project()->instances(), "meshnode_mat_array_link_array"); EXPECT_EQ(ValueHandle(meshnode_mat_array_link_array, {"materials", "material", "uniforms", "ivec", "1"}).asInt(), 1); EXPECT_EQ(ValueHandle(meshnode_mat_array_link_array, {"materials", "material", "uniforms", "ivec", "2"}).asInt(), 2); - auto meshnode_mat_array_link_member = raco::core::Queries::findByName(racoproject->project()->instances(), "meshnode_mat_array_link_member"); + auto meshnode_mat_array_link_member = core::Queries::findByName(racoproject->project()->instances(), "meshnode_mat_array_link_member"); - auto meshnode_mat_struct = raco::core::Queries::findByName(racoproject->project()->instances(), "meshnode_mat_struct"); + auto meshnode_mat_struct = core::Queries::findByName(racoproject->project()->instances(), "meshnode_mat_struct"); EXPECT_EQ(ValueHandle(meshnode_mat_struct, {"materials", "material", "uniforms", "s_prims", "i"}).asInt(), 42); checkVec2iValue(ValueHandle(meshnode_mat_struct, {"materials", "material", "uniforms", "s_prims", "iv2"}), {1, 2}); @@ -838,8 +841,8 @@ TEST_F(MigrationTest, migrate_from_V51_vec_struct_link_validity_update) { auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V51_link_vec_struct.rca").string())); - auto start = raco::core::Queries::findByName(racoproject->project()->instances(), "start")->as(); - auto end = raco::core::Queries::findByName(racoproject->project()->instances(), "end")->as(); + auto start = core::Queries::findByName(racoproject->project()->instances(), "start")->as(); + auto end = core::Queries::findByName(racoproject->project()->instances(), "end")->as(); checkLinks(*racoproject->project(), {{{start, {"inputs", "v3f"}}, {end, {"inputs", "s3f"}}, false, false}, @@ -933,6 +936,384 @@ TEST_F(MigrationTest, migrate_from_V52) { EXPECT_EQ(settings->defaultResourceDirectories_->shaderSubdirectory_.query()->getFolderTypeKey(), core::PathManager::FolderTypeKeys::Project); } + +TEST_F(MigrationTest, migrate_from_V54) { + using namespace raco; + auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V54.rca").string())); + + auto node = core::Queries::findByName(racoproject->project()->instances(), "Node")->as(); + auto meshnode = core::Queries::findByName(racoproject->project()->instances(), "MeshNode")->as(); + auto nodePrefab = core::Queries::findByName(racoproject->project()->instances(), "NodePrefab")->as(); + auto prefab = core::Queries::findByName(racoproject->project()->instances(), "Prefab")->as(); + + EXPECT_EQ(node->children_->asVector(), std::vector({meshnode})); + EXPECT_EQ(prefab->children_->asVector(), std::vector({nodePrefab})); + + auto animation = core::Queries::findByName(racoproject->project()->instances(), "Animation")->as(); + auto animationChannel = core::Queries::findByName(racoproject->project()->instances(), "AnimationChannel")->as(); + auto skin = core::Queries::findByName(racoproject->project()->instances(), "Skin")->as(); + + auto renderBuffer = core::Queries::findByName(racoproject->project()->instances(), "RenderBuffer")->as(); + auto renderBufferMS = core::Queries::findByName(racoproject->project()->instances(), "RenderBufferMS")->as(); + auto renderLayer = core::Queries::findByName(racoproject->project()->instances(), "MainRenderLayer")->as(); + + auto renderTarget = core::Queries::findByName(racoproject->project()->instances(), "RenderTarget")->as(); + auto renderPass = core::Queries::findByName(racoproject->project()->instances(), "MainRenderPass")->as(); + + EXPECT_EQ(animation->animationChannels_->asVector(), + std::vector({animationChannel, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); + EXPECT_EQ(skin->targets_->asVector(), std::vector({meshnode})); + + EXPECT_EQ(renderTarget->buffers_->asVector(), + std::vector({renderBuffer, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); + + EXPECT_EQ(renderPass->layers_->asVector(), + std::vector({renderLayer, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); +} + +TEST_F(MigrationTest, migrate_from_V55) { + using namespace raco; + auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V55.rca").string())); + + auto renderBuffer = core::Queries::findByName(racoproject->project()->instances(), "RenderBuffer")->as(); + auto renderBufferMS = core::Queries::findByName(racoproject->project()->instances(), "RenderBufferMS")->as(); + + auto renderTarget = core::Queries::findByName(racoproject->project()->instances(), "RenderTarget")->as(); + auto renderTarget_MS = core::Queries::findByName(racoproject->project()->instances(), "RenderTarget_MS")->as(); + auto renderTarget_mixed = core::Queries::findByName(racoproject->project()->instances(), "RenderTarget_mixed")->as(); + + auto mainRenderPass = core::Queries::findByName(racoproject->project()->instances(), "MainRenderPass")->as(); + auto renderPass = core::Queries::findByName(racoproject->project()->instances(), "RenderPass")->as(); + auto renderPass_MS = core::Queries::findByName(racoproject->project()->instances(), "RenderPass_MS")->as(); + auto renderPass_mixed = core::Queries::findByName(racoproject->project()->instances(), "RenderPass_mixed")->as(); + + EXPECT_EQ(*mainRenderPass->target_, nullptr); + EXPECT_EQ(*renderPass->target_, renderTarget); + EXPECT_EQ(*renderPass_MS->target_, renderTarget_MS); + EXPECT_EQ(*renderPass_mixed->target_, renderTarget_mixed); + + EXPECT_EQ(renderTarget->buffers_->asVector(), + std::vector({renderBuffer, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); + EXPECT_EQ(renderTarget_MS->buffers_->asVector(), + std::vector({renderBufferMS, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); + EXPECT_EQ(renderTarget_mixed->buffers_->asVector(), + std::vector({renderBuffer, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); + + EXPECT_EQ(renderTarget->userTags_->asVector(), std::vector({"cat"})); + EXPECT_EQ(renderTarget_MS->userTags_->asVector(), std::vector({"cat", "dog"})); + EXPECT_EQ(renderTarget_mixed->userTags_->asVector(), std::vector({"dog"})); +} + +// The following tests verify the migration and fixup of the split of the render targets in the ->V56 migration: +TEST_F(MigrationTest, migrate_from_V54_rendertarget_base) { + using namespace raco; + auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V54-rendertarget-base.rca").string())); + + auto renderBuffer = core::Queries::findByName(racoproject->project()->instances(), "RenderBuffer")->as(); + auto renderBufferMS = core::Queries::findByName(racoproject->project()->instances(), "RenderBufferMS")->as(); + + auto renderTarget_normal = core::Queries::findByName(racoproject->project()->instances(), "rt-normal")->as(); + auto renderTarget_multi = core::Queries::findByName(racoproject->project()->instances(), "rt-multi")->as(); + auto renderTarget_mixed = core::Queries::findByName(racoproject->project()->instances(), "rt-mixed")->as(); + + auto mainRenderPass = core::Queries::findByName(racoproject->project()->instances(), "MainRenderPass")->as(); + auto renderPass_normal = core::Queries::findByName(racoproject->project()->instances(), "rp-normal")->as(); + auto renderPass_multi = core::Queries::findByName(racoproject->project()->instances(), "rp-multi")->as(); + auto renderPass_mixed = core::Queries::findByName(racoproject->project()->instances(), "rp-mixed")->as(); + + EXPECT_EQ(*mainRenderPass->target_, nullptr); + EXPECT_EQ(*renderPass_normal->target_, renderTarget_normal); + EXPECT_EQ(*renderPass_multi->target_, renderTarget_multi); + EXPECT_EQ(*renderPass_mixed->target_, renderTarget_mixed); + + EXPECT_EQ(renderTarget_normal->buffers_->asVector(), + std::vector({renderBuffer, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); + EXPECT_EQ(renderTarget_multi->buffers_->asVector(), + std::vector({renderBufferMS, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); + EXPECT_EQ(renderTarget_mixed->buffers_->asVector(), + std::vector({renderBuffer, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); +} + +TEST_F(MigrationTest, migrate_from_V54_rendertarget_extref) { + using namespace raco; + auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V54-rendertarget-extref.rca").string())); + + auto renderBuffer = core::Queries::findByName(racoproject->project()->instances(), "RenderBuffer")->as(); + auto renderBufferMS = core::Queries::findByName(racoproject->project()->instances(), "RenderBufferMS")->as(); + + auto renderTarget_normal = core::Queries::findByName(racoproject->project()->instances(), "rt-normal")->as(); + auto renderTarget_multi = core::Queries::findByName(racoproject->project()->instances(), "rt-multi")->as(); + auto renderTarget_mixed = core::Queries::findByName(racoproject->project()->instances(), "rt-mixed")->as(); + EXPECT_TRUE(renderTarget_normal->query() != nullptr); + EXPECT_TRUE(renderTarget_multi->query() != nullptr); + EXPECT_TRUE(renderTarget_mixed->query() != nullptr); + + auto mainRenderPass = core::Queries::findByName(racoproject->project()->instances(), "MainRenderPass")->as(); + auto renderPass_normal = core::Queries::findByName(racoproject->project()->instances(), "rp-normal")->as(); + auto renderPass_multi = core::Queries::findByName(racoproject->project()->instances(), "rp-multi")->as(); + auto renderPass_mixed = core::Queries::findByName(racoproject->project()->instances(), "rp-mixed")->as(); + + EXPECT_EQ(*mainRenderPass->target_, nullptr); + EXPECT_EQ(*renderPass_normal->target_, renderTarget_normal); + EXPECT_EQ(*renderPass_multi->target_, renderTarget_multi); + EXPECT_EQ(*renderPass_mixed->target_, renderTarget_mixed); + + EXPECT_EQ(renderTarget_normal->buffers_->asVector(), + std::vector({renderBuffer, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); + EXPECT_EQ(renderTarget_multi->buffers_->asVector(), + std::vector({renderBufferMS, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); + EXPECT_EQ(renderTarget_mixed->buffers_->asVector(), + std::vector({renderBuffer, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); +} + +TEST_F(MigrationTest, migrate_from_V54_rendertarget_extref_keepalive) { + using namespace raco; + auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V54-rendertarget-extref-keepalive.rca").string())); + + auto renderBuffer = core::Queries::findByName(racoproject->project()->instances(), "RenderBuffer")->as(); + auto renderBufferMS = core::Queries::findByName(racoproject->project()->instances(), "RenderBufferMS")->as(); + + auto renderTarget_normal = core::Queries::findByName(racoproject->project()->instances(), "rt-normal")->as(); + auto renderTarget_multi = core::Queries::findByName(racoproject->project()->instances(), "rt-multi")->as(); + auto renderTarget_mixed = core::Queries::findByName(racoproject->project()->instances(), "rt-mixed")->as(); + EXPECT_TRUE(renderTarget_normal->query() != nullptr); + EXPECT_TRUE(renderTarget_multi->query() != nullptr); + EXPECT_TRUE(renderTarget_mixed->query() != nullptr); + + auto mainRenderPass = core::Queries::findByName(racoproject->project()->instances(), "MainRenderPass")->as(); + auto renderPass_normal = core::Queries::findByName(racoproject->project()->instances(), "rp-normal")->as(); + auto renderPass_multi = core::Queries::findByName(racoproject->project()->instances(), "rp-multi")->as(); + auto renderPass_mixed = core::Queries::findByName(racoproject->project()->instances(), "rp-mixed")->as(); + + EXPECT_EQ(*mainRenderPass->target_, nullptr); + EXPECT_EQ(*renderPass_normal->target_, renderTarget_normal); + EXPECT_EQ(*renderPass_multi->target_, renderTarget_multi); + EXPECT_EQ(*renderPass_mixed->target_, renderTarget_mixed); + + EXPECT_EQ(renderTarget_normal->buffers_->asVector(), + std::vector({renderBuffer, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); + EXPECT_EQ(renderTarget_multi->buffers_->asVector(), + std::vector({renderBufferMS, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); + EXPECT_EQ(renderTarget_mixed->buffers_->asVector(), + std::vector({renderBuffer, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); +} + + +TEST_F(MigrationTest, migrate_from_V57) { + using namespace raco; + auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V57.rca").string())); + + auto settings = racoproject->project()->settings(); + auto node = core::Queries::findByName(racoproject->project()->instances(), "Node")->as(); + auto prefab = core::Queries::findByName(racoproject->project()->instances(), "Prefab")->as(); + + EXPECT_FALSE(settings->hasProperty("userTags")); + EXPECT_EQ(node->userTags_->asVector(), std::vector({"dog"})); + EXPECT_EQ(prefab->userTags_->asVector(), std::vector({"cat", "dog"})); +} + +TEST_F(MigrationTest, migrate_from_V58) { + using namespace raco; + auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V58.rca").string())); + + auto node = core::Queries::findByName(racoproject->project()->instances(), "Node")->as(); + auto meshnode = core::Queries::findByName(racoproject->project()->instances(), "MeshNode")->as(); + + auto animation = core::Queries::findByName(racoproject->project()->instances(), "Animation")->as(); + auto animationChannel = core::Queries::findByName(racoproject->project()->instances(), "AnimationChannel")->as(); + auto skin = core::Queries::findByName(racoproject->project()->instances(), "Skin")->as(); + + auto renderBuffer = core::Queries::findByName(racoproject->project()->instances(), "RenderBuffer")->as(); + auto renderBufferMS = core::Queries::findByName(racoproject->project()->instances(), "RenderBufferMS")->as(); + auto renderLayer = core::Queries::findByName(racoproject->project()->instances(), "MainRenderLayer")->as(); + + auto renderTarget = core::Queries::findByName(racoproject->project()->instances(), "RenderTarget")->as(); + auto renderTargetMS = core::Queries::findByName(racoproject->project()->instances(), "RenderTargetMS")->as(); + auto renderPass = core::Queries::findByName(racoproject->project()->instances(), "MainRenderPass")->as(); + + EXPECT_EQ(animation->animationChannels_->asVector(), + std::vector({animationChannel, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); + EXPECT_EQ(skin->targets_->asVector(), std::vector({meshnode})); + + EXPECT_EQ(renderTarget->buffers_->asVector(), + std::vector({renderBuffer, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); + EXPECT_EQ(renderTargetMS->buffers_->asVector(), + std::vector({renderBufferMS, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); + + EXPECT_EQ(renderPass->layers_->asVector(), + std::vector({renderLayer, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr})); +} + +TEST_F(MigrationTest, migrate_from_V59) { + using namespace raco; + + auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V59.rca").string())); + + auto intf_scalar = core::Queries::findByName(racoproject->project()->instances(), "intf-scalar")->as(); + auto intf_array = core::Queries::findByName(racoproject->project()->instances(), "intf-array")->as(); + auto intf_struct = core::Queries::findByName(racoproject->project()->instances(), "intf-struct")->as(); + + auto texture = core::Queries::findByName(racoproject->project()->instances(), "texture"); + + auto node = core::Queries::findByName(racoproject->project()->instances(), "Node"); + auto meshnode_no_mat = core::Queries::findByName(racoproject->project()->instances(), "meshnode_no_mat"); + + auto mat_scalar = core::Queries::findByName(racoproject->project()->instances(), "mat_scalar")->as(); + EXPECT_EQ(ValueHandle(mat_scalar, {"uniforms", "i"}).asInt(), 2); + checkVec2iValue(ValueHandle(mat_scalar, {"uniforms", "iv2"}), {1, 2}); + + auto mat_array_link_array = core::Queries::findByName(racoproject->project()->instances(), "mat_array_link_array")->as(); + EXPECT_EQ(ValueHandle(mat_array_link_array, {"uniforms", "ivec", "1"}).asInt(), 1); + EXPECT_EQ(ValueHandle(mat_array_link_array, {"uniforms", "ivec", "2"}).asInt(), 2); + + auto mat_array_link_member = core::Queries::findByName(racoproject->project()->instances(), "mat_array_link_member")->as(); + + auto mat_struct = core::Queries::findByName(racoproject->project()->instances(), "mat_struct")->as(); + EXPECT_EQ(ValueHandle(mat_struct, {"uniforms", "s_prims", "i"}).asInt(), 42); + checkVec2iValue(ValueHandle(mat_struct, {"uniforms", "s_prims", "iv2"}), {1, 2}); + + EXPECT_EQ(ValueHandle(mat_struct, {"uniforms", "s_samplers", "s_texture"}).asRef(), texture); + + EXPECT_EQ(ValueHandle(mat_struct, {"uniforms", "nested", "prims", "i"}).asInt(), 42); + checkVec2iValue(ValueHandle(mat_struct, {"uniforms", "nested", "prims", "iv2"}), {1, 2}); + + EXPECT_EQ(ValueHandle(mat_struct, {"uniforms", "a_s_prims", "1", "i"}).asInt(), 42); + checkVec2iValue(ValueHandle(mat_struct, {"uniforms", "a_s_prims", "1", "iv2"}), {1, 2}); + + EXPECT_EQ(ValueHandle(mat_struct, {"uniforms", "s_a_struct_prim", "prims", "1", "i"}).asInt(), 42); + checkVec2iValue(ValueHandle(mat_struct, {"uniforms", "s_a_struct_prim", "prims", "1", "iv2"}), {1, 2}); + + EXPECT_EQ(ValueHandle(mat_struct, {"uniforms", "a_s_a_struct_prim", "1", "prims", "1", "i"}).asInt(), 42); + checkVec2iValue(ValueHandle(mat_struct, {"uniforms", "a_s_a_struct_prim", "1", "prims", "1", "iv2"}), {1, 2}); + + EXPECT_EQ(ValueHandle(mat_struct, {"uniforms", "s_a_prims", "ivec", "1"}).asInt(), 1); + EXPECT_EQ(ValueHandle(mat_struct, {"uniforms", "s_a_prims", "ivec", "2"}).asInt(), 2); + checkVec2iValue(ValueHandle(mat_struct, {"uniforms", "s_a_prims", "aivec2", "1"}), {1, 2}); + checkVec2iValue(ValueHandle(mat_struct, {"uniforms", "s_a_prims", "aivec2", "2"}), {3, 4}); + + auto meshnode_mat_scalar = core::Queries::findByName(racoproject->project()->instances(), "meshnode_mat_scalar"); + EXPECT_EQ(ValueHandle(meshnode_mat_scalar, {"materials", "material", "uniforms", "i"}).asInt(), 2); + checkVec2iValue(ValueHandle(meshnode_mat_scalar, {"materials", "material", "uniforms", "iv2"}), {1, 2}); + + auto meshnode_mat_array_link_array = core::Queries::findByName(racoproject->project()->instances(), "meshnode_mat_array_link_array"); + EXPECT_EQ(ValueHandle(meshnode_mat_array_link_array, {"materials", "material", "uniforms", "ivec", "1"}).asInt(), 1); + EXPECT_EQ(ValueHandle(meshnode_mat_array_link_array, {"materials", "material", "uniforms", "ivec", "2"}).asInt(), 2); + + auto meshnode_mat_array_link_member = core::Queries::findByName(racoproject->project()->instances(), "meshnode_mat_array_link_member"); + + auto meshnode_mat_struct = core::Queries::findByName(racoproject->project()->instances(), "meshnode_mat_struct"); + EXPECT_EQ(ValueHandle(meshnode_mat_struct, {"materials", "material", "uniforms", "s_prims", "i"}).asInt(), 42); + checkVec2iValue(ValueHandle(meshnode_mat_struct, {"materials", "material", "uniforms", "s_prims", "iv2"}), {1, 2}); + + EXPECT_EQ(ValueHandle(meshnode_mat_struct, {"materials", "material", "uniforms", "s_samplers", "s_texture"}).asRef(), texture); + + EXPECT_EQ(ValueHandle(meshnode_mat_struct, {"materials", "material", "uniforms", "nested", "prims", "i"}).asInt(), 42); + checkVec2iValue(ValueHandle(meshnode_mat_struct, {"materials", "material", "uniforms", "nested", "prims", "iv2"}), {1, 2}); + + EXPECT_EQ(ValueHandle(meshnode_mat_struct, {"materials", "material", "uniforms", "a_s_prims", "1", "i"}).asInt(), 42); + checkVec2iValue(ValueHandle(meshnode_mat_struct, {"materials", "material", "uniforms", "a_s_prims", "1", "iv2"}), {1, 2}); + + EXPECT_EQ(ValueHandle(meshnode_mat_struct, {"materials", "material", "uniforms", "s_a_struct_prim", "prims", "1", "i"}).asInt(), 42); + checkVec2iValue(ValueHandle(meshnode_mat_struct, {"materials", "material", "uniforms", "s_a_struct_prim", "prims", "1", "iv2"}), {1, 2}); + + EXPECT_EQ(ValueHandle(meshnode_mat_struct, {"materials", "material", "uniforms", "a_s_a_struct_prim", "1", "prims", "1", "i"}).asInt(), 42); + checkVec2iValue(ValueHandle(meshnode_mat_struct, {"materials", "material", "uniforms", "a_s_a_struct_prim", "1", "prims", "1", "iv2"}), {1, 2}); + + EXPECT_EQ(ValueHandle(meshnode_mat_struct, {"materials", "material", "uniforms", "s_a_prims", "ivec", "1"}).asInt(), 1); + EXPECT_EQ(ValueHandle(meshnode_mat_struct, {"materials", "material", "uniforms", "s_a_prims", "ivec", "2"}).asInt(), 2); + checkVec2iValue(ValueHandle(meshnode_mat_struct, {"materials", "material", "uniforms", "s_a_prims", "aivec2", "1"}), {1, 2}); + checkVec2iValue(ValueHandle(meshnode_mat_struct, {"materials", "material", "uniforms", "s_a_prims", "aivec2", "2"}), {3, 4}); + + checkLinks(*racoproject->project(), + {{{intf_scalar, {"inputs", "bool"}}, {node, {"visibility"}}, true, false}, + {{intf_scalar, {"inputs", "bool"}}, {meshnode_no_mat, {"visibility"}}, true, false}, + + {{intf_scalar, {"inputs", "float"}}, {mat_scalar, {"uniforms", "f"}}, true, false}, + {{intf_scalar, {"inputs", "vector2f"}}, {mat_scalar, {"uniforms", "v2"}}, true, false}, + {{intf_array, {"inputs", "fvec"}}, {mat_array_link_array, {"uniforms", "fvec"}}, true, false}, + {{intf_scalar, {"inputs", "float"}}, {mat_array_link_member, {"uniforms", "fvec", "5"}}, true, false}, + {{intf_scalar, {"inputs", "vector3f"}}, {mat_array_link_member, {"uniforms", "avec3", "2"}}, true, false}, + + {{intf_scalar, {"inputs", "float"}}, {mat_struct, {"uniforms", "s_prims", "f"}}, true, false}, + + {{intf_array, {"inputs", "fvec"}}, {mat_struct, {"uniforms", "s_a_prims", "fvec"}}, true, false}, + {{intf_scalar, {"inputs", "vector3f"}}, {mat_struct, {"uniforms", "s_a_prims", "avec3", "1"}}, true, false}, + + {{intf_scalar, {"inputs", "float"}}, {mat_struct, {"uniforms", "nested", "prims", "f"}}, true, false}, + {{intf_scalar, {"inputs", "vector3f"}}, {mat_struct, {"uniforms", "nested", "prims", "v3"}}, true, false}, + + {{intf_scalar, {"inputs", "float"}}, {mat_struct, {"uniforms", "s_a_struct_prim", "prims", "1", "f"}}, true, false}, + {{intf_scalar, {"inputs", "vector3f"}}, {mat_struct, {"uniforms", "s_a_struct_prim", "prims", "1", "v3"}}, true, false}, + + {{intf_scalar, {"inputs", "float"}}, {mat_struct, {"uniforms", "a_s_prims", "1", "f"}}, true, false}, + {{intf_scalar, {"inputs", "vector3f"}}, {mat_struct, {"uniforms", "a_s_prims", "1", "v3"}}, true, false}, + + {{intf_scalar, {"inputs", "float"}}, {mat_struct, {"uniforms", "a_s_a_struct_prim", "1", "prims", "1", "f"}}, true, false}, + {{intf_scalar, {"inputs", "vector3f"}}, {mat_struct, {"uniforms", "a_s_a_struct_prim", "1", "prims", "1", "v3"}}, true, false}, + + {{intf_scalar, {"inputs", "float"}}, {meshnode_mat_scalar, {"materials", "material", "uniforms", "f"}}, true, false}, + {{intf_scalar, {"inputs", "vector2f"}}, {meshnode_mat_scalar, {"materials", "material", "uniforms", "v2"}}, true, false}, + {{intf_array, {"inputs", "fvec"}}, {meshnode_mat_array_link_array, {"materials", "material", "uniforms", "fvec"}}, true, false}, + {{intf_scalar, {"inputs", "float"}}, {meshnode_mat_array_link_member, {"materials", "material", "uniforms", "fvec", "5"}}, true, false}, + {{intf_scalar, {"inputs", "vector3f"}}, {meshnode_mat_array_link_member, {"materials", "material", "uniforms", "avec3", "2"}}, true, false}, + + {{intf_scalar, {"inputs", "float"}}, {meshnode_mat_struct, {"materials", "material", "uniforms", "s_prims", "f"}}, true, false}, + + {{intf_array, {"inputs", "fvec"}}, {meshnode_mat_struct, {"materials", "material", "uniforms", "s_a_prims", "fvec"}}, true, false}, + {{intf_scalar, {"inputs", "vector3f"}}, {meshnode_mat_struct, {"materials", "material", "uniforms", "s_a_prims", "avec3", "1"}}, true, false}, + + {{intf_scalar, {"inputs", "float"}}, {meshnode_mat_struct, {"materials", "material", "uniforms", "nested", "prims", "f"}}, true, false}, + {{intf_scalar, {"inputs", "vector3f"}}, {meshnode_mat_struct, {"materials", "material", "uniforms", "nested", "prims", "v3"}}, true, false}, + + {{intf_scalar, {"inputs", "float"}}, {meshnode_mat_struct, {"materials", "material", "uniforms", "s_a_struct_prim", "prims", "1", "f"}}, true, false}, + {{intf_scalar, {"inputs", "vector3f"}}, {meshnode_mat_struct, {"materials", "material", "uniforms", "s_a_struct_prim", "prims", "1", "v3"}}, true, false}, + + {{intf_scalar, {"inputs", "float"}}, {meshnode_mat_struct, {"materials", "material", "uniforms", "a_s_prims", "1", "f"}}, true, false}, + {{intf_scalar, {"inputs", "vector3f"}}, {meshnode_mat_struct, {"materials", "material", "uniforms", "a_s_prims", "1", "v3"}}, true, false}, + + {{intf_scalar, {"inputs", "float"}}, {meshnode_mat_struct, {"materials", "material", "uniforms", "a_s_a_struct_prim", "1", "prims", "1", "f"}}, true, false}, + {{intf_scalar, {"inputs", "vector3f"}}, {meshnode_mat_struct, {"materials", "material", "uniforms", "a_s_a_struct_prim", "1", "prims", "1", "v3"}}, true, false} + + }); +} + +TEST_F(MigrationTest, migrate_from_V60) { + auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "V60.rca").string())); + + EXPECT_EQ(*racoproject->project()->settings()->featureLevel_, 1); + + auto layer = core::Queries::findByName(racoproject->project()->instances(), "RenderLayerManual")->as(); + auto anno_main = layer->renderableTags_->get("main")->query(); + EXPECT_TRUE(anno_main != nullptr); + // migration to V2001 reset feature level to 1 + EXPECT_EQ(*anno_main->featureLevel_, 1); + + auto luaModule = core::Queries::findByName(racoproject->project()->instances(), "LuaScriptModule")->as(); + + auto luaScript = core::Queries::findByName(racoproject->project()->instances(), "LuaScript")->as(); + EXPECT_EQ(luaScript->luaModules_->get("coalas")->asRef(), luaModule); + + auto luaInterface= core::Queries::findByName(racoproject->project()->instances(), "LuaInterface")->as(); + EXPECT_EQ(luaInterface->luaModules_->get("coalas")->asRef(), luaModule); + + + auto renderpass = core::Queries::findByName(racoproject->project()->instances(), "RenderPass")->as(); + auto order_anno = renderpass->renderOrder_.query(); + EXPECT_EQ(*order_anno->featureLevel_, 1); + auto clearColor_anno = renderpass->clearColor_.query(); + EXPECT_EQ(*clearColor_anno->featureLevel_, 1); + auto enabled_anno = renderpass->enabled_.query(); + EXPECT_EQ(*enabled_anno->featureLevel_, 1); + auto renderOnce_anno = renderpass->renderOnce_.query(); + EXPECT_EQ(*renderOnce_anno->featureLevel_, 1); + + auto meshnode = core::Queries::findByName(racoproject->project()->instances(), "meshnode_no_tex")->as(); + auto instanceCount_anno = meshnode->instanceCount_.query(); + EXPECT_EQ(*instanceCount_anno->featureLevel_, 1); + auto meshnode_enabled_anno = meshnode->enabled_.query(); + EXPECT_EQ(*meshnode_enabled_anno->featureLevel_, 1); +} + TEST_F(MigrationTest, migrate_from_current) { // Check for changes in serialized JSON in newest version. // Should detect changes in data model with missing migration code. @@ -946,9 +1327,9 @@ TEST_F(MigrationTest, migrate_from_current) { int fileVersion; auto racoproject = loadAndCheckJson(QString::fromStdString((test_path() / "migrationTestData" / "version-current.rca").string()), &fileVersion); - ASSERT_EQ(fileVersion, raco::serialization::RAMSES_PROJECT_FILE_VERSION); + ASSERT_EQ(fileVersion, serialization::RAMSES_PROJECT_FILE_VERSION); - ASSERT_EQ(racoproject->project()->featureLevel(), static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel)); + ASSERT_EQ(racoproject->project()->featureLevel(), static_cast(ramses_base::BaseEngineBackend::maxFeatureLevel)); // check that all user types present in file auto& instances = racoproject->project()->instances(); @@ -956,7 +1337,7 @@ TEST_F(MigrationTest, migrate_from_current) { auto name = item.first; EXPECT_TRUE(std::find_if(instances.begin(), instances.end(), [name](SEditorObject obj) { return name == obj->getTypeDescription().typeName; - }) != instances.end()); + }) != instances.end()) << fmt::format("Type '{}' missing in version-current.rca", name); } } @@ -973,11 +1354,11 @@ TEST_F(MigrationTest, check_current_type_maps) { auto document{QJsonDocument::fromJson(file.readAll())}; file.close(); - auto fileUserPropTypeMap = raco::serialization::deserializeUserTypePropertyMap(document[raco::serialization::keys::USER_TYPE_PROP_MAP]); - auto fileStructTypeMap = raco::serialization::deserializeUserTypePropertyMap(document[raco::serialization::keys::STRUCT_PROP_MAP]); + auto fileUserPropTypeMap = serialization::deserializeUserTypePropertyMap(document[serialization::keys::USER_TYPE_PROP_MAP]); + auto fileStructTypeMap = serialization::deserializeUserTypePropertyMap(document[serialization::keys::STRUCT_PROP_MAP]); - auto currentUserPropTypeMap = raco::serialization::makeUserTypePropertyMap(); - auto currentStructTypeMap = raco::serialization::makeStructPropertyMap(); + auto currentUserPropTypeMap = serialization::makeUserTypePropertyMap(); + auto currentStructTypeMap = serialization::makeStructPropertyMap(); EXPECT_EQ(fileUserPropTypeMap, currentUserPropTypeMap); EXPECT_EQ(fileStructTypeMap, currentStructTypeMap); @@ -988,7 +1369,7 @@ TEST_F(MigrationTest, check_proxy_factory_has_all_objects_types) { // also have the corresponding proxy type added in the ProxyObjectFactory constructor. // If this fails add the type in the ProxyObjectFactory constructor makeTypeMap call. - auto& proxyFactory{raco::serialization::proxy::ProxyObjectFactory::getInstance()}; + auto& proxyFactory{serialization::proxy::ProxyObjectFactory::getInstance()}; auto& proxyTypeMap{proxyFactory.getTypes()}; for (auto& item : objectFactory()->getTypes()) { @@ -1002,7 +1383,7 @@ TEST_F(MigrationTest, check_proxy_factory_has_all_dynamic_property_types) { // have their corresponding properties added in ProxyObjectFactory::PropertyTypeMapType too. // If this fails add the property in ProxyObjectFactory::PropertyTypeMapType. - auto& proxyFactory{raco::serialization::proxy::ProxyObjectFactory::getInstance()}; + auto& proxyFactory{serialization::proxy::ProxyObjectFactory::getInstance()}; auto& userFactory{UserObjectFactory::getInstance()}; auto& proxyProperties{proxyFactory.getProperties()}; @@ -1011,11 +1392,12 @@ TEST_F(MigrationTest, check_proxy_factory_has_all_dynamic_property_types) { EXPECT_TRUE(proxyProperties.find(name) != proxyProperties.end()) << fmt::format("property name: '{}'", name); } } + TEST_F(MigrationTest, check_proxy_factory_can_create_all_static_properties) { // Check that the ProxyObjectFactory can create all statically known properties. // If this fails add the failing property to the ProxyObjectFactory::PropertyTypeMapType. - auto& proxyFactory{raco::serialization::proxy::ProxyObjectFactory::getInstance()}; + auto& proxyFactory{serialization::proxy::ProxyObjectFactory::getInstance()}; auto& userFactory{UserObjectFactory::getInstance()}; for (auto& item : userFactory.getTypes()) { @@ -1023,6 +1405,9 @@ TEST_F(MigrationTest, check_proxy_factory_can_create_all_static_properties) { auto object = objectFactory()->createObject(name); ASSERT_TRUE(object != nullptr); for (size_t index = 0; index < object->size(); index++) { + if (object->get(index)->query()) { + continue; + } auto propTypeName = object->get(index)->typeName(); auto proxyProperty = proxyFactory.createValue(propTypeName); ASSERT_TRUE(proxyProperty != nullptr) << fmt::format("property type name: '{}'", propTypeName); @@ -1054,6 +1439,9 @@ TEST_F(MigrationTest, check_user_factory_can_create_all_static_properties) { auto object = objectFactory()->createObject(name); ASSERT_TRUE(object != nullptr); for (size_t index = 0; index < object->size(); index++) { + if (object->get(index)->query()) { + continue; + } auto propTypeName = object->get(index)->typeName(); auto userProperty = userFactory.createValue(propTypeName); ASSERT_TRUE(userProperty != nullptr) << fmt::format("property type name: '{}'", propTypeName); diff --git a/datamodel/libCore/tests/Reference_test.cpp b/datamodel/libCore/tests/Reference_test.cpp index 07af1f97..256a4efa 100644 --- a/datamodel/libCore/tests/Reference_test.cpp +++ b/datamodel/libCore/tests/Reference_test.cpp @@ -9,6 +9,7 @@ */ #include "core/BasicTypes.h" #include "data_storage/Value.h" +#include "data_storage/Array.h" #include "testing/TestUtil.h" @@ -193,3 +194,39 @@ TEST(ReferenceTest, TypeEquality) { EXPECT_TRUE(ValueBase::classesEqual(pnodehidden, *pnodehidden_clone)); } + +TEST(ReferenceTest, Array) { + SNode node{new Node("node")}; + SNode node_b{new Node("node b")}; + SMeshNode meshnode{new MeshNode("meshnode")}; + SMeshNode meshnode_b{new MeshNode("meshnode b")}; + SMesh mesh{new Mesh("mesh")}; + + Value> anode; + Value> anode_2; + Value> ameshnode; + + auto node_elem_1 = anode->addProperty(); + *node_elem_1 = node; + EXPECT_EQ(anode->size(), 1); + EXPECT_EQ((*anode)[0]->asRef(), node); + + *node_elem_1 = meshnode; + + auto meshnode_elem_1 = ameshnode->addProperty(); + *meshnode_elem_1 = meshnode; + + // Assigning wrong type: + // statically known wrong type -> doesn't compile: + //*meshnode_elem_1 = node; + // ValueBase::operator= + EXPECT_THROW(*static_cast(meshnode_elem_1) = node, std::runtime_error); + + + EXPECT_EQ(anode_2->size(), 0); + anode_2 = anode; + EXPECT_EQ(anode_2->size(), 1); + EXPECT_EQ((*anode_2)[0]->asRef(), meshnode); + + EXPECT_THROW(ameshnode = anode, std::runtime_error); +} \ No newline at end of file diff --git a/datamodel/libCore/tests/Serialization_test.cpp b/datamodel/libCore/tests/Serialization_test.cpp index a2e69528..fd5d3a0f 100644 --- a/datamodel/libCore/tests/Serialization_test.cpp +++ b/datamodel/libCore/tests/Serialization_test.cpp @@ -10,6 +10,7 @@ #include "core/Serialization.h" +#include "testing/MockUserTypes.h" #include "testing/TestEnvironmentCore.h" #include "testing/TestUtil.h" #include "core/BasicAnnotations.h" @@ -29,13 +30,19 @@ constexpr bool WRITE_RESULT{false}; #endif using namespace raco::utils; +using namespace raco::data_storage; + + +class SerializationTest : public TestEnvironmentCore { +public: + SerializationTest() : TestEnvironmentCore(&TestObjectFactory::getInstance()) { + } -struct SerializationTest : public TestEnvironmentCore { void assertFileContentEqual(const std::string &filePath, const std::string &deserializedFileContent) { auto expectedFileContent = file::read(filePath); #if (defined(__linux__)) - expectedFileContent.erase(std::remove(expectedFileContent.begin(), expectedFileContent.end(), '\r'), expectedFileContent.end()); + expectedFileContent.erase(std::remove(expectedFileContent.begin(), expectedFileContent.end(), '\r'), expectedFileContent.end()); #endif ASSERT_EQ(expectedFileContent, deserializedFileContent); @@ -43,189 +50,189 @@ struct SerializationTest : public TestEnvironmentCore { }; TEST_F(SerializationTest, serializeNode) { - const auto sNode{std::make_shared("node", "node_id")}; - sNode->scaling_->z.staticQuery>().max_ = 100.0; - auto result = raco::serialization::test_helpers::serializeObject(sNode); + const auto sNode{std::make_shared("node", "node_id")}; + sNode->scaling_->z.staticQuery>().max_ = 100.0; + auto result = serialization::test_helpers::serializeObject(sNode); if (WRITE_RESULT) file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "Node.json").string(), result); assertFileContentEqual((test_path() / "expectations" / "Node.json").string(), result); } TEST_F(SerializationTest, serializeNodeRotated) { - const auto sNode{context.createObject(raco::user_types::Node::typeDescription.typeName, "node", "node_id")}; + const auto sNode{context.createObject(user_types::Node::typeDescription.typeName, "node", "node_id")}; commandInterface.set({sNode, {"rotation", "x"}}, 90.0); commandInterface.set({sNode, {"rotation", "y"}}, -90.0); commandInterface.set({sNode, {"rotation", "z"}}, 180.0); - auto result = raco::serialization::test_helpers::serializeObject(sNode); + auto result = serialization::test_helpers::serializeObject(sNode); if (WRITE_RESULT) file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "NodeRotated.json").string(), result); assertFileContentEqual((test_path() / "expectations" / "NodeRotated.json").string(), result); } TEST_F(SerializationTest, serializeNodeWithAnnotations) { - const auto sNode{std::make_shared("node", "node_id")}; + const auto sNode{std::make_shared("node", "node_id")}; - auto anno = std::make_shared(); + auto anno = std::make_shared(); sNode->addAnnotation(anno); anno->projectID_ = "base_id"; - auto result = raco::serialization::test_helpers::serializeObject(sNode); + auto result = serialization::test_helpers::serializeObject(sNode); if (WRITE_RESULT) file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "NodeWithAnnotations.json").string(), result); ASSERT_EQ(file::read((test_path() / "expectations" / "NodeWithAnnotations.json").string()), result); } TEST_F(SerializationTest, serializeMeshNode) { - const auto sMeshNode{std::make_shared("mesh_node", "mesh_node_id")}; - auto result = raco::serialization::test_helpers::serializeObject(sMeshNode); + const auto sMeshNode{std::make_shared("mesh_node", "mesh_node_id")}; + auto result = serialization::test_helpers::serializeObject(sMeshNode); if (WRITE_RESULT) file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "MeshNode.json").string(), result); assertFileContentEqual((test_path() / "expectations" / "MeshNode.json").string(), result); } TEST_F(SerializationTest, serializeMeshNodeWithMesh) { - const auto sMeshNode{context.createObject(raco::user_types::MeshNode::typeDescription.typeName, "mesh_node", "mesh_node_id")}; - const auto sMesh{context.createObject(raco::user_types::Mesh::typeDescription.typeName, "mesh", "mesh_id")}; + const auto sMeshNode{context.createObject(user_types::MeshNode::typeDescription.typeName, "mesh_node", "mesh_node_id")}; + const auto sMesh{context.createObject(user_types::Mesh::typeDescription.typeName, "mesh", "mesh_id")}; auto uri{(test_relative_path() / "testData" / "duck.glb").string()}; commandInterface.set({sMesh, {"uri"}}, uri); commandInterface.set({sMeshNode, {"mesh"}}, sMesh); - auto result = raco::serialization::test_helpers::serializeObject(sMeshNode); + auto result = serialization::test_helpers::serializeObject(sMeshNode); if (WRITE_RESULT) file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "MeshNodeWithMesh.json").string(), result); assertFileContentEqual((test_path() / "expectations" / "MeshNodeWithMesh.json").string(), result); } TEST_F(SerializationTest, serializeNodeWithChildMeshNode) { - const auto sMeshNode{context.createObject(raco::user_types::MeshNode::typeDescription.typeName, "mesh_node", "mesh_node_id")}; - const auto sNode{context.createObject(raco::user_types::Node::typeDescription.typeName, "node", "node_id")}; + const auto sMeshNode{context.createObject(user_types::MeshNode::typeDescription.typeName, "mesh_node", "mesh_node_id")}; + const auto sNode{context.createObject(user_types::Node::typeDescription.typeName, "node", "node_id")}; commandInterface.moveScenegraphChildren({sMeshNode}, sNode); - auto result = raco::serialization::test_helpers::serializeObject(sNode); + auto result = serialization::test_helpers::serializeObject(sNode); if (WRITE_RESULT) file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "NodeWithChildMeshNode.json").string(), result); assertFileContentEqual((test_path() / "expectations" / "NodeWithChildMeshNode.json").string(), result); } TEST_F(SerializationTest, serializeLuaScript) { - const auto sLuaScript{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; - auto result = raco::serialization::test_helpers::serializeObject(sLuaScript); + const auto sLuaScript{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; + auto result = serialization::test_helpers::serializeObject(sLuaScript); if (WRITE_RESULT) file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "LuaScript.json").string(), result); assertFileContentEqual((test_path() / "expectations" / "LuaScript.json").string(), result); } TEST_F(SerializationTest, serializeLuaScriptInFloat) { - const auto sLuaScript{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; + const auto sLuaScript{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; auto uri { (test_relative_path() / "testData" / "in-float.lua").string() }; - commandInterface.set(raco::core::ValueHandle{sLuaScript, {"uri"}}, uri); - auto result = raco::serialization::test_helpers::serializeObject(sLuaScript); + commandInterface.set(core::ValueHandle{sLuaScript, {"uri"}}, uri); + auto result = serialization::test_helpers::serializeObject(sLuaScript); if (WRITE_RESULT) file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "LuaScriptInFloat.json").string(), result); assertFileContentEqual((test_path() / "expectations" / "LuaScriptInFloat.json").string(), result); } TEST_F(SerializationTest, serializeLuaScriptInFloatArray) { - const auto sLuaScript{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; + const auto sLuaScript{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; auto uri{(test_relative_path() / "testData" / "in-float-array.lua").string()}; - commandInterface.set(raco::core::ValueHandle{sLuaScript, {"uri"}}, uri); - auto result = raco::serialization::test_helpers::serializeObject(sLuaScript); + commandInterface.set(core::ValueHandle{sLuaScript, {"uri"}}, uri); + auto result = serialization::test_helpers::serializeObject(sLuaScript); if (WRITE_RESULT) file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "LuaScriptInFloatArray.json").string(), result); assertFileContentEqual((test_path() / "expectations" / "LuaScriptInFloatArray.json").string(), result); } TEST_F(SerializationTest, serializeLuaScriptInStruct) { - const auto sLuaScript{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; + const auto sLuaScript{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; auto uri{(test_relative_path() / "testData" / "in-struct.lua").string()}; - commandInterface.set(raco::core::ValueHandle{sLuaScript, {"uri"}}, uri); - auto result = raco::serialization::test_helpers::serializeObject(sLuaScript); + commandInterface.set(core::ValueHandle{sLuaScript, {"uri"}}, uri); + auto result = serialization::test_helpers::serializeObject(sLuaScript); if (WRITE_RESULT) file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "LuaScriptInStruct.json").string(), result); assertFileContentEqual((test_path() / "expectations" / "LuaScriptInStruct.json").string(), result); } TEST_F(SerializationTest, serializeLuaScriptInSpecificPropNames) { - const auto sLuaScript{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; + const auto sLuaScript{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; auto uri{(test_relative_path() / "testData" / "in-specific-prop-names.lua").string()}; - commandInterface.set(raco::core::ValueHandle{sLuaScript, {"uri"}}, uri); - auto result = raco::serialization::test_helpers::serializeObject(sLuaScript); + commandInterface.set(core::ValueHandle{sLuaScript, {"uri"}}, uri); + auto result = serialization::test_helpers::serializeObject(sLuaScript); if (WRITE_RESULT) file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "LuaScriptSpecificPropNames.json").string(), result); assertFileContentEqual((test_path() / "expectations" / "LuaScriptSpecificPropNames.json").string(), result); } TEST_F(SerializationTest, serializeMesh) { - const auto sMesh{context.createObject(raco::user_types::Mesh::typeDescription.typeName, "mesh", "mesh_id")}; + const auto sMesh{context.createObject(user_types::Mesh::typeDescription.typeName, "mesh", "mesh_id")}; auto uri{(test_relative_path() / "testData" / "duck.glb").string()}; commandInterface.set({sMesh, {"uri"}}, uri); - auto result = raco::serialization::test_helpers::serializeObject(sMesh); + auto result = serialization::test_helpers::serializeObject(sMesh); if (WRITE_RESULT) file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "Mesh.json").string(), result); assertFileContentEqual((test_path() / "expectations" / "Mesh.json").string(), result); } TEST_F(SerializationTest, serializeMeshglTFSubmesh) { - const auto sMesh{context.createObject(raco::user_types::Mesh::typeDescription.typeName, "mesh", "mesh_id")}; + const auto sMesh{context.createObject(user_types::Mesh::typeDescription.typeName, "mesh", "mesh_id")}; auto uri{(test_relative_path() / "testData" / "ToyCar.gltf").string()}; commandInterface.set({sMesh, {"uri"}}, uri); commandInterface.set({sMesh, {"bakeMeshes"}}, false); commandInterface.set({sMesh, {"meshIndex"}}, 2); - auto result = raco::serialization::test_helpers::serializeObject(sMesh); + auto result = serialization::test_helpers::serializeObject(sMesh); if (WRITE_RESULT) file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "MeshGLTFSubmesh.json").string(), result); assertFileContentEqual((test_path() / "expectations" / "MeshGLTFSubmesh.json").string(), result); } TEST_F(SerializationTest, serializeMeshglTFBakedSubmeshes) { - const auto sMesh{context.createObject(raco::user_types::Mesh::typeDescription.typeName, "mesh", "mesh_id")}; + const auto sMesh{context.createObject(user_types::Mesh::typeDescription.typeName, "mesh", "mesh_id")}; auto uri{(test_relative_path() / "testData" / "ToyCar.gltf").string()}; commandInterface.set({sMesh, {"uri"}}, uri); commandInterface.set({sMesh, {"meshIndex"}}, 2); commandInterface.set({sMesh, {"bakeMeshes"}}, true); - auto result = raco::serialization::test_helpers::serializeObject(sMesh); + auto result = serialization::test_helpers::serializeObject(sMesh); if (WRITE_RESULT) file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "MeshGLTFBaked.json").string(), result); assertFileContentEqual((test_path() / "expectations" / "MeshGLTFBaked.json").string(), result); } TEST_F(SerializationTest, serializeLuaScriptWithRefToUserTypeWithAnnotation) { - const auto editorObject{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "mesh", "mesh_id")}; - raco::user_types::SLuaScript sLuaScript{std::dynamic_pointer_cast(editorObject)}; - sLuaScript->inputs_->addProperty("ref", new raco::data_storage::Property({}, {raco::core::EnginePrimitive::TextureSampler2D})); + const auto editorObject{context.createObject(user_types::LuaScript::typeDescription.typeName, "mesh", "mesh_id")}; + user_types::SLuaScript sLuaScript{std::dynamic_pointer_cast(editorObject)}; + sLuaScript->inputs_->addProperty("ref", new data_storage::Property({}, {core::EnginePrimitive::TextureSampler2D})); - auto result = raco::serialization::test_helpers::serializeObject(editorObject); + auto result = serialization::test_helpers::serializeObject(editorObject); if (WRITE_RESULT) file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "LuaScriptWithRefToUserTypeWithAnnotation.json").string(), result); assertFileContentEqual((test_path() / "expectations" / "LuaScriptWithRefToUserTypeWithAnnotation.json").string(), result); } TEST_F(SerializationTest, serializeLuaScriptWithURI) { - const auto editorObject{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; - raco::user_types::SLuaScript sLuaScript{std::dynamic_pointer_cast(editorObject)}; - sLuaScript->inputs_->addProperty("uri", new raco::data_storage::Property("", {})); + const auto editorObject{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; + user_types::SLuaScript sLuaScript{std::dynamic_pointer_cast(editorObject)}; + sLuaScript->inputs_->addProperty("uri", new data_storage::Property("", {})); - auto result = raco::serialization::test_helpers::serializeObject(editorObject); + auto result = serialization::test_helpers::serializeObject(editorObject); if (WRITE_RESULT) file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "LuaScriptWithURI.json").string(), result); assertFileContentEqual((test_path() / "expectations" / "LuaScriptWithURI.json").string(), result); } TEST_F(SerializationTest, serializeLuaScriptWithAnnotatedDouble) { - const auto editorObject{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; - raco::user_types::SLuaScript sLuaScript{std::dynamic_pointer_cast(editorObject)}; - sLuaScript->inputs_->addProperty("double", new raco::data_storage::Property>({}, {"Double"}, {-10.0, 10.0})); + const auto editorObject{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; + user_types::SLuaScript sLuaScript{std::dynamic_pointer_cast(editorObject)}; + sLuaScript->inputs_->addProperty("double", new data_storage::Property>({}, {"Double"}, {-10.0, 10.0})); - auto result = raco::serialization::test_helpers::serializeObject(editorObject); + auto result = serialization::test_helpers::serializeObject(editorObject); if (WRITE_RESULT) file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "LuaScriptWithAnnotatedDouble.json").string(), result); assertFileContentEqual((test_path() / "expectations" / "LuaScriptWithAnnotatedDouble.json").string(), result); } TEST_F(SerializationTest, serializeNodeAndScript_withLink) { - const auto editorObject{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; - raco::user_types::SLuaScript sLuaScript{std::dynamic_pointer_cast(editorObject)}; - sLuaScript->inputs_->addProperty("double", new raco::data_storage::Property>({}, {"Double"}, {-10.0, 10.0})); + const auto editorObject{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; + user_types::SLuaScript sLuaScript{std::dynamic_pointer_cast(editorObject)}; + sLuaScript->inputs_->addProperty("double", new data_storage::Property>({}, {"Double"}, {-10.0, 10.0})); - auto result = raco::serialization::test_helpers::serializeObject(editorObject); + auto result = serialization::test_helpers::serializeObject(editorObject); if (WRITE_RESULT) file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "LuaScriptWithAnnotatedDouble.json").string(), result); assertFileContentEqual((test_path() / "expectations" / "LuaScriptWithAnnotatedDouble.json").string(), result); @@ -233,10 +240,10 @@ TEST_F(SerializationTest, serializeNodeAndScript_withLink) { TEST_F(SerializationTest, serializeObjects_luaScriptLinkedToNode) { auto objs{raco::createLinkedScene(context, test_relative_path())}; - std::map externalProjectsMap; + std::map externalProjectsMap; std::map originFolders; - auto result = raco::serialization::serializeObjects( + auto result = serialization::serializeObjects( {std::get<0>(objs), std::get<1>(objs)}, {std::get<0>(objs)->objectID(), std::get<1>(objs)->objectID()}, {std::get<2>(objs)}, "", "", "", "", externalProjectsMap, originFolders, -1, false); @@ -244,3 +251,53 @@ TEST_F(SerializationTest, serializeObjects_luaScriptLinkedToNode) { assertFileContentEqual((test_path() / "expectations" / "LuaScriptLinkedToNode.json").string(), result); } + +TEST_F(SerializationTest, serializeArrays) { + auto obj = context.createObject(user_types::ObjectWithArrays::typeDescription.typeName, "obj_name", "obj_id")->as(); + const auto node_1{context.createObject(user_types::Node::typeDescription.typeName, "node_1", "node_1_id")->as()}; + const auto node_2{context.createObject(user_types::Node::typeDescription.typeName, "node_2", "node_2_id")->as()}; + + auto array = std::make_unique>>(); + auto nested = std::make_unique>>>(); + for (size_t outer = 0; outer < 2; outer++) { + *(*array)->addProperty() = outer; + + auto& row = (*nested)->addProperty()->asArray(); + for (size_t inner = 0; inner < 3; inner++) { + *row.addProperty() = outer + static_cast(inner) / 10.0; + } + + *obj->array_double_->addProperty() = outer; + + { + auto& row = obj->array_array_double_->addProperty()->asArray(); + for (size_t inner = 0; inner < 3; inner++) { + *row.addProperty() = outer + static_cast(inner) / 10.0; + } + } + + } + obj->table_->addProperty("array", std::move(array)); + obj->table_->addProperty("nested", std::move(nested)); + + *obj->array_ref_->addProperty() = node_1; + *obj->array_ref_->addProperty() = node_2; + + auto array_ref = std::make_unique>>(); + *(*array_ref)->addProperty() = node_1; + *(*array_ref)->addProperty() = node_2; + obj->table_->addProperty("array_ref", std::move(array_ref)); + + std::map externalProjectsMap; + std::map originFolders; + auto result = serialization::serializeObjects( + {obj, node_1, node_2}, + {obj->objectID(), node_1->objectID(), node_2->objectID()}, + {}, "", "", "", "", externalProjectsMap, originFolders, -1, false); + + if (WRITE_RESULT) { + file::write((u8path{CMAKE_CURRENT_SOURCE_DIR} / "expectations" / "Arrays.json").string(), result); + } + + assertFileContentEqual((test_path() / "expectations" / "Arrays.json").string(), result); +} diff --git a/datamodel/libCore/tests/Undo_test.cpp b/datamodel/libCore/tests/Undo_test.cpp index fe128561..ed332659 100644 --- a/datamodel/libCore/tests/Undo_test.cpp +++ b/datamodel/libCore/tests/Undo_test.cpp @@ -639,7 +639,7 @@ TEST_F(UndoTest, link_input_changed_add_another_link) { commandInterface.set(ValueHandle{linkRecipient, {"uri"}}, test_path().append("scripts/types-scalar.lua").string()); checkUndoRedo([this, linkBase, linkRecipient]() { commandInterface.addLink(ValueHandle{linkBase, {"outputs", "ofloat"}}, ValueHandle{linkRecipient, {"inputs", "float"}}); }, - [this, linkBase, linkRecipient]() { + [this, linkBase, linkRecipient]() { checkLinks({{{linkBase, {"outputs", "ofloat"}}, {linkRecipient, {"inputs", "in_float"}}, false}}); }, [this, linkBase, linkRecipient]() { @@ -650,10 +650,10 @@ TEST_F(UndoTest, link_input_changed_add_another_link) { TEST_F(UndoTest, lua_module_added) { auto script = create("script"); - commandInterface.set(ValueHandle{script, &raco::user_types::LuaScript::uri_}, test_path().append("scripts/moduleDependency.lua").string()); + commandInterface.set(ValueHandle{script, &user_types::LuaScript::uri_}, test_path().append("scripts/moduleDependency.lua").string()); auto module = create("module"); - commandInterface.set(ValueHandle{module, &raco::user_types::LuaScriptModule::uri_}, test_path().append("scripts/moduleDefinition.lua").string()); + commandInterface.set(ValueHandle{module, &user_types::LuaScriptModule::uri_}, test_path().append("scripts/moduleDefinition.lua").string()); checkUndoRedo([this, script, module]() { commandInterface.set(ValueHandle{script, {"luaModules", "coalas"}}, module); @@ -674,13 +674,13 @@ TEST_F(UndoTest, lua_module_added) { TEST_F(UndoTest, lua_module_script_uri_changed) { auto script = create("script"); - commandInterface.set(ValueHandle{script, &raco::user_types::LuaScript::uri_}, test_path().append("scripts/moduleDependency.lua").string()); + commandInterface.set(ValueHandle{script, &user_types::LuaScript::uri_}, test_path().append("scripts/moduleDependency.lua").string()); auto module = create("module"); - commandInterface.set(ValueHandle{module, &raco::user_types::LuaScriptModule::uri_}, test_path().append("scripts/moduleDefinition.lua").string()); + commandInterface.set(ValueHandle{module, &user_types::LuaScriptModule::uri_}, test_path().append("scripts/moduleDefinition.lua").string()); commandInterface.set(ValueHandle{script, {"luaModules", "coalas"}}, module); - checkUndoRedo([this, script, module]() { commandInterface.set(ValueHandle{script, &raco::user_types::LuaScript::uri_}, test_path().append("scripts/types-scalar.lua").string()); }, + checkUndoRedo([this, script, module]() { commandInterface.set(ValueHandle{script, &user_types::LuaScript::uri_}, test_path().append("scripts/types-scalar.lua").string()); }, [this, script]() { ASSERT_FALSE(commandInterface.errors().hasError({script})); auto coalasRef = ValueHandle{script, {"luaModules", "coalas"}}.asRef(); @@ -694,13 +694,13 @@ TEST_F(UndoTest, lua_module_script_uri_changed) { TEST_F(UndoTest, lua_module_script_module_made_invalid) { auto script = create("script"); - commandInterface.set(ValueHandle{script, &raco::user_types::LuaScript::uri_}, test_path().append("scripts/moduleDependency.lua").string()); + commandInterface.set(ValueHandle{script, &user_types::LuaScript::uri_}, test_path().append("scripts/moduleDependency.lua").string()); auto module = create("module"); - commandInterface.set(ValueHandle{module, &raco::user_types::LuaScriptModule::uri_}, test_path().append("scripts/moduleDefinition.lua").string()); + commandInterface.set(ValueHandle{module, &user_types::LuaScriptModule::uri_}, test_path().append("scripts/moduleDefinition.lua").string()); commandInterface.set(ValueHandle{script, {"luaModules", "coalas"}}, module); - checkUndoRedo([this, script, module]() { commandInterface.set(ValueHandle{module, &raco::user_types::LuaScriptModule::uri_}, std::string()); }, + checkUndoRedo([this, script, module]() { commandInterface.set(ValueHandle{module, &user_types::LuaScriptModule::uri_}, std::string()); }, [this, script]() { ASSERT_FALSE(commandInterface.errors().hasError({script})); ASSERT_FALSE(commandInterface.errors().hasError(ValueHandle{script, {"luaModules", "coalas"}})); @@ -710,12 +710,12 @@ TEST_F(UndoTest, lua_module_script_module_made_invalid) { [this, script, module]() { ASSERT_FALSE(commandInterface.errors().hasError({script})); ASSERT_TRUE(commandInterface.errors().hasError(ValueHandle{script, {"luaModules", "coalas"}})); - ASSERT_TRUE(commandInterface.errors().hasError({module, &raco::user_types::LuaScriptModule::uri_})); + ASSERT_TRUE(commandInterface.errors().hasError({module, &user_types::LuaScriptModule::uri_})); }); } TEST_F(UndoTest, link_quaternion_euler_change) { - raco::utils::file::write((test_path() / "lua_script_out1.lua").string(), R"( + utils::file::write((test_path() / "lua_script_out1.lua").string(), R"( function interface(IN,OUT) IN.vec = Type:Vec4f() OUT.vec = Type:Vec4f() @@ -725,7 +725,7 @@ function run(IN,OUT) end )"); - raco::utils::file::write((test_path() / "lua_script_out2.lua").string(), R"( + utils::file::write((test_path() / "lua_script_out2.lua").string(), R"( function interface(IN,OUT) IN.vec = Type:Vec3f() OUT.vec = Type:Vec3f() @@ -759,12 +759,12 @@ end TEST_F(UndoTest, mesh_asset_with_anims_import_multiple_undo_redo) { - raco::core::MeshDescriptor desc; + core::MeshDescriptor desc; desc.absPath = test_path().append("meshes/InterpolationTest/InterpolationTest.gltf").string(); desc.bakeAllSubmeshes = false; auto [scenegraph, dummyCacheEntry] = raco::getMeshSceneGraphWithHandler(commandInterface.meshCache(), desc); - + commandInterface.insertAssetScenegraph(scenegraph, desc.absPath, nullptr); for (auto i = 0; i < 10; ++i) { @@ -873,7 +873,7 @@ void main() { undoStack.setIndex(preIndex); - raco::utils::file::write(fragShader.path.string(), altFragShaderText); + utils::file::write(fragShader.path.string(), altFragShaderText); undoStack.setIndex(postIndex); @@ -922,7 +922,7 @@ void main() { size_t preIndex = undoStack.getIndex(); - commandInterface.set(raco::core::ValueHandle{meshnode, {"materials", "material", "uniforms", "u_color"}}, 5.0); + commandInterface.set(core::ValueHandle{meshnode, {"materials", "material", "uniforms", "u_color"}}, 5.0); size_t postIndex = undoStack.getIndex(); @@ -932,7 +932,7 @@ void main() { undoStack.setIndex(preIndex); undoStack.setIndex(postIndex); - ASSERT_NO_THROW((raco::core::ValueHandle{meshnode, {"materials", "material", "uniforms", "u_color"}}.asDouble())); + ASSERT_NO_THROW((core::ValueHandle{meshnode, {"materials", "material", "uniforms", "u_color"}}.asDouble())); } #if (!defined(__linux__)) @@ -965,7 +965,7 @@ end EXPECT_FALSE(luaOutputs.hasProperty("renamed")); recorder.reset(); - raco::utils::file::write(luaFile.path.string(), altLuaScript); + utils::file::write(luaFile.path.string(), altLuaScript); EXPECT_TRUE(raco::awaitPreviewDirty(recorder, lua)); EXPECT_FALSE(luaOutputs.hasProperty("vec")); @@ -1017,7 +1017,7 @@ end EXPECT_FALSE(luaOutputs.hasProperty("renamed")); recorder.reset(); - raco::utils::file::write(luaFile.path.string(), altLuaScript); + utils::file::write(luaFile.path.string(), altLuaScript); EXPECT_TRUE(raco::awaitPreviewDirty(recorder, lua)); EXPECT_FALSE(luaOutputs.hasProperty("vec")); @@ -1033,7 +1033,7 @@ end checkLinks({}); ASSERT_FALSE(commandInterface.errors().hasError({node})); - // redo #1 + // redo #1 commandInterface.undoStack().redo(); checkLinks({{sprop, eprop, false}}); ASSERT_TRUE(commandInterface.errors().hasError({node})); @@ -1071,7 +1071,7 @@ end EXPECT_FALSE(luaOutputs.hasProperty("renamed")); recorder.reset(); - raco::utils::file::write(luaFile.path.string(), altLuaScript); + utils::file::write(luaFile.path.string(), altLuaScript); EXPECT_TRUE(raco::awaitPreviewDirty(recorder, lua)); EXPECT_FALSE(luaOutputs.hasProperty("vec")); @@ -1125,7 +1125,7 @@ end EXPECT_FALSE(luaOutputs.hasProperty("renamed")); recorder.reset(); - raco::utils::file::write(luaFile.path.string(), altLuaScript); + utils::file::write(luaFile.path.string(), altLuaScript); EXPECT_TRUE(raco::awaitPreviewDirty(recorder, lua)); EXPECT_FALSE(luaOutputs.hasProperty("vec")); @@ -1139,7 +1139,7 @@ end auto [sprop, eprop] = link(lua, {"outputs", "renamed"}, node, {"translation"}); checkLinks({{sprop, eprop, true}}); - raco::utils::file::write(luaFile.path.string(), origLuaScript); + utils::file::write(luaFile.path.string(), origLuaScript); EXPECT_TRUE(raco::awaitPreviewDirty(recorder, lua)); undoStack.undo(); @@ -1156,7 +1156,7 @@ TEST_F(UndoTest, add_remove_property_ref) { auto refTarget = create("foo"); auto refSource = create("sourceObject"); ValueHandle tableHandle{refSource, &ObjectWithTableProperty::t_}; - + checkUndoRedoMultiStep<2>( {[this, tableHandle, refTarget]() { context.addProperty(tableHandle, "ref", std::make_unique>(refTarget)); @@ -1276,7 +1276,7 @@ TEST_F(UndoTest, add_remove_property_struct_with_ref) { }}); } -TEST_F(UndoTest, setTable_with_ref) { +TEST_F(UndoTest, set_table_with_ref) { auto refTarget = create("foo"); auto refSource = create("sourceObject"); ValueHandle tableHandle{refSource, &ObjectWithTableProperty::t_}; @@ -1305,7 +1305,7 @@ TEST_F(UndoTest, setTable_with_ref) { }}); } -TEST_F(UndoTest, setArray_with_ref) { +TEST_F(UndoTest, set_tableArray_with_ref) { auto refTarget = create("foo"); auto refSource = create("sourceObject"); ValueHandle arrayHandle{refSource, &ObjectWithTableProperty::array_}; @@ -1334,7 +1334,7 @@ TEST_F(UndoTest, setArray_with_ref) { }}); } -TEST_F(UndoTest, setStruct_with_ref) { +TEST_F(UndoTest, set_struct_with_ref) { auto refTarget = create("foo"); auto refSource = create("sourceObject"); const ValueHandle structHandle{refSource, &ObjectWithStructProperty::s_}; @@ -1364,7 +1364,7 @@ TEST_F(UndoTest, setStruct_with_ref) { }}); } -TEST_F(UndoTest, setTable_nested_table_with_ref) { +TEST_F(UndoTest, set_table_nested_table_with_ref) { auto refTarget = create("foo"); auto refSource = create("sourceObject"); ValueHandle tableHandle{refSource, &ObjectWithTableProperty::t_}; @@ -1397,7 +1397,7 @@ TEST_F(UndoTest, setTable_nested_table_with_ref) { }}); } -TEST_F(UndoTest, setArray_nested_table_with_ref) { +TEST_F(UndoTest, set_tableArray_nested_table_with_ref) { auto refTarget = create("foo"); auto refSource = create("sourceObject"); ValueHandle tableHandle{refSource, &ObjectWithTableProperty::array_}; @@ -1430,7 +1430,7 @@ TEST_F(UndoTest, setArray_nested_table_with_ref) { }}); } -TEST_F(UndoTest, setTable_nested_struct_with_ref) { +TEST_F(UndoTest, set_table_nested_struct_with_ref) { auto refTarget = create("foo"); auto refSource = create("sourceObject"); ValueHandle tableHandle{refSource, &ObjectWithTableProperty::t_}; @@ -1463,7 +1463,7 @@ TEST_F(UndoTest, setTable_nested_struct_with_ref) { }}); } -TEST_F(UndoTest, setArray_nested_struct_with_ref) { +TEST_F(UndoTest, set_tableArray_nested_struct_with_ref) { auto refTarget = create("foo"); auto refSource = create("sourceObject"); ValueHandle tableHandle{refSource, &ObjectWithTableProperty::array_}; @@ -1501,20 +1501,20 @@ TEST_F(UndoTest, referenced_object_moved_into_prefab) { auto camera = create("camera"); auto renderPass = create("pass"); - auto refTargets = raco::core::Queries::findAllValidReferenceTargets(*commandInterface.project(), {renderPass, &raco::user_types::RenderPass::camera_}); + auto refTargets = core::Queries::findAllValidReferenceTargets(*commandInterface.project(), {renderPass, &user_types::RenderPass::camera_}); ASSERT_EQ(refTargets, std::vector{camera}); - commandInterface.set({renderPass, &raco::user_types::RenderPass::camera_}, camera); - ASSERT_EQ(raco::core::ValueHandle(renderPass, &raco::user_types::RenderPass::camera_).asRef(), camera); + commandInterface.set({renderPass, &user_types::RenderPass::camera_}, camera); + ASSERT_EQ(core::ValueHandle(renderPass, &user_types::RenderPass::camera_).asRef(), camera); commandInterface.moveScenegraphChildren({camera}, prefab); - ASSERT_EQ(raco::core::ValueHandle(renderPass, &raco::user_types::RenderPass::camera_).asRef(), SEditorObject()); + ASSERT_EQ(core::ValueHandle(renderPass, &user_types::RenderPass::camera_).asRef(), SEditorObject()); commandInterface.undoStack().undo(); - ASSERT_EQ(raco::core::ValueHandle(renderPass, &raco::user_types::RenderPass::camera_).asRef(), camera); + ASSERT_EQ(core::ValueHandle(renderPass, &user_types::RenderPass::camera_).asRef(), camera); commandInterface.undoStack().redo(); - ASSERT_EQ(raco::core::ValueHandle(renderPass, &raco::user_types::RenderPass::camera_).asRef(), SEditorObject()); + ASSERT_EQ(core::ValueHandle(renderPass, &user_types::RenderPass::camera_).asRef(), SEditorObject()); } TEST_F(UndoTest, composite_single_op) { @@ -1872,3 +1872,278 @@ TEST_F(UndoTest, set_multi_double_merge) { EXPECT_EQ(index + 1, undoStack.getIndex()); EXPECT_EQ(size + 1, undoStack.size()); } + +TEST_F(UndoTest, add_remove_property_array_double) { + Array ad; + *ad.addProperty() = -1.0; + *ad.addProperty() = -2.0; + + auto obj = create("obj"); + ValueHandle tableHandle{obj, &ObjectWithArrays::table_}; + + checkUndoRedoMultiStep<2>( + {[this, tableHandle, &ad]() { + context.addProperty(tableHandle, "array", std::make_unique>>(ad)); + this->undoStack.push("step 1"); + }, + [this, tableHandle]() { + context.removeProperty(tableHandle, "array"); + this->undoStack.push("step 2"); + }}, + {[this, obj]() { + EXPECT_EQ(obj->table_->size(), 0); + }, + [this, obj, &ad]() { + EXPECT_EQ(obj->table_->size(), 1); + EXPECT_TRUE(obj->table_->get("array")->asArray() == ad); + }, + [this, obj]() { + EXPECT_EQ(obj->table_->size(), 0); + }}); +} + +TEST_F(UndoTest, add_remove_property_array_array_double) { + Array ad; + *ad.addProperty() = -1.0; + *ad.addProperty() = -2.0; + Array> aad; + *aad.addProperty() = ad; + + auto obj = create("obj"); + ValueHandle tableHandle{obj, &ObjectWithArrays::table_}; + + checkUndoRedoMultiStep<2>( + {[this, tableHandle, &aad]() { + context.addProperty(tableHandle, "array", std::make_unique>>>(aad)); + this->undoStack.push("step 1"); + }, + [this, tableHandle]() { + context.removeProperty(tableHandle, "array"); + this->undoStack.push("step 2"); + }}, + {[this, obj]() { + EXPECT_EQ(obj->table_->size(), 0); + }, + [this, obj, &aad]() { + EXPECT_EQ(obj->table_->size(), 1); + EXPECT_TRUE(obj->table_->get("array")->asArray() == aad); + }, + [this, obj]() { + EXPECT_EQ(obj->table_->size(), 0); + }}); +} + +TEST_F(UndoTest, add_remove_property_array_with_ref) { + auto refTarget = create("foo"); + Array aref; + *aref.addProperty() = refTarget; + + auto obj = create("obj"); + ValueHandle tableHandle{obj, &ObjectWithArrays::table_}; + + checkUndoRedoMultiStep<2>( + {[this, tableHandle, &aref]() { + context.addProperty(tableHandle, "array", std::make_unique>>(aref)); + this->undoStack.push("step 1"); + }, + [this, tableHandle]() { + context.removeProperty(tableHandle, "array"); + this->undoStack.push("step 2"); + }}, + {[this, obj, refTarget]() { + EXPECT_EQ(obj->table_->size(), 0); + EXPECT_EQ(refTarget->referencesToThis().size(), 0); + }, + [this, obj, refTarget, &aref]() { + EXPECT_EQ(obj->table_->size(), 1); + ASSERT_EQ(refTarget->referencesToThis().size(), 1); + EXPECT_TRUE(obj->table_->get("array")->asArray() == aref); + EXPECT_EQ(refTarget->referencesToThis().begin()->lock(), obj); + }, + [this, obj, refTarget]() { + EXPECT_EQ(obj->table_->size(), 0); + EXPECT_EQ(refTarget->referencesToThis().size(), 0); + }}); +} + +TEST_F(UndoTest, set_array_elem_array_double) { + Array ad; + *ad.addProperty() = -1.0; + *ad.addProperty() = -2.0; + + auto obj = create("obj"); + ValueHandle tableHandle{obj, &ObjectWithArrays::table_}; + + checkUndoRedoMultiStep<2>( + {[this, tableHandle, &ad]() { + context.addProperty(tableHandle, "array", std::make_unique>>(ad)); + this->undoStack.push("step 1"); + }, + [this, tableHandle]() { + context.set(tableHandle.get("array")[0], 12.0); + this->undoStack.push("step 2"); + }}, + {[this, obj]() { + EXPECT_EQ(obj->table_->size(), 0); + }, + [this, obj, &ad]() { + EXPECT_EQ(obj->table_->size(), 1); + EXPECT_TRUE(obj->table_->get("array")->asArray() == ad); + }, + [this, obj]() { + EXPECT_EQ(obj->table_->size(), 1); + EXPECT_EQ(obj->table_->get("array")->asArray().get(0)->asDouble(), 12.0); + EXPECT_EQ(obj->table_->get("array")->asArray().get(1)->asDouble(), -2.0); + }}); +} + +TEST_F(UndoTest, add_remove_array_element) { + auto obj = create("obj"); + ValueHandle arrayHandle{obj, &ObjectWithArrays::array_double_}; + + checkUndoRedoMultiStep<2>( + {[this, arrayHandle]() { + context.addProperty(arrayHandle, {}, std::make_unique>(12.0)); + context.addProperty(arrayHandle, {}, std::make_unique>(3.0), 0); + context.addProperty(arrayHandle, {}, std::make_unique>(15.0), -1); + context.addProperty(arrayHandle, {}, std::make_unique>(17.0)); + this->undoStack.push("step 1"); + }, + [this, arrayHandle]() { + context.removeProperty(arrayHandle, 1); + context.removeProperty(arrayHandle, "1"); + context.removeAllProperties(arrayHandle); + this->undoStack.push("step 2"); + }}, + {[this, obj]() { + EXPECT_EQ(obj->array_double_->size(), 0); + }, + [this, obj]() { + EXPECT_EQ(obj->array_double_->size(), 4); + EXPECT_EQ(**obj->array_double_->get(0), 3.0); + EXPECT_EQ(**obj->array_double_->get(1), 12.0); + EXPECT_EQ(**obj->array_double_->get(2), 15.0); + EXPECT_EQ(**obj->array_double_->get(3), 17.0); + }, + [this, obj]() { + EXPECT_EQ(obj->array_double_->size(), 0); + }}); +} + +TEST_F(UndoTest, set_array) { + Array ad_1; + *ad_1.addProperty() = -1.0; + *ad_1.addProperty() = -2.0; + + Array ad_2; + *ad_2.addProperty() = 1.0; + *ad_2.addProperty() = 2.0; + *ad_2.addProperty() = 3.0; + + auto obj = create("obj"); + ValueHandle arrayHandle{obj, &ObjectWithArrays::array_double_}; + + checkUndoRedoMultiStep<2>( + {[this, arrayHandle, &ad_1]() { + context.set(arrayHandle, ad_1); + this->undoStack.push("step 1"); + }, + [this, arrayHandle, &ad_2]() { + context.set(arrayHandle, ad_2); + this->undoStack.push("step 2"); + }}, + {[this, obj]() { + EXPECT_EQ(obj->array_double_->size(), 0); + }, + [this, obj, &ad_1]() { + EXPECT_TRUE(*obj->array_double_ == ad_1); + }, + [this, obj, &ad_2]() { + EXPECT_TRUE(*obj->array_double_ == ad_2); + }}); +} + +TEST_F(UndoTest, set_array_ref) { + auto node_1 = create("node1"); + auto node_2 = create("node2"); + auto meshnode_1 = create("meshnode1"); + auto meshnode_2 = create("meshnode2"); + auto meshnode_3 = create("meshnode3"); + + Array aref_nodes; + *aref_nodes.addProperty() = node_1; + *aref_nodes.addProperty() = node_2; + + Array aref_meshnodes; + *aref_meshnodes.addProperty() = meshnode_1; + *aref_meshnodes.addProperty() = meshnode_2; + *aref_meshnodes.addProperty() = meshnode_3; + + auto obj = create("obj"); + ValueHandle arrayHandle{obj, &ObjectWithArrays::array_ref_}; + + checkUndoRedoMultiStep<2>( + {[this, arrayHandle, &aref_nodes]() { + context.set(arrayHandle, aref_nodes); + this->undoStack.push("step 1"); + }, + [this, arrayHandle, &aref_meshnodes]() { + context.set(arrayHandle, aref_meshnodes); + this->undoStack.push("step 2"); + }}, + {[this, obj, node_1, node_2, meshnode_1, meshnode_2, meshnode_3]() { + EXPECT_EQ(obj->array_ref_->size(), 0); + EXPECT_EQ(node_1->referencesToThis().size(), 0); + EXPECT_EQ(node_2->referencesToThis().size(), 0); + EXPECT_EQ(meshnode_1->referencesToThis().size(), 0); + EXPECT_EQ(meshnode_2->referencesToThis().size(), 0); + EXPECT_EQ(meshnode_3->referencesToThis().size(), 0); + }, + [this, obj, node_1, node_2, meshnode_1, meshnode_2, meshnode_3, &aref_nodes]() { + EXPECT_TRUE(*obj->array_ref_ == aref_nodes); + EXPECT_EQ(node_1->referencesToThis().size(), 1); + EXPECT_EQ(node_1->referencesToThis().begin()->lock(), obj); + EXPECT_EQ(node_2->referencesToThis().size(), 1); + EXPECT_EQ(node_2->referencesToThis().begin()->lock(), obj); + EXPECT_EQ(meshnode_1->referencesToThis().size(), 0); + EXPECT_EQ(meshnode_2->referencesToThis().size(), 0); + EXPECT_EQ(meshnode_3->referencesToThis().size(), 0); + }, + [this, obj, node_1, node_2, meshnode_1, meshnode_2, meshnode_3, &aref_meshnodes]() { + EXPECT_TRUE(*obj->array_ref_ == aref_meshnodes); + EXPECT_EQ(node_1->referencesToThis().size(), 0); + EXPECT_EQ(node_2->referencesToThis().size(), 0); + EXPECT_EQ(meshnode_1->referencesToThis().size(), 1); + EXPECT_EQ(meshnode_1->referencesToThis().begin()->lock(), obj); + EXPECT_EQ(meshnode_2->referencesToThis().size(), 1); + EXPECT_EQ(meshnode_2->referencesToThis().begin()->lock(), obj); + EXPECT_EQ(meshnode_3->referencesToThis().size(), 1); + EXPECT_EQ(meshnode_3->referencesToThis().begin()->lock(), obj); + }}); +} + + +TEST_F(UndoTest, volatile_no_undo) { + auto node = create("node"); + + EXPECT_EQ(*node->visibility_, true); + EXPECT_EQ(*node->editorVisibility_, true); + + size_t preIndex = this->undoStack.getIndex(); + commandInterface.set({node, &Node::visibility_}, false); + commandInterface.set({node, &Node::editorVisibility_}, false); + + EXPECT_EQ(*node->visibility_, false); + EXPECT_EQ(*node->editorVisibility_, false); + + size_t postIndex = this->undoStack.getIndex(); + this->undoStack.setIndex(preIndex); + + EXPECT_EQ(*node->visibility_, true); + EXPECT_EQ(*node->editorVisibility_, false); + + this->undoStack.setIndex(postIndex); + + EXPECT_EQ(*node->visibility_, false); + EXPECT_EQ(*node->editorVisibility_, false); +} \ No newline at end of file diff --git a/datamodel/libCore/tests/expectations/Arrays.json b/datamodel/libCore/tests/expectations/Arrays.json new file mode 100644 index 00000000..3dfb89a9 --- /dev/null +++ b/datamodel/libCore/tests/expectations/Arrays.json @@ -0,0 +1,327 @@ +{ + "externalProjects": { + }, + "featureLevel": -1, + "links": [ + ], + "objectOriginFolders": { + }, + "objects": [ + { + "properties": { + "array_array_double": [ + [ + 0, + 0.1, + 0.2 + ], + [ + 1, + 1.1, + 1.2 + ] + ], + "array_double": [ + 0, + 1 + ], + "array_ref": [ + "node_1_id", + "node_2_id" + ], + "objectID": "obj_id", + "objectName": "obj_name", + "table": { + "order": [ + "array", + "nested", + "array_ref" + ], + "properties": { + "array": { + "properties": [ + 0, + 1 + ], + "typeName": "Array[Double]" + }, + "array_ref": { + "properties": [ + "node_1_id", + "node_2_id" + ], + "typeName": "Array[Node]" + }, + "nested": { + "properties": [ + [ + 0, + 0.1, + 0.2 + ], + [ + 1, + 1.1, + 1.2 + ] + ], + "typeName": "Array[Array[Double]]" + } + } + } + }, + "typeName": "ObjectWithArrays" + }, + { + "properties": { + "enabled": true, + "objectID": "node_1_id", + "objectName": "node_1", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "Node" + }, + { + "properties": { + "enabled": true, + "objectID": "node_2_id", + "objectName": "node_2", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "Node" + } + ], + "rootObjectIDs": [ + "obj_id", + "node_1_id", + "node_2_id" + ] +} diff --git a/datamodel/libCore/tests/expectations/LuaScriptLinkedToNode.json b/datamodel/libCore/tests/expectations/LuaScriptLinkedToNode.json index d0dc0d86..caad4527 100644 --- a/datamodel/libCore/tests/expectations/LuaScriptLinkedToNode.json +++ b/datamodel/libCore/tests/expectations/LuaScriptLinkedToNode.json @@ -6,29 +6,16 @@ { "properties": { "endObject": "node_id", - "endProp": { - "properties": [ - { - "typeName": "String", - "value": "translation" - } - ] - }, + "endProp": [ + "translation" + ], "isValid": true, "isWeak": false, "startObject": "lua_script_id", - "startProp": { - "properties": [ - { - "typeName": "String", - "value": "outputs" - }, - { - "typeName": "String", - "value": "translation" - } - ] - } + "startProp": [ + "outputs", + "translation" + ] }, "typeName": "Link" } diff --git a/datamodel/libCore/tests/expectations/Mesh.json b/datamodel/libCore/tests/expectations/Mesh.json index b76e3834..c5af944a 100644 --- a/datamodel/libCore/tests/expectations/Mesh.json +++ b/datamodel/libCore/tests/expectations/Mesh.json @@ -10,6 +10,35 @@ ] }, "meshIndex": 0, + "metaData": { + "order": [ + "meshInfo" + ], + "properties": { + "meshInfo": { + "annotations": [ + { + "typeName": "ReadOnlyAnnotation" + } + ], + "order": [ + "triangles", + "vertices" + ], + "properties": { + "triangles": { + "typeName": "Int", + "value": 4212 + }, + "vertices": { + "typeName": "Int", + "value": 2399 + } + }, + "typeName": "Table::ReadOnlyAnnotation" + } + } + }, "objectID": "mesh_id", "objectName": "mesh", "uri": "SerializationTest/serializeMesh/testData/duck.glb" diff --git a/datamodel/libCore/tests/expectations/NodeWithChildMeshNode.json b/datamodel/libCore/tests/expectations/NodeWithChildMeshNode.json index 62bd7e1e..6685bfa7 100644 --- a/datamodel/libCore/tests/expectations/NodeWithChildMeshNode.json +++ b/datamodel/libCore/tests/expectations/NodeWithChildMeshNode.json @@ -1,13 +1,8 @@ { "properties": { - "children": { - "properties": [ - { - "typeName": "Ref", - "value": "mesh_node_id" - } - ] - }, + "children": [ + "mesh_node_id" + ], "enabled": true, "objectID": "node_id", "objectName": "node", diff --git a/datamodel/libCore/tests/migrationTestData/V44.rca b/datamodel/libCore/tests/migrationTestData/V44.rca index 3f298a03..bc1d2256 100644 --- a/datamodel/libCore/tests/migrationTestData/V44.rca +++ b/datamodel/libCore/tests/migrationTestData/V44.rca @@ -144,9 +144,9 @@ } }, "uriDefines": "", - "uriFragment": "../../../../resources/shaders/basic-alpha.frag", + "uriFragment": "../testData/basic.frag", "uriGeometry": "", - "uriVertex": "../../../../resources/shaders/basic-alpha.vert" + "uriVertex": "../testData/basic.vert" }, "typeName": "Material" }, @@ -1045,7 +1045,7 @@ "meshIndex": 0, "objectID": "8dcb406c-3056-4de0-94bc-8f64e8d05306", "objectName": "Mesh", - "uri": "../../../../../../OneDrive - Paradox Cat GmbH/Documents/RamsesComposer/meshes/cube.gltf" + "uri": "../testData/cube.gltf" }, "typeName": "Mesh" }, diff --git a/screenshot_tests/projects/morphing.rca b/datamodel/libCore/tests/migrationTestData/V54-rendertarget-base.rca similarity index 65% rename from screenshot_tests/projects/morphing.rca rename to datamodel/libCore/tests/migrationTestData/V54-rendertarget-base.rca index 86a21bf3..fc68672e 100644 --- a/screenshot_tests/projects/morphing.rca +++ b/datamodel/libCore/tests/migrationTestData/V54-rendertarget-base.rca @@ -1,26 +1,126 @@ { "externalProjects": { }, - "featureLevel": 4, - "fileVersion": 47, + "featureLevel": 5, + "fileVersion": 54, "instances": [ + { + "properties": { + "backgroundColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "defaultResourceFolders": { + "imageSubdirectory": "images", + "interfaceSubdirectory": "interfaces", + "meshSubdirectory": "meshes", + "scriptSubdirectory": "scripts", + "shaderSubdirectory": "shaders" + }, + "featureLevel": 5, + "objectID": "23506439-27f1-4e29-8c49-ce748b82e2fa", + "objectName": "rendertarget-base", + "saveAsZip": false, + "sceneId": { + "annotations": [ + { + "properties": { + "max": 1024, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 123 + }, + "viewport": { + "i1": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + } + } + }, + "typeName": "ProjectSettings" + }, { "properties": { "children": { "properties": [ { "typeName": "Ref", - "value": "e69caa22-df52-4a86-8e7e-2d5925c8f16f" - }, - { - "typeName": "Ref", - "value": "bae4c8ab-c42c-4a51-9b3b-e526495ba5f1" + "value": "50bb1849-d0d4-4d2b-9c6f-021084658cb2" } ] }, "enabled": true, - "objectID": "25e3818c-8028-4cc8-b318-a007fbc6724d", - "objectName": "AnimatedMorphCube.gltf", + "objectID": "c325a7d5-f231-43d3-9cda-45676d25c965", + "objectName": "Node", "rotation": { "x": { "annotations": [ @@ -97,6 +197,14 @@ "value": 1 } }, + "tags": { + "properties": [ + { + "typeName": "String", + "value": "render_main" + } + ] + }, "translation": { "x": { "annotations": [ @@ -139,210 +247,6 @@ }, "typeName": "Node" }, - { - "properties": { - "animationIndex": 0, - "objectID": "5989a658-3868-4106-a4e7-d468cdf046c6", - "objectName": "Square.ch0", - "samplerIndex": 0, - "uri": "../../resources/meshes/AnimatedMorphCube/AnimatedMorphCube.gltf" - }, - "typeName": "AnimationChannel" - }, - { - "properties": { - "objectID": "b61a6d00-300d-4086-a59a-01d93991e336", - "objectName": "Material", - "options": { - "blendColor": { - "w": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "x": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "blendFactorDestAlpha": 1, - "blendFactorDestColor": 3, - "blendFactorSrcAlpha": 1, - "blendFactorSrcColor": 2, - "blendOperationAlpha": 0, - "blendOperationColor": 0, - "cullmode": 2, - "depthFunction": 4, - "depthwrite": true - }, - "uniforms": { - "order": [ - "weights", - "u_color" - ], - "properties": { - "u_color": { - "annotations": [ - { - "properties": { - "engineType": 8 - }, - "typeName": "EngineTypeAnnotation" - }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } - ], - "properties": { - "x": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" - }, - "weights": { - "annotations": [ - { - "properties": { - "engineType": 14 - }, - "typeName": "EngineTypeAnnotation" - }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } - ], - "order": [ - "1", - "2" - ], - "properties": { - "1": { - "annotations": [ - { - "properties": { - "engineType": 5 - }, - "typeName": "EngineTypeAnnotation" - }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", - "value": 0 - }, - "2": { - "annotations": [ - { - "properties": { - "engineType": 5 - }, - "typeName": "EngineTypeAnnotation" - }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", - "value": 0 - } - }, - "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" - } - } - }, - "uriDefines": "", - "uriFragment": "shaders/morphing-template.frag", - "uriGeometry": "", - "uriVertex": "shaders/morphing-template.vert" - }, - "typeName": "Material" - }, { "properties": { "enabled": true, @@ -377,7 +281,7 @@ } ], "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 1 + "value": 2 }, "farPlane": { "annotations": [ @@ -457,7 +361,7 @@ } }, "frustumType": 0, - "objectID": "b7bc3f22-0cd9-4004-b2f0-ded8e945088f", + "objectID": "c3be671d-893e-43a4-bd23-ddb6bcefebfd", "objectName": "PerspectiveCamera", "rotation": { "x": { @@ -584,7 +488,7 @@ "typeName": "RangeAnnotationInt" } ], - "value": 400 + "value": 720 }, "offsetX": { "annotations": [ @@ -620,7 +524,7 @@ "typeName": "RangeAnnotationInt" } ], - "value": 400 + "value": 1440 } }, "visibility": true @@ -629,150 +533,218 @@ }, { "properties": { - "animationChannels": { - "order": [ - "Channel 0" - ], - "properties": { - "Channel 0": { - "typeName": "AnimationChannel", - "value": "5989a658-3868-4106-a4e7-d468cdf046c6" - } + "camera": null, + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 } }, - "objectID": "bae4c8ab-c42c-4a51-9b3b-e526495ba5f1", - "objectName": "Square", - "outputs": { - "order": [ - "Ch0.Square.ch0" + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layer0": null, + "layer1": null, + "layer2": null, + "layer3": null, + "layer4": null, + "layer5": null, + "layer6": null, + "layer7": null, + "objectID": "05755c0d-5c29-4950-a1f7-2045bcd98653", + "objectName": "rp-mixed", + "renderOnce": false, + "renderOrder": 1, + "target": "e6dd3803-b2aa-4978-a09a-b4abdb8558ef" + }, + "typeName": "RenderPass" + }, + { + "properties": { + "anisotropy": { + "annotations": [ + { + "properties": { + "max": 32000, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } ], - "properties": { - "Ch0.Square.ch0": { - "annotations": [ - { - "properties": { - "engineType": 14 - }, - "typeName": "EngineTypeAnnotation" - }, - { - "typeName": "LinkStartAnnotation" - } - ], - "order": [ - "1", - "2" - ], + "value": 1 + }, + "format": 4, + "height": { + "annotations": [ + { "properties": { - "1": { - "annotations": [ - { - "properties": { - "engineType": 5 - }, - "typeName": "EngineTypeAnnotation" - }, - { - "typeName": "LinkStartAnnotation" - } - ], - "typeName": "Double::EngineTypeAnnotation::LinkStartAnnotation", - "value": 0 - }, - "2": { - "annotations": [ - { - "properties": { - "engineType": 5 - }, - "typeName": "EngineTypeAnnotation" - }, - { - "typeName": "LinkStartAnnotation" - } - ], - "typeName": "Double::EngineTypeAnnotation::LinkStartAnnotation", - "value": 0.7310736775398254 - } + "max": 7680, + "min": 1 }, - "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation" + "typeName": "RangeAnnotationInt" } - } + ], + "value": 256 }, - "progress": { + "magSamplingMethod": 0, + "minSamplingMethod": 0, + "objectID": "2ad46e3e-4011-4ae6-984c-d013c6864204", + "objectName": "RenderBuffer", + "width": { "annotations": [ { "properties": { - "max": 1, - "min": 0 + "max": 7680, + "min": 1 }, - "typeName": "RangeAnnotationDouble" + "typeName": "RangeAnnotationInt" } ], - "value": 0.8743589743589735 - } + "value": 256 + }, + "wrapUMode": 0, + "wrapVMode": 0 }, - "typeName": "Animation" + "typeName": "RenderBuffer" }, { "properties": { - "bakeMeshes": false, - "materialNames": { - "properties": [ + "format": 4, + "height": { + "annotations": [ { - "typeName": "String", - "value": "material" + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" } - ] + ], + "value": 256 }, - "meshIndex": 0, - "objectID": "c684011a-e199-468a-bdcb-51e72bd3249b", - "objectName": "Cube", - "uri": "../../resources/meshes/AnimatedMorphCube/AnimatedMorphCube.gltf" + "objectID": "43648499-e4a6-48b0-b654-4eab4898abb5", + "objectName": "RenderBufferMS", + "sampleCount": { + "annotations": [ + { + "properties": { + "max": 8, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + } }, - "typeName": "Mesh" + "typeName": "RenderBufferMS" }, { "properties": { - "materialFilterMode": 1, - "objectID": "ca08e470-8451-4702-9084-68b417ca4129", - "objectName": "MainRenderLayer", - "renderableTags": { - "order": [ - "render_main" - ], - "properties": { - "render_main": { - "annotations": [ - { - "properties": { - "featureLevel": 3 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Int::LinkEndAnnotation", - "value": 0 + "buffer0": "2ad46e3e-4011-4ae6-984c-d013c6864204", + "buffer1": null, + "buffer2": null, + "buffer3": null, + "buffer4": null, + "buffer5": null, + "buffer6": null, + "buffer7": null, + "bufferMS0": null, + "bufferMS1": null, + "bufferMS2": null, + "bufferMS3": null, + "bufferMS4": null, + "bufferMS5": null, + "bufferMS6": null, + "bufferMS7": null, + "objectID": "4f4ec080-b8aa-4b84-96fa-eb04909289a4", + "objectName": "rt-normal", + "userTags": { + "properties": [ + { + "typeName": "String", + "value": "test" } - } - }, - "sortOrder": 0 + ] + } }, - "typeName": "RenderLayer" + "typeName": "RenderTarget" }, { "properties": { - "children": { - "properties": [ + "enabled": true, + "instanceCount": { + "annotations": [ { - "typeName": "Ref", - "value": "25e3818c-8028-4cc8-b318-a007fbc6724d" + "properties": { + "max": 20, + "min": 1 + }, + "typeName": "RangeAnnotationInt" } - ] + ], + "value": 1 }, - "enabled": true, - "objectID": "cda39099-fa49-48fb-b41e-6f9899c29631", - "objectName": "Node", + "mesh": null, + "objectID": "50bb1849-d0d4-4d2b-9c6f-021084658cb2", + "objectName": "MeshNode", "rotation": { "x": { "annotations": [ @@ -784,7 +756,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 16.62817551963048 + "value": 0 }, "y": { "annotations": [ @@ -796,7 +768,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 44.89607390300232 + "value": 0 }, "z": { "annotations": [ @@ -843,19 +815,11 @@ "max": 100, "min": 0.1 }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 1 - } - }, - "tags": { - "properties": [ - { - "typeName": "String", - "value": "render_main" - } - ] + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } }, "translation": { "x": { @@ -892,16 +856,17 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 3 + "value": 0 } }, "visibility": true }, - "typeName": "Node" + "typeName": "MeshNode" }, { "properties": { - "backgroundColor": { + "camera": "c3be671d-893e-43a4-bd23-ddb6bcefebfd", + "clearColor": { "w": { "annotations": [ { @@ -912,7 +877,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 1 + "value": 0 }, "x": { "annotations": [ @@ -951,388 +916,107 @@ "value": 0 } }, - "defaultResourceFolders": { - "imageSubdirectory": "images", - "interfaceSubdirectory": "interfaces", - "meshSubdirectory": "meshes", - "scriptSubdirectory": "scripts", - "shaderSubdirectory": "shaders" - }, - "featureLevel": 4, - "objectID": "d7cab50b-975a-4529-bdb5-ab30bede014c", - "objectName": "morphing", - "saveAsZip": false, - "sceneId": { - "annotations": [ + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layer0": "8eb37565-2194-43bd-b748-8bdca98ef38b", + "layer1": null, + "layer2": null, + "layer3": null, + "layer4": null, + "layer5": null, + "layer6": null, + "layer7": null, + "objectID": "55fd51d6-b6d8-43b6-816d-da4f4a83b119", + "objectName": "MainRenderPass", + "renderOnce": false, + "renderOrder": 1, + "target": null + }, + "typeName": "RenderPass" + }, + { + "properties": { + "buffer0": null, + "buffer1": null, + "buffer2": null, + "buffer3": null, + "buffer4": null, + "buffer5": null, + "buffer6": null, + "buffer7": null, + "bufferMS0": "43648499-e4a6-48b0-b654-4eab4898abb5", + "bufferMS1": null, + "bufferMS2": null, + "bufferMS3": null, + "bufferMS4": null, + "bufferMS5": null, + "bufferMS6": null, + "bufferMS7": null, + "objectID": "89bc24f1-2232-47f7-a8a7-4435e8a8d5f2", + "objectName": "rt-multi", + "userTags": { + "properties": [ { - "properties": { - "max": 1024, - "min": 1 - }, - "typeName": "RangeAnnotationInt" + "typeName": "String", + "value": "test" } - ], - "value": 123 - }, - "viewport": { - "i1": { - "annotations": [ - { - "properties": { - "max": 4096, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 400 - }, - "i2": { - "annotations": [ - { - "properties": { - "max": 4096, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 400 - } + ] } }, - "typeName": "ProjectSettings" + "typeName": "RenderTarget" }, { "properties": { - "enabled": true, - "instanceCount": { - "annotations": [ - { - "properties": { - "max": 20, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 - }, - "materials": { + "materialFilterMode": 1, + "objectID": "8eb37565-2194-43bd-b748-8bdca98ef38b", + "objectName": "MainRenderLayer", + "renderableTags": { "order": [ - "material" + "render_main" ], "properties": { - "material": { - "order": [ - "material", - "private", - "options", - "uniforms" - ], - "properties": { - "material": { - "typeName": "Material", - "value": "b61a6d00-300d-4086-a59a-01d93991e336" - }, - "options": { - "annotations": [ - { - "properties": { - "name": "Options" - }, - "typeName": "DisplayNameAnnotation" - } - ], - "properties": { - "blendColor": { - "w": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "x": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "blendFactorDestAlpha": 1, - "blendFactorDestColor": 3, - "blendFactorSrcAlpha": 1, - "blendFactorSrcColor": 2, - "blendOperationAlpha": 0, - "blendOperationColor": 0, - "cullmode": 2, - "depthFunction": 4, - "depthwrite": true - }, - "typeName": "BlendOptions::DisplayNameAnnotation" - }, - "private": { - "annotations": [ - { - "properties": { - "name": "Private Material" - }, - "typeName": "DisplayNameAnnotation" - } - ], - "typeName": "Bool::DisplayNameAnnotation", - "value": true - }, - "uniforms": { - "order": [ - "weights", - "u_color" - ], + "render_main": { + "annotations": [ + { "properties": { - "u_color": { - "annotations": [ - { - "properties": { - "engineType": 8 - }, - "typeName": "EngineTypeAnnotation" - }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } - ], - "properties": { - "x": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0.3333333333333333 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0.6666666666666666 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 1 - } - }, - "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" - }, - "weights": { - "annotations": [ - { - "properties": { - "engineType": 14 - }, - "typeName": "EngineTypeAnnotation" - }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } - ], - "order": [ - "1", - "2" - ], - "properties": { - "1": { - "annotations": [ - { - "properties": { - "engineType": 5 - }, - "typeName": "EngineTypeAnnotation" - }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", - "value": 0 - }, - "2": { - "annotations": [ - { - "properties": { - "engineType": 5 - }, - "typeName": "EngineTypeAnnotation" - }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", - "value": 0.7310736775398254 - } - }, - "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" - } + "featureLevel": 3 }, - "typeName": "Table" + "typeName": "LinkEndAnnotation" } - }, - "typeName": "Table" + ], + "typeName": "Int::LinkEndAnnotation", + "value": 0 } } }, - "mesh": "c684011a-e199-468a-bdcb-51e72bd3249b", - "objectID": "e69caa22-df52-4a86-8e7e-2d5925c8f16f", - "objectName": "AnimatedMorphCube", - "rotation": { - "x": { - "annotations": [ - { - "properties": { - "max": 360, - "min": -360 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 89.99999237060547 - }, - "y": { + "sortOrder": 0 + }, + "typeName": "RenderLayer" + }, + { + "properties": { + "camera": null, + "clearColor": { + "w": { "annotations": [ { "properties": { - "max": 360, - "min": -360 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } ], "value": 0 }, - "z": { - "annotations": [ - { - "properties": { - "max": 360, - "min": -360 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": -180 - } - }, - "scaling": { - "x": { - "annotations": [ - { - "properties": { - "max": 100, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 100 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 100, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 100 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 100, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 100 - } - }, - "translation": { "x": { "annotations": [ { "properties": { - "max": 100, - "min": -100 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } @@ -1343,8 +1027,8 @@ "annotations": [ { "properties": { - "max": 100, - "min": -100 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } @@ -1355,8 +1039,8 @@ "annotations": [ { "properties": { - "max": 100, - "min": -100 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } @@ -1364,13 +1048,29 @@ "value": 0 } }, - "visibility": true + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layer0": null, + "layer1": null, + "layer2": null, + "layer3": null, + "layer4": null, + "layer5": null, + "layer6": null, + "layer7": null, + "objectID": "b68713e1-2159-4e17-80fe-f7515566e28a", + "objectName": "rp-normal", + "renderOnce": false, + "renderOrder": 1, + "target": "4f4ec080-b8aa-4b84-96fa-eb04909289a4" }, - "typeName": "MeshNode" + "typeName": "RenderPass" }, { "properties": { - "camera": "b7bc3f22-0cd9-4004-b2f0-ded8e945088f", + "camera": null, "clearColor": { "w": { "annotations": [ @@ -1425,7 +1125,7 @@ "enableClearDepth": true, "enableClearStencil": true, "enabled": true, - "layer0": "ca08e470-8451-4702-9084-68b417ca4129", + "layer0": null, "layer1": null, "layer2": null, "layer3": null, @@ -1433,72 +1133,62 @@ "layer5": null, "layer6": null, "layer7": null, - "objectID": "fb603e5f-26de-40a4-8753-5e4cc0e5d96a", - "objectName": "MainRenderPass", + "objectID": "dbee1274-2b82-4626-b146-d5bdf075d6f6", + "objectName": "rp-multi", "renderOnce": false, "renderOrder": 1, - "target": null + "target": "89bc24f1-2232-47f7-a8a7-4435e8a8d5f2" }, "typeName": "RenderPass" - } - ], - "links": [ + }, { "properties": { - "endObject": "e69caa22-df52-4a86-8e7e-2d5925c8f16f", - "endProp": { - "properties": [ - { - "typeName": "String", - "value": "materials" - }, - { - "typeName": "String", - "value": "material" - }, - { - "typeName": "String", - "value": "uniforms" - }, - { - "typeName": "String", - "value": "weights" - } - ] - }, - "isValid": true, - "isWeak": false, - "startObject": "bae4c8ab-c42c-4a51-9b3b-e526495ba5f1", - "startProp": { + "buffer0": "2ad46e3e-4011-4ae6-984c-d013c6864204", + "buffer1": null, + "buffer2": null, + "buffer3": null, + "buffer4": null, + "buffer5": null, + "buffer6": null, + "buffer7": null, + "bufferMS0": "43648499-e4a6-48b0-b654-4eab4898abb5", + "bufferMS1": null, + "bufferMS2": null, + "bufferMS3": null, + "bufferMS4": null, + "bufferMS5": null, + "bufferMS6": null, + "bufferMS7": null, + "objectID": "e6dd3803-b2aa-4978-a09a-b4abdb8558ef", + "objectName": "rt-mixed", + "userTags": { "properties": [ { "typeName": "String", - "value": "outputs" - }, - { - "typeName": "String", - "value": "Ch0.Square.ch0" + "value": "test" } ] } }, - "typeName": "Link" + "typeName": "RenderTarget" } ], + "links": [ + ], "logicEngineVersion": [ 1, 4, - 0 + 2 ], "racoVersion": [ 1, - 6, + 10, 0 ], "ramsesVersion": [ 27, 0, - 126 + 130 ], "structPropMap": { "AnchorPointOutputs": { @@ -1513,9 +1203,12 @@ "blendFactorSrcColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", "blendOperationAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", "blendOperationColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "colorWriteMask": "ColorWriteMask::DisplayNameAnnotation", "cullmode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "depthFunction": "Int::DisplayNameAnnotation::EnumerationAnnotation", - "depthwrite": "Bool::DisplayNameAnnotation" + "depthwrite": "Bool::DisplayNameAnnotation", + "scissorOptions": "ScissorOptions::DisplayNameAnnotation", + "stencilOptions": "StencilOptions::DisplayNameAnnotation" }, "CameraViewport": { "height": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", @@ -1523,6 +1216,12 @@ "offsetY": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", "width": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation" }, + "ColorWriteMask": { + "alpha": "Bool::DisplayNameAnnotation", + "blue": "Bool::DisplayNameAnnotation", + "green": "Bool::DisplayNameAnnotation", + "red": "Bool::DisplayNameAnnotation" + }, "DefaultResourceDirectories": { "imageSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", "interfaceSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", @@ -1545,6 +1244,18 @@ "rightPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", "topPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation" }, + "ScissorOptions": { + "scissorEnable": "Bool::DisplayNameAnnotation", + "scissorRegion": "CameraViewport::DisplayNameAnnotation" + }, + "StencilOptions": { + "stencilFunc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilMask": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "stencilOpDepthFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpDepthSucc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpStencilFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilRef": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, "TimerInput": { "ticker_us": "Int64::DisplayNameAnnotation::LinkEndAnnotation" }, @@ -1589,7 +1300,8 @@ "node": "Node::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "outputs": "AnchorPointOutputs::DisplayNameAnnotation" + "outputs": "AnchorPointOutputs::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Animation": { "animationChannels": "Table::DisplayNameAnnotation", @@ -1597,7 +1309,8 @@ "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "outputs": "Table::DisplayNameAnnotation", - "progress": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation" + "progress": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "AnimationChannel": { "animationIndex": "Int::DisplayNameAnnotation", @@ -1605,7 +1318,8 @@ "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "samplerIndex": "Int::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "BlitPass": { "children": "Table::ArraySemanticAnnotation::HiddenProperty", @@ -1622,6 +1336,7 @@ "sourceY": "Int::RangeAnnotationInt::DisplayNameAnnotation", "targetRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", "targetRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" }, "CubeMap": { @@ -1658,15 +1373,19 @@ "uriLeft": "String::URIAnnotation::DisplayNameAnnotation", "uriRight": "String::URIAnnotation::DisplayNameAnnotation", "uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" }, "LuaInterface": { "children": "Table::ArraySemanticAnnotation::HiddenProperty", "inputs": "Table::DisplayNameAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation::FeatureLevel", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation::FeatureLevel", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "LuaScript": { "children": "Table::ArraySemanticAnnotation::HiddenProperty", @@ -1676,14 +1395,16 @@ "objectName": "String::DisplayNameAnnotation", "outputs": "Table::DisplayNameAnnotation", "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "LuaScriptModule": { "children": "Table::ArraySemanticAnnotation::HiddenProperty", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Material": { "children": "Table::ArraySemanticAnnotation::HiddenProperty", @@ -1695,7 +1416,8 @@ "uriDefines": "String::URIAnnotation::DisplayNameAnnotation", "uriFragment": "String::URIAnnotation::DisplayNameAnnotation", "uriGeometry": "String::URIAnnotation::DisplayNameAnnotation", - "uriVertex": "String::URIAnnotation::DisplayNameAnnotation" + "uriVertex": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Mesh": { "bakeMeshes": "Bool::DisplayNameAnnotation", @@ -1704,12 +1426,13 @@ "meshIndex": "Int::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "MeshNode": { "children": "Table::ArraySemanticAnnotation::HiddenProperty", "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", - "instanceCount": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "instanceCount": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", "materials": "Table::DisplayNameAnnotation", "mesh": "Mesh::DisplayNameAnnotation", "objectID": "String::HiddenProperty", @@ -1718,6 +1441,7 @@ "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "Node": { @@ -1729,6 +1453,7 @@ "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "OrthographicCamera": { @@ -1741,6 +1466,7 @@ "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, @@ -1755,13 +1481,15 @@ "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "Prefab": { "children": "Table::ArraySemanticAnnotation::HiddenProperty", "objectID": "String::HiddenProperty", - "objectName": "String::DisplayNameAnnotation" + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "PrefabInstance": { "children": "Table::ArraySemanticAnnotation::HiddenProperty", @@ -1773,6 +1501,7 @@ "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "template": "Prefab::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "ProjectSettings": { @@ -1784,6 +1513,7 @@ "objectName": "String::DisplayNameAnnotation", "saveAsZip": "Bool::DisplayNameAnnotation", "sceneId": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "viewport": "Vec2i::DisplayNameAnnotation" }, "RenderBuffer": { @@ -1795,6 +1525,7 @@ "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "width": "Int::RangeAnnotationInt::DisplayNameAnnotation", "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" @@ -1806,6 +1537,7 @@ "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "sampleCount": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" }, "RenderLayer": { @@ -1816,7 +1548,8 @@ "objectName": "String::DisplayNameAnnotation", "renderableTags": "Table::RenderableTagContainerAnnotation::DisplayNameAnnotation", "sortOrder": "Int::DisplayNameAnnotation::EnumerationAnnotation", - "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation" + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "RenderPass": { "camera": "BaseCamera::DisplayNameAnnotation", @@ -1838,7 +1571,8 @@ "objectName": "String::DisplayNameAnnotation", "renderOnce": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", "renderOrder": "Int::DisplayNameAnnotation::LinkEndAnnotation", - "target": "RenderTarget::DisplayNameAnnotation::EmptyReferenceAllowable" + "target": "RenderTarget::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "RenderTarget": { "buffer0": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", @@ -1859,7 +1593,8 @@ "bufferMS7": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", "children": "Table::ArraySemanticAnnotation::HiddenProperty", "objectID": "String::HiddenProperty", - "objectName": "String::DisplayNameAnnotation" + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Skin": { "children": "Table::ArraySemanticAnnotation::HiddenProperty", @@ -1868,7 +1603,8 @@ "objectName": "String::DisplayNameAnnotation", "skinIndex": "Int::DisplayNameAnnotation", "targets": "Table::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Texture": { "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", @@ -1885,15 +1621,25 @@ "objectName": "String::DisplayNameAnnotation", "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" }, + "TextureExternal": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, "Timer": { "children": "Table::ArraySemanticAnnotation::HiddenProperty", "inputs": "TimerInput::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "outputs": "TimerOutput::DisplayNameAnnotation" + "outputs": "TimerOutput::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" } } } diff --git a/datamodel/libCore/tests/migrationTestData/V54-rendertarget-extref-keepalive.rca b/datamodel/libCore/tests/migrationTestData/V54-rendertarget-extref-keepalive.rca new file mode 100644 index 00000000..31bb415f --- /dev/null +++ b/datamodel/libCore/tests/migrationTestData/V54-rendertarget-extref-keepalive.rca @@ -0,0 +1,1656 @@ +{ + "externalProjects": { + "23506439-27f1-4e29-8c49-ce748b82e2fa": { + "name": "rendertarget-base", + "path": "V54-rendertarget-base.rca" + } + }, + "featureLevel": 5, + "fileVersion": 54, + "instances": [ + { + "properties": { + "backgroundColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "defaultResourceFolders": { + "imageSubdirectory": "images", + "interfaceSubdirectory": "interfaces", + "meshSubdirectory": "meshes", + "scriptSubdirectory": "scripts", + "shaderSubdirectory": "shaders" + }, + "featureLevel": 5, + "objectID": "eac08457-ffc6-42d7-88a7-4e0ff1398ca0", + "objectName": "rendertarget-extref", + "saveAsZip": false, + "sceneId": { + "annotations": [ + { + "properties": { + "max": 1024, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 123 + }, + "viewport": { + "i1": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + } + } + }, + "typeName": "ProjectSettings" + }, + { + "properties": { + "children": { + "properties": [ + { + "typeName": "Ref", + "value": "31de91b9-0b1c-47a8-9d66-b943025b9cbc" + } + ] + }, + "enabled": true, + "objectID": "65ca4fe8-fcbb-4688-a650-6538e0c2ab06", + "objectName": "Node", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "tags": { + "properties": [ + { + "typeName": "String", + "value": "render_main" + } + ] + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "Node" + }, + { + "properties": { + "enabled": true, + "frustum": { + "order": [ + "nearPlane", + "farPlane", + "fieldOfView", + "aspectRatio" + ], + "properties": { + "aspectRatio": { + "annotations": [ + { + "properties": { + "name": "aspectRatio" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 4, + "min": 0.5 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 2 + }, + "farPlane": { + "annotations": [ + { + "properties": { + "name": "farPlane" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 10000, + "min": 100 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 1000 + }, + "fieldOfView": { + "annotations": [ + { + "properties": { + "name": "fieldOfView" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 120, + "min": 10 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 35 + }, + "nearPlane": { + "annotations": [ + { + "properties": { + "name": "nearPlane" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 1, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 0.1 + } + } + }, + "frustumType": 0, + "objectID": "01a5cfeb-9ee7-4779-a3de-920b6b9bd86a", + "objectName": "PerspectiveCamera", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 10 + } + }, + "viewport": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + }, + "visibility": true + }, + "typeName": "PerspectiveCamera" + }, + { + "properties": { + "buffer0": null, + "buffer1": null, + "buffer2": null, + "buffer3": null, + "buffer4": null, + "buffer5": null, + "buffer6": null, + "buffer7": null, + "bufferMS0": "43648499-e4a6-48b0-b654-4eab4898abb5", + "bufferMS1": null, + "bufferMS2": null, + "bufferMS3": null, + "bufferMS4": null, + "bufferMS5": null, + "bufferMS6": null, + "bufferMS7": null, + "objectID": "0a19d0c9-ae7b-4b82-8462-90397826d682", + "objectName": "rt-keepalive-multi" + }, + "typeName": "RenderTarget" + }, + { + "properties": { + "camera": null, + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layer0": null, + "layer1": null, + "layer2": null, + "layer3": null, + "layer4": null, + "layer5": null, + "layer6": null, + "layer7": null, + "objectID": "2973cded-32ec-4c1c-850e-5563aa8eefcc", + "objectName": "rp-mixed", + "renderOnce": false, + "renderOrder": 1, + "target": "e6dd3803-b2aa-4978-a09a-b4abdb8558ef" + }, + "typeName": "RenderPass" + }, + { + "properties": { + "enabled": true, + "instanceCount": { + "annotations": [ + { + "properties": { + "max": 20, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "mesh": null, + "objectID": "31de91b9-0b1c-47a8-9d66-b943025b9cbc", + "objectName": "MeshNode", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "MeshNode" + }, + { + "annotations": [ + { + "properties": { + "projectID": "23506439-27f1-4e29-8c49-ce748b82e2fa" + }, + "typeName": "ExternalReferenceAnnotation" + } + ], + "properties": { + "format": 4, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "objectID": "43648499-e4a6-48b0-b654-4eab4898abb5", + "objectName": "RenderBufferMS", + "sampleCount": { + "annotations": [ + { + "properties": { + "max": 8, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + } + }, + "typeName": "RenderBufferMS" + }, + { + "properties": { + "camera": "01a5cfeb-9ee7-4779-a3de-920b6b9bd86a", + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layer0": "fde2cb09-6953-4157-a933-057dfd6b9279", + "layer1": null, + "layer2": null, + "layer3": null, + "layer4": null, + "layer5": null, + "layer6": null, + "layer7": null, + "objectID": "4db17c8b-c73e-47e4-9ec5-91200feb7aea", + "objectName": "MainRenderPass", + "renderOnce": false, + "renderOrder": 1, + "target": null + }, + "typeName": "RenderPass" + }, + { + "annotations": [ + { + "properties": { + "projectID": "23506439-27f1-4e29-8c49-ce748b82e2fa" + }, + "typeName": "ExternalReferenceAnnotation" + } + ], + "properties": { + "buffer0": null, + "buffer1": null, + "buffer2": null, + "buffer3": null, + "buffer4": null, + "buffer5": null, + "buffer6": null, + "buffer7": null, + "bufferMS0": null, + "bufferMS1": null, + "bufferMS2": null, + "bufferMS3": null, + "bufferMS4": null, + "bufferMS5": null, + "bufferMS6": null, + "bufferMS7": null, + "objectID": "4f4ec080-b8aa-4b84-96fa-eb04909289a4", + "objectName": "rt-normal", + "userTags": { + "properties": [ + { + "typeName": "String", + "value": "test" + } + ] + } + }, + "typeName": "RenderTarget" + }, + { + "annotations": [ + { + "properties": { + "projectID": "23506439-27f1-4e29-8c49-ce748b82e2fa" + }, + "typeName": "ExternalReferenceAnnotation" + } + ], + "properties": { + "buffer0": null, + "buffer1": null, + "buffer2": null, + "buffer3": null, + "buffer4": null, + "buffer5": null, + "buffer6": null, + "buffer7": null, + "bufferMS0": "43648499-e4a6-48b0-b654-4eab4898abb5", + "bufferMS1": null, + "bufferMS2": null, + "bufferMS3": null, + "bufferMS4": null, + "bufferMS5": null, + "bufferMS6": null, + "bufferMS7": null, + "objectID": "89bc24f1-2232-47f7-a8a7-4435e8a8d5f2", + "objectName": "rt-multi", + "userTags": { + "properties": [ + { + "typeName": "String", + "value": "test" + } + ] + } + }, + "typeName": "RenderTarget" + }, + { + "properties": { + "camera": null, + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layer0": null, + "layer1": null, + "layer2": null, + "layer3": null, + "layer4": null, + "layer5": null, + "layer6": null, + "layer7": null, + "objectID": "c6a20401-4c66-46b5-9e83-0423995269e4", + "objectName": "rp-multi", + "renderOnce": false, + "renderOrder": 1, + "target": "89bc24f1-2232-47f7-a8a7-4435e8a8d5f2" + }, + "typeName": "RenderPass" + }, + { + "annotations": [ + { + "properties": { + "projectID": "23506439-27f1-4e29-8c49-ce748b82e2fa" + }, + "typeName": "ExternalReferenceAnnotation" + } + ], + "properties": { + "buffer0": null, + "buffer1": null, + "buffer2": null, + "buffer3": null, + "buffer4": null, + "buffer5": null, + "buffer6": null, + "buffer7": null, + "bufferMS0": "43648499-e4a6-48b0-b654-4eab4898abb5", + "bufferMS1": null, + "bufferMS2": null, + "bufferMS3": null, + "bufferMS4": null, + "bufferMS5": null, + "bufferMS6": null, + "bufferMS7": null, + "objectID": "e6dd3803-b2aa-4978-a09a-b4abdb8558ef", + "objectName": "rt-mixed", + "userTags": { + "properties": [ + { + "typeName": "String", + "value": "test" + } + ] + } + }, + "typeName": "RenderTarget" + }, + { + "properties": { + "materialFilterMode": 1, + "objectID": "fde2cb09-6953-4157-a933-057dfd6b9279", + "objectName": "MainRenderLayer", + "renderableTags": { + "order": [ + "render_main" + ], + "properties": { + "render_main": { + "annotations": [ + { + "properties": { + "featureLevel": 3 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::LinkEndAnnotation", + "value": 0 + } + } + }, + "sortOrder": 0 + }, + "typeName": "RenderLayer" + }, + { + "properties": { + "camera": null, + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layer0": null, + "layer1": null, + "layer2": null, + "layer3": null, + "layer4": null, + "layer5": null, + "layer6": null, + "layer7": null, + "objectID": "fdf7c94c-c7d2-4972-981c-f329f80fca72", + "objectName": "rp-normal", + "renderOnce": false, + "renderOrder": 1, + "target": "4f4ec080-b8aa-4b84-96fa-eb04909289a4" + }, + "typeName": "RenderPass" + } + ], + "links": [ + ], + "logicEngineVersion": [ + 1, + 4, + 2 + ], + "racoVersion": [ + 1, + 10, + 0 + ], + "ramsesVersion": [ + 27, + 0, + 130 + ], + "structPropMap": { + "AnchorPointOutputs": { + "depth": "Double::DisplayNameAnnotation::LinkStartAnnotation", + "viewportCoords": "Vec2f::DisplayNameAnnotation::LinkStartAnnotation" + }, + "BlendOptions": { + "blendColor": "Vec4f::DisplayNameAnnotation", + "blendFactorDestAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorDestColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorSrcAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorSrcColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendOperationAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendOperationColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "colorWriteMask": "ColorWriteMask::DisplayNameAnnotation", + "cullmode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "depthFunction": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "depthwrite": "Bool::DisplayNameAnnotation", + "scissorOptions": "ScissorOptions::DisplayNameAnnotation", + "stencilOptions": "StencilOptions::DisplayNameAnnotation" + }, + "CameraViewport": { + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "offsetX": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "offsetY": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation" + }, + "ColorWriteMask": { + "alpha": "Bool::DisplayNameAnnotation", + "blue": "Bool::DisplayNameAnnotation", + "green": "Bool::DisplayNameAnnotation", + "red": "Bool::DisplayNameAnnotation" + }, + "DefaultResourceDirectories": { + "imageSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "interfaceSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "meshSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "scriptSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "shaderSubdirectory": "String::DisplayNameAnnotation::URIAnnotation" + }, + "LuaStandardModuleSelection": { + "base": "Bool::DisplayNameAnnotation", + "debug": "Bool::DisplayNameAnnotation", + "math": "Bool::DisplayNameAnnotation", + "string": "Bool::DisplayNameAnnotation", + "table": "Bool::DisplayNameAnnotation" + }, + "OrthographicFrustum": { + "bottomPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "farPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "leftPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "nearPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "rightPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "topPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation" + }, + "ScissorOptions": { + "scissorEnable": "Bool::DisplayNameAnnotation", + "scissorRegion": "CameraViewport::DisplayNameAnnotation" + }, + "StencilOptions": { + "stencilFunc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilMask": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "stencilOpDepthFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpDepthSucc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpStencilFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilRef": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "TimerInput": { + "ticker_us": "Int64::DisplayNameAnnotation::LinkEndAnnotation" + }, + "TimerOutput": { + "ticker_us": "Int64::DisplayNameAnnotation::LinkStartAnnotation" + }, + "Vec2f": { + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec2i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "Vec3f": { + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "z": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec3i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i3": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "Vec4f": { + "w": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "z": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec4i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i3": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i4": "Int::DisplayNameAnnotation::RangeAnnotationInt" + } + }, + "userTypePropMap": { + "AnchorPoint": { + "camera": "BaseCamera::DisplayNameAnnotation", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "node": "Node::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "AnchorPointOutputs::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Animation": { + "animationChannels": "Table::DisplayNameAnnotation", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "Table::DisplayNameAnnotation", + "progress": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "AnimationChannel": { + "animationIndex": "Int::DisplayNameAnnotation", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "samplerIndex": "Int::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "BlitPass": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "destinationX": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "destinationY": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "enabled": "Bool::DisplayNameAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderOrder": "Int::DisplayNameAnnotation", + "sourceRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "sourceRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "sourceX": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "sourceY": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "targetRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "targetRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" + }, + "CubeMap": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "generateMipmaps": "Bool::DisplayNameAnnotation", + "level2uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "LuaInterface": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "inputs": "Table::DisplayNameAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation::FeatureLevel", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation::FeatureLevel", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "LuaScript": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "inputs": "Table::DisplayNameAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "Table::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "LuaScriptModule": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Material": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "options": "BlendOptions::DisplayNameAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "uniforms": "Table::DisplayNameAnnotation", + "uriDefines": "String::URIAnnotation::DisplayNameAnnotation", + "uriFragment": "String::URIAnnotation::DisplayNameAnnotation", + "uriGeometry": "String::URIAnnotation::DisplayNameAnnotation", + "uriVertex": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Mesh": { + "bakeMeshes": "Bool::DisplayNameAnnotation", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "materialNames": "Table::ArraySemanticAnnotation::HiddenProperty", + "meshIndex": "Int::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "MeshNode": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "instanceCount": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "materials": "Table::DisplayNameAnnotation", + "mesh": "Mesh::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "Node": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "OrthographicCamera": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "frustum": "OrthographicFrustum::DisplayNameAnnotation::LinkEndAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "PerspectiveCamera": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "frustum": "Table::DisplayNameAnnotation::LinkEndAnnotation", + "frustumType": "Int::DisplayNameAnnotation::EnumerationAnnotation::FeatureLevel", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "Prefab": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "PrefabInstance": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "template": "Prefab::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "ProjectSettings": { + "backgroundColor": "Vec4f::DisplayNameAnnotation", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "defaultResourceFolders": "DefaultResourceDirectories::DisplayNameAnnotation", + "featureLevel": "Int::DisplayNameAnnotation::ReadOnlyAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "saveAsZip": "Bool::DisplayNameAnnotation", + "sceneId": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "Vec2i::DisplayNameAnnotation" + }, + "RenderBuffer": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "RenderBufferMS": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "sampleCount": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" + }, + "RenderLayer": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "materialFilterMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "materialFilterTags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderableTags": "Table::RenderableTagContainerAnnotation::DisplayNameAnnotation", + "sortOrder": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderPass": { + "camera": "BaseCamera::DisplayNameAnnotation", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "clearColor": "Vec4f::DisplayNameAnnotation::LinkEndAnnotation", + "enableClearColor": "Bool::DisplayNameAnnotation", + "enableClearDepth": "Bool::DisplayNameAnnotation", + "enableClearStencil": "Bool::DisplayNameAnnotation", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "layer0": "RenderLayer::DisplayNameAnnotation", + "layer1": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layer2": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layer3": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layer4": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layer5": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layer6": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layer7": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderOnce": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "renderOrder": "Int::DisplayNameAnnotation::LinkEndAnnotation", + "target": "RenderTarget::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderTarget": { + "buffer0": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer1": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer2": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer3": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer4": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer5": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer6": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer7": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS0": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS1": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS2": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS3": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS4": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS5": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS6": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS7": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Skin": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "joints": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "skinIndex": "Int::DisplayNameAnnotation", + "targets": "Table::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Texture": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "flipTexture": "Bool::DisplayNameAnnotation", + "generateMipmaps": "Bool::DisplayNameAnnotation", + "level2uri": "String::URIAnnotation::DisplayNameAnnotation", + "level3uri": "String::URIAnnotation::DisplayNameAnnotation", + "level4uri": "String::URIAnnotation::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "TextureExternal": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Timer": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "inputs": "TimerInput::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "TimerOutput::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + } + } +} diff --git a/datamodel/libCore/tests/migrationTestData/V54-rendertarget-extref.rca b/datamodel/libCore/tests/migrationTestData/V54-rendertarget-extref.rca new file mode 100644 index 00000000..c72fc5e0 --- /dev/null +++ b/datamodel/libCore/tests/migrationTestData/V54-rendertarget-extref.rca @@ -0,0 +1,1581 @@ +{ + "externalProjects": { + "23506439-27f1-4e29-8c49-ce748b82e2fa": { + "name": "rendertarget-base", + "path": "V54-rendertarget-base.rca" + } + }, + "featureLevel": 5, + "fileVersion": 54, + "instances": [ + { + "properties": { + "backgroundColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "defaultResourceFolders": { + "imageSubdirectory": "images", + "interfaceSubdirectory": "interfaces", + "meshSubdirectory": "meshes", + "scriptSubdirectory": "scripts", + "shaderSubdirectory": "shaders" + }, + "featureLevel": 5, + "objectID": "eac08457-ffc6-42d7-88a7-4e0ff1398ca0", + "objectName": "rendertarget-extref", + "saveAsZip": false, + "sceneId": { + "annotations": [ + { + "properties": { + "max": 1024, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 123 + }, + "viewport": { + "i1": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + } + } + }, + "typeName": "ProjectSettings" + }, + { + "properties": { + "children": { + "properties": [ + { + "typeName": "Ref", + "value": "31de91b9-0b1c-47a8-9d66-b943025b9cbc" + } + ] + }, + "enabled": true, + "objectID": "65ca4fe8-fcbb-4688-a650-6538e0c2ab06", + "objectName": "Node", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "tags": { + "properties": [ + { + "typeName": "String", + "value": "render_main" + } + ] + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "Node" + }, + { + "properties": { + "enabled": true, + "frustum": { + "order": [ + "nearPlane", + "farPlane", + "fieldOfView", + "aspectRatio" + ], + "properties": { + "aspectRatio": { + "annotations": [ + { + "properties": { + "name": "aspectRatio" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 4, + "min": 0.5 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 2 + }, + "farPlane": { + "annotations": [ + { + "properties": { + "name": "farPlane" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 10000, + "min": 100 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 1000 + }, + "fieldOfView": { + "annotations": [ + { + "properties": { + "name": "fieldOfView" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 120, + "min": 10 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 35 + }, + "nearPlane": { + "annotations": [ + { + "properties": { + "name": "nearPlane" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 1, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 0.1 + } + } + }, + "frustumType": 0, + "objectID": "01a5cfeb-9ee7-4779-a3de-920b6b9bd86a", + "objectName": "PerspectiveCamera", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 10 + } + }, + "viewport": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + }, + "visibility": true + }, + "typeName": "PerspectiveCamera" + }, + { + "properties": { + "camera": null, + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layer0": null, + "layer1": null, + "layer2": null, + "layer3": null, + "layer4": null, + "layer5": null, + "layer6": null, + "layer7": null, + "objectID": "2973cded-32ec-4c1c-850e-5563aa8eefcc", + "objectName": "rp-mixed", + "renderOnce": false, + "renderOrder": 1, + "target": "e6dd3803-b2aa-4978-a09a-b4abdb8558ef" + }, + "typeName": "RenderPass" + }, + { + "properties": { + "enabled": true, + "instanceCount": { + "annotations": [ + { + "properties": { + "max": 20, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "mesh": null, + "objectID": "31de91b9-0b1c-47a8-9d66-b943025b9cbc", + "objectName": "MeshNode", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "MeshNode" + }, + { + "properties": { + "camera": "01a5cfeb-9ee7-4779-a3de-920b6b9bd86a", + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layer0": "fde2cb09-6953-4157-a933-057dfd6b9279", + "layer1": null, + "layer2": null, + "layer3": null, + "layer4": null, + "layer5": null, + "layer6": null, + "layer7": null, + "objectID": "4db17c8b-c73e-47e4-9ec5-91200feb7aea", + "objectName": "MainRenderPass", + "renderOnce": false, + "renderOrder": 1, + "target": null + }, + "typeName": "RenderPass" + }, + { + "annotations": [ + { + "properties": { + "projectID": "23506439-27f1-4e29-8c49-ce748b82e2fa" + }, + "typeName": "ExternalReferenceAnnotation" + } + ], + "properties": { + "buffer0": null, + "buffer1": null, + "buffer2": null, + "buffer3": null, + "buffer4": null, + "buffer5": null, + "buffer6": null, + "buffer7": null, + "bufferMS0": null, + "bufferMS1": null, + "bufferMS2": null, + "bufferMS3": null, + "bufferMS4": null, + "bufferMS5": null, + "bufferMS6": null, + "bufferMS7": null, + "objectID": "4f4ec080-b8aa-4b84-96fa-eb04909289a4", + "objectName": "rt-normal", + "userTags": { + "properties": [ + { + "typeName": "String", + "value": "test" + } + ] + } + }, + "typeName": "RenderTarget" + }, + { + "annotations": [ + { + "properties": { + "projectID": "23506439-27f1-4e29-8c49-ce748b82e2fa" + }, + "typeName": "ExternalReferenceAnnotation" + } + ], + "properties": { + "buffer0": null, + "buffer1": null, + "buffer2": null, + "buffer3": null, + "buffer4": null, + "buffer5": null, + "buffer6": null, + "buffer7": null, + "bufferMS0": null, + "bufferMS1": null, + "bufferMS2": null, + "bufferMS3": null, + "bufferMS4": null, + "bufferMS5": null, + "bufferMS6": null, + "bufferMS7": null, + "objectID": "89bc24f1-2232-47f7-a8a7-4435e8a8d5f2", + "objectName": "rt-multi", + "userTags": { + "properties": [ + { + "typeName": "String", + "value": "test" + } + ] + } + }, + "typeName": "RenderTarget" + }, + { + "properties": { + "camera": null, + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layer0": null, + "layer1": null, + "layer2": null, + "layer3": null, + "layer4": null, + "layer5": null, + "layer6": null, + "layer7": null, + "objectID": "c6a20401-4c66-46b5-9e83-0423995269e4", + "objectName": "rp-multi", + "renderOnce": false, + "renderOrder": 1, + "target": "89bc24f1-2232-47f7-a8a7-4435e8a8d5f2" + }, + "typeName": "RenderPass" + }, + { + "annotations": [ + { + "properties": { + "projectID": "23506439-27f1-4e29-8c49-ce748b82e2fa" + }, + "typeName": "ExternalReferenceAnnotation" + } + ], + "properties": { + "buffer0": null, + "buffer1": null, + "buffer2": null, + "buffer3": null, + "buffer4": null, + "buffer5": null, + "buffer6": null, + "buffer7": null, + "bufferMS0": null, + "bufferMS1": null, + "bufferMS2": null, + "bufferMS3": null, + "bufferMS4": null, + "bufferMS5": null, + "bufferMS6": null, + "bufferMS7": null, + "objectID": "e6dd3803-b2aa-4978-a09a-b4abdb8558ef", + "objectName": "rt-mixed", + "userTags": { + "properties": [ + { + "typeName": "String", + "value": "test" + } + ] + } + }, + "typeName": "RenderTarget" + }, + { + "properties": { + "materialFilterMode": 1, + "objectID": "fde2cb09-6953-4157-a933-057dfd6b9279", + "objectName": "MainRenderLayer", + "renderableTags": { + "order": [ + "render_main" + ], + "properties": { + "render_main": { + "annotations": [ + { + "properties": { + "featureLevel": 3 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::LinkEndAnnotation", + "value": 0 + } + } + }, + "sortOrder": 0 + }, + "typeName": "RenderLayer" + }, + { + "properties": { + "camera": null, + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layer0": null, + "layer1": null, + "layer2": null, + "layer3": null, + "layer4": null, + "layer5": null, + "layer6": null, + "layer7": null, + "objectID": "fdf7c94c-c7d2-4972-981c-f329f80fca72", + "objectName": "rp-normal", + "renderOnce": false, + "renderOrder": 1, + "target": "4f4ec080-b8aa-4b84-96fa-eb04909289a4" + }, + "typeName": "RenderPass" + } + ], + "links": [ + ], + "logicEngineVersion": [ + 1, + 4, + 2 + ], + "racoVersion": [ + 1, + 10, + 0 + ], + "ramsesVersion": [ + 27, + 0, + 130 + ], + "structPropMap": { + "AnchorPointOutputs": { + "depth": "Double::DisplayNameAnnotation::LinkStartAnnotation", + "viewportCoords": "Vec2f::DisplayNameAnnotation::LinkStartAnnotation" + }, + "BlendOptions": { + "blendColor": "Vec4f::DisplayNameAnnotation", + "blendFactorDestAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorDestColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorSrcAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorSrcColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendOperationAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendOperationColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "colorWriteMask": "ColorWriteMask::DisplayNameAnnotation", + "cullmode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "depthFunction": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "depthwrite": "Bool::DisplayNameAnnotation", + "scissorOptions": "ScissorOptions::DisplayNameAnnotation", + "stencilOptions": "StencilOptions::DisplayNameAnnotation" + }, + "CameraViewport": { + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "offsetX": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "offsetY": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation" + }, + "ColorWriteMask": { + "alpha": "Bool::DisplayNameAnnotation", + "blue": "Bool::DisplayNameAnnotation", + "green": "Bool::DisplayNameAnnotation", + "red": "Bool::DisplayNameAnnotation" + }, + "DefaultResourceDirectories": { + "imageSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "interfaceSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "meshSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "scriptSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "shaderSubdirectory": "String::DisplayNameAnnotation::URIAnnotation" + }, + "LuaStandardModuleSelection": { + "base": "Bool::DisplayNameAnnotation", + "debug": "Bool::DisplayNameAnnotation", + "math": "Bool::DisplayNameAnnotation", + "string": "Bool::DisplayNameAnnotation", + "table": "Bool::DisplayNameAnnotation" + }, + "OrthographicFrustum": { + "bottomPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "farPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "leftPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "nearPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "rightPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "topPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation" + }, + "ScissorOptions": { + "scissorEnable": "Bool::DisplayNameAnnotation", + "scissorRegion": "CameraViewport::DisplayNameAnnotation" + }, + "StencilOptions": { + "stencilFunc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilMask": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "stencilOpDepthFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpDepthSucc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpStencilFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilRef": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "TimerInput": { + "ticker_us": "Int64::DisplayNameAnnotation::LinkEndAnnotation" + }, + "TimerOutput": { + "ticker_us": "Int64::DisplayNameAnnotation::LinkStartAnnotation" + }, + "Vec2f": { + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec2i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "Vec3f": { + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "z": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec3i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i3": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "Vec4f": { + "w": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "z": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec4i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i3": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i4": "Int::DisplayNameAnnotation::RangeAnnotationInt" + } + }, + "userTypePropMap": { + "AnchorPoint": { + "camera": "BaseCamera::DisplayNameAnnotation", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "node": "Node::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "AnchorPointOutputs::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Animation": { + "animationChannels": "Table::DisplayNameAnnotation", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "Table::DisplayNameAnnotation", + "progress": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "AnimationChannel": { + "animationIndex": "Int::DisplayNameAnnotation", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "samplerIndex": "Int::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "BlitPass": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "destinationX": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "destinationY": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "enabled": "Bool::DisplayNameAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderOrder": "Int::DisplayNameAnnotation", + "sourceRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "sourceRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "sourceX": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "sourceY": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "targetRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "targetRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" + }, + "CubeMap": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "generateMipmaps": "Bool::DisplayNameAnnotation", + "level2uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "LuaInterface": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "inputs": "Table::DisplayNameAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation::FeatureLevel", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation::FeatureLevel", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "LuaScript": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "inputs": "Table::DisplayNameAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "Table::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "LuaScriptModule": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Material": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "options": "BlendOptions::DisplayNameAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "uniforms": "Table::DisplayNameAnnotation", + "uriDefines": "String::URIAnnotation::DisplayNameAnnotation", + "uriFragment": "String::URIAnnotation::DisplayNameAnnotation", + "uriGeometry": "String::URIAnnotation::DisplayNameAnnotation", + "uriVertex": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Mesh": { + "bakeMeshes": "Bool::DisplayNameAnnotation", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "materialNames": "Table::ArraySemanticAnnotation::HiddenProperty", + "meshIndex": "Int::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "MeshNode": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "instanceCount": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "materials": "Table::DisplayNameAnnotation", + "mesh": "Mesh::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "Node": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "OrthographicCamera": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "frustum": "OrthographicFrustum::DisplayNameAnnotation::LinkEndAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "PerspectiveCamera": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "frustum": "Table::DisplayNameAnnotation::LinkEndAnnotation", + "frustumType": "Int::DisplayNameAnnotation::EnumerationAnnotation::FeatureLevel", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "Prefab": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "PrefabInstance": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "template": "Prefab::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "ProjectSettings": { + "backgroundColor": "Vec4f::DisplayNameAnnotation", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "defaultResourceFolders": "DefaultResourceDirectories::DisplayNameAnnotation", + "featureLevel": "Int::DisplayNameAnnotation::ReadOnlyAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "saveAsZip": "Bool::DisplayNameAnnotation", + "sceneId": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "Vec2i::DisplayNameAnnotation" + }, + "RenderBuffer": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "RenderBufferMS": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "sampleCount": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" + }, + "RenderLayer": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "materialFilterMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "materialFilterTags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderableTags": "Table::RenderableTagContainerAnnotation::DisplayNameAnnotation", + "sortOrder": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderPass": { + "camera": "BaseCamera::DisplayNameAnnotation", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "clearColor": "Vec4f::DisplayNameAnnotation::LinkEndAnnotation", + "enableClearColor": "Bool::DisplayNameAnnotation", + "enableClearDepth": "Bool::DisplayNameAnnotation", + "enableClearStencil": "Bool::DisplayNameAnnotation", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "layer0": "RenderLayer::DisplayNameAnnotation", + "layer1": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layer2": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layer3": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layer4": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layer5": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layer6": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layer7": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderOnce": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "renderOrder": "Int::DisplayNameAnnotation::LinkEndAnnotation", + "target": "RenderTarget::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderTarget": { + "buffer0": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer1": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer2": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer3": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer4": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer5": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer6": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer7": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS0": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS1": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS2": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS3": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS4": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS5": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS6": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS7": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Skin": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "joints": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "skinIndex": "Int::DisplayNameAnnotation", + "targets": "Table::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Texture": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "flipTexture": "Bool::DisplayNameAnnotation", + "generateMipmaps": "Bool::DisplayNameAnnotation", + "level2uri": "String::URIAnnotation::DisplayNameAnnotation", + "level3uri": "String::URIAnnotation::DisplayNameAnnotation", + "level4uri": "String::URIAnnotation::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "TextureExternal": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Timer": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "inputs": "TimerInput::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "TimerOutput::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + } + } +} diff --git a/datamodel/libCore/tests/migrationTestData/V54.rca b/datamodel/libCore/tests/migrationTestData/V54.rca new file mode 100644 index 00000000..8ce478c7 --- /dev/null +++ b/datamodel/libCore/tests/migrationTestData/V54.rca @@ -0,0 +1,1297 @@ +{ + "externalProjects": { + }, + "featureLevel": 4, + "fileVersion": 54, + "instances": [ + { + "properties": { + "backgroundColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "defaultResourceFolders": { + "imageSubdirectory": "images", + "interfaceSubdirectory": "interfaces", + "meshSubdirectory": "meshes", + "scriptSubdirectory": "scripts", + "shaderSubdirectory": "shaders" + }, + "featureLevel": 4, + "objectID": "f3fb6d33-bef3-4578-800d-b2e9b861aaa4", + "objectName": "V54", + "saveAsZip": false, + "sceneId": { + "annotations": [ + { + "properties": { + "max": 1024, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 123 + }, + "viewport": { + "i1": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + } + } + }, + "typeName": "ProjectSettings" + }, + { + "properties": { + "children": { + "properties": [ + { + "typeName": "Ref", + "value": "24f2e2df-cdea-43c9-aec3-fe2d2f03382d" + } + ] + }, + "enabled": true, + "objectID": "a330388c-b285-42df-b72f-86f452378efc", + "objectName": "Node", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "Node" + }, + { + "properties": { + "children": { + "properties": [ + { + "typeName": "Ref", + "value": "d641a032-27f1-4414-ab34-d351ccaaa597" + } + ] + }, + "objectID": "730a6c19-4d53-46f0-80fa-48d99734fbb7", + "objectName": "Prefab" + }, + "typeName": "Prefab" + }, + { + "properties": { + "animationChannels": { + "order": [ + "Channel 0", + "Channel 1", + "Channel 2", + "Channel 3", + "Channel 4", + "Channel 5", + "Channel 6", + "Channel 7" + ], + "properties": { + "Channel 0": { + "typeName": "AnimationChannel", + "value": "5bce0a0a-7064-4f76-980d-7bbc5e8df8b0" + }, + "Channel 1": { + "typeName": "AnimationChannel", + "value": null + }, + "Channel 2": { + "typeName": "AnimationChannel", + "value": null + }, + "Channel 3": { + "typeName": "AnimationChannel", + "value": null + }, + "Channel 4": { + "typeName": "AnimationChannel", + "value": null + }, + "Channel 5": { + "typeName": "AnimationChannel", + "value": null + }, + "Channel 6": { + "typeName": "AnimationChannel", + "value": null + }, + "Channel 7": { + "typeName": "AnimationChannel", + "value": null + } + } + }, + "objectID": "aa9bb6a4-b84d-4cd8-9372-eae344d93d21", + "objectName": "Animation", + "progress": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Animation" + }, + { + "properties": { + "objectID": "e203e0f9-b78c-40d3-bc6d-85e0d33688df", + "objectName": "Skin", + "skinIndex": 0, + "targets": { + "order": [ + "target_0" + ], + "properties": { + "target_0": { + "typeName": "MeshNode", + "value": "24f2e2df-cdea-43c9-aec3-fe2d2f03382d" + } + } + }, + "uri": "" + }, + "typeName": "Skin" + }, + { + "properties": { + "format": 4, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "objectID": "0808588c-0aad-42ed-bff7-5e2c2444f32b", + "objectName": "RenderBufferMS", + "sampleCount": { + "annotations": [ + { + "properties": { + "max": 8, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + } + }, + "typeName": "RenderBufferMS" + }, + { + "properties": { + "enabled": true, + "instanceCount": { + "annotations": [ + { + "properties": { + "max": 20, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "mesh": null, + "objectID": "24f2e2df-cdea-43c9-aec3-fe2d2f03382d", + "objectName": "MeshNode", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "MeshNode" + }, + { + "properties": { + "camera": null, + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layer0": "b25bb2d1-af54-4a03-a916-1db454f69f2f", + "layer1": null, + "layer2": null, + "layer3": null, + "layer4": null, + "layer5": null, + "layer6": null, + "layer7": null, + "objectID": "57b301f0-02a3-496e-939f-b8c850deccc0", + "objectName": "MainRenderPass", + "renderOnce": false, + "renderOrder": 1, + "target": null + }, + "typeName": "RenderPass" + }, + { + "properties": { + "animationIndex": 0, + "objectID": "5bce0a0a-7064-4f76-980d-7bbc5e8df8b0", + "objectName": "AnimationChannel", + "samplerIndex": 0, + "uri": "" + }, + "typeName": "AnimationChannel" + }, + { + "properties": { + "anisotropy": { + "annotations": [ + { + "properties": { + "max": 32000, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "format": 4, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "magSamplingMethod": 0, + "minSamplingMethod": 0, + "objectID": "6b168cc5-4194-44ba-94ad-1eb1ea5df1a5", + "objectName": "RenderBuffer", + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "wrapUMode": 0, + "wrapVMode": 0 + }, + "typeName": "RenderBuffer" + }, + { + "properties": { + "buffer0": "6b168cc5-4194-44ba-94ad-1eb1ea5df1a5", + "buffer1": null, + "buffer2": null, + "buffer3": null, + "buffer4": null, + "buffer5": null, + "buffer6": null, + "buffer7": null, + "bufferMS0": "0808588c-0aad-42ed-bff7-5e2c2444f32b", + "bufferMS1": null, + "bufferMS2": null, + "bufferMS3": null, + "bufferMS4": null, + "bufferMS5": null, + "bufferMS6": null, + "bufferMS7": null, + "objectID": "70891db2-0107-4811-a504-39263c5a59b8", + "objectName": "RenderTarget" + }, + "typeName": "RenderTarget" + }, + { + "properties": { + "materialFilterMode": 1, + "objectID": "b25bb2d1-af54-4a03-a916-1db454f69f2f", + "objectName": "MainRenderLayer", + "renderableTags": { + "order": [ + "render_main" + ], + "properties": { + "render_main": { + "annotations": [ + { + "properties": { + "featureLevel": 3 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::LinkEndAnnotation", + "value": 0 + } + } + }, + "sortOrder": 0 + }, + "typeName": "RenderLayer" + }, + { + "properties": { + "enabled": true, + "objectID": "d641a032-27f1-4414-ab34-d351ccaaa597", + "objectName": "NodePrefab", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "Node" + } + ], + "links": [ + ], + "logicEngineVersion": [ + 1, + 4, + 2 + ], + "racoVersion": [ + 1, + 9, + 1 + ], + "ramsesVersion": [ + 27, + 0, + 130 + ], + "structPropMap": { + "AnchorPointOutputs": { + "depth": "Double::DisplayNameAnnotation::LinkStartAnnotation", + "viewportCoords": "Vec2f::DisplayNameAnnotation::LinkStartAnnotation" + }, + "BlendOptions": { + "blendColor": "Vec4f::DisplayNameAnnotation", + "blendFactorDestAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorDestColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorSrcAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorSrcColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendOperationAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendOperationColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "colorWriteMask": "ColorWriteMask::DisplayNameAnnotation", + "cullmode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "depthFunction": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "depthwrite": "Bool::DisplayNameAnnotation", + "scissorOptions": "ScissorOptions::DisplayNameAnnotation", + "stencilOptions": "StencilOptions::DisplayNameAnnotation" + }, + "CameraViewport": { + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "offsetX": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "offsetY": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation" + }, + "ColorWriteMask": { + "alpha": "Bool::DisplayNameAnnotation", + "blue": "Bool::DisplayNameAnnotation", + "green": "Bool::DisplayNameAnnotation", + "red": "Bool::DisplayNameAnnotation" + }, + "DefaultResourceDirectories": { + "imageSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "interfaceSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "meshSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "scriptSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "shaderSubdirectory": "String::DisplayNameAnnotation::URIAnnotation" + }, + "LuaStandardModuleSelection": { + "base": "Bool::DisplayNameAnnotation", + "debug": "Bool::DisplayNameAnnotation", + "math": "Bool::DisplayNameAnnotation", + "string": "Bool::DisplayNameAnnotation", + "table": "Bool::DisplayNameAnnotation" + }, + "OrthographicFrustum": { + "bottomPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "farPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "leftPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "nearPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "rightPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "topPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation" + }, + "ScissorOptions": { + "scissorEnable": "Bool::DisplayNameAnnotation", + "scissorRegion": "CameraViewport::DisplayNameAnnotation" + }, + "StencilOptions": { + "stencilFunc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilMask": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "stencilOpDepthFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpDepthSucc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpStencilFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilRef": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "TimerInput": { + "ticker_us": "Int64::DisplayNameAnnotation::LinkEndAnnotation" + }, + "TimerOutput": { + "ticker_us": "Int64::DisplayNameAnnotation::LinkStartAnnotation" + }, + "Vec2f": { + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec2i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "Vec3f": { + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "z": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec3i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i3": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "Vec4f": { + "w": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "z": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec4i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i3": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i4": "Int::DisplayNameAnnotation::RangeAnnotationInt" + } + }, + "userTypePropMap": { + "AnchorPoint": { + "camera": "BaseCamera::DisplayNameAnnotation", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "node": "Node::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "AnchorPointOutputs::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Animation": { + "animationChannels": "Table::DisplayNameAnnotation", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "Table::DisplayNameAnnotation", + "progress": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "AnimationChannel": { + "animationIndex": "Int::DisplayNameAnnotation", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "samplerIndex": "Int::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "BlitPass": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "destinationX": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "destinationY": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "enabled": "Bool::DisplayNameAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderOrder": "Int::DisplayNameAnnotation", + "sourceRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "sourceRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "sourceX": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "sourceY": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "targetRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "targetRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" + }, + "CubeMap": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "generateMipmaps": "Bool::DisplayNameAnnotation", + "level2uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "LuaInterface": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "inputs": "Table::DisplayNameAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation::FeatureLevel", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation::FeatureLevel", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "LuaScript": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "inputs": "Table::DisplayNameAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "Table::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "LuaScriptModule": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Material": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "options": "BlendOptions::DisplayNameAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "uniforms": "Table::DisplayNameAnnotation", + "uriDefines": "String::URIAnnotation::DisplayNameAnnotation", + "uriFragment": "String::URIAnnotation::DisplayNameAnnotation", + "uriGeometry": "String::URIAnnotation::DisplayNameAnnotation", + "uriVertex": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Mesh": { + "bakeMeshes": "Bool::DisplayNameAnnotation", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "materialNames": "Table::ArraySemanticAnnotation::HiddenProperty", + "meshIndex": "Int::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "MeshNode": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "instanceCount": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "materials": "Table::DisplayNameAnnotation", + "mesh": "Mesh::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "Node": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "OrthographicCamera": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "frustum": "OrthographicFrustum::DisplayNameAnnotation::LinkEndAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "PerspectiveCamera": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "frustum": "Table::DisplayNameAnnotation::LinkEndAnnotation", + "frustumType": "Int::DisplayNameAnnotation::EnumerationAnnotation::FeatureLevel", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "Prefab": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "PrefabInstance": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "template": "Prefab::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "ProjectSettings": { + "backgroundColor": "Vec4f::DisplayNameAnnotation", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "defaultResourceFolders": "DefaultResourceDirectories::DisplayNameAnnotation", + "featureLevel": "Int::DisplayNameAnnotation::ReadOnlyAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "saveAsZip": "Bool::DisplayNameAnnotation", + "sceneId": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "Vec2i::DisplayNameAnnotation" + }, + "RenderBuffer": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "RenderBufferMS": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "sampleCount": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" + }, + "RenderLayer": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "materialFilterMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "materialFilterTags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderableTags": "Table::RenderableTagContainerAnnotation::DisplayNameAnnotation", + "sortOrder": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderPass": { + "camera": "BaseCamera::DisplayNameAnnotation", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "clearColor": "Vec4f::DisplayNameAnnotation::LinkEndAnnotation", + "enableClearColor": "Bool::DisplayNameAnnotation", + "enableClearDepth": "Bool::DisplayNameAnnotation", + "enableClearStencil": "Bool::DisplayNameAnnotation", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "layer0": "RenderLayer::DisplayNameAnnotation", + "layer1": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layer2": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layer3": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layer4": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layer5": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layer6": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layer7": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderOnce": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "renderOrder": "Int::DisplayNameAnnotation::LinkEndAnnotation", + "target": "RenderTarget::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderTarget": { + "buffer0": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer1": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer2": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer3": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer4": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer5": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer6": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffer7": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS0": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS1": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS2": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS3": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS4": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS5": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS6": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "bufferMS7": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Skin": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "joints": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "skinIndex": "Int::DisplayNameAnnotation", + "targets": "Table::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Texture": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "flipTexture": "Bool::DisplayNameAnnotation", + "generateMipmaps": "Bool::DisplayNameAnnotation", + "level2uri": "String::URIAnnotation::DisplayNameAnnotation", + "level3uri": "String::URIAnnotation::DisplayNameAnnotation", + "level4uri": "String::URIAnnotation::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "TextureExternal": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Timer": { + "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "inputs": "TimerInput::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "TimerOutput::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + } + } +} diff --git a/datamodel/libCore/tests/migrationTestData/V55.rca b/datamodel/libCore/tests/migrationTestData/V55.rca new file mode 100644 index 00000000..211ce833 --- /dev/null +++ b/datamodel/libCore/tests/migrationTestData/V55.rca @@ -0,0 +1,1061 @@ +{ + "externalProjects": { + }, + "featureLevel": 4, + "fileVersion": 55, + "instances": [ + { + "properties": { + "backgroundColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "defaultResourceFolders": { + "imageSubdirectory": "images", + "interfaceSubdirectory": "interfaces", + "meshSubdirectory": "meshes", + "scriptSubdirectory": "scripts", + "shaderSubdirectory": "shaders" + }, + "featureLevel": 4, + "objectID": "f3fb6d33-bef3-4578-800d-b2e9b861aaa4", + "objectName": "V54", + "saveAsZip": false, + "sceneId": { + "annotations": [ + { + "properties": { + "max": 1024, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 123 + }, + "viewport": { + "i1": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + } + } + }, + "typeName": "ProjectSettings" + }, + { + "properties": { + "buffers": [ + null, + null, + null, + null, + null, + null, + null, + null + ], + "buffersMS": [ + "0808588c-0aad-42ed-bff7-5e2c2444f32b", + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "06f0f063-2903-4032-b187-c41e8202514f", + "objectName": "RenderTarget_MS", + "userTags": { + "properties": [ + { + "typeName": "String", + "value": "cat" + }, + { + "typeName": "String", + "value": "dog" + } + ] + } + }, + "typeName": "RenderTarget" + }, + { + "properties": { + "format": 4, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "objectID": "0808588c-0aad-42ed-bff7-5e2c2444f32b", + "objectName": "RenderBufferMS", + "sampleCount": { + "annotations": [ + { + "properties": { + "max": 8, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + } + }, + "typeName": "RenderBufferMS" + }, + { + "properties": { + "buffers": [ + "6b168cc5-4194-44ba-94ad-1eb1ea5df1a5", + null, + null, + null, + null, + null, + null, + null + ], + "buffersMS": [ + null, + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "18b16697-e860-45ef-89a7-fee8fa285986", + "objectName": "RenderTarget", + "userTags": { + "properties": [ + { + "typeName": "String", + "value": "cat" + } + ] + } + }, + "typeName": "RenderTarget" + }, + { + "properties": { + "camera": null, + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layers": [ + null, + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "47d43f90-30b2-4f63-90d9-7d1cf610e80e", + "objectName": "RenderPass_mixed", + "renderOnce": false, + "renderOrder": 4, + "target": "70891db2-0107-4811-a504-39263c5a59b8" + }, + "typeName": "RenderPass" + }, + { + "properties": { + "camera": null, + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layers": [ + null, + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "4ba3d10f-8031-4e5a-b156-070cea767c56", + "objectName": "RenderPass_MS", + "renderOnce": false, + "renderOrder": 3, + "target": "06f0f063-2903-4032-b187-c41e8202514f" + }, + "typeName": "RenderPass" + }, + { + "properties": { + "camera": null, + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layers": [ + null, + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "57b301f0-02a3-496e-939f-b8c850deccc0", + "objectName": "MainRenderPass", + "renderOnce": false, + "renderOrder": 1, + "target": null + }, + "typeName": "RenderPass" + }, + { + "properties": { + "camera": null, + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layers": [ + null, + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "5ffafab9-5227-422c-875c-215933699718", + "objectName": "RenderPass", + "renderOnce": false, + "renderOrder": 2, + "target": "18b16697-e860-45ef-89a7-fee8fa285986" + }, + "typeName": "RenderPass" + }, + { + "properties": { + "anisotropy": { + "annotations": [ + { + "properties": { + "max": 32000, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "format": 4, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "magSamplingMethod": 0, + "minSamplingMethod": 0, + "objectID": "6b168cc5-4194-44ba-94ad-1eb1ea5df1a5", + "objectName": "RenderBuffer", + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "wrapUMode": 0, + "wrapVMode": 0 + }, + "typeName": "RenderBuffer" + }, + { + "properties": { + "buffers": [ + "6b168cc5-4194-44ba-94ad-1eb1ea5df1a5", + null, + null, + null, + null, + null, + null, + null + ], + "buffersMS": [ + "0808588c-0aad-42ed-bff7-5e2c2444f32b", + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "70891db2-0107-4811-a504-39263c5a59b8", + "objectName": "RenderTarget_mixed", + "userTags": { + "properties": [ + { + "typeName": "String", + "value": "dog" + } + ] + } + }, + "typeName": "RenderTarget" + } + ], + "links": [ + ], + "logicEngineVersion": [ + 1, + 4, + 2 + ], + "racoVersion": [ + 1, + 10, + 0 + ], + "ramsesVersion": [ + 27, + 0, + 130 + ], + "structPropMap": { + "AnchorPointOutputs": { + "depth": "Double::DisplayNameAnnotation::LinkStartAnnotation", + "viewportCoords": "Vec2f::DisplayNameAnnotation::LinkStartAnnotation" + }, + "BlendOptions": { + "blendColor": "Vec4f::DisplayNameAnnotation", + "blendFactorDestAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorDestColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorSrcAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorSrcColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendOperationAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendOperationColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "colorWriteMask": "ColorWriteMask::DisplayNameAnnotation", + "cullmode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "depthFunction": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "depthwrite": "Bool::DisplayNameAnnotation", + "scissorOptions": "ScissorOptions::DisplayNameAnnotation", + "stencilOptions": "StencilOptions::DisplayNameAnnotation" + }, + "CameraViewport": { + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "offsetX": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "offsetY": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation" + }, + "ColorWriteMask": { + "alpha": "Bool::DisplayNameAnnotation", + "blue": "Bool::DisplayNameAnnotation", + "green": "Bool::DisplayNameAnnotation", + "red": "Bool::DisplayNameAnnotation" + }, + "DefaultResourceDirectories": { + "imageSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "interfaceSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "meshSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "scriptSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "shaderSubdirectory": "String::DisplayNameAnnotation::URIAnnotation" + }, + "LuaStandardModuleSelection": { + "base": "Bool::DisplayNameAnnotation", + "debug": "Bool::DisplayNameAnnotation", + "math": "Bool::DisplayNameAnnotation", + "string": "Bool::DisplayNameAnnotation", + "table": "Bool::DisplayNameAnnotation" + }, + "OrthographicFrustum": { + "bottomPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "farPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "leftPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "nearPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "rightPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "topPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation" + }, + "ScissorOptions": { + "scissorEnable": "Bool::DisplayNameAnnotation", + "scissorRegion": "CameraViewport::DisplayNameAnnotation" + }, + "StencilOptions": { + "stencilFunc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilMask": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "stencilOpDepthFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpDepthSucc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpStencilFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilRef": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "TimerInput": { + "ticker_us": "Int64::DisplayNameAnnotation::LinkEndAnnotation" + }, + "TimerOutput": { + "ticker_us": "Int64::DisplayNameAnnotation::LinkStartAnnotation" + }, + "Vec2f": { + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec2i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "Vec3f": { + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "z": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec3i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i3": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "Vec4f": { + "w": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "z": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec4i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i3": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i4": "Int::DisplayNameAnnotation::RangeAnnotationInt" + } + }, + "userTypePropMap": { + "AnchorPoint": { + "camera": "BaseCamera::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "node": "Node::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "AnchorPointOutputs::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Animation": { + "animationChannels": "Array[AnimationChannel]::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "Table::DisplayNameAnnotation", + "progress": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "AnimationChannel": { + "animationIndex": "Int::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "samplerIndex": "Int::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "BlitPass": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "destinationX": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "destinationY": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "enabled": "Bool::DisplayNameAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderOrder": "Int::DisplayNameAnnotation", + "sourceRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "sourceRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "sourceX": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "sourceY": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "targetRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "targetRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" + }, + "CubeMap": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "generateMipmaps": "Bool::DisplayNameAnnotation", + "level2uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "LuaInterface": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "inputs": "Table::DisplayNameAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation::FeatureLevel", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation::FeatureLevel", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "LuaScript": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "inputs": "Table::DisplayNameAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "Table::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "LuaScriptModule": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Material": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "options": "BlendOptions::DisplayNameAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "uniforms": "Table::DisplayNameAnnotation", + "uriDefines": "String::URIAnnotation::DisplayNameAnnotation", + "uriFragment": "String::URIAnnotation::DisplayNameAnnotation", + "uriGeometry": "String::URIAnnotation::DisplayNameAnnotation", + "uriVertex": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Mesh": { + "bakeMeshes": "Bool::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "materialNames": "Table::ArraySemanticAnnotation::HiddenProperty", + "meshIndex": "Int::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "MeshNode": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "instanceCount": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "materials": "Table::DisplayNameAnnotation", + "mesh": "Mesh::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "Node": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "OrthographicCamera": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "frustum": "OrthographicFrustum::DisplayNameAnnotation::LinkEndAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "PerspectiveCamera": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "frustum": "Table::DisplayNameAnnotation::LinkEndAnnotation", + "frustumType": "Int::DisplayNameAnnotation::EnumerationAnnotation::FeatureLevel", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "Prefab": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "PrefabInstance": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "template": "Prefab::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "ProjectSettings": { + "backgroundColor": "Vec4f::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "defaultResourceFolders": "DefaultResourceDirectories::DisplayNameAnnotation", + "featureLevel": "Int::DisplayNameAnnotation::ReadOnlyAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "saveAsZip": "Bool::DisplayNameAnnotation", + "sceneId": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "Vec2i::DisplayNameAnnotation" + }, + "RenderBuffer": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "RenderBufferMS": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "sampleCount": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" + }, + "RenderLayer": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "materialFilterMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "materialFilterTags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderableTags": "Table::RenderableTagContainerAnnotation::DisplayNameAnnotation", + "sortOrder": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderPass": { + "camera": "BaseCamera::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "clearColor": "Vec4f::DisplayNameAnnotation::LinkEndAnnotation", + "enableClearColor": "Bool::DisplayNameAnnotation", + "enableClearDepth": "Bool::DisplayNameAnnotation", + "enableClearStencil": "Bool::DisplayNameAnnotation", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "layers": "Array[RenderLayer]::DisplayNameAnnotation::EmptyReferenceAllowable", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderOnce": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "renderOrder": "Int::DisplayNameAnnotation::LinkEndAnnotation", + "target": "RenderTarget::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderTarget": { + "buffers": "Array[RenderBuffer]::DisplayNameAnnotation::EmptyReferenceAllowable", + "buffersMS": "Array[RenderBufferMS]::DisplayNameAnnotation::EmptyReferenceAllowable", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Skin": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "joints": "Array[Node]::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "skinIndex": "Int::DisplayNameAnnotation", + "targets": "Array[MeshNode]::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Texture": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "flipTexture": "Bool::DisplayNameAnnotation", + "generateMipmaps": "Bool::DisplayNameAnnotation", + "level2uri": "String::URIAnnotation::DisplayNameAnnotation", + "level3uri": "String::URIAnnotation::DisplayNameAnnotation", + "level4uri": "String::URIAnnotation::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "TextureExternal": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Timer": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "inputs": "TimerInput::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "TimerOutput::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + } + } +} diff --git a/datamodel/libCore/tests/migrationTestData/V57.rca b/datamodel/libCore/tests/migrationTestData/V57.rca new file mode 100644 index 00000000..094d8d67 --- /dev/null +++ b/datamodel/libCore/tests/migrationTestData/V57.rca @@ -0,0 +1,750 @@ +{ + "externalProjects": { + }, + "featureLevel": 4, + "fileVersion": 57, + "instances": [ + { + "properties": { + "backgroundColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "defaultResourceFolders": { + "imageSubdirectory": "images", + "interfaceSubdirectory": "interfaces", + "meshSubdirectory": "meshes", + "scriptSubdirectory": "scripts", + "shaderSubdirectory": "shaders" + }, + "featureLevel": 4, + "objectID": "f3fb6d33-bef3-4578-800d-b2e9b861aaa4", + "objectName": "V57", + "saveAsZip": false, + "sceneId": { + "annotations": [ + { + "properties": { + "max": 1024, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 123 + }, + "userTags": { + "properties": [ + { + "typeName": "String", + "value": "cat" + } + ] + }, + "viewport": { + "i1": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + } + } + }, + "typeName": "ProjectSettings" + }, + { + "properties": { + "enabled": true, + "objectID": "3652b4e7-3a86-4bbb-935d-600170d5abf5", + "objectName": "Node", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "userTags": { + "properties": [ + { + "typeName": "String", + "value": "dog" + } + ] + }, + "visibility": true + }, + "typeName": "Node" + }, + { + "properties": { + "objectID": "a920ad68-5c76-4be4-99da-625d5fd0194a", + "objectName": "Prefab", + "userTags": { + "properties": [ + { + "typeName": "String", + "value": "cat" + }, + { + "typeName": "String", + "value": "dog" + } + ] + } + }, + "typeName": "Prefab" + } + ], + "links": [ + ], + "logicEngineVersion": [ + 1, + 4, + 2 + ], + "racoVersion": [ + 1, + 10, + 0 + ], + "ramsesVersion": [ + 27, + 0, + 130 + ], + "structPropMap": { + "AnchorPointOutputs": { + "depth": "Double::DisplayNameAnnotation::LinkStartAnnotation", + "viewportCoords": "Vec2f::DisplayNameAnnotation::LinkStartAnnotation" + }, + "BlendOptions": { + "blendColor": "Vec4f::DisplayNameAnnotation", + "blendFactorDestAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorDestColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorSrcAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorSrcColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendOperationAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendOperationColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "colorWriteMask": "ColorWriteMask::DisplayNameAnnotation", + "cullmode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "depthFunction": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "depthwrite": "Bool::DisplayNameAnnotation", + "scissorOptions": "ScissorOptions::DisplayNameAnnotation", + "stencilOptions": "StencilOptions::DisplayNameAnnotation" + }, + "CameraViewport": { + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "offsetX": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "offsetY": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation" + }, + "ColorWriteMask": { + "alpha": "Bool::DisplayNameAnnotation", + "blue": "Bool::DisplayNameAnnotation", + "green": "Bool::DisplayNameAnnotation", + "red": "Bool::DisplayNameAnnotation" + }, + "DefaultResourceDirectories": { + "imageSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "interfaceSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "meshSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "scriptSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "shaderSubdirectory": "String::DisplayNameAnnotation::URIAnnotation" + }, + "LuaStandardModuleSelection": { + "base": "Bool::DisplayNameAnnotation", + "debug": "Bool::DisplayNameAnnotation", + "math": "Bool::DisplayNameAnnotation", + "string": "Bool::DisplayNameAnnotation", + "table": "Bool::DisplayNameAnnotation" + }, + "OrthographicFrustum": { + "bottomPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "farPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "leftPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "nearPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "rightPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "topPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation" + }, + "ScissorOptions": { + "scissorEnable": "Bool::DisplayNameAnnotation", + "scissorRegion": "CameraViewport::DisplayNameAnnotation" + }, + "StencilOptions": { + "stencilFunc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilMask": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "stencilOpDepthFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpDepthSucc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpStencilFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilRef": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "TimerInput": { + "ticker_us": "Int64::DisplayNameAnnotation::LinkEndAnnotation" + }, + "TimerOutput": { + "ticker_us": "Int64::DisplayNameAnnotation::LinkStartAnnotation" + }, + "Vec2f": { + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec2i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "Vec3f": { + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "z": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec3i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i3": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "Vec4f": { + "w": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "z": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec4i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i3": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i4": "Int::DisplayNameAnnotation::RangeAnnotationInt" + } + }, + "userTypePropMap": { + "AnchorPoint": { + "camera": "BaseCamera::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "node": "Node::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "AnchorPointOutputs::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Animation": { + "animationChannels": "Array[AnimationChannel]::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "Table::DisplayNameAnnotation", + "progress": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "AnimationChannel": { + "animationIndex": "Int::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "samplerIndex": "Int::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "BlitPass": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "destinationX": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "destinationY": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "enabled": "Bool::DisplayNameAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderOrder": "Int::DisplayNameAnnotation", + "sourceRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "sourceRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "sourceX": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "sourceY": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "targetRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "targetRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" + }, + "CubeMap": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "generateMipmaps": "Bool::DisplayNameAnnotation", + "level2uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "LuaInterface": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "inputs": "Table::DisplayNameAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation::FeatureLevel", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation::FeatureLevel", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "LuaScript": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "inputs": "Table::DisplayNameAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "Table::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "LuaScriptModule": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Material": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "options": "BlendOptions::DisplayNameAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "uniforms": "Table::DisplayNameAnnotation", + "uriDefines": "String::URIAnnotation::DisplayNameAnnotation", + "uriFragment": "String::URIAnnotation::DisplayNameAnnotation", + "uriGeometry": "String::URIAnnotation::DisplayNameAnnotation", + "uriVertex": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Mesh": { + "bakeMeshes": "Bool::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "materialNames": "Table::ArraySemanticAnnotation::HiddenProperty", + "meshIndex": "Int::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "MeshNode": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "instanceCount": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "materials": "Table::DisplayNameAnnotation", + "mesh": "Mesh::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "Node": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "OrthographicCamera": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "frustum": "OrthographicFrustum::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "PerspectiveCamera": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "frustum": "Table::DisplayNameAnnotation::LinkEndAnnotation", + "frustumType": "Int::DisplayNameAnnotation::EnumerationAnnotation::FeatureLevel", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "Prefab": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "PrefabInstance": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "template": "Prefab::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "ProjectSettings": { + "backgroundColor": "Vec4f::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "defaultResourceFolders": "DefaultResourceDirectories::DisplayNameAnnotation", + "featureLevel": "Int::DisplayNameAnnotation::ReadOnlyAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "saveAsZip": "Bool::DisplayNameAnnotation", + "sceneId": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "Vec2i::DisplayNameAnnotation" + }, + "RenderBuffer": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "RenderBufferMS": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "sampleCount": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" + }, + "RenderLayer": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "materialFilterMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "materialFilterTags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderableTags": "Table::RenderableTagContainerAnnotation::DisplayNameAnnotation", + "sortOrder": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderPass": { + "camera": "BaseCamera::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "clearColor": "Vec4f::DisplayNameAnnotation::LinkEndAnnotation", + "enableClearColor": "Bool::DisplayNameAnnotation", + "enableClearDepth": "Bool::DisplayNameAnnotation", + "enableClearStencil": "Bool::DisplayNameAnnotation", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "layers": "Array[RenderLayer]::DisplayNameAnnotation::EmptyReferenceAllowable", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderOnce": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "renderOrder": "Int::DisplayNameAnnotation::LinkEndAnnotation", + "target": "RenderTargetBase::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderTarget": { + "buffers": "Array[RenderBuffer]::DisplayNameAnnotation::EmptyReferenceAllowable", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderTargetMS": { + "buffers": "Array[RenderBufferMS]::DisplayNameAnnotation::EmptyReferenceAllowable", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Skin": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "joints": "Array[Node]::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "skinIndex": "Int::DisplayNameAnnotation", + "targets": "Array[MeshNode]::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Texture": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "flipTexture": "Bool::DisplayNameAnnotation", + "generateMipmaps": "Bool::DisplayNameAnnotation", + "level2uri": "String::URIAnnotation::DisplayNameAnnotation", + "level3uri": "String::URIAnnotation::DisplayNameAnnotation", + "level4uri": "String::URIAnnotation::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "TextureExternal": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Timer": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "inputs": "TimerInput::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "TimerOutput::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + } + } +} diff --git a/datamodel/libCore/tests/migrationTestData/V58.rca b/datamodel/libCore/tests/migrationTestData/V58.rca new file mode 100644 index 00000000..73f2a85a --- /dev/null +++ b/datamodel/libCore/tests/migrationTestData/V58.rca @@ -0,0 +1,1266 @@ +{ + "externalProjects": { + }, + "featureLevel": 5, + "fileVersion": 58, + "instances": [ + { + "properties": { + "backgroundColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "defaultResourceFolders": { + "imageSubdirectory": "images", + "interfaceSubdirectory": "interfaces", + "meshSubdirectory": "meshes", + "scriptSubdirectory": "scripts", + "shaderSubdirectory": "shaders" + }, + "featureLevel": 5, + "objectID": "f3fb6d33-bef3-4578-800d-b2e9b861aaa4", + "objectName": "V54", + "saveAsZip": false, + "sceneId": { + "annotations": [ + { + "properties": { + "max": 1024, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 123 + }, + "viewport": { + "i1": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + } + } + }, + "typeName": "ProjectSettings" + }, + { + "properties": { + "children": [ + "24f2e2df-cdea-43c9-aec3-fe2d2f03382d" + ], + "enabled": true, + "objectID": "a330388c-b285-42df-b72f-86f452378efc", + "objectName": "Node", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "Node" + }, + { + "properties": { + "children": [ + "d641a032-27f1-4414-ab34-d351ccaaa597" + ], + "objectID": "730a6c19-4d53-46f0-80fa-48d99734fbb7", + "objectName": "Prefab" + }, + "typeName": "Prefab" + }, + { + "properties": { + "animationChannels": [ + "5bce0a0a-7064-4f76-980d-7bbc5e8df8b0", + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "aa9bb6a4-b84d-4cd8-9372-eae344d93d21", + "objectName": "Animation", + "progress": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Animation" + }, + { + "properties": { + "objectID": "e203e0f9-b78c-40d3-bc6d-85e0d33688df", + "objectName": "Skin", + "skinIndex": 0, + "targets": [ + "24f2e2df-cdea-43c9-aec3-fe2d2f03382d" + ], + "uri": "" + }, + "typeName": "Skin" + }, + { + "properties": { + "format": 4, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "objectID": "0808588c-0aad-42ed-bff7-5e2c2444f32b", + "objectName": "RenderBufferMS", + "sampleCount": { + "annotations": [ + { + "properties": { + "max": 8, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + } + }, + "typeName": "RenderBufferMS" + }, + { + "properties": { + "enabled": true, + "instanceCount": { + "annotations": [ + { + "properties": { + "max": 20, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "mesh": null, + "objectID": "24f2e2df-cdea-43c9-aec3-fe2d2f03382d", + "objectName": "MeshNode", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "MeshNode" + }, + { + "properties": { + "camera": null, + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layers": [ + "b25bb2d1-af54-4a03-a916-1db454f69f2f", + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "57b301f0-02a3-496e-939f-b8c850deccc0", + "objectName": "MainRenderPass", + "renderOnce": false, + "renderOrder": 1, + "target": null + }, + "typeName": "RenderPass" + }, + { + "properties": { + "animationIndex": 0, + "objectID": "5bce0a0a-7064-4f76-980d-7bbc5e8df8b0", + "objectName": "AnimationChannel", + "samplerIndex": 0, + "uri": "" + }, + "typeName": "AnimationChannel" + }, + { + "properties": { + "anisotropy": { + "annotations": [ + { + "properties": { + "max": 32000, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "format": 4, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "magSamplingMethod": 0, + "minSamplingMethod": 0, + "objectID": "6b168cc5-4194-44ba-94ad-1eb1ea5df1a5", + "objectName": "RenderBuffer", + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "wrapUMode": 0, + "wrapVMode": 0 + }, + "typeName": "RenderBuffer" + }, + { + "properties": { + "buffers": [ + "6b168cc5-4194-44ba-94ad-1eb1ea5df1a5", + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "70891db2-0107-4811-a504-39263c5a59b8", + "objectName": "RenderTarget" + }, + "typeName": "RenderTarget" + }, + { + "properties": { + "materialFilterMode": 1, + "objectID": "b25bb2d1-af54-4a03-a916-1db454f69f2f", + "objectName": "MainRenderLayer", + "renderableTags": { + "order": [ + "render_main" + ], + "properties": { + "render_main": { + "annotations": [ + { + "properties": { + "featureLevel": 3 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::LinkEndAnnotation", + "value": 0 + } + } + }, + "sortOrder": 0 + }, + "typeName": "RenderLayer" + }, + { + "properties": { + "enabled": true, + "objectID": "d641a032-27f1-4414-ab34-d351ccaaa597", + "objectName": "NodePrefab", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "Node" + }, + { + "properties": { + "buffers": [ + "0808588c-0aad-42ed-bff7-5e2c2444f32b", + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "d8ff6844-df68-4b6f-a0ee-d14cb2fc4dd5", + "objectName": "RenderTargetMS" + }, + "typeName": "RenderTargetMS" + } + ], + "links": [ + ], + "logicEngineVersion": [ + 1, + 4, + 2 + ], + "racoVersion": [ + 1, + 10, + 0 + ], + "ramsesVersion": [ + 27, + 0, + 130 + ], + "structPropMap": { + "AnchorPointOutputs": { + "depth": "Double::DisplayNameAnnotation::LinkStartAnnotation", + "viewportCoords": "Vec2f::DisplayNameAnnotation::LinkStartAnnotation" + }, + "BlendOptions": { + "blendColor": "Vec4f::DisplayNameAnnotation", + "blendFactorDestAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorDestColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorSrcAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorSrcColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendOperationAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendOperationColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "colorWriteMask": "ColorWriteMask::DisplayNameAnnotation", + "cullmode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "depthFunction": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "depthwrite": "Bool::DisplayNameAnnotation", + "scissorOptions": "ScissorOptions::DisplayNameAnnotation", + "stencilOptions": "StencilOptions::DisplayNameAnnotation" + }, + "CameraViewport": { + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "offsetX": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "offsetY": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation" + }, + "ColorWriteMask": { + "alpha": "Bool::DisplayNameAnnotation", + "blue": "Bool::DisplayNameAnnotation", + "green": "Bool::DisplayNameAnnotation", + "red": "Bool::DisplayNameAnnotation" + }, + "DefaultResourceDirectories": { + "imageSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "interfaceSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "meshSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "scriptSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "shaderSubdirectory": "String::DisplayNameAnnotation::URIAnnotation" + }, + "LuaStandardModuleSelection": { + "base": "Bool::DisplayNameAnnotation", + "debug": "Bool::DisplayNameAnnotation", + "math": "Bool::DisplayNameAnnotation", + "string": "Bool::DisplayNameAnnotation", + "table": "Bool::DisplayNameAnnotation" + }, + "OrthographicFrustum": { + "bottomPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "farPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "leftPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "nearPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "rightPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "topPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation" + }, + "ScissorOptions": { + "scissorEnable": "Bool::DisplayNameAnnotation", + "scissorRegion": "CameraViewport::DisplayNameAnnotation" + }, + "StencilOptions": { + "stencilFunc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilMask": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "stencilOpDepthFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpDepthSucc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpStencilFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilRef": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "TimerInput": { + "ticker_us": "Int64::DisplayNameAnnotation::LinkEndAnnotation" + }, + "TimerOutput": { + "ticker_us": "Int64::DisplayNameAnnotation::LinkStartAnnotation" + }, + "Vec2f": { + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec2i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "Vec3f": { + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "z": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec3i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i3": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "Vec4f": { + "w": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "z": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec4i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i3": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i4": "Int::DisplayNameAnnotation::RangeAnnotationInt" + } + }, + "userTypePropMap": { + "AnchorPoint": { + "camera": "BaseCamera::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "node": "Node::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "AnchorPointOutputs::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Animation": { + "animationChannels": "Array[AnimationChannel]::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "Table::DisplayNameAnnotation", + "progress": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "AnimationChannel": { + "animationIndex": "Int::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "samplerIndex": "Int::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "BlitPass": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "destinationX": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "destinationY": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "enabled": "Bool::DisplayNameAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderOrder": "Int::DisplayNameAnnotation", + "sourceRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "sourceRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "sourceX": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "sourceY": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "targetRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "targetRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" + }, + "CubeMap": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "generateMipmaps": "Bool::DisplayNameAnnotation", + "level2uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "LuaInterface": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "inputs": "Table::DisplayNameAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation::FeatureLevel", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation::FeatureLevel", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "LuaScript": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "inputs": "Table::DisplayNameAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "Table::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "LuaScriptModule": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Material": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "options": "BlendOptions::DisplayNameAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "uniforms": "Table::DisplayNameAnnotation", + "uriDefines": "String::URIAnnotation::DisplayNameAnnotation", + "uriFragment": "String::URIAnnotation::DisplayNameAnnotation", + "uriGeometry": "String::URIAnnotation::DisplayNameAnnotation", + "uriVertex": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Mesh": { + "bakeMeshes": "Bool::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "materialNames": "Table::ArraySemanticAnnotation::HiddenProperty", + "meshIndex": "Int::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "MeshNode": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "instanceCount": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "materials": "Table::DisplayNameAnnotation", + "mesh": "Mesh::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "Node": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "OrthographicCamera": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "frustum": "OrthographicFrustum::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "PerspectiveCamera": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "frustum": "Table::DisplayNameAnnotation::LinkEndAnnotation", + "frustumType": "Int::DisplayNameAnnotation::EnumerationAnnotation::FeatureLevel", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "Prefab": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "PrefabInstance": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "template": "Prefab::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "ProjectSettings": { + "backgroundColor": "Vec4f::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "defaultResourceFolders": "DefaultResourceDirectories::DisplayNameAnnotation", + "featureLevel": "Int::DisplayNameAnnotation::ReadOnlyAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "saveAsZip": "Bool::DisplayNameAnnotation", + "sceneId": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "viewport": "Vec2i::DisplayNameAnnotation" + }, + "RenderBuffer": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "RenderBufferMS": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "sampleCount": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" + }, + "RenderLayer": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "materialFilterMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "materialFilterTags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderableTags": "Table::RenderableTagContainerAnnotation::DisplayNameAnnotation", + "sortOrder": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderPass": { + "camera": "BaseCamera::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "clearColor": "Vec4f::DisplayNameAnnotation::LinkEndAnnotation", + "enableClearColor": "Bool::DisplayNameAnnotation", + "enableClearDepth": "Bool::DisplayNameAnnotation", + "enableClearStencil": "Bool::DisplayNameAnnotation", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "layers": "Array[RenderLayer]::DisplayNameAnnotation::EmptyReferenceAllowable", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderOnce": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "renderOrder": "Int::DisplayNameAnnotation::LinkEndAnnotation", + "target": "RenderTargetBase::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderTarget": { + "buffers": "Array[RenderBuffer]::DisplayNameAnnotation::EmptyReferenceAllowable", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderTargetMS": { + "buffers": "Array[RenderBufferMS]::DisplayNameAnnotation::EmptyReferenceAllowable", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Skin": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "joints": "Array[Node]::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "skinIndex": "Int::DisplayNameAnnotation", + "targets": "Array[MeshNode]::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Texture": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "flipTexture": "Bool::DisplayNameAnnotation", + "generateMipmaps": "Bool::DisplayNameAnnotation", + "level2uri": "String::URIAnnotation::DisplayNameAnnotation", + "level3uri": "String::URIAnnotation::DisplayNameAnnotation", + "level4uri": "String::URIAnnotation::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "TextureExternal": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Timer": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "inputs": "TimerInput::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "TimerOutput::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + } + } +} diff --git a/datamodel/libCore/tests/migrationTestData/V59.rca b/datamodel/libCore/tests/migrationTestData/V59.rca new file mode 100644 index 00000000..a8e15e1a --- /dev/null +++ b/datamodel/libCore/tests/migrationTestData/V59.rca @@ -0,0 +1,35829 @@ +{ + "externalProjects": { + }, + "featureLevel": 5, + "fileVersion": 59, + "instances": [ + { + "properties": { + "children": [ + "e14cfbcf-2fac-47fe-84e8-d4108ed3d905", + "0b04064e-1aaa-4818-82e1-712bef82dc78", + "642b030c-d1d1-4a28-ae7f-38adb9dfd5ba", + "9bf4ce1c-e034-4d13-8018-bff7d49b2ca7", + "e7e85580-a647-4332-b269-05f143f2138f" + ], + "enabled": true, + "objectID": "3bb7981a-5a5c-497e-9b38-0ae26e79f5ca", + "objectName": "Node", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "tags": { + "properties": [ + { + "typeName": "String", + "value": "render_main" + } + ] + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": false + }, + "typeName": "Node" + }, + { + "properties": { + "inputs": { + "order": [ + "bool", + "float", + "integer", + "integer64", + "string", + "vector2f", + "vector2i", + "vector3f", + "vector3i", + "vector4f", + "vector4i" + ], + "properties": { + "bool": { + "annotations": [ + { + "properties": { + "engineType": 1 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Bool::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": false + }, + "float": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "integer": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "integer64": { + "annotations": [ + { + "properties": { + "engineType": 18 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int64::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": "0" + }, + "string": { + "annotations": [ + { + "properties": { + "engineType": 6 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "String::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": "" + }, + "vector2f": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "vector2i": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "vector3f": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "vector3i": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "vector4f": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "vector4i": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + } + }, + "objectID": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "objectName": "intf-scalar", + "stdModules": { + "base": true, + "debug": true, + "math": true, + "string": true, + "table": true + }, + "uri": "scripts/interface-scalar-types.lua" + }, + "typeName": "LuaInterface" + }, + { + "properties": { + "inputs": { + "order": [ + "a_s_prims", + "s_a_prims", + "s_a_struct_prim", + "s_prims" + ], + "properties": { + "a_s_prims": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "f", + "i", + "iv2", + "iv3", + "iv4", + "v2", + "v3", + "v4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "f", + "i", + "iv2", + "iv3", + "iv4", + "v2", + "v3", + "v4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "s_a_prims": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "aivec2", + "aivec3", + "aivec4", + "avec2", + "avec3", + "avec4", + "fvec", + "ivec" + ], + "properties": { + "aivec2": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "aivec3": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "aivec4": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5", + "6" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "6": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "avec2": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "avec3": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "avec4": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5", + "6" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "6": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "fvec": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "ivec": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "s_a_struct_prim": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "prims" + ], + "properties": { + "prims": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "f", + "i", + "iv2", + "iv3", + "iv4", + "v2", + "v3", + "v4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "f", + "i", + "iv2", + "iv3", + "iv4", + "v2", + "v3", + "v4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "s_prims": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "f", + "i", + "iv2", + "iv3", + "iv4", + "v2", + "v3", + "v4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + } + }, + "objectID": "84c914dd-f6f4-40d9-a9a8-74ae41265f0b", + "objectName": "intf-struct", + "stdModules": { + "base": true, + "debug": true, + "math": true, + "string": true, + "table": true + }, + "uri": "scripts/uniform-structs.lua" + }, + "typeName": "LuaInterface" + }, + { + "properties": { + "enabled": true, + "frustum": { + "order": [ + "nearPlane", + "farPlane", + "fieldOfView", + "aspectRatio" + ], + "properties": { + "aspectRatio": { + "annotations": [ + { + "properties": { + "name": "aspectRatio" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 4, + "min": 0.5 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 2 + }, + "farPlane": { + "annotations": [ + { + "properties": { + "name": "farPlane" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 10000, + "min": 100 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 1000 + }, + "fieldOfView": { + "annotations": [ + { + "properties": { + "name": "fieldOfView" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 120, + "min": 10 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 35 + }, + "nearPlane": { + "annotations": [ + { + "properties": { + "name": "nearPlane" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 1, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 0.1 + } + } + }, + "frustumType": 0, + "objectID": "b1c9a9e2-ab43-44f2-9c7e-07f3d3cc8f17", + "objectName": "PerspectiveCamera", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 10 + } + }, + "viewport": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + }, + "visibility": true + }, + "typeName": "PerspectiveCamera" + }, + { + "properties": { + "backgroundColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "defaultResourceFolders": { + "imageSubdirectory": "images", + "interfaceSubdirectory": "interfaces", + "meshSubdirectory": "meshes", + "scriptSubdirectory": "scripts", + "shaderSubdirectory": "shaders" + }, + "featureLevel": 5, + "objectID": "d557731f-3888-43ba-9022-2cc251dca613", + "objectName": "uniform-struct", + "saveAsZip": false, + "sceneId": { + "annotations": [ + { + "properties": { + "max": 1024, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 123 + }, + "viewport": { + "i1": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + } + } + }, + "typeName": "ProjectSettings" + }, + { + "properties": { + "inputs": { + "order": [ + "aivec2", + "aivec3", + "aivec4", + "avec2", + "avec3", + "avec4", + "fvec", + "ivec" + ], + "properties": { + "aivec2": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "aivec3": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "aivec4": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5", + "6" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "6": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "avec2": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "avec3": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "avec4": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5", + "6" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "6": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "fvec": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + }, + "ivec": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "typeName": "LinkStartAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "value": 0 + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkStartAnnotation::LinkEndAnnotation" + } + } + }, + "objectID": "dc75ba18-b463-4afa-a6ca-4b2bb0fb861e", + "objectName": "intf-array", + "stdModules": { + "base": true, + "debug": true, + "math": true, + "string": true, + "table": true + }, + "uri": "scripts/uniform-array.lua" + }, + "typeName": "LuaInterface" + }, + { + "properties": { + "enabled": true, + "instanceCount": { + "annotations": [ + { + "properties": { + "max": 20, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "materials": { + "order": [ + "material" + ], + "properties": { + "material": { + "order": [ + "material", + "private", + "options", + "uniforms" + ], + "properties": { + "material": { + "typeName": "Material", + "value": null + }, + "options": { + "annotations": [ + { + "properties": { + "name": "Options" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "properties": { + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } + }, + "typeName": "BlendOptions::DisplayNameAnnotation" + }, + "private": { + "annotations": [ + { + "properties": { + "name": "Private Material" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "typeName": "Bool::DisplayNameAnnotation", + "value": false + }, + "uniforms": { + "typeName": "Table" + } + }, + "typeName": "Table" + } + } + }, + "mesh": "f6dc8cd1-472e-4a0f-a651-3877d07c1264", + "objectID": "0b04064e-1aaa-4818-82e1-712bef82dc78", + "objectName": "meshnode_no_mat", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": false + }, + "typeName": "MeshNode" + }, + { + "properties": { + "enabled": true, + "instanceCount": { + "annotations": [ + { + "properties": { + "max": 20, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "materials": { + "order": [ + "material" + ], + "properties": { + "material": { + "order": [ + "material", + "private", + "options", + "uniforms" + ], + "properties": { + "material": { + "typeName": "Material", + "value": "d78190c5-f339-458d-9ad4-f448cc12f936" + }, + "options": { + "annotations": [ + { + "properties": { + "name": "Options" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "properties": { + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } + }, + "typeName": "BlendOptions::DisplayNameAnnotation" + }, + "private": { + "annotations": [ + { + "properties": { + "name": "Private Material" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "typeName": "Bool::DisplayNameAnnotation", + "value": true + }, + "uniforms": { + "order": [ + "scalar", + "ivec", + "fvec", + "avec2", + "avec3", + "avec4", + "aivec2", + "aivec3", + "aivec4" + ], + "properties": { + "aivec2": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "aivec3": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "aivec4": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5", + "6" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "6": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "avec2": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "avec3": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "avec4": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5", + "6" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "6": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "fvec": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "ivec": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 1 + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 2 + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "scalar": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + } + }, + "typeName": "Table" + } + }, + "typeName": "Table" + } + } + }, + "mesh": "f6dc8cd1-472e-4a0f-a651-3877d07c1264", + "objectID": "642b030c-d1d1-4a28-ae7f-38adb9dfd5ba", + "objectName": "meshnode_mat_array_link_array", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "MeshNode" + }, + { + "properties": { + "enabled": true, + "instanceCount": { + "annotations": [ + { + "properties": { + "max": 20, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "materials": { + "order": [ + "material" + ], + "properties": { + "material": { + "order": [ + "material", + "private", + "options", + "uniforms" + ], + "properties": { + "material": { + "typeName": "Material", + "value": "d2948231-30b7-4f3c-bef1-35fa9bde4590" + }, + "options": { + "annotations": [ + { + "properties": { + "name": "Options" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "properties": { + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } + }, + "typeName": "BlendOptions::DisplayNameAnnotation" + }, + "private": { + "annotations": [ + { + "properties": { + "name": "Private Material" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "typeName": "Bool::DisplayNameAnnotation", + "value": true + }, + "uniforms": { + "order": [ + "scalar", + "ivec", + "fvec", + "avec2", + "avec3", + "avec4", + "aivec2", + "aivec3", + "aivec4" + ], + "properties": { + "aivec2": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "aivec3": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "aivec4": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5", + "6" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "6": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "avec2": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "avec3": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "avec4": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5", + "6" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "6": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "fvec": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "ivec": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "scalar": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + } + }, + "typeName": "Table" + } + }, + "typeName": "Table" + } + } + }, + "mesh": "f6dc8cd1-472e-4a0f-a651-3877d07c1264", + "objectID": "9bf4ce1c-e034-4d13-8018-bff7d49b2ca7", + "objectName": "meshnode_mat_array_link_member", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "MeshNode" + }, + { + "properties": { + "anisotropy": { + "annotations": [ + { + "properties": { + "max": 32000, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "flipTexture": false, + "generateMipmaps": false, + "level2uri": "", + "level3uri": "", + "level4uri": "", + "magSamplingMethod": 0, + "minSamplingMethod": 0, + "mipmapLevel": { + "annotations": [ + { + "properties": { + "max": 4, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "objectID": "afdd39cb-0296-42ac-ae26-6729b229f0d9", + "objectName": "texture", + "textureFormat": 5, + "uri": "../testData/DuckCM.png", + "wrapUMode": 0, + "wrapVMode": 0 + }, + "typeName": "Texture" + }, + { + "properties": { + "objectID": "c443aa5d-2f10-4208-8966-460ad6a730d8", + "objectName": "mat_struct", + "options": { + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } + }, + "uniforms": { + "order": [ + "s_prims", + "s_samplers", + "s_a_prims", + "nested", + "s_a_struct_prim", + "s_a_struct_samplers", + "a_s_prims", + "a_s_samplers", + "a_s_a_struct_prim", + "a_s_a_struct_samplers" + ], + "properties": { + "a_s_a_struct_prim": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "prims" + ], + "properties": { + "prims": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 42 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 2 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "prims" + ], + "properties": { + "prims": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "a_s_a_struct_samplers": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "samplers" + ], + "properties": { + "samplers": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "samplers" + ], + "properties": { + "samplers": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "a_s_prims": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 42 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 2 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "a_s_samplers": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "nested": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "prims", + "samplers" + ], + "properties": { + "prims": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 42 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 2 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "samplers": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "s_a_prims": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "ivec", + "fvec", + "avec2", + "avec3", + "avec4", + "aivec2", + "aivec3", + "aivec4" + ], + "properties": { + "aivec2": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 2 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 3 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 4 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "aivec3": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "aivec4": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5", + "6" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "6": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "avec2": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "avec3": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "avec4": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5", + "6" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "6": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "fvec": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "ivec": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 1 + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 2 + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "s_a_struct_prim": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "prims" + ], + "properties": { + "prims": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 42 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 2 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "s_a_struct_samplers": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "samplers" + ], + "properties": { + "samplers": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "s_prims": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 42 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 2 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 5 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 2 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "s_samplers": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": "afdd39cb-0296-42ac-ae26-6729b229f0d9" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + } + }, + "uriDefines": "", + "uriFragment": "shaders/uniform-struct.frag", + "uriGeometry": "", + "uriVertex": "shaders/uniform-struct.vert" + }, + "typeName": "Material" + }, + { + "properties": { + "objectID": "c51a5beb-cb1a-4460-b7d8-5da6282cdc11", + "objectName": "mat_scalar", + "options": { + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } + }, + "uniforms": { + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 2 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 2 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + } + }, + "uriDefines": "", + "uriFragment": "shaders/uniform-scalar.frag", + "uriGeometry": "", + "uriVertex": "shaders/uniform-scalar.vert" + }, + "typeName": "Material" + }, + { + "properties": { + "objectID": "d2948231-30b7-4f3c-bef1-35fa9bde4590", + "objectName": "mat_array_link_member", + "options": { + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } + }, + "uniforms": { + "order": [ + "scalar", + "ivec", + "fvec", + "avec2", + "avec3", + "avec4", + "aivec2", + "aivec3", + "aivec4" + ], + "properties": { + "aivec2": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "aivec3": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "aivec4": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5", + "6" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "6": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "avec2": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "avec3": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "avec4": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5", + "6" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "6": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "fvec": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "ivec": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "scalar": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + } + } + }, + "uriDefines": "", + "uriFragment": "shaders/uniform-array.frag", + "uriGeometry": "", + "uriVertex": "shaders/uniform-array.vert" + }, + "typeName": "Material" + }, + { + "properties": { + "camera": "b1c9a9e2-ab43-44f2-9c7e-07f3d3cc8f17", + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layers": [ + "d9e286e0-1a00-4e91-ae46-9cec3628818e", + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "d56af14b-1516-4b23-bf0c-a7dc6144f99e", + "objectName": "MainRenderPass", + "renderOnce": false, + "renderOrder": 1, + "target": null + }, + "typeName": "RenderPass" + }, + { + "properties": { + "objectID": "d78190c5-f339-458d-9ad4-f448cc12f936", + "objectName": "mat_array_link_array", + "options": { + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } + }, + "uniforms": { + "order": [ + "scalar", + "ivec", + "fvec", + "avec2", + "avec3", + "avec4", + "aivec2", + "aivec3", + "aivec4" + ], + "properties": { + "aivec2": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "aivec3": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "aivec4": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5", + "6" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "6": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "avec2": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "avec3": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "avec4": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5", + "6" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "6": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "fvec": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "ivec": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 1 + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 2 + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "scalar": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + } + } + }, + "uriDefines": "", + "uriFragment": "shaders/uniform-array.frag", + "uriGeometry": "", + "uriVertex": "shaders/uniform-array.vert" + }, + "typeName": "Material" + }, + { + "properties": { + "materialFilterMode": 1, + "objectID": "d9e286e0-1a00-4e91-ae46-9cec3628818e", + "objectName": "MainRenderLayer", + "renderableTags": { + "order": [ + "render_main" + ], + "properties": { + "render_main": { + "annotations": [ + { + "properties": { + "featureLevel": 3 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::LinkEndAnnotation", + "value": 0 + } + } + }, + "sortOrder": 0 + }, + "typeName": "RenderLayer" + }, + { + "properties": { + "enabled": true, + "instanceCount": { + "annotations": [ + { + "properties": { + "max": 20, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "materials": { + "order": [ + "material" + ], + "properties": { + "material": { + "order": [ + "material", + "private", + "options", + "uniforms" + ], + "properties": { + "material": { + "typeName": "Material", + "value": "c51a5beb-cb1a-4460-b7d8-5da6282cdc11" + }, + "options": { + "annotations": [ + { + "properties": { + "name": "Options" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "properties": { + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } + }, + "typeName": "BlendOptions::DisplayNameAnnotation" + }, + "private": { + "annotations": [ + { + "properties": { + "name": "Private Material" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "typeName": "Bool::DisplayNameAnnotation", + "value": true + }, + "uniforms": { + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 2 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 2 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table" + } + }, + "typeName": "Table" + } + } + }, + "mesh": "f6dc8cd1-472e-4a0f-a651-3877d07c1264", + "objectID": "e14cfbcf-2fac-47fe-84e8-d4108ed3d905", + "objectName": "meshnode_mat_scalar", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "MeshNode" + }, + { + "properties": { + "enabled": true, + "instanceCount": { + "annotations": [ + { + "properties": { + "max": 20, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "materials": { + "order": [ + "material" + ], + "properties": { + "material": { + "order": [ + "material", + "private", + "options", + "uniforms" + ], + "properties": { + "material": { + "typeName": "Material", + "value": "c443aa5d-2f10-4208-8966-460ad6a730d8" + }, + "options": { + "annotations": [ + { + "properties": { + "name": "Options" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "properties": { + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } + }, + "typeName": "BlendOptions::DisplayNameAnnotation" + }, + "private": { + "annotations": [ + { + "properties": { + "name": "Private Material" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "typeName": "Bool::DisplayNameAnnotation", + "value": true + }, + "uniforms": { + "order": [ + "s_prims", + "s_samplers", + "s_a_prims", + "nested", + "s_a_struct_prim", + "s_a_struct_samplers", + "a_s_prims", + "a_s_samplers", + "a_s_a_struct_prim", + "a_s_a_struct_samplers" + ], + "properties": { + "a_s_a_struct_prim": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "prims" + ], + "properties": { + "prims": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 42 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 2 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "prims" + ], + "properties": { + "prims": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "a_s_a_struct_samplers": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "samplers" + ], + "properties": { + "samplers": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "samplers" + ], + "properties": { + "samplers": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "a_s_prims": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 42 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 2 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": -1 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "a_s_samplers": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "nested": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "prims", + "samplers" + ], + "properties": { + "prims": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 42 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 2 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "samplers": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "s_a_prims": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "ivec", + "fvec", + "avec2", + "avec3", + "avec4", + "aivec2", + "aivec3", + "aivec4" + ], + "properties": { + "aivec2": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 2 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 3 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 4 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "aivec3": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "aivec4": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5", + "6" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "6": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "avec2": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "avec3": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "avec4": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5", + "6" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "6": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "fvec": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2", + "3", + "4", + "5" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "3": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "4": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "5": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "ivec": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 1 + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 2 + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "s_a_struct_prim": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "prims" + ], + "properties": { + "prims": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 42 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 2 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "s_a_struct_samplers": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "samplers" + ], + "properties": { + "samplers": { + "annotations": [ + { + "properties": { + "engineType": 14 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "1", + "2" + ], + "properties": { + "1": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "2": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "s_prims": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "i", + "f", + "v2", + "v3", + "v4", + "iv2", + "iv3", + "iv4" + ], + "properties": { + "f": { + "annotations": [ + { + "properties": { + "engineType": 5 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::EngineTypeAnnotation::LinkEndAnnotation", + "value": 0 + }, + "i": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 42 + }, + "iv2": { + "annotations": [ + { + "properties": { + "engineType": 10 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 2 + } + }, + "typeName": "Vec2i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv3": { + "annotations": [ + { + "properties": { + "engineType": 11 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec3i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "iv4": { + "annotations": [ + { + "properties": { + "engineType": 12 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "i1": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i3": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "i4": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + } + }, + "typeName": "Vec4i::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v2": { + "annotations": [ + { + "properties": { + "engineType": 7 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 5 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 2 + } + }, + "typeName": "Vec2f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v3": { + "annotations": [ + { + "properties": { + "engineType": 8 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec3f::EngineTypeAnnotation::LinkEndAnnotation" + }, + "v4": { + "annotations": [ + { + "properties": { + "engineType": 9 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "properties": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Vec4f::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + }, + "s_samplers": { + "annotations": [ + { + "properties": { + "engineType": 13 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "order": [ + "s_texture", + "s_cubemap", + "s_buffer", + "s_buffer_ms" + ], + "properties": { + "s_buffer": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_buffer_ms": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_cubemap": { + "annotations": [ + { + "properties": { + "engineType": 17 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "CubeMap::EngineTypeAnnotation::LinkEndAnnotation", + "value": null + }, + "s_texture": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation::LinkEndAnnotation", + "value": "afdd39cb-0296-42ac-ae26-6729b229f0d9" + } + }, + "typeName": "Table::EngineTypeAnnotation::LinkEndAnnotation" + } + }, + "typeName": "Table" + } + }, + "typeName": "Table" + } + } + }, + "mesh": "f6dc8cd1-472e-4a0f-a651-3877d07c1264", + "objectID": "e7e85580-a647-4332-b269-05f143f2138f", + "objectName": "meshnode_mat_struct", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "MeshNode" + }, + { + "properties": { + "bakeMeshes": true, + "materialNames": { + "properties": [ + { + "typeName": "String", + "value": "material" + } + ] + }, + "meshIndex": 0, + "metaData": { + "order": [ + "meshInfo" + ], + "properties": { + "meshInfo": { + "annotations": [ + { + "typeName": "ReadOnlyAnnotation" + } + ], + "order": [ + "triangles", + "vertices" + ], + "properties": { + "triangles": { + "typeName": "Int", + "value": 4212 + }, + "vertices": { + "typeName": "Int", + "value": 2399 + } + }, + "typeName": "Table::ReadOnlyAnnotation" + } + } + }, + "objectID": "f6dc8cd1-472e-4a0f-a651-3877d07c1264", + "objectName": "Mesh", + "uri": "../testData/duck.glb" + }, + "typeName": "Mesh" + } + ], + "links": [ + { + "properties": { + "endObject": "0b04064e-1aaa-4818-82e1-712bef82dc78", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "visibility" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "bool" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "3bb7981a-5a5c-497e-9b38-0ae26e79f5ca", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "visibility" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "bool" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "9bf4ce1c-e034-4d13-8018-bff7d49b2ca7", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "materials" + }, + { + "typeName": "String", + "value": "material" + }, + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "fvec" + }, + { + "typeName": "String", + "value": "5" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "float" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "c443aa5d-2f10-4208-8966-460ad6a730d8", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "a_s_a_struct_prim" + }, + { + "typeName": "String", + "value": "1" + }, + { + "typeName": "String", + "value": "prims" + }, + { + "typeName": "String", + "value": "1" + }, + { + "typeName": "String", + "value": "f" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "float" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "c443aa5d-2f10-4208-8966-460ad6a730d8", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "a_s_prims" + }, + { + "typeName": "String", + "value": "1" + }, + { + "typeName": "String", + "value": "f" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "float" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "c443aa5d-2f10-4208-8966-460ad6a730d8", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "nested" + }, + { + "typeName": "String", + "value": "prims" + }, + { + "typeName": "String", + "value": "f" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "float" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "c443aa5d-2f10-4208-8966-460ad6a730d8", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "s_a_struct_prim" + }, + { + "typeName": "String", + "value": "prims" + }, + { + "typeName": "String", + "value": "1" + }, + { + "typeName": "String", + "value": "f" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "float" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "c443aa5d-2f10-4208-8966-460ad6a730d8", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "s_prims" + }, + { + "typeName": "String", + "value": "f" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "float" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "c51a5beb-cb1a-4460-b7d8-5da6282cdc11", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "f" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "float" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "d2948231-30b7-4f3c-bef1-35fa9bde4590", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "fvec" + }, + { + "typeName": "String", + "value": "5" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "float" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "e14cfbcf-2fac-47fe-84e8-d4108ed3d905", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "materials" + }, + { + "typeName": "String", + "value": "material" + }, + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "f" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "float" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "e7e85580-a647-4332-b269-05f143f2138f", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "materials" + }, + { + "typeName": "String", + "value": "material" + }, + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "a_s_a_struct_prim" + }, + { + "typeName": "String", + "value": "1" + }, + { + "typeName": "String", + "value": "prims" + }, + { + "typeName": "String", + "value": "1" + }, + { + "typeName": "String", + "value": "f" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "float" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "e7e85580-a647-4332-b269-05f143f2138f", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "materials" + }, + { + "typeName": "String", + "value": "material" + }, + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "a_s_prims" + }, + { + "typeName": "String", + "value": "1" + }, + { + "typeName": "String", + "value": "f" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "float" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "e7e85580-a647-4332-b269-05f143f2138f", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "materials" + }, + { + "typeName": "String", + "value": "material" + }, + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "nested" + }, + { + "typeName": "String", + "value": "prims" + }, + { + "typeName": "String", + "value": "f" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "float" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "e7e85580-a647-4332-b269-05f143f2138f", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "materials" + }, + { + "typeName": "String", + "value": "material" + }, + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "s_a_struct_prim" + }, + { + "typeName": "String", + "value": "prims" + }, + { + "typeName": "String", + "value": "1" + }, + { + "typeName": "String", + "value": "f" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "float" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "e7e85580-a647-4332-b269-05f143f2138f", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "materials" + }, + { + "typeName": "String", + "value": "material" + }, + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "s_prims" + }, + { + "typeName": "String", + "value": "f" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "float" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "c51a5beb-cb1a-4460-b7d8-5da6282cdc11", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "v2" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "vector2f" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "e14cfbcf-2fac-47fe-84e8-d4108ed3d905", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "materials" + }, + { + "typeName": "String", + "value": "material" + }, + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "v2" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "vector2f" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "9bf4ce1c-e034-4d13-8018-bff7d49b2ca7", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "materials" + }, + { + "typeName": "String", + "value": "material" + }, + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "avec3" + }, + { + "typeName": "String", + "value": "2" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "vector3f" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "c443aa5d-2f10-4208-8966-460ad6a730d8", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "a_s_a_struct_prim" + }, + { + "typeName": "String", + "value": "1" + }, + { + "typeName": "String", + "value": "prims" + }, + { + "typeName": "String", + "value": "1" + }, + { + "typeName": "String", + "value": "v3" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "vector3f" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "c443aa5d-2f10-4208-8966-460ad6a730d8", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "a_s_prims" + }, + { + "typeName": "String", + "value": "1" + }, + { + "typeName": "String", + "value": "v3" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "vector3f" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "c443aa5d-2f10-4208-8966-460ad6a730d8", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "nested" + }, + { + "typeName": "String", + "value": "prims" + }, + { + "typeName": "String", + "value": "v3" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "vector3f" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "c443aa5d-2f10-4208-8966-460ad6a730d8", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "s_a_prims" + }, + { + "typeName": "String", + "value": "avec3" + }, + { + "typeName": "String", + "value": "1" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "vector3f" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "c443aa5d-2f10-4208-8966-460ad6a730d8", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "s_a_struct_prim" + }, + { + "typeName": "String", + "value": "prims" + }, + { + "typeName": "String", + "value": "1" + }, + { + "typeName": "String", + "value": "v3" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "vector3f" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "d2948231-30b7-4f3c-bef1-35fa9bde4590", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "avec3" + }, + { + "typeName": "String", + "value": "2" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "vector3f" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "e7e85580-a647-4332-b269-05f143f2138f", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "materials" + }, + { + "typeName": "String", + "value": "material" + }, + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "a_s_a_struct_prim" + }, + { + "typeName": "String", + "value": "1" + }, + { + "typeName": "String", + "value": "prims" + }, + { + "typeName": "String", + "value": "1" + }, + { + "typeName": "String", + "value": "v3" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "vector3f" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "e7e85580-a647-4332-b269-05f143f2138f", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "materials" + }, + { + "typeName": "String", + "value": "material" + }, + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "a_s_prims" + }, + { + "typeName": "String", + "value": "1" + }, + { + "typeName": "String", + "value": "v3" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "vector3f" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "e7e85580-a647-4332-b269-05f143f2138f", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "materials" + }, + { + "typeName": "String", + "value": "material" + }, + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "nested" + }, + { + "typeName": "String", + "value": "prims" + }, + { + "typeName": "String", + "value": "v3" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "vector3f" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "e7e85580-a647-4332-b269-05f143f2138f", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "materials" + }, + { + "typeName": "String", + "value": "material" + }, + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "s_a_prims" + }, + { + "typeName": "String", + "value": "avec3" + }, + { + "typeName": "String", + "value": "1" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "vector3f" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "e7e85580-a647-4332-b269-05f143f2138f", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "materials" + }, + { + "typeName": "String", + "value": "material" + }, + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "s_a_struct_prim" + }, + { + "typeName": "String", + "value": "prims" + }, + { + "typeName": "String", + "value": "1" + }, + { + "typeName": "String", + "value": "v3" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "3c1c0971-31a8-45b7-8be6-a96e0ac1639a", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "vector3f" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "642b030c-d1d1-4a28-ae7f-38adb9dfd5ba", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "materials" + }, + { + "typeName": "String", + "value": "material" + }, + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "fvec" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "dc75ba18-b463-4afa-a6ca-4b2bb0fb861e", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "fvec" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "c443aa5d-2f10-4208-8966-460ad6a730d8", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "s_a_prims" + }, + { + "typeName": "String", + "value": "fvec" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "dc75ba18-b463-4afa-a6ca-4b2bb0fb861e", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "fvec" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "d78190c5-f339-458d-9ad4-f448cc12f936", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "fvec" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "dc75ba18-b463-4afa-a6ca-4b2bb0fb861e", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "fvec" + } + ] + } + }, + "typeName": "Link" + }, + { + "properties": { + "endObject": "e7e85580-a647-4332-b269-05f143f2138f", + "endProp": { + "properties": [ + { + "typeName": "String", + "value": "materials" + }, + { + "typeName": "String", + "value": "material" + }, + { + "typeName": "String", + "value": "uniforms" + }, + { + "typeName": "String", + "value": "s_a_prims" + }, + { + "typeName": "String", + "value": "fvec" + } + ] + }, + "isValid": true, + "isWeak": false, + "startObject": "dc75ba18-b463-4afa-a6ca-4b2bb0fb861e", + "startProp": { + "properties": [ + { + "typeName": "String", + "value": "inputs" + }, + { + "typeName": "String", + "value": "fvec" + } + ] + } + }, + "typeName": "Link" + } + ], + "logicEngineVersion": [ + 1, + 4, + 2 + ], + "racoVersion": [ + 1, + 10, + 0 + ], + "ramsesVersion": [ + 27, + 0, + 130 + ], + "structPropMap": { + "AnchorPointOutputs": { + "depth": "Double::DisplayNameAnnotation::LinkStartAnnotation", + "viewportCoords": "Vec2f::DisplayNameAnnotation::LinkStartAnnotation" + }, + "BlendOptions": { + "blendColor": "Vec4f::DisplayNameAnnotation", + "blendFactorDestAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorDestColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorSrcAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorSrcColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendOperationAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendOperationColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "colorWriteMask": "ColorWriteMask::DisplayNameAnnotation", + "cullmode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "depthFunction": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "depthwrite": "Bool::DisplayNameAnnotation", + "scissorOptions": "ScissorOptions::DisplayNameAnnotation", + "stencilOptions": "StencilOptions::DisplayNameAnnotation" + }, + "CameraViewport": { + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "offsetX": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "offsetY": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation" + }, + "ColorWriteMask": { + "alpha": "Bool::DisplayNameAnnotation", + "blue": "Bool::DisplayNameAnnotation", + "green": "Bool::DisplayNameAnnotation", + "red": "Bool::DisplayNameAnnotation" + }, + "DefaultResourceDirectories": { + "imageSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "interfaceSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "meshSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "scriptSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "shaderSubdirectory": "String::DisplayNameAnnotation::URIAnnotation" + }, + "LuaStandardModuleSelection": { + "base": "Bool::DisplayNameAnnotation", + "debug": "Bool::DisplayNameAnnotation", + "math": "Bool::DisplayNameAnnotation", + "string": "Bool::DisplayNameAnnotation", + "table": "Bool::DisplayNameAnnotation" + }, + "OrthographicFrustum": { + "bottomPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "farPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "leftPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "nearPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "rightPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "topPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation" + }, + "ScissorOptions": { + "scissorEnable": "Bool::DisplayNameAnnotation", + "scissorRegion": "CameraViewport::DisplayNameAnnotation" + }, + "StencilOptions": { + "stencilFunc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilMask": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "stencilOpDepthFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpDepthSucc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpStencilFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilRef": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "TimerInput": { + "ticker_us": "Int64::DisplayNameAnnotation::LinkEndAnnotation" + }, + "TimerOutput": { + "ticker_us": "Int64::DisplayNameAnnotation::LinkStartAnnotation" + }, + "Vec2f": { + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec2i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "Vec3f": { + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "z": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec3i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i3": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "Vec4f": { + "w": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "z": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec4i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i3": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i4": "Int::DisplayNameAnnotation::RangeAnnotationInt" + } + }, + "userTypePropMap": { + "AnchorPoint": { + "camera": "BaseCamera::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "node": "Node::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "AnchorPointOutputs::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Animation": { + "animationChannels": "Array[AnimationChannel]::DisplayNameAnnotation::ResizableArray", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "Table::DisplayNameAnnotation", + "progress": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "AnimationChannel": { + "animationIndex": "Int::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "samplerIndex": "Int::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "BlitPass": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "destinationX": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "destinationY": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "enabled": "Bool::DisplayNameAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderOrder": "Int::DisplayNameAnnotation", + "sourceRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "sourceRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "sourceX": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "sourceY": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "targetRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "targetRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" + }, + "CubeMap": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "generateMipmaps": "Bool::DisplayNameAnnotation", + "level2uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "LuaInterface": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "inputs": "Table::DisplayNameAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation::FeatureLevel", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation::FeatureLevel", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "LuaScript": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "inputs": "Table::DisplayNameAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "Table::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "LuaScriptModule": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Material": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "options": "BlendOptions::DisplayNameAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "uniforms": "Table::DisplayNameAnnotation", + "uriDefines": "String::URIAnnotation::DisplayNameAnnotation", + "uriFragment": "String::URIAnnotation::DisplayNameAnnotation", + "uriGeometry": "String::URIAnnotation::DisplayNameAnnotation", + "uriVertex": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Mesh": { + "bakeMeshes": "Bool::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "materialNames": "Table::ArraySemanticAnnotation::HiddenProperty", + "meshIndex": "Int::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "MeshNode": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "instanceCount": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "materials": "Table::DisplayNameAnnotation", + "mesh": "Mesh::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "Node": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "OrthographicCamera": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "frustum": "OrthographicFrustum::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "PerspectiveCamera": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "frustum": "Table::DisplayNameAnnotation::LinkEndAnnotation", + "frustumType": "Int::DisplayNameAnnotation::EnumerationAnnotation::FeatureLevel", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "Prefab": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "PrefabInstance": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "template": "Prefab::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "ProjectSettings": { + "backgroundColor": "Vec4f::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "defaultResourceFolders": "DefaultResourceDirectories::DisplayNameAnnotation", + "featureLevel": "Int::DisplayNameAnnotation::ReadOnlyAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "saveAsZip": "Bool::DisplayNameAnnotation", + "sceneId": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "viewport": "Vec2i::DisplayNameAnnotation" + }, + "RenderBuffer": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "RenderBufferMS": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "sampleCount": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" + }, + "RenderLayer": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "materialFilterMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "materialFilterTags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderableTags": "Table::RenderableTagContainerAnnotation::DisplayNameAnnotation", + "sortOrder": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderPass": { + "camera": "BaseCamera::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "clearColor": "Vec4f::DisplayNameAnnotation::LinkEndAnnotation", + "enableClearColor": "Bool::DisplayNameAnnotation", + "enableClearDepth": "Bool::DisplayNameAnnotation", + "enableClearStencil": "Bool::DisplayNameAnnotation", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "layers": "Array[RenderLayer]::DisplayNameAnnotation::EmptyReferenceAllowable::ResizableArray", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderOnce": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "renderOrder": "Int::DisplayNameAnnotation::LinkEndAnnotation", + "target": "RenderTargetBase::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderTarget": { + "buffers": "Array[RenderBuffer]::DisplayNameAnnotation::EmptyReferenceAllowable::ResizableArray", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderTargetMS": { + "buffers": "Array[RenderBufferMS]::DisplayNameAnnotation::EmptyReferenceAllowable::ResizableArray", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Skin": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "joints": "Array[Node]::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "skinIndex": "Int::DisplayNameAnnotation", + "targets": "Array[MeshNode]::DisplayNameAnnotation::ResizableArray", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Texture": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "flipTexture": "Bool::DisplayNameAnnotation", + "generateMipmaps": "Bool::DisplayNameAnnotation", + "level2uri": "String::URIAnnotation::DisplayNameAnnotation", + "level3uri": "String::URIAnnotation::DisplayNameAnnotation", + "level4uri": "String::URIAnnotation::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "TextureExternal": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Timer": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "inputs": "TimerInput::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "TimerOutput::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + } + } +} diff --git a/datamodel/libCore/tests/migrationTestData/V60.rca b/datamodel/libCore/tests/migrationTestData/V60.rca new file mode 100644 index 00000000..b6c7f380 --- /dev/null +++ b/datamodel/libCore/tests/migrationTestData/V60.rca @@ -0,0 +1,3102 @@ +{ + "externalProjects": { + }, + "featureLevel": 5, + "fileVersion": 60, + "instances": [ + { + "properties": { + "objectID": "027c8479-47a5-498b-a39e-8c43b7f709fb", + "objectName": "Prefab" + }, + "typeName": "Prefab" + }, + { + "properties": { + "enabled": true, + "frustum": { + "bottomPlane": { + "annotations": [ + { + "properties": { + "max": 0, + "min": -1000 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": -10 + }, + "farPlane": { + "annotations": [ + { + "properties": { + "max": 10000, + "min": 100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1000 + }, + "leftPlane": { + "annotations": [ + { + "properties": { + "max": 0, + "min": -1000 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": -10 + }, + "nearPlane": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0.1 + }, + "rightPlane": { + "annotations": [ + { + "properties": { + "max": 1000, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 10 + }, + "topPlane": { + "annotations": [ + { + "properties": { + "max": 1000, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 10 + } + }, + "objectID": "2bf34d57-3ad1-48a4-ac27-ace003f55167", + "objectName": "OrthographicCamera", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "viewport": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + }, + "visibility": true + }, + "typeName": "OrthographicCamera" + }, + { + "properties": { + "enabled": true, + "frustum": { + "order": [ + "nearPlane", + "farPlane", + "fieldOfView", + "aspectRatio" + ], + "properties": { + "aspectRatio": { + "annotations": [ + { + "properties": { + "name": "aspectRatio" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 4, + "min": 0.5 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 2 + }, + "farPlane": { + "annotations": [ + { + "properties": { + "name": "farPlane" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 10000, + "min": 100 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 1000 + }, + "fieldOfView": { + "annotations": [ + { + "properties": { + "name": "fieldOfView" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 120, + "min": 10 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 35 + }, + "nearPlane": { + "annotations": [ + { + "properties": { + "name": "nearPlane" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 1, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 0.1 + } + } + }, + "frustumType": 0, + "objectID": "34d3f7f0-1d2d-4d1d-adc1-4eee283a7b80", + "objectName": "PerspectiveCamera", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "viewport": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + }, + "visibility": true + }, + "typeName": "PerspectiveCamera" + }, + { + "properties": { + "luaModules": { + "order": [ + "coalas" + ], + "properties": { + "coalas": { + "typeName": "LuaScriptModule", + "value": "04ada1c4-7e3a-4f9e-983d-4724a073cad8" + } + } + }, + "objectID": "588bfb37-2015-4819-a868-6ed65f986484", + "objectName": "LuaScript", + "stdModules": { + "base": true, + "debug": true, + "math": true, + "string": true, + "table": true + }, + "uri": "scripts/script-using-module.lua" + }, + "typeName": "LuaScript" + }, + { + "properties": { + "animationChannels": [ + null, + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "6d1b00fe-912f-4a92-83ce-7d405ac6b989", + "objectName": "Animation", + "progress": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "typeName": "Animation" + }, + { + "properties": { + "backgroundColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "defaultResourceFolders": { + "imageSubdirectory": "images", + "interfaceSubdirectory": "interfaces", + "meshSubdirectory": "meshes", + "scriptSubdirectory": "scripts", + "shaderSubdirectory": "shaders" + }, + "featureLevel": 5, + "objectID": "71454add-eb56-4288-9057-825539914bed", + "objectName": "test-offscreen-tex-uniform-migration-material", + "saveAsZip": false, + "sceneId": { + "annotations": [ + { + "properties": { + "max": 1024, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 123 + }, + "viewport": { + "i1": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + } + } + }, + "typeName": "ProjectSettings" + }, + { + "properties": { + "children": [ + "122d0f90-2dea-4ddd-95f5-d537f5381a3e", + "3ccf4fe2-660d-40e8-84f9-eb4a932c87ca" + ], + "enabled": true, + "objectID": "8593d288-67a3-4ae1-9c8c-942786ddd1f2", + "objectName": "Node", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "Node" + }, + { + "properties": { + "enabled": true, + "objectID": "9ec70db9-1ec5-4c64-833d-44eb4ad1d495", + "objectName": "PrefabInstance", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "template": null, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "PrefabInstance" + }, + { + "properties": { + "luaModules": { + "order": [ + "coalas" + ], + "properties": { + "coalas": { + "typeName": "LuaScriptModule", + "value": "04ada1c4-7e3a-4f9e-983d-4724a073cad8" + } + } + }, + "objectID": "cba9dca1-d412-430e-b278-2d11f08107bf", + "objectName": "LuaInterface", + "stdModules": { + "base": true, + "debug": true, + "math": true, + "string": true, + "table": true + }, + "uri": "scripts/interface-using-module.lua" + }, + "typeName": "LuaInterface" + }, + { + "properties": { + "objectID": "fdcbf4ea-3802-484b-be53-4b38ec2d5ac3", + "objectName": "Skin", + "skinIndex": 0, + "targets": [ + null + ], + "uri": "" + }, + "typeName": "Skin" + }, + { + "properties": { + "objectID": "04ada1c4-7e3a-4f9e-983d-4724a073cad8", + "objectName": "LuaScriptModule", + "stdModules": { + "base": true, + "debug": true, + "math": true, + "string": true, + "table": true + }, + "uri": "" + }, + "typeName": "LuaScriptModule" + }, + { + "properties": { + "buffers": [ + null, + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "077b744c-c82d-467d-a406-4fca3603ae8a", + "objectName": "RenderTarget" + }, + "typeName": "RenderTarget" + }, + { + "properties": { + "anisotropy": { + "annotations": [ + { + "properties": { + "max": 32000, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "flipTexture": false, + "generateMipmaps": false, + "level2uri": "", + "level3uri": "", + "level4uri": "", + "magSamplingMethod": 0, + "minSamplingMethod": 0, + "mipmapLevel": { + "annotations": [ + { + "properties": { + "max": 4, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "objectID": "0d2c96e3-0ed2-4f95-ac54-03b9fa81e963", + "objectName": "Texture", + "textureFormat": 5, + "uri": "", + "wrapUMode": 0, + "wrapVMode": 0 + }, + "typeName": "Texture" + }, + { + "properties": { + "materialFilterMode": 0, + "objectID": "0e55bd9c-7f72-4afe-bfa8-64cdfd59cb8d", + "objectName": "RenderLayerOptimized", + "sortOrder": 0 + }, + "typeName": "RenderLayer" + }, + { + "properties": { + "enabled": true, + "instanceCount": { + "annotations": [ + { + "properties": { + "max": 20, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "materials": { + "order": [ + "material" + ], + "properties": { + "material": { + "order": [ + "material", + "private", + "options", + "uniforms" + ], + "properties": { + "material": { + "typeName": "Material", + "value": "383b0dab-8d10-4d96-b17e-f0144d268263" + }, + "options": { + "annotations": [ + { + "properties": { + "name": "Options" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "properties": { + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } + }, + "typeName": "BlendOptions::DisplayNameAnnotation" + }, + "private": { + "annotations": [ + { + "properties": { + "name": "Private Material" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "typeName": "Bool::DisplayNameAnnotation", + "value": true + }, + "uniforms": { + "order": [ + "u_Tex" + ], + "properties": { + "u_Tex": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation", + "value": null + } + }, + "typeName": "Table" + } + }, + "typeName": "Table" + } + } + }, + "mesh": "a11461f9-239e-4fb5-8a4e-aa55cd177039", + "objectID": "122d0f90-2dea-4ddd-95f5-d537f5381a3e", + "objectName": "meshnode_no_tex", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "MeshNode" + }, + { + "properties": { + "anisotropy": { + "annotations": [ + { + "properties": { + "max": 32000, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "format": 4, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "magSamplingMethod": 0, + "minSamplingMethod": 0, + "objectID": "16718bb0-058f-4b13-8105-68d98bf23a9f", + "objectName": "RenderBuffer", + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "wrapUMode": 0, + "wrapVMode": 0 + }, + "typeName": "RenderBuffer" + }, + { + "properties": { + "objectID": "323d3539-5667-4b0e-b009-a324a9d35247", + "objectName": "mat_with_tex", + "options": { + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } + }, + "uniforms": { + "order": [ + "u_Tex" + ], + "properties": { + "u_Tex": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation", + "value": null + } + } + }, + "uriDefines": "", + "uriFragment": "../../../../../raco-oss-ref/datamodel/libCore/tests/testData/simple_texture.frag", + "uriGeometry": "", + "uriVertex": "../../../../../raco-oss-ref/datamodel/libCore/tests/testData/simple_texture.vert" + }, + "typeName": "Material" + }, + { + "properties": { + "objectID": "383b0dab-8d10-4d96-b17e-f0144d268263", + "objectName": "mat_no_tex", + "options": { + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } + }, + "uniforms": { + "order": [ + "u_Tex" + ], + "properties": { + "u_Tex": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation", + "value": null + } + } + }, + "uriDefines": "", + "uriFragment": "../../../../../raco-oss-ref/datamodel/libCore/tests/testData/simple_texture.frag", + "uriGeometry": "", + "uriVertex": "../../../../../raco-oss-ref/datamodel/libCore/tests/testData/simple_texture.vert" + }, + "typeName": "Material" + }, + { + "properties": { + "enabled": true, + "instanceCount": { + "annotations": [ + { + "properties": { + "max": 20, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "materials": { + "order": [ + "material" + ], + "properties": { + "material": { + "order": [ + "material", + "private", + "options", + "uniforms" + ], + "properties": { + "material": { + "typeName": "Material", + "value": "383b0dab-8d10-4d96-b17e-f0144d268263" + }, + "options": { + "annotations": [ + { + "properties": { + "name": "Options" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "properties": { + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } + }, + "typeName": "BlendOptions::DisplayNameAnnotation" + }, + "private": { + "annotations": [ + { + "properties": { + "name": "Private Material" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "typeName": "Bool::DisplayNameAnnotation", + "value": true + }, + "uniforms": { + "order": [ + "u_Tex" + ], + "properties": { + "u_Tex": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation", + "value": null + } + }, + "typeName": "Table" + } + }, + "typeName": "Table" + } + } + }, + "mesh": "a11461f9-239e-4fb5-8a4e-aa55cd177039", + "objectID": "3ccf4fe2-660d-40e8-84f9-eb4a932c87ca", + "objectName": "meshnode_with_tex", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "MeshNode" + }, + { + "properties": { + "anisotropy": { + "annotations": [ + { + "properties": { + "max": 32000, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "generateMipmaps": false, + "level2uriBack": "", + "level2uriBottom": "", + "level2uriFront": "", + "level2uriLeft": "", + "level2uriRight": "", + "level2uriTop": "", + "level3uriBack": "", + "level3uriBottom": "", + "level3uriFront": "", + "level3uriLeft": "", + "level3uriRight": "", + "level3uriTop": "", + "level4uriBack": "", + "level4uriBottom": "", + "level4uriFront": "", + "level4uriLeft": "", + "level4uriRight": "", + "level4uriTop": "", + "magSamplingMethod": 0, + "minSamplingMethod": 0, + "mipmapLevel": { + "annotations": [ + { + "properties": { + "max": 4, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "objectID": "410631d1-cb7f-40c9-88c7-3bb1515d5caa", + "objectName": "CubeMap", + "textureFormat": 5, + "uriBack": "", + "uriBottom": "", + "uriFront": "", + "uriLeft": "", + "uriRight": "", + "uriTop": "", + "wrapUMode": 0, + "wrapVMode": 0 + }, + "typeName": "CubeMap" + }, + { + "properties": { + "materialFilterMode": 0, + "objectID": "4ba33009-0575-4128-bbbe-48e3ebc6e6ad", + "objectName": "RenderLayerManual", + "renderableTags": { + "order": [ + "main" + ], + "properties": { + "main": { + "annotations": [ + { + "properties": { + "featureLevel": 3 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::LinkEndAnnotation", + "value": 0 + } + } + }, + "sortOrder": 0 + }, + "typeName": "RenderLayer" + }, + { + "properties": { + "destinationX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "destinationY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "enabled": true, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "objectID": "76759483-55f2-45e4-bcdc-bb59d7e9d481", + "objectName": "BlitPass", + "renderOrder": 0, + "sourceRenderBuffer": null, + "sourceRenderBufferMS": null, + "sourceX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "sourceY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "targetRenderBuffer": null, + "targetRenderBufferMS": null, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + } + }, + "typeName": "BlitPass" + }, + { + "properties": { + "inputs": { + "ticker_us": "0" + }, + "objectID": "9c2eeeea-cef0-42a5-9815-d32d38ccfd60", + "objectName": "Timer", + "outputs": { + "ticker_us": "5782355188" + } + }, + "typeName": "Timer" + }, + { + "properties": { + "bakeMeshes": true, + "materialNames": { + "properties": [ + { + "typeName": "String", + "value": "material" + } + ] + }, + "meshIndex": 0, + "metaData": { + "order": [ + "meshInfo" + ], + "properties": { + "meshInfo": { + "annotations": [ + { + "typeName": "ReadOnlyAnnotation" + } + ], + "order": [ + "triangles", + "vertices" + ], + "properties": { + "triangles": { + "typeName": "Int", + "value": 4212 + }, + "vertices": { + "typeName": "Int", + "value": 2399 + } + }, + "typeName": "Table::ReadOnlyAnnotation" + } + } + }, + "objectID": "a11461f9-239e-4fb5-8a4e-aa55cd177039", + "objectName": "Mesh", + "uri": "../../../../../raco-oss-ref/datamodel/libCore/tests/testData/duck.glb" + }, + "typeName": "Mesh" + }, + { + "properties": { + "materialFilterMode": 0, + "objectID": "b9826309-15d0-425b-8ca7-431dc9b6964e", + "objectName": "RenderLayerSceneGraph", + "sortOrder": 1 + }, + "typeName": "RenderLayer" + }, + { + "properties": { + "magSamplingMethod": 0, + "minSamplingMethod": 0, + "objectID": "d14f0900-fcb0-4222-bda6-e475629d30fe", + "objectName": "TextureExternal" + }, + "typeName": "TextureExternal" + }, + { + "properties": { + "animationIndex": 0, + "objectID": "d23a0d37-3a25-46f2-8a64-92f1a8a4b925", + "objectName": "AnimationChannel", + "samplerIndex": 0, + "uri": "" + }, + "typeName": "AnimationChannel" + }, + { + "properties": { + "camera": null, + "node": null, + "objectID": "dbc922bf-9012-47ce-8d53-5b48aa897c50", + "objectName": "AnchorPoint", + "outputs": { + "depth": 0, + "viewportCoords": { + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + } + } + }, + "typeName": "AnchorPoint" + }, + { + "properties": { + "format": 4, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "objectID": "dc208dbd-5bc6-4bb0-b4f5-6710c82dd65c", + "objectName": "RenderBufferMS", + "sampleCount": { + "annotations": [ + { + "properties": { + "max": 8, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + } + }, + "typeName": "RenderBufferMS" + }, + { + "properties": { + "camera": null, + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layers": [ + null, + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "f9550c5f-edd9-431c-8713-5709ef2d625d", + "objectName": "RenderPass", + "renderOnce": true, + "renderOrder": 1, + "target": null + }, + "typeName": "RenderPass" + }, + { + "properties": { + "buffers": [ + null, + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "fcba6ccf-ecf9-4a28-834e-fca6c4768b1d", + "objectName": "RenderTargetMS" + }, + "typeName": "RenderTargetMS" + } + ], + "links": [ + ], + "logicEngineVersion": [ + 1, + 4, + 2 + ], + "racoVersion": [ + 1, + 10, + 0 + ], + "ramsesVersion": [ + 27, + 0, + 130 + ], + "structPropMap": { + "AnchorPointOutputs": { + "depth": "Double::DisplayNameAnnotation::LinkStartAnnotation", + "viewportCoords": "Vec2f::DisplayNameAnnotation::LinkStartAnnotation" + }, + "BlendOptions": { + "blendColor": "Vec4f::DisplayNameAnnotation", + "blendFactorDestAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorDestColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorSrcAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorSrcColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendOperationAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendOperationColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "colorWriteMask": "ColorWriteMask::DisplayNameAnnotation", + "cullmode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "depthFunction": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "depthwrite": "Bool::DisplayNameAnnotation", + "scissorOptions": "ScissorOptions::DisplayNameAnnotation", + "stencilOptions": "StencilOptions::DisplayNameAnnotation" + }, + "CameraViewport": { + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "offsetX": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "offsetY": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation" + }, + "ColorWriteMask": { + "alpha": "Bool::DisplayNameAnnotation", + "blue": "Bool::DisplayNameAnnotation", + "green": "Bool::DisplayNameAnnotation", + "red": "Bool::DisplayNameAnnotation" + }, + "DefaultResourceDirectories": { + "imageSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "interfaceSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "meshSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "scriptSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "shaderSubdirectory": "String::DisplayNameAnnotation::URIAnnotation" + }, + "LuaStandardModuleSelection": { + "base": "Bool::DisplayNameAnnotation", + "debug": "Bool::DisplayNameAnnotation", + "math": "Bool::DisplayNameAnnotation", + "string": "Bool::DisplayNameAnnotation", + "table": "Bool::DisplayNameAnnotation" + }, + "OrthographicFrustum": { + "bottomPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "farPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "leftPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "nearPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "rightPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "topPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation" + }, + "ScissorOptions": { + "scissorEnable": "Bool::DisplayNameAnnotation", + "scissorRegion": "CameraViewport::DisplayNameAnnotation" + }, + "StencilOptions": { + "stencilFunc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilMask": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "stencilOpDepthFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpDepthSucc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpStencilFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilRef": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "TimerInput": { + "ticker_us": "Int64::DisplayNameAnnotation::LinkEndAnnotation" + }, + "TimerOutput": { + "ticker_us": "Int64::DisplayNameAnnotation::LinkStartAnnotation" + }, + "Vec2f": { + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec2i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "Vec3f": { + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "z": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec3i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i3": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "Vec4f": { + "w": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "z": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec4i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i3": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i4": "Int::DisplayNameAnnotation::RangeAnnotationInt" + } + }, + "userTypePropMap": { + "AnchorPoint": { + "camera": "BaseCamera::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "node": "Node::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "AnchorPointOutputs::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Animation": { + "animationChannels": "Array[AnimationChannel]::DisplayNameAnnotation::ResizableArray", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "Table::DisplayNameAnnotation", + "progress": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "AnimationChannel": { + "animationIndex": "Int::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "samplerIndex": "Int::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "BlitPass": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "destinationX": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "destinationY": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "enabled": "Bool::DisplayNameAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderOrder": "Int::DisplayNameAnnotation", + "sourceRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "sourceRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "sourceX": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "sourceY": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "targetRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "targetRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" + }, + "CubeMap": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "generateMipmaps": "Bool::DisplayNameAnnotation", + "level2uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "LuaInterface": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "inputs": "Table::DisplayNameAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation::FeatureLevel", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation::FeatureLevel", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "LuaScript": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "inputs": "Table::DisplayNameAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "Table::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "LuaScriptModule": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Material": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "options": "BlendOptions::DisplayNameAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "uniforms": "Table::DisplayNameAnnotation", + "uriDefines": "String::URIAnnotation::DisplayNameAnnotation", + "uriFragment": "String::URIAnnotation::DisplayNameAnnotation", + "uriGeometry": "String::URIAnnotation::DisplayNameAnnotation", + "uriVertex": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Mesh": { + "bakeMeshes": "Bool::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "materialNames": "Table::ArraySemanticAnnotation::HiddenProperty", + "meshIndex": "Int::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "MeshNode": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "instanceCount": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "materials": "Table::DisplayNameAnnotation", + "mesh": "Mesh::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "Node": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "OrthographicCamera": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "frustum": "OrthographicFrustum::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "PerspectiveCamera": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "frustum": "Table::DisplayNameAnnotation::LinkEndAnnotation", + "frustumType": "Int::DisplayNameAnnotation::EnumerationAnnotation::FeatureLevel", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "Prefab": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "PrefabInstance": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "template": "Prefab::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "ProjectSettings": { + "backgroundColor": "Vec4f::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "defaultResourceFolders": "DefaultResourceDirectories::DisplayNameAnnotation", + "featureLevel": "Int::DisplayNameAnnotation::ReadOnlyAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "saveAsZip": "Bool::DisplayNameAnnotation", + "sceneId": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "viewport": "Vec2i::DisplayNameAnnotation" + }, + "RenderBuffer": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "RenderBufferMS": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "sampleCount": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" + }, + "RenderLayer": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "materialFilterMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "materialFilterTags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderableTags": "Table::RenderableTagContainerAnnotation::DisplayNameAnnotation", + "sortOrder": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderPass": { + "camera": "BaseCamera::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "clearColor": "Vec4f::DisplayNameAnnotation::LinkEndAnnotation", + "enableClearColor": "Bool::DisplayNameAnnotation", + "enableClearDepth": "Bool::DisplayNameAnnotation", + "enableClearStencil": "Bool::DisplayNameAnnotation", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "layers": "Array[RenderLayer]::DisplayNameAnnotation::EmptyReferenceAllowable::ResizableArray", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderOnce": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "renderOrder": "Int::DisplayNameAnnotation::LinkEndAnnotation", + "target": "RenderTargetBase::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderTarget": { + "buffers": "Array[RenderBuffer]::DisplayNameAnnotation::EmptyReferenceAllowable::ResizableArray", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderTargetMS": { + "buffers": "Array[RenderBufferMS]::DisplayNameAnnotation::EmptyReferenceAllowable::ResizableArray", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Skin": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "joints": "Array[Node]::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "skinIndex": "Int::DisplayNameAnnotation", + "targets": "Array[MeshNode]::DisplayNameAnnotation::ResizableArray", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Texture": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "flipTexture": "Bool::DisplayNameAnnotation", + "generateMipmaps": "Bool::DisplayNameAnnotation", + "level2uri": "String::URIAnnotation::DisplayNameAnnotation", + "level3uri": "String::URIAnnotation::DisplayNameAnnotation", + "level4uri": "String::URIAnnotation::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "TextureExternal": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Timer": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "inputs": "TimerInput::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "TimerOutput::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + } + } +} diff --git a/datamodel/libCore/tests/migrationTestData/scripts/interface-using-module.lua b/datamodel/libCore/tests/migrationTestData/scripts/interface-using-module.lua new file mode 100644 index 00000000..ea7bed7d --- /dev/null +++ b/datamodel/libCore/tests/migrationTestData/scripts/interface-using-module.lua @@ -0,0 +1,5 @@ +modules("coalas") + +function interface(INOUT) + INOUT.coala = coalas.getStruct() +end diff --git a/datamodel/libCore/tests/migrationTestData/scripts/moduleDefinition.lua b/datamodel/libCore/tests/migrationTestData/scripts/moduleDefinition.lua new file mode 100644 index 00000000..7ca9613a --- /dev/null +++ b/datamodel/libCore/tests/migrationTestData/scripts/moduleDefinition.lua @@ -0,0 +1,26 @@ +local coalaModule = {} + +coalaModule.coalaChief = "Alfred" + +coalaModule.coalaStruct = { + preferredFood = Type:String(), + weight = Type:Int32() +} + +function coalaModule.getStruct() + return { + preferredFood = Type:String(), + weight = Type:Int32() + } +end + +coalaModule.value = { + preferredFood = "eucalypt", + weight = 42 +} + +function coalaModule.bark() + print("Coalas don't bark...") +end + +return coalaModule \ No newline at end of file diff --git a/datamodel/libCore/tests/migrationTestData/scripts/script-using-module.lua b/datamodel/libCore/tests/migrationTestData/scripts/script-using-module.lua new file mode 100644 index 00000000..8bd68398 --- /dev/null +++ b/datamodel/libCore/tests/migrationTestData/scripts/script-using-module.lua @@ -0,0 +1,10 @@ +modules("coalas") + +function interface(IN,OUT) + IN.coala = coalas.getStruct() + OUT.coala = coalas.getStruct() +end + +function run(IN,OUT) + OUT.coala = IN.coala +end diff --git a/datamodel/libCore/tests/migrationTestData/version-current.rca b/datamodel/libCore/tests/migrationTestData/version-current.rca index c5c27eb5..6ca5fc1d 100644 --- a/datamodel/libCore/tests/migrationTestData/version-current.rca +++ b/datamodel/libCore/tests/migrationTestData/version-current.rca @@ -1,8 +1,8 @@ { "externalProjects": { }, - "featureLevel": 5, - "fileVersion": 54, + "featureLevel": 1, + "fileVersion": 2001, "instances": [ { "properties": { @@ -13,326 +13,367 @@ }, { "properties": { - "objectID": "04ada1c4-7e3a-4f9e-983d-4724a073cad8", - "objectName": "LuaScriptModule", - "stdModules": { - "base": true, - "debug": true, - "math": true, - "string": true, - "table": true + "enabled": true, + "frustum": { + "bottomPlane": { + "annotations": [ + { + "properties": { + "max": 0, + "min": -1000 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": -10 + }, + "farPlane": { + "annotations": [ + { + "properties": { + "max": 10000, + "min": 100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1000 + }, + "leftPlane": { + "annotations": [ + { + "properties": { + "max": 0, + "min": -1000 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": -10 + }, + "nearPlane": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0.1 + }, + "rightPlane": { + "annotations": [ + { + "properties": { + "max": 1000, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 10 + }, + "topPlane": { + "annotations": [ + { + "properties": { + "max": 1000, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 10 + } }, - "uri": "" + "objectID": "2bf34d57-3ad1-48a4-ac27-ace003f55167", + "objectName": "OrthographicCamera", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "viewport": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + }, + "visibility": true }, - "typeName": "LuaScriptModule" - }, - { - "properties": { - "buffer0": null, - "buffer1": null, - "buffer2": null, - "buffer3": null, - "buffer4": null, - "buffer5": null, - "buffer6": null, - "buffer7": null, - "bufferMS0": null, - "bufferMS1": null, - "bufferMS2": null, - "bufferMS3": null, - "bufferMS4": null, - "bufferMS5": null, - "bufferMS6": null, - "bufferMS7": null, - "objectID": "077b744c-c82d-467d-a406-4fca3603ae8a", - "objectName": "RenderTarget" - }, - "typeName": "RenderTarget" - }, - { - "properties": { - "anisotropy": { - "annotations": [ - { - "properties": { - "max": 32000, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 - }, - "flipTexture": false, - "generateMipmaps": false, - "level2uri": "", - "level3uri": "", - "level4uri": "", - "magSamplingMethod": 0, - "minSamplingMethod": 0, - "mipmapLevel": { - "annotations": [ - { - "properties": { - "max": 4, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 - }, - "objectID": "0d2c96e3-0ed2-4f95-ac54-03b9fa81e963", - "objectName": "Texture", - "textureFormat": 5, - "uri": "", - "wrapUMode": 0, - "wrapVMode": 0 - }, - "typeName": "Texture" - }, - { - "properties": { - "materialFilterMode": 0, - "objectID": "0e55bd9c-7f72-4afe-bfa8-64cdfd59cb8d", - "objectName": "RenderLayerOptimized", - "sortOrder": 0 - }, - "typeName": "RenderLayer" + "typeName": "OrthographicCamera" }, { "properties": { "enabled": true, - "instanceCount": { - "annotations": [ - { - "properties": { - "max": 20, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 - }, - "materials": { + "frustum": { "order": [ - "material" + "nearPlane", + "farPlane", + "fieldOfView", + "aspectRatio" ], "properties": { - "material": { - "order": [ - "material", - "private", - "options", - "uniforms" - ], - "properties": { - "material": { - "typeName": "Material", - "value": "383b0dab-8d10-4d96-b17e-f0144d268263" + "aspectRatio": { + "annotations": [ + { + "properties": { + "name": "aspectRatio" + }, + "typeName": "DisplayNameAnnotation" }, - "options": { - "annotations": [ - { - "properties": { - "name": "Options" - }, - "typeName": "DisplayNameAnnotation" - } - ], + { "properties": { - "blendColor": { - "w": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "x": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "blendFactorDestAlpha": 1, - "blendFactorDestColor": 3, - "blendFactorSrcAlpha": 1, - "blendFactorSrcColor": 2, - "blendOperationAlpha": 0, - "blendOperationColor": 0, - "colorWriteMask": { - "alpha": true, - "blue": true, - "green": true, - "red": true - }, - "cullmode": 2, - "depthFunction": 4, - "depthwrite": true, - "scissorOptions": { - "scissorEnable": false, - "scissorRegion": { - "height": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 720 - }, - "offsetX": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": -7680 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 0 - }, - "offsetY": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": -7680 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 0 - }, - "width": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1440 - } - } - }, - "stencilOptions": { - "stencilFunc": 0, - "stencilMask": { - "annotations": [ - { - "properties": { - "max": 255, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 255 - }, - "stencilOpDepthFail": 0, - "stencilOpDepthSucc": 0, - "stencilOpStencilFail": 0, - "stencilRef": { - "annotations": [ - { - "properties": { - "max": 255, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 - } - } + "max": 4, + "min": 0.5 }, - "typeName": "BlendOptions::DisplayNameAnnotation" + "typeName": "RangeAnnotationDouble" }, - "private": { - "annotations": [ - { - "properties": { - "name": "Private Material" - }, - "typeName": "DisplayNameAnnotation" - } - ], - "typeName": "Bool::DisplayNameAnnotation", - "value": true + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 2 + }, + "farPlane": { + "annotations": [ + { + "properties": { + "name": "farPlane" + }, + "typeName": "DisplayNameAnnotation" }, - "uniforms": { - "order": [ - "u_Tex" - ], + { "properties": { - "u_Tex": { - "annotations": [ - { - "properties": { - "engineType": 15 - }, - "typeName": "EngineTypeAnnotation" - } - ], - "typeName": "TextureSampler2DBase::EngineTypeAnnotation", - "value": null - } + "max": 10000, + "min": 100 }, - "typeName": "Table" + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" } - }, - "typeName": "Table" + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 1000 + }, + "fieldOfView": { + "annotations": [ + { + "properties": { + "name": "fieldOfView" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 120, + "min": 10 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 35 + }, + "nearPlane": { + "annotations": [ + { + "properties": { + "name": "nearPlane" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 1, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 0.1 } } }, - "mesh": "a11461f9-239e-4fb5-8a4e-aa55cd177039", - "objectID": "122d0f90-2dea-4ddd-95f5-d537f5381a3e", - "objectName": "meshnode_no_tex", + "frustumType": 0, + "objectID": "34d3f7f0-1d2d-4d1d-adc1-4eee283a7b80", + "objectName": "PerspectiveCamera", "rotation": { "x": { "annotations": [ @@ -447,137 +488,217 @@ "value": 0 } }, + "viewport": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + }, "visibility": true }, - "typeName": "MeshNode" + "typeName": "PerspectiveCamera" }, { "properties": { - "anisotropy": { - "annotations": [ - { - "properties": { - "max": 32000, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 - }, - "format": 4, - "height": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 256 + "objectID": "588bfb37-2015-4819-a868-6ed65f986484", + "objectName": "LuaScript", + "stdModules": { + "base": true, + "debug": true, + "math": true, + "string": true, + "table": true }, - "magSamplingMethod": 0, - "minSamplingMethod": 0, - "objectID": "16718bb0-058f-4b13-8105-68d98bf23a9f", - "objectName": "RenderBuffer", - "width": { + "uri": "" + }, + "typeName": "LuaScript" + }, + { + "properties": { + "animationChannels": [ + null, + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "6d1b00fe-912f-4a92-83ce-7d405ac6b989", + "objectName": "Animation", + "progress": { "annotations": [ { "properties": { - "max": 7680, - "min": 1 + "max": 1, + "min": 0 }, - "typeName": "RangeAnnotationInt" + "typeName": "RangeAnnotationDouble" } ], - "value": 256 - }, - "wrapUMode": 0, - "wrapVMode": 0 + "value": 0 + } }, - "typeName": "RenderBuffer" + "typeName": "Animation" }, { "properties": { - "enabled": true, - "frustum": { - "bottomPlane": { + "backgroundColor": { + "w": { "annotations": [ { "properties": { - "max": 0, - "min": -1000 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } ], - "value": -10 + "value": 1 }, - "farPlane": { + "x": { "annotations": [ { "properties": { - "max": 10000, - "min": 100 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } ], - "value": 1000 + "value": 0 }, - "leftPlane": { + "y": { "annotations": [ { "properties": { - "max": 0, - "min": -1000 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } ], - "value": -10 + "value": 0 }, - "nearPlane": { + "z": { "annotations": [ { "properties": { "max": 1, - "min": 0.1 + "min": 0 }, "typeName": "RangeAnnotationDouble" } ], - "value": 0.1 - }, - "rightPlane": { + "value": 0 + } + }, + "defaultResourceFolders": { + "imageSubdirectory": "images", + "interfaceSubdirectory": "interfaces", + "meshSubdirectory": "meshes", + "scriptSubdirectory": "scripts", + "shaderSubdirectory": "shaders" + }, + "featureLevel": 1, + "objectID": "71454add-eb56-4288-9057-825539914bed", + "objectName": "test-offscreen-tex-uniform-migration-material", + "saveAsZip": false, + "sceneId": { + "annotations": [ + { + "properties": { + "max": 1024, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 123 + }, + "viewport": { + "i1": { "annotations": [ { "properties": { - "max": 1000, + "max": 4096, "min": 0 }, - "typeName": "RangeAnnotationDouble" + "typeName": "RangeAnnotationInt" } ], - "value": 10 + "value": 1440 }, - "topPlane": { + "i2": { "annotations": [ { "properties": { - "max": 1000, + "max": 4096, "min": 0 }, - "typeName": "RangeAnnotationDouble" + "typeName": "RangeAnnotationInt" } ], - "value": 10 + "value": 720 } - }, - "objectID": "2bf34d57-3ad1-48a4-ac27-ace003f55167", - "objectName": "OrthographicCamera", + } + }, + "typeName": "ProjectSettings" + }, + { + "properties": { + "children": [ + "122d0f90-2dea-4ddd-95f5-d537f5381a3e", + "3ccf4fe2-660d-40e8-84f9-eb4a932c87ca" + ], + "enabled": true, + "objectID": "8593d288-67a3-4ae1-9c8c-942786ddd1f2", + "objectName": "Node", "rotation": { "x": { "annotations": [ @@ -692,356 +813,477 @@ "value": 0 } }, - "viewport": { - "height": { + "visibility": true + }, + "typeName": "Node" + }, + { + "properties": { + "enabled": true, + "objectID": "9ec70db9-1ec5-4c64-833d-44eb4ad1d495", + "objectName": "PrefabInstance", + "rotation": { + "x": { "annotations": [ { "properties": { - "max": 7680, - "min": 1 + "max": 360, + "min": -360 }, - "typeName": "RangeAnnotationInt" + "typeName": "RangeAnnotationDouble" } ], - "value": 720 + "value": 0 }, - "offsetX": { + "y": { "annotations": [ { "properties": { - "max": 7680, - "min": -7680 + "max": 360, + "min": -360 }, - "typeName": "RangeAnnotationInt" + "typeName": "RangeAnnotationDouble" } ], "value": 0 }, - "offsetY": { + "z": { "annotations": [ { "properties": { - "max": 7680, - "min": -7680 + "max": 360, + "min": -360 }, - "typeName": "RangeAnnotationInt" + "typeName": "RangeAnnotationDouble" } ], "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 }, - "width": { + "y": { "annotations": [ { "properties": { - "max": 7680, - "min": 1 + "max": 100, + "min": 0.1 }, - "typeName": "RangeAnnotationInt" + "typeName": "RangeAnnotationDouble" } ], - "value": 1440 + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "template": null, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 } }, "visibility": true }, - "typeName": "OrthographicCamera" + "typeName": "PrefabInstance" }, { "properties": { - "objectID": "323d3539-5667-4b0e-b009-a324a9d35247", - "objectName": "mat_with_tex", - "options": { - "blendColor": { - "w": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "x": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "blendFactorDestAlpha": 1, - "blendFactorDestColor": 3, - "blendFactorSrcAlpha": 1, - "blendFactorSrcColor": 2, - "blendOperationAlpha": 0, - "blendOperationColor": 0, - "colorWriteMask": { - "alpha": true, - "blue": true, - "green": true, - "red": true - }, - "cullmode": 2, - "depthFunction": 4, - "depthwrite": true, - "scissorOptions": { - "scissorEnable": false, - "scissorRegion": { - "height": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 720 - }, - "offsetX": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": -7680 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 0 - }, - "offsetY": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": -7680 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 0 + "objectID": "cba9dca1-d412-430e-b278-2d11f08107bf", + "objectName": "LuaInterface", + "stdModules": { + "base": true, + "debug": true, + "math": true, + "string": true, + "table": true + }, + "uri": "" + }, + "typeName": "LuaInterface" + }, + { + "properties": { + "objectID": "fdcbf4ea-3802-484b-be53-4b38ec2d5ac3", + "objectName": "Skin", + "skinIndex": 0, + "targets": [ + null + ], + "uri": "" + }, + "typeName": "Skin" + }, + { + "properties": { + "objectID": "04ada1c4-7e3a-4f9e-983d-4724a073cad8", + "objectName": "LuaScriptModule", + "stdModules": { + "base": true, + "debug": true, + "math": true, + "string": true, + "table": true + }, + "uri": "" + }, + "typeName": "LuaScriptModule" + }, + { + "properties": { + "buffers": [ + null, + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "077b744c-c82d-467d-a406-4fca3603ae8a", + "objectName": "RenderTarget" + }, + "typeName": "RenderTarget" + }, + { + "properties": { + "anisotropy": { + "annotations": [ + { + "properties": { + "max": 32000, + "min": 1 }, - "width": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1440 - } - } - }, - "stencilOptions": { - "stencilFunc": 0, - "stencilMask": { - "annotations": [ - { - "properties": { - "max": 255, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 255 - }, - "stencilOpDepthFail": 0, - "stencilOpDepthSucc": 0, - "stencilOpStencilFail": 0, - "stencilRef": { - "annotations": [ - { - "properties": { - "max": 255, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 + "typeName": "RangeAnnotationInt" } - } - }, - "uniforms": { - "order": [ - "u_Tex" ], - "properties": { - "u_Tex": { - "annotations": [ - { - "properties": { - "engineType": 15 - }, - "typeName": "EngineTypeAnnotation" - } - ], - "typeName": "TextureSampler2DBase::EngineTypeAnnotation", - "value": null + "value": 1 + }, + "flipTexture": false, + "generateMipmaps": false, + "level2uri": "", + "level3uri": "", + "level4uri": "", + "magSamplingMethod": 0, + "minSamplingMethod": 0, + "mipmapLevel": { + "annotations": [ + { + "properties": { + "max": 4, + "min": 1 + }, + "typeName": "RangeAnnotationInt" } - } + ], + "value": 1 }, - "uriDefines": "", - "uriFragment": "../../../../../raco-oss-ref/datamodel/libCore/tests/testData/simple_texture.frag", - "uriGeometry": "", - "uriVertex": "../../../../../raco-oss-ref/datamodel/libCore/tests/testData/simple_texture.vert" + "objectID": "0d2c96e3-0ed2-4f95-ac54-03b9fa81e963", + "objectName": "Texture", + "textureFormat": 5, + "uri": "", + "wrapUMode": 0, + "wrapVMode": 0 }, - "typeName": "Material" + "typeName": "Texture" + }, + { + "properties": { + "materialFilterMode": 0, + "objectID": "0e55bd9c-7f72-4afe-bfa8-64cdfd59cb8d", + "objectName": "RenderLayerOptimized", + "sortOrder": 0 + }, + "typeName": "RenderLayer" }, { "properties": { "enabled": true, - "frustum": { + "instanceCount": { + "annotations": [ + { + "properties": { + "max": 20, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "materials": { "order": [ - "nearPlane", - "farPlane", - "fieldOfView", - "aspectRatio" + "material" ], "properties": { - "aspectRatio": { - "annotations": [ - { - "properties": { - "name": "aspectRatio" - }, - "typeName": "DisplayNameAnnotation" - }, - { - "properties": { - "max": 4, - "min": 0.5 - }, - "typeName": "RangeAnnotationDouble" - }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } + "material": { + "order": [ + "material", + "private", + "options", + "uniforms" ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 2 - }, - "farPlane": { - "annotations": [ - { - "properties": { - "name": "farPlane" - }, - "typeName": "DisplayNameAnnotation" - }, - { - "properties": { - "max": 10000, - "min": 100 - }, - "typeName": "RangeAnnotationDouble" + "properties": { + "material": { + "typeName": "Material", + "value": "383b0dab-8d10-4d96-b17e-f0144d268263" }, - { + "options": { + "annotations": [ + { + "properties": { + "name": "Options" + }, + "typeName": "DisplayNameAnnotation" + } + ], "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 1000 - }, - "fieldOfView": { - "annotations": [ - { - "properties": { - "name": "fieldOfView" - }, - "typeName": "DisplayNameAnnotation" - }, - { - "properties": { - "max": 120, - "min": 10 - }, - "typeName": "RangeAnnotationDouble" - }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 35 - }, - "nearPlane": { - "annotations": [ - { - "properties": { - "name": "nearPlane" + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } }, - "typeName": "DisplayNameAnnotation" + "typeName": "BlendOptions::DisplayNameAnnotation" }, - { - "properties": { - "max": 1, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" + "private": { + "annotations": [ + { + "properties": { + "name": "Private Material" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "typeName": "Bool::DisplayNameAnnotation", + "value": true }, - { + "uniforms": { + "order": [ + "u_Tex" + ], "properties": { - "featureLevel": 1 + "u_Tex": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation", + "value": null + } }, - "typeName": "LinkEndAnnotation" + "typeName": "Table" } - ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 0.1 + }, + "typeName": "Table" } } }, - "frustumType": 0, - "objectID": "34d3f7f0-1d2d-4d1d-adc1-4eee283a7b80", - "objectName": "PerspectiveCamera", + "mesh": "a11461f9-239e-4fb5-8a4e-aa55cd177039", + "objectID": "122d0f90-2dea-4ddd-95f5-d537f5381a3e", + "objectName": "meshnode_no_tex", "rotation": { "x": { "annotations": [ @@ -1156,59 +1398,237 @@ "value": 0 } }, - "viewport": { - "height": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 720 - }, - "offsetX": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": -7680 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 0 - }, - "offsetY": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": -7680 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 0 + "visibility": true + }, + "typeName": "MeshNode" + }, + { + "properties": { + "anisotropy": { + "annotations": [ + { + "properties": { + "max": 32000, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "format": 4, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "magSamplingMethod": 0, + "minSamplingMethod": 0, + "objectID": "16718bb0-058f-4b13-8105-68d98bf23a9f", + "objectName": "RenderBuffer", + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "wrapUMode": 0, + "wrapVMode": 0 + }, + "typeName": "RenderBuffer" + }, + { + "properties": { + "objectID": "323d3539-5667-4b0e-b009-a324a9d35247", + "objectName": "mat_with_tex", + "options": { + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } }, - "width": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 } - ], - "value": 1440 + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } } }, - "visibility": true + "uniforms": { + "order": [ + "u_Tex" + ], + "properties": { + "u_Tex": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation", + "value": null + } + } + }, + "uriDefines": "", + "uriFragment": "../../../../../raco-oss-ref/datamodel/libCore/tests/testData/simple_texture.frag", + "uriGeometry": "", + "uriVertex": "../../../../../raco-oss-ref/datamodel/libCore/tests/testData/simple_texture.vert" }, - "typeName": "PerspectiveCamera" + "typeName": "Material" }, { "properties": { @@ -1614,625 +2034,15 @@ } }, "typeName": "Table" - } - }, - "typeName": "Table" - } - } - }, - "mesh": "a11461f9-239e-4fb5-8a4e-aa55cd177039", - "objectID": "3ccf4fe2-660d-40e8-84f9-eb4a932c87ca", - "objectName": "meshnode_with_tex", - "rotation": { - "x": { - "annotations": [ - { - "properties": { - "max": 360, - "min": -360 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 360, - "min": -360 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 360, - "min": -360 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "scaling": { - "x": { - "annotations": [ - { - "properties": { - "max": 100, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 1 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 100, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 1 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 100, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 1 - } - }, - "translation": { - "x": { - "annotations": [ - { - "properties": { - "max": 100, - "min": -100 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 100, - "min": -100 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 100, - "min": -100 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "visibility": true - }, - "typeName": "MeshNode" - }, - { - "properties": { - "anisotropy": { - "annotations": [ - { - "properties": { - "max": 32000, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 - }, - "generateMipmaps": false, - "level2uriBack": "", - "level2uriBottom": "", - "level2uriFront": "", - "level2uriLeft": "", - "level2uriRight": "", - "level2uriTop": "", - "level3uriBack": "", - "level3uriBottom": "", - "level3uriFront": "", - "level3uriLeft": "", - "level3uriRight": "", - "level3uriTop": "", - "level4uriBack": "", - "level4uriBottom": "", - "level4uriFront": "", - "level4uriLeft": "", - "level4uriRight": "", - "level4uriTop": "", - "magSamplingMethod": 0, - "minSamplingMethod": 0, - "mipmapLevel": { - "annotations": [ - { - "properties": { - "max": 4, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 - }, - "objectID": "410631d1-cb7f-40c9-88c7-3bb1515d5caa", - "objectName": "CubeMap", - "textureFormat": 5, - "uriBack": "", - "uriBottom": "", - "uriFront": "", - "uriLeft": "", - "uriRight": "", - "uriTop": "", - "wrapUMode": 0, - "wrapVMode": 0 - }, - "typeName": "CubeMap" - }, - { - "properties": { - "materialFilterMode": 0, - "objectID": "4ba33009-0575-4128-bbbe-48e3ebc6e6ad", - "objectName": "RenderLayerManual", - "sortOrder": 0 - }, - "typeName": "RenderLayer" - }, - { - "properties": { - "objectID": "588bfb37-2015-4819-a868-6ed65f986484", - "objectName": "LuaScript", - "stdModules": { - "base": true, - "debug": true, - "math": true, - "string": true, - "table": true - }, - "uri": "" - }, - "typeName": "LuaScript" - }, - { - "properties": { - "animationChannels": { - "order": [ - "Channel 0", - "Channel 1", - "Channel 2", - "Channel 3", - "Channel 4", - "Channel 5", - "Channel 6", - "Channel 7" - ], - "properties": { - "Channel 0": { - "typeName": "AnimationChannel", - "value": null - }, - "Channel 1": { - "typeName": "AnimationChannel", - "value": null - }, - "Channel 2": { - "typeName": "AnimationChannel", - "value": null - }, - "Channel 3": { - "typeName": "AnimationChannel", - "value": null - }, - "Channel 4": { - "typeName": "AnimationChannel", - "value": null - }, - "Channel 5": { - "typeName": "AnimationChannel", - "value": null - }, - "Channel 6": { - "typeName": "AnimationChannel", - "value": null - }, - "Channel 7": { - "typeName": "AnimationChannel", - "value": null - } - } - }, - "objectID": "6d1b00fe-912f-4a92-83ce-7d405ac6b989", - "objectName": "Animation", - "progress": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "typeName": "Animation" - }, - { - "properties": { - "backgroundColor": { - "w": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 1 - }, - "x": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "defaultResourceFolders": { - "imageSubdirectory": "images", - "interfaceSubdirectory": "interfaces", - "meshSubdirectory": "meshes", - "scriptSubdirectory": "scripts", - "shaderSubdirectory": "shaders" - }, - "featureLevel": 5, - "objectID": "71454add-eb56-4288-9057-825539914bed", - "objectName": "test-offscreen-tex-uniform-migration-material", - "saveAsZip": false, - "sceneId": { - "annotations": [ - { - "properties": { - "max": 1024, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 123 - }, - "viewport": { - "i1": { - "annotations": [ - { - "properties": { - "max": 4096, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1440 - }, - "i2": { - "annotations": [ - { - "properties": { - "max": 4096, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 720 - } - } - }, - "typeName": "ProjectSettings" - }, - { - "properties": { - "destinationX": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 0 - }, - "destinationY": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 0 - }, - "enabled": true, - "height": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 256 - }, - "objectID": "76759483-55f2-45e4-bcdc-bb59d7e9d481", - "objectName": "BlitPass", - "renderOrder": 0, - "sourceRenderBuffer": null, - "sourceRenderBufferMS": null, - "sourceX": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 0 - }, - "sourceY": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 0 - }, - "targetRenderBuffer": null, - "targetRenderBufferMS": null, - "width": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 256 - } - }, - "typeName": "BlitPass" - }, - { - "properties": { - "children": { - "properties": [ - { - "typeName": "Ref", - "value": "122d0f90-2dea-4ddd-95f5-d537f5381a3e" - }, - { - "typeName": "Ref", - "value": "3ccf4fe2-660d-40e8-84f9-eb4a932c87ca" - } - ] - }, - "enabled": true, - "objectID": "8593d288-67a3-4ae1-9c8c-942786ddd1f2", - "objectName": "Node", - "rotation": { - "x": { - "annotations": [ - { - "properties": { - "max": 360, - "min": -360 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 360, - "min": -360 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 360, - "min": -360 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "scaling": { - "x": { - "annotations": [ - { - "properties": { - "max": 100, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 1 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 100, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 1 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 100, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 1 - } - }, - "translation": { - "x": { - "annotations": [ - { - "properties": { - "max": 100, - "min": -100 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 100, - "min": -100 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 100, - "min": -100 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 + } + }, + "typeName": "Table" + } } }, - "visibility": true - }, - "typeName": "Node" - }, - { - "properties": { - "inputs": { - "ticker_us": "0" - }, - "objectID": "9c2eeeea-cef0-42a5-9815-d32d38ccfd60", - "objectName": "Timer", - "outputs": { - "ticker_us": "705447578607" - } - }, - "typeName": "Timer" - }, - { - "properties": { - "enabled": true, - "objectID": "9ec70db9-1ec5-4c64-833d-44eb4ad1d495", - "objectName": "PrefabInstance", + "mesh": "a11461f9-239e-4fb5-8a4e-aa55cd177039", + "objectID": "3ccf4fe2-660d-40e8-84f9-eb4a932c87ca", + "objectName": "meshnode_with_tex", "rotation": { "x": { "annotations": [ @@ -2309,7 +2119,6 @@ "value": 1 } }, - "template": null, "translation": { "x": { "annotations": [ @@ -2350,7 +2159,175 @@ }, "visibility": true }, - "typeName": "PrefabInstance" + "typeName": "MeshNode" + }, + { + "properties": { + "anisotropy": { + "annotations": [ + { + "properties": { + "max": 32000, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "generateMipmaps": false, + "level2uriBack": "", + "level2uriBottom": "", + "level2uriFront": "", + "level2uriLeft": "", + "level2uriRight": "", + "level2uriTop": "", + "level3uriBack": "", + "level3uriBottom": "", + "level3uriFront": "", + "level3uriLeft": "", + "level3uriRight": "", + "level3uriTop": "", + "level4uriBack": "", + "level4uriBottom": "", + "level4uriFront": "", + "level4uriLeft": "", + "level4uriRight": "", + "level4uriTop": "", + "magSamplingMethod": 0, + "minSamplingMethod": 0, + "mipmapLevel": { + "annotations": [ + { + "properties": { + "max": 4, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "objectID": "410631d1-cb7f-40c9-88c7-3bb1515d5caa", + "objectName": "CubeMap", + "textureFormat": 5, + "uriBack": "", + "uriBottom": "", + "uriFront": "", + "uriLeft": "", + "uriRight": "", + "uriTop": "", + "wrapUMode": 0, + "wrapVMode": 0 + }, + "typeName": "CubeMap" + }, + { + "properties": { + "materialFilterMode": 0, + "objectID": "4ba33009-0575-4128-bbbe-48e3ebc6e6ad", + "objectName": "RenderLayerManual", + "sortOrder": 0 + }, + "typeName": "RenderLayer" + }, + { + "properties": { + "destinationX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "destinationY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "enabled": true, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "objectID": "76759483-55f2-45e4-bcdc-bb59d7e9d481", + "objectName": "BlitPass", + "renderOrder": 0, + "sourceRenderBuffer": null, + "sourceRenderBufferMS": null, + "sourceX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "sourceY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "targetRenderBuffer": null, + "targetRenderBufferMS": null, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + } + }, + "typeName": "BlitPass" + }, + { + "properties": { + "inputs": { + "ticker_us": "0" + }, + "objectID": "9c2eeeea-cef0-42a5-9815-d32d38ccfd60", + "objectName": "Timer", + "outputs": { + "ticker_us": "5331962091" + } + }, + "typeName": "Timer" }, { "properties": { @@ -2364,6 +2341,35 @@ ] }, "meshIndex": 0, + "metaData": { + "order": [ + "meshInfo" + ], + "properties": { + "meshInfo": { + "annotations": [ + { + "typeName": "ReadOnlyAnnotation" + } + ], + "order": [ + "triangles", + "vertices" + ], + "properties": { + "triangles": { + "typeName": "Int", + "value": 4212 + }, + "vertices": { + "typeName": "Int", + "value": 2399 + } + }, + "typeName": "Table::ReadOnlyAnnotation" + } + } + }, "objectID": "a11461f9-239e-4fb5-8a4e-aa55cd177039", "objectName": "Mesh", "uri": "../../../../../raco-oss-ref/datamodel/libCore/tests/testData/duck.glb" @@ -2379,21 +2385,6 @@ }, "typeName": "RenderLayer" }, - { - "properties": { - "objectID": "cba9dca1-d412-430e-b278-2d11f08107bf", - "objectName": "LuaInterface", - "stdModules": { - "base": true, - "debug": true, - "math": true, - "string": true, - "table": true - }, - "uri": "" - }, - "typeName": "LuaInterface" - }, { "properties": { "magSamplingMethod": 0, @@ -2552,14 +2543,16 @@ "enableClearDepth": true, "enableClearStencil": true, "enabled": true, - "layer0": null, - "layer1": null, - "layer2": null, - "layer3": null, - "layer4": null, - "layer5": null, - "layer6": null, - "layer7": null, + "layers": [ + null, + null, + null, + null, + null, + null, + null, + null + ], "objectID": "f9550c5f-edd9-431c-8713-5709ef2d625d", "objectName": "RenderPass", "renderOnce": true, @@ -2570,41 +2563,33 @@ }, { "properties": { - "objectID": "fdcbf4ea-3802-484b-be53-4b38ec2d5ac3", - "objectName": "Skin", - "skinIndex": 0, - "targets": { - "order": [ - "target_0" - ], - "properties": { - "target_0": { - "typeName": "MeshNode", - "value": null - } - } - }, - "uri": "" + "buffers": [ + null, + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "fcba6ccf-ecf9-4a28-834e-fca6c4768b1d", + "objectName": "RenderTargetMS" }, - "typeName": "Skin" + "typeName": "RenderTargetMS" } ], "links": [ ], - "logicEngineVersion": [ - 1, - 4, - 2 - ], "racoVersion": [ - 1, - 8, + 2, + 0, 0 ], "ramsesVersion": [ - 27, + 28, 0, - 130 + 0 ], "structPropMap": { "AnchorPointOutputs": { @@ -2712,7 +2697,8 @@ "userTypePropMap": { "AnchorPoint": { "camera": "BaseCamera::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "node": "Node::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", @@ -2720,8 +2706,9 @@ "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Animation": { - "animationChannels": "Table::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "animationChannels": "Array[AnimationChannel]::DisplayNameAnnotation::ResizableArray", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "outputs": "Table::DisplayNameAnnotation", @@ -2730,7 +2717,8 @@ }, "AnimationChannel": { "animationIndex": "Int::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "samplerIndex": "Int::DisplayNameAnnotation", @@ -2738,11 +2726,12 @@ "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "BlitPass": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "destinationX": "Int::RangeAnnotationInt::DisplayNameAnnotation", "destinationY": "Int::RangeAnnotationInt::DisplayNameAnnotation", "enabled": "Bool::DisplayNameAnnotation", "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "renderOrder": "Int::DisplayNameAnnotation", @@ -2757,7 +2746,7 @@ }, "CubeMap": { "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "generateMipmaps": "Bool::DisplayNameAnnotation", "level2uriBack": "String::URIAnnotation::DisplayNameAnnotation", "level2uriBottom": "String::URIAnnotation::DisplayNameAnnotation", @@ -2778,6 +2767,7 @@ "level4uriRight": "String::URIAnnotation::DisplayNameAnnotation", "level4uriTop": "String::URIAnnotation::DisplayNameAnnotation", "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", "objectID": "String::HiddenProperty", @@ -2794,19 +2784,21 @@ "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" }, "LuaInterface": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "inputs": "Table::DisplayNameAnnotation::LinkStartAnnotation::LinkEndAnnotation", - "luaModules": "Table::DisplayNameAnnotation::FeatureLevel", + "luaModules": "Table::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation::FeatureLevel", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", "uri": "String::URIAnnotation::DisplayNameAnnotation", "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "LuaScript": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "inputs": "Table::DisplayNameAnnotation::LinkEndAnnotation", "luaModules": "Table::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "outputs": "Table::DisplayNameAnnotation", @@ -2815,7 +2807,8 @@ "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "LuaScriptModule": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", @@ -2823,7 +2816,8 @@ "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Material": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "options": "BlendOptions::DisplayNameAnnotation", @@ -2837,20 +2831,22 @@ }, "Mesh": { "bakeMeshes": "Bool::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "materialNames": "Table::ArraySemanticAnnotation::HiddenProperty", "meshIndex": "Int::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "uri": "String::URIAnnotation::DisplayNameAnnotation", "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "MeshNode": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", "instanceCount": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", "materials": "Table::DisplayNameAnnotation", "mesh": "Mesh::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", @@ -2861,8 +2857,9 @@ "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "Node": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", @@ -2873,9 +2870,10 @@ "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "OrthographicCamera": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", "frustum": "OrthographicFrustum::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", @@ -2887,10 +2885,11 @@ "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "PerspectiveCamera": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", "frustum": "Table::DisplayNameAnnotation::LinkEndAnnotation", - "frustumType": "Int::DisplayNameAnnotation::EnumerationAnnotation::FeatureLevel", + "frustumType": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", @@ -2902,14 +2901,16 @@ "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "Prefab": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "PrefabInstance": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", @@ -2922,22 +2923,22 @@ }, "ProjectSettings": { "backgroundColor": "Vec4f::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "defaultResourceFolders": "DefaultResourceDirectories::DisplayNameAnnotation", "featureLevel": "Int::DisplayNameAnnotation::ReadOnlyAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "saveAsZip": "Bool::DisplayNameAnnotation", "sceneId": "Int::DisplayNameAnnotation::RangeAnnotationInt", - "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "viewport": "Vec2i::DisplayNameAnnotation" }, "RenderBuffer": { "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", @@ -2947,9 +2948,10 @@ "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" }, "RenderBufferMS": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "sampleCount": "Int::RangeAnnotationInt::DisplayNameAnnotation", @@ -2957,9 +2959,10 @@ "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" }, "RenderLayer": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "materialFilterMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "materialFilterTags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "renderableTags": "Table::RenderableTagContainerAnnotation::DisplayNameAnnotation", @@ -2969,68 +2972,58 @@ }, "RenderPass": { "camera": "BaseCamera::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "clearColor": "Vec4f::DisplayNameAnnotation::LinkEndAnnotation", "enableClearColor": "Bool::DisplayNameAnnotation", "enableClearDepth": "Bool::DisplayNameAnnotation", "enableClearStencil": "Bool::DisplayNameAnnotation", "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", - "layer0": "RenderLayer::DisplayNameAnnotation", - "layer1": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer2": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer3": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer4": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer5": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer6": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer7": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layers": "Array[RenderLayer]::DisplayNameAnnotation::EmptyReferenceAllowable::ResizableArray", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "renderOnce": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "renderOnce": "Bool::DisplayNameAnnotation::LinkEndAnnotation", "renderOrder": "Int::DisplayNameAnnotation::LinkEndAnnotation", - "target": "RenderTarget::DisplayNameAnnotation::EmptyReferenceAllowable", + "target": "RenderTargetBase::DisplayNameAnnotation::EmptyReferenceAllowable", "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "RenderTarget": { - "buffer0": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer1": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer2": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer3": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer4": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer5": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer6": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer7": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS0": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS1": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS2": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS3": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS4": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS5": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS6": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS7": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "buffers": "Array[RenderBuffer]::DisplayNameAnnotation::EmptyReferenceAllowable::ResizableArray", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderTargetMS": { + "buffers": "Array[RenderBufferMS]::DisplayNameAnnotation::EmptyReferenceAllowable::ResizableArray", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Skin": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "joints": "Table::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "joints": "Array[Node]::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "skinIndex": "Int::DisplayNameAnnotation", - "targets": "Table::DisplayNameAnnotation", + "targets": "Array[MeshNode]::DisplayNameAnnotation::ResizableArray", "uri": "String::URIAnnotation::DisplayNameAnnotation", "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Texture": { "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "flipTexture": "Bool::DisplayNameAnnotation", "generateMipmaps": "Bool::DisplayNameAnnotation", "level2uri": "String::URIAnnotation::DisplayNameAnnotation", "level3uri": "String::URIAnnotation::DisplayNameAnnotation", "level4uri": "String::URIAnnotation::DisplayNameAnnotation", "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", "objectID": "String::HiddenProperty", @@ -3042,16 +3035,18 @@ "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" }, "TextureExternal": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Timer": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "inputs": "TimerInput::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "outputs": "TimerOutput::DisplayNameAnnotation", diff --git a/datamodel/libCore/tests/testData/basic.frag b/datamodel/libCore/tests/testData/basic.frag new file mode 100644 index 00000000..eab524cf --- /dev/null +++ b/datamodel/libCore/tests/testData/basic.frag @@ -0,0 +1,11 @@ + +#version 300 es +precision mediump float; + +out vec4 FragColor; + +uniform vec3 u_color; + +void main() { + FragColor = vec4(u_color.r, u_color.g, u_color.b, 1.0); +} diff --git a/datamodel/libCore/tests/testData/basic.vert b/datamodel/libCore/tests/testData/basic.vert new file mode 100644 index 00000000..a624d05f --- /dev/null +++ b/datamodel/libCore/tests/testData/basic.vert @@ -0,0 +1,10 @@ + +#version 300 es +precision mediump float; +in vec3 a_Position; + +uniform mat4 u_MVPMatrix; +void main() { + float offset = float(gl_InstanceID) * 0.2; + gl_Position = u_MVPMatrix * vec4(a_Position.x + offset, a_Position.yz, 1.0); +} diff --git a/datamodel/libCore/tests/testData/cube.gltf b/datamodel/libCore/tests/testData/cube.gltf new file mode 100644 index 00000000..00c82774 --- /dev/null +++ b/datamodel/libCore/tests/testData/cube.gltf @@ -0,0 +1,166 @@ +{ + "asset" : { + "generator" : "Khronos glTF Blender I/O v1.6.16", + "version" : "2.0" + }, + "scene" : 0, + "scenes" : [ + { + "name" : "Scene", + "nodes" : [ + 0, + 1, + 2 + ] + } + ], + "nodes" : [ + { + "mesh" : 0, + "name" : "Cube", + "rotation" : [ + 0.398443341255188, + 0.15567483007907867, + -0.06882311403751373, + 0.9012611508369446 + ] + }, + { + "name" : "Light", + "rotation" : [ + 0.16907575726509094, + 0.27217137813568115, + 0.7558803558349609, + 0.570947527885437 + ], + "translation" : [ + 4.076245307922363, + 1.0054539442062378, + 5.903861999511719 + ] + }, + { + "camera" : 0, + "name" : "Camera", + "rotation" : [ + 0.483536034822464, + 0.20870360732078552, + 0.33687159419059753, + 0.7804827094078064 + ], + "translation" : [ + 7.358891487121582, + -6.925790786743164, + 4.958309173583984 + ] + } + ], + "cameras" : [ + { + "name" : "Camera", + "perspective" : { + "aspectRatio" : 1.7777777777777777, + "yfov" : 0.39959652046304894, + "zfar" : 100, + "znear" : 0.10000000149011612 + }, + "type" : "perspective" + } + ], + "materials" : [ + { + "doubleSided" : true, + "name" : "Material", + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1 + ], + "metallicFactor" : 0, + "roughnessFactor" : 0.4000000059604645 + } + } + ], + "meshes" : [ + { + "name" : "Cube", + "primitives" : [ + { + "attributes" : { + "POSITION" : 0, + "NORMAL" : 1, + "TEXCOORD_0" : 2 + }, + "indices" : 3, + "material" : 0 + } + ] + } + ], + "accessors" : [ + { + "bufferView" : 0, + "componentType" : 5126, + "count" : 24, + "max" : [ + 1, + 1, + 1 + ], + "min" : [ + -1, + -1, + -1 + ], + "type" : "VEC3" + }, + { + "bufferView" : 1, + "componentType" : 5126, + "count" : 24, + "type" : "VEC3" + }, + { + "bufferView" : 2, + "componentType" : 5126, + "count" : 24, + "type" : "VEC2" + }, + { + "bufferView" : 3, + "componentType" : 5123, + "count" : 36, + "type" : "SCALAR" + } + ], + "bufferViews" : [ + { + "buffer" : 0, + "byteLength" : 288, + "byteOffset" : 0 + }, + { + "buffer" : 0, + "byteLength" : 288, + "byteOffset" : 288 + }, + { + "buffer" : 0, + "byteLength" : 192, + "byteOffset" : 576 + }, + { + "buffer" : 0, + "byteLength" : 72, + "byteOffset" : 768 + } + ], + "buffers" : [ + { + "byteLength" : 840, + "uri" : "data:application/octet-stream;base64,AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIC/AACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AACAvwAAAAAAAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIC/AAAgPwAAAD8AACA/AAAAPwAAID8AAAA/AADAPgAAAD8AAMA+AAAAPwAAwD4AAAA/AAAgPwAAgD4AACA/AACAPgAAID8AAIA+AADAPgAAgD4AAMA+AACAPgAAwD4AAIA+AAAgPwAAQD8AAGA/AAAAPwAAID8AAEA/AADAPgAAQD8AAAA+AAAAPwAAwD4AAEA/AAAgPwAAgD8AACA/AAAAAAAAYD8AAIA+AADAPgAAgD8AAMA+AAAAAAAAAD4AAIA+AAANABQAAAAUAAcACQAGABMACQATABYAFQASAAwAFQAMAA8AEAADAAoAEAAKABcABQACAAgABQAIAAsAEQAOAAEAEQABAAQA" + } + ] +} diff --git a/datamodel/libDataStorage/CMakeLists.txt b/datamodel/libDataStorage/CMakeLists.txt index 7a4d86af..a9fcb745 100644 --- a/datamodel/libDataStorage/CMakeLists.txt +++ b/datamodel/libDataStorage/CMakeLists.txt @@ -10,6 +10,7 @@ If a copy of the MPL was not distributed with this file, You can obtain one at h add_library(libDataStorage include/data_storage/AnnotationBase.h + include/data_storage/Array.h src/Array.cpp include/data_storage/ReflectionInterface.h src/ReflectionInterface.cpp include/data_storage/Table.h src/Table.cpp include/data_storage/Value.h src/Value.cpp diff --git a/datamodel/libDataStorage/include/data_storage/Array.h b/datamodel/libDataStorage/include/data_storage/Array.h new file mode 100644 index 00000000..6a4f32bd --- /dev/null +++ b/datamodel/libDataStorage/include/data_storage/Array.h @@ -0,0 +1,296 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "ReflectionInterface.h" +#include "Value.h" + +#include +#include +#include +#include + +namespace raco::data_storage { + +// Base class for all Array types +class ArrayBase : public ReflectionInterface { +public: + static inline const TypeDescriptor typeDescription = {"Array", false}; + TypeDescriptor const& getTypeDescription() const override { + return typeDescription; + } + bool serializationRequired() const override { + return true; + } + + virtual std::string typeName() const = 0; + + virtual PrimitiveType elementType() const = 0; + + virtual std::string elementTypeName() const = 0; + + // Create and insert property of statically known element type into array before the insertion_index + // or at the end if insertion_index = -1 + virtual ValueBase* addProperty(int index_before = -1) = 0; + + // Insert user-created property before the insertion_index or at the end if insertion_index = -1. + // Will check if the type of the property is identical to the array element type and throw exception if not. + virtual ValueBase* addProperty(ValueBase* property, int index_before = -1) = 0; + + // Insert user-created property before the insertion_index or at the end if insertion_index = -1. + // Will check if the type of the property is identical to the array element type and throw exception if not. + virtual ValueBase* addProperty(std::unique_ptr&& property, int index_before = -1) = 0; + + virtual void resize(size_t newSize) = 0; + + virtual void removeProperty(size_t index) = 0; + +protected: + void growPropertyNames(size_t requestedSize) const { + if (requestedSize > propNames_.size()) { + auto oldSize = propNames_.size(); + size_t newSize = std::max(2 * oldSize, requestedSize); + propNames_.resize(newSize); + for (size_t index = oldSize; index < propNames_.size(); index++) { + propNames_[index] = std::to_string(index + 1); + } + } + } + + static std::vector propNames_; +}; + +// Concrete Array type with statically known element type +// - elements are of type Value +template +class Array : public ArrayBase { +public: + Array() = default; + + Array(const Array& other, std::function* translateRef = nullptr) { + for (auto const& item : other.elements_) { + addProperty(item->staticClone(translateRef)); + } + } + + Array& operator=(const Array& value) { + elements_.clear(); + for (auto const& item : value.elements_) { + addProperty(item->staticClone(nullptr)); + } + return *this; + } + + static std::string staticTypeName() { + return "Array[" + Value::staticTypeName() + "]"; + } + + /// + /// ReflectionInterface interface implementation: + /// + + Value* get(std::string_view propertyName) override { + int index; + auto [ptr, error] = std::from_chars(propertyName.data(), propertyName.data() + propertyName.size(), index); + if (error == std::errc() && ptr == propertyName.data() + propertyName.size() && index > 0) { + return get(index - 1); + } + throw std::out_of_range("Array::get: property doesn't exist."); + } + + // Note: the return type is more specific than the overriden ReflectionInterface function + Value* get(size_t index) override { + if (index < elements_.size()) { + return elements_[index].get(); + } + throw std::out_of_range("Array::name: index out of range"); + } + + const Value* get(std::string_view propertyName) const override { + int index; + auto [ptr, error] = std::from_chars(propertyName.data(), propertyName.data() + propertyName.size(), index); + if (error == std::errc() && ptr == propertyName.data() + propertyName.size() && index > 0) { + return get(index - 1); + } + throw std::out_of_range("Array::get: property doesn't exist."); + } + + // Note: the return type is more specific than the overriden ReflectionInterface function + const Value* get(size_t index) const override { + if (index < elements_.size()) { + return elements_[index].get(); + } + throw std::out_of_range("Array::name: index out of range"); + } + + size_t size() const override { + return elements_.size(); + } + + int index(std::string_view propertyName) const override { + int index; + auto [ptr, error] = std::from_chars(propertyName.data(), propertyName.data() + propertyName.size(), index); + if (error == std::errc() && ptr == propertyName.data() + propertyName.size() && index > 0) { + return index - 1; + } + return -1; + } + + const std::string& name(size_t index) const override { + if (index >= elements_.size()) { + throw std::out_of_range("Array::name: index out of range"); + } + growPropertyNames(index + 1); + return propNames_[index]; + } + + /// + /// ArrayBase interface implementation: + /// + + std::string typeName() const override { + return staticTypeName(); + } + + PrimitiveType elementType() const override { + return Value::staticType(); + } + + std::string elementTypeName() const override { + return Value::staticTypeName(); + } + + Value* addProperty(int index_before = -1) override { + if (index_before < -1 || index_before > static_cast(elements_.size())) { + throw std::out_of_range("Array::addProperty: index out of range"); + } + + if (index_before == -1) { + return elements_.emplace_back(std::unique_ptr>(new Value())).get(); + } + return elements_.insert(elements_.begin() + index_before, std::unique_ptr>(new Value()))->get(); + } + + Value* addProperty(ValueBase* property, int index_before = -1) override { + auto* vp = dynamic_cast*>(property); + if (!vp) { + throw std::runtime_error("Array::addProperty: type mismatch"); + } + + if (index_before < -1 || index_before > static_cast(elements_.size())) { + throw std::out_of_range("Array::addProperty: index out of range"); + } + + if (index_before == -1) { + return elements_.emplace_back(std::unique_ptr>(vp)).get(); + } + return elements_.insert(elements_.begin() + index_before, std::unique_ptr>(vp))->get(); + } + + Value* addProperty(std::unique_ptr>&& property, int index_before = -1) { + if (index_before < -1 || index_before > static_cast(elements_.size())) { + throw std::out_of_range("Array::addProperty: index out of range"); + } + + if (index_before == -1) { + return elements_.emplace_back(std::move(property)).get(); + } + return elements_.insert(elements_.begin() + index_before, std::move(property))->get(); + } + + ValueBase* addProperty(std::unique_ptr&& property, int index_before = -1) override { + auto* vp = dynamic_cast*>(property.release()); + if (!vp) { + throw std::runtime_error("Array::addProperty: type mismatch"); + } + + if (index_before < -1 || index_before > static_cast(elements_.size())) { + throw std::out_of_range("Array::addProperty: index out of range"); + } + + if (index_before == -1) { + return elements_.emplace_back(std::unique_ptr>(vp)).get(); + } + return elements_.insert(elements_.begin() + index_before, std::unique_ptr>(vp))->get(); + } + + void resize(size_t newSize) override { + if (newSize < 0) { + throw std::out_of_range("Array::resize: negative size not allowed"); + } + auto oldSize = elements_.size(); + elements_.resize(newSize); + for (size_t index = oldSize; index < elements_.size(); index++) { + elements_[index] = std::make_unique>(); + } + } + + void removeProperty(size_t index) override { + if (index >= static_cast(elements_.size())) { + throw std::out_of_range("Array::removeProperty: index out of range"); + } + elements_.erase(elements_.begin() + index); + } + + void copyAnnotationData(const Array& other) { + if (elements_.size() != other.elements_.size()) { + throw std::runtime_error("Array::copyAnnotationData: array size mismatch"); + } + for (size_t index = 0; index < elements_.size(); index++) { + elements_[index]->copyAnnotationData(*other.elements_[index].get()); + } + } + + template + typename std::enable_if::value, std::vector>::type + asVector() const { + std::vector result; + for (size_t index = 0; index < elements_.size(); index++) { + result.emplace_back(**elements_[index]); + } + return result; + } + + void set(const std::vector& data) { + resize(data.size()); + for (size_t index = 0; index < data.size(); index++) { + *elements_[index] = data[index]; + } + } + + bool compare(std::vector const& array) const { + if (elements_.size() != array.size()) { + return false; + } + for (size_t index = 0; index < elements_.size(); index++) { + if (**elements_[index] != array[index]) { + return false; + } + } + return true; + } + + bool compare(const Array& other) const { + if (elements_.size() != other.elements_.size()) { + return false; + } + for (size_t index = 0; index < elements_.size(); index++) { + if (**elements_[index] != **other.elements_[index]) { + return false; + } + } + return true; + } + +private: + std::vector>> elements_; +}; + +} // namespace raco::data_storage \ No newline at end of file diff --git a/datamodel/libDataStorage/include/data_storage/ReflectionInterface.h b/datamodel/libDataStorage/include/data_storage/ReflectionInterface.h index e9945398..86787ef8 100644 --- a/datamodel/libDataStorage/include/data_storage/ReflectionInterface.h +++ b/datamodel/libDataStorage/include/data_storage/ReflectionInterface.h @@ -22,7 +22,7 @@ using SCEditorObject = std::shared_ptr; namespace raco::data_storage { -//using raco::core::EditorObject; +//using core::EditorObject; using core::SEditorObject; class ValueBase; @@ -62,31 +62,31 @@ class ReflectionInterface { return getTypeDescription().typeName; } - // Find property by name; returns nullptr if not found - virtual ValueBase* get(std::string const& propertyName) = 0; + // Find property by name; throws std::out_of_range if not found + virtual ValueBase* get(std::string_view propertyName) = 0; - // Find property by index; return nullptr if index out of bounds + // Find property by index; throws std::out_of_range if index out of bounds virtual ValueBase* get(size_t index) = 0; - virtual const ValueBase* get(std::string const& propertyName) const = 0; + virtual const ValueBase* get(std::string_view propertyName) const = 0; virtual const ValueBase* get(size_t index) const = 0; - ValueBase* operator[](std::string const& propertyName); + ValueBase* operator[](std::string_view propertyName); ValueBase* operator[](size_t index); - const ValueBase* operator[](std::string const& propertyName) const; + const ValueBase* operator[](std::string_view propertyName) const; const ValueBase* operator[](size_t index) const; virtual size_t size() const = 0; // Find index from property name; return -1 if not found - virtual int index(std::string const& propertyName) const = 0; + virtual int index(std::string_view propertyName) const = 0; - // Find name from index; asserts when index out of bounds + // Find name from index; throws std::out_of_range when index out of bounds virtual const std::string& name(size_t index) const = 0; - bool hasProperty(std::string const& propertyName) const; + bool hasProperty(std::string_view propertyName) const; // Compare the value but not the annotation data bool operator==(const ReflectionInterface& other) const; @@ -104,15 +104,15 @@ class ClassWithReflectedMembers : public ReflectionInterface { ClassWithReflectedMembers(std::vector>&& properties = {}) : properties_(std::move(properties)) {} - virtual ValueBase* get(std::string const& propertyName) override; + virtual ValueBase* get(std::string_view propertyName) override; virtual ValueBase* get(size_t index) override; - virtual const ValueBase* get(std::string const& propertyName) const override; + virtual const ValueBase* get(std::string_view propertyName) const override; virtual const ValueBase* get(size_t index) const override; virtual size_t size() const override; - virtual int index(std::string const& propertyName) const override; + virtual int index(std::string_view propertyName) const override; virtual const std::string& name(size_t index) const override; template @@ -139,8 +139,8 @@ class ClassWithReflectedMembers : public ReflectionInterface { return nullptr; } - std::shared_ptr query(const std::string& typeName); - std::shared_ptr query(const std::string& typeName) const; + std::shared_ptr query(std::string_view typeName); + std::shared_ptr query(std::string_view typeName) const; void addAnnotation(std::shared_ptr annotation); diff --git a/datamodel/libDataStorage/include/data_storage/Table.h b/datamodel/libDataStorage/include/data_storage/Table.h index f3b30c42..7952ee71 100644 --- a/datamodel/libDataStorage/include/data_storage/Table.h +++ b/datamodel/libDataStorage/include/data_storage/Table.h @@ -33,15 +33,15 @@ class Table : public ReflectionInterface { // Performs deep copy of all property values of the argument Table(const Table&, std::function* translateRef = nullptr); - virtual ValueBase* get(std::string const& propertyName) override; + virtual ValueBase* get(std::string_view propertyName) override; virtual ValueBase* get(size_t index) override; - virtual const ValueBase* get(std::string const& propertyName) const override; + virtual const ValueBase* get(std::string_view propertyName) const override; virtual const ValueBase* get(size_t index) const override; virtual size_t size() const override; - virtual int index(std::string const& propertyName) const override; + virtual int index(std::string_view propertyName) const override; virtual const std::string& name(size_t index) const override; @@ -51,13 +51,13 @@ class Table : public ReflectionInterface { // can add and remove array entries / named properties // Add named property at the end of the property list. - ValueBase *addProperty(std::string const &name, PrimitiveType type); + ValueBase *addProperty(std::string_view name, PrimitiveType type); // Add user-created property; Table will take over ownership of object. - ValueBase* addProperty(std::string const& name, ValueBase* property, int index_before = -1); + ValueBase* addProperty(std::string_view name, ValueBase* property, int index_before = -1); // Add user-created property; Table will take over ownership of object. - ValueBase* addProperty(const std::string& name, std::unique_ptr&& property, int index_before = -1); + ValueBase* addProperty(std::string_view name, std::unique_ptr&& property, int index_before = -1); // Insert new property at specified position into the property list. // If index_before = -1 the property is appended, otherwise it will be insert before the @@ -67,12 +67,12 @@ class Table : public ReflectionInterface { ValueBase* addProperty(std::unique_ptr&& property, int index_before = -1); void removeProperty(size_t index); - void removeProperty(std::string const& propertyName); + void removeProperty(std::string_view propertyName); - void renameProperty(const std::string& oldName, const std::string& newName); + void renameProperty(std::string_view oldName, std::string_view newName); void replaceProperty(size_t index, ValueBase* property); - void replaceProperty(const std::string& name, ValueBase* property); + void replaceProperty(std::string_view name, ValueBase* property); void swapProperties(size_t index_1, size_t index_2); diff --git a/datamodel/libDataStorage/include/data_storage/Value.h b/datamodel/libDataStorage/include/data_storage/Value.h index 87acab34..ad518cf1 100644 --- a/datamodel/libDataStorage/include/data_storage/Value.h +++ b/datamodel/libDataStorage/include/data_storage/Value.h @@ -9,6 +9,7 @@ */ #pragma once +#include #include #include #include @@ -24,13 +25,15 @@ using SEditorObject = std::shared_ptr; namespace raco::data_storage { -using raco::core::EditorObject; -using raco::core::SEditorObject; +using core::EditorObject; +using core::SEditorObject; class AnnotationBase; class Table; +class ArrayBase; + enum class PrimitiveType { // Simple scalar types: Bool = 0, @@ -42,11 +45,20 @@ enum class PrimitiveType { // References: hold a std::shared_ptr where T is EditorObject or a subclass Ref, - // Dictionary-like: holds a Table + // Dictionary-like container + // - holds a Table + // - dynamic properties (can add/remove properties) with heterogeneous types Table, - // Complex C++ class types; must be class derived from StructBase - Struct + // Complex C++ class types + // - holds a class derived from StructBase + // - static properties with heterogeneous types + Struct, + + // Variable-length containers with elements of uniform and statically known type + // - holds an Array class (derived from ArrayBase) + // - dynamic properties (can add/remove elements) with homogeneous types + Array }; // For the datatypes Int, Int64 and Double we define extreme values which are allowed in our data model. @@ -95,6 +107,8 @@ constexpr PrimitiveType primitiveType() { return PrimitiveType::Table; } else if constexpr (std::is_base_of::value) { return PrimitiveType::Struct; + } else if constexpr (std::is_base_of::value) { + return PrimitiveType::Array; } else if constexpr (std::is_base_of::value) { return PrimitiveType::Ref; } else { @@ -209,6 +223,16 @@ class ValueBase { // Identical types are dynamically enforced as runtime. virtual void setStruct(const StructBase&) = 0; + // Get reference to generic base class for Array type values + virtual ArrayBase& asArray() = 0; + virtual const ArrayBase& asArray() const = 0; + + // Set Array type value. + // Matching of element types if enforced at runtime. + // Clears array and fills it with clones of the source array elements. + virtual void setArray(const ArrayBase&) = 0; + + // Check for equality of the actual classes of the arguments; // differs from comparing the PrimitiveType by // - Value differs from Property @@ -291,28 +315,32 @@ class Value : public ValueBase { Value(T const& val) : ValueBase(), value_(val) {} Value(const Value& other, std::function* translateRef) : ValueBase(), value_(*other, translateRef) {} - virtual PrimitiveType type() const override; - virtual std::string baseTypeName() const override { + static PrimitiveType staticType() { + return primitiveType(); + } + PrimitiveType type() const override { + return staticType(); + } + + static std::string staticTypeName() { if constexpr (std::is_same::value) { return getTypeName(primitiveType()); } else if constexpr (std::is_convertible>::value) { return T::element_type::typeDescription.typeName; } else if constexpr (primitiveType() == PrimitiveType::Struct) { return T::typeDescription.typeName; + } else if constexpr (primitiveType() == PrimitiveType::Array) { + return T::staticTypeName(); } else { return getTypeName(primitiveType()); } } + + virtual std::string baseTypeName() const override { + return staticTypeName(); + } virtual std::string typeName() const override { - if constexpr (std::is_same::value) { - return getTypeName(primitiveType()); - } else if constexpr (std::is_convertible>::value) { - return T::element_type::typeDescription.typeName; - } else if constexpr (primitiveType() == PrimitiveType::Struct) { - return T::typeDescription.typeName; - } else { - return getTypeName(primitiveType()); - } + return Value::staticTypeName(); } ValueBase& operator=(const ValueBase& other) override { @@ -320,6 +348,8 @@ class Value : public ValueBase { setRef(other.asRef()); } else if constexpr (primitiveType() == PrimitiveType::Struct) { setStruct(other.asStruct()); + } else if constexpr (primitiveType() == PrimitiveType::Array) { + setArray(other.asArray()); } else { value_ = other.as(); } @@ -344,6 +374,11 @@ class Value : public ValueBase { setStruct(other.asStruct()); return true; } + } else if constexpr (primitiveType() == PrimitiveType::Array) { + if (!(value_ == other.asArray())) { + setArray(other.asArray()); + return true; + } } else { if (!(value_ == other.as())) { value_ = other.as(); @@ -359,10 +394,12 @@ class Value : public ValueBase { return value_ == other.asRef(); } else if constexpr (primitiveType() == PrimitiveType::Struct) { const T* vp = dynamic_cast(&other.asStruct()); - if (!vp) { - throw std::runtime_error("type mismatch"); - } + assert(vp != nullptr); // we aleady made the classesEqual check above so this can't happen return value_ == *vp; + } else if constexpr (primitiveType() == PrimitiveType::Array) { + const T* vp = dynamic_cast(&other.asArray()); + assert(vp != nullptr); // we aleady made the classesEqual check above so this can't happen + return value_ == *vp; } else { return value_ == other.as(); } @@ -377,12 +414,14 @@ class Value : public ValueBase { return translatedValue == other.asRef(); } else if constexpr (primitiveType() == PrimitiveType::Struct) { const T* vp = dynamic_cast(&other.asStruct()); - if (!vp) { - throw std::runtime_error("type mismatch"); - } + assert(vp != nullptr); // we aleady made the classesEqual check above so this can't happen return ReflectionInterface::compare(value_, *vp, translateRef); } else if constexpr (primitiveType() == PrimitiveType::Table) { return ReflectionInterface::compare(value_, other.as(), translateRef); + } else if constexpr (primitiveType() == PrimitiveType::Array) { + const T* vp = dynamic_cast(&other.asArray()); + assert(vp != nullptr); // we aleady made the classesEqual check above so this can't happen + return ReflectionInterface::compare(value_, *vp, translateRef); } else { return value_ == other.as(); } @@ -397,6 +436,12 @@ class Value : public ValueBase { throw std::runtime_error("type mismatch"); } value_.copyAnnotationData(*vp); + } else if constexpr (primitiveType() == PrimitiveType::Array) { + const T* vp = dynamic_cast(&src.asArray()); + if (!vp) { + throw std::runtime_error("type mismatch"); + } + value_.copyAnnotationData(*vp); } else if constexpr (!std::is_convertible::value) { // The Vec2f,... types may have annotations nested inside, so we need to copy them too: primitiveCopyAnnotationData(value_, src.as()); @@ -491,6 +536,28 @@ class Value : public ValueBase { } } + virtual ArrayBase& asArray() override { + if constexpr (primitiveType() == PrimitiveType::Array) { + return value_; + } + throw std::runtime_error("type mismatch"); + } + virtual const ArrayBase& asArray() const override { + if constexpr (primitiveType() == PrimitiveType::Array) { + return value_; + } + throw std::runtime_error("type mismatch"); + } + virtual void setArray(const ArrayBase& newValue) override { + if constexpr (primitiveType() == PrimitiveType::Array) { + const T* vp = dynamic_cast(&newValue); + if (!vp) { + throw std::runtime_error("type mismatch"); + } + value_ = *vp; + } + } + virtual bool canSetRef(SEditorObject v) const override { if constexpr (std::is_same::value) { return true; @@ -533,23 +600,31 @@ class Value : public ValueBase { return asImplConst(); } - virtual std::unique_ptr clone(std::function* translateRef) const { + Value* cloneHelper(std::function* translateRef) const { if constexpr (std::is_same::value) { if (translateRef) { - return std::make_unique((*translateRef)(**this)); + return new Value((*translateRef)(**this)); } - return std::make_unique(*this); + return new Value(*this); } else if constexpr (std::is_convertible::value) { if (translateRef) { auto p = std::dynamic_pointer_cast((*translateRef)(**this)); - return std::make_unique(p); + return new Value(p); } - return std::make_unique(*this); + return new Value(*this); } else { - return std::make_unique(*this, translateRef); + return new Value(*this, translateRef); } } + virtual std::unique_ptr clone(std::function* translateRef) const { + return std::unique_ptr(cloneHelper(translateRef)); + } + + std::unique_ptr staticClone(std::function* translateRef) const { + return std::unique_ptr(cloneHelper(translateRef)); + } + private: template U& asImpl(); @@ -560,10 +635,6 @@ class Value : public ValueBase { T value_; }; -template -PrimitiveType Value::type() const { - return primitiveType(); -} template template diff --git a/datamodel/libDataStorage/src/Array.cpp b/datamodel/libDataStorage/src/Array.cpp new file mode 100644 index 00000000..7201d3b8 --- /dev/null +++ b/datamodel/libDataStorage/src/Array.cpp @@ -0,0 +1,16 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#include "data_storage/Array.h" + +namespace raco::data_storage { + +std::vector ArrayBase::propNames_; + +} diff --git a/datamodel/libDataStorage/src/ReflectionInterface.cpp b/datamodel/libDataStorage/src/ReflectionInterface.cpp index ddcd9f12..d28794e4 100644 --- a/datamodel/libDataStorage/src/ReflectionInterface.cpp +++ b/datamodel/libDataStorage/src/ReflectionInterface.cpp @@ -13,11 +13,10 @@ #include #include -#include namespace raco::data_storage { -ValueBase* ReflectionInterface::operator[](std::string const& propertyName) +ValueBase* ReflectionInterface::operator[](std::string_view propertyName) { return get(propertyName); } @@ -27,7 +26,7 @@ ValueBase* ReflectionInterface::operator[](size_t index) return get(index); } -const ValueBase* ReflectionInterface::operator[](std::string const& propertyName) const { +const ValueBase* ReflectionInterface::operator[](std::string_view propertyName) const { return get(propertyName); } @@ -35,7 +34,7 @@ const ValueBase* ReflectionInterface::operator[](size_t index) const { return get(index); } -ValueBase* ClassWithReflectedMembers::get(std::string const& propertyName) { +ValueBase* ClassWithReflectedMembers::get(std::string_view propertyName) { auto it = std::find_if(properties_.begin(), properties_.end(), [&propertyName](auto const& item) { return item.first == propertyName; @@ -43,17 +42,17 @@ ValueBase* ClassWithReflectedMembers::get(std::string const& propertyName) { if (it != properties_.end()) { return it->second; } - return nullptr; + throw std::out_of_range("ClassWithReflectedMembers::get: property doesn't exist."); } ValueBase* ClassWithReflectedMembers::get(size_t index) { if (index < properties_.size()) { return properties_[index].second; } - return nullptr; + throw std::out_of_range("ClassWithReflectedMembers::get: index out of range."); } -const ValueBase* ClassWithReflectedMembers::get(std::string const& propertyName) const { +const ValueBase* ClassWithReflectedMembers::get(std::string_view propertyName) const { auto it = std::find_if(properties_.begin(), properties_.end(), [&propertyName](auto const& item) { return item.first == propertyName; @@ -61,21 +60,21 @@ const ValueBase* ClassWithReflectedMembers::get(std::string const& propertyName) if (it != properties_.end()) { return it->second; } - return nullptr; + throw std::out_of_range("ClassWithReflectedMembers::get: property doesn't exist."); } const ValueBase* ClassWithReflectedMembers::get(size_t index) const { if (index < properties_.size()) { return properties_[index].second; } - return nullptr; + throw std::out_of_range("ClassWithReflectedMembers::get: index out of range."); } size_t ClassWithReflectedMembers::size() const { return properties_.size(); } -int ClassWithReflectedMembers::index(std::string const& propertyName) const { +int ClassWithReflectedMembers::index(std::string_view propertyName) const { auto it = std::find_if(properties_.begin(), properties_.end(), [&propertyName](auto const& item) { return item.first == propertyName; @@ -87,11 +86,13 @@ int ClassWithReflectedMembers::index(std::string const& propertyName) const { } const std::string& ClassWithReflectedMembers::name(size_t index) const { - assert(index < properties_.size()); + if (index >= properties_.size()) { + throw std::out_of_range("ClassWithReflectedMembers::name: index out of range"); + } return properties_[index].first; } -bool ReflectionInterface::hasProperty(std::string const& propertyName) const { +bool ReflectionInterface::hasProperty(std::string_view propertyName) const { return index(propertyName) != -1; } @@ -127,7 +128,7 @@ bool ReflectionInterface::compare(const ReflectionInterface& left, const Reflect } -std::shared_ptr ClassWithReflectedMembers::query(const std::string& typeName) { +std::shared_ptr ClassWithReflectedMembers::query(std::string_view typeName) { for (auto anno : annotations_ ) { if (anno->serializationTypeName() == typeName) { return anno; @@ -136,7 +137,7 @@ std::shared_ptr ClassWithReflectedMembers::query(const std::stri return nullptr; } -std::shared_ptr ClassWithReflectedMembers::query(const std::string& typeName) const { +std::shared_ptr ClassWithReflectedMembers::query(std::string_view typeName) const { for (auto anno : annotations_) { if (anno->serializationTypeName() == typeName) { return anno; diff --git a/datamodel/libDataStorage/src/Table.cpp b/datamodel/libDataStorage/src/Table.cpp index 51b19a0a..79347723 100644 --- a/datamodel/libDataStorage/src/Table.cpp +++ b/datamodel/libDataStorage/src/Table.cpp @@ -11,7 +11,6 @@ #include "data_storage/Value.h" #include -#include #include namespace raco::data_storage { @@ -22,7 +21,7 @@ Table::Table(const Table& other, std::function* tr } } -ValueBase* Table::get(std::string const& propertyName) { +ValueBase* Table::get(std::string_view propertyName) { auto it = std::find_if(properties_.begin(), properties_.end(), [&propertyName](auto const& item) { return item.first == propertyName; @@ -30,17 +29,17 @@ ValueBase* Table::get(std::string const& propertyName) { if (it != properties_.end()) { return it->second.get(); } - return nullptr; + throw std::out_of_range("Table::get: property doesn't exist."); } ValueBase* Table::get(size_t index) { if (index < properties_.size()) { return properties_[index].second.get(); } - return nullptr; + throw std::out_of_range("Table::name: index out of range"); } -const ValueBase* Table::get(std::string const& propertyName) const { +const ValueBase* Table::get(std::string_view propertyName) const { auto it = std::find_if(properties_.begin(), properties_.end(), [&propertyName](auto const& item) { return item.first == propertyName; @@ -48,14 +47,14 @@ const ValueBase* Table::get(std::string const& propertyName) const { if (it != properties_.end()) { return it->second.get(); } - return nullptr; + throw std::out_of_range("Table::get: property doesn't exist."); } const ValueBase* Table::get(size_t index) const { if (index < properties_.size()) { return properties_[index].second.get(); } - return nullptr; + throw std::out_of_range("Table::name: index out of range"); } @@ -64,11 +63,13 @@ size_t Table::size() const { } const std::string& Table::name(size_t index) const { - assert(index < properties_.size()); + if (index >= properties_.size()) { + throw std::out_of_range("Table::name: index out of range"); + } return properties_[index].first; } -int Table::index(std::string const& propertyName) const { +int Table::index(std::string_view propertyName) const { auto it = std::find_if(properties_.begin(), properties_.end(), [&propertyName](auto const& item) { return item.first == propertyName; @@ -80,37 +81,43 @@ int Table::index(std::string const& propertyName) const { } -ValueBase *Table::addProperty(std::string const &name, PrimitiveType type) +ValueBase *Table::addProperty(std::string_view name, PrimitiveType type) { properties_.emplace_back(std::make_pair(name, ValueBase::create(type))); return properties_.back().second.get(); } -ValueBase* Table::addProperty(std::string const& name, ValueBase* property, int index_before) { - assert(index_before >= -1 && index_before <= static_cast(properties_.size())); +ValueBase* Table::addProperty(std::string_view name, ValueBase* property, int index_before) { + if (index_before < -1 || index_before > static_cast(properties_.size())) { + throw std::out_of_range("Table::addProperty: index out of range"); + } if (index_before == -1) { properties_.emplace_back(std::make_pair(name, std::unique_ptr(property))); return properties_.back().second.get(); } - return properties_.insert(properties_.begin() + index_before, std::make_pair(name, std::unique_ptr(property)))->second.get(); + return properties_.insert(properties_.begin() + index_before, std::make_pair(std::string(name), std::unique_ptr(property)))->second.get(); } -ValueBase* Table::addProperty(const std::string& name, std::unique_ptr&& property, int index_before) { - assert(index_before >= -1 && index_before <= static_cast(properties_.size())); +ValueBase* Table::addProperty(std::string_view name, std::unique_ptr&& property, int index_before) { + if (index_before < -1 || index_before > static_cast(properties_.size())) { + throw std::out_of_range("Table::addProperty: index out of range"); + } if (index_before == -1) { properties_.emplace_back(std::make_pair(name, std::move(property))); return properties_.back().second.get(); } - return properties_.insert(properties_.begin() + index_before, std::make_pair(name, std::move(property)))->second.get(); + return properties_.insert(properties_.begin() + index_before, std::make_pair(std::string(name), std::move(property)))->second.get(); } ValueBase* Table::addProperty(PrimitiveType type, int index_before) { - assert(index_before >= -1 && index_before <= static_cast(properties_.size())); + if (index_before < -1 || index_before > static_cast(properties_.size())) { + throw std::out_of_range("Table::addProperty: index out of range"); + } if (index_before == -1) { properties_.emplace_back(std::make_pair(std::string(), ValueBase::create(type))); @@ -125,7 +132,9 @@ ValueBase* Table::addProperty(ValueBase* property, int index_before) { } ValueBase* Table::addProperty(std::unique_ptr&& property, int index_before) { - assert(index_before >= -1 && index_before <= static_cast(properties_.size())); + if (index_before < -1 || index_before > static_cast(properties_.size())) { + throw std::out_of_range("Table::addProperty: index out of range"); + } if (index_before == -1) { properties_.emplace_back(std::make_pair(std::string(), std::move(property))); @@ -136,18 +145,20 @@ ValueBase* Table::addProperty(std::unique_ptr&& property, int index_b } void Table::removeProperty(size_t index) { - assert(index < properties_.size()); + if (index >= properties_.size()) { + throw std::out_of_range("Table::name: index out of range"); + } properties_.erase(properties_.begin() + index); } -void Table::removeProperty(std::string const &propertyName) { +void Table::removeProperty(std::string_view propertyName) { int ind = index(propertyName); if (ind != -1) { removeProperty(ind); } } -void Table::renameProperty(const std::string& oldName, const std::string& newName) { +void Table::renameProperty(std::string_view oldName, std::string_view newName) { auto it = std::find_if(properties_.begin(), properties_.end(), [&oldName](auto const& item) { return item.first == oldName; @@ -163,7 +174,7 @@ void Table::replaceProperty(size_t index, ValueBase* property) { } } -void Table::replaceProperty(const std::string& name, ValueBase* property) { +void Table::replaceProperty(std::string_view name, ValueBase* property) { int ind = index(name); if (ind != -1) { replaceProperty(ind, property); diff --git a/datamodel/libDataStorage/src/Value.cpp b/datamodel/libDataStorage/src/Value.cpp index 0de7fa10..4db6b452 100644 --- a/datamodel/libDataStorage/src/Value.cpp +++ b/datamodel/libDataStorage/src/Value.cpp @@ -26,7 +26,8 @@ static std::map& primitiveTypeName() { {PrimitiveType::String, "String"}, {PrimitiveType::Ref, "Ref"}, - {PrimitiveType::Table, "Table"}}; + {PrimitiveType::Table, "Table"}, + {PrimitiveType::Array, "Array"}}; return primitiveTypeNameMap; }; @@ -80,6 +81,10 @@ std::unique_ptr ValueBase::create(PrimitiveType type) { case PrimitiveType::Struct: throw std::runtime_error("ValueBase::create can't create generic Value"); break; + + case PrimitiveType::Array: + throw std::runtime_error("ValueBase::create can't create generic Value"); + break; } return std::unique_ptr(); } diff --git a/datamodel/libDataStorage/tests/CMakeLists.txt b/datamodel/libDataStorage/tests/CMakeLists.txt index 95edf3b5..5a862e2e 100644 --- a/datamodel/libDataStorage/tests/CMakeLists.txt +++ b/datamodel/libDataStorage/tests/CMakeLists.txt @@ -23,5 +23,3 @@ raco_package_add_test( "${TEST_LIBRARIES}" ${CMAKE_CURRENT_BINARY_DIR} ) - -target_link_libraries(libDataStorage_test raco::ramses-logic-lib-client-only) diff --git a/datamodel/libDataStorage/tests/Property_test.cpp b/datamodel/libDataStorage/tests/Property_test.cpp index d7f1788c..357f9a30 100644 --- a/datamodel/libDataStorage/tests/Property_test.cpp +++ b/datamodel/libDataStorage/tests/Property_test.cpp @@ -7,6 +7,7 @@ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "data_storage/Array.h" #include "data_storage/Value.h" #include "data_storage/AnnotationBase.h" @@ -24,7 +25,7 @@ using namespace raco::data_storage; // Duplicate of Dummy class in MockUserTypes.h: // Dedpulicating this would need to create a new cmake library which seem overkill for a single helper class only used once here. -class Dummy: public AnnotationBase { +class Dummy : public AnnotationBase { public: static inline const TypeDescriptor typeDescription = {"Dummy", false}; TypeDescriptor const& getTypeDescription() const override { @@ -42,9 +43,7 @@ class Dummy: public AnnotationBase { return *this; } }; -TEST(PropertyTest, Scalar) -{ - +TEST(PropertyTest, Scalar) { Property bv{false, {}}; Property iv{0, {}}; @@ -62,7 +61,6 @@ TEST(PropertyTest, Scalar) u = 3.0; } - TEST(PropertyTest, Struct) { SimpleStruct s; s.bb = false; @@ -74,6 +72,7 @@ TEST(PropertyTest, Struct) { EXPECT_EQ(vs.type(), PrimitiveType::Struct); EXPECT_EQ(vs.typeName(), "SimpleStruct::Dummy"); + EXPECT_EQ(vs.baseTypeName(), "SimpleStruct"); EXPECT_THROW(vs.asBool(), std::runtime_error); EXPECT_THROW(vs.as(), std::runtime_error); @@ -119,3 +118,44 @@ TEST(PropertyTest, Struct) { EXPECT_TRUE(vs == *vsclone.get()); } + +TEST(PropertyTest, Array) { + Property, Dummy> vad; + + // ValueBase::type + EXPECT_EQ(vad.type(), PrimitiveType::Array); + // Array::elementType + EXPECT_EQ(vad->elementType(), PrimitiveType::Double); + + // Value::baseTypeName + EXPECT_EQ(vad.baseTypeName(), "Array[Double]"); + // Value::typeName + EXPECT_EQ(vad.typeName(), "Array[Double]::Dummy"); + + // Array::typeName + EXPECT_EQ(vad->typeName(), "Array[Double]"); + // Array::elementTypeName + EXPECT_EQ(vad->elementTypeName(), "Double"); +} + +TEST(PropertyTest, ArrayNested) { + Property>, Dummy> vaad; + auto prop1 = vaad->addProperty(); + + EXPECT_EQ(vaad.type(), PrimitiveType::Array); + EXPECT_EQ(vaad->elementType(), PrimitiveType::Array); + + EXPECT_EQ(prop1->type(), PrimitiveType::Array); + EXPECT_EQ((*prop1)->elementType(), PrimitiveType::Double); + + // Value::typeName + EXPECT_EQ(vaad.typeName(), "Array[Array[Double]]::Dummy"); + // Value::baseTypeName + EXPECT_EQ(vaad.baseTypeName(), "Array[Array[Double]]"); + // Array::typeName + EXPECT_EQ(vaad->typeName(), "Array[Array[Double]]"); + // Array::elementTypeName + EXPECT_EQ(vaad->elementTypeName(), "Array[Double]"); + EXPECT_EQ(prop1->typeName(), "Array[Double]"); + EXPECT_EQ((*prop1)->elementTypeName(), "Double"); +} \ No newline at end of file diff --git a/datamodel/libDataStorage/tests/Value_test.cpp b/datamodel/libDataStorage/tests/Value_test.cpp index 3cb10e16..5b349a5b 100644 --- a/datamodel/libDataStorage/tests/Value_test.cpp +++ b/datamodel/libDataStorage/tests/Value_test.cpp @@ -8,6 +8,7 @@ * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "data_storage/Value.h" +#include "data_storage/Array.h" #include "data_storage/Table.h" #include "testing/StructTypes.h" @@ -16,10 +17,7 @@ using namespace raco::data_storage; - - TEST(ValueTest, Scalar) { - Value bv; Value iv; @@ -33,18 +31,14 @@ TEST(ValueTest, Scalar) { EXPECT_THROW(dv.asBool(), std::runtime_error); EXPECT_THROW(dv.as(), std::runtime_error); - Value u; u = 3.0; u = dv; - Value s; - } -TEST(ValueTest, Tables) -{ +TEST(ValueTest, Tables) { Value
tv; EXPECT_EQ(tv->size(), 0); @@ -82,10 +76,9 @@ TEST(ValueTest, Tables) EXPECT_EQ(tv->get("fval")->asDouble(), 2.0); } - TEST(ValueTest, Table_nested_struct) { Value
tv; - + tv->addProperty("struct", std::make_unique>()); EXPECT_EQ((*tv)["struct"]->getSubstructure().get("bool")->asBool(), true); EXPECT_EQ((*tv)["struct"]->getSubstructure().get("double")->asDouble(), 1.5); @@ -93,7 +86,7 @@ TEST(ValueTest, Table_nested_struct) { Value s; s->bb = false; s->dd = 2.0; - + *tv->get("struct") = s; EXPECT_EQ((*tv)["struct"]->getSubstructure().get("bool")->asBool(), false); EXPECT_EQ((*tv)["struct"]->getSubstructure().get("double")->asDouble(), 2.0); @@ -104,9 +97,8 @@ TEST(ValueTest, Table_nested_struct) { EXPECT_EQ((*tu)["struct"]->getSubstructure().get("double")->asDouble(), 2.0); } - TEST(ValueTest, clone) { - Value vint {23}; + Value vint{23}; auto vint_clone = vint.clone(nullptr); EXPECT_EQ(vint_clone->asInt(), *vint); @@ -130,6 +122,7 @@ TEST(ValueTest, Struct) { EXPECT_EQ(vs.type(), PrimitiveType::Struct); EXPECT_EQ(vs.typeName(), "SimpleStruct"); + EXPECT_EQ(vs.baseTypeName(), "SimpleStruct"); EXPECT_THROW(vs.asBool(), std::runtime_error); EXPECT_THROW(vs.as(), std::runtime_error); @@ -179,4 +172,258 @@ TEST(ValueTest, Struct) { auto vsclone = vs.clone(nullptr); EXPECT_TRUE(vs == *vsclone.get()); + + // Value::asArray-> throw + EXPECT_THROW(vs.asArray(), std::runtime_error); } + +TEST(ValueTest, Array) { + Array ad; + *ad.addProperty() = -1.0; + *ad.addProperty() = -2.0; + Array ai; + *ai.addProperty() = 13; + *ai.addProperty() = 17; + + Value> vad; + Value> vai; + const Value>& cvad{vad}; + + // ValueBase::type + EXPECT_EQ(vad.type(), PrimitiveType::Array); + // Array::elementType + EXPECT_EQ(vad->elementType(), PrimitiveType::Double); + + // Value::baseTypeName + EXPECT_EQ(vad.baseTypeName(), "Array[Double]"); + // Value::typeName + EXPECT_EQ(vad.typeName(), "Array[Double]"); + + // Array::typeName + EXPECT_EQ(vad->typeName(), "Array[Double]"); + // Array::elementTypeName + EXPECT_EQ(vad->elementTypeName(), "Double"); + + // Array::addProperty(int index_before) + EXPECT_THROW(vad->addProperty(-2), std::out_of_range); + EXPECT_THROW(vad->addProperty(1), std::out_of_range); + auto prop1 = vad->addProperty(); + auto prop2 = vad->addProperty(-1); + auto prop3 = vad->addProperty(1); + EXPECT_EQ(vad->size(), 3); + + // Array::get(index) + EXPECT_EQ(vad->get(0), prop1); + EXPECT_EQ(vad->get(1), prop3); + EXPECT_EQ(vad->get(2), prop2); + + + // Array::get(index) const + EXPECT_EQ(cvad->get(0), prop1); + EXPECT_EQ(cvad->get(1), prop3); + EXPECT_EQ(cvad->get(2), prop2); + + + // Array:get(string) + EXPECT_THROW(vad->get("0"), std::out_of_range); + EXPECT_THROW(vad->get("nonumber"), std::out_of_range); + EXPECT_EQ(vad->get("1"), prop1); + EXPECT_EQ(vad->get("2"), prop3); + EXPECT_EQ(vad->get("3"), prop2); + + + // Array:get(string) const + EXPECT_THROW(cvad->get("0"), std::out_of_range); + EXPECT_THROW(cvad->get("nonumber"), std::out_of_range); + EXPECT_EQ(cvad->get("1"), prop1); + EXPECT_EQ(cvad->get("2"), prop3); + EXPECT_EQ(cvad->get("3"), prop2); + + + // Array::index(string) + EXPECT_EQ(vad->index("0"), -1); + EXPECT_EQ(vad->index("nonumber"), -1); + EXPECT_EQ(vad->index("1"), 0); + EXPECT_EQ(vad->index("2"), 1); + EXPECT_EQ(vad->index("3"), 2); + + + // Array::name(index) + EXPECT_THROW(vad->name(-1), std::out_of_range); + EXPECT_THROW(vad->name(4), std::out_of_range); + EXPECT_EQ(vad->name(0), "1"); + EXPECT_EQ(vad->name(1), "2"); + EXPECT_EQ(vad->name(2), "3"); + + + + // Array::removeProperty + EXPECT_THROW(vad->addProperty(-2), std::out_of_range); + EXPECT_THROW(vad->addProperty(4), std::out_of_range); + + vad->removeProperty(0); + EXPECT_EQ(vad->size(), 2); + EXPECT_EQ(vad->get(0), prop3); + EXPECT_EQ(vad->get(1), prop2); + + vad->removeProperty(1); + EXPECT_EQ(vad->size(), 1); + EXPECT_EQ(vad->get(0), prop3); + + vad->removeProperty(0); + EXPECT_EQ(vad->size(), 0); + + + // Array::addProperty(ValueBase * property, int index_before) + auto vd = new Value(); + EXPECT_THROW(vad->addProperty(vd, -2), std::out_of_range); + EXPECT_THROW(vad->addProperty(vd, 2), std::out_of_range); + + prop1 = vad->addProperty(new Value()); + prop2 = vad->addProperty(new Value(), -1); + prop3 = vad->addProperty(new Value(), 1); + EXPECT_EQ(vad->size(), 3); + EXPECT_EQ(vad->get(0), prop1); + EXPECT_EQ(vad->get(1), prop3); + EXPECT_EQ(vad->get(2), prop2); + + + // element Value::operator= + EXPECT_EQ((*vad)[0]->asDouble(), 0.0); + EXPECT_EQ((*vad)[1]->asDouble(), 0.0); + EXPECT_EQ((*vad)[2]->asDouble(), 0.0); + *prop1 = 1.0; + *prop2 = 2.0; + *prop3 = 3.0; + EXPECT_EQ((*vad)[0]->asDouble(), 1.0); + EXPECT_EQ((*vad)[1]->asDouble(), 3.0); + EXPECT_EQ((*vad)[2]->asDouble(), 2.0); + + + // Array::compare(std::vector const&) + EXPECT_TRUE(vad->compare(std::vector({1.0, 3.0, 2.0}))); + EXPECT_FALSE(vad->compare(std::vector({1.0, 2.0, 3.0}))); + EXPECT_FALSE(vad->compare(std::vector({1.0, 3.0}))); + EXPECT_FALSE(vad->compare(std::vector({1.0, 3.0, 2.0, 0.0}))); + + // Array::compare(const Array&) + { + Value> vad2; + EXPECT_FALSE(vad2->compare(*vad)); + EXPECT_FALSE(vad->compare(*vad2)); + vad2 = vad; + EXPECT_TRUE(vad2->compare(*vad)); + EXPECT_TRUE(vad->compare(*vad2)); + } + + // Array::set + { + Array ad2; + std::vector vec({1.0, 2.0, 3.0}); + ad2.set(vec); + EXPECT_TRUE(ad2.compare(vec)); + } + + // Array:get results in statically known Value* + EXPECT_EQ(**vad->get(0), 1.0); + EXPECT_EQ(**vad->get(1), 3.0); + EXPECT_EQ(**vad->get(2), 2.0); + + // Value::operator=(Value&) + { + Value> vad2; + vad2 = vad; + + EXPECT_EQ(vad2->size(), 3); + EXPECT_EQ((*vad2)[0]->asDouble(), 1.0); + EXPECT_EQ((*vad2)[1]->asDouble(), 3.0); + EXPECT_EQ((*vad2)[2]->asDouble(), 2.0); + } + + // Value::operator=(T&) + { + Value> vad2; + vad2 = ad; + EXPECT_TRUE(*vad2 == ad); + } + + // Value::operator=(ValueBase&) + EXPECT_THROW(vad = vai, std::runtime_error); + + Value> vad2; + vad2 = *(static_cast(&vad)); + + EXPECT_EQ(vad2->size(), 3); + EXPECT_EQ((*vad2)[0]->asDouble(), 1.0); + EXPECT_EQ((*vad2)[1]->asDouble(), 3.0); + EXPECT_EQ((*vad2)[2]->asDouble(), 2.0); + + // Value::assign + Value> vad3; + EXPECT_TRUE(vad3.assign(vad)); + + EXPECT_EQ(vad3->size(), 3); + EXPECT_EQ((*vad3)[0]->asDouble(), 1.0); + EXPECT_EQ((*vad3)[1]->asDouble(), 3.0); + EXPECT_EQ((*vad3)[2]->asDouble(), 2.0); + + // Value::operator== + EXPECT_FALSE(vad == vai); + EXPECT_TRUE(vad == vad2); + + // Value::compare + EXPECT_FALSE(vad.compare(vai, nullptr)); + EXPECT_TRUE(vad.compare(vad2, nullptr)); + + // Value::copyAnnotationData -> only check exception behaviour for now + vad2.copyAnnotationData(vad); + // type mismatch: + EXPECT_THROW(vad2.copyAnnotationData(vai), std::runtime_error); + vad2 = ad; + EXPECT_EQ(vad2->size(), 2); + EXPECT_EQ(vad->size(), 3); + // array size mismatch + EXPECT_THROW(vad2.copyAnnotationData(vai), std::runtime_error); + + // Value::asStruct -> throw + EXPECT_THROW(vad.asStruct(), std::runtime_error); + + // Value::asArray -> check no throw + vad.asArray(); + (static_cast>&>(vad)).asArray(); + + // Value::setArray + vad.setArray(ad); + EXPECT_EQ(vad->size(), 2); + EXPECT_EQ((*vad)[0]->asDouble(), -1.0); + EXPECT_EQ((*vad)[1]->asDouble(), -2.0); + EXPECT_TRUE(*vad == ad); + + EXPECT_THROW(vad.setArray(ai), std::runtime_error); + + // Value::clone + auto vad_clone = vad.clone(nullptr); + EXPECT_TRUE(vad == *vad_clone); +} + +TEST(ValueTest, ArrayNested) { + Value>> vaad; + auto prop1 = vaad->addProperty(); + + EXPECT_EQ(vaad.type(), PrimitiveType::Array); + EXPECT_EQ(vaad->elementType(), PrimitiveType::Array); + + EXPECT_EQ(prop1->type(), PrimitiveType::Array); + EXPECT_EQ((*prop1)->elementType(), PrimitiveType::Double); + + // Value::typeName + EXPECT_EQ(vaad.typeName(), "Array[Array[Double]]"); + // Value::baseTypeName + EXPECT_EQ(vaad.baseTypeName(), "Array[Array[Double]]"); + // Array::typeName + EXPECT_EQ(vaad->typeName(), "Array[Array[Double]]"); + // Array::elementTypeName + EXPECT_EQ(vaad->elementTypeName(), "Array[Double]"); + EXPECT_EQ(prop1->typeName(), "Array[Double]"); + EXPECT_EQ((*prop1)->elementTypeName(), "Double"); +} \ No newline at end of file diff --git a/datamodel/libTesting/include/testing/MockUserTypes.h b/datamodel/libTesting/include/testing/MockUserTypes.h index 78caf7e7..9404095f 100644 --- a/datamodel/libTesting/include/testing/MockUserTypes.h +++ b/datamodel/libTesting/include/testing/MockUserTypes.h @@ -12,6 +12,8 @@ #include "core/EditorObject.h" #include "core/BasicTypes.h" #include "core/Link.h" +#include "data_storage/Array.h" + #include @@ -37,7 +39,7 @@ class Dummy : public AnnotationBase { } }; -class MockTableObject : public raco::core::EditorObject { +class MockTableObject : public core::EditorObject { public: static inline const TypeDescriptor typeDescription = {"MockTableObject", true}; TypeDescriptor const& getTypeDescription() const override { @@ -266,6 +268,48 @@ class ObjectWithStructProperty : public EditorObject { Value s_{}; }; +class ObjectWithArrays : public EditorObject { +public: + static inline const TypeDescriptor typeDescription = {"ObjectWithArrays", false}; + TypeDescriptor const& getTypeDescription() const override { + return typeDescription; + } + + ObjectWithArrays(ObjectWithArrays const& other) + : EditorObject(other), + table_(other.table_), + array_double_(other.array_double_), + array_array_double_(other.array_array_double_), + array_ref_(other.array_ref_), + array_ref_resizable_(other.array_ref_resizable_), + array_ref_array_semantic_(other.array_ref_array_semantic_) { + fillPropertyDescription(); + } + + ObjectWithArrays(std::string name = {}, std::string id = {}) : EditorObject(name, id) { + fillPropertyDescription(); + } + + void fillPropertyDescription() { + properties_.emplace_back("table", &table_); + properties_.emplace_back("array_double", &array_double_); + properties_.emplace_back("array_array_double", &array_array_double_); + properties_.emplace_back("array_ref", &array_ref_); + properties_.emplace_back("array_ref_resizable", &array_ref_resizable_); + properties_.emplace_back("array_ref_empty", &array_ref_array_semantic_); + } + + Value
table_{}; + + // These forms are used by the animation channel data + Value> array_double_{}; + Value>> array_array_double_{}; + + Value> array_ref_; + Property, ResizableArray> array_ref_resizable_; + Property, ArraySemanticAnnotation> array_ref_array_semantic_; +}; + class FutureType : public EditorObject { public: static inline const TypeDescriptor typeDescription = {"FutureType", false, 0x12345678}; diff --git a/datamodel/libTesting/include/testing/RaCoApplicationTest.h b/datamodel/libTesting/include/testing/RaCoApplicationTest.h index dce6ff20..10f6cdd4 100644 --- a/datamodel/libTesting/include/testing/RaCoApplicationTest.h +++ b/datamodel/libTesting/include/testing/RaCoApplicationTest.h @@ -18,27 +18,27 @@ class RaCoApplicationTest : public RacoBaseTest<> { public: - raco::ramses_base::HeadlessEngineBackend backend{raco::ramses_base::BaseEngineBackend::maxFeatureLevel}; + ramses_base::HeadlessEngineBackend backend{}; raco::application::RaCoApplication application{backend, {{}, false, false, -1, -1, false}}; - raco::core::ExternalProjectsStoreInterface* externalProjectStore() { + core::ExternalProjectsStoreInterface* externalProjectStore() { return application.externalProjects(); }; - raco::core::CommandInterface& commandInterface() { + core::CommandInterface& commandInterface() { return *application.activeRaCoProject().commandInterface(); }; - raco::core::DataChangeRecorder& recorder() { + core::DataChangeRecorder& recorder() { return *application.activeRaCoProject().recorder(); }; - raco::core::Project& project() { + core::Project& project() { return *application.activeRaCoProject().project(); }; template - std::shared_ptr create(std::string name, raco::core::SEditorObject parent = nullptr) { + std::shared_ptr create(std::string name, core::SEditorObject parent = nullptr) { auto obj = std::dynamic_pointer_cast(commandInterface().createObject(C::typeDescription.typeName, name)); if (parent) { commandInterface().moveScenegraphChildren({obj}, parent); diff --git a/datamodel/libTesting/include/testing/RacoBaseTest.h b/datamodel/libTesting/include/testing/RacoBaseTest.h index f3f6ab65..41dea3ae 100644 --- a/datamodel/libTesting/include/testing/RacoBaseTest.h +++ b/datamodel/libTesting/include/testing/RacoBaseTest.h @@ -21,6 +21,8 @@ #include +using namespace raco; + template class RacoBaseTest : public BaseClass { public: @@ -32,15 +34,15 @@ class RacoBaseTest : public BaseClass { return ::testing::UnitTest::GetInstance()->current_test_info()->test_suite_name(); } - virtual raco::utils::u8path test_relative_path() const { - return raco::utils::u8path{test_suite_name()} / test_case_name(); + virtual utils::u8path test_relative_path() const { + return utils::u8path{test_suite_name()} / test_case_name(); } - raco::utils::u8path test_path() const { - return raco::utils::u8path::current() / test_relative_path(); + utils::u8path test_path() const { + return utils::u8path::current() / test_relative_path(); } - void checkUndoRedo(raco::core::CommandInterface& cmd, std::function operation, std::function preCheck, std::function postCheck) { + void checkUndoRedo(core::CommandInterface& cmd, std::function operation, std::function preCheck, std::function postCheck) { preCheck(); operation(); postCheck(); @@ -51,7 +53,7 @@ class RacoBaseTest : public BaseClass { } template - void checkUndoRedoMultiStep(raco::core::CommandInterface& cmd, std::array, N> operations, std::array, N + 1> checks) { + void checkUndoRedoMultiStep(core::CommandInterface& cmd, std::array, N> operations, std::array, N + 1> checks) { // forward pass for (std::size_t i = 0; i < N; i++) { checks[i](); @@ -72,15 +74,15 @@ class RacoBaseTest : public BaseClass { } } - static void checkLinks(raco::core::Project& project, const std::vector& refLinks) { + static void checkLinks(core::Project& project, const std::vector& refLinks) { EXPECT_EQ(refLinks.size(), project.links().size()); for (const auto& refLink : refLinks) { - auto projectLink = raco::core::Queries::getLink(project, refLink.endProp()); + auto projectLink = core::Queries::getLink(project, refLink.endProp()); EXPECT_TRUE(projectLink); EXPECT_TRUE(projectLink->startProp() == refLink.startProp()); EXPECT_TRUE(projectLink->isValid() == refLink.isValid()); EXPECT_TRUE(*projectLink->isWeak_ == *refLink.isWeak_); - auto refValid = raco::core::Queries::linkWouldBeValid(project, projectLink->startProp(), projectLink->endProp()); + auto refValid = core::Queries::linkWouldBeValid(project, projectLink->startProp(), projectLink->endProp()); EXPECT_TRUE(projectLink->isValid() == refValid); } } @@ -106,16 +108,18 @@ class RacoBaseTest : public BaseClass { // Setup fake directory hierachy to simulate different directories configfiles can live in. auto programPath = test_path() / "App" / "bin"; auto appDataPath = test_path() / "AppData"; - raco::core::PathManager::init(programPath.string(), appDataPath.string()); + core::PathManager::init(programPath.string(), appDataPath.string()); + // Always setup the actual resource path to ensure the gizmo meshes can be loaded: + core::PathManager::setDefaultResourceDirectory(DEFAULT_RESOURCES_DIRECTORY); #ifdef RACO_LOCAL_TEST_RESOURCES_FILE_LIST auto fileNames{split(RACO_LOCAL_TEST_RESOURCES_FILE_LIST, '!')}; auto dirNames{split(RACO_LOCAL_TEST_RESOURCES_DIRECTORY_LIST, '!')}; for (size_t index = 0; index < fileNames.size(); index++) { - auto from{raco::utils::u8path(dirNames[index]) / fileNames[index]}; + auto from{utils::u8path(dirNames[index]) / fileNames[index]}; auto to{test_path() / fileNames[index]}; - raco::utils::u8path toWithoutFilename{to}; + utils::u8path toWithoutFilename{to}; toWithoutFilename.remove_filename(); std::filesystem::create_directories(toWithoutFilename); std::filesystem::copy(from, to); @@ -131,14 +135,14 @@ class RacoBaseTest : public BaseClass { struct TextFile { TextFile(RacoBaseTest& test, std::string fileName, std::string contents) { path = test.test_path() / fileName; - raco::utils::file::write(path.string(), contents); + utils::file::write(path.string(), contents); } operator std::string() const { return path.string(); } - raco::utils::u8path path; + utils::u8path path; }; TextFile makeFile(std::string fileName, std::string contents) { diff --git a/datamodel/libTesting/include/testing/TestEnvironmentCore.h b/datamodel/libTesting/include/testing/TestEnvironmentCore.h index 18b5eaf3..a017833a 100644 --- a/datamodel/libTesting/include/testing/TestEnvironmentCore.h +++ b/datamodel/libTesting/include/testing/TestEnvironmentCore.h @@ -57,28 +57,35 @@ inline void clearQEventLoop() { } -class TestUndoStack : public raco::core::UndoStack { +class TestUndoStack : public core::UndoStack { public: - using Entry = raco::core::UndoStack::Entry; + using Entry = core::UndoStack::Entry; std::vector>& stack() { return stack_; } }; -class TestObjectFactory : public raco::user_types::UserObjectFactory { +class TestObjectFactory : public user_types::UserObjectFactory { public: TestObjectFactory() : UserObjectFactory() {} static TestObjectFactory& getInstance() { + using namespace raco::data_storage; + static TestObjectFactory* instance = nullptr; if (!instance) { instance = new TestObjectFactory(); - instance->addType(); - instance->addType(); - instance->addType(); - instance->addType(); - instance->addType(); + instance->addType(); + instance->addType(); + instance->addType(); + instance->addType(); + instance->addType(); + instance->addType(); + + instance->addProperty>>(); + instance->addProperty>>>(); + instance->addProperty>>(); } return *instance; } @@ -87,19 +94,19 @@ class TestObjectFactory : public raco::user_types::UserObjectFactory { template struct TestEnvironmentCoreT : public RacoBaseTest { - using BaseContext = raco::core::BaseContext; - using Project = raco::core::Project; - using Errors = raco::core::Errors; - using UserObjectFactoryInterface = raco::core::UserObjectFactoryInterface; - using UserObjectFactory = raco::user_types::UserObjectFactory; - using DataChangeRecorderInterface = raco::core::DataChangeRecorderInterface; + using BaseContext = core::BaseContext; + using Project = core::Project; + using Errors = core::Errors; + using UserObjectFactoryInterface = core::UserObjectFactoryInterface; + using UserObjectFactory = user_types::UserObjectFactory; + using DataChangeRecorderInterface = core::DataChangeRecorderInterface; UserObjectFactoryInterface* objectFactory() { return context.objectFactory(); }; template - std::shared_ptr create(std::string name, raco::core::SEditorObject parent = nullptr, const std::vector& tags = {}) { + std::shared_ptr create(std::string name, core::SEditorObject parent = nullptr, const std::vector& tags = {}) { auto obj = std::dynamic_pointer_cast(commandInterface.createObject(C::typeDescription.typeName, name)); if (parent) { commandInterface.moveScenegraphChildren({obj}, parent); @@ -111,7 +118,7 @@ struct TestEnvironmentCoreT : public RacoBaseTest { } template - std::shared_ptr create(raco::core::CommandInterface& cmd, std::string name, raco::core::SEditorObject parent = nullptr) { + std::shared_ptr create(core::CommandInterface& cmd, std::string name, core::SEditorObject parent = nullptr) { auto obj = std::dynamic_pointer_cast(cmd.createObject(C::typeDescription.typeName, name)); if (parent) { cmd.moveScenegraphChildren({obj}, parent); @@ -119,14 +126,14 @@ struct TestEnvironmentCoreT : public RacoBaseTest { return obj; } - raco::user_types::SMesh create_mesh(const std::string& name, const std::string& relpath) { - auto mesh = create(name); + user_types::SMesh create_mesh(const std::string& name, const std::string& relpath) { + auto mesh = create(name); commandInterface.set({mesh, {"uri"}}, (RacoBaseTest::test_path() / relpath).string()); return mesh; } - raco::user_types::SMaterial create_material(const std::string& name, const std::string& relpathVertex, const std::string& relpathFragment, const std::string& relpathGeometry = std::string()) { - auto material = create(name); + user_types::SMaterial create_material(const std::string& name, const std::string& relpathVertex, const std::string& relpathFragment, const std::string& relpathGeometry = std::string()) { + auto material = create(name); if (relpathGeometry.length()) { commandInterface.set({material, {"uriGeometry"}}, (RacoBaseTest::test_path() / relpathGeometry).string()); } @@ -135,98 +142,98 @@ struct TestEnvironmentCoreT : public RacoBaseTest { return material; } - raco::user_types::SMeshNode create_meshnode(const std::string& name, raco::user_types::SMesh mesh, raco::user_types::SMaterial material, raco::user_types::SEditorObject parent = nullptr) { - auto meshnode = create(name, parent); + user_types::SMeshNode create_meshnode(const std::string& name, user_types::SMesh mesh, user_types::SMaterial material, user_types::SEditorObject parent = nullptr) { + auto meshnode = create(name, parent); commandInterface.set({meshnode, {"mesh"}}, mesh); commandInterface.set({meshnode, {"materials", "material", "material"}}, material); return meshnode; } - raco::user_types::SLuaScript create_lua(raco::core::CommandInterface& cmd, const std::string& name, const std::string& relpath, raco::core::SEditorObject parent = nullptr) { - auto lua = create(cmd, name, parent); + user_types::SLuaScript create_lua(core::CommandInterface& cmd, const std::string& name, const std::string& relpath, core::SEditorObject parent = nullptr) { + auto lua = create(cmd, name, parent); cmd.set({lua, {"uri"}}, (RacoBaseTest::test_path() / relpath).string()); return lua; } - raco::user_types::SLuaScript create_lua(const std::string& name, const std::string& relpath, raco::core::SEditorObject parent = nullptr) { + user_types::SLuaScript create_lua(const std::string& name, const std::string& relpath, core::SEditorObject parent = nullptr) { return create_lua(commandInterface, name, relpath, parent); } - raco::user_types::SLuaScript create_lua(raco::core::CommandInterface& cmd, const std::string& name, const typename RacoBaseTest::TextFile& file) { - auto lua = create(cmd, name); + user_types::SLuaScript create_lua(core::CommandInterface& cmd, const std::string& name, const typename RacoBaseTest::TextFile& file) { + auto lua = create(cmd, name); cmd.set({lua, {"uri"}}, file); return lua; } - raco::user_types::SLuaScript create_lua(const std::string& name, const typename + user_types::SLuaScript create_lua(const std::string& name, const typename RacoBaseTest::TextFile& file) { return create_lua(commandInterface, name, file); } - raco::user_types::SLuaScriptModule create_lua_module(const std::string& name, const std::string& relpath, raco::core::SEditorObject parent = nullptr) { - auto module = create(commandInterface, name, parent); + user_types::SLuaScriptModule create_lua_module(const std::string& name, const std::string& relpath, core::SEditorObject parent = nullptr) { + auto module = create(commandInterface, name, parent); commandInterface.set({module, {"uri"}}, (RacoBaseTest::test_path() / relpath).string()); return module; } - raco::user_types::SLuaInterface create_lua_interface(const std::string& name, const std::string& relpath, raco::core::SEditorObject parent = nullptr) { - auto interface = create(commandInterface, name, parent); + user_types::SLuaInterface create_lua_interface(const std::string& name, const std::string& relpath, core::SEditorObject parent = nullptr) { + auto interface = create(commandInterface, name, parent); commandInterface.set({interface, {"uri"}}, (RacoBaseTest::test_path() / relpath).string()); return interface; } - raco::user_types::SLuaInterface create_lua_interface(const std::string& name, const typename RacoBaseTest::TextFile& file, raco::core::SEditorObject parent = nullptr) { - auto interface = create(commandInterface, name, parent); + user_types::SLuaInterface create_lua_interface(const std::string& name, const typename RacoBaseTest::TextFile& file, core::SEditorObject parent = nullptr) { + auto interface = create(commandInterface, name, parent); commandInterface.set({interface, {"uri"}}, file); return interface; } - raco::user_types::SRenderLayer create_layer(const std::string& name, + user_types::SRenderLayer create_layer(const std::string& name, const std::vector& tags = {}, const std::vector>& renderables = {}, const std::vector& matFilterTags = {}, bool filterExclusive = true) { - auto layer = create(name, nullptr, tags); + auto layer = create(name, nullptr, tags); for (int index = 0; index < renderables.size(); index++) { - context.addProperty({layer, {"renderableTags"}}, renderables[index].first, std::make_unique>(renderables[index].second)); + context.addProperty({layer, {"renderableTags"}}, renderables[index].first, std::make_unique>(renderables[index].second)); } if (!matFilterTags.empty()) { - context.set({layer, &raco::user_types::RenderLayer::materialFilterTags_}, matFilterTags); + context.set({layer, &user_types::RenderLayer::materialFilterTags_}, matFilterTags); } - context.set({layer, &raco::user_types::RenderLayer::materialFilterMode_}, - static_cast(filterExclusive ? raco::user_types::ERenderLayerMaterialFilterMode::Exclusive : raco::user_types::ERenderLayerMaterialFilterMode::Inclusive)); + context.set({layer, &user_types::RenderLayer::materialFilterMode_}, + static_cast(filterExclusive ? user_types::ERenderLayerMaterialFilterMode::Exclusive : user_types::ERenderLayerMaterialFilterMode::Inclusive)); return layer; } - raco::user_types::SSkin create_skin(const std::string& name, + user_types::SSkin create_skin(const std::string& name, const std::string& relpath, int skinIndex, - raco::user_types::SMeshNode meshnode, - const std::vector& nodes) { - auto skin = create(name); - commandInterface.set(raco::core::ValueHandle(skin, &raco::user_types::Skin::targets_)[0], meshnode); - commandInterface.set({skin, &raco::user_types::Skin::uri_}, (RacoBaseTest::test_path() / relpath).string()); - commandInterface.set({skin, &raco::user_types::Skin::skinIndex_}, skinIndex); + user_types::SMeshNode meshnode, + const std::vector& nodes) { + auto skin = create(name); + commandInterface.set(core::ValueHandle(skin, &user_types::Skin::targets_)[0], meshnode); + commandInterface.set({skin, &user_types::Skin::uri_}, (RacoBaseTest::test_path() / relpath).string()); + commandInterface.set({skin, &user_types::Skin::skinIndex_}, skinIndex); for (int index = 0; index < nodes.size(); index++) { - commandInterface.set(raco::core::ValueHandle(skin, &raco::user_types::Skin::joints_)[index], nodes[index]); + commandInterface.set(core::ValueHandle(skin, &user_types::Skin::joints_)[index], nodes[index]); } return skin; } - raco::user_types::STexture create_texture(const std::string& name, const std::string& relpath) { - auto texture = create(name); + user_types::STexture create_texture(const std::string& name, const std::string& relpath) { + auto texture = create(name); commandInterface.set({texture, {"uri"}}, (RacoBaseTest::test_path() / relpath).string()); return texture; } - raco::user_types::SPrefabInstance create_prefabInstance(raco::core::CommandInterface& cmd, const std::string& name, raco::user_types::SPrefab prefab, raco::user_types::SEditorObject parent = nullptr) { - auto inst = create(cmd, name, parent); + user_types::SPrefabInstance create_prefabInstance(core::CommandInterface& cmd, const std::string& name, user_types::SPrefab prefab, user_types::SEditorObject parent = nullptr) { + auto inst = create(cmd, name, parent); cmd.set({inst, {"template"}}, prefab); return inst; } - raco::user_types::SPrefabInstance create_prefabInstance(const std::string& name, raco::user_types::SPrefab prefab, raco::user_types::SEditorObject parent = nullptr) { + user_types::SPrefabInstance create_prefabInstance(const std::string& name, user_types::SPrefab prefab, user_types::SEditorObject parent = nullptr) { return create_prefabInstance(commandInterface, name, prefab, parent); } @@ -239,18 +246,18 @@ struct TestEnvironmentCoreT : public RacoBaseTest { RacoBaseTest::checkUndoRedoMultiStep(commandInterface, operations, checks); } - std::pair link(raco::user_types::SEditorObject startObj, std::vector startProp, raco::user_types::SEditorObject endObj, std::vector endProp, bool isWeak = false) { - raco::core::PropertyDescriptor start{startObj, startProp}; - raco::core::PropertyDescriptor end{endObj, endProp}; - commandInterface.addLink(raco::core::ValueHandle(start), raco::core::ValueHandle(end), isWeak); + std::pair link(user_types::SEditorObject startObj, std::vector startProp, user_types::SEditorObject endObj, std::vector endProp, bool isWeak = false) { + core::PropertyDescriptor start{startObj, startProp}; + core::PropertyDescriptor end{endObj, endProp}; + commandInterface.addLink(core::ValueHandle(start), core::ValueHandle(end), isWeak); return {start, end}; } - static void checkLinks(raco::core::Project& project, const std::vector& refLinks) { + static void checkLinks(core::Project& project, const std::vector& refLinks) { RacoBaseTest::checkLinks(project, refLinks); } - void checkLinks(const std::vector& refLinks) { + void checkLinks(const std::vector& refLinks) { checkLinks(project, refLinks); } @@ -262,8 +269,8 @@ struct TestEnvironmentCoreT : public RacoBaseTest { ASSERT_LE(opTimeMs, maxMs) << "Operation took longer than allowed boundary of " << maxMs << " ms\nActual operation duration: " << opTimeMs << " ms"; } - TestEnvironmentCoreT(UserObjectFactoryInterface* objectFactory = &UserObjectFactory::getInstance(), rlogic::EFeatureLevel featureLevel = raco::ramses_base::BaseEngineBackend::maxFeatureLevel) - : backend{featureLevel}, + TestEnvironmentCoreT(UserObjectFactoryInterface* objectFactory = &UserObjectFactory::getInstance(), ramses::EFeatureLevel featureLevel = ramses_base::BaseEngineBackend::maxFeatureLevel) + : backend{}, meshCache{}, project{}, recorder{}, @@ -272,13 +279,14 @@ struct TestEnvironmentCoreT : public RacoBaseTest { undoStack{&context}, commandInterface{&context, &undoStack} { spdlog::drop_all(); - raco::log_system::init(); + log_system::init(); clearQEventLoop(); context.setMeshCache(&meshCache); - auto settings = context.createObject(raco::core::ProjectSettings::typeDescription.typeName, "ProjectSettings"); - context.set({settings, &raco::core::ProjectSettings::featureLevel_}, static_cast(featureLevel)); + auto settings = context.createObject(core::ProjectSettings::typeDescription.typeName, "ProjectSettings"); + context.set({settings, &core::ProjectSettings::featureLevel_}, static_cast(featureLevel)); undoStack.reset(); context.changeMultiplexer().reset(); + backend.setFeatureLevel(featureLevel); } virtual ~TestEnvironmentCoreT() { @@ -290,14 +298,14 @@ struct TestEnvironmentCoreT : public RacoBaseTest { } - raco::ramses_base::HeadlessEngineBackend backend; - raco::components::MeshCacheImpl meshCache; + ramses_base::HeadlessEngineBackend backend; + components::MeshCacheImpl meshCache; Project project; - raco::core::DataChangeRecorder recorder; + core::DataChangeRecorder recorder; Errors errors; BaseContext context; TestUndoStack undoStack; - raco::core::CommandInterface commandInterface; + core::CommandInterface commandInterface; }; using TestEnvironmentCore = TestEnvironmentCoreT<>; diff --git a/datamodel/libTesting/include/testing/TestUtil.h b/datamodel/libTesting/include/testing/TestUtil.h index 91c54a74..8aa60226 100644 --- a/datamodel/libTesting/include/testing/TestUtil.h +++ b/datamodel/libTesting/include/testing/TestUtil.h @@ -45,10 +45,10 @@ inline std::shared_ptr select(const std::vector& vec, std::string_view nam return {}; } -inline auto createLinkedScene(raco::core::CommandInterface& context, const raco::utils::u8path& path) { - const auto luaScript{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script")}; - const auto node{context.createObject(raco::user_types::Node::typeDescription.typeName, "node")}; - raco::utils::file::write((path / "lua_script.lua").string(), R"( +inline auto createLinkedScene(core::CommandInterface& context, const utils::u8path& path) { + const auto luaScript{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script")}; + const auto node{context.createObject(user_types::Node::typeDescription.typeName, "node")}; + utils::file::write((path / "lua_script.lua").string(), R"( function interface(IN,OUT) OUT.translation = Type:Vec3f() OUT.rotation3 = Type:Vec3f() @@ -64,10 +64,10 @@ end } -inline auto createLinkedScene(raco::core::BaseContext& context, const raco::utils::u8path& path) { - const auto luaScript{context.createObject(raco::user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; - const auto node{context.createObject(raco::user_types::Node::typeDescription.typeName, "node", "node_id")}; - raco::utils::file::write((path / "lua_script.lua").string(), R"( +inline auto createLinkedScene(core::BaseContext& context, const utils::u8path& path) { + const auto luaScript{context.createObject(user_types::LuaScript::typeDescription.typeName, "lua_script", "lua_script_id")}; + const auto node{context.createObject(user_types::Node::typeDescription.typeName, "node", "node_id")}; + utils::file::write((path / "lua_script.lua").string(), R"( function interface(IN,OUT) OUT.translation = Type:Vec3f() OUT.rotation3 = Type:Vec3f() @@ -83,10 +83,10 @@ end } template -inline auto createAnimatedScene(ContextOrCommandInterface& context, const raco::utils::u8path& path) { - const auto anim{context.createObject(raco::user_types::Animation::typeDescription.typeName, "anim")}; - const auto animChannel{context.createObject(raco::user_types::AnimationChannel::typeDescription.typeName, "anim_ch")}; - const auto node{context.createObject(raco::user_types::Node::typeDescription.typeName, "node")}; +inline auto createAnimatedScene(ContextOrCommandInterface& context, const utils::u8path& path) { + const auto anim{context.createObject(user_types::Animation::typeDescription.typeName, "anim")}; + const auto animChannel{context.createObject(user_types::AnimationChannel::typeDescription.typeName, "anim_ch")}; + const auto node{context.createObject(user_types::Node::typeDescription.typeName, "node")}; context.set({anim, {"animationChannels", "Channel 0"}}, animChannel); context.set({animChannel, {"uri"}}, (path / "meshes" / "InterpolationTest" / "InterpolationTest.gltf").string()); @@ -99,7 +99,7 @@ inline auto createAnimatedScene(ContextOrCommandInterface& context, const raco:: link); } -inline bool awaitPreviewDirty(const raco::core::DataChangeRecorder& recorder, const raco::core::SEditorObject& obj, long long timeout = 5) { +inline bool awaitPreviewDirty(const core::DataChangeRecorder& recorder, const core::SEditorObject& obj, long long timeout = 5) { const std::chrono::steady_clock::time_point timeoutTS = std::chrono::steady_clock::now() + std::chrono::seconds{timeout}; auto dirtyObjects{recorder.getPreviewDirtyObjects()}; int argc = 0; @@ -125,43 +125,43 @@ inline void createGitLfsPlaceholderFile(const std::string& path) { file.close(); } -inline std::pair getMeshSceneGraphWithHandler(raco::core::MeshCache* meshCache, const raco::core::MeshDescriptor& descriptor) { +inline std::pair getMeshSceneGraphWithHandler(core::MeshCache* meshCache, const core::MeshDescriptor& descriptor) { auto dummyCacheEntry = meshCache->registerFileChangedHandler(descriptor.absPath, {nullptr, nullptr}); - raco::core::MeshScenegraph scenegraph{*meshCache->getMeshScenegraph(descriptor.absPath)}; + core::MeshScenegraph scenegraph{*meshCache->getMeshScenegraph(descriptor.absPath)}; return {scenegraph, std::move(dummyCacheEntry)}; } -inline void checkVec2fValue(raco::core::ValueHandle handle, const std::array& value) { +inline void checkVec2fValue(core::ValueHandle handle, const std::array& value) { EXPECT_EQ(handle[0].asDouble(), value[0]); EXPECT_EQ(handle[1].asDouble(), value[1]); } -inline void checkVec3fValue(raco::core::ValueHandle handle, const std::array& value) { +inline void checkVec3fValue(core::ValueHandle handle, const std::array& value) { EXPECT_EQ(handle[0].asDouble(), value[0]); EXPECT_EQ(handle[1].asDouble(), value[1]); EXPECT_EQ(handle[2].asDouble(), value[2]); } -inline void checkVec4fValue(raco::core::ValueHandle handle, const std::array& value) { +inline void checkVec4fValue(core::ValueHandle handle, const std::array& value) { EXPECT_EQ(handle[0].asDouble(), value[0]); EXPECT_EQ(handle[1].asDouble(), value[1]); EXPECT_EQ(handle[2].asDouble(), value[2]); EXPECT_EQ(handle[3].asDouble(), value[3]); } -inline void checkVec2iValue(raco::core::ValueHandle handle, const std::array& value) { +inline void checkVec2iValue(core::ValueHandle handle, const std::array& value) { EXPECT_EQ(handle[0].asInt(), value[0]); EXPECT_EQ(handle[1].asInt(), value[1]); } -inline void checkVec3iValue(raco::core::ValueHandle handle, const std::array& value) { +inline void checkVec3iValue(core::ValueHandle handle, const std::array& value) { EXPECT_EQ(handle[0].asInt(), value[0]); EXPECT_EQ(handle[1].asInt(), value[1]); EXPECT_EQ(handle[2].asInt(), value[2]); } -inline void checkVec4iValue(raco::core::ValueHandle handle, const std::array& value) { +inline void checkVec4iValue(core::ValueHandle handle, const std::array& value) { EXPECT_EQ(handle[0].asInt(), value[0]); EXPECT_EQ(handle[1].asInt(), value[1]); EXPECT_EQ(handle[2].asInt(), value[2]); diff --git a/datamodel/libUserTypes/CMakeLists.txt b/datamodel/libUserTypes/CMakeLists.txt index 83dffb0b..050f31d1 100644 --- a/datamodel/libUserTypes/CMakeLists.txt +++ b/datamodel/libUserTypes/CMakeLists.txt @@ -43,6 +43,7 @@ add_library(libUserTypes include/user_types/TextureExternal.h src/TextureExternal.cpp include/user_types/Timer.h src/Timer.cpp include/user_types/UserObjectFactory.h src/UserObjectFactory.cpp + include/user_types/UserTypeAnnotations.h src/Validation.h src/LuaUtils.h src/LuaUtils.cpp ) diff --git a/datamodel/libUserTypes/include/user_types/AnchorPoint.h b/datamodel/libUserTypes/include/user_types/AnchorPoint.h index 2a2f4145..c71664e9 100644 --- a/datamodel/libUserTypes/include/user_types/AnchorPoint.h +++ b/datamodel/libUserTypes/include/user_types/AnchorPoint.h @@ -58,7 +58,7 @@ class AnchorPointOutputs : public StructBase { class AnchorPoint : public BaseObject { public: - static inline const TypeDescriptor typeDescription = {"AnchorPoint", true, 2}; + static inline const TypeDescriptor typeDescription = {"AnchorPoint", true}; TypeDescriptor const& getTypeDescription() const override { return typeDescription; } diff --git a/datamodel/libUserTypes/include/user_types/Animation.h b/datamodel/libUserTypes/include/user_types/Animation.h index 5049d0c3..05e8d0a0 100644 --- a/datamodel/libUserTypes/include/user_types/Animation.h +++ b/datamodel/libUserTypes/include/user_types/Animation.h @@ -17,8 +17,6 @@ namespace raco::user_types { class Animation : public BaseObject { public: - static inline const auto ANIMATION_CHANNEL_AMOUNT = 8; - static inline const TypeDescriptor typeDescription = { "Animation", false }; TypeDescriptor const& getTypeDescription() const override { return typeDescription; @@ -36,6 +34,7 @@ class Animation : public BaseObject { Animation(std::string name = std::string(), std::string id = std::string()) : BaseObject(name, id) { fillPropertyDescription(); + setChannelAmount(1); } void fillPropertyDescription() { @@ -54,7 +53,7 @@ class Animation : public BaseObject { Property, LinkEndAnnotation> progress_{0.0, {"Progress"}, {0.0, 1.0}, {}}; - Property animationChannels_{{}, {"Animation Channels"}}; + Property, DisplayNameAnnotation, ResizableArray> animationChannels_{{}, {"Animation Channels"}, {}}; Property outputs_{{}, {"Outputs"}}; }; diff --git a/datamodel/libUserTypes/include/user_types/AnimationChannel.h b/datamodel/libUserTypes/include/user_types/AnimationChannel.h index d62391b1..05b77f53 100644 --- a/datamodel/libUserTypes/include/user_types/AnimationChannel.h +++ b/datamodel/libUserTypes/include/user_types/AnimationChannel.h @@ -52,10 +52,10 @@ class AnimationChannel : public BaseObject { Property animationIndex_{{}, DisplayNameAnnotation("Animation Index")}; Property samplerIndex_{{}, DisplayNameAnnotation("Sampler Index")}; - raco::core::SharedAnimationSamplerData currentSamplerData_; + core::SharedAnimationSamplerData currentSamplerData_; private: - void createSamplerInfoBox(BaseContext& context, int animationAmount, int samplerAmount, bool unsupportedArray); + void createSamplerInfoBox(BaseContext& context, int animationAmount, int samplerAmount); }; using SAnimationChannel = std::shared_ptr; diff --git a/datamodel/libUserTypes/include/user_types/BaseObject.h b/datamodel/libUserTypes/include/user_types/BaseObject.h index 12ae8cd7..eea6755a 100644 --- a/datamodel/libUserTypes/include/user_types/BaseObject.h +++ b/datamodel/libUserTypes/include/user_types/BaseObject.h @@ -21,10 +21,16 @@ #include - namespace raco::user_types { using namespace raco::core; +// These are the available metadata categories. +// They are used as property names of the containers in the BaseObject::metaData_ property. +struct MetaDataCategories { + static inline const char* GLTF_EXTRAS{"gltfExtras"}; + static inline const char* MESH_INFO{"meshInfo"}; +}; + // scene object hierarchy as C++ classes: // - Value (without annotations) or Property (with annotations) data members allowed // - needs to provide ReflectionInterface -> automatic serialization & property browser etc interface @@ -32,19 +38,26 @@ using namespace raco::core; class BaseObject : public EditorObject { public: - BaseObject(BaseObject const& other) : EditorObject() { + BaseObject(BaseObject const& other) + : EditorObject(), + userTags_(other.userTags_), + metaData_(other.metaData_) { fillPropertyDescription(); } BaseObject(std::string name = std::string(), std::string id = std::string()) - : EditorObject(name, id) - { + : EditorObject(name, id) { fillPropertyDescription(); } void fillPropertyDescription() { + properties_.emplace_back("userTags", &userTags_); + properties_.emplace_back("metaData", &metaData_); } + Property userTags_{{}, {}, {}, {}, {"User Tags"}}; + + Property metaData_{{}, {"Meta Data"}}; }; -} \ No newline at end of file +} // namespace raco::user_types \ No newline at end of file diff --git a/datamodel/libUserTypes/include/user_types/EngineTypeAnnotation.h b/datamodel/libUserTypes/include/user_types/EngineTypeAnnotation.h index e0bef0fa..162b7acf 100644 --- a/datamodel/libUserTypes/include/user_types/EngineTypeAnnotation.h +++ b/datamodel/libUserTypes/include/user_types/EngineTypeAnnotation.h @@ -17,7 +17,7 @@ namespace raco::user_types { using namespace raco::data_storage; -class EngineTypeAnnotation : public raco::data_storage::AnnotationBase { +class EngineTypeAnnotation : public data_storage::AnnotationBase { public: static inline const TypeDescriptor typeDescription = {"EngineTypeAnnotation", false}; TypeDescriptor const& getTypeDescription() const override { @@ -29,7 +29,7 @@ class EngineTypeAnnotation : public raco::data_storage::AnnotationBase { EngineTypeAnnotation(EngineTypeAnnotation const& other) : AnnotationBase({{"engineType", &engineType_}}), engineType_(other.engineType_) {} - EngineTypeAnnotation(raco::core::EnginePrimitive engineType = raco::core::EnginePrimitive::Undefined) : AnnotationBase({{"engineType", &engineType_}}), + EngineTypeAnnotation(core::EnginePrimitive engineType = core::EnginePrimitive::Undefined) : AnnotationBase({{"engineType", &engineType_}}), engineType_(static_cast(engineType)) { } @@ -38,11 +38,11 @@ class EngineTypeAnnotation : public raco::data_storage::AnnotationBase { return *this; } - raco::core::EnginePrimitive type() const { - return static_cast(*engineType_); + core::EnginePrimitive type() const { + return static_cast(*engineType_); } - // This is a raco::core::EnginePrimitive + // This is a core::EnginePrimitive Value engineType_; }; diff --git a/datamodel/libUserTypes/include/user_types/Enumerations.h b/datamodel/libUserTypes/include/user_types/Enumerations.h index 0b7d1993..9346ae39 100644 --- a/datamodel/libUserTypes/include/user_types/Enumerations.h +++ b/datamodel/libUserTypes/include/user_types/Enumerations.h @@ -141,9 +141,9 @@ extern std::map enumDescriptionTextureMinSamplingMethod; extern std::map enumDescriptionTextureMagSamplingMethod; -// items match ramses::ETextureFormat +// As of Ramses 28 the item do _not_ match ramses::ETextureFormat anymore! +// You must use enumerationTranslationTextureFormat for translation. enum class ETextureFormat { - //Invalid = 0, R8 = 1, RG8 = 2, RGB8 = 3, @@ -167,7 +167,8 @@ enum class ETextureFormat { extern std::map enumDescriptionTextureFormat; -// items match ramses::ERenderBufferFormat +// As of Ramses 28 the item do _not_ match ramses::ERenderBufferFormat anymore! +// You must use enumerationTranslationRenderBufferFormat for translation. enum class ERenderBufferFormat { RGBA4 = 0, R8, @@ -184,7 +185,9 @@ enum class ERenderBufferFormat { RGBA32F, Depth24, - Depth24_Stencil8 + Depth24_Stencil8, + Depth16, + Depth32 }; extern std::map enumDescriptionRenderBufferFormat; diff --git a/datamodel/libUserTypes/include/user_types/LuaInterface.h b/datamodel/libUserTypes/include/user_types/LuaInterface.h index c4e40880..cf3f389f 100644 --- a/datamodel/libUserTypes/include/user_types/LuaInterface.h +++ b/datamodel/libUserTypes/include/user_types/LuaInterface.h @@ -47,9 +47,9 @@ class LuaInterface : public BaseObject { Property uri_{std::string{}, {"Lua interface files(*.lua);; All files (*.*)", core::PathManager::FolderTypeKeys::Interface}, DisplayNameAnnotation("URI")}; - Property stdModules_{{}, {"Standard Modules"}, FeatureLevel{5}}; + Property stdModules_{{}, {"Standard Modules"}}; - Property luaModules_{{}, DisplayNameAnnotation("Modules"), FeatureLevel{5}}; + Property luaModules_{{}, DisplayNameAnnotation("Modules")}; Property inputs_{{}, DisplayNameAnnotation("Inputs"), {}, {}}; diff --git a/datamodel/libUserTypes/include/user_types/Mesh.h b/datamodel/libUserTypes/include/user_types/Mesh.h index 4e27fc86..0f76f924 100644 --- a/datamodel/libUserTypes/include/user_types/Mesh.h +++ b/datamodel/libUserTypes/include/user_types/Mesh.h @@ -58,8 +58,6 @@ class Mesh : public BaseObject { return mesh_; } - std::map metaData_; - private: SharedMeshData mesh_; diff --git a/datamodel/libUserTypes/include/user_types/MeshNode.h b/datamodel/libUserTypes/include/user_types/MeshNode.h index a972bd70..5522bd3d 100644 --- a/datamodel/libUserTypes/include/user_types/MeshNode.h +++ b/datamodel/libUserTypes/include/user_types/MeshNode.h @@ -52,7 +52,8 @@ class MeshNode : public Node { SMaterial getMaterial(size_t materialSlot); bool materialPrivate(size_t materialSlot); Table* getUniformContainer(size_t materialSlot); - + BlendOptions* getOptions(size_t materialSlot); + ValueHandle getMaterialHandle(size_t materialSlot); ValueHandle getMaterialPrivateHandle(size_t materialSlot); ValueHandle getUniformContainerHandle(size_t materialSlot); @@ -61,7 +62,7 @@ class MeshNode : public Node { Property mesh_{nullptr, DisplayNameAnnotation("Mesh")}; Property materials_{{}, DisplayNameAnnotation("Materials")}; - Property, DisplayNameAnnotation, LinkEndAnnotation> instanceCount_{1, RangeAnnotation(1, 20), DisplayNameAnnotation("Instance Count"), {5}}; + Property, DisplayNameAnnotation, LinkEndAnnotation> instanceCount_{1, RangeAnnotation(1, 20), DisplayNameAnnotation("Instance Count"), {}}; private: std::vector getMaterialNames(); diff --git a/datamodel/libUserTypes/include/user_types/Node.h b/datamodel/libUserTypes/include/user_types/Node.h index d17461d2..3c196cb5 100644 --- a/datamodel/libUserTypes/include/user_types/Node.h +++ b/datamodel/libUserTypes/include/user_types/Node.h @@ -34,7 +34,8 @@ class Node : public BaseObject { enabled_(other.enabled_), translation_(other.translation_), rotation_(other.rotation_), - scaling_(other.scaling_) { + scaling_(other.scaling_), + editorVisibility_ (other.editorVisibility_) { fillPropertyDescription(); } @@ -50,6 +51,7 @@ class Node : public BaseObject { properties_.emplace_back("translation", &translation_); properties_.emplace_back("rotation", &rotation_); properties_.emplace_back("scaling", &scaling_); + properties_.emplace_back("editorVisibility", &editorVisibility_); } void onAfterContextActivated(BaseContext& context) override { @@ -66,11 +68,16 @@ class Node : public BaseObject { Property visibility_{true, DisplayNameAnnotation("Visibility"), {}}; - Property enabled_{true, DisplayNameAnnotation("Enabled"), {2}, FeatureLevel(2)}; + Property enabled_{true, DisplayNameAnnotation("Enabled"), {}}; Property translation_{Vec3f(0.0, 1.0, -100, 100), DisplayNameAnnotation("Translation"), {}}; Property scaling_{Vec3f(1.0, 0.1, 0.1, 100), DisplayNameAnnotation("Scaling"), {}}; Property rotation_{Vec3f(0.0, 5.0, -360.0, 360.0), DisplayNameAnnotation("Rotation"), {}}; + + /** + * @brief The editor visibility controls the visibility of objects in the abstract scene view. + */ + Property editorVisibility_{true, {}, {}}; }; } // namespace raco::user_types diff --git a/datamodel/libUserTypes/include/user_types/PerspectiveCamera.h b/datamodel/libUserTypes/include/user_types/PerspectiveCamera.h index 3b3be179..909214d1 100644 --- a/datamodel/libUserTypes/include/user_types/PerspectiveCamera.h +++ b/datamodel/libUserTypes/include/user_types/PerspectiveCamera.h @@ -42,7 +42,7 @@ class PerspectiveCamera : public BaseCamera { void onAfterValueChanged(BaseContext& context, ValueHandle const& value) override; - Property frustumType_{static_cast(EFrustumType::Aspect_FieldOfView), {"Frustum Type"}, {EUserTypeEnumerations::FrustumType}, {2}}; + Property frustumType_{static_cast(EFrustumType::Aspect_FieldOfView), {"Frustum Type"}, {EUserTypeEnumerations::FrustumType}}; Property frustum_{{}, {"Frustum"}, {}}; private: diff --git a/datamodel/libUserTypes/include/user_types/RenderBuffer.h b/datamodel/libUserTypes/include/user_types/RenderBuffer.h index 9dd53f4c..ec815585 100644 --- a/datamodel/libUserTypes/include/user_types/RenderBuffer.h +++ b/datamodel/libUserTypes/include/user_types/RenderBuffer.h @@ -41,7 +41,8 @@ class RenderBuffer : public TextureSampler2DBase { bool areSamplingParametersSupported(EngineInterface const& engineInterface) const { auto format = static_cast(*format_); - return format != ERenderBufferFormat::Depth24 && format != ERenderBufferFormat::Depth24_Stencil8; + return format != ERenderBufferFormat::Depth24 && format != ERenderBufferFormat::Depth24_Stencil8 && + format != ERenderBufferFormat::Depth16 && format != ERenderBufferFormat::Depth32; } bool isSamplingProperty(ValueHandle const& valueHandle) const { diff --git a/datamodel/libUserTypes/include/user_types/RenderPass.h b/datamodel/libUserTypes/include/user_types/RenderPass.h index f2afe7ee..4a7824d4 100644 --- a/datamodel/libUserTypes/include/user_types/RenderPass.h +++ b/datamodel/libUserTypes/include/user_types/RenderPass.h @@ -31,14 +31,7 @@ class RenderPass : public BaseObject { : BaseObject(other), target_(other.target_), camera_(other.camera_), - layer0_(other.layer0_), - layer1_(other.layer1_), - layer2_(other.layer2_), - layer3_(other.layer3_), - layer4_(other.layer4_), - layer5_(other.layer5_), - layer6_(other.layer6_), - layer7_(other.layer7_), + layers_(other.layers_), enabled_(other.enabled_), renderOnce_(other.renderOnce_), renderOrder_(other.renderOrder_), @@ -51,20 +44,13 @@ class RenderPass : public BaseObject { RenderPass(const std::string& name, const std::string& id) : BaseObject(name, id) { fillPropertyDescription(); + layers_->resize(1); } void fillPropertyDescription() { properties_.emplace_back("target", &target_); properties_.emplace_back("camera", &camera_); - properties_.emplace_back("layer0", &layer0_); - properties_.emplace_back("layer1", &layer1_); - properties_.emplace_back("layer2", &layer2_); - properties_.emplace_back("layer3", &layer3_); - properties_.emplace_back("layer4", &layer4_); - properties_.emplace_back("layer5", &layer5_); - properties_.emplace_back("layer6", &layer6_); - properties_.emplace_back("layer7", &layer7_); - + properties_.emplace_back("layers", &layers_); properties_.emplace_back("enabled", &enabled_); properties_.emplace_back("renderOnce", &renderOnce_); properties_.emplace_back("renderOrder", &renderOrder_); @@ -76,23 +62,17 @@ class RenderPass : public BaseObject { bool isClearTargetProperty(ValueHandle const& handle) const; - Property target_{{}, {"Target"}, {"Default Framebuffer"}}; + + Property target_{{}, {"Target"}, {"Default Framebuffer"}}; Property camera_{{}, {"Camera"}}; - Property layer0_{{}, {"Layer 0"}}; - Property layer1_{{}, {"Layer 1"}, {}}; - Property layer2_{{}, {"Layer 2"}, {}}; - Property layer3_{{}, {"Layer 3"}, {}}; - Property layer4_{{}, {"Layer 4"}, {}}; - Property layer5_{{}, {"Layer 5"}, {}}; - Property layer6_{{}, {"Layer 6"}, {}}; - Property layer7_{{}, {"Layer 7"}, {}}; + Property, DisplayNameAnnotation, ExpectEmptyReference, ResizableArray> layers_{{}, {"Layers"}, {}, {}}; - Property enabled_{true, {"Enabled"}, {2}}; - Property renderOnce_{false, {"Render Once"}, {2}, {2}}; - Property renderOrder_{1, {"Render Order"}, {2}}; + Property enabled_{true, {"Enabled"}, {}}; + Property renderOnce_{false, {"Render Once"}, {}}; + Property renderOrder_{1, {"Render Order"}, {}}; - Property clearColor_{{}, {"Clear Color"}, {2}}; + Property clearColor_{{}, {"Clear Color"}, {}}; Property enableClearColor_{true, {"Enable Clear Color"}}; Property enableClearDepth_{true, {"Enable Clear Depth"}}; diff --git a/datamodel/libUserTypes/include/user_types/RenderTarget.h b/datamodel/libUserTypes/include/user_types/RenderTarget.h index 0798c00f..82d86af0 100644 --- a/datamodel/libUserTypes/include/user_types/RenderTarget.h +++ b/datamodel/libUserTypes/include/user_types/RenderTarget.h @@ -15,7 +15,22 @@ namespace raco::user_types { -class RenderTarget : public BaseObject { +class RenderTargetBase : public BaseObject { +public: + static inline const TypeDescriptor typeDescription = {"RenderTargetBase", true}; + TypeDescriptor const& getTypeDescription() const override { + return typeDescription; + } + + RenderTargetBase(std::string name = std::string(), std::string id = std::string()) + : BaseObject(name, id) { + } +}; + +using SRenderTargetBase = std::shared_ptr; + + +class RenderTarget : public RenderTargetBase { public: static inline const TypeDescriptor typeDescription = {"RenderTarget", true}; TypeDescriptor const& getTypeDescription() const override { @@ -23,71 +38,53 @@ class RenderTarget : public BaseObject { } RenderTarget(RenderTarget const& other) - : BaseObject(other), - buffer0_(other.buffer0_), - buffer1_(other.buffer1_), - buffer2_(other.buffer2_), - buffer3_(other.buffer3_), - buffer4_(other.buffer4_), - buffer5_(other.buffer5_), - buffer6_(other.buffer6_), - buffer7_(other.buffer7_), - bufferMS0_(other.bufferMS0_), - bufferMS1_(other.bufferMS1_), - bufferMS2_(other.bufferMS2_), - bufferMS3_(other.bufferMS3_), - bufferMS4_(other.bufferMS4_), - bufferMS5_(other.bufferMS5_), - bufferMS6_(other.bufferMS6_), - bufferMS7_(other.bufferMS7_) { + : RenderTargetBase(other), + buffers_(other.buffers_) { fillPropertyDescription(); } - RenderTarget(const std::string& name, const std::string& id) : BaseObject(name, id) { + RenderTarget(const std::string& name, const std::string& id) : RenderTargetBase(name, id) { fillPropertyDescription(); + buffers_->resize(1); } void fillPropertyDescription() { - properties_.emplace_back("buffer0", &buffer0_); - properties_.emplace_back("buffer1", &buffer1_); - properties_.emplace_back("buffer2", &buffer2_); - properties_.emplace_back("buffer3", &buffer3_); - properties_.emplace_back("buffer4", &buffer4_); - properties_.emplace_back("buffer5", &buffer5_); - properties_.emplace_back("buffer6", &buffer6_); - properties_.emplace_back("buffer7", &buffer7_); - properties_.emplace_back("bufferMS0", &bufferMS0_); - properties_.emplace_back("bufferMS1", &bufferMS1_); - properties_.emplace_back("bufferMS2", &bufferMS2_); - properties_.emplace_back("bufferMS3", &bufferMS3_); - properties_.emplace_back("bufferMS4", &bufferMS4_); - properties_.emplace_back("bufferMS5", &bufferMS5_); - properties_.emplace_back("bufferMS6", &bufferMS6_); - properties_.emplace_back("bufferMS7", &bufferMS7_); + properties_.emplace_back("buffers", &buffers_); } - // TODO: want variable number of buffers - //Property buffers_{{}, {}, {"Buffers"}}; - - Property buffer0_{{}, {"Buffer 0"}, {}}; - Property buffer1_{{}, {"Buffer 1"}, {}}; - Property buffer2_{{}, {"Buffer 2"}, {}}; - Property buffer3_{{}, {"Buffer 3"}, {}}; - Property buffer4_{{}, {"Buffer 4"}, {}}; - Property buffer5_{{}, {"Buffer 5"}, {}}; - Property buffer6_{{}, {"Buffer 6"}, {}}; - Property buffer7_{{}, {"Buffer 7"}, {}}; - Property bufferMS0_{{}, {"Buffer (Multisampled) 0"}, {}}; - Property bufferMS1_{{}, {"Buffer (Multisampled) 1"}, {}}; - Property bufferMS2_{{}, {"Buffer (Multisampled) 2"}, {}}; - Property bufferMS3_{{}, {"Buffer (Multisampled) 3"}, {}}; - Property bufferMS4_{{}, {"Buffer (Multisampled) 4"}, {}}; - Property bufferMS5_{{}, {"Buffer (Multisampled) 5"}, {}}; - Property bufferMS6_{{}, {"Buffer (Multisampled) 6"}, {}}; - Property bufferMS7_{{}, {"Buffer (Multisampled) 7"}, {}}; + + Property, DisplayNameAnnotation, ExpectEmptyReference, ResizableArray> buffers_{{}, {"Buffers"}, {}, {}}; }; using SRenderTarget = std::shared_ptr; + +class RenderTargetMS : public RenderTargetBase { +public: + static inline const TypeDescriptor typeDescription = {"RenderTargetMS", true}; + TypeDescriptor const& getTypeDescription() const override { + return typeDescription; + } + + RenderTargetMS(RenderTargetMS const& other) + : RenderTargetBase(other), + buffers_(other.buffers_) { + fillPropertyDescription(); + } + + RenderTargetMS(const std::string& name, const std::string& id) : RenderTargetBase(name, id) { + fillPropertyDescription(); + buffers_->resize(1); + } + + void fillPropertyDescription() { + properties_.emplace_back("buffers", &buffers_); + } + + Property, DisplayNameAnnotation, ExpectEmptyReference, ResizableArray> buffers_{{}, {"Buffers"}, {}, {}}; +}; + +using SRenderTargetMS = std::shared_ptr; + } // namespace raco::user_types #pragma once diff --git a/datamodel/libUserTypes/include/user_types/Skin.h b/datamodel/libUserTypes/include/user_types/Skin.h index 395c7ae7..a6274b35 100644 --- a/datamodel/libUserTypes/include/user_types/Skin.h +++ b/datamodel/libUserTypes/include/user_types/Skin.h @@ -11,12 +11,13 @@ #include "user_types/BaseObject.h" #include "user_types/MeshNode.h" +#include "core/CoreAnnotations.h" namespace raco::user_types { class Skin : public BaseObject { public: - static inline const TypeDescriptor typeDescription = {"Skin", false, 4}; + static inline const TypeDescriptor typeDescription = {"Skin", false}; TypeDescriptor const& getTypeDescription() const override { return typeDescription; } @@ -33,6 +34,7 @@ class Skin : public BaseObject { Skin(std::string name = std::string(), std::string id = std::string()) : BaseObject(name, id) { fillPropertyDescription(); + setupTargetProperties(1); } void fillPropertyDescription() { @@ -42,18 +44,16 @@ class Skin : public BaseObject { properties_.emplace_back("skinIndex", &skinIndex_); } - void onAfterContextActivated(BaseContext& context) override; void onAfterValueChanged(BaseContext& context, ValueHandle const& value) override; void updateFromExternalFile(BaseContext& context) override; // To account for multi-material meshnodes in gltf files (multiple primitives in single mesh in gltf) // the Skin can contain target multiple meshnodes. - Property targets_{{}, {"Target MeshNodes"}}; + Property, DisplayNameAnnotation, ResizableArray> targets_{{}, {"Target MeshNodes"}, {}}; - // TODO want variable number of properties - // contains SNode properties - Property joints_{{}, {"Joint Nodes"}}; + // Joints are not user-resizable since the joint set is read from the gltf-file + Property, DisplayNameAnnotation> joints_{{}, {"Joint Nodes"}}; Property uri_{std::string(), {"glTF files (*.glTF *.glb);;All Files (*.*)", core::PathManager::FolderTypeKeys::Mesh}, DisplayNameAnnotation("URI")}; Property skinIndex_{0, {"Skin Index"}}; diff --git a/datamodel/libUserTypes/include/user_types/SyncTableWithEngineInterface.h b/datamodel/libUserTypes/include/user_types/SyncTableWithEngineInterface.h index 91042e31..5d7505d6 100644 --- a/datamodel/libUserTypes/include/user_types/SyncTableWithEngineInterface.h +++ b/datamodel/libUserTypes/include/user_types/SyncTableWithEngineInterface.h @@ -17,20 +17,20 @@ namespace raco::user_types { -using raco::core::PropertyInterface; -using raco::core::PropertyInterfaceList; +using core::PropertyInterface; +using core::PropertyInterfaceList; // To cache properties nested inside Tables we use a /-separated property path as string. -using OutdatedPropertiesStore = std::map, - std::unique_ptr>; +using OutdatedPropertiesStore = std::map, + std::unique_ptr>; -void syncTableWithEngineInterface(raco::core::BaseContext& context, const PropertyInterfaceList& interface, const raco::core::ValueHandle& handle, OutdatedPropertiesStore& outdatedPropertiesStore, bool linkStart, bool linkEnd); +void syncTableWithEngineInterface(core::BaseContext& context, const PropertyInterfaceList& interface, const core::ValueHandle& handle, OutdatedPropertiesStore& outdatedPropertiesStore, bool linkStart, bool linkEnd); -void syncTableWithEngineInterface(raco::core::BaseContext& context, const PropertyInterfaceList& interface, const raco::core::ValueHandle& handle, OutdatedPropertiesStore& outdatedPropertiesStore, bool linkStart, bool linkEnd, - std::function cacheLookupFunc); +void syncTableWithEngineInterface(core::BaseContext& context, const PropertyInterfaceList& interface, const core::ValueHandle& handle, OutdatedPropertiesStore& outdatedPropertiesStore, bool linkStart, bool linkEnd, + std::function cacheLookupFunc); template -raco::data_storage::ValueBase* createDynamicProperty(raco::core::EnginePrimitive type); +data_storage::ValueBase* createDynamicProperty(core::EnginePrimitive type); std::string dataModelPropNameForLogicEnginePropName(const std::string& propName, size_t index); diff --git a/datamodel/libUserTypes/include/user_types/Texture.h b/datamodel/libUserTypes/include/user_types/Texture.h index a4c0c353..b9f932cf 100644 --- a/datamodel/libUserTypes/include/user_types/Texture.h +++ b/datamodel/libUserTypes/include/user_types/Texture.h @@ -24,10 +24,12 @@ class Texture : public TextureSampler2DBase { Texture(Texture const& other) : TextureSampler2DBase(other), uri_(other.uri_), flipTexture_(other.flipTexture_), generateMipmaps_(other.generateMipmaps_), textureFormat_(other.textureFormat_) { fillPropertyDescription(); + addTexturePreviewProperty(); } Texture(const std::string& name, const std::string& id) : TextureSampler2DBase(name, id) { fillPropertyDescription(); + addTexturePreviewProperty(); } void fillPropertyDescription() { @@ -39,6 +41,7 @@ class Texture : public TextureSampler2DBase { properties_.emplace_back("level2uri", &level2uri_); properties_.emplace_back("level3uri", &level3uri_); properties_.emplace_back("level4uri", &level4uri_); + properties_.emplace_back("preview", &preview_); } void onAfterContextActivated(BaseContext& context) override; @@ -57,9 +60,12 @@ class Texture : public TextureSampler2DBase { Property level3uri_{std::string{}, {"Image files(*.png);; All files (*.*)", core::PathManager::FolderTypeKeys::Image}, DisplayNameAnnotation{"Level 3 URI"}}; Property level4uri_{std::string{}, {"Image files(*.png);; All files (*.*)", core::PathManager::FolderTypeKeys::Image}, DisplayNameAnnotation{"Level 4 URI"}}; + Property preview_{{}, {"Preview"}, {}, {}}; + private: void validateURIs(BaseContext& context); void validateMipmapLevel(BaseContext& context); + void addTexturePreviewProperty(); }; using STexture = std::shared_ptr; diff --git a/datamodel/libUserTypes/include/user_types/UserObjectFactory.h b/datamodel/libUserTypes/include/user_types/UserObjectFactory.h index b73a5b61..15996d42 100644 --- a/datamodel/libUserTypes/include/user_types/UserObjectFactory.h +++ b/datamodel/libUserTypes/include/user_types/UserObjectFactory.h @@ -24,6 +24,9 @@ class DefaultResourceDirectories; namespace raco::user_types { +class AnimationChannel; +using SAnimationChannel = std::shared_ptr; + class Mesh; using SMesh = std::shared_ptr; @@ -57,8 +60,8 @@ using SRenderBufferMS = std::shared_ptr; class RenderLayer; using SRenderLayer = std::shared_ptr; -class RenderTarget; -using SRenderTarget= std::shared_ptr; +class RenderTargetBase; +using SRenderTargetBase = std::shared_ptr; class Prefab; using SPrefab = std::shared_ptr; @@ -84,7 +87,7 @@ struct tuple_has_type> : std::disjunction }; -class UserObjectFactory : public raco::core::UserObjectFactoryInterface { +class UserObjectFactory : public core::UserObjectFactoryInterface { public: // Master list of all Property types that can be deserialized. // Contains @@ -96,6 +99,11 @@ class UserObjectFactory : public raco::core::UserObjectFactoryInterface { // - this only contains properties of the current data model unlike ProxyObjectFactory::PropertyTypeMapType // which contains in addition properties contained in old data model version to make sure // these can be deserialized as input for the migration code. + // + // Constraints: + // - the annotation types in a Property should always be given in alphabetical order to ensure + // that we don't create multiple different types with the same semantic content. + // using PropertyTypeMapType = std::tuple< Property, @@ -183,7 +191,15 @@ class UserObjectFactory : public raco::core::UserObjectFactoryInterface { Property, Property, + // BaseObject + // dynamic: metadata category tables: + Property, + + // Animation + Property, DisplayNameAnnotation, ResizableArray>, + // EditorObject + Property, ArraySemanticAnnotation, HiddenProperty>, Property, Property, Property, @@ -193,7 +209,6 @@ class UserObjectFactory : public raco::core::UserObjectFactoryInterface { Property, Property, Property, - Property, Property, // MeshNode @@ -216,8 +231,6 @@ class UserObjectFactory : public raco::core::UserObjectFactoryInterface { // LuaInterface Property, - Property, - Property, // BaseCamera Property, @@ -226,7 +239,6 @@ class UserObjectFactory : public raco::core::UserObjectFactoryInterface { Property, DisplayNameAnnotation, LinkEndAnnotation>, // PerspectiveCamera - Property, // PerspectiveFrustum Property, LinkEndAnnotation>, @@ -238,8 +250,9 @@ class UserObjectFactory : public raco::core::UserObjectFactoryInterface { Property, DisplayNameAnnotation>, // RenderPass - Property, + Property, Property, + Property, DisplayNameAnnotation, ExpectEmptyReference, ResizableArray>, Property, Property, Property, @@ -253,13 +266,17 @@ class UserObjectFactory : public raco::core::UserObjectFactoryInterface { Property, // RenderTarget + Property, DisplayNameAnnotation, ExpectEmptyReference, ResizableArray>, + Property, DisplayNameAnnotation, ExpectEmptyReference, ResizableArray>, Property, Property, Property, // Skin + Property, DisplayNameAnnotation, ResizableArray>, + Property, DisplayNameAnnotation>, Property, - + // Texture Property, @@ -321,6 +338,10 @@ class UserObjectFactory : public raco::core::UserObjectFactoryInterface { void addType() { types_[T::typeDescription.typeName] = {T::typeDescription, createObjectInternal, createValueInternal}; } + template + void addProperty() { + properties_[T().typeName()] = []() { return new T(); }; + } UserObjectFactory(); diff --git a/datamodel/libUserTypes/include/user_types/UserTypeAnnotations.h b/datamodel/libUserTypes/include/user_types/UserTypeAnnotations.h new file mode 100644 index 00000000..12cb4e2e --- /dev/null +++ b/datamodel/libUserTypes/include/user_types/UserTypeAnnotations.h @@ -0,0 +1,33 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "data_storage/AnnotationBase.h" + +namespace raco::user_types { + +class TexturePreviewEditorAnnotation : public data_storage::AnnotationBase { +public: + static inline const TypeDescriptor typeDescription = {"TexturePreviewEditorAnnotation", false}; + TypeDescriptor const& getTypeDescription() const override { + return typeDescription; + } + bool serializationRequired() const override { + return false; + } + TexturePreviewEditorAnnotation(const TexturePreviewEditorAnnotation& other) : AnnotationBase({}) {} + TexturePreviewEditorAnnotation() : AnnotationBase({}) {} + + TexturePreviewEditorAnnotation& operator=(const TexturePreviewEditorAnnotation& other) { + return *this; + } +}; + +} // namespace raco::user_types \ No newline at end of file diff --git a/datamodel/libUserTypes/src/Animation.cpp b/datamodel/libUserTypes/src/Animation.cpp index c7aa617c..e3899df9 100644 --- a/datamodel/libUserTypes/src/Animation.cpp +++ b/datamodel/libUserTypes/src/Animation.cpp @@ -17,16 +17,6 @@ namespace raco::user_types { void Animation::onAfterContextActivated(BaseContext& context) { - // Only set default animation channel amount when animationChannels is empty (ie. created by user) - // TODO: the initial creation of the channel should be in the constructor. - // BUT: that doesn't work since the deserialization will not handle this case correctly. - // The deserialization will only create but not remove properties in Tables. - // Animation objects with less than ANIMATION_CHANNEL_AMOUNT channels created by BaseContext::insertAssetScenegraph - // will then be loaded incorrectly. - // We would need to fix the serialization if we want to move the setChannelAmount to the constructor. - if (animationChannels_.asTable().size() == 0) { - setChannelAmount(ANIMATION_CHANNEL_AMOUNT); - } syncOutputInterface(context); } @@ -35,12 +25,8 @@ void Animation::onAfterReferencedObjectChanged(BaseContext& context, ValueHandle } void Animation::onAfterValueChanged(BaseContext& context, ValueHandle const& value) { - const auto &channelTable = animationChannels_.asTable(); - for (auto channelIndex = 0; channelIndex < channelTable.size(); ++channelIndex) { - if (value == ValueHandle{shared_from_this(), {"animationChannels", fmt::format("Channel {}", channelIndex)}}) { - syncOutputInterface(context); - return; - } + if (ValueHandle(shared_from_this(), &Animation::animationChannels_).contains(value)) { + syncOutputInterface(context); } if (value == ValueHandle(shared_from_this(), &Animation::objectName_)) { @@ -53,19 +39,20 @@ void Animation::syncOutputInterface(BaseContext& context) { OutdatedPropertiesStore dummyCache{}; - auto &channelTable = animationChannels_.asTable(); - for (auto channelIndex = 0; channelIndex < channelTable.size(); ++channelIndex) { - context.errors().removeError({shared_from_this(), {"animationChannels", fmt::format("Channel {}", channelIndex)}}); - auto channelRef = channelTable[channelIndex]->asRef(); - if (channelRef) { - auto samp = channelRef->as(); - if (samp->currentSamplerData_) { - auto prop = samp->getOutputProperty(); + for (auto channelIndex = 0; channelIndex < animationChannels_->size(); ++channelIndex) { + ValueHandle channelHandle = ValueHandle(shared_from_this(), &Animation::animationChannels_)[channelIndex]; + auto channel = **animationChannels_->get(channelIndex); + if (channel) { + if (channel->currentSamplerData_) { + auto prop = channel->getOutputProperty(); prop.name = createAnimChannelOutputName(channelIndex, prop.name); outputs.emplace_back(prop); + context.errors().removeError(channelHandle); } else { - context.errors().addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::ERROR, {shared_from_this(), {"animationChannels", fmt::format("Channel {}", channelIndex)}}, fmt::format("Invalid animation channel.")); + context.errors().addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, channelHandle, "Invalid animation channel."); } + } else { + context.errors().removeError(channelHandle); } } @@ -79,10 +66,7 @@ std::string Animation::createAnimChannelOutputName(int channelIndex, const std:: } void Animation::setChannelAmount(int amount) { - animationChannels_->clear(); - for (auto i = 0; i < amount; ++i) { - animationChannels_->addProperty(fmt::format("Channel {}", i), new Value()); - } + animationChannels_->resize(amount); } } // namespace raco::user_types \ No newline at end of file diff --git a/datamodel/libUserTypes/src/AnimationChannel.cpp b/datamodel/libUserTypes/src/AnimationChannel.cpp index 14260b7a..646b112e 100644 --- a/datamodel/libUserTypes/src/AnimationChannel.cpp +++ b/datamodel/libUserTypes/src/AnimationChannel.cpp @@ -25,43 +25,45 @@ void AnimationChannel::onAfterValueChanged(BaseContext& context, ValueHandle con } } -raco::core::PropertyInterface AnimationChannel::getOutputProperty() const { - if (currentSamplerData_->getOutputComponentType() == EnginePrimitive::Array) { +core::PropertyInterface AnimationChannel::getOutputProperty() const { + if (currentSamplerData_->componentType == EnginePrimitive::Array) { return PropertyInterface::makeArrayOf(objectName(), EnginePrimitive::Double, currentSamplerData_->getOutputComponentSize()); } - return {objectName(), currentSamplerData_->getOutputComponentType()}; + return {objectName(), currentSamplerData_->componentType}; } void AnimationChannel::updateFromExternalFile(BaseContext& context) { + // TODO(error) try to avoid unnecessary error item updates context.errors().removeError({shared_from_this()}); - context.errors().removeError({shared_from_this(), &AnimationChannel::uri_}); + + ValueHandle uriHandle{shared_from_this(), &AnimationChannel::uri_}; context.errors().removeError({shared_from_this(), &AnimationChannel::animationIndex_}); context.errors().removeError({shared_from_this(), &AnimationChannel::samplerIndex_}); currentSamplerData_.reset(); context.changeMultiplexer().recordPreviewDirty(shared_from_this()); - auto uriAbsPath = PathQueries::resolveUriPropertyToAbsolutePath(*context.project(), {shared_from_this(), {"uri"}}); - if (!(validateURI(context, {shared_from_this(), &AnimationChannel::uri_})) || uriAbsPath.empty()) { + if (!validateURI(context, uriHandle)) { return; } + auto uriAbsPath = PathQueries::resolveUriPropertyToAbsolutePath(*context.project(), uriHandle); auto scenegraph = context.meshCache()->getMeshScenegraph(uriAbsPath); if (!scenegraph) { auto fileErrorText = context.meshCache()->getMeshError(uriAbsPath); auto errorText = fileErrorText.empty() ? "Selected Animation Source file is not valid." : fmt::format("Error while loading Animation Source:\n\n{}", fileErrorText); - context.errors().addError(core::ErrorCategory::PARSING, core::ErrorLevel::ERROR, {shared_from_this(), {"uri"}}, errorText); + context.errors().addError(core::ErrorCategory::PARSING, core::ErrorLevel::ERROR, uriHandle, errorText); return; } auto animationAmount = scenegraph->animations.size(); if (animationAmount == 0) { - context.errors().addError(ErrorCategory::GENERAL, ErrorLevel::WARNING, ValueHandle{shared_from_this(), {"uri"}}, "Selected Animation Source does not contain animations."); + context.errors().addError(ErrorCategory::GENERAL, ErrorLevel::WARNING, uriHandle, "Selected Animation Source does not contain animations."); return; } - auto animIndex = ValueHandle{shared_from_this(), &AnimationChannel::animationIndex_}.asInt(); + auto animIndex = *animationIndex_; if (animIndex < 0 || animIndex >= animationAmount) { auto errorText = fmt::format("Selected animation index is outside of valid range [{}, {}]", 0, animationAmount - 1); context.errors().addError(ErrorCategory::GENERAL, ErrorLevel::ERROR, ValueHandle{shared_from_this(), &AnimationChannel::animationIndex_}, errorText); @@ -69,7 +71,7 @@ void AnimationChannel::updateFromExternalFile(BaseContext& context) { } auto samplerAmount = scenegraph->animationSamplers[animIndex].size(); - auto animSamplerIndex = ValueHandle{shared_from_this(), &AnimationChannel::samplerIndex_}.asInt(); + auto animSamplerIndex = *samplerIndex_; if (animSamplerIndex < 0 || animSamplerIndex >= samplerAmount) { auto errorText = fmt::format("Selected animation sampler index is outside of valid range [{}, {}]", 0, samplerAmount - 1); context.errors().addError(ErrorCategory::GENERAL, ErrorLevel::ERROR, ValueHandle{shared_from_this(), &AnimationChannel::samplerIndex_}, errorText); @@ -82,49 +84,43 @@ void AnimationChannel::updateFromExternalFile(BaseContext& context) { auto errorText = fileErrorText.empty() ? "Selected Animation Source does not contain valid animation samplers." : fmt::format("Error while loading Animation Source:\n\n{}", fileErrorText); - context.errors().addError(core::ErrorCategory::PARSING, core::ErrorLevel::ERROR, {shared_from_this(), {"uri"}}, errorText); + context.errors().addError(core::ErrorCategory::PARSING, core::ErrorLevel::ERROR, uriHandle, errorText); currentSamplerData_.reset(); return; } - if (currentSamplerData_->input.empty()) { + if (currentSamplerData_->timeStamps.empty()) { context.errors().addError(core::ErrorCategory::PARSING, core::ErrorLevel::ERROR, {shared_from_this(), &AnimationChannel::samplerIndex_}, "Selected animation sampler does not contain valid input data."); currentSamplerData_.reset(); return; } - if (currentSamplerData_->output.empty()) { + if (currentSamplerData_->keyFrames.empty()) { context.errors().addError(core::ErrorCategory::PARSING, core::ErrorLevel::ERROR, {shared_from_this(), &AnimationChannel::samplerIndex_}, "Selected animation sampler does not contain valid output data."); currentSamplerData_.reset(); return; } - bool unsupportedArray = currentSamplerData_->getOutputComponentType() == EnginePrimitive::Array && context.project()->featureLevel() < 4; - - createSamplerInfoBox(context, animationAmount, samplerAmount, unsupportedArray); + createSamplerInfoBox(context, animationAmount, samplerAmount); } -void AnimationChannel::createSamplerInfoBox(BaseContext& context, int animationAmount, int samplerAmount, bool unsupportedArray) { +void AnimationChannel::createSamplerInfoBox(BaseContext& context, int animationAmount, int samplerAmount) { std::string samplerInfoText; - if (unsupportedArray) { - samplerInfoText.append(fmt::format("Can't create RamsesLogic DataArrays for AnimationChannel '{}': array samplers are only supported at feature level >= 4.\n\n", objectName())); - } samplerInfoText.append(fmt::format("Current Animation: {} of {}\n", *animationIndex_ + 1, animationAmount)); samplerInfoText.append(fmt::format("Current Sampler: {} of {}\n\n", *samplerIndex_ + 1, samplerAmount)); - samplerInfoText.append(fmt::format("Keyframes (non-interpolated): {}\n", currentSamplerData_->input.size())); - auto type = currentSamplerData_->getOutputComponentType(); + samplerInfoText.append(fmt::format("Keyframes (non-interpolated): {}\n", currentSamplerData_->timeStamps.size())); + auto type = currentSamplerData_->componentType; samplerInfoText.append(fmt::format("Component Type: {}\n", type)); if (type == EnginePrimitive::Array) { samplerInfoText.append(fmt::format("Component Size: {}\n", currentSamplerData_->getOutputComponentSize())); } samplerInfoText.append(fmt::format("Interpolation: {}\n", currentSamplerData_->interpolation)); - samplerInfoText.append(fmt::format("Start: {:.2f} s\n", currentSamplerData_->input.front())); - samplerInfoText.append(fmt::format("End: {:.2f} s\n", currentSamplerData_->input.back())); - samplerInfoText.append(fmt::format("Duration: {:.2f} s", currentSamplerData_->input.back() - currentSamplerData_->input.front())); + samplerInfoText.append(fmt::format("Start: {:.2f} s\n", currentSamplerData_->timeStamps.front())); + samplerInfoText.append(fmt::format("End: {:.2f} s\n", currentSamplerData_->timeStamps.back())); + samplerInfoText.append(fmt::format("Duration: {:.2f} s", currentSamplerData_->timeStamps.back() - currentSamplerData_->timeStamps.front())); - context.errors().addError(raco::core::ErrorCategory::GENERAL, unsupportedArray ? raco::core::ErrorLevel::ERROR : raco::core::ErrorLevel::INFORMATION, - {shared_from_this()}, samplerInfoText); + context.errors().addError(core::ErrorCategory::GENERAL, core::ErrorLevel::INFORMATION, {shared_from_this()}, samplerInfoText); } } // namespace raco::user_types \ No newline at end of file diff --git a/datamodel/libUserTypes/src/BlitPass.cpp b/datamodel/libUserTypes/src/BlitPass.cpp index 5d9dd264..5349bbeb 100644 --- a/datamodel/libUserTypes/src/BlitPass.cpp +++ b/datamodel/libUserTypes/src/BlitPass.cpp @@ -40,14 +40,14 @@ void BlitPass::onAfterReferencedObjectChanged(BaseContext& context, ValueHandle void BlitPass::validateBufferCompatibility(BaseContext & context) { ValueHandle sourceBufferHandle{shared_from_this(), &user_types::BlitPass::sourceRenderBufferMS_}; if (*sourceRenderBuffer_ && *sourceRenderBufferMS_) { - context.errors().addError(raco::core::ErrorCategory::GENERAL, ErrorLevel::WARNING, sourceBufferHandle, "Single-sample and multi-sample source buffer selected: Single-sample source buffer will be preferred."); + context.errors().addError(core::ErrorCategory::GENERAL, ErrorLevel::WARNING, sourceBufferHandle, "Single-sample and multi-sample source buffer selected: Single-sample source buffer will be preferred."); } else { context.errors().removeError(sourceBufferHandle); } ValueHandle targetBufferHandle{shared_from_this(), &user_types::BlitPass::targetRenderBufferMS_}; if (*targetRenderBuffer_ && *targetRenderBufferMS_) { - context.errors().addError(raco::core::ErrorCategory::GENERAL, ErrorLevel::WARNING, targetBufferHandle, "Single-sample and multi-sample target buffer selected: Single-sample target buffer will be preferred."); + context.errors().addError(core::ErrorCategory::GENERAL, ErrorLevel::WARNING, targetBufferHandle, "Single-sample and multi-sample target buffer selected: Single-sample target buffer will be preferred."); } else { context.errors().removeError(targetBufferHandle); } diff --git a/datamodel/libUserTypes/src/CubeMap.cpp b/datamodel/libUserTypes/src/CubeMap.cpp index 713d0677..56f7dd98 100644 --- a/datamodel/libUserTypes/src/CubeMap.cpp +++ b/datamodel/libUserTypes/src/CubeMap.cpp @@ -41,31 +41,6 @@ void CubeMap::updateFromExternalFile(BaseContext& context) { } void CubeMap::validateURIs(BaseContext& context) { - context.errors().removeError({shared_from_this(), &CubeMap::uriFront_}); - context.errors().removeError({shared_from_this(), &CubeMap::uriBack_}); - context.errors().removeError({shared_from_this(), &CubeMap::uriLeft_}); - context.errors().removeError({shared_from_this(), &CubeMap::uriRight_}); - context.errors().removeError({shared_from_this(), &CubeMap::uriTop_}); - context.errors().removeError({shared_from_this(), &CubeMap::uriBottom_}); - context.errors().removeError({shared_from_this(), &CubeMap::level2uriFront_}); - context.errors().removeError({shared_from_this(), &CubeMap::level2uriBack_}); - context.errors().removeError({shared_from_this(), &CubeMap::level2uriLeft_}); - context.errors().removeError({shared_from_this(), &CubeMap::level2uriRight_}); - context.errors().removeError({shared_from_this(), &CubeMap::level2uriTop_}); - context.errors().removeError({shared_from_this(), &CubeMap::level2uriBottom_}); - context.errors().removeError({shared_from_this(), &CubeMap::level3uriFront_}); - context.errors().removeError({shared_from_this(), &CubeMap::level3uriBack_}); - context.errors().removeError({shared_from_this(), &CubeMap::level3uriLeft_}); - context.errors().removeError({shared_from_this(), &CubeMap::level3uriRight_}); - context.errors().removeError({shared_from_this(), &CubeMap::level3uriTop_}); - context.errors().removeError({shared_from_this(), &CubeMap::level3uriBottom_}); - context.errors().removeError({shared_from_this(), &CubeMap::level4uriFront_}); - context.errors().removeError({shared_from_this(), &CubeMap::level4uriBack_}); - context.errors().removeError({shared_from_this(), &CubeMap::level4uriLeft_}); - context.errors().removeError({shared_from_this(), &CubeMap::level4uriRight_}); - context.errors().removeError({shared_from_this(), &CubeMap::level4uriTop_}); - context.errors().removeError({shared_from_this(), &CubeMap::level4uriBottom_}); - validateURI(context, {shared_from_this(), &CubeMap::uriFront_}); validateURI(context, {shared_from_this(), &CubeMap::uriBack_}); validateURI(context, {shared_from_this(), &CubeMap::uriLeft_}); @@ -80,6 +55,13 @@ void CubeMap::validateURIs(BaseContext& context) { validateURI(context, {shared_from_this(), &CubeMap::level2uriRight_}); validateURI(context, {shared_from_this(), &CubeMap::level2uriTop_}); validateURI(context, {shared_from_this(), &CubeMap::level2uriBottom_}); + } else { + context.errors().removeError({shared_from_this(), &CubeMap::level2uriFront_}); + context.errors().removeError({shared_from_this(), &CubeMap::level2uriBack_}); + context.errors().removeError({shared_from_this(), &CubeMap::level2uriLeft_}); + context.errors().removeError({shared_from_this(), &CubeMap::level2uriRight_}); + context.errors().removeError({shared_from_this(), &CubeMap::level2uriTop_}); + context.errors().removeError({shared_from_this(), &CubeMap::level2uriBottom_}); } if (*mipmapLevel_ > 2) { @@ -89,6 +71,13 @@ void CubeMap::validateURIs(BaseContext& context) { validateURI(context, {shared_from_this(), &CubeMap::level3uriRight_}); validateURI(context, {shared_from_this(), &CubeMap::level3uriTop_}); validateURI(context, {shared_from_this(), &CubeMap::level3uriBottom_}); + } else { + context.errors().removeError({shared_from_this(), &CubeMap::level3uriFront_}); + context.errors().removeError({shared_from_this(), &CubeMap::level3uriBack_}); + context.errors().removeError({shared_from_this(), &CubeMap::level3uriLeft_}); + context.errors().removeError({shared_from_this(), &CubeMap::level3uriRight_}); + context.errors().removeError({shared_from_this(), &CubeMap::level3uriTop_}); + context.errors().removeError({shared_from_this(), &CubeMap::level3uriBottom_}); } if (*mipmapLevel_ > 3) { @@ -98,11 +87,18 @@ void CubeMap::validateURIs(BaseContext& context) { validateURI(context, {shared_from_this(), &CubeMap::level4uriRight_}); validateURI(context, {shared_from_this(), &CubeMap::level4uriTop_}); validateURI(context, {shared_from_this(), &CubeMap::level4uriBottom_}); + } else { + context.errors().removeError({shared_from_this(), &CubeMap::level4uriFront_}); + context.errors().removeError({shared_from_this(), &CubeMap::level4uriBack_}); + context.errors().removeError({shared_from_this(), &CubeMap::level4uriLeft_}); + context.errors().removeError({shared_from_this(), &CubeMap::level4uriRight_}); + context.errors().removeError({shared_from_this(), &CubeMap::level4uriTop_}); + context.errors().removeError({shared_from_this(), &CubeMap::level4uriBottom_}); } } void CubeMap::validateMipmapLevel(BaseContext& context) { - auto mipmapLevelValue = ValueHandle{shared_from_this(), &raco::user_types::CubeMap::mipmapLevel_}; + auto mipmapLevelValue = ValueHandle{shared_from_this(), &user_types::CubeMap::mipmapLevel_}; if (*mipmapLevel_ < 1 || *mipmapLevel_ > 4) { context.errors().addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, mipmapLevelValue, diff --git a/datamodel/libUserTypes/src/Enumerations.cpp b/datamodel/libUserTypes/src/Enumerations.cpp index 29cdbdcc..ee9b60f6 100644 --- a/datamodel/libUserTypes/src/Enumerations.cpp +++ b/datamodel/libUserTypes/src/Enumerations.cpp @@ -169,7 +169,9 @@ std::map enumDescriptionRenderBufferFormat{ {static_cast(ERenderBufferFormat::RGBA16F), "RGBA16F"}, {static_cast(ERenderBufferFormat::RGBA32F), "RGBA32F"}, + {static_cast(ERenderBufferFormat::Depth16), "Depth16"}, {static_cast(ERenderBufferFormat::Depth24), "Depth24"}, + {static_cast(ERenderBufferFormat::Depth32), "Depth32"}, {static_cast(ERenderBufferFormat::Depth24_Stencil8), "Depth24_Stencil8"}}; std::map enumDescriptionRenderLayerOrder{ diff --git a/datamodel/libUserTypes/src/LuaInterface.cpp b/datamodel/libUserTypes/src/LuaInterface.cpp index 550b9184..9ce2f494 100644 --- a/datamodel/libUserTypes/src/LuaInterface.cpp +++ b/datamodel/libUserTypes/src/LuaInterface.cpp @@ -50,6 +50,7 @@ void LuaInterface::updateFromExternalFile(BaseContext& context) { } void LuaInterface::syncLuaScript(BaseContext& context, bool syncModules) { + // TODO(error) try to avoid unnecessary error item updates context.errors().removeAll({shared_from_this()}); PropertyInterfaceList inputs{}; @@ -59,21 +60,17 @@ void LuaInterface::syncLuaScript(BaseContext& context, bool syncModules) { std::string error{}; bool success = true; - - if (context.project()->featureLevel() >= 5) { - if (syncModules) { - success = syncLuaModules(context, ValueHandle{shared_from_this(), &LuaInterface::luaModules_}, luaInterface, cachedModuleRefs_, error); - } - if (success) { - success = checkLuaModules(ValueHandle{shared_from_this(), &LuaInterface::luaModules_}, context.errors()); - } + if (syncModules) { + success = syncLuaModules(context, ValueHandle{shared_from_this(), &LuaInterface::luaModules_}, luaInterface, cachedModuleRefs_, error); + } - if (success) { - success = context.engineInterface().parseLuaInterface(luaInterface, stdModules_->activeModules(), *luaModules_, true, inputs, error); - } - } else { - success = context.engineInterface().parseLuaInterface(luaInterface, {}, *luaModules_, false, inputs, error); + if (success) { + success = checkLuaModules(ValueHandle{shared_from_this(), &LuaInterface::luaModules_}, context.errors()); + } + + if (success) { + success = context.engineInterface().parseLuaInterface(luaInterface, stdModules_->activeModules(), *luaModules_, inputs, error); } if (!success) { diff --git a/datamodel/libUserTypes/src/LuaScript.cpp b/datamodel/libUserTypes/src/LuaScript.cpp index 80b1e08c..b6a86eda 100644 --- a/datamodel/libUserTypes/src/LuaScript.cpp +++ b/datamodel/libUserTypes/src/LuaScript.cpp @@ -52,6 +52,7 @@ void LuaScript::updateFromExternalFile(BaseContext& context) { } void LuaScript::syncLuaScript(BaseContext& context, bool syncModules) { + // TODO(error) try to avoid unnecessary error item updates context.errors().removeAll({shared_from_this()}); PropertyInterfaceList inputs{}; diff --git a/datamodel/libUserTypes/src/LuaScriptModule.cpp b/datamodel/libUserTypes/src/LuaScriptModule.cpp index 0fcf37e2..c8e92477 100644 --- a/datamodel/libUserTypes/src/LuaScriptModule.cpp +++ b/datamodel/libUserTypes/src/LuaScriptModule.cpp @@ -39,8 +39,6 @@ void LuaScriptModule::updateFromExternalFile(BaseContext& context) { } void LuaScriptModule::sync(BaseContext& context) { - context.errors().removeError({shared_from_this()}); - if (validateURI(context, {shared_from_this(), &LuaScriptModule::uri_})) { std::string luaScript = utils::file::read(PathQueries::resolveUriPropertyToAbsolutePath(*context.project(), {shared_from_this(), &LuaScriptModule::uri_})); @@ -49,9 +47,12 @@ void LuaScriptModule::sync(BaseContext& context) { if (!isValid_) { context.errors().addError(ErrorCategory::PARSING, ErrorLevel::ERROR, shared_from_this(), error); + } else { + context.errors().removeError({shared_from_this()}); } currentScriptContents_ = luaScript; } else { + context.errors().removeError({shared_from_this()}); currentScriptContents_.clear(); context.engineInterface().removeModuleFromCache(shared_from_this()); isValid_ = false; diff --git a/datamodel/libUserTypes/src/LuaUtils.cpp b/datamodel/libUserTypes/src/LuaUtils.cpp index 5e8f15b7..d9f09400 100644 --- a/datamodel/libUserTypes/src/LuaUtils.cpp +++ b/datamodel/libUserTypes/src/LuaUtils.cpp @@ -22,13 +22,13 @@ bool checkLuaModules(ValueHandle moduleTableHandle, Errors& errors) { const Table& moduleTable = moduleTableHandle.constValueRef()->asTable(); for (auto i = 0; i < moduleTable.size(); ++i) { if (auto moduleRef = moduleTable.get(i)->asRef()) { - const auto module = moduleRef->as(); + const auto module = moduleRef->as(); if (!module->isValid()) { - errors.addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::ERROR, moduleTableHandle[i], fmt::format("Invalid LuaScriptModule '{}' assigned.", moduleRef->objectName())); + errors.addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, moduleTableHandle[i], fmt::format("Invalid LuaScriptModule '{}' assigned.", moduleRef->objectName())); success = false; } } else { - errors.addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::ERROR, moduleTableHandle[i], fmt::format("Required LuaScriptModule '{}' is unassigned.", moduleTable.name(i))); + errors.addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, moduleTableHandle[i], fmt::format("Required LuaScriptModule '{}' is unassigned.", moduleTable.name(i))); success = false; } } @@ -44,7 +44,7 @@ bool syncLuaModules(BaseContext& context, ValueHandle moduleHandle, const std::s std::vector redeclaredStandardModules; for (const auto& dep : moduleDeps) { - if (raco::user_types::LuaScriptModule::LUA_STANDARD_MODULES.find(dep) != raco::user_types::LuaScriptModule::LUA_STANDARD_MODULES.end()) { + if (user_types::LuaScriptModule::LUA_STANDARD_MODULES.find(dep) != user_types::LuaScriptModule::LUA_STANDARD_MODULES.end()) { redeclaredStandardModules.emplace_back(dep); } } @@ -76,7 +76,7 @@ bool syncLuaModules(BaseContext& context, ValueHandle moduleHandle, const std::s // Add new module properties for (const auto& moduleName : moduleDeps) { if (!moduleTable.hasProperty(moduleName)) { - std::unique_ptr newValue = std::make_unique>(); + std::unique_ptr newValue = std::make_unique>(); auto it = cachedModuleRefs.find(moduleName); if (it != cachedModuleRefs.end()) { std::string cachedRefID = it->second; diff --git a/datamodel/libUserTypes/src/Material.cpp b/datamodel/libUserTypes/src/Material.cpp index 053bb458..60635e83 100644 --- a/datamodel/libUserTypes/src/Material.cpp +++ b/datamodel/libUserTypes/src/Material.cpp @@ -66,11 +66,12 @@ std::tuple Material::validateShader(BaseContext& context, con } void Material::updateFromExternalFile(BaseContext& context) { - context.errors().removeError(ValueHandle{shared_from_this()}); bool isUriDefinesValid = false; const auto definesUriHandle = ValueHandle{shared_from_this(), &Material::uriDefines_}; - if (uriDefines_.asString().empty() || (isUriDefinesValid = validateURI(context, definesUriHandle))) { + if (uriDefines_.asString().empty()) { context.errors().removeError(definesUriHandle); + } else { + isUriDefinesValid = validateURI(context, definesUriHandle); } isShaderProgramValid_ = false; @@ -90,7 +91,7 @@ void Material::updateFromExternalFile(BaseContext& context) { std::string shaderDefines; if (isUriDefinesValid) { - shaderDefines = {raco::utils::file::read(PathQueries::resolveUriPropertyToAbsolutePath(*context.project(), {shared_from_this(), &Material::uriDefines_}))}; + shaderDefines = {utils::file::read(PathQueries::resolveUriPropertyToAbsolutePath(*context.project(), {shared_from_this(), &Material::uriDefines_}))}; // ramses treats the empty string as no shader defines should be loaded and only shows errors if the string contains at least a single charcater. // We want to display errors when the file load was successful but the file is empty. if (shaderDefines.empty()) { @@ -102,8 +103,13 @@ void Material::updateFromExternalFile(BaseContext& context) { isShaderProgramValid_ = context.engineInterface().parseShader(vertexShader, geometryShader, fragmentShader, shaderDefines, uniforms, attributes_, error); if (!error.empty()) { context.errors().addError(ErrorCategory::PARSING, ErrorLevel::ERROR, ValueHandle{shared_from_this()}, error); + } else { + context.errors().removeError(ValueHandle{shared_from_this()}); } + } else { + context.errors().removeError(ValueHandle{shared_from_this()}); } + if (!isShaderProgramValid_) { attributes_.clear(); } @@ -144,7 +150,7 @@ std::string Material::getShaderFileEnding(ShaderFileType shader, bool endsWithDo void Material::autofillShaderIfFileExists(BaseContext& context, const std::string& fileNameWithoutEnding, bool endsWithDotGlsl, ShaderFileType shaderType) { auto fileName = fileNameWithoutEnding + getShaderFileEnding(shaderType, endsWithDotGlsl); - if (raco::utils::u8path(fileName).normalizedAbsolutePath(context.project()->currentFolder()).existsFile()) { + if (utils::u8path(fileName).normalizedAbsolutePath(context.project()->currentFolder()).existsFile()) { ValueHandle handle; switch (shaderType) { case ShaderFileType::Vertex: diff --git a/datamodel/libUserTypes/src/Mesh.cpp b/datamodel/libUserTypes/src/Mesh.cpp index 6e146d91..7150d29b 100644 --- a/datamodel/libUserTypes/src/Mesh.cpp +++ b/datamodel/libUserTypes/src/Mesh.cpp @@ -9,19 +9,16 @@ */ #include "user_types/Mesh.h" +#include "Validation.h" #include "core/Context.h" #include "core/Errors.h" #include "core/MeshCacheInterface.h" #include "core/PathQueries.h" #include "core/Project.h" -#include "Validation.h" namespace raco::user_types { void Mesh::updateFromExternalFile(BaseContext& context) { - context.errors().removeError(ValueHandle{shared_from_this()}); - metaData_.clear(); - MeshDescriptor desc; desc.absPath = PathQueries::resolveUriPropertyToAbsolutePath(*context.project(), {shared_from_this(), &Mesh::uri_}); desc.bakeAllSubmeshes = bakeMeshes_.asBool(); @@ -35,25 +32,30 @@ void Mesh::updateFromExternalFile(BaseContext& context) { context.errors().addError(ErrorCategory::PARSING, ErrorLevel::ERROR, {shared_from_this()}, errorMessage); } } else { + context.errors().removeError(ValueHandle{shared_from_this()}); mesh_.reset(); } + ValueHandle metaDataHandle(shared_from_this(), &Mesh::metaData_); + + std::map currentMetaData; + if (mesh_) { std::string infoText; auto selectedMesh = mesh_.get(); - static std::map formatDescription = { - {raco::core::MeshData::VertexAttribDataType::VAT_Float, "float"}, - {raco::core::MeshData::VertexAttribDataType::VAT_Float2, "vec2"}, - {raco::core::MeshData::VertexAttribDataType::VAT_Float3, "vec3"}, - {raco::core::MeshData::VertexAttribDataType::VAT_Float4, "vec4"}, + static std::map formatDescription = { + {core::MeshData::VertexAttribDataType::VAT_Float, "float"}, + {core::MeshData::VertexAttribDataType::VAT_Float2, "vec2"}, + {core::MeshData::VertexAttribDataType::VAT_Float3, "vec3"}, + {core::MeshData::VertexAttribDataType::VAT_Float4, "vec4"}, }; infoText += "Mesh information\n\n"; infoText += fmt::format("Triangles: {}\n", selectedMesh->numTriangles()); infoText += fmt::format("Vertices: {}\n", selectedMesh->numVertices()); - //infoText += fmt::format("Submeshes: {}\n", selectedMesh->numSubmeshes()); + // infoText += fmt::format("Submeshes: {}\n", selectedMesh->numSubmeshes()); infoText += fmt::format("Total Asset File Meshes: {}\n", context.meshCache()->getTotalMeshCount(desc.absPath)); infoText += "\nAttributes:"; @@ -61,21 +63,51 @@ void Mesh::updateFromExternalFile(BaseContext& context) { infoText += fmt::format("\nin {} {};", formatDescription[selectedMesh->attribDataType(i)], selectedMesh->attribName(i)); } - metaData_ = selectedMesh->getMetadata(); - if (!metaData_.empty()) { + currentMetaData = selectedMesh->getMetadata(); + if (!currentMetaData.empty()) { infoText += "\n\nMetadata:"; - for (const auto& [key, value] : metaData_) { + for (const auto& [key, value] : currentMetaData) { infoText.append(fmt::format("\n{}: {}", key, value)); } } if (!infoText.empty()) { context.errors().addError(ErrorCategory::GENERAL, ErrorLevel::INFORMATION, ValueHandle{shared_from_this()}, infoText); + } else { + context.errors().removeError(ValueHandle{shared_from_this()}); + } + + Table meshInfo; + meshInfo.addProperty("triangles", new Value(selectedMesh->numTriangles())); + meshInfo.addProperty("vertices", new Value(selectedMesh->numVertices())); + if (!metaDataHandle.hasProperty(MetaDataCategories::MESH_INFO)) { + context.addProperty(metaDataHandle, MetaDataCategories::MESH_INFO, std::make_unique>()); } + context.set(metaDataHandle.get(MetaDataCategories::MESH_INFO), meshInfo); ValueHandle matnames_handle{shared_from_this(), &Mesh::materialNames_}; context.set(matnames_handle, std::vector{"material"}); + } else { + if (metaDataHandle.hasProperty(MetaDataCategories::MESH_INFO)) { + context.removeProperty(metaDataHandle, MetaDataCategories::MESH_INFO); + } + } + + if (!currentMetaData.empty()) { + Table extrasTable; + for (const auto& [key, value] : currentMetaData) { + extrasTable.addProperty(key, new Value(value)); + } + + if (!metaDataHandle.hasProperty(MetaDataCategories::GLTF_EXTRAS)) { + context.addProperty(metaDataHandle, MetaDataCategories::GLTF_EXTRAS, std::make_unique>()); + } + context.set(metaDataHandle.get(MetaDataCategories::GLTF_EXTRAS), extrasTable); + } else { + if (metaDataHandle.hasProperty(MetaDataCategories::GLTF_EXTRAS)) { + context.removeProperty(metaDataHandle, MetaDataCategories::GLTF_EXTRAS); + } } context.changeMultiplexer().recordPreviewDirty(shared_from_this()); diff --git a/datamodel/libUserTypes/src/MeshNode.cpp b/datamodel/libUserTypes/src/MeshNode.cpp index bc8ab872..00617569 100644 --- a/datamodel/libUserTypes/src/MeshNode.cpp +++ b/datamodel/libUserTypes/src/MeshNode.cpp @@ -90,6 +90,13 @@ Table* MeshNode::getUniformContainer(size_t materialSlot) { return &materials_->get(materialSlot)->asTable().get("uniforms")->asTable(); } return nullptr; +} + +BlendOptions* MeshNode::getOptions(size_t materialSlot) { + if (materialSlot < materials_->size()) { + return dynamic_cast(&materials_->get(materialSlot)->asTable().get("options")->asStruct()); + } + return nullptr; }; ValueHandle MeshNode::getMaterialHandle(size_t materialSlot) { @@ -133,7 +140,7 @@ PropertyInterface MeshNode::makeInterfaceFromProperty(std::string_view name, con } void MeshNode::updateUniformContainer(BaseContext& context, const std::string& materialName, const Table* src, ValueHandle& destUniforms) { - raco::core::PropertyInterfaceList uniformDescription; + core::PropertyInterfaceList uniformDescription; if (src) { for (size_t i = 0; i < src->size(); i++) { uniformDescription.emplace_back(makeInterfaceFromProperty(src->name(i), src->get(i))); @@ -141,14 +148,17 @@ void MeshNode::updateUniformContainer(BaseContext& context, const std::string& m } OutdatedPropertiesStore& cache = cachedUniformValues_[materialName]; - auto lookup = [src, &cache](const std::string& fullPropPath, raco::core::EnginePrimitive engineType) -> const ValueBase* { + auto lookup = [src, &cache](const std::string& fullPropPath, core::EnginePrimitive engineType) -> const ValueBase* { auto it = cache.find(std::make_pair(fullPropPath, engineType)); if (it != cache.end()) { return it->second.get(); } // Copy value from material if not found in cache. // To get the property name we need to remove the leading '/' from the property path. - return src->get(fullPropPath.substr(1)); + if (src->hasProperty(fullPropPath.substr(1))) { + return src->get(fullPropPath.substr(1)); + } + return nullptr; }; syncTableWithEngineInterface(context, uniformDescription, destUniforms, cache, false, true, lookup); @@ -163,11 +173,11 @@ void MeshNode::checkMeshMaterialAttributMatch(BaseContext& context) { for (const auto& attrib : material->attributes()) { std::string name = attrib.name; - static const std::unordered_map meshAttribTypeMap = { - {raco::core::MeshData::VertexAttribDataType::VAT_Float, EnginePrimitive::Double}, - {raco::core::MeshData::VertexAttribDataType::VAT_Float2, EnginePrimitive::Vec2f}, - {raco::core::MeshData::VertexAttribDataType::VAT_Float3, EnginePrimitive::Vec3f}, - {raco::core::MeshData::VertexAttribDataType::VAT_Float4, EnginePrimitive::Vec4f}}; + static const std::unordered_map meshAttribTypeMap = { + {core::MeshData::VertexAttribDataType::VAT_Float, EnginePrimitive::Double}, + {core::MeshData::VertexAttribDataType::VAT_Float2, EnginePrimitive::Vec2f}, + {core::MeshData::VertexAttribDataType::VAT_Float3, EnginePrimitive::Vec3f}, + {core::MeshData::VertexAttribDataType::VAT_Float4, EnginePrimitive::Vec4f}}; int index = mesh->meshData()->attribIndex(name); if (index != -1) { @@ -187,10 +197,11 @@ void MeshNode::checkMeshMaterialAttributMatch(BaseContext& context) { } } - context.errors().removeError(ValueHandle{shared_from_this(), {"mesh"}}); context.updateBrokenLinkErrors(shared_from_this()); if (!errors.empty()) { - context.errors().addError(ErrorCategory::GENERAL, ErrorLevel::ERROR, ValueHandle{shared_from_this(), {"mesh"}}, errors); + context.errors().addError(ErrorCategory::GENERAL, ErrorLevel::ERROR, ValueHandle{shared_from_this(), &MeshNode::mesh_}, errors); + } else { + context.errors().removeError(ValueHandle{shared_from_this(), &MeshNode::mesh_}); } } diff --git a/datamodel/libUserTypes/src/PerspectiveCamera.cpp b/datamodel/libUserTypes/src/PerspectiveCamera.cpp index 03ea9b7f..1cd6c75e 100644 --- a/datamodel/libUserTypes/src/PerspectiveCamera.cpp +++ b/datamodel/libUserTypes/src/PerspectiveCamera.cpp @@ -30,11 +30,11 @@ void PerspectiveCamera::onAfterValueChanged(BaseContext& context, ValueHandle co void PerspectiveCamera::syncFrustum(BaseContext& context) { ValueHandle frustumHandle{shared_from_this(), &PerspectiveCamera::frustum_}; if (!frustum_->hasProperty("nearPlane")) { - std::unique_ptr near = std::make_unique, LinkEndAnnotation>>(0.1, DisplayNameAnnotation("nearPlane"), RangeAnnotation(0.1, 1.0), LinkEndAnnotation()); + std::unique_ptr near = std::make_unique, LinkEndAnnotation>>(0.1, DisplayNameAnnotation("nearPlane"), RangeAnnotation(0.1, 1.0), LinkEndAnnotation()); context.addProperty(frustumHandle, "nearPlane", std::move(near)); } if (!frustum_->hasProperty("farPlane")) { - std::unique_ptr far = std::make_unique, LinkEndAnnotation>>(1000.0, DisplayNameAnnotation("farPlane"), RangeAnnotation(100.0, 10000.0), LinkEndAnnotation()); + std::unique_ptr far = std::make_unique, LinkEndAnnotation>>(1000.0, DisplayNameAnnotation("farPlane"), RangeAnnotation(100.0, 10000.0), LinkEndAnnotation()); context.addProperty(frustumHandle, "farPlane", std::move(far)); } @@ -57,7 +57,7 @@ void PerspectiveCamera::syncFrustum(BaseContext& context) { context.removeProperty(frustumHandle, "bottomPlane"); } if (!frustum_->hasProperty("fieldOfView")) { - std::unique_ptr fov = std::make_unique, LinkEndAnnotation>>(35.0, DisplayNameAnnotation("fieldOfView"), RangeAnnotation(10.0, 120.0), LinkEndAnnotation()); + std::unique_ptr fov = std::make_unique, LinkEndAnnotation>>(35.0, DisplayNameAnnotation("fieldOfView"), RangeAnnotation(10.0, 120.0), LinkEndAnnotation()); auto it = cachedFrustumValues_.find({"fieldOfView", EnginePrimitive::Double}); if (it != cachedFrustumValues_.end()) { *fov = *it->second; @@ -65,7 +65,7 @@ void PerspectiveCamera::syncFrustum(BaseContext& context) { context.addProperty(frustumHandle, "fieldOfView", std::move(fov)); } if (!frustum_->hasProperty("aspectRatio")) { - std::unique_ptr aspect = std::make_unique, LinkEndAnnotation>>(1440.0 / 720.0, DisplayNameAnnotation("aspectRatio"), RangeAnnotation(0.5, 4.0), LinkEndAnnotation()); + std::unique_ptr aspect = std::make_unique, LinkEndAnnotation>>(1440.0 / 720.0, DisplayNameAnnotation("aspectRatio"), RangeAnnotation(0.5, 4.0), LinkEndAnnotation()); auto it = cachedFrustumValues_.find({"aspectRatio", EnginePrimitive::Double}); if (it != cachedFrustumValues_.end()) { *aspect = *it->second; @@ -83,7 +83,7 @@ void PerspectiveCamera::syncFrustum(BaseContext& context) { context.removeProperty(frustumHandle, "aspectRatio"); } if (!frustum_->hasProperty("leftPlane")) { - std::unique_ptr left = std::make_unique, LinkEndAnnotation>>(-10.0, DisplayNameAnnotation("leftPlane"), RangeAnnotation(-1000.0, 0.0), LinkEndAnnotation()); + std::unique_ptr left = std::make_unique, LinkEndAnnotation>>(-10.0, DisplayNameAnnotation("leftPlane"), RangeAnnotation(-1000.0, 0.0), LinkEndAnnotation()); auto it = cachedFrustumValues_.find({"leftPlane", EnginePrimitive::Double}); if (it != cachedFrustumValues_.end()) { *left = *it->second; @@ -91,7 +91,7 @@ void PerspectiveCamera::syncFrustum(BaseContext& context) { context.addProperty(frustumHandle, "leftPlane", std::move(left)); } if (!frustum_->hasProperty("rightPlane")) { - std::unique_ptr right = std::make_unique, LinkEndAnnotation>>(10.0, DisplayNameAnnotation("rightPlane"), RangeAnnotation(0.0, 1000.0), LinkEndAnnotation()); + std::unique_ptr right = std::make_unique, LinkEndAnnotation>>(10.0, DisplayNameAnnotation("rightPlane"), RangeAnnotation(0.0, 1000.0), LinkEndAnnotation()); auto it = cachedFrustumValues_.find({"rightPlane", EnginePrimitive::Double}); if (it != cachedFrustumValues_.end()) { *right = *it->second; @@ -99,7 +99,7 @@ void PerspectiveCamera::syncFrustum(BaseContext& context) { context.addProperty(frustumHandle, "rightPlane", std::move(right)); } if (!frustum_->hasProperty("bottomPlane")) { - std::unique_ptr bottom = std::make_unique, LinkEndAnnotation>>(-10.0, DisplayNameAnnotation("bottomPlane"), RangeAnnotation(-1000.0, 0.0), LinkEndAnnotation()); + std::unique_ptr bottom = std::make_unique, LinkEndAnnotation>>(-10.0, DisplayNameAnnotation("bottomPlane"), RangeAnnotation(-1000.0, 0.0), LinkEndAnnotation()); auto it = cachedFrustumValues_.find({"bottomPlane", EnginePrimitive::Double}); if (it != cachedFrustumValues_.end()) { *bottom = *it->second; @@ -107,7 +107,7 @@ void PerspectiveCamera::syncFrustum(BaseContext& context) { context.addProperty(frustumHandle, "bottomPlane", std::move(bottom)); } if (!frustum_->hasProperty("topPlane")) { - std::unique_ptr top = std::make_unique, LinkEndAnnotation>>(10.0, DisplayNameAnnotation("topPlane"), RangeAnnotation(0.0, 1000.0), LinkEndAnnotation()); + std::unique_ptr top = std::make_unique, LinkEndAnnotation>>(10.0, DisplayNameAnnotation("topPlane"), RangeAnnotation(0.0, 1000.0), LinkEndAnnotation()); auto it = cachedFrustumValues_.find({"topPlane", EnginePrimitive::Double}); if (it != cachedFrustumValues_.end()) { *top = *it->second; diff --git a/datamodel/libUserTypes/src/Skin.cpp b/datamodel/libUserTypes/src/Skin.cpp index 09334960..ed0d4272 100644 --- a/datamodel/libUserTypes/src/Skin.cpp +++ b/datamodel/libUserTypes/src/Skin.cpp @@ -16,18 +16,6 @@ namespace raco::user_types { -void Skin::onAfterContextActivated(BaseContext& context) { - BaseObject::onAfterContextActivated(context); - - // TODO: the initial creation of the channel should be in the constructor. - // BUT: that doesn't work since the deserialization will not handle this case correctly. - // The deserialization will only create but not remove properties in Tables. - // We would need to fix the serialization if we want to move the setChannelAmount to the constructor. - if (targets_->size() == 0) { - setupTargetProperties(1); - } -} - void Skin::onAfterValueChanged(BaseContext& context, ValueHandle const& value) { BaseObject::onAfterValueChanged(context, value); @@ -37,8 +25,6 @@ void Skin::onAfterValueChanged(BaseContext& context, ValueHandle const& value) { } void Skin::updateFromExternalFile(BaseContext& context) { - context.errors().removeError(ValueHandle{shared_from_this()}); - if (validateURI(context, {shared_from_this(), &Skin::uri_})) { std::string uriAbsPath = PathQueries::resolveUriPropertyToAbsolutePath(*context.project(), {shared_from_this(), &Skin::uri_}); std::string loaderErrorMessage; @@ -47,6 +33,7 @@ void Skin::updateFromExternalFile(BaseContext& context) { context.errors().addError(ErrorCategory::PARSING, ErrorLevel::ERROR, {shared_from_this()}, loaderErrorMessage); } } else { + context.errors().removeError(ValueHandle{shared_from_this()}); skinData_.reset(); } @@ -56,7 +43,7 @@ void Skin::updateFromExternalFile(BaseContext& context) { info.append(fmt::format("Skin {} of {}\n", *skinIndex_ + 1, skinData_->numSkins)); info.append(fmt::format("Number of Joints: {}", skinData_->inverseBindMatrices.size())); - context.errors().addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::INFORMATION, {shared_from_this()}, info); + context.errors().addError(core::ErrorCategory::GENERAL, core::ErrorLevel::INFORMATION, {shared_from_this()}, info); } syncJointProperties(context); @@ -67,21 +54,17 @@ void Skin::updateFromExternalFile(BaseContext& context) { void Skin::syncJointProperties(BaseContext& context) { if (joints_->size() > numJoints()) { while (joints_->size() > numJoints()) { - context.removeProperty(raco::core::ValueHandle(shared_from_this(), &Skin::joints_), joints_->size() - 1); + context.removeProperty(core::ValueHandle(shared_from_this(), &Skin::joints_), joints_->size() - 1); } } else if (joints_->size() < numJoints()) { for (auto index = joints_->size(); index < numJoints(); index++) { - context.addProperty(raco::core::ValueHandle(shared_from_this(), &Skin::joints_), fmt::format("joint_{}", index), - std::make_unique>(), -1); + context.addProperty(core::ValueHandle(shared_from_this(), &Skin::joints_), {}, std::make_unique>(), -1); } } } void Skin::setupTargetProperties(size_t numTargets) { - targets_->clear(); - for (auto i = 0; i < numTargets ; ++i) { - targets_->addProperty(fmt::format("target_{}", i), new Value()); - } + targets_->resize(numTargets); } size_t Skin::numJoints() const { diff --git a/datamodel/libUserTypes/src/SyncTableWithEngineInterface.cpp b/datamodel/libUserTypes/src/SyncTableWithEngineInterface.cpp index c126951e..34c2a934 100644 --- a/datamodel/libUserTypes/src/SyncTableWithEngineInterface.cpp +++ b/datamodel/libUserTypes/src/SyncTableWithEngineInterface.cpp @@ -23,13 +23,13 @@ namespace raco::user_types { -using raco::core::PropertyInterface; -using raco::core::PropertyInterfaceList; -using raco::core::ValueHandle; -using raco::data_storage::PrimitiveType; +using core::PropertyInterface; +using core::PropertyInterfaceList; +using core::ValueHandle; +using data_storage::PrimitiveType; template -raco::data_storage::ValueBase* createDynamicProperty(EnginePrimitive type) { +data_storage::ValueBase* createDynamicProperty(EnginePrimitive type) { switch (type) { case EnginePrimitive::Bool: return UserObjectFactory::staticCreateProperty({}, {type}, {Args()}...); @@ -123,7 +123,7 @@ std::vector::const_iterator findNameInInterfaces(const Proper return interfaces.end(); } -inline void cacheRecursive(raco::core::BaseContext& context, const ValueHandle& property, const std::string& propertyPath, OutdatedPropertiesStore& outdatedPropertiesStore) { +inline void cacheRecursive(core::BaseContext& context, const ValueHandle& property, const std::string& propertyPath, OutdatedPropertiesStore& outdatedPropertiesStore) { for (size_t i{0}; i < property.size(); i++) { const auto name = property[i].getPropName(); const ValueBase* value = property[i].constValueRef(); @@ -139,7 +139,7 @@ inline void cacheRecursive(raco::core::BaseContext& context, const ValueHandle& } } -inline void removeProperties(raco::core::BaseContext& context, const PropertyInterfaceList& interface, const ValueHandle& property, const std::string& propertyPath, OutdatedPropertiesStore& outdatedPropertiesStore) { +inline void removeProperties(core::BaseContext& context, const PropertyInterfaceList& interface, const ValueHandle& property, const std::string& propertyPath, OutdatedPropertiesStore& outdatedPropertiesStore) { std::vector toRemove{}; for (size_t propertyIndex{0}; propertyIndex < property.size(); propertyIndex++) { const auto name = property[propertyIndex].getPropName(); @@ -165,26 +165,25 @@ inline void removeProperties(raco::core::BaseContext& context, const PropertyInt } } -inline void addProperties(raco::core::BaseContext& context, const PropertyInterfaceList& interface, const ValueHandle& property, const std::string& propertyPath, const OutdatedPropertiesStore& outdatedPropertiesStore, bool linkStart, bool linkEnd, std::function cacheLookupFunc) { +inline void addProperties(core::BaseContext& context, const PropertyInterfaceList& interface, const ValueHandle& property, const std::string& propertyPath, const OutdatedPropertiesStore& outdatedPropertiesStore, bool linkStart, bool linkEnd, std::function cacheLookupFunc) { for (size_t interfaceIndex{0}; interfaceIndex < interface.size(); interfaceIndex++) { const auto& iEntry = interface[interfaceIndex]; const std::string name(dataModelNameFromInterface(iEntry, interfaceIndex)); if (!property.hasProperty(name)) { - std::unique_ptr uniqueValue; + std::unique_ptr uniqueValue; bool isRefType = PropertyInterface::primitiveType(iEntry.type) == PrimitiveType::Ref; if (linkStart && linkEnd && !isRefType) { - uniqueValue = std::unique_ptr(createDynamicProperty(iEntry.type)); + uniqueValue = std::unique_ptr(createDynamicProperty(iEntry.type)); } else if (linkStart && !isRefType) { - uniqueValue = std::unique_ptr(createDynamicProperty(iEntry.type)); + uniqueValue = std::unique_ptr(createDynamicProperty(iEntry.type)); } else if (linkEnd && !isRefType) { - uniqueValue = std::unique_ptr(createDynamicProperty(iEntry.type)); + uniqueValue = std::unique_ptr(createDynamicProperty(iEntry.type)); } else { - uniqueValue = std::unique_ptr(createDynamicProperty<>(iEntry.type)); + uniqueValue = std::unique_ptr(createDynamicProperty<>(iEntry.type)); } - ValueBase* newValue = context.addProperty(property, name, std::move(uniqueValue), interfaceIndex); - auto fullPropPath = propertyPath + propertyPathSeparator + name; if (iEntry.primitiveType() != PrimitiveType::Table) { + auto fullPropPath = propertyPath + propertyPathSeparator + name; const ValueBase* cachedValue = cacheLookupFunc(fullPropPath, iEntry.type); if (cachedValue) { if (iEntry.primitiveType() == PrimitiveType::Ref) { @@ -195,13 +194,13 @@ inline void addProperties(raco::core::BaseContext& context, const PropertyInterf if (cachedValue->asRef()) { cachedObject = context.project()->getInstanceByID(cachedValue->asRef()->objectID()); } - // Use the context to set reference properties to make sure the onAfterAddReferenceToThis handlers are called. - context.set(property.get(name), cachedObject); + *uniqueValue = cachedObject; } else { - *newValue = *cachedValue; + *uniqueValue = *cachedValue; } } } + ValueBase* newValue = context.addProperty(property, name, std::move(uniqueValue), interfaceIndex); } if (iEntry.primitiveType() == PrimitiveType::Table) { addProperties(context, iEntry.children, property.get(name), propertyPath + propertyPathSeparator + name, outdatedPropertiesStore, linkStart, linkEnd, cacheLookupFunc); @@ -210,13 +209,13 @@ inline void addProperties(raco::core::BaseContext& context, const PropertyInterf } } // namespace -void syncTableWithEngineInterface(raco::core::BaseContext& context, const PropertyInterfaceList& interface, const ValueHandle& handle, OutdatedPropertiesStore& outdatedPropertiesStore, bool linkStart, bool linkEnd, std::function cacheLookupFunc) { +void syncTableWithEngineInterface(core::BaseContext& context, const PropertyInterfaceList& interface, const ValueHandle& handle, OutdatedPropertiesStore& outdatedPropertiesStore, bool linkStart, bool linkEnd, std::function cacheLookupFunc) { removeProperties(context, interface, handle, "", outdatedPropertiesStore); addProperties(context, interface, handle, "", outdatedPropertiesStore, linkStart, linkEnd, cacheLookupFunc); } -void syncTableWithEngineInterface(raco::core::BaseContext& context, const PropertyInterfaceList& interface, const ValueHandle& handle, OutdatedPropertiesStore& outdatedPropertiesStore, bool linkStart, bool linkEnd) { - syncTableWithEngineInterface(context, interface, handle, outdatedPropertiesStore, linkStart, linkEnd, [&outdatedPropertiesStore](const std::string& fullPropPath, raco::core::EnginePrimitive engineType) -> const ValueBase* { +void syncTableWithEngineInterface(core::BaseContext& context, const PropertyInterfaceList& interface, const ValueHandle& handle, OutdatedPropertiesStore& outdatedPropertiesStore, bool linkStart, bool linkEnd) { + syncTableWithEngineInterface(context, interface, handle, outdatedPropertiesStore, linkStart, linkEnd, [&outdatedPropertiesStore](const std::string& fullPropPath, core::EnginePrimitive engineType) -> const ValueBase* { auto it = outdatedPropertiesStore.find(std::make_pair(fullPropPath, engineType)); if (it != outdatedPropertiesStore.end()) { return it->second.get(); diff --git a/datamodel/libUserTypes/src/Texture.cpp b/datamodel/libUserTypes/src/Texture.cpp index 3548cbd6..60a84c25 100644 --- a/datamodel/libUserTypes/src/Texture.cpp +++ b/datamodel/libUserTypes/src/Texture.cpp @@ -12,6 +12,8 @@ #include "core/Context.h" #include "core/Handles.h" +#include "user_types/UserTypeAnnotations.h" + namespace raco::user_types { void Texture::onAfterContextActivated(BaseContext& context) { @@ -39,28 +41,29 @@ void Texture::updateFromExternalFile(BaseContext& context) { } void Texture::validateURIs(BaseContext& context) { - context.errors().removeError({shared_from_this(), &Texture::uri_}); - context.errors().removeError({shared_from_this(), &Texture::level2uri_}); - context.errors().removeError({shared_from_this(), &Texture::level3uri_}); - context.errors().removeError({shared_from_this(), &Texture::level4uri_}); - validateURI(context, {shared_from_this(), &Texture::uri_}); if (*mipmapLevel_ > 1) { validateURI(context, {shared_from_this(), &Texture::level2uri_}); + } else { + context.errors().removeError({shared_from_this(), &Texture::level2uri_}); } if (*mipmapLevel_ > 2) { validateURI(context, {shared_from_this(), &Texture::level3uri_}); + } else { + context.errors().removeError({shared_from_this(), &Texture::level3uri_}); } if (*mipmapLevel_ > 3) { validateURI(context, {shared_from_this(), &Texture::level4uri_}); + } else { + context.errors().removeError({shared_from_this(), &Texture::level4uri_}); } } void Texture::validateMipmapLevel(BaseContext& context) { - auto mipmapLevelValue = ValueHandle{shared_from_this(), &raco::user_types::Texture::mipmapLevel_}; + auto mipmapLevelValue = ValueHandle{shared_from_this(), &user_types::Texture::mipmapLevel_}; if (*mipmapLevel_ < 1 || *mipmapLevel_ > 4) { context.errors().addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, mipmapLevelValue, @@ -73,4 +76,8 @@ void Texture::validateMipmapLevel(BaseContext& context) { } } +void Texture::addTexturePreviewProperty() { + preview_->addProperty("texturePreview", new Property{{}, {}}); +} + } // namespace raco::user_types diff --git a/datamodel/libUserTypes/src/UserObjectFactory.cpp b/datamodel/libUserTypes/src/UserObjectFactory.cpp index 25b17049..f8b3235b 100644 --- a/datamodel/libUserTypes/src/UserObjectFactory.cpp +++ b/datamodel/libUserTypes/src/UserObjectFactory.cpp @@ -70,8 +70,8 @@ constexpr std::pair> createTypeMapP } template -std::map UserObjectFactory::makePropertyMapTuple(std::tuple* dummy) { - return std::map{ createTypeMapPair()...}; +std::map UserObjectFactory::makePropertyMapTuple(std::tuple* dummy) { + return std::map{ createTypeMapPair()...}; } template @@ -114,6 +114,7 @@ UserObjectFactory::UserObjectFactory() { RenderBufferMS, RenderLayer, RenderTarget, + RenderTargetMS, RenderPass, Skin >(); @@ -123,12 +124,12 @@ UserObjectFactory::UserObjectFactory() { >(); structTypes_ = makeStructTypeMap< - raco::core::Vec2f, - raco::core::Vec3f, - raco::core::Vec4f, - raco::core::Vec2i, - raco::core::Vec3i, - raco::core::Vec4i, + core::Vec2f, + core::Vec3f, + core::Vec4f, + core::Vec2i, + core::Vec3i, + core::Vec4i, ColorWriteMask, BlendOptions, DefaultResourceDirectories, diff --git a/datamodel/libUserTypes/src/Validation.h b/datamodel/libUserTypes/src/Validation.h index 26de5eaf..7df16721 100644 --- a/datamodel/libUserTypes/src/Validation.h +++ b/datamodel/libUserTypes/src/Validation.h @@ -21,16 +21,16 @@ namespace raco::user_types { -inline bool validateURI(raco::core::BaseContext& context, const raco::core::ValueHandle& handle) { - using raco::core::ErrorCategory; - using raco::core::ErrorLevel; +inline bool validateURI(core::BaseContext& context, const core::ValueHandle& handle) { + using core::ErrorCategory; + using core::ErrorLevel; - auto uriPath = raco::core::PathQueries::resolveUriPropertyToAbsolutePath(*context.project(), handle); + auto uriPath = core::PathQueries::resolveUriPropertyToAbsolutePath(*context.project(), handle); if (handle.asString().empty()) { context.errors().addError(ErrorCategory::FILESYSTEM, ErrorLevel::WARNING, handle, "Empty URI."); return false; - } else if (!raco::utils::u8path(uriPath).exists(context.isUriValidationCaseSensitive())) { + } else if (!utils::u8path(uriPath).exists(context.isUriValidationCaseSensitive())) { context.errors().addError(ErrorCategory::FILESYSTEM, ErrorLevel::ERROR, handle, "File not found."); return false; } else { @@ -40,7 +40,7 @@ inline bool validateURI(raco::core::BaseContext& context, const raco::core::Valu } template -inline bool validateURIs(raco::core::BaseContext& context, Args... args) { +inline bool validateURIs(core::BaseContext& context, Args... args) { return (validateURI(context, args) & ...) > 0; } diff --git a/datamodel/libUserTypes/tests/AnimationChannel_test.cpp b/datamodel/libUserTypes/tests/AnimationChannel_test.cpp index 50ae0e1e..b5c464e5 100644 --- a/datamodel/libUserTypes/tests/AnimationChannel_test.cpp +++ b/datamodel/libUserTypes/tests/AnimationChannel_test.cpp @@ -20,11 +20,6 @@ using namespace raco::user_types; class AnimationChannelTest : public TestEnvironmentCore {}; -class AnimationChannelTest_FL3 : public TestEnvironmentCoreT<::testing::Test> { -public: - AnimationChannelTest_FL3() : TestEnvironmentCoreT(&UserObjectFactory::getInstance(), static_cast(3)) {} -}; - TEST_F(AnimationChannelTest, URI_setValidURI) { auto animChannel{commandInterface.createObject(AnimationChannel::typeDescription.typeName)}; ValueHandle m{animChannel}; @@ -57,7 +52,7 @@ TEST_F(AnimationChannelTest, URI_setValidURI_noAnims) { commandInterface.set(uriHandle, animChannelPath); ASSERT_TRUE(commandInterface.errors().hasError(uriHandle)); - ASSERT_EQ(commandInterface.errors().getError(uriHandle).level(), raco::core::ErrorLevel::WARNING); + ASSERT_EQ(commandInterface.errors().getError(uriHandle).level(), core::ErrorLevel::WARNING); } TEST_F(AnimationChannelTest, Inputs_setInvalidAnimationIndex_error) { @@ -70,7 +65,7 @@ TEST_F(AnimationChannelTest, Inputs_setInvalidAnimationIndex_error) { commandInterface.set(uriHandle, animChannelPath); ASSERT_TRUE(commandInterface.errors().hasError(animHandle)); - ASSERT_EQ(commandInterface.errors().getError(animHandle).level(), raco::core::ErrorLevel::INFORMATION); + ASSERT_EQ(commandInterface.errors().getError(animHandle).level(), core::ErrorLevel::INFORMATION); ASSERT_FALSE(commandInterface.errors().hasError(animIndexHandle)); ASSERT_FALSE(commandInterface.errors().hasError(samplerIndexHandle)); @@ -82,7 +77,7 @@ TEST_F(AnimationChannelTest, Inputs_setInvalidAnimationIndex_error) { commandInterface.set(animIndexHandle, 0); ASSERT_TRUE(commandInterface.errors().hasError(animHandle)); - ASSERT_EQ(commandInterface.errors().getError(animHandle).level(), raco::core::ErrorLevel::INFORMATION); + ASSERT_EQ(commandInterface.errors().getError(animHandle).level(), core::ErrorLevel::INFORMATION); ASSERT_FALSE(commandInterface.errors().hasError(animIndexHandle)); ASSERT_FALSE(commandInterface.errors().hasError(samplerIndexHandle)); @@ -93,7 +88,7 @@ TEST_F(AnimationChannelTest, Inputs_setInvalidAnimationIndex_error) { commandInterface.set(animIndexHandle, 0); ASSERT_TRUE(commandInterface.errors().hasError(animHandle)); - ASSERT_EQ(commandInterface.errors().getError(animHandle).level(), raco::core::ErrorLevel::INFORMATION); + ASSERT_EQ(commandInterface.errors().getError(animHandle).level(), core::ErrorLevel::INFORMATION); ASSERT_FALSE(commandInterface.errors().hasError(animIndexHandle)); ASSERT_FALSE(commandInterface.errors().hasError(samplerIndexHandle)); } @@ -108,7 +103,7 @@ TEST_F(AnimationChannelTest, Inputs_setInvalidSamplerIndex_noError) { commandInterface.set(uriHandle, animChannelPath); ASSERT_TRUE(commandInterface.errors().hasError(animHandle)); - ASSERT_EQ(commandInterface.errors().getError(animHandle).level(), raco::core::ErrorLevel::INFORMATION); + ASSERT_EQ(commandInterface.errors().getError(animHandle).level(), core::ErrorLevel::INFORMATION); ASSERT_FALSE(commandInterface.errors().hasError(animIndexHandle)); ASSERT_FALSE(commandInterface.errors().hasError(samplerIndexHandle)); @@ -120,7 +115,7 @@ TEST_F(AnimationChannelTest, Inputs_setInvalidSamplerIndex_noError) { commandInterface.set(samplerIndexHandle, 0); ASSERT_TRUE(commandInterface.errors().hasError(animHandle)); - ASSERT_EQ(commandInterface.errors().getError(animHandle).level(), raco::core::ErrorLevel::INFORMATION); + ASSERT_EQ(commandInterface.errors().getError(animHandle).level(), core::ErrorLevel::INFORMATION); ASSERT_FALSE(commandInterface.errors().hasError(animIndexHandle)); ASSERT_FALSE(commandInterface.errors().hasError(samplerIndexHandle)); @@ -131,7 +126,7 @@ TEST_F(AnimationChannelTest, Inputs_setInvalidSamplerIndex_noError) { commandInterface.set(samplerIndexHandle, 0); ASSERT_TRUE(commandInterface.errors().hasError(animHandle)); - ASSERT_EQ(commandInterface.errors().getError(animHandle).level(), raco::core::ErrorLevel::INFORMATION); + ASSERT_EQ(commandInterface.errors().getError(animHandle).level(), core::ErrorLevel::INFORMATION); ASSERT_FALSE(commandInterface.errors().hasError(animIndexHandle)); ASSERT_FALSE(commandInterface.errors().hasError(samplerIndexHandle)); } @@ -146,38 +141,23 @@ TEST_F(AnimationChannelTest, invalidAnim_weights_supported) { ValueHandle samplerIndexHandle{animChannel, {"samplerIndex"}}; ValueHandle animHandle{animChannel}; ASSERT_TRUE(commandInterface.errors().hasError(animHandle)); - ASSERT_EQ(commandInterface.errors().getError(animHandle).level(), raco::core::ErrorLevel::INFORMATION); - ASSERT_FALSE(commandInterface.errors().hasError(samplerIndexHandle)); -} - -TEST_F(AnimationChannelTest_FL3, invalidAnim_weights_unsupported_fl3) { - auto animChannel{commandInterface.createObject(AnimationChannel::typeDescription.typeName)}; - ValueHandle uriHandle{animChannel, {"uri"}}; - - std::string uriPath{(test_path() / "meshes" / "AnimatedMorphCube" / "AnimatedMorphCube.gltf").string()}; - commandInterface.set({animChannel, {"uri"}}, uriPath); - - ValueHandle samplerIndexHandle{animChannel, {"samplerIndex"}}; - ValueHandle animHandle{animChannel}; - ASSERT_TRUE(commandInterface.errors().hasError(animHandle)); - ASSERT_EQ(commandInterface.errors().getError(animHandle).level(), raco::core::ErrorLevel::ERROR); + ASSERT_EQ(commandInterface.errors().getError(animHandle).level(), core::ErrorLevel::INFORMATION); ASSERT_FALSE(commandInterface.errors().hasError(samplerIndexHandle)); } - #if (!defined(__linux__)) // awaitPreviewDirty does not work in Linux as expected. See RAOS-692 TEST_F(AnimationChannelTest, validAnim_madeInvalid) { auto animChannel = create("anim_channel"); - ValueHandle uriHandle{animChannel, &raco::user_types::AnimationChannel::uri_}; + ValueHandle uriHandle{animChannel, &user_types::AnimationChannel::uri_}; auto animChannelPath = test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string(); commandInterface.set(uriHandle, animChannelPath); ASSERT_FALSE(commandInterface.errors().hasError(uriHandle)); recorder.reset(); - raco::utils::file::write(animChannelPath, ""); + utils::file::write(animChannelPath, ""); EXPECT_TRUE(raco::awaitPreviewDirty(recorder, animChannel)); ASSERT_TRUE(commandInterface.errors().hasError(uriHandle)); diff --git a/datamodel/libUserTypes/tests/Animation_test.cpp b/datamodel/libUserTypes/tests/Animation_test.cpp index b9b18e07..39fd0095 100644 --- a/datamodel/libUserTypes/tests/Animation_test.cpp +++ b/datamodel/libUserTypes/tests/Animation_test.cpp @@ -28,23 +28,26 @@ TEST_F(AnimationTest, emptyAnimChannelsErrors) { auto anim = commandInterface.createObject(Animation::typeDescription.typeName, "Animation Name"); auto animChannel = commandInterface.createObject(AnimationChannel::typeDescription.typeName, "Animation Channel Name"); - commandInterface.set({anim, {"animationChannels", "Channel 0"}}, animChannel); - ASSERT_TRUE(commandInterface.errors().hasError({anim, {"animationChannels", "Channel 0"}})); + ValueHandle channelsHandle(anim, &Animation::animationChannels_); + commandInterface.resizeArray(channelsHandle, 4); - commandInterface.set({anim, {"animationChannels", "Channel 3"}}, animChannel); - ASSERT_TRUE(commandInterface.errors().hasError({anim, {"animationChannels", "Channel 0"}})); - ASSERT_TRUE(commandInterface.errors().hasError({anim, {"animationChannels", "Channel 3"}})); + commandInterface.set(channelsHandle[0], animChannel); + ASSERT_TRUE(commandInterface.errors().hasError(channelsHandle[0])); - commandInterface.set({anim, {"animationChannels", "Channel 3"}}, SEditorObject()); - ASSERT_TRUE(commandInterface.errors().hasError({anim, {"animationChannels", "Channel 0"}})); - ASSERT_FALSE(commandInterface.errors().hasError({anim, {"animationChannels", "Channel 3"}})); + commandInterface.set(channelsHandle[3], animChannel); + ASSERT_TRUE(commandInterface.errors().hasError(channelsHandle[0])); + ASSERT_TRUE(commandInterface.errors().hasError(channelsHandle[3])); + + commandInterface.set(channelsHandle[3], SEditorObject()); + ASSERT_TRUE(commandInterface.errors().hasError(channelsHandle[0])); + ASSERT_FALSE(commandInterface.errors().hasError(channelsHandle[3])); ValueHandle uriHandle{animChannel, {"uri"}}; auto animChannelPath = test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string(); commandInterface.set(uriHandle, animChannelPath); - ASSERT_FALSE(commandInterface.errors().hasError({anim, {"animationChannels", "Channel 0"}})); - ASSERT_FALSE(commandInterface.errors().hasError({anim, {"animationChannels", "Channel 3"}})); + ASSERT_FALSE(commandInterface.errors().hasError(channelsHandle[0])); + ASSERT_FALSE(commandInterface.errors().hasError(channelsHandle[3])); } TEST_F(AnimationTest, link_with_meshNode_mesh_changed) { @@ -54,16 +57,17 @@ TEST_F(AnimationTest, link_with_meshNode_mesh_changed) { auto meshNode = context.createObject(MeshNode::typeDescription.typeName, "MeshNode"); std::string uriPath{(test_path() / "meshes" / "InterpolationTest" / "InterpolationTest.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); - commandInterface.set({mesh, &raco::user_types::Mesh::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({mesh, &user_types::Mesh::uri_}, uriPath); - commandInterface.set({anim, {"animationChannels", "Channel 0"}}, animChannel); - commandInterface.set({mesh, &raco::user_types::Mesh::bakeMeshes_}, false); - commandInterface.set({meshNode, &raco::user_types::MeshNode::mesh_}, mesh); + ValueHandle channelsHandle(anim, &Animation::animationChannels_); + commandInterface.set(channelsHandle[0], animChannel); + commandInterface.set({mesh, &user_types::Mesh::bakeMeshes_}, false); + commandInterface.set({meshNode, &user_types::MeshNode::mesh_}, mesh); commandInterface.addLink({anim, {"outputs", "Ch0.Animation Sampler Name"}}, {meshNode, {"translation"}}); - commandInterface.set({mesh, &raco::user_types::Mesh::uri_}, (test_path() / "meshes" / "CesiumMilkTruck" / "CesiumMilkTruck.gltf").string()); + commandInterface.set({mesh, &user_types::Mesh::uri_}, (test_path() / "meshes" / "CesiumMilkTruck" / "CesiumMilkTruck.gltf").string()); ASSERT_EQ(commandInterface.project()->links().size(), 1); ASSERT_TRUE((*commandInterface.project()->links().begin())->isValid()); @@ -76,12 +80,13 @@ TEST_F(AnimationTest, link_with_meshNode_submesh_index_changed) { auto meshNode = context.createObject(MeshNode::typeDescription.typeName, "MeshNode"); std::string uriPath{(test_path() / "meshes" / "InterpolationTest" / "InterpolationTest.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); - commandInterface.set({mesh, &raco::user_types::Mesh::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({mesh, &user_types::Mesh::uri_}, uriPath); - commandInterface.set({anim, {"animationChannels", "Channel 0"}}, animChannel); - commandInterface.set({mesh, &raco::user_types::Mesh::bakeMeshes_}, false); - commandInterface.set({meshNode, &raco::user_types::MeshNode::mesh_}, mesh); + ValueHandle channelsHandle(anim, &Animation::animationChannels_); + commandInterface.set(channelsHandle[0], animChannel); + commandInterface.set({mesh, &user_types::Mesh::bakeMeshes_}, false); + commandInterface.set({meshNode, &user_types::MeshNode::mesh_}, mesh); commandInterface.addLink({anim, {"outputs", "Ch0.Animation Sampler Name"}}, {meshNode, {"translation"}}); @@ -98,16 +103,17 @@ TEST_F(AnimationTest, link_with_meshNode_channel_data_changed_valid_type) { auto meshNode = context.createObject(MeshNode::typeDescription.typeName, "MeshNode"); std::string uriPath{(test_path() / "meshes" / "InterpolationTest" / "InterpolationTest.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); - commandInterface.set({mesh, &raco::user_types::Mesh::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({mesh, &user_types::Mesh::uri_}, uriPath); - commandInterface.set({anim, {"animationChannels", "Channel 0"}}, animChannel); - commandInterface.set({mesh, &raco::user_types::Mesh::bakeMeshes_}, false); - commandInterface.set({meshNode, &raco::user_types::MeshNode::mesh_}, mesh); + ValueHandle channelsHandle(anim, &Animation::animationChannels_); + commandInterface.set(channelsHandle[0], animChannel); + commandInterface.set({mesh, &user_types::Mesh::bakeMeshes_}, false); + commandInterface.set({meshNode, &user_types::MeshNode::mesh_}, mesh); commandInterface.addLink({anim, {"outputs", "Ch0.Animation Sampler Name"}}, {meshNode, {"translation"}}); - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::animationIndex_}, 1); + commandInterface.set({animChannel, &user_types::AnimationChannel::animationIndex_}, 1); ASSERT_EQ(commandInterface.project()->links().size(), 1); ASSERT_TRUE((*commandInterface.project()->links().begin())->isValid()); @@ -120,17 +126,18 @@ TEST_F(AnimationTest, link_with_meshNode_channel_data_changed_invalid_type) { auto meshNode = context.createObject(MeshNode::typeDescription.typeName, "MeshNode"); std::string uriPath{(test_path() / "meshes" / "InterpolationTest" / "InterpolationTest.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); - commandInterface.set({mesh, &raco::user_types::Mesh::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({mesh, &user_types::Mesh::uri_}, uriPath); - commandInterface.set({anim, {"animationChannels", "Channel 0"}}, animChannel); - commandInterface.set({mesh, &raco::user_types::Mesh::bakeMeshes_}, false); - commandInterface.set({meshNode, &raco::user_types::MeshNode::mesh_}, mesh); + ValueHandle channelsHandle(anim, &Animation::animationChannels_); + commandInterface.set(channelsHandle[0], animChannel); + commandInterface.set({mesh, &user_types::Mesh::bakeMeshes_}, false); + commandInterface.set({meshNode, &user_types::MeshNode::mesh_}, mesh); commandInterface.addLink({anim, {"outputs", "Ch0.Animation Sampler Name"}}, {meshNode, {"translation"}}); // changing from vec3f output to vec4f output - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::animationIndex_}, 3); + commandInterface.set({animChannel, &user_types::AnimationChannel::animationIndex_}, 3); ASSERT_EQ(commandInterface.project()->links().size(), 1); ASSERT_FALSE((*commandInterface.project()->links().begin())->isValid()); @@ -143,22 +150,23 @@ TEST_F(AnimationTest, link_with_meshNode_channel_removed) { auto meshNode = context.createObject(MeshNode::typeDescription.typeName, "MeshNode"); std::string uriPath{(test_path() / "meshes" / "InterpolationTest" / "InterpolationTest.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); - commandInterface.set({mesh, &raco::user_types::Mesh::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({mesh, &user_types::Mesh::uri_}, uriPath); - commandInterface.set({anim, {"animationChannels", "Channel 0"}}, animChannel); - commandInterface.set({mesh, &raco::user_types::Mesh::bakeMeshes_}, false); - commandInterface.set({meshNode, &raco::user_types::MeshNode::mesh_}, mesh); + ValueHandle channelsHandle(anim, &Animation::animationChannels_); + commandInterface.set(channelsHandle[0], animChannel); + commandInterface.set({mesh, &user_types::Mesh::bakeMeshes_}, false); + commandInterface.set({meshNode, &user_types::MeshNode::mesh_}, mesh); commandInterface.addLink({anim, {"outputs", "Ch0.Animation Sampler Name"}}, {meshNode, {"translation"}}); - commandInterface.set({anim, {"animationChannels", "Channel 0"}}, SEditorObject()); + commandInterface.set(channelsHandle[0], SEditorObject()); ASSERT_EQ(commandInterface.project()->links().size(), 1); ASSERT_FALSE((*commandInterface.project()->links().begin())->isValid()); - commandInterface.set({anim, {"animationChannels", "Channel 0"}}, animChannel); - + commandInterface.set(channelsHandle[0], animChannel); + ASSERT_EQ(commandInterface.project()->links().size(), 1); ASSERT_TRUE((*commandInterface.project()->links().begin())->isValid()); } @@ -172,16 +180,18 @@ TEST_F(AnimationTest, anim_in_prefab_prefabinstance_link_inside_prefabinstance) auto prefabInstance = context.createObject(PrefabInstance::typeDescription.typeName, "PrefabInstance"); std::string uriPath{(test_path() / "meshes" / "InterpolationTest" / "InterpolationTest.gltf").string()}; - commandInterface.set({animChannel, &raco::user_types::AnimationChannel::uri_}, uriPath); - commandInterface.set({mesh, &raco::user_types::Mesh::uri_}, uriPath); + commandInterface.set({animChannel, &user_types::AnimationChannel::uri_}, uriPath); + commandInterface.set({mesh, &user_types::Mesh::uri_}, uriPath); commandInterface.moveScenegraphChildren({anim}, prefab); commandInterface.moveScenegraphChildren({meshNode}, prefab); - commandInterface.set({anim, {"animationChannels", "Channel 1"}}, animChannel); - commandInterface.set({mesh, &raco::user_types::Mesh::bakeMeshes_}, false); - commandInterface.set({meshNode, &raco::user_types::MeshNode::mesh_}, mesh); - commandInterface.addLink({anim, {"outputs", "Ch1.Animation Sampler Name"}}, {meshNode, {"translation"}}); + ValueHandle channelsHandle(anim, &Animation::animationChannels_); + commandInterface.set(channelsHandle[0], animChannel); + commandInterface.set({mesh, &user_types::Mesh::bakeMeshes_}, false); + commandInterface.set({meshNode, &user_types::MeshNode::mesh_}, mesh); + + commandInterface.addLink({anim, {"outputs", "Ch0.Animation Sampler Name"}}, {meshNode, {"translation"}}); ASSERT_EQ(commandInterface.project()->links().size(), 1); ASSERT_TRUE((*commandInterface.project()->links().begin())->isValid()); diff --git a/datamodel/libUserTypes/tests/CubeMap_test.cpp b/datamodel/libUserTypes/tests/CubeMap_test.cpp index d5e8f5d6..6a064cbc 100644 --- a/datamodel/libUserTypes/tests/CubeMap_test.cpp +++ b/datamodel/libUserTypes/tests/CubeMap_test.cpp @@ -19,31 +19,31 @@ class CubeMapTest : public TestEnvironmentCore {}; TEST_F(CubeMapTest, invalidLevels) { auto cubeMap{commandInterface.createObject(CubeMap::typeDescription.typeName)}; - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::mipmapLevel_})); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::mipmapLevel_})); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::mipmapLevel_}, -1); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::mipmapLevel_})); + commandInterface.set({cubeMap, &user_types::CubeMap::mipmapLevel_}, -1); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::mipmapLevel_})); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::mipmapLevel_}, 1); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::mipmapLevel_})); + commandInterface.set({cubeMap, &user_types::CubeMap::mipmapLevel_}, 1); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::mipmapLevel_})); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::mipmapLevel_}, 5); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::mipmapLevel_})); + commandInterface.set({cubeMap, &user_types::CubeMap::mipmapLevel_}, 5); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::mipmapLevel_})); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::mipmapLevel_}, 4); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::mipmapLevel_})); + commandInterface.set({cubeMap, &user_types::CubeMap::mipmapLevel_}, 4); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::mipmapLevel_})); } TEST_F(CubeMapTest, levelOtherThanOneWhenGenerationFlagIsActivated) { auto cubeMap{commandInterface.createObject(CubeMap::typeDescription.typeName)}; - commandInterface.set({cubeMap, &raco::user_types::CubeMap::mipmapLevel_}, 2); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::mipmapLevel_})); + commandInterface.set({cubeMap, &user_types::CubeMap::mipmapLevel_}, 2); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::mipmapLevel_})); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::generateMipmaps_}, true); - ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::mipmapLevel_})); - ASSERT_EQ(commandInterface.errors().getError({cubeMap, &raco::user_types::CubeMap::mipmapLevel_}).level(), raco::core::ErrorLevel::WARNING); + commandInterface.set({cubeMap, &user_types::CubeMap::generateMipmaps_}, true); + ASSERT_TRUE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::mipmapLevel_})); + ASSERT_EQ(commandInterface.errors().getError({cubeMap, &user_types::CubeMap::mipmapLevel_}).level(), core::ErrorLevel::WARNING); - commandInterface.set({cubeMap, &raco::user_types::CubeMap::generateMipmaps_}, false); - ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &raco::user_types::CubeMap::mipmapLevel_})); + commandInterface.set({cubeMap, &user_types::CubeMap::generateMipmaps_}, false); + ASSERT_FALSE(commandInterface.errors().hasError({cubeMap, &user_types::CubeMap::mipmapLevel_})); } diff --git a/datamodel/libUserTypes/tests/DefaultValues_test.cpp b/datamodel/libUserTypes/tests/DefaultValues_test.cpp index 12a72277..eaeb065a 100644 --- a/datamodel/libUserTypes/tests/DefaultValues_test.cpp +++ b/datamodel/libUserTypes/tests/DefaultValues_test.cpp @@ -10,12 +10,12 @@ #include #include "user_types/DefaultValues.h" -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include constexpr const char* emptyVertexShader = "#version 300 es\n\ @@ -31,14 +31,14 @@ ramses::Appearance* createAppearance(ramses::Scene* scene) { ramses::EffectDescription desc{}; desc.setVertexShader(emptyVertexShader); desc.setFragmentShader(emptyFragmentShader); - ramses::Effect* effect = scene->createEffect(desc, ramses::ResourceCacheFlag_DoNotCache); + ramses::Effect* effect = scene->createEffect(desc); return scene->createAppearance(*effect); } TEST(DefaultValues, Appearance) { - ramses::RamsesFramework ramsesFramework; + ramses::RamsesFramework ramsesFramework{ramses::RamsesFrameworkConfig{ramses::EFeatureLevel::EFeatureLevel_01}}; ramses::RamsesClient& client = *ramsesFramework.createClient("client"); - ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), ramses::SceneConfig(), "scene"); + ramses::Scene* scene = client.createScene(ramses::sceneId_t(123u), "scene"); auto* appearance = createAppearance(scene); { @@ -46,31 +46,31 @@ TEST(DefaultValues, Appearance) { appearance->getBlendingFactors(srcColor, destColor, srcAlpha, destAlpha); using namespace raco::user_types; - ASSERT_EQ(srcColor, DEFAULT_VALUE_MATERIAL_BLEND_FACTOR_SRC_COLOR); - ASSERT_EQ(destColor, DEFAULT_VALUE_MATERIAL_BLEND_FACTOR_DEST_COLOR); - ASSERT_EQ(srcAlpha, DEFAULT_VALUE_MATERIAL_BLEND_FACTOR_SRC_ALPHA); - ASSERT_EQ(destAlpha, DEFAULT_VALUE_MATERIAL_BLEND_FACTOR_DEST_ALPHA); + ASSERT_EQ(static_cast(srcColor), DEFAULT_VALUE_MATERIAL_BLEND_FACTOR_SRC_COLOR); + ASSERT_EQ(static_cast(destColor), DEFAULT_VALUE_MATERIAL_BLEND_FACTOR_DEST_COLOR); + ASSERT_EQ(static_cast(srcAlpha), DEFAULT_VALUE_MATERIAL_BLEND_FACTOR_SRC_ALPHA); + ASSERT_EQ(static_cast(destAlpha), DEFAULT_VALUE_MATERIAL_BLEND_FACTOR_DEST_ALPHA); } { ramses::EBlendOperation colorOp, alphaOp; appearance->getBlendingOperations(colorOp, alphaOp); using namespace raco::user_types; - ASSERT_EQ(colorOp, DEFAULT_VALUE_MATERIAL_BLEND_OPERATION_COLOR); - ASSERT_EQ(alphaOp, DEFAULT_VALUE_MATERIAL_BLEND_OPERATION_ALPHA); + ASSERT_EQ(static_cast(colorOp), DEFAULT_VALUE_MATERIAL_BLEND_OPERATION_COLOR); + ASSERT_EQ(static_cast(alphaOp), DEFAULT_VALUE_MATERIAL_BLEND_OPERATION_ALPHA); } { ramses::ECullMode cullMode; appearance->getCullingMode(cullMode); using namespace raco::user_types; - ASSERT_EQ(cullMode, DEFAULT_VALUE_MATERIAL_CULL_MODE); + ASSERT_EQ(static_cast(cullMode), DEFAULT_VALUE_MATERIAL_CULL_MODE); } { ramses::EDepthFunc depthFunc; appearance->getDepthFunction(depthFunc); using namespace raco::user_types; - ASSERT_EQ(depthFunc, DEFAULT_VALUE_MATERIAL_DEPTH_FUNCTION); + ASSERT_EQ(static_cast(depthFunc), DEFAULT_VALUE_MATERIAL_DEPTH_FUNCTION); } } \ No newline at end of file diff --git a/datamodel/libUserTypes/tests/LuaInterface_test.cpp b/datamodel/libUserTypes/tests/LuaInterface_test.cpp index 611d071d..a66807b1 100644 --- a/datamodel/libUserTypes/tests/LuaInterface_test.cpp +++ b/datamodel/libUserTypes/tests/LuaInterface_test.cpp @@ -18,17 +18,12 @@ using namespace raco::user_types; class LuaInterfaceTest : public TestEnvironmentCore {}; -class LuaInterfaceTest_FL4 : public TestEnvironmentCore { -public: - LuaInterfaceTest_FL4() : TestEnvironmentCore(&UserObjectFactory::getInstance(), rlogic::EFeatureLevel::EFeatureLevel_04) {} -}; - TEST_F(LuaInterfaceTest, uri_warning_empty_uri) { auto interface = create("interface"); ValueHandle uriHandle{interface, &LuaInterface::uri_}; EXPECT_TRUE(commandInterface.errors().hasError(uriHandle)); - EXPECT_EQ(commandInterface.errors().getError(uriHandle).level(), raco::core::ErrorLevel::WARNING); + EXPECT_EQ(commandInterface.errors().getError(uriHandle).level(), core::ErrorLevel::WARNING); } TEST_F(LuaInterfaceTest, uri_error_set_invalid_uri) { @@ -38,7 +33,7 @@ TEST_F(LuaInterfaceTest, uri_error_set_invalid_uri) { commandInterface.set(uriHandle, std::string("invalid")); EXPECT_TRUE(commandInterface.errors().hasError(uriHandle)); - EXPECT_EQ(commandInterface.errors().getError(uriHandle).level(), raco::core::ErrorLevel::ERROR); + EXPECT_EQ(commandInterface.errors().getError(uriHandle).level(), core::ErrorLevel::ERROR); } TEST_F(LuaInterfaceTest, uri_error_compile_error) { @@ -68,19 +63,7 @@ end EXPECT_TRUE(commandInterface.errors().hasError({interface})); } -TEST_F(LuaInterfaceTest_FL4, interface_using_modules_FL4) { - TextFile interfaceFile = makeFile("interface.lua", R"( -modules("coalas") -function interface(INOUT) -end -)"); - auto interface = create_lua_interface("script", interfaceFile); - - EXPECT_FALSE(commandInterface.errors().hasError({interface})); - ASSERT_FALSE(commandInterface.errors().hasError({interface, {"luaModules", "coalas"}})); -} - -TEST_F(LuaInterfaceTest, interface_using_modules_FL5) { +TEST_F(LuaInterfaceTest, interface_using_modules) { TextFile interfaceFile = makeFile("interface.lua", R"( modules("coalas") function interface(INOUT) @@ -186,7 +169,7 @@ return what ASSERT_FALSE(commandInterface.errors().hasError({interface})); ASSERT_TRUE(commandInterface.errors().hasError(modulesHandle.get("coalas"))); - ASSERT_EQ(commandInterface.errors().getError(modulesHandle.get("coalas")).level(), raco::core::ErrorLevel::ERROR); + ASSERT_EQ(commandInterface.errors().getError(modulesHandle.get("coalas")).level(), core::ErrorLevel::ERROR); ASSERT_EQ(commandInterface.errors().getError(modulesHandle.get("coalas")).message(), "Invalid LuaScriptModule 'module' assigned."); } diff --git a/datamodel/libUserTypes/tests/LuaScriptModule_test.cpp b/datamodel/libUserTypes/tests/LuaScriptModule_test.cpp index 8be93c63..5bacf97b 100644 --- a/datamodel/libUserTypes/tests/LuaScriptModule_test.cpp +++ b/datamodel/libUserTypes/tests/LuaScriptModule_test.cpp @@ -31,7 +31,7 @@ TEST_F(LuaScriptModuleTest, URI_emptyURI_error) { ValueHandle uriHandle{module, {"uri"}}; ASSERT_TRUE(commandInterface.errors().hasError(uriHandle)); - ASSERT_EQ(commandInterface.errors().getError(uriHandle).level(), raco::core::ErrorLevel::WARNING); + ASSERT_EQ(commandInterface.errors().getError(uriHandle).level(), core::ErrorLevel::WARNING); } TEST_F(LuaScriptModuleTest, URI_setInvalidURI_error) { @@ -40,7 +40,7 @@ TEST_F(LuaScriptModuleTest, URI_setInvalidURI_error) { commandInterface.set(uriHandle, std::string("blah.lua")); ASSERT_TRUE(commandInterface.errors().hasError(uriHandle)); - ASSERT_EQ(commandInterface.errors().getError(uriHandle).level(), raco::core::ErrorLevel::ERROR); + ASSERT_EQ(commandInterface.errors().getError(uriHandle).level(), core::ErrorLevel::ERROR); } TEST_F(LuaScriptModuleTest, URI_setValidURI_noError) { diff --git a/datamodel/libUserTypes/tests/LuaScript_test.cpp b/datamodel/libUserTypes/tests/LuaScript_test.cpp index 4f10e211..f5d7b106 100644 --- a/datamodel/libUserTypes/tests/LuaScript_test.cpp +++ b/datamodel/libUserTypes/tests/LuaScript_test.cpp @@ -79,7 +79,7 @@ TEST_F(LuaScriptTest, URI_sanitizeSlashes) { #endif commandInterface.set({script, {"uri"}}, unsanitizedPath); - ASSERT_EQ(raco::core::ValueHandle(script, {"uri"}).asString(), sanitizedPath); + ASSERT_EQ(core::ValueHandle(script, {"uri"}).asString(), sanitizedPath); } TEST_F(LuaScriptTest, URI_sanitizeNetworkPath) { @@ -93,7 +93,7 @@ TEST_F(LuaScriptTest, URI_sanitizeNetworkPath) { #endif commandInterface.set({script, {"uri"}}, unsanitizedPath); - ASSERT_EQ(raco::core::ValueHandle(script, {"uri"}).asString(), sanitizedPath); + ASSERT_EQ(core::ValueHandle(script, {"uri"}).asString(), sanitizedPath); } TEST_F(LuaScriptTest, inputs_are_correctly_built) { @@ -325,7 +325,7 @@ TEST_F(LuaScriptTest, modules_in_uri_are_rejected) { commandInterface.set(s.get("uri"), test_path().append("scripts/moduleDefinition.lua").string()); ASSERT_TRUE(commandInterface.errors().hasError({newScript})); - ASSERT_EQ(commandInterface.errors().getError({newScript}).level(), raco::core::ErrorLevel::ERROR); + ASSERT_EQ(commandInterface.errors().getError({newScript}).level(), core::ErrorLevel::ERROR); ASSERT_EQ(newScript->luaModules_->size(), 0); } @@ -420,21 +420,21 @@ return anothermodule ASSERT_TRUE(commandInterface.errors().hasError(s.get("luaModules").get("module"))); ASSERT_TRUE(commandInterface.errors().hasError(s.get("luaModules").get("anothermodule"))); - commandInterface.set({modules[0], &raco::user_types::LuaScriptModule::uri_}, moduleFile1); + commandInterface.set({modules[0], &user_types::LuaScriptModule::uri_}, moduleFile1); ASSERT_FALSE(commandInterface.errors().hasError({newScript})); ASSERT_FALSE(commandInterface.errors().hasError(s.get("luaModules").get("coalas"))); ASSERT_TRUE(commandInterface.errors().hasError(s.get("luaModules").get("module"))); ASSERT_TRUE(commandInterface.errors().hasError(s.get("luaModules").get("anothermodule"))); - commandInterface.set({modules[1], &raco::user_types::LuaScriptModule::uri_}, moduleFile2); + commandInterface.set({modules[1], &user_types::LuaScriptModule::uri_}, moduleFile2); ASSERT_FALSE(commandInterface.errors().hasError({newScript})); ASSERT_FALSE(commandInterface.errors().hasError(s.get("luaModules").get("coalas"))); ASSERT_FALSE(commandInterface.errors().hasError(s.get("luaModules").get("module"))); ASSERT_TRUE(commandInterface.errors().hasError(s.get("luaModules").get("anothermodule"))); - commandInterface.set({modules[2], &raco::user_types::LuaScriptModule::uri_}, moduleFile3); + commandInterface.set({modules[2], &user_types::LuaScriptModule::uri_}, moduleFile3); ASSERT_FALSE(commandInterface.errors().hasError({newScript})); ASSERT_FALSE(commandInterface.errors().hasError(s.get("luaModules").get("coalas"))); @@ -445,7 +445,7 @@ return anothermodule ASSERT_EQ(newScript->inputs_->propertyNames(), std::vector({"aa", "abc", "ff", "za", "zz"})); ASSERT_EQ(newScript->outputs_->propertyNames(), std::vector({"aa", "e", "zz", "zzz"})); - commandInterface.set({modules[2], &raco::user_types::LuaScriptModule::uri_}, std::string()); + commandInterface.set({modules[2], &user_types::LuaScriptModule::uri_}, std::string()); ASSERT_FALSE(commandInterface.errors().hasError({newScript})); ASSERT_FALSE(commandInterface.errors().hasError(s.get("luaModules").get("coalas"))); @@ -517,9 +517,9 @@ return anothermodule commandInterface.set(s.get("luaModules").get("coalas"), modules[0]); commandInterface.set(s.get("luaModules").get("module"), modules[1]); commandInterface.set(s.get("luaModules").get("anothermodule"), modules[2]); - commandInterface.set({modules[0], &raco::user_types::LuaScriptModule::uri_}, moduleFile1); - commandInterface.set({modules[1], &raco::user_types::LuaScriptModule::uri_}, moduleFile2); - commandInterface.set({modules[2], &raco::user_types::LuaScriptModule::uri_}, moduleFile3); + commandInterface.set({modules[0], &user_types::LuaScriptModule::uri_}, moduleFile1); + commandInterface.set({modules[1], &user_types::LuaScriptModule::uri_}, moduleFile2); + commandInterface.set({modules[2], &user_types::LuaScriptModule::uri_}, moduleFile3); commandInterface.set(s.get("uri"), scriptFile2); ASSERT_FALSE(commandInterface.errors().hasError({newScript})); @@ -587,7 +587,7 @@ local coalaModule = {} return coalaModule )"); - commandInterface.set(raco::core::ValueHandle{module, &raco::user_types::LuaScriptModule::uri_}, moduleFile); + commandInterface.set(core::ValueHandle{module, &user_types::LuaScriptModule::uri_}, moduleFile); commandInterface.set(scriptUri, scriptFile); ASSERT_TRUE(commandInterface.errors().hasError({newScript})); ASSERT_TRUE(newScript->luaModules_->propertyNames().empty()); @@ -665,13 +665,13 @@ return what )"); commandInterface.set(scriptUri, scriptFile); - commandInterface.set(raco::core::ValueHandle{moduleInvalid, &raco::user_types::LuaScriptModule::uri_}, moduleInvalidFile); + commandInterface.set(core::ValueHandle{moduleInvalid, &user_types::LuaScriptModule::uri_}, moduleInvalidFile); commandInterface.set(s.get("luaModules").get("coalas"), moduleInvalid); ASSERT_FALSE(commandInterface.errors().hasError({newScript})); ASSERT_TRUE(commandInterface.errors().hasError(s.get("luaModules").get("coalas"))); - ASSERT_EQ(commandInterface.errors().getError(s.get("luaModules").get("coalas")).level(), raco::core::ErrorLevel::ERROR); + ASSERT_EQ(commandInterface.errors().getError(s.get("luaModules").get("coalas")).level(), core::ErrorLevel::ERROR); ASSERT_EQ(commandInterface.errors().getError(s.get("luaModules").get("coalas")).message(), "Invalid LuaScriptModule 'invalid' assigned."); ASSERT_TRUE(commandInterface.errors().hasError(s.get("luaModules").get("test"))); @@ -701,18 +701,18 @@ return what )"); commandInterface.set(scriptUri, scriptFile); - commandInterface.set(raco::core::ValueHandle{moduleInvalid1, &raco::user_types::LuaScriptModule::uri_}, moduleInvalidFile); - commandInterface.set(raco::core::ValueHandle{moduleInvalid2, &raco::user_types::LuaScriptModule::uri_}, moduleInvalidFile); + commandInterface.set(core::ValueHandle{moduleInvalid1, &user_types::LuaScriptModule::uri_}, moduleInvalidFile); + commandInterface.set(core::ValueHandle{moduleInvalid2, &user_types::LuaScriptModule::uri_}, moduleInvalidFile); commandInterface.set(s.get("luaModules").get("coalas"), moduleInvalid1); commandInterface.set(s.get("luaModules").get("test"), moduleInvalid2); ASSERT_FALSE(commandInterface.errors().hasError({newScript})); ASSERT_TRUE(commandInterface.errors().hasError(s.get("luaModules").get("coalas"))); - ASSERT_EQ(commandInterface.errors().getError(s.get("luaModules").get("coalas")).level(), raco::core::ErrorLevel::ERROR); + ASSERT_EQ(commandInterface.errors().getError(s.get("luaModules").get("coalas")).level(), core::ErrorLevel::ERROR); ASSERT_EQ(commandInterface.errors().getError(s.get("luaModules").get("coalas")).message(), "Invalid LuaScriptModule 'invalid1' assigned."); ASSERT_TRUE(commandInterface.errors().hasError(s.get("luaModules").get("test"))); - ASSERT_EQ(commandInterface.errors().getError(s.get("luaModules").get("test")).level(), raco::core::ErrorLevel::ERROR); + ASSERT_EQ(commandInterface.errors().getError(s.get("luaModules").get("test")).level(), core::ErrorLevel::ERROR); ASSERT_EQ(commandInterface.errors().getError(s.get("luaModules").get("test")).message(), "Invalid LuaScriptModule 'invalid2' assigned."); } @@ -746,8 +746,8 @@ return coalaModule )"); commandInterface.set(scriptUri, scriptFile); - commandInterface.set(raco::core::ValueHandle{moduleValid, &raco::user_types::LuaScriptModule::uri_}, moduleValidFile); - commandInterface.set(raco::core::ValueHandle{moduleInvalid, &raco::user_types::LuaScriptModule::uri_}, moduleInvalidFile); + commandInterface.set(core::ValueHandle{moduleValid, &user_types::LuaScriptModule::uri_}, moduleValidFile); + commandInterface.set(core::ValueHandle{moduleInvalid, &user_types::LuaScriptModule::uri_}, moduleInvalidFile); commandInterface.set(s.get("luaModules").get("coalas"), moduleValid); commandInterface.set(s.get("luaModules").get("test"), moduleValid); @@ -764,7 +764,7 @@ return coalaModule ASSERT_FALSE(commandInterface.errors().hasError(s.get("luaModules").get("test"))); // make invalid by changing URIs - commandInterface.set(raco::core::ValueHandle{moduleValid, &raco::user_types::LuaScriptModule::uri_}, moduleInvalidFile); + commandInterface.set(core::ValueHandle{moduleValid, &user_types::LuaScriptModule::uri_}, moduleInvalidFile); ASSERT_FALSE(commandInterface.errors().hasError({newScript})); ASSERT_TRUE(commandInterface.errors().hasError(s.get("luaModules").get("test"))); @@ -801,8 +801,8 @@ return coalaModule )"); commandInterface.set(scriptUri, scriptFile); - commandInterface.set(raco::core::ValueHandle{moduleValid, &raco::user_types::LuaScriptModule::uri_}, moduleValidFile); - commandInterface.set(raco::core::ValueHandle{moduleInvalid, &raco::user_types::LuaScriptModule::uri_}, moduleInvalidFile); + commandInterface.set(core::ValueHandle{moduleValid, &user_types::LuaScriptModule::uri_}, moduleValidFile); + commandInterface.set(core::ValueHandle{moduleInvalid, &user_types::LuaScriptModule::uri_}, moduleInvalidFile); commandInterface.set(s.get("luaModules").get("coalas"), moduleInvalid); commandInterface.set(s.get("luaModules").get("test"), moduleValid); diff --git a/datamodel/libUserTypes/tests/Material_test.cpp b/datamodel/libUserTypes/tests/Material_test.cpp index 6ec78992..3b6fccca 100644 --- a/datamodel/libUserTypes/tests/Material_test.cpp +++ b/datamodel/libUserTypes/tests/Material_test.cpp @@ -79,6 +79,7 @@ TEST_F(MaterialTest, uniform_array) { } }; + checkArray(*mat->uniforms_, "bvec", 3, PrimitiveType::Bool); checkArray(*mat->uniforms_, "ivec", 2, PrimitiveType::Int); checkArray(*mat->uniforms_, "fvec", 5, PrimitiveType::Double); diff --git a/datamodel/libUserTypes/tests/MeshNode_test.cpp b/datamodel/libUserTypes/tests/MeshNode_test.cpp index b7e6bd06..53d077bf 100644 --- a/datamodel/libUserTypes/tests/MeshNode_test.cpp +++ b/datamodel/libUserTypes/tests/MeshNode_test.cpp @@ -16,7 +16,7 @@ using namespace raco::user_types; class MeshNodeTest : public TestEnvironmentCore { protected: - void setMaterialOptions(raco::user_types::SMaterial& material) { + void setMaterialOptions(user_types::SMaterial& material) { commandInterface.set({material, {"options", "blendOperationColor"}}, 3); commandInterface.set({material, {"options", "blendOperationAlpha"}}, 2); commandInterface.set({material, {"options", "blendFactorSrcColor"}}, 8); @@ -241,12 +241,12 @@ void main() { auto meshnode = create_meshnode("meshnode", mesh, material); commandInterface.set(meshnode->getMaterialPrivateHandle(0), true); - commandInterface.set(raco::core::ValueHandle{material, {"uniforms", "p", "x"}}, 0.5); - commandInterface.set(raco::core::ValueHandle{meshnode, {"materials", "material", "uniforms", "p", "x"}}, 2.0); + commandInterface.set(core::ValueHandle{material, {"uniforms", "p", "x"}}, 0.5); + commandInterface.set(core::ValueHandle{meshnode, {"materials", "material", "uniforms", "p", "x"}}, 2.0); commandInterface.set({material, &Material::uriFragment_}, altFragShader); - EXPECT_FALSE(raco::core::ValueHandle(meshnode, {"materials", "material", "uniforms"}).hasProperty("a")); + EXPECT_FALSE(core::ValueHandle(meshnode, {"materials", "material", "uniforms"}).hasProperty("a")); // Check tha we keep the uniform value of the meshnode and don't copy the value from the material instead: - EXPECT_EQ(raco::core::ValueHandle(meshnode, {"materials", "material", "uniforms", "p", "x"}).asDouble(), 2.0); + EXPECT_EQ(core::ValueHandle(meshnode, {"materials", "material", "uniforms", "p", "x"}).asDouble(), 2.0); } \ No newline at end of file diff --git a/datamodel/libUserTypes/tests/Mesh_test.cpp b/datamodel/libUserTypes/tests/Mesh_test.cpp index f1913e14..ce0be469 100644 --- a/datamodel/libUserTypes/tests/Mesh_test.cpp +++ b/datamodel/libUserTypes/tests/Mesh_test.cpp @@ -23,7 +23,7 @@ TEST_F(MeshTest, submeshSelection_wrongSubmeshIndexCreatesErrorTooLow) { commandInterface.set(ValueHandle{mesh, {"bakeMeshes"}}, false); commandInterface.set(ValueHandle{mesh, {"uri"}}, test_path().append("meshes/Duck.glb").string()); commandInterface.set(ValueHandle{mesh, {"meshIndex"}}, -1); - ASSERT_EQ(commandInterface.errors().getError(ValueHandle{mesh}).level(), raco::core::ErrorLevel::ERROR); + ASSERT_EQ(commandInterface.errors().getError(ValueHandle{mesh}).level(), core::ErrorLevel::ERROR); } TEST_F(MeshTest, submeshSelection_correctSubmeshIndexFixesError) { @@ -34,14 +34,14 @@ TEST_F(MeshTest, submeshSelection_correctSubmeshIndexFixesError) { commandInterface.set(ValueHandle{mesh, {"meshIndex"}}, 1); commandInterface.set(ValueHandle{mesh, {"meshIndex"}}, 0); - ASSERT_EQ(commandInterface.errors().getError(ValueHandle{mesh}).level(), raco::core::ErrorLevel::INFORMATION); + ASSERT_EQ(commandInterface.errors().getError(ValueHandle{mesh}).level(), core::ErrorLevel::INFORMATION); } TEST_F(MeshTest, meshInfo_showMetaDataWithUnbakedMeshes) { auto mesh = commandInterface.createObject(Mesh::typeDescription.typeName, "Mesh"); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::bakeMeshes_}, false); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::uri_}, test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string()); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::bakeMeshes_}, false); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::uri_}, test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string()); ASSERT_EQ(commandInterface.errors().getError(ValueHandle{mesh}).message(), R"(Mesh information @@ -55,7 +55,7 @@ in vec3 a_Position; in vec3 a_Normal; in vec2 a_TextureCoordinate;)"); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::meshIndex_}, 1); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::meshIndex_}, 1); ASSERT_EQ(commandInterface.errors().getError(ValueHandle{mesh}).message(), R"(Mesh information @@ -71,7 +71,7 @@ in vec2 a_TextureCoordinate; Metadata: prop1: truck mesh property)"); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::meshIndex_}, 2); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::meshIndex_}, 2); ASSERT_EQ(commandInterface.errors().getError(ValueHandle{mesh}).message(), R"(Mesh information @@ -87,7 +87,7 @@ in vec2 a_TextureCoordinate; Metadata: prop1: truck mesh property)"); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::meshIndex_}, 3); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::meshIndex_}, 3); ASSERT_EQ(commandInterface.errors().getError(ValueHandle{mesh}).message(), R"(Mesh information @@ -107,10 +107,10 @@ prop1: truck mesh property)"); TEST_F(MeshTest, meshInfo_dontShowMetaDataWithBakedMeshes) { auto mesh = commandInterface.createObject(Mesh::typeDescription.typeName, "Mesh"); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::bakeMeshes_}, false); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::uri_}, test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string()); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::meshIndex_}, 1); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::bakeMeshes_}, true); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::bakeMeshes_}, false); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::uri_}, test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string()); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::meshIndex_}, 1); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::bakeMeshes_}, true); ASSERT_EQ(commandInterface.errors().getError(ValueHandle{mesh}).message(), R"(Mesh information @@ -126,36 +126,39 @@ in vec2 a_TextureCoordinate;)"); } TEST_F(MeshTest, meshInfo_updateMetaDataAfterInvalidUri) { - auto mesh = commandInterface.createObject(Mesh::typeDescription.typeName, "Mesh"); + auto mesh = commandInterface.createObject(Mesh::typeDescription.typeName, "Mesh")->as(); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::bakeMeshes_}, false); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::uri_}, test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string()); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::meshIndex_}, 1); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::uri_}, std::string("invalid")); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::bakeMeshes_}, false); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::uri_}, test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string()); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::meshIndex_}, 1); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::uri_}, std::string("invalid")); - ASSERT_TRUE(mesh->as()->metaData_.empty()); + ASSERT_FALSE(mesh->metaData_->hasProperty("gltfExtras")); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::uri_}, test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string()); - ASSERT_FALSE(mesh->as()->metaData_.empty()); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::uri_}, test_path().append("meshes/CesiumMilkTruck/CesiumMilkTruck.gltf").string()); + ASSERT_TRUE(mesh->metaData_->hasProperty("gltfExtras")); + auto& extrasContainer = mesh->metaData_->get("gltfExtras")->asTable(); + ASSERT_TRUE(extrasContainer.hasProperty("prop1")); + EXPECT_EQ(extrasContainer.get("prop1")->asString(), std::string("truck mesh property")); } TEST_F(MeshTest, valid_file_with_no_meshes_unbaked_submesh_error) { auto mesh = commandInterface.createObject(Mesh::typeDescription.typeName, "Mesh"); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::bakeMeshes_}, false); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::uri_}, test_path().append("meshes/meshless.gltf").string()); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::bakeMeshes_}, false); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::uri_}, test_path().append("meshes/meshless.gltf").string()); ASSERT_TRUE(commandInterface.errors().hasError({mesh})); - ASSERT_EQ(commandInterface.errors().getError(ValueHandle{mesh}).level(), raco::core::ErrorLevel::ERROR); + ASSERT_EQ(commandInterface.errors().getError(ValueHandle{mesh}).level(), core::ErrorLevel::ERROR); } TEST_F(MeshTest, valid_file_with_no_meshes_baked_no_submesh_error) { auto mesh = commandInterface.createObject(Mesh::typeDescription.typeName, "Mesh"); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::bakeMeshes_}, false); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::uri_}, test_path().append("meshes/meshless.gltf").string()); - commandInterface.set(ValueHandle{mesh, &raco::user_types::Mesh::bakeMeshes_}, true); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::bakeMeshes_}, false); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::uri_}, test_path().append("meshes/meshless.gltf").string()); + commandInterface.set(ValueHandle{mesh, &user_types::Mesh::bakeMeshes_}, true); ASSERT_TRUE(commandInterface.errors().hasError({mesh})); - ASSERT_EQ(commandInterface.errors().getError(ValueHandle{mesh}).level(), raco::core::ErrorLevel::ERROR); + ASSERT_EQ(commandInterface.errors().getError(ValueHandle{mesh}).level(), core::ErrorLevel::ERROR); } \ No newline at end of file diff --git a/datamodel/libUserTypes/tests/Skin_test.cpp b/datamodel/libUserTypes/tests/Skin_test.cpp index 9971b9d8..82b52115 100644 --- a/datamodel/libUserTypes/tests/Skin_test.cpp +++ b/datamodel/libUserTypes/tests/Skin_test.cpp @@ -23,7 +23,7 @@ TEST_F(SkinTest, uri_empty) { ValueHandle uriHandle{skin, &Skin::uri_}; EXPECT_TRUE(commandInterface.errors().hasError(uriHandle)); - EXPECT_EQ(commandInterface.errors().getError(uriHandle).level(), raco::core::ErrorLevel::WARNING); + EXPECT_EQ(commandInterface.errors().getError(uriHandle).level(), core::ErrorLevel::WARNING); } TEST_F(SkinTest, uri_invalid) { @@ -32,7 +32,7 @@ TEST_F(SkinTest, uri_invalid) { commandInterface.set(uriHandle, std::string("invalid")); EXPECT_TRUE(commandInterface.errors().hasError(uriHandle)); - EXPECT_EQ(commandInterface.errors().getError(uriHandle).level(), raco::core::ErrorLevel::ERROR); + EXPECT_EQ(commandInterface.errors().getError(uriHandle).level(), core::ErrorLevel::ERROR); } TEST_F(SkinTest, uri_valid) { @@ -60,14 +60,14 @@ TEST_F(SkinTest, skin_index_range_errors) { EXPECT_EQ(skin->joints_->size(), 0); EXPECT_TRUE(commandInterface.errors().hasError({skin})); - EXPECT_EQ(commandInterface.errors().getError({skin}).level(), raco::core::ErrorLevel::ERROR); + EXPECT_EQ(commandInterface.errors().getError({skin}).level(), core::ErrorLevel::ERROR); EXPECT_EQ(skin->skinData(), nullptr); commandInterface.set(indexHandle, 0); EXPECT_EQ(skin->joints_->size(), 2); EXPECT_TRUE(commandInterface.errors().hasError({skin})); - EXPECT_EQ(commandInterface.errors().getError({skin}).level(), raco::core::ErrorLevel::INFORMATION); + EXPECT_EQ(commandInterface.errors().getError({skin}).level(), core::ErrorLevel::INFORMATION); EXPECT_NE(skin->skinData(), nullptr); EXPECT_EQ(skin->skinData()->numSkins, 1); EXPECT_EQ(skin->skinData()->inverseBindMatrices.size(), 2); diff --git a/datamodel/libUserTypes/tests/Texture_test.cpp b/datamodel/libUserTypes/tests/Texture_test.cpp index 9c6461dd..d0aa1a32 100644 --- a/datamodel/libUserTypes/tests/Texture_test.cpp +++ b/datamodel/libUserTypes/tests/Texture_test.cpp @@ -22,45 +22,45 @@ class TextureTest : public TestEnvironmentCore {}; TEST_F(TextureTest, invalidLevels) { auto texture{commandInterface.createObject(Texture::typeDescription.typeName)}; - ASSERT_FALSE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::mipmapLevel_})); + ASSERT_FALSE(commandInterface.errors().hasError({texture, &user_types::Texture::mipmapLevel_})); - commandInterface.set({texture, &raco::user_types::Texture::mipmapLevel_}, -1); - ASSERT_TRUE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::mipmapLevel_})); + commandInterface.set({texture, &user_types::Texture::mipmapLevel_}, -1); + ASSERT_TRUE(commandInterface.errors().hasError({texture, &user_types::Texture::mipmapLevel_})); - commandInterface.set({texture, &raco::user_types::Texture::mipmapLevel_}, 1); - ASSERT_FALSE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::mipmapLevel_})); + commandInterface.set({texture, &user_types::Texture::mipmapLevel_}, 1); + ASSERT_FALSE(commandInterface.errors().hasError({texture, &user_types::Texture::mipmapLevel_})); - commandInterface.set({texture, &raco::user_types::Texture::mipmapLevel_}, 5); - ASSERT_TRUE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::mipmapLevel_})); + commandInterface.set({texture, &user_types::Texture::mipmapLevel_}, 5); + ASSERT_TRUE(commandInterface.errors().hasError({texture, &user_types::Texture::mipmapLevel_})); - commandInterface.set({texture, &raco::user_types::Texture::mipmapLevel_}, 4); - ASSERT_FALSE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::mipmapLevel_})); + commandInterface.set({texture, &user_types::Texture::mipmapLevel_}, 4); + ASSERT_FALSE(commandInterface.errors().hasError({texture, &user_types::Texture::mipmapLevel_})); } TEST_F(TextureTest, levelOtherThanOneWhenGenerationFlagIsActivated) { auto texture{commandInterface.createObject(Texture::typeDescription.typeName)}; - commandInterface.set({texture, &raco::user_types::Texture::mipmapLevel_}, 2); - ASSERT_FALSE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::mipmapLevel_})); + commandInterface.set({texture, &user_types::Texture::mipmapLevel_}, 2); + ASSERT_FALSE(commandInterface.errors().hasError({texture, &user_types::Texture::mipmapLevel_})); - commandInterface.set({texture, &raco::user_types::Texture::generateMipmaps_}, true); - ASSERT_TRUE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::mipmapLevel_})); - ASSERT_EQ(commandInterface.errors().getError({texture, &raco::user_types::Texture::mipmapLevel_}).level(), raco::core::ErrorLevel::WARNING); + commandInterface.set({texture, &user_types::Texture::generateMipmaps_}, true); + ASSERT_TRUE(commandInterface.errors().hasError({texture, &user_types::Texture::mipmapLevel_})); + ASSERT_EQ(commandInterface.errors().getError({texture, &user_types::Texture::mipmapLevel_}).level(), core::ErrorLevel::WARNING); - commandInterface.set({texture, &raco::user_types::Texture::generateMipmaps_}, false); - ASSERT_FALSE(commandInterface.errors().hasError({texture, &raco::user_types::Texture::mipmapLevel_})); + commandInterface.set({texture, &user_types::Texture::generateMipmaps_}, false); + ASSERT_FALSE(commandInterface.errors().hasError({texture, &user_types::Texture::mipmapLevel_})); } TEST_F(TextureTest, error_present_after_load) { - raco::ramses_base::HeadlessEngineBackend backend{raco::ramses_base::BaseEngineBackend::maxFeatureLevel}; + ramses_base::HeadlessEngineBackend backend; { raco::application::RaCoApplication app{backend}; auto& cmd = *app.activeRaCoProject().commandInterface(); auto texture{cmd.createObject(Texture::typeDescription.typeName, "texture")}; - cmd.set({texture, &raco::user_types::Texture::mipmapLevel_}, -1); - ASSERT_TRUE(cmd.errors().hasError({texture, &raco::user_types::Texture::mipmapLevel_})); + cmd.set({texture, &user_types::Texture::mipmapLevel_}, -1); + ASSERT_TRUE(cmd.errors().hasError({texture, &user_types::Texture::mipmapLevel_})); std::string msg; app.activeRaCoProject().saveAs(QString::fromStdString((test_path() / "test.rca").string()), msg); @@ -73,8 +73,8 @@ TEST_F(TextureTest, error_present_after_load) { auto& project = *app.activeRaCoProject().project(); - auto texture = raco::core::Queries::findByName(project.instances(), "texture"); + auto texture = core::Queries::findByName(project.instances(), "texture"); - ASSERT_TRUE(app.activeRaCoProject().errors()->hasError({texture, &raco::user_types::Texture::mipmapLevel_})); + ASSERT_TRUE(app.activeRaCoProject().errors()->hasError({texture, &user_types::Texture::mipmapLevel_})); } } \ No newline at end of file diff --git a/doc/advanced/python_api/README.md b/doc/advanced/python_api/README.md index 086eafd4..ad712b3b 100644 --- a/doc/advanced/python_api/README.md +++ b/doc/advanced/python_api/README.md @@ -125,8 +125,8 @@ The `raco` module is available in both RaCoHeadless and RaCoEditor. You'll need > externalProjects() >> Get a list of the absolute paths of all externally referenced projects. -> export(ramses_path, logic_path, compress) ->> Export the active project. The paths of the Ramses and RamsesLogic files need to be specified. Additionally, compression can be enabled using the `compress` flag. +> export(ramses_path, compress[, luaSaveMode]) +>> Export the active project. The paths of the Ramses file needs to be specified. Additionally, compression can be enabled using the `compress` flag. Optionally the `luaSaveMode` parameter can be used to control whether the export should include Lua scripts as source code, byte code, or both. The `luaSaveMode` must be a `ELuaSavingMode` enumeration with the valid values being `SourceCodeOnly`, `ByteCodeOnly`, and `SourceAndByteCode`. > getErrors() >> Returns a list of active `ErrorItems` @@ -134,9 +134,6 @@ The `raco` module is available in both RaCoHeadless and RaCoEditor. You'll need > importGLTF(path[, parent]) >> Import complete contents of a gltf file into the current scene. Inserts the new nodes below `parent` in the scenegraph when the optional argument is given. -> saveScreenshot(path) ->> Save a screenshot of the preview to the given `path` as a `.png` image file. - ### Active Project Access @@ -233,9 +230,6 @@ Member functions: > keys() >> Returns a list of the names of all properties in internal data model order. -> metadata() ->> If the object is a mesh this will return gltf `extras` metadata as a dictionary. Only string values in the gltf `extras` are supported. - > getUserTags() >> Return the `userTags` property of an object as list of strings. @@ -305,6 +299,8 @@ The printed representation includes the type and the full path of the property s > keys() >> Returns a list of the names of all nested properties if `property` has substructure. Returns an empty list if `property` has no substructure. +> resize(newSize) +>> Resize an array property to `newSize`. Array properties have a `typeName()` of the form `Array[elementType]`. ### Child property access @@ -400,6 +396,31 @@ The member variables of a LinkDescriptor can't be changed. Modification of links >> In case of object errors, this will return the EditorObject causing the error. >> If the error refers to a property, this will return the PropertyDescriptor instead. +### Composite Commands + +Each Python API call will normally generate a single undo stack entry. In complicated scripts this may lead to a huge number of undo stack entries. This makes it more difficult for users to find the range of operations a script performed and may also lead to unnecessarily high memory consumption. + +It is therefore possible to group individual Python API calls into composite commands which only generate a single undo stack entry. This is done using a `with` statement context manager as follows +``` +with raco.compositeCommand("create and init node"): + node = raco.create("Node", "node") + node.translation.x = 100.0 +``` +The parameter of the context manager is the description of the entry which is shown in the undo view. + +Composite commands can be nested, e.g. +``` +with raco.compositeCommand("create and init node"): + node = raco.create("Node", "node") + node.translation.x = 100.0 + with raco.compositeCommand("inner composite command"): + raco.create("Material", "material") + raco.create("Mesh", "mesh") +``` +will still generate only a single undo stack entry. + +If any operation within a possibly nested composite command fails or an exception is thrown inside a composite command the outermost composite command is aborted and the project is restored to the state before entering the outermost composite command. In other words, composite commands are executed atomically, i.e. they succeeed or fail as a whole. + ## `raco_gui` module reference When running python scripts inside RaCoEditor, `raco_gui` is available to interact with editor specific things. You'll need to add an explicit import statement for the module in order to call the methods mentioned below. @@ -407,3 +428,6 @@ If you need to ensure that your scripts run both in headless and in gui, you can > getSelection() >> Returns a list of the currently selected editor objects. + +> saveScreenshot(path) +>> Save a screenshot of the preview to the given `path` as a `.png` image file. diff --git a/doc/basics/blitpass/blitpass.rca b/doc/basics/blitpass/blitpass.rca index 0365c13f..5ee3458e 100644 --- a/doc/basics/blitpass/blitpass.rca +++ b/doc/basics/blitpass/blitpass.rca @@ -2,306 +2,172 @@ "externalProjects": { }, "featureLevel": 1, - "fileVersion": 46, + "fileVersion": 2001, "instances": [ { "properties": { - "destinationX": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 128 - }, - "destinationY": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 0 - }, - "enabled": true, - "height": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 128 + "backgroundColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } }, - "objectID": "0425a489-8986-4ba8-bbeb-6a77cc4850f6", - "objectName": "BlitPass (1)", - "renderOrder": 1, - "sourceRenderBuffer": "5bc6f436-a4db-4680-b443-1bc21573a661", - "sourceRenderBufferMS": null, - "sourceX": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 70 + "defaultResourceFolders": { + "imageSubdirectory": "images", + "interfaceSubdirectory": "interfaces", + "meshSubdirectory": "meshes", + "scriptSubdirectory": "scripts", + "shaderSubdirectory": "shaders" }, - "sourceY": { + "featureLevel": 1, + "objectID": "a2840514-1f24-4e84-b843-ae26eb95f0b4", + "objectName": "blitpass", + "saveAsZip": false, + "sceneId": { "annotations": [ { "properties": { - "max": 7680, - "min": 0 + "max": 1024, + "min": 1 }, "typeName": "RangeAnnotationInt" } ], - "value": 116 + "value": 123 }, - "targetRenderBuffer": "b72d7ae5-cfd1-4caf-bc70-828584fdf2b8", - "targetRenderBufferMS": null, - "width": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 128 + "viewport": { + "i1": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + } } }, - "typeName": "BlitPass" + "typeName": "ProjectSettings" }, { "properties": { + "children": [ + "ce64a3b9-ef82-49af-bbd1-25dfc2f22a90", + "3128e5b1-f908-45f2-8397-bc946589808e", + "0945082f-ba9d-4a9b-9c35-d6ae31462946" + ], "enabled": true, - "instanceCount": { - "annotations": [ - { - "properties": { - "max": 20, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 + "objectID": "a42eae27-ec9d-4864-9e59-c895c962282d", + "objectName": "Node", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } }, - "materials": { - "order": [ - "material" - ], - "properties": { - "material": { - "order": [ - "material", - "private", - "options", - "uniforms" - ], - "properties": { - "material": { - "typeName": "Material", - "value": "848d6e6e-0f13-4e8d-89a3-32638c1c6d9f" - }, - "options": { - "annotations": [ - { - "properties": { - "name": "Options" - }, - "typeName": "DisplayNameAnnotation" - } - ], - "properties": { - "blendColor": { - "w": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "x": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "blendFactorDestAlpha": 1, - "blendFactorDestColor": 3, - "blendFactorSrcAlpha": 1, - "blendFactorSrcColor": 2, - "blendOperationAlpha": 0, - "blendOperationColor": 0, - "cullmode": 2, - "depthFunction": 4, - "depthwrite": true - }, - "typeName": "BlendOptions::DisplayNameAnnotation" - }, - "private": { - "annotations": [ - { - "properties": { - "name": "Private Material" - }, - "typeName": "DisplayNameAnnotation" - } - ], - "typeName": "Bool::DisplayNameAnnotation", - "value": true - }, - "uniforms": { - "order": [ - "u_FlipUV", - "u_Tex" - ], - "properties": { - "u_FlipUV": { - "annotations": [ - { - "properties": { - "engineType": 2 - }, - "typeName": "EngineTypeAnnotation" - }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", - "value": 1 - }, - "u_Tex": { - "annotations": [ - { - "properties": { - "engineType": 15 - }, - "typeName": "EngineTypeAnnotation" - } - ], - "typeName": "TextureSampler2DBase::EngineTypeAnnotation", - "value": "b72d7ae5-cfd1-4caf-bc70-828584fdf2b8" - } - }, - "typeName": "Table" - } - }, - "typeName": "Table" - } - } - }, - "mesh": "2f1b8ddf-0f43-46fb-8100-4450a5e6a2f0", - "objectID": "0945082f-ba9d-4a9b-9c35-d6ae31462946", - "objectName": "RightQuadMeshNode", - "rotation": { - "x": { - "annotations": [ - { - "properties": { - "max": 360, - "min": -360 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 360, - "min": -360 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 360, - "min": -360 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "scaling": { - "x": { - "annotations": [ - { - "properties": { - "max": 100, - "min": 0.1 + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 }, "typeName": "RangeAnnotationDouble" } ], - "value": 2 + "value": 1 }, "y": { "annotations": [ @@ -313,7 +179,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 2 + "value": 1 }, "z": { "annotations": [ @@ -328,14 +194,6 @@ "value": 1 } }, - "tags": { - "properties": [ - { - "typeName": "String", - "value": "render_main" - } - ] - }, "translation": { "x": { "annotations": [ @@ -347,7 +205,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 4 + "value": 0 }, "y": { "annotations": [ @@ -376,319 +234,124 @@ }, "visibility": true }, - "typeName": "MeshNode" + "typeName": "Node" }, { "properties": { - "materialFilterMode": 1, - "objectID": "1571c0ee-5fc0-4bef-93b8-329b75a64e95", - "objectName": "MainRenderLayer", - "renderableTags": { + "enabled": true, + "frustum": { "order": [ - "render_main", - "duck" + "nearPlane", + "farPlane", + "fieldOfView", + "aspectRatio" ], "properties": { - "duck": { + "aspectRatio": { "annotations": [ { "properties": { - "featureLevel": 3 + "name": "aspectRatio" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 4, + "min": 0.5 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 }, "typeName": "LinkEndAnnotation" } ], - "typeName": "Int::LinkEndAnnotation", - "value": 0 + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 1 }, - "render_main": { + "farPlane": { "annotations": [ { "properties": { - "featureLevel": 3 + "name": "farPlane" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 10000, + "min": 100 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 }, "typeName": "LinkEndAnnotation" } ], - "typeName": "Int::LinkEndAnnotation", - "value": 0 - } - } - }, - "sortOrder": 0 - }, - "typeName": "RenderLayer" - }, - { - "properties": { - "anisotropy": { - "annotations": [ - { - "properties": { - "max": 32000, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 - }, - "format": 13, - "height": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 256 - }, - "magSamplingMethod": 0, - "minSamplingMethod": 0, - "objectID": "1e0241f2-ac34-4afa-82b5-fddeff24e029", - "objectName": "DuckDepthRenderBuffer", - "width": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 256 - }, - "wrapUMode": 0, - "wrapVMode": 0 - }, - "typeName": "RenderBuffer" - }, - { - "properties": { - "buffer0": "b72d7ae5-cfd1-4caf-bc70-828584fdf2b8", - "buffer1": null, - "buffer2": null, - "buffer3": null, - "buffer4": null, - "buffer5": null, - "buffer6": null, - "buffer7": null, - "bufferMS0": null, - "bufferMS1": null, - "bufferMS2": null, - "bufferMS3": null, - "bufferMS4": null, - "bufferMS5": null, - "bufferMS6": null, - "bufferMS7": null, - "objectID": "22ce3cfc-c159-497a-9022-a7df3913ce34", - "objectName": "BlitRenderTarget" - }, - "typeName": "RenderTarget" - }, - { - "properties": { - "bakeMeshes": true, - "materialNames": { - "properties": [ - { - "typeName": "String", - "value": "material" - } - ] - }, - "meshIndex": 0, - "objectID": "2f1b8ddf-0f43-46fb-8100-4450a5e6a2f0", - "objectName": "Quad", - "uri": "meshes/quad.gltf" - }, - "typeName": "Mesh" - }, - { - "properties": { - "bakeMeshes": true, - "materialNames": { - "properties": [ - { - "typeName": "String", - "value": "material" - } - ] - }, - "meshIndex": 0, - "objectID": "2f973ad3-c85a-4254-ba00-20868046f74d", - "objectName": "Duck", - "uri": "meshes/Duck.glb" - }, - "typeName": "Mesh" - }, - { - "properties": { - "enabled": true, - "instanceCount": { - "annotations": [ - { - "properties": { - "max": 20, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 - }, - "materials": { - "order": [ - "material" - ], - "properties": { - "material": { - "order": [ - "material", - "private", - "options", - "uniforms" - ], - "properties": { - "material": { - "typeName": "Material", - "value": "848d6e6e-0f13-4e8d-89a3-32638c1c6d9f" + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 1000 + }, + "fieldOfView": { + "annotations": [ + { + "properties": { + "name": "fieldOfView" + }, + "typeName": "DisplayNameAnnotation" }, - "options": { - "annotations": [ - { - "properties": { - "name": "Options" - }, - "typeName": "DisplayNameAnnotation" - } - ], + { "properties": { - "blendColor": { - "w": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "x": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "blendFactorDestAlpha": 1, - "blendFactorDestColor": 3, - "blendFactorSrcAlpha": 1, - "blendFactorSrcColor": 2, - "blendOperationAlpha": 0, - "blendOperationColor": 0, - "cullmode": 2, - "depthFunction": 4, - "depthwrite": true + "max": 120, + "min": 10 }, - "typeName": "BlendOptions::DisplayNameAnnotation" + "typeName": "RangeAnnotationDouble" }, - "private": { - "annotations": [ - { - "properties": { - "name": "Private Material" - }, - "typeName": "DisplayNameAnnotation" - } - ], - "typeName": "Bool::DisplayNameAnnotation", - "value": true + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 35 + }, + "nearPlane": { + "annotations": [ + { + "properties": { + "name": "nearPlane" + }, + "typeName": "DisplayNameAnnotation" }, - "uniforms": { - "order": [ - "u_FlipUV", - "u_Tex" - ], + { "properties": { - "u_FlipUV": { - "annotations": [ - { - "properties": { - "engineType": 2 - }, - "typeName": "EngineTypeAnnotation" - }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", - "value": 1 - }, - "u_Tex": { - "annotations": [ - { - "properties": { - "engineType": 15 - }, - "typeName": "EngineTypeAnnotation" - } - ], - "typeName": "TextureSampler2DBase::EngineTypeAnnotation", - "value": "5bc6f436-a4db-4680-b443-1bc21573a661" - } + "max": 1, + "min": 0.1 }, - "typeName": "Table" + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" } - }, - "typeName": "Table" + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 0.1 } } }, - "mesh": "2f1b8ddf-0f43-46fb-8100-4450a5e6a2f0", - "objectID": "3128e5b1-f908-45f2-8397-bc946589808e", - "objectName": "LeftQuadMeshNode", + "frustumType": 0, + "objectID": "edfb98e9-d20e-4554-9ca4-66d973252b98", + "objectName": "DuckCamera", "rotation": { "x": { "annotations": [ @@ -712,7 +375,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 0 + "value": 90 }, "z": { "annotations": [ @@ -738,7 +401,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 2 + "value": 1 }, "y": { "annotations": [ @@ -750,7 +413,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 2 + "value": 1 }, "z": { "annotations": [ @@ -765,14 +428,6 @@ "value": 1 } }, - "tags": { - "properties": [ - { - "typeName": "String", - "value": "render_main" - } - ] - }, "translation": { "x": { "annotations": [ @@ -784,7 +439,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": -4 + "value": 10 }, "y": { "annotations": [ @@ -811,108 +466,357 @@ "value": 0 } }, + "viewport": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + } + }, "visibility": true }, - "typeName": "MeshNode" + "typeName": "PerspectiveCamera" }, { "properties": { - "destinationX": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 0 - }, - "destinationY": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 128 - }, "enabled": true, - "height": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 128 - }, - "objectID": "3d58b368-adeb-49c2-8b2e-8ecfb4d4ae02", - "objectName": "BlitPass (2)", - "renderOrder": 1, - "sourceRenderBuffer": "5bc6f436-a4db-4680-b443-1bc21573a661", - "sourceRenderBufferMS": null, - "sourceX": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } + "frustum": { + "order": [ + "nearPlane", + "farPlane", + "fieldOfView", + "aspectRatio" ], - "value": 70 - }, - "sourceY": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 0 - }, - "typeName": "RangeAnnotationInt" + "properties": { + "aspectRatio": { + "annotations": [ + { + "properties": { + "name": "aspectRatio" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 4, + "min": 0.5 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 2 + }, + "farPlane": { + "annotations": [ + { + "properties": { + "name": "farPlane" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 10000, + "min": 100 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 1000 + }, + "fieldOfView": { + "annotations": [ + { + "properties": { + "name": "fieldOfView" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 120, + "min": 10 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 35 + }, + "nearPlane": { + "annotations": [ + { + "properties": { + "name": "nearPlane" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 1, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 0.1 } - ], - "value": 116 + } }, - "targetRenderBuffer": "b72d7ae5-cfd1-4caf-bc70-828584fdf2b8", - "targetRenderBufferMS": null, - "width": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 128 - } - }, - "typeName": "BlitPass" - }, - { - "properties": { - "destinationX": { - "annotations": [ - { - "properties": { + "frustumType": 0, + "objectID": "f7cf2c3a-be22-4379-8d50-3669c3304da9", + "objectName": "PerspectiveCamera", + "rotation": { + "x": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 360, + "min": -360 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 10 + } + }, + "viewport": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + }, + "visibility": true + }, + "typeName": "PerspectiveCamera" + }, + { + "properties": { + "destinationX": { + "annotations": [ + { + "properties": { "max": 7680, "min": 0 }, "typeName": "RangeAnnotationInt" } ], - "value": 0 + "value": 128 }, "destinationY": { "annotations": [ @@ -939,9 +843,9 @@ ], "value": 128 }, - "objectID": "498cde0d-6bdf-45db-b922-61edd7e96f3e", - "objectName": "BlitPass", - "renderOrder": 1, + "objectID": "0425a489-8986-4ba8-bbeb-6a77cc4850f6", + "objectName": "BlitPass (1)", + "renderOrder": 2, "sourceRenderBuffer": "5bc6f436-a4db-4680-b443-1bc21573a661", "sourceRenderBufferMS": null, "sourceX": { @@ -987,11 +891,12 @@ }, { "properties": { - "anisotropy": { + "enabled": true, + "instanceCount": { "annotations": [ { "properties": { - "max": 32000, + "max": 20, "min": 1 }, "typeName": "RangeAnnotationInt" @@ -999,413 +904,243 @@ ], "value": 1 }, - "format": 4, - "height": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 256 - }, - "magSamplingMethod": 0, - "minSamplingMethod": 0, - "objectID": "5bc6f436-a4db-4680-b443-1bc21573a661", - "objectName": "DuckRenderBuffer", - "width": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } + "materials": { + "order": [ + "material" ], - "value": 256 - }, - "wrapUMode": 0, - "wrapVMode": 0 - }, - "typeName": "RenderBuffer" - }, - { - "properties": { - "anisotropy": { - "annotations": [ - { + "properties": { + "material": { + "order": [ + "material", + "private", + "options", + "uniforms" + ], "properties": { - "max": 32000, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 - }, - "flipTexture": false, - "generateMipmaps": false, - "level2uri": "", - "level3uri": "", - "level4uri": "", - "magSamplingMethod": 0, - "minSamplingMethod": 0, - "mipmapLevel": { - "annotations": [ - { - "properties": { - "max": 4, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 - }, - "objectID": "645d7b03-b503-4e58-ab19-aface09fba97", - "objectName": "DuckTexture", - "textureFormat": 5, - "uri": "images/DuckCM.png", - "wrapUMode": 0, - "wrapVMode": 0 - }, - "typeName": "Texture" - }, - { - "properties": { - "buffer0": "5bc6f436-a4db-4680-b443-1bc21573a661", - "buffer1": "1e0241f2-ac34-4afa-82b5-fddeff24e029", - "buffer2": null, - "buffer3": null, - "buffer4": null, - "buffer5": null, - "buffer6": null, - "buffer7": null, - "bufferMS0": null, - "bufferMS1": null, - "bufferMS2": null, - "bufferMS3": null, - "bufferMS4": null, - "bufferMS5": null, - "bufferMS6": null, - "bufferMS7": null, - "objectID": "80d35c68-f4bf-41b2-b759-085572918791", - "objectName": "DuckRenderTarget" - }, - "typeName": "RenderTarget" - }, - { - "properties": { - "objectID": "848d6e6e-0f13-4e8d-89a3-32638c1c6d9f", - "objectName": "TextureMaterial", - "options": { - "blendColor": { - "w": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "x": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "blendFactorDestAlpha": 1, - "blendFactorDestColor": 3, - "blendFactorSrcAlpha": 1, - "blendFactorSrcColor": 2, - "blendOperationAlpha": 0, - "blendOperationColor": 0, - "cullmode": 2, - "depthFunction": 4, - "depthwrite": true - }, - "uniforms": { - "order": [ - "u_FlipUV", - "u_Tex" - ], - "properties": { - "u_FlipUV": { - "annotations": [ - { - "properties": { - "engineType": 2 - }, - "typeName": "EngineTypeAnnotation" + "material": { + "typeName": "Material", + "value": "848d6e6e-0f13-4e8d-89a3-32638c1c6d9f" }, - { + "options": { + "annotations": [ + { + "properties": { + "name": "Options" + }, + "typeName": "DisplayNameAnnotation" + } + ], "properties": { - "featureLevel": 1 + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", - "value": 0 - }, - "u_Tex": { - "annotations": [ - { + "typeName": "BlendOptions::DisplayNameAnnotation" + }, + "private": { + "annotations": [ + { + "properties": { + "name": "Private Material" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "typeName": "Bool::DisplayNameAnnotation", + "value": true + }, + "uniforms": { + "order": [ + "u_FlipUV", + "u_Tex" + ], "properties": { - "engineType": 15 + "u_FlipUV": { + "annotations": [ + { + "properties": { + "engineType": 1 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Bool::EngineTypeAnnotation::LinkEndAnnotation", + "value": false + }, + "u_Tex": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation", + "value": "b72d7ae5-cfd1-4caf-bc70-828584fdf2b8" + } }, - "typeName": "EngineTypeAnnotation" + "typeName": "Table" } - ], - "typeName": "TextureSampler2DBase::EngineTypeAnnotation", - "value": null - } - } - }, - "uriDefines": "", - "uriFragment": "shaders/simple_texture.frag", - "uriGeometry": "", - "uriVertex": "shaders/simple_texture.vert" - }, - "typeName": "Material" - }, - { - "properties": { - "camera": "f7cf2c3a-be22-4379-8d50-3669c3304da9", - "clearColor": { - "w": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "x": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "enableClearColor": true, - "enableClearDepth": true, - "enableClearStencil": true, - "enabled": true, - "layer0": "1571c0ee-5fc0-4bef-93b8-329b75a64e95", - "layer1": null, - "layer2": null, - "layer3": null, - "layer4": null, - "layer5": null, - "layer6": null, - "layer7": null, - "objectID": "8703286b-f230-4c15-b110-eb0a9e209ae3", - "objectName": "MainRenderPass", - "renderOnce": false, - "renderOrder": 3, - "target": null - }, - "typeName": "RenderPass" - }, - { - "properties": { - "backgroundColor": { - "w": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 1 - }, - "x": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "defaultResourceFolders": { - "imageSubdirectory": "images", - "interfaceSubdirectory": "interfaces", - "meshSubdirectory": "meshes", - "scriptSubdirectory": "scripts", - "shaderSubdirectory": "shaders" - }, - "featureLevel": 1, - "objectID": "a2840514-1f24-4e84-b843-ae26eb95f0b4", - "objectName": "blitpass", - "saveAsZip": false, - "sceneId": { - "annotations": [ - { - "properties": { - "max": 1024, - "min": 1 }, - "typeName": "RangeAnnotationInt" + "typeName": "Table" } - ], - "value": 123 - }, - "viewport": { - "i1": { - "annotations": [ - { - "properties": { - "max": 4096, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1440 - }, - "i2": { - "annotations": [ - { - "properties": { - "max": 4096, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 720 } - } - }, - "typeName": "ProjectSettings" - }, - { - "properties": { - "children": { - "properties": [ - { - "typeName": "Ref", - "value": "ce64a3b9-ef82-49af-bbd1-25dfc2f22a90" - }, - { - "typeName": "Ref", - "value": "3128e5b1-f908-45f2-8397-bc946589808e" - }, - { - "typeName": "Ref", - "value": "0945082f-ba9d-4a9b-9c35-d6ae31462946" - } - ] }, - "enabled": true, - "objectID": "a42eae27-ec9d-4864-9e59-c895c962282d", - "objectName": "Node", + "mesh": "2f1b8ddf-0f43-46fb-8100-4450a5e6a2f0", + "objectID": "0945082f-ba9d-4a9b-9c35-d6ae31462946", + "objectName": "RightQuadMeshNode", "rotation": { "x": { "annotations": [ @@ -1455,7 +1190,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 1 + "value": 2 }, "y": { "annotations": [ @@ -1467,7 +1202,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 1 + "value": 2 }, "z": { "annotations": [ @@ -1482,6 +1217,14 @@ "value": 1 } }, + "tags": { + "properties": [ + { + "typeName": "String", + "value": "render_main" + } + ] + }, "translation": { "x": { "annotations": [ @@ -1493,7 +1236,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 0 + "value": 4 }, "y": { "annotations": [ @@ -1522,7 +1265,48 @@ }, "visibility": true }, - "typeName": "Node" + "typeName": "MeshNode" + }, + { + "properties": { + "materialFilterMode": 1, + "objectID": "1571c0ee-5fc0-4bef-93b8-329b75a64e95", + "objectName": "MainRenderLayer", + "renderableTags": { + "order": [ + "render_main", + "duck" + ], + "properties": { + "duck": { + "annotations": [ + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::LinkEndAnnotation", + "value": 0 + }, + "render_main": { + "annotations": [ + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::LinkEndAnnotation", + "value": 0 + } + } + }, + "sortOrder": 0 + }, + "typeName": "RenderLayer" }, { "properties": { @@ -1538,7 +1322,7 @@ ], "value": 1 }, - "format": 4, + "format": 13, "height": { "annotations": [ { @@ -1553,8 +1337,8 @@ }, "magSamplingMethod": 0, "minSamplingMethod": 0, - "objectID": "b72d7ae5-cfd1-4caf-bc70-828584fdf2b8", - "objectName": "BlitRenderBuffer", + "objectID": "1e0241f2-ac34-4afa-82b5-fddeff24e029", + "objectName": "DuckDepthRenderBuffer", "width": { "annotations": [ { @@ -1572,6 +1356,117 @@ }, "typeName": "RenderBuffer" }, + { + "properties": { + "buffers": [ + "b72d7ae5-cfd1-4caf-bc70-828584fdf2b8", + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "22ce3cfc-c159-497a-9022-a7df3913ce34", + "objectName": "BlitRenderTarget" + }, + "typeName": "RenderTarget" + }, + { + "properties": { + "bakeMeshes": true, + "materialNames": { + "properties": [ + { + "typeName": "String", + "value": "material" + } + ] + }, + "meshIndex": 0, + "metaData": { + "order": [ + "meshInfo" + ], + "properties": { + "meshInfo": { + "annotations": [ + { + "typeName": "ReadOnlyAnnotation" + } + ], + "order": [ + "triangles", + "vertices" + ], + "properties": { + "triangles": { + "typeName": "Int", + "value": 2 + }, + "vertices": { + "typeName": "Int", + "value": 4 + } + }, + "typeName": "Table::ReadOnlyAnnotation" + } + } + }, + "objectID": "2f1b8ddf-0f43-46fb-8100-4450a5e6a2f0", + "objectName": "Quad", + "uri": "meshes/quad.gltf" + }, + "typeName": "Mesh" + }, + { + "properties": { + "bakeMeshes": true, + "materialNames": { + "properties": [ + { + "typeName": "String", + "value": "material" + } + ] + }, + "meshIndex": 0, + "metaData": { + "order": [ + "meshInfo" + ], + "properties": { + "meshInfo": { + "annotations": [ + { + "typeName": "ReadOnlyAnnotation" + } + ], + "order": [ + "triangles", + "vertices" + ], + "properties": { + "triangles": { + "typeName": "Int", + "value": 4212 + }, + "vertices": { + "typeName": "Int", + "value": 2399 + } + }, + "typeName": "Table::ReadOnlyAnnotation" + } + } + }, + "objectID": "2f973ad3-c85a-4254-ba00-20868046f74d", + "objectName": "Duck", + "uri": "meshes/Duck.glb" + }, + "typeName": "Mesh" + }, { "properties": { "enabled": true, @@ -1670,9 +1565,98 @@ "blendFactorSrcColor": 2, "blendOperationAlpha": 0, "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, "cullmode": 2, "depthFunction": 4, - "depthwrite": true + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } }, "typeName": "BlendOptions::DisplayNameAnnotation" }, @@ -1698,7 +1682,7 @@ "annotations": [ { "properties": { - "engineType": 2 + "engineType": 1 }, "typeName": "EngineTypeAnnotation" }, @@ -1709,8 +1693,8 @@ "typeName": "LinkEndAnnotation" } ], - "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", - "value": 0 + "typeName": "Bool::EngineTypeAnnotation::LinkEndAnnotation", + "value": false }, "u_Tex": { "annotations": [ @@ -1722,7 +1706,7 @@ } ], "typeName": "TextureSampler2DBase::EngineTypeAnnotation", - "value": "645d7b03-b503-4e58-ab19-aface09fba97" + "value": "5bc6f436-a4db-4680-b443-1bc21573a661" } }, "typeName": "Table" @@ -1732,9 +1716,9 @@ } } }, - "mesh": "2f973ad3-c85a-4254-ba00-20868046f74d", - "objectID": "ce64a3b9-ef82-49af-bbd1-25dfc2f22a90", - "objectName": "DuckMeshNode", + "mesh": "2f1b8ddf-0f43-46fb-8100-4450a5e6a2f0", + "objectID": "3128e5b1-f908-45f2-8397-bc946589808e", + "objectName": "LeftQuadMeshNode", "rotation": { "x": { "annotations": [ @@ -1808,14 +1792,14 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 2 + "value": 1 } }, "tags": { "properties": [ { "typeName": "String", - "value": "duck" + "value": "render_main" } ] }, @@ -1830,7 +1814,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 0 + "value": -4 }, "y": { "annotations": [ @@ -1842,7 +1826,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": -2 + "value": 0 }, "z": { "annotations": [ @@ -1863,31 +1847,88 @@ }, { "properties": { - "materialFilterMode": 1, - "objectID": "d120ade7-8b3f-4607-b2db-5115e3218b25", - "objectName": "DuckRenderLayer", - "renderableTags": { - "order": [ - "duck" + "destinationX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } ], - "properties": { - "duck": { - "annotations": [ - { - "properties": { - "featureLevel": 3 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Int::LinkEndAnnotation", - "value": 0 + "value": 0 + }, + "destinationY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 128 + }, + "enabled": true, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 128 + }, + "objectID": "3d58b368-adeb-49c2-8b2e-8ecfb4d4ae02", + "objectName": "BlitPass (2)", + "renderOrder": 3, + "sourceRenderBuffer": "5bc6f436-a4db-4680-b443-1bc21573a661", + "sourceRenderBufferMS": null, + "sourceX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 70 + }, + "sourceY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" } - } + ], + "value": 116 }, - "sortOrder": 0 + "targetRenderBuffer": "b72d7ae5-cfd1-4caf-bc70-828584fdf2b8", + "targetRenderBufferMS": null, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 128 + } }, - "typeName": "RenderLayer" + "typeName": "BlitPass" }, { "properties": { @@ -1901,7 +1942,7 @@ "typeName": "RangeAnnotationInt" } ], - "value": 128 + "value": 0 }, "destinationY": { "annotations": [ @@ -1913,7 +1954,7 @@ "typeName": "RangeAnnotationInt" } ], - "value": 128 + "value": 0 }, "enabled": true, "height": { @@ -1928,8 +1969,8 @@ ], "value": 128 }, - "objectID": "e27948cd-f3e1-4805-b86d-49df2d34f541", - "objectName": "BlitPass (3)", + "objectID": "498cde0d-6bdf-45db-b922-61edd7e96f3e", + "objectName": "BlitPass", "renderOrder": 1, "sourceRenderBuffer": "5bc6f436-a4db-4680-b443-1bc21573a661", "sourceRenderBufferMS": null, @@ -1976,152 +2017,278 @@ }, { "properties": { - "camera": "edfb98e9-d20e-4554-9ca4-66d973252b98", - "clearColor": { - "w": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 1 - }, - "x": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0.2 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0.5 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0.2 - } + "anisotropy": { + "annotations": [ + { + "properties": { + "max": 32000, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 }, - "enableClearColor": true, - "enableClearDepth": true, - "enableClearStencil": true, - "enabled": true, - "layer0": "d120ade7-8b3f-4607-b2db-5115e3218b25", - "layer1": null, - "layer2": null, - "layer3": null, - "layer4": null, - "layer5": null, - "layer6": null, - "layer7": null, - "objectID": "e3c42eff-716c-4148-a38c-7e6fc37b78c0", - "objectName": "DuckRenderPass", - "renderOnce": false, - "renderOrder": 0, - "target": "80d35c68-f4bf-41b2-b759-085572918791" + "format": 4, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "magSamplingMethod": 0, + "minSamplingMethod": 0, + "objectID": "5bc6f436-a4db-4680-b443-1bc21573a661", + "objectName": "DuckRenderBuffer", + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "wrapUMode": 0, + "wrapVMode": 0 }, - "typeName": "RenderPass" + "typeName": "RenderBuffer" }, { "properties": { - "enabled": true, - "frustum": { - "order": [ - "nearPlane", - "farPlane", - "fieldOfView", - "aspectRatio" + "anisotropy": { + "annotations": [ + { + "properties": { + "max": 32000, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } ], - "properties": { - "aspectRatio": { + "value": 1 + }, + "flipTexture": false, + "generateMipmaps": false, + "level2uri": "", + "level3uri": "", + "level4uri": "", + "magSamplingMethod": 0, + "minSamplingMethod": 0, + "mipmapLevel": { + "annotations": [ + { + "properties": { + "max": 4, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "objectID": "645d7b03-b503-4e58-ab19-aface09fba97", + "objectName": "DuckTexture", + "textureFormat": 5, + "uri": "images/DuckCM.png", + "wrapUMode": 0, + "wrapVMode": 0 + }, + "typeName": "Texture" + }, + { + "properties": { + "buffers": [ + "5bc6f436-a4db-4680-b443-1bc21573a661", + "1e0241f2-ac34-4afa-82b5-fddeff24e029", + null, + null, + null, + null, + null, + null + ], + "objectID": "80d35c68-f4bf-41b2-b759-085572918791", + "objectName": "DuckRenderTarget" + }, + "typeName": "RenderTarget" + }, + { + "properties": { + "objectID": "848d6e6e-0f13-4e8d-89a3-32638c1c6d9f", + "objectName": "TextureMaterial", + "options": { + "blendColor": { + "w": { "annotations": [ { "properties": { - "name": "aspectRatio" + "max": 1, + "min": 0 }, - "typeName": "DisplayNameAnnotation" - }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ { "properties": { - "max": 4, - "min": 0.5 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" - }, + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ { "properties": { - "featureLevel": 1 + "max": 255, + "min": 0 }, - "typeName": "LinkEndAnnotation" + "typeName": "RangeAnnotationInt" } ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 1 + "value": 255 }, - "farPlane": { + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { "annotations": [ { "properties": { - "name": "farPlane" - }, - "typeName": "DisplayNameAnnotation" - }, - { - "properties": { - "max": 10000, - "min": 100 - }, - "typeName": "RangeAnnotationDouble" - }, - { - "properties": { - "featureLevel": 1 + "max": 255, + "min": 0 }, - "typeName": "LinkEndAnnotation" + "typeName": "RangeAnnotationInt" } ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 1000 - }, - "fieldOfView": { + "value": 1 + } + } + }, + "uniforms": { + "order": [ + "u_FlipUV", + "u_Tex" + ], + "properties": { + "u_FlipUV": { "annotations": [ { "properties": { - "name": "fieldOfView" - }, - "typeName": "DisplayNameAnnotation" - }, - { - "properties": { - "max": 120, - "min": 10 + "engineType": 1 }, - "typeName": "RangeAnnotationDouble" + "typeName": "EngineTypeAnnotation" }, { "properties": { @@ -2130,134 +2297,64 @@ "typeName": "LinkEndAnnotation" } ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 35 + "typeName": "Bool::EngineTypeAnnotation::LinkEndAnnotation", + "value": false }, - "nearPlane": { + "u_Tex": { "annotations": [ { "properties": { - "name": "nearPlane" - }, - "typeName": "DisplayNameAnnotation" - }, - { - "properties": { - "max": 1, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" - }, - { - "properties": { - "featureLevel": 1 + "engineType": 15 }, - "typeName": "LinkEndAnnotation" + "typeName": "EngineTypeAnnotation" } ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 0.1 + "typeName": "TextureSampler2DBase::EngineTypeAnnotation", + "value": "645d7b03-b503-4e58-ab19-aface09fba97" } } }, - "frustumType": 0, - "objectID": "edfb98e9-d20e-4554-9ca4-66d973252b98", - "objectName": "DuckCamera", - "rotation": { - "x": { - "annotations": [ - { - "properties": { - "max": 360, - "min": -360 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 360, - "min": -360 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 90 - }, - "z": { + "uriDefines": "", + "uriFragment": "shaders/simple_texture.frag", + "uriGeometry": "", + "uriVertex": "shaders/simple_texture.vert" + }, + "typeName": "Material" + }, + { + "properties": { + "camera": "f7cf2c3a-be22-4379-8d50-3669c3304da9", + "clearColor": { + "w": { "annotations": [ { "properties": { - "max": 360, - "min": -360 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } ], "value": 0 - } - }, - "scaling": { - "x": { - "annotations": [ - { - "properties": { - "max": 100, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 1 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 100, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 1 }, - "z": { - "annotations": [ - { - "properties": { - "max": 100, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 1 - } - }, - "translation": { "x": { "annotations": [ { "properties": { - "max": 100, - "min": -100 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } ], - "value": 10 + "value": 0 }, "y": { "annotations": [ { "properties": { - "max": 100, - "min": -100 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } @@ -2268,8 +2365,8 @@ "annotations": [ { "properties": { - "max": 100, - "min": -100 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } @@ -2277,176 +2374,328 @@ "value": 0 } }, - "viewport": { - "height": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 256 - }, - "offsetX": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": -7680 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 0 - }, - "offsetY": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": -7680 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 0 - }, - "width": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 256 - } + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layers": [ + "1571c0ee-5fc0-4bef-93b8-329b75a64e95", + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "8703286b-f230-4c15-b110-eb0a9e209ae3", + "objectName": "MainRenderPass", + "renderOnce": false, + "renderOrder": 5, + "target": null + }, + "typeName": "RenderPass" + }, + { + "properties": { + "anisotropy": { + "annotations": [ + { + "properties": { + "max": 32000, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "format": 4, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 }, - "visibility": true + "magSamplingMethod": 0, + "minSamplingMethod": 0, + "objectID": "b72d7ae5-cfd1-4caf-bc70-828584fdf2b8", + "objectName": "BlitRenderBuffer", + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 256 + }, + "wrapUMode": 0, + "wrapVMode": 0 }, - "typeName": "PerspectiveCamera" + "typeName": "RenderBuffer" }, { "properties": { "enabled": true, - "frustum": { + "instanceCount": { + "annotations": [ + { + "properties": { + "max": 20, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "materials": { "order": [ - "nearPlane", - "farPlane", - "fieldOfView", - "aspectRatio" + "material" ], "properties": { - "aspectRatio": { - "annotations": [ - { - "properties": { - "name": "aspectRatio" - }, - "typeName": "DisplayNameAnnotation" - }, - { - "properties": { - "max": 4, - "min": 0.5 - }, - "typeName": "RangeAnnotationDouble" - }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 2 - }, - "farPlane": { - "annotations": [ - { - "properties": { - "name": "farPlane" - }, - "typeName": "DisplayNameAnnotation" - }, - { - "properties": { - "max": 10000, - "min": 100 - }, - "typeName": "RangeAnnotationDouble" - }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } + "material": { + "order": [ + "material", + "private", + "options", + "uniforms" ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 1000 - }, - "fieldOfView": { - "annotations": [ - { - "properties": { - "name": "fieldOfView" - }, - "typeName": "DisplayNameAnnotation" - }, - { - "properties": { - "max": 120, - "min": 10 - }, - "typeName": "RangeAnnotationDouble" + "properties": { + "material": { + "typeName": "Material", + "value": "848d6e6e-0f13-4e8d-89a3-32638c1c6d9f" }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 35 - }, - "nearPlane": { - "annotations": [ - { + "options": { + "annotations": [ + { + "properties": { + "name": "Options" + }, + "typeName": "DisplayNameAnnotation" + } + ], "properties": { - "name": "nearPlane" + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } }, - "typeName": "DisplayNameAnnotation" + "typeName": "BlendOptions::DisplayNameAnnotation" }, - { - "properties": { - "max": 1, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" + "private": { + "annotations": [ + { + "properties": { + "name": "Private Material" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "typeName": "Bool::DisplayNameAnnotation", + "value": true }, - { + "uniforms": { + "order": [ + "u_FlipUV", + "u_Tex" + ], "properties": { - "featureLevel": 1 + "u_FlipUV": { + "annotations": [ + { + "properties": { + "engineType": 1 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Bool::EngineTypeAnnotation::LinkEndAnnotation", + "value": false + }, + "u_Tex": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation", + "value": "645d7b03-b503-4e58-ab19-aface09fba97" + } }, - "typeName": "LinkEndAnnotation" + "typeName": "Table" } - ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 0.1 + }, + "typeName": "Table" } } }, - "frustumType": 0, - "objectID": "f7cf2c3a-be22-4379-8d50-3669c3304da9", - "objectName": "PerspectiveCamera", + "mesh": "2f973ad3-c85a-4254-ba00-20868046f74d", + "objectID": "ce64a3b9-ef82-49af-bbd1-25dfc2f22a90", + "objectName": "DuckMeshNode", "rotation": { "x": { "annotations": [ @@ -2496,7 +2745,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 1 + "value": 2 }, "y": { "annotations": [ @@ -2508,7 +2757,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 1 + "value": 2 }, "z": { "annotations": [ @@ -2520,9 +2769,17 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 1 + "value": 2 } }, + "tags": { + "properties": [ + { + "typeName": "String", + "value": "duck" + } + ] + }, "translation": { "x": { "annotations": [ @@ -2546,7 +2803,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 0 + "value": -2 }, "z": { "annotations": [ @@ -2558,80 +2815,213 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 10 + "value": 0 } }, - "viewport": { - "height": { + "visibility": true + }, + "typeName": "MeshNode" + }, + { + "properties": { + "materialFilterMode": 1, + "objectID": "d120ade7-8b3f-4607-b2db-5115e3218b25", + "objectName": "DuckRenderLayer", + "renderableTags": { + "order": [ + "duck" + ], + "properties": { + "duck": { + "annotations": [ + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::LinkEndAnnotation", + "value": 0 + } + } + }, + "sortOrder": 0 + }, + "typeName": "RenderLayer" + }, + { + "properties": { + "destinationX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 128 + }, + "destinationY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 128 + }, + "enabled": true, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 128 + }, + "objectID": "e27948cd-f3e1-4805-b86d-49df2d34f541", + "objectName": "BlitPass (3)", + "renderOrder": 4, + "sourceRenderBuffer": "5bc6f436-a4db-4680-b443-1bc21573a661", + "sourceRenderBufferMS": null, + "sourceX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 70 + }, + "sourceY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 116 + }, + "targetRenderBuffer": "b72d7ae5-cfd1-4caf-bc70-828584fdf2b8", + "targetRenderBufferMS": null, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 128 + } + }, + "typeName": "BlitPass" + }, + { + "properties": { + "camera": "edfb98e9-d20e-4554-9ca4-66d973252b98", + "clearColor": { + "w": { "annotations": [ { "properties": { - "max": 7680, - "min": 1 + "max": 1, + "min": 0 }, - "typeName": "RangeAnnotationInt" + "typeName": "RangeAnnotationDouble" } ], - "value": 720 + "value": 1 }, - "offsetX": { + "x": { "annotations": [ { "properties": { - "max": 7680, - "min": -7680 + "max": 1, + "min": 0 }, - "typeName": "RangeAnnotationInt" + "typeName": "RangeAnnotationDouble" } ], - "value": 0 + "value": 0.2 }, - "offsetY": { + "y": { "annotations": [ { "properties": { - "max": 7680, - "min": -7680 + "max": 1, + "min": 0 }, - "typeName": "RangeAnnotationInt" + "typeName": "RangeAnnotationDouble" } ], - "value": 0 + "value": 0.5 }, - "width": { + "z": { "annotations": [ { "properties": { - "max": 7680, - "min": 1 + "max": 1, + "min": 0 }, - "typeName": "RangeAnnotationInt" + "typeName": "RangeAnnotationDouble" } ], - "value": 1440 + "value": 0.2 } }, - "visibility": true + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layers": [ + "d120ade7-8b3f-4607-b2db-5115e3218b25", + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "e3c42eff-716c-4148-a38c-7e6fc37b78c0", + "objectName": "DuckRenderPass", + "renderOnce": false, + "renderOrder": 0, + "target": "80d35c68-f4bf-41b2-b759-085572918791" }, - "typeName": "PerspectiveCamera" + "typeName": "RenderPass" } ], "links": [ ], - "logicEngineVersion": [ - 1, - 3, - 0 - ], "racoVersion": [ - 1, - 5, + 2, + 0, 0 ], "ramsesVersion": [ - 27, + 28, 0, - 126 + 0 ], "structPropMap": { "AnchorPointOutputs": { @@ -2646,9 +3036,12 @@ "blendFactorSrcColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", "blendOperationAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", "blendOperationColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "colorWriteMask": "ColorWriteMask::DisplayNameAnnotation", "cullmode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "depthFunction": "Int::DisplayNameAnnotation::EnumerationAnnotation", - "depthwrite": "Bool::DisplayNameAnnotation" + "depthwrite": "Bool::DisplayNameAnnotation", + "scissorOptions": "ScissorOptions::DisplayNameAnnotation", + "stencilOptions": "StencilOptions::DisplayNameAnnotation" }, "CameraViewport": { "height": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", @@ -2656,6 +3049,12 @@ "offsetY": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", "width": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation" }, + "ColorWriteMask": { + "alpha": "Bool::DisplayNameAnnotation", + "blue": "Bool::DisplayNameAnnotation", + "green": "Bool::DisplayNameAnnotation", + "red": "Bool::DisplayNameAnnotation" + }, "DefaultResourceDirectories": { "imageSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", "interfaceSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", @@ -2678,6 +3077,18 @@ "rightPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", "topPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation" }, + "ScissorOptions": { + "scissorEnable": "Bool::DisplayNameAnnotation", + "scissorRegion": "CameraViewport::DisplayNameAnnotation" + }, + "StencilOptions": { + "stencilFunc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilMask": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "stencilOpDepthFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpDepthSucc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpStencilFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilRef": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, "TimerInput": { "ticker_us": "Int64::DisplayNameAnnotation::LinkEndAnnotation" }, @@ -2718,34 +3129,41 @@ "userTypePropMap": { "AnchorPoint": { "camera": "BaseCamera::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "node": "Node::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "outputs": "AnchorPointOutputs::DisplayNameAnnotation" + "outputs": "AnchorPointOutputs::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Animation": { - "animationChannels": "Table::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "animationChannels": "Array[AnimationChannel]::DisplayNameAnnotation::ResizableArray", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "outputs": "Table::DisplayNameAnnotation", - "progress": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation" + "progress": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "AnimationChannel": { "animationIndex": "Int::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "samplerIndex": "Int::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "BlitPass": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "destinationX": "Int::RangeAnnotationInt::DisplayNameAnnotation", "destinationY": "Int::RangeAnnotationInt::DisplayNameAnnotation", "enabled": "Bool::DisplayNameAnnotation", "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "renderOrder": "Int::DisplayNameAnnotation", @@ -2755,11 +3173,12 @@ "sourceY": "Int::RangeAnnotationInt::DisplayNameAnnotation", "targetRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", "targetRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" }, "CubeMap": { "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "generateMipmaps": "Bool::DisplayNameAnnotation", "level2uriBack": "String::URIAnnotation::DisplayNameAnnotation", "level2uriBottom": "String::URIAnnotation::DisplayNameAnnotation", @@ -2780,6 +3199,7 @@ "level4uriRight": "String::URIAnnotation::DisplayNameAnnotation", "level4uriTop": "String::URIAnnotation::DisplayNameAnnotation", "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", "objectID": "String::HiddenProperty", @@ -2791,35 +3211,45 @@ "uriLeft": "String::URIAnnotation::DisplayNameAnnotation", "uriRight": "String::URIAnnotation::DisplayNameAnnotation", "uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" }, "LuaInterface": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "inputs": "Table::DisplayNameAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "LuaScript": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "inputs": "Table::DisplayNameAnnotation::LinkEndAnnotation", "luaModules": "Table::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "outputs": "Table::DisplayNameAnnotation", "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "LuaScriptModule": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Material": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "options": "BlendOptions::DisplayNameAnnotation", @@ -2828,77 +3258,91 @@ "uriDefines": "String::URIAnnotation::DisplayNameAnnotation", "uriFragment": "String::URIAnnotation::DisplayNameAnnotation", "uriGeometry": "String::URIAnnotation::DisplayNameAnnotation", - "uriVertex": "String::URIAnnotation::DisplayNameAnnotation" + "uriVertex": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Mesh": { "bakeMeshes": "Bool::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "materialNames": "Table::ArraySemanticAnnotation::HiddenProperty", "meshIndex": "Int::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "MeshNode": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", - "instanceCount": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "instanceCount": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", "materials": "Table::DisplayNameAnnotation", "mesh": "Mesh::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "Node": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "OrthographicCamera": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", "frustum": "OrthographicFrustum::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "PerspectiveCamera": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", "frustum": "Table::DisplayNameAnnotation::LinkEndAnnotation", - "frustumType": "Int::DisplayNameAnnotation::EnumerationAnnotation::FeatureLevel", + "frustumType": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "Prefab": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", - "objectName": "String::DisplayNameAnnotation" + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "PrefabInstance": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", @@ -2906,11 +3350,12 @@ "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "template": "Prefab::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "ProjectSettings": { "backgroundColor": "Vec4f::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "defaultResourceFolders": "DefaultResourceDirectories::DisplayNameAnnotation", "featureLevel": "Int::DisplayNameAnnotation::ReadOnlyAnnotation", "objectID": "String::HiddenProperty", @@ -2921,103 +3366,123 @@ }, "RenderBuffer": { "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "width": "Int::RangeAnnotationInt::DisplayNameAnnotation", "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" }, "RenderBufferMS": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "sampleCount": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" }, "RenderLayer": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "materialFilterMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "materialFilterTags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "renderableTags": "Table::RenderableTagContainerAnnotation::DisplayNameAnnotation", "sortOrder": "Int::DisplayNameAnnotation::EnumerationAnnotation", - "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation" + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "RenderPass": { "camera": "BaseCamera::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "clearColor": "Vec4f::DisplayNameAnnotation::LinkEndAnnotation", "enableClearColor": "Bool::DisplayNameAnnotation", "enableClearDepth": "Bool::DisplayNameAnnotation", "enableClearStencil": "Bool::DisplayNameAnnotation", "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", - "layer0": "RenderLayer::DisplayNameAnnotation", - "layer1": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer2": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer3": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer4": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer5": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer6": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer7": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layers": "Array[RenderLayer]::DisplayNameAnnotation::EmptyReferenceAllowable::ResizableArray", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "renderOnce": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "renderOnce": "Bool::DisplayNameAnnotation::LinkEndAnnotation", "renderOrder": "Int::DisplayNameAnnotation::LinkEndAnnotation", - "target": "RenderTarget::DisplayNameAnnotation::EmptyReferenceAllowable" + "target": "RenderTargetBase::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "RenderTarget": { - "buffer0": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer1": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer2": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer3": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer4": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer5": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer6": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer7": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS0": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS1": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS2": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS3": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS4": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS5": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS6": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS7": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "buffers": "Array[RenderBuffer]::DisplayNameAnnotation::EmptyReferenceAllowable::ResizableArray", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderTargetMS": { + "buffers": "Array[RenderBufferMS]::DisplayNameAnnotation::EmptyReferenceAllowable::ResizableArray", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Skin": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "joints": "Array[Node]::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", - "objectName": "String::DisplayNameAnnotation" + "objectName": "String::DisplayNameAnnotation", + "skinIndex": "Int::DisplayNameAnnotation", + "targets": "Array[MeshNode]::DisplayNameAnnotation::ResizableArray", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Texture": { "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "flipTexture": "Bool::DisplayNameAnnotation", "generateMipmaps": "Bool::DisplayNameAnnotation", "level2uri": "String::URIAnnotation::DisplayNameAnnotation", "level3uri": "String::URIAnnotation::DisplayNameAnnotation", "level4uri": "String::URIAnnotation::DisplayNameAnnotation", "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" }, + "TextureExternal": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, "Timer": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "inputs": "TimerInput::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "outputs": "TimerOutput::DisplayNameAnnotation" + "outputs": "TimerOutput::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" } } } diff --git a/doc/basics/introduction/README.md b/doc/basics/introduction/README.md index 73e34882..73deb831 100644 --- a/doc/basics/introduction/README.md +++ b/doc/basics/introduction/README.md @@ -48,6 +48,66 @@ the elements of your scene. The elements can be rearranged by drag&drop. Multipl selected and cut/copied/pasted whenever possible. The order in the scene graph also determines the rendering order. +__Objects filtering__: Ramses Composer supports objects filtering to help users to focus on the +objects they want to edit. These filters can be either simple or complex including keywords and +boolean operators. + +Filter expressions are built up from individual search terms. Each search term is of the form +` = `. The keywords can be omitted. In this case the default +keyword will be taken from the filter combobox. Additionally if the operator is also ommitted `=` is used as default operator. + +| Seach Term Forms | | +|-|-| +| ` ` | general match | +| ` ` | use filter combobox for keyword | +| `` | use filter combobox for keyword and `=` for operator | + +The keywords, operators, and values can be specified as follows: + +| KEYWORD | | +| -------- | -------------------------------------------------------------- | +| name | sort by name | +| type | sort by object types (Node, LuaScript, PerspectiveCamera etc.) | +| id | sort by ids (each object has a unique ID) | +| tag | sort by user tags | + +| Search Term Operators | | +| -------- | -------------------------------------------------------------- | +| = | equal | +| != | not equal | + +| Values | | +| -------- | ---------------------------------------------------------------------------------------- | +| string | unquoted string without special characters or spaces | +| "string" | use double quotes for EXACT match (case sensitive) | +| 'string' | use single quotes for the items which contain WHITESPACEs or ROUNDED BRACKETS | + +Individual search terms can be combined using `&` and `|` operators, see table below. The `|` operator may also be omitted, i.e. combining search terms using spaces is equivalent to using `|`. The `&` operator has a higher preference than the `|` operator. Search terms can be grouped using `()` rounded brackets. + +| Combination Operators | | +| -------- | -------------------------------------------------------------- | +| | | logical OR | +| & | logical AND (has a priority over the OR operator) | +| () | use rounded brackets to group parts of an expression and prioritize their processing | + +**Filter examples** + + name = myName show objects which CONTAIN myName in their names + type = "myType" show objects which type is EXACTLY myType + id != 123-456-789 show objects which DO NOT CONTAIN 123-456-789 in their IDs + tag != "myTag" show objects which tag is EXACTLY NOT myTag + name = name1 | name = name2 show objects with names CONTAINING name1 OR name2 + name = name1 & type = type1 show objects with names CONTAINING name1 AND type CONTAINING type1 + name = name1 & (type = type1 | id = myId) show objects with type CONTAINING type1 OR id CONTAINING myId which at the same time CONTAIN name1 in their names + name = "name(1)" show objects with names EXACTLY name(1) + name = 'name(1)' show objects with names CONTAINING name(1). Here the single quotes are IMPORTANT because the name contains rounded brackets + != myName show objects which DO NOT CONTAIN myName in their names + "myName" show objects which name is EXACTLY myName + != name1 | != name2 show objects which DO NOT CONTAIN name1 OR name2 in their names + myTag show objects which CONTAIN myTag in their user tags + tag1 tag2 show objects which CONTAIN tag1 OR tag2 in their user tags + + __Resources__: The resource view shows all the resources like meshes or textures used by the scene. By clicking on the column headers, it can be sorted by name or by type. It is possible to use resources which are included from other projects. Such external resources are colored in green. @@ -124,7 +184,7 @@ and the RAMSES client. -t, --trace-messages-ramses Enable trace-level Ramses log messages. -f, --featurelevel RamsesLogic feature level (-1, 1 ... 2) -r, --run Run Python script. Specify arguments for python script by writing '--' before arguments. - -y, --pythonpath Directory to add to python module search path. + -y, --pythonpath Directory to add to python module search path. ## Ramses Composer Headless diff --git a/doc/basics/multisampling/msaa.rca b/doc/basics/multisampling/msaa.rca index 899829a0..bf103482 100644 --- a/doc/basics/multisampling/msaa.rca +++ b/doc/basics/multisampling/msaa.rca @@ -2,135 +2,122 @@ "externalProjects": { }, "featureLevel": 1, - "fileVersion": 49, + "fileVersion": 2001, "instances": [ { "properties": { - "enabled": true, - "instanceCount": { + "backgroundColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "defaultResourceFolders": { + "imageSubdirectory": "images", + "interfaceSubdirectory": "interfaces", + "meshSubdirectory": "meshes", + "scriptSubdirectory": "scripts", + "shaderSubdirectory": "shaders" + }, + "featureLevel": 1, + "objectID": "a2840514-1f24-4e84-b843-ae26eb95f0b4", + "objectName": "msaa", + "saveAsZip": false, + "sceneId": { "annotations": [ { "properties": { - "max": 20, + "max": 1024, "min": 1 }, "typeName": "RangeAnnotationInt" } ], - "value": 1 + "value": 123 }, - "materials": { - "order": [ - "material" - ], - "properties": { - "material": { - "order": [ - "material", - "private", - "options", - "uniforms" - ], - "properties": { - "material": { - "typeName": "Material", - "value": "f2ba6982-a897-4a3d-9a90-328173da2922" - }, - "options": { - "annotations": [ - { - "properties": { - "name": "Options" - }, - "typeName": "DisplayNameAnnotation" - } - ], - "properties": { - "blendColor": { - "w": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "x": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "blendFactorDestAlpha": 1, - "blendFactorDestColor": 3, - "blendFactorSrcAlpha": 1, - "blendFactorSrcColor": 2, - "blendOperationAlpha": 0, - "blendOperationColor": 0, - "cullmode": 2, - "depthFunction": 4, - "depthwrite": true - }, - "typeName": "BlendOptions::DisplayNameAnnotation" + "viewport": { + "i1": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 }, - "private": { - "annotations": [ - { - "properties": { - "name": "Private Material" - }, - "typeName": "DisplayNameAnnotation" - } - ], - "typeName": "Bool::DisplayNameAnnotation", - "value": false + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 }, - "uniforms": { - "typeName": "Table" - } - }, - "typeName": "Table" - } + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 } - }, - "mesh": "2f1b8ddf-0f43-46fb-8100-4450a5e6a2f0", - "objectID": "0945082f-ba9d-4a9b-9c35-d6ae31462946", - "objectName": "RightQuadMeshNode", + } + }, + "typeName": "ProjectSettings" + }, + { + "properties": { + "children": [ + "ce64a3b9-ef82-49af-bbd1-25dfc2f22a90", + "3128e5b1-f908-45f2-8397-bc946589808e", + "0945082f-ba9d-4a9b-9c35-d6ae31462946" + ], + "enabled": true, + "objectID": "a42eae27-ec9d-4864-9e59-c895c962282d", + "objectName": "Node", "rotation": { "x": { "annotations": [ @@ -180,7 +167,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 3 + "value": 1 }, "y": { "annotations": [ @@ -192,7 +179,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 3 + "value": 1 }, "z": { "annotations": [ @@ -207,14 +194,6 @@ "value": 1 } }, - "tags": { - "properties": [ - { - "typeName": "String", - "value": "render_main" - } - ] - }, "translation": { "x": { "annotations": [ @@ -226,7 +205,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 3 + "value": 0 }, "y": { "annotations": [ @@ -255,671 +234,83 @@ }, "visibility": true }, - "typeName": "MeshNode" + "typeName": "Node" }, { "properties": { - "anisotropy": { - "annotations": [ - { - "properties": { - "max": 32000, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 - }, - "format": 4, - "height": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } + "enabled": true, + "frustum": { + "order": [ + "nearPlane", + "farPlane", + "fieldOfView", + "aspectRatio" ], - "value": 128 - }, - "magSamplingMethod": 0, - "minSamplingMethod": 0, - "objectID": "0d579482-9a27-4aa0-8f4d-189aa6f0e9f7", - "objectName": "DuckRenderBuffer", - "width": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 128 - }, - "wrapUMode": 0, - "wrapVMode": 0 - }, - "typeName": "RenderBuffer" - }, - { - "properties": { - "materialFilterMode": 1, - "objectID": "1571c0ee-5fc0-4bef-93b8-329b75a64e95", - "objectName": "MainRenderLayer", - "renderableTags": { - "order": [ - "render_main" - ], - "properties": { - "render_main": { - "annotations": [ - { - "properties": { - "featureLevel": 3 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Int::LinkEndAnnotation", - "value": 0 - } - } - }, - "sortOrder": 0 - }, - "typeName": "RenderLayer" - }, - { - "properties": { - "bakeMeshes": true, - "materialNames": { - "properties": [ - { - "typeName": "String", - "value": "material" - } - ] - }, - "meshIndex": 0, - "objectID": "2f1b8ddf-0f43-46fb-8100-4450a5e6a2f0", - "objectName": "Quad", - "uri": "meshes/quad.gltf" - }, - "typeName": "Mesh" - }, - { - "properties": { - "bakeMeshes": true, - "materialNames": { - "properties": [ - { - "typeName": "String", - "value": "material" - } - ] - }, - "meshIndex": 0, - "objectID": "2f973ad3-c85a-4254-ba00-20868046f74d", - "objectName": "Duck", - "uri": "meshes/Duck.glb" - }, - "typeName": "Mesh" - }, - { - "properties": { - "anisotropy": { - "annotations": [ - { - "properties": { - "max": 32000, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 - }, - "format": 13, - "height": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 128 - }, - "magSamplingMethod": 0, - "minSamplingMethod": 0, - "objectID": "2fab3570-e465-4b9d-b0c5-e66de519cff7", - "objectName": "DuckDepthRenderBuffer", - "width": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 128 - }, - "wrapUMode": 0, - "wrapVMode": 0 - }, - "typeName": "RenderBuffer" - }, - { - "properties": { - "enabled": true, - "instanceCount": { - "annotations": [ - { - "properties": { - "max": 20, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 - }, - "materials": { - "order": [ - "material" - ], - "properties": { - "material": { - "order": [ - "material", - "private", - "options", - "uniforms" - ], - "properties": { - "material": { - "typeName": "Material", - "value": "848d6e6e-0f13-4e8d-89a3-32638c1c6d9f" - }, - "options": { - "annotations": [ - { - "properties": { - "name": "Options" - }, - "typeName": "DisplayNameAnnotation" - } - ], - "properties": { - "blendColor": { - "w": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "x": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "blendFactorDestAlpha": 1, - "blendFactorDestColor": 3, - "blendFactorSrcAlpha": 1, - "blendFactorSrcColor": 2, - "blendOperationAlpha": 0, - "blendOperationColor": 0, - "cullmode": 2, - "depthFunction": 4, - "depthwrite": true - }, - "typeName": "BlendOptions::DisplayNameAnnotation" - }, - "private": { - "annotations": [ - { - "properties": { - "name": "Private Material" - }, - "typeName": "DisplayNameAnnotation" - } - ], - "typeName": "Bool::DisplayNameAnnotation", - "value": true - }, - "uniforms": { - "order": [ - "u_FlipUV", - "u_Tex" - ], - "properties": { - "u_FlipUV": { - "annotations": [ - { - "properties": { - "engineType": 2 - }, - "typeName": "EngineTypeAnnotation" - }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", - "value": 1 - }, - "u_Tex": { - "annotations": [ - { - "properties": { - "engineType": 15 - }, - "typeName": "EngineTypeAnnotation" - } - ], - "typeName": "TextureSampler2DBase::EngineTypeAnnotation", - "value": "0d579482-9a27-4aa0-8f4d-189aa6f0e9f7" - } - }, - "typeName": "Table" - } - }, - "typeName": "Table" - } - } - }, - "mesh": "2f1b8ddf-0f43-46fb-8100-4450a5e6a2f0", - "objectID": "3128e5b1-f908-45f2-8397-bc946589808e", - "objectName": "LeftQuadMeshNode", - "rotation": { - "x": { - "annotations": [ - { - "properties": { - "max": 360, - "min": -360 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 360, - "min": -360 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 360, - "min": -360 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "scaling": { - "x": { - "annotations": [ - { - "properties": { - "max": 100, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 3 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 100, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 3 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 100, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 1 - } - }, - "tags": { - "properties": [ - { - "typeName": "String", - "value": "render_main" - } - ] - }, - "translation": { - "x": { - "annotations": [ - { - "properties": { - "max": 100, - "min": -100 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": -3 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 100, - "min": -100 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 100, - "min": -100 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "visibility": true - }, - "typeName": "MeshNode" - }, - { - "properties": { - "buffer0": "0d579482-9a27-4aa0-8f4d-189aa6f0e9f7", - "buffer1": "2fab3570-e465-4b9d-b0c5-e66de519cff7", - "buffer2": null, - "buffer3": null, - "buffer4": null, - "buffer5": null, - "buffer6": null, - "buffer7": null, - "bufferMS0": null, - "bufferMS1": null, - "bufferMS2": null, - "bufferMS3": null, - "bufferMS4": null, - "bufferMS5": null, - "bufferMS6": null, - "bufferMS7": null, - "objectID": "436cfa56-2be5-41db-ba92-fb6f31e2ed09", - "objectName": "RenderTarget" - }, - "typeName": "RenderTarget" - }, - { - "properties": { - "anisotropy": { - "annotations": [ - { - "properties": { - "max": 32000, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 - }, - "format": 4, - "height": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 128 - }, - "magSamplingMethod": 0, - "minSamplingMethod": 0, - "objectID": "5bc6f436-a4db-4680-b443-1bc21573a661", - "objectName": "DuckRenderBufferMS4", - "width": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 128 - }, - "wrapUMode": 0, - "wrapVMode": 0 - }, - "typeName": "RenderBuffer" - }, - { - "properties": { - "anisotropy": { - "annotations": [ - { - "properties": { - "max": 32000, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 - }, - "flipTexture": false, - "generateMipmaps": false, - "level2uri": "", - "level3uri": "", - "level4uri": "", - "magSamplingMethod": 0, - "minSamplingMethod": 0, - "mipmapLevel": { - "annotations": [ - { - "properties": { - "max": 4, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1 - }, - "objectID": "645d7b03-b503-4e58-ab19-aface09fba97", - "objectName": "DuckTexture", - "textureFormat": 5, - "uri": "images/DuckCM.png", - "wrapUMode": 0, - "wrapVMode": 0 - }, - "typeName": "Texture" - }, - { - "properties": { - "buffer0": null, - "buffer1": null, - "buffer2": null, - "buffer3": null, - "buffer4": null, - "buffer5": null, - "buffer6": null, - "buffer7": null, - "bufferMS0": "b48a46aa-4340-4153-a43f-998194089091", - "bufferMS1": "d8301386-444e-489a-8190-6d7e5721d2f2", - "bufferMS2": null, - "bufferMS3": null, - "bufferMS4": null, - "bufferMS5": null, - "bufferMS6": null, - "bufferMS7": null, - "objectID": "80d35c68-f4bf-41b2-b759-085572918791", - "objectName": "RenderTargetMSx4" - }, - "typeName": "RenderTarget" - }, - { - "properties": { - "objectID": "848d6e6e-0f13-4e8d-89a3-32638c1c6d9f", - "objectName": "TextureMaterial", - "options": { - "blendColor": { - "w": { + "properties": { + "aspectRatio": { "annotations": [ { "properties": { - "max": 1, - "min": 0 + "name": "aspectRatio" }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "x": { - "annotations": [ + "typeName": "DisplayNameAnnotation" + }, { "properties": { - "max": 1, - "min": 0 + "max": 4, + "min": 0.5 }, "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ + }, { "properties": { - "max": 1, - "min": 0 + "featureLevel": 1 }, - "typeName": "RangeAnnotationDouble" + "typeName": "LinkEndAnnotation" } ], - "value": 0 + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 1 }, - "z": { + "farPlane": { "annotations": [ { "properties": { - "max": 1, - "min": 0 + "name": "farPlane" }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "blendFactorDestAlpha": 1, - "blendFactorDestColor": 3, - "blendFactorSrcAlpha": 1, - "blendFactorSrcColor": 2, - "blendOperationAlpha": 0, - "blendOperationColor": 0, - "cullmode": 2, - "depthFunction": 4, - "depthwrite": true - }, - "uniforms": { - "order": [ - "u_FlipUV", - "u_Tex" - ], - "properties": { - "u_FlipUV": { + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 10000, + "min": 100 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 1000 + }, + "fieldOfView": { "annotations": [ { "properties": { - "engineType": 2 + "name": "fieldOfView" }, - "typeName": "EngineTypeAnnotation" + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 120, + "min": 10 + }, + "typeName": "RangeAnnotationDouble" }, { "properties": { @@ -928,124 +319,122 @@ "typeName": "LinkEndAnnotation" } ], - "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", - "value": 0 + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 35 }, - "u_Tex": { + "nearPlane": { "annotations": [ { "properties": { - "engineType": 15 + "name": "nearPlane" }, - "typeName": "EngineTypeAnnotation" + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 1, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" } ], - "typeName": "TextureSampler2DBase::EngineTypeAnnotation", - "value": "5bc6f436-a4db-4680-b443-1bc21573a661" + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 0.1 } } }, - "uriDefines": "", - "uriFragment": "shaders/simple_texture.frag", - "uriGeometry": "", - "uriVertex": "shaders/simple_texture.vert" - }, - "typeName": "Material" - }, - { - "properties": { - "camera": "f7cf2c3a-be22-4379-8d50-3669c3304da9", - "clearColor": { - "w": { + "frustumType": 0, + "objectID": "edfb98e9-d20e-4554-9ca4-66d973252b98", + "objectName": "DuckCamera", + "rotation": { + "x": { "annotations": [ { "properties": { - "max": 1, - "min": 0 + "max": 360, + "min": -360 }, "typeName": "RangeAnnotationDouble" } ], "value": 0 }, - "x": { + "y": { "annotations": [ { "properties": { - "max": 1, - "min": 0 + "max": 360, + "min": -360 }, "typeName": "RangeAnnotationDouble" } ], "value": 0 }, - "y": { + "z": { "annotations": [ { "properties": { - "max": 1, - "min": 0 + "max": 360, + "min": -360 }, "typeName": "RangeAnnotationDouble" } ], "value": 0 - }, - "z": { + } + }, + "scaling": { + "x": { "annotations": [ { "properties": { - "max": 1, - "min": 0 + "max": 100, + "min": 0.1 }, "typeName": "RangeAnnotationDouble" } ], - "value": 0 - } - }, - "enableClearColor": true, - "enableClearDepth": true, - "enableClearStencil": true, - "enabled": true, - "layer0": "1571c0ee-5fc0-4bef-93b8-329b75a64e95", - "layer1": null, - "layer2": null, - "layer3": null, - "layer4": null, - "layer5": null, - "layer6": null, - "layer7": null, - "objectID": "8703286b-f230-4c15-b110-eb0a9e209ae3", - "objectName": "MainRenderPass", - "renderOnce": false, - "renderOrder": 1, - "target": null - }, - "typeName": "RenderPass" - }, - { - "properties": { - "backgroundColor": { - "w": { + "value": 1 + }, + "y": { "annotations": [ { "properties": { - "max": 1, - "min": 0 + "max": 100, + "min": 0.1 }, "typeName": "RangeAnnotationDouble" } ], "value": 1 }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + } + }, + "translation": { "x": { "annotations": [ { "properties": { - "max": 1, - "min": 0 + "max": 100, + "min": -100 }, "typeName": "RangeAnnotationDouble" } @@ -1056,8 +445,8 @@ "annotations": [ { "properties": { - "max": 1, - "min": 0 + "max": 100, + "min": -100 }, "typeName": "RangeAnnotationDouble" } @@ -1068,88 +457,185 @@ "annotations": [ { "properties": { - "max": 1, - "min": 0 + "max": 100, + "min": -100 }, "typeName": "RangeAnnotationDouble" } ], - "value": 0 + "value": 10 } }, - "defaultResourceFolders": { - "imageSubdirectory": "images", - "interfaceSubdirectory": "interfaces", - "meshSubdirectory": "meshes", - "scriptSubdirectory": "scripts", - "shaderSubdirectory": "shaders" - }, - "featureLevel": 1, - "objectID": "a2840514-1f24-4e84-b843-ae26eb95f0b4", - "objectName": "msaa", - "saveAsZip": false, - "sceneId": { - "annotations": [ - { - "properties": { - "max": 1024, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 123 - }, "viewport": { - "i1": { + "height": { "annotations": [ { "properties": { - "max": 4096, - "min": 0 + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 128 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 128 + } + }, + "visibility": true + }, + "typeName": "PerspectiveCamera" + }, + { + "properties": { + "enabled": true, + "frustum": { + "order": [ + "nearPlane", + "farPlane", + "fieldOfView", + "aspectRatio" + ], + "properties": { + "aspectRatio": { + "annotations": [ + { + "properties": { + "name": "aspectRatio" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 4, + "min": 0.5 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 2 + }, + "farPlane": { + "annotations": [ + { + "properties": { + "name": "farPlane" + }, + "typeName": "DisplayNameAnnotation" }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1440 - }, - "i2": { - "annotations": [ - { - "properties": { - "max": 4096, - "min": 0 + { + "properties": { + "max": 10000, + "min": 100 + }, + "typeName": "RangeAnnotationDouble" }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 720 - } - } - }, - "typeName": "ProjectSettings" - }, - { - "properties": { - "children": { - "properties": [ - { - "typeName": "Ref", - "value": "ce64a3b9-ef82-49af-bbd1-25dfc2f22a90" + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 1000 }, - { - "typeName": "Ref", - "value": "3128e5b1-f908-45f2-8397-bc946589808e" + "fieldOfView": { + "annotations": [ + { + "properties": { + "name": "fieldOfView" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 120, + "min": 10 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 35 }, - { - "typeName": "Ref", - "value": "0945082f-ba9d-4a9b-9c35-d6ae31462946" + "nearPlane": { + "annotations": [ + { + "properties": { + "name": "nearPlane" + }, + "typeName": "DisplayNameAnnotation" + }, + { + "properties": { + "max": 1, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "value": 0.1 } - ] + } }, - "enabled": true, - "objectID": "a42eae27-ec9d-4864-9e59-c895c962282d", - "objectName": "Node", + "frustumType": 0, + "objectID": "f7cf2c3a-be22-4379-8d50-3669c3304da9", + "objectName": "PerspectiveCamera", "rotation": { "x": { "annotations": [ @@ -1261,56 +747,62 @@ "typeName": "RangeAnnotationDouble" } ], + "value": 10 + } + }, + "viewport": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 } }, "visibility": true }, - "typeName": "Node" - }, - { - "properties": { - "format": 4, - "height": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 128 - }, - "objectID": "b48a46aa-4340-4153-a43f-998194089091", - "objectName": "ColorMSx4", - "sampleCount": { - "annotations": [ - { - "properties": { - "max": 8, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 4 - }, - "width": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 128 - } - }, - "typeName": "RenderBufferMS" + "typeName": "PerspectiveCamera" }, { "properties": { @@ -1342,7 +834,7 @@ "properties": { "material": { "typeName": "Material", - "value": "848d6e6e-0f13-4e8d-89a3-32638c1c6d9f" + "value": "f2ba6982-a897-4a3d-9a90-328173da2922" }, "options": { "annotations": [ @@ -1410,9 +902,98 @@ "blendFactorSrcColor": 2, "blendOperationAlpha": 0, "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, "cullmode": 2, "depthFunction": 4, - "depthwrite": true + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } }, "typeName": "BlendOptions::DisplayNameAnnotation" }, @@ -1430,11 +1011,11 @@ }, "uniforms": { "order": [ - "u_FlipUV", - "u_Tex" + "textureSampler", + "sampleCount" ], "properties": { - "u_FlipUV": { + "sampleCount": { "annotations": [ { "properties": { @@ -1450,19 +1031,19 @@ } ], "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", - "value": 0 + "value": 4 }, - "u_Tex": { + "textureSampler": { "annotations": [ { "properties": { - "engineType": 15 + "engineType": 19 }, "typeName": "EngineTypeAnnotation" } ], - "typeName": "TextureSampler2DBase::EngineTypeAnnotation", - "value": "645d7b03-b503-4e58-ab19-aface09fba97" + "typeName": "RenderBufferMS::EngineTypeAnnotation", + "value": "b48a46aa-4340-4153-a43f-998194089091" } }, "typeName": "Table" @@ -1472,9 +1053,9 @@ } } }, - "mesh": "2f973ad3-c85a-4254-ba00-20868046f74d", - "objectID": "ce64a3b9-ef82-49af-bbd1-25dfc2f22a90", - "objectName": "DuckMeshNode", + "mesh": "2f1b8ddf-0f43-46fb-8100-4450a5e6a2f0", + "objectID": "0945082f-ba9d-4a9b-9c35-d6ae31462946", + "objectName": "RightQuadMeshNode", "rotation": { "x": { "annotations": [ @@ -1524,7 +1105,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 2 + "value": 3 }, "y": { "annotations": [ @@ -1536,7 +1117,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 2 + "value": 3 }, "z": { "annotations": [ @@ -1548,14 +1129,14 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 2 + "value": 1 } }, "tags": { "properties": [ { "typeName": "String", - "value": "duck" + "value": "render_main" } ] }, @@ -1570,7 +1151,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 0 + "value": 3 }, "y": { "annotations": [ @@ -1582,7 +1163,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": -2 + "value": 0 }, "z": { "annotations": [ @@ -1603,61 +1184,35 @@ }, { "properties": { - "materialFilterMode": 1, - "objectID": "d120ade7-8b3f-4607-b2db-5115e3218b25", - "objectName": "DuckRenderLayer", - "renderableTags": { - "order": [ - "duck" - ], - "properties": { - "duck": { - "annotations": [ - { - "properties": { - "featureLevel": 3 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Int::LinkEndAnnotation", - "value": 0 - } - } - }, - "sortOrder": 0 - }, - "typeName": "RenderLayer" - }, - { - "properties": { - "format": 13, - "height": { + "anisotropy": { "annotations": [ { "properties": { - "max": 7680, + "max": 32000, "min": 1 }, "typeName": "RangeAnnotationInt" } ], - "value": 128 + "value": 1 }, - "objectID": "d8301386-444e-489a-8190-6d7e5721d2f2", - "objectName": "DepthMSx4", - "sampleCount": { + "format": 4, + "height": { "annotations": [ { "properties": { - "max": 8, + "max": 7680, "min": 1 }, "typeName": "RangeAnnotationInt" } ], - "value": 4 + "value": 128 }, + "magSamplingMethod": 0, + "minSamplingMethod": 0, + "objectID": "0d579482-9a27-4aa0-8f4d-189aa6f0e9f7", + "objectName": "DuckRenderBuffer", "width": { "annotations": [ { @@ -1669,272 +1224,434 @@ } ], "value": 128 - } + }, + "wrapUMode": 0, + "wrapVMode": 0 }, - "typeName": "RenderBufferMS" + "typeName": "RenderBuffer" }, { "properties": { - "camera": "edfb98e9-d20e-4554-9ca4-66d973252b98", - "clearColor": { - "w": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 1 - }, - "x": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0.1 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0.2 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0.2 + "materialFilterMode": 1, + "objectID": "1571c0ee-5fc0-4bef-93b8-329b75a64e95", + "objectName": "MainRenderLayer", + "renderableTags": { + "order": [ + "render_main" + ], + "properties": { + "render_main": { + "annotations": [ + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::LinkEndAnnotation", + "value": 0 + } } }, - "enableClearColor": true, - "enableClearDepth": true, - "enableClearStencil": true, - "enabled": true, - "layer0": "d120ade7-8b3f-4607-b2db-5115e3218b25", - "layer1": null, - "layer2": null, - "layer3": null, - "layer4": null, - "layer5": null, - "layer6": null, - "layer7": null, - "objectID": "e3c42eff-716c-4148-a38c-7e6fc37b78c0", - "objectName": "DuckRenderPassMSx4", - "renderOnce": false, - "renderOrder": 0, - "target": "80d35c68-f4bf-41b2-b759-085572918791" + "sortOrder": 0 }, - "typeName": "RenderPass" + "typeName": "RenderLayer" }, { "properties": { - "camera": "edfb98e9-d20e-4554-9ca4-66d973252b98", - "clearColor": { - "w": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 1 - }, - "x": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0.1 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 + "bakeMeshes": true, + "materialNames": { + "properties": [ + { + "typeName": "String", + "value": "material" + } + ] + }, + "meshIndex": 0, + "metaData": { + "order": [ + "meshInfo" + ], + "properties": { + "meshInfo": { + "annotations": [ + { + "typeName": "ReadOnlyAnnotation" + } + ], + "order": [ + "triangles", + "vertices" + ], + "properties": { + "triangles": { + "typeName": "Int", + "value": 2 }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0.2 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 + "vertices": { + "typeName": "Int", + "value": 4 + } + }, + "typeName": "Table::ReadOnlyAnnotation" + } + } + }, + "objectID": "2f1b8ddf-0f43-46fb-8100-4450a5e6a2f0", + "objectName": "Quad", + "uri": "meshes/quad.gltf" + }, + "typeName": "Mesh" + }, + { + "properties": { + "bakeMeshes": true, + "materialNames": { + "properties": [ + { + "typeName": "String", + "value": "material" + } + ] + }, + "meshIndex": 0, + "metaData": { + "order": [ + "meshInfo" + ], + "properties": { + "meshInfo": { + "annotations": [ + { + "typeName": "ReadOnlyAnnotation" + } + ], + "order": [ + "triangles", + "vertices" + ], + "properties": { + "triangles": { + "typeName": "Int", + "value": 4212 }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0.2 + "vertices": { + "typeName": "Int", + "value": 2399 + } + }, + "typeName": "Table::ReadOnlyAnnotation" + } } }, - "enableClearColor": true, - "enableClearDepth": true, - "enableClearStencil": true, - "enabled": true, - "layer0": "d120ade7-8b3f-4607-b2db-5115e3218b25", - "layer1": null, - "layer2": null, - "layer3": null, - "layer4": null, - "layer5": null, - "layer6": null, - "layer7": null, - "objectID": "e8a483cb-1d70-4f1f-80ee-b67f90c67247", - "objectName": "DuckRenderPass", - "renderOnce": false, - "renderOrder": 0, - "target": "436cfa56-2be5-41db-ba92-fb6f31e2ed09" + "objectID": "2f973ad3-c85a-4254-ba00-20868046f74d", + "objectName": "Duck", + "uri": "meshes/Duck.glb" + }, + "typeName": "Mesh" + }, + { + "properties": { + "anisotropy": { + "annotations": [ + { + "properties": { + "max": 32000, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "format": 13, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 128 + }, + "magSamplingMethod": 0, + "minSamplingMethod": 0, + "objectID": "2fab3570-e465-4b9d-b0c5-e66de519cff7", + "objectName": "DuckDepthRenderBuffer", + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 128 + }, + "wrapUMode": 0, + "wrapVMode": 0 }, - "typeName": "RenderPass" + "typeName": "RenderBuffer" }, { "properties": { "enabled": true, - "frustum": { + "instanceCount": { + "annotations": [ + { + "properties": { + "max": 20, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "materials": { "order": [ - "nearPlane", - "farPlane", - "fieldOfView", - "aspectRatio" + "material" ], "properties": { - "aspectRatio": { - "annotations": [ - { - "properties": { - "name": "aspectRatio" - }, - "typeName": "DisplayNameAnnotation" - }, - { - "properties": { - "max": 4, - "min": 0.5 - }, - "typeName": "RangeAnnotationDouble" - }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 1 - }, - "farPlane": { - "annotations": [ - { - "properties": { - "name": "farPlane" - }, - "typeName": "DisplayNameAnnotation" - }, - { - "properties": { - "max": 10000, - "min": 100 - }, - "typeName": "RangeAnnotationDouble" - }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } + "material": { + "order": [ + "material", + "private", + "options", + "uniforms" ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 1000 - }, - "fieldOfView": { - "annotations": [ - { - "properties": { - "name": "fieldOfView" - }, - "typeName": "DisplayNameAnnotation" - }, - { - "properties": { - "max": 120, - "min": 10 - }, - "typeName": "RangeAnnotationDouble" + "properties": { + "material": { + "typeName": "Material", + "value": "848d6e6e-0f13-4e8d-89a3-32638c1c6d9f" }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 35 - }, - "nearPlane": { - "annotations": [ - { + "options": { + "annotations": [ + { + "properties": { + "name": "Options" + }, + "typeName": "DisplayNameAnnotation" + } + ], "properties": { - "name": "nearPlane" + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } }, - "typeName": "DisplayNameAnnotation" + "typeName": "BlendOptions::DisplayNameAnnotation" }, - { - "properties": { - "max": 1, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" + "private": { + "annotations": [ + { + "properties": { + "name": "Private Material" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "typeName": "Bool::DisplayNameAnnotation", + "value": true }, - { + "uniforms": { + "order": [ + "u_FlipUV", + "u_Tex" + ], "properties": { - "featureLevel": 1 + "u_FlipUV": { + "annotations": [ + { + "properties": { + "engineType": 1 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Bool::EngineTypeAnnotation::LinkEndAnnotation", + "value": false + }, + "u_Tex": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation", + "value": "0d579482-9a27-4aa0-8f4d-189aa6f0e9f7" + } }, - "typeName": "LinkEndAnnotation" + "typeName": "Table" } - ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 0.1 + }, + "typeName": "Table" } } }, - "frustumType": 0, - "objectID": "edfb98e9-d20e-4554-9ca4-66d973252b98", - "objectName": "DuckCamera", + "mesh": "2f1b8ddf-0f43-46fb-8100-4450a5e6a2f0", + "objectID": "3128e5b1-f908-45f2-8397-bc946589808e", + "objectName": "LeftQuadMeshNode", "rotation": { "x": { "annotations": [ @@ -1984,7 +1701,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 1 + "value": 3 }, "y": { "annotations": [ @@ -1996,7 +1713,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 1 + "value": 3 }, "z": { "annotations": [ @@ -2011,6 +1728,14 @@ "value": 1 } }, + "tags": { + "properties": [ + { + "typeName": "String", + "value": "render_main" + } + ] + }, "translation": { "x": { "annotations": [ @@ -2022,7 +1747,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 0 + "value": -3 }, "y": { "annotations": [ @@ -2046,67 +1771,93 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 10 - } - }, - "viewport": { - "height": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 128 - }, - "offsetX": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": -7680 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 0 - }, - "offsetY": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": -7680 - }, - "typeName": "RangeAnnotationInt" - } - ], "value": 0 - }, - "width": { - "annotations": [ - { - "properties": { - "max": 7680, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 128 } }, "visibility": true }, - "typeName": "PerspectiveCamera" + "typeName": "MeshNode" }, { "properties": { - "objectID": "f2ba6982-a897-4a3d-9a90-328173da2922", - "objectName": "TextureMaterialMS", + "buffers": [ + "0d579482-9a27-4aa0-8f4d-189aa6f0e9f7", + "2fab3570-e465-4b9d-b0c5-e66de519cff7", + null, + null, + null, + null, + null, + null + ], + "objectID": "436cfa56-2be5-41db-ba92-fb6f31e2ed09", + "objectName": "RenderTarget" + }, + "typeName": "RenderTarget" + }, + { + "properties": { + "anisotropy": { + "annotations": [ + { + "properties": { + "max": 32000, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "flipTexture": false, + "generateMipmaps": false, + "level2uri": "", + "level3uri": "", + "level4uri": "", + "magSamplingMethod": 0, + "minSamplingMethod": 0, + "mipmapLevel": { + "annotations": [ + { + "properties": { + "max": 4, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "objectID": "645d7b03-b503-4e58-ab19-aface09fba97", + "objectName": "DuckTexture", + "textureFormat": 5, + "uri": "images/DuckCM.png", + "wrapUMode": 0, + "wrapVMode": 0 + }, + "typeName": "Texture" + }, + { + "properties": { + "buffers": [ + "b48a46aa-4340-4153-a43f-998194089091", + "d8301386-444e-489a-8190-6d7e5721d2f2", + null, + null, + null, + null, + null, + null + ], + "objectID": "80d35c68-f4bf-41b2-b759-085572918791", + "objectName": "RenderTargetMSx4" + }, + "typeName": "RenderTargetMS" + }, + { + "properties": { + "objectID": "848d6e6e-0f13-4e8d-89a3-32638c1c6d9f", + "objectName": "TextureMaterial", "options": { "blendColor": { "w": { @@ -2164,105 +1915,112 @@ "blendFactorSrcColor": 2, "blendOperationAlpha": 0, "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, "cullmode": 2, "depthFunction": 4, - "depthwrite": true - }, - "uniforms": { - "order": [ - "textureSampler", - "sampleCount" - ], - "properties": { - "sampleCount": { - "annotations": [ - { - "properties": { - "engineType": 2 - }, - "typeName": "EngineTypeAnnotation" - }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", - "value": 4 - }, - "textureSampler": { - "annotations": [ - { - "properties": { - "engineType": 19 - }, - "typeName": "EngineTypeAnnotation" - } - ], - "typeName": "RenderBufferMS::EngineTypeAnnotation", - "value": "b48a46aa-4340-4153-a43f-998194089091" - } - } - }, - "uriDefines": "", - "uriFragment": "shaders/multisampler.frag", - "uriGeometry": "", - "uriVertex": "shaders/multisampler.vert" - }, - "typeName": "Material" - }, - { - "properties": { - "enabled": true, - "frustum": { - "order": [ - "nearPlane", - "farPlane", - "fieldOfView", - "aspectRatio" - ], - "properties": { - "aspectRatio": { - "annotations": [ - { - "properties": { - "name": "aspectRatio" - }, - "typeName": "DisplayNameAnnotation" - }, - { - "properties": { - "max": 4, - "min": 0.5 - }, - "typeName": "RangeAnnotationDouble" - }, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ { "properties": { - "featureLevel": 1 + "max": 255, + "min": 0 }, - "typeName": "LinkEndAnnotation" + "typeName": "RangeAnnotationInt" } ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 2 + "value": 255 }, - "farPlane": { + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { "annotations": [ { "properties": { - "name": "farPlane" + "max": 255, + "min": 0 }, - "typeName": "DisplayNameAnnotation" - }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } + }, + "uniforms": { + "order": [ + "u_FlipUV", + "u_Tex" + ], + "properties": { + "u_FlipUV": { + "annotations": [ { "properties": { - "max": 10000, - "min": 100 + "engineType": 1 }, - "typeName": "RangeAnnotationDouble" + "typeName": "EngineTypeAnnotation" }, { "properties": { @@ -2271,64 +2029,401 @@ "typeName": "LinkEndAnnotation" } ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 1000 + "typeName": "Bool::EngineTypeAnnotation::LinkEndAnnotation", + "value": false }, - "fieldOfView": { + "u_Tex": { "annotations": [ { "properties": { - "name": "fieldOfView" + "engineType": 15 }, - "typeName": "DisplayNameAnnotation" + "typeName": "EngineTypeAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation", + "value": "0d579482-9a27-4aa0-8f4d-189aa6f0e9f7" + } + } + }, + "uriDefines": "", + "uriFragment": "shaders/simple_texture.frag", + "uriGeometry": "", + "uriVertex": "shaders/simple_texture.vert" + }, + "typeName": "Material" + }, + { + "properties": { + "camera": "f7cf2c3a-be22-4379-8d50-3669c3304da9", + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 }, - { - "properties": { - "max": 120, - "min": 10 - }, - "typeName": "RangeAnnotationDouble" + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 }, - { - "properties": { - "featureLevel": 1 - }, - "typeName": "LinkEndAnnotation" - } + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layers": [ + "1571c0ee-5fc0-4bef-93b8-329b75a64e95", + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "8703286b-f230-4c15-b110-eb0a9e209ae3", + "objectName": "MainRenderPass", + "renderOnce": false, + "renderOrder": 2, + "target": null + }, + "typeName": "RenderPass" + }, + { + "properties": { + "format": 4, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 128 + }, + "objectID": "b48a46aa-4340-4153-a43f-998194089091", + "objectName": "ColorMSx4", + "sampleCount": { + "annotations": [ + { + "properties": { + "max": 8, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 4 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 128 + } + }, + "typeName": "RenderBufferMS" + }, + { + "properties": { + "enabled": true, + "instanceCount": { + "annotations": [ + { + "properties": { + "max": 20, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + }, + "materials": { + "order": [ + "material" + ], + "properties": { + "material": { + "order": [ + "material", + "private", + "options", + "uniforms" ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 35 - }, - "nearPlane": { - "annotations": [ - { + "properties": { + "material": { + "typeName": "Material", + "value": "848d6e6e-0f13-4e8d-89a3-32638c1c6d9f" + }, + "options": { + "annotations": [ + { + "properties": { + "name": "Options" + }, + "typeName": "DisplayNameAnnotation" + } + ], "properties": { - "name": "nearPlane" + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } }, - "typeName": "DisplayNameAnnotation" + "typeName": "BlendOptions::DisplayNameAnnotation" }, - { - "properties": { - "max": 1, - "min": 0.1 - }, - "typeName": "RangeAnnotationDouble" + "private": { + "annotations": [ + { + "properties": { + "name": "Private Material" + }, + "typeName": "DisplayNameAnnotation" + } + ], + "typeName": "Bool::DisplayNameAnnotation", + "value": true }, - { + "uniforms": { + "order": [ + "u_FlipUV", + "u_Tex" + ], "properties": { - "featureLevel": 1 + "u_FlipUV": { + "annotations": [ + { + "properties": { + "engineType": 1 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Bool::EngineTypeAnnotation::LinkEndAnnotation", + "value": false + }, + "u_Tex": { + "annotations": [ + { + "properties": { + "engineType": 15 + }, + "typeName": "EngineTypeAnnotation" + } + ], + "typeName": "TextureSampler2DBase::EngineTypeAnnotation", + "value": "645d7b03-b503-4e58-ab19-aface09fba97" + } }, - "typeName": "LinkEndAnnotation" + "typeName": "Table" } - ], - "typeName": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", - "value": 0.1 + }, + "typeName": "Table" } } }, - "frustumType": 0, - "objectID": "f7cf2c3a-be22-4379-8d50-3669c3304da9", - "objectName": "PerspectiveCamera", + "mesh": "2f973ad3-c85a-4254-ba00-20868046f74d", + "objectID": "ce64a3b9-ef82-49af-bbd1-25dfc2f22a90", + "objectName": "DuckMeshNode", "rotation": { "x": { "annotations": [ @@ -2378,7 +2473,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 1 + "value": 2 }, "y": { "annotations": [ @@ -2390,7 +2485,7 @@ "typeName": "RangeAnnotationDouble" } ], - "value": 1 + "value": 2 }, "z": { "annotations": [ @@ -2402,118 +2497,492 @@ "typeName": "RangeAnnotationDouble" } ], + "value": 2 + } + }, + "tags": { + "properties": [ + { + "typeName": "String", + "value": "duck" + } + ] + }, + "translation": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": -2 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 100, + "min": -100 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "visibility": true + }, + "typeName": "MeshNode" + }, + { + "properties": { + "materialFilterMode": 1, + "objectID": "d120ade7-8b3f-4607-b2db-5115e3218b25", + "objectName": "DuckRenderLayer", + "renderableTags": { + "order": [ + "duck" + ], + "properties": { + "duck": { + "annotations": [ + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::LinkEndAnnotation", + "value": 0 + } + } + }, + "sortOrder": 0 + }, + "typeName": "RenderLayer" + }, + { + "properties": { + "format": 13, + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 128 + }, + "objectID": "d8301386-444e-489a-8190-6d7e5721d2f2", + "objectName": "DepthMSx4", + "sampleCount": { + "annotations": [ + { + "properties": { + "max": 8, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 4 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 128 + } + }, + "typeName": "RenderBufferMS" + }, + { + "properties": { + "camera": "edfb98e9-d20e-4554-9ca4-66d973252b98", + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], "value": 1 - } - }, - "translation": { + }, "x": { "annotations": [ { "properties": { - "max": 100, - "min": -100 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } ], - "value": 0 + "value": 0.1 }, "y": { "annotations": [ { "properties": { - "max": 100, - "min": -100 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } ], - "value": 0 + "value": 0.2 }, "z": { "annotations": [ { "properties": { - "max": 100, - "min": -100 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } ], - "value": 10 + "value": 0.2 } }, - "viewport": { - "height": { + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layers": [ + "d120ade7-8b3f-4607-b2db-5115e3218b25", + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "e3c42eff-716c-4148-a38c-7e6fc37b78c0", + "objectName": "DuckRenderPassMSx4", + "renderOnce": false, + "renderOrder": 1, + "target": "80d35c68-f4bf-41b2-b759-085572918791" + }, + "typeName": "RenderPass" + }, + { + "properties": { + "camera": "edfb98e9-d20e-4554-9ca4-66d973252b98", + "clearColor": { + "w": { "annotations": [ { "properties": { - "max": 7680, - "min": 1 + "max": 1, + "min": 0 }, - "typeName": "RangeAnnotationInt" + "typeName": "RangeAnnotationDouble" } ], - "value": 720 + "value": 1 }, - "offsetX": { + "x": { "annotations": [ { "properties": { - "max": 7680, - "min": -7680 + "max": 1, + "min": 0 }, - "typeName": "RangeAnnotationInt" + "typeName": "RangeAnnotationDouble" } ], - "value": 0 + "value": 0.1 }, - "offsetY": { + "y": { "annotations": [ { "properties": { - "max": 7680, - "min": -7680 + "max": 1, + "min": 0 }, - "typeName": "RangeAnnotationInt" + "typeName": "RangeAnnotationDouble" } ], - "value": 0 + "value": 0.2 }, - "width": { + "z": { "annotations": [ { "properties": { - "max": 7680, - "min": 1 + "max": 1, + "min": 0 }, - "typeName": "RangeAnnotationInt" + "typeName": "RangeAnnotationDouble" } ], - "value": 1440 + "value": 0.2 } }, - "visibility": true + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layers": [ + "d120ade7-8b3f-4607-b2db-5115e3218b25", + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "e8a483cb-1d70-4f1f-80ee-b67f90c67247", + "objectName": "DuckRenderPass", + "renderOnce": false, + "renderOrder": 0, + "target": "436cfa56-2be5-41db-ba92-fb6f31e2ed09" }, - "typeName": "PerspectiveCamera" + "typeName": "RenderPass" + }, + { + "properties": { + "objectID": "f2ba6982-a897-4a3d-9a90-328173da2922", + "objectName": "TextureMaterialMS", + "options": { + "blendColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "blendFactorDestAlpha": 1, + "blendFactorDestColor": 3, + "blendFactorSrcAlpha": 1, + "blendFactorSrcColor": 2, + "blendOperationAlpha": 0, + "blendOperationColor": 0, + "colorWriteMask": { + "alpha": true, + "blue": true, + "green": true, + "red": true + }, + "cullmode": 2, + "depthFunction": 4, + "depthwrite": true, + "scissorOptions": { + "scissorEnable": false, + "scissorRegion": { + "height": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + }, + "offsetX": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "offsetY": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": -7680 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 0 + }, + "width": { + "annotations": [ + { + "properties": { + "max": 7680, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + } + } + }, + "stencilOptions": { + "stencilFunc": 0, + "stencilMask": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 255 + }, + "stencilOpDepthFail": 0, + "stencilOpDepthSucc": 0, + "stencilOpStencilFail": 0, + "stencilRef": { + "annotations": [ + { + "properties": { + "max": 255, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1 + } + } + }, + "uniforms": { + "order": [ + "textureSampler", + "sampleCount" + ], + "properties": { + "sampleCount": { + "annotations": [ + { + "properties": { + "engineType": 2 + }, + "typeName": "EngineTypeAnnotation" + }, + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::EngineTypeAnnotation::LinkEndAnnotation", + "value": 4 + }, + "textureSampler": { + "annotations": [ + { + "properties": { + "engineType": 19 + }, + "typeName": "EngineTypeAnnotation" + } + ], + "typeName": "RenderBufferMS::EngineTypeAnnotation", + "value": "b48a46aa-4340-4153-a43f-998194089091" + } + } + }, + "uriDefines": "", + "uriFragment": "shaders/multisampler.frag", + "uriGeometry": "", + "uriVertex": "shaders/multisampler.vert" + }, + "typeName": "Material" } ], "links": [ ], - "logicEngineVersion": [ - 1, - 4, - 2 - ], "racoVersion": [ - 1, - 7, + 2, + 0, 0 ], "ramsesVersion": [ - 27, + 28, 0, - 130 + 0 ], "structPropMap": { "AnchorPointOutputs": { @@ -2528,9 +2997,12 @@ "blendFactorSrcColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", "blendOperationAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", "blendOperationColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "colorWriteMask": "ColorWriteMask::DisplayNameAnnotation", "cullmode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "depthFunction": "Int::DisplayNameAnnotation::EnumerationAnnotation", - "depthwrite": "Bool::DisplayNameAnnotation" + "depthwrite": "Bool::DisplayNameAnnotation", + "scissorOptions": "ScissorOptions::DisplayNameAnnotation", + "stencilOptions": "StencilOptions::DisplayNameAnnotation" }, "CameraViewport": { "height": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", @@ -2538,6 +3010,12 @@ "offsetY": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", "width": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation" }, + "ColorWriteMask": { + "alpha": "Bool::DisplayNameAnnotation", + "blue": "Bool::DisplayNameAnnotation", + "green": "Bool::DisplayNameAnnotation", + "red": "Bool::DisplayNameAnnotation" + }, "DefaultResourceDirectories": { "imageSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", "interfaceSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", @@ -2560,6 +3038,18 @@ "rightPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", "topPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation" }, + "ScissorOptions": { + "scissorEnable": "Bool::DisplayNameAnnotation", + "scissorRegion": "CameraViewport::DisplayNameAnnotation" + }, + "StencilOptions": { + "stencilFunc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilMask": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "stencilOpDepthFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpDepthSucc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpStencilFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilRef": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, "TimerInput": { "ticker_us": "Int64::DisplayNameAnnotation::LinkEndAnnotation" }, @@ -2600,34 +3090,41 @@ "userTypePropMap": { "AnchorPoint": { "camera": "BaseCamera::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "node": "Node::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "outputs": "AnchorPointOutputs::DisplayNameAnnotation" + "outputs": "AnchorPointOutputs::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Animation": { - "animationChannels": "Table::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "animationChannels": "Array[AnimationChannel]::DisplayNameAnnotation::ResizableArray", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "outputs": "Table::DisplayNameAnnotation", - "progress": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation" + "progress": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "AnimationChannel": { "animationIndex": "Int::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "samplerIndex": "Int::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "BlitPass": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "destinationX": "Int::RangeAnnotationInt::DisplayNameAnnotation", "destinationY": "Int::RangeAnnotationInt::DisplayNameAnnotation", "enabled": "Bool::DisplayNameAnnotation", "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "renderOrder": "Int::DisplayNameAnnotation", @@ -2637,11 +3134,12 @@ "sourceY": "Int::RangeAnnotationInt::DisplayNameAnnotation", "targetRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", "targetRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" }, "CubeMap": { "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "generateMipmaps": "Bool::DisplayNameAnnotation", "level2uriBack": "String::URIAnnotation::DisplayNameAnnotation", "level2uriBottom": "String::URIAnnotation::DisplayNameAnnotation", @@ -2662,6 +3160,7 @@ "level4uriRight": "String::URIAnnotation::DisplayNameAnnotation", "level4uriTop": "String::URIAnnotation::DisplayNameAnnotation", "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", "objectID": "String::HiddenProperty", @@ -2673,37 +3172,45 @@ "uriLeft": "String::URIAnnotation::DisplayNameAnnotation", "uriRight": "String::URIAnnotation::DisplayNameAnnotation", "uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" }, "LuaInterface": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "inputs": "Table::DisplayNameAnnotation::LinkStartAnnotation::LinkEndAnnotation", - "luaModules": "Table::DisplayNameAnnotation::FeatureLevel", + "luaModules": "Table::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation::FeatureLevel", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "LuaScript": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "inputs": "Table::DisplayNameAnnotation::LinkEndAnnotation", "luaModules": "Table::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "outputs": "Table::DisplayNameAnnotation", "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "LuaScriptModule": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Material": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "options": "BlendOptions::DisplayNameAnnotation", @@ -2712,77 +3219,91 @@ "uriDefines": "String::URIAnnotation::DisplayNameAnnotation", "uriFragment": "String::URIAnnotation::DisplayNameAnnotation", "uriGeometry": "String::URIAnnotation::DisplayNameAnnotation", - "uriVertex": "String::URIAnnotation::DisplayNameAnnotation" + "uriVertex": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Mesh": { "bakeMeshes": "Bool::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "materialNames": "Table::ArraySemanticAnnotation::HiddenProperty", "meshIndex": "Int::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "MeshNode": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", - "instanceCount": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "instanceCount": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", "materials": "Table::DisplayNameAnnotation", "mesh": "Mesh::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "Node": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "OrthographicCamera": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", "frustum": "OrthographicFrustum::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "PerspectiveCamera": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", "frustum": "Table::DisplayNameAnnotation::LinkEndAnnotation", - "frustumType": "Int::DisplayNameAnnotation::EnumerationAnnotation::FeatureLevel", + "frustumType": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "Prefab": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", - "objectName": "String::DisplayNameAnnotation" + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "PrefabInstance": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", @@ -2790,11 +3311,12 @@ "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "template": "Prefab::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "ProjectSettings": { "backgroundColor": "Vec4f::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "defaultResourceFolders": "DefaultResourceDirectories::DisplayNameAnnotation", "featureLevel": "Int::DisplayNameAnnotation::ReadOnlyAnnotation", "objectID": "String::HiddenProperty", @@ -2805,119 +3327,123 @@ }, "RenderBuffer": { "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "width": "Int::RangeAnnotationInt::DisplayNameAnnotation", "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" }, "RenderBufferMS": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "sampleCount": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" }, "RenderLayer": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "materialFilterMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "materialFilterTags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "renderableTags": "Table::RenderableTagContainerAnnotation::DisplayNameAnnotation", "sortOrder": "Int::DisplayNameAnnotation::EnumerationAnnotation", - "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation" + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "RenderPass": { "camera": "BaseCamera::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "clearColor": "Vec4f::DisplayNameAnnotation::LinkEndAnnotation", "enableClearColor": "Bool::DisplayNameAnnotation", "enableClearDepth": "Bool::DisplayNameAnnotation", "enableClearStencil": "Bool::DisplayNameAnnotation", "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", - "layer0": "RenderLayer::DisplayNameAnnotation", - "layer1": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer2": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer3": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer4": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer5": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer6": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer7": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layers": "Array[RenderLayer]::DisplayNameAnnotation::EmptyReferenceAllowable::ResizableArray", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "renderOnce": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "renderOnce": "Bool::DisplayNameAnnotation::LinkEndAnnotation", "renderOrder": "Int::DisplayNameAnnotation::LinkEndAnnotation", - "target": "RenderTarget::DisplayNameAnnotation::EmptyReferenceAllowable" + "target": "RenderTargetBase::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "RenderTarget": { - "buffer0": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer1": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer2": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer3": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer4": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer5": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer6": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer7": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS0": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS1": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS2": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS3": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS4": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS5": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS6": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS7": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "buffers": "Array[RenderBuffer]::DisplayNameAnnotation::EmptyReferenceAllowable::ResizableArray", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderTargetMS": { + "buffers": "Array[RenderBufferMS]::DisplayNameAnnotation::EmptyReferenceAllowable::ResizableArray", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", - "objectName": "String::DisplayNameAnnotation" + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Skin": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "joints": "Table::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "joints": "Array[Node]::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "skinIndex": "Int::DisplayNameAnnotation", - "targets": "Table::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "targets": "Array[MeshNode]::DisplayNameAnnotation::ResizableArray", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Texture": { "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "flipTexture": "Bool::DisplayNameAnnotation", "generateMipmaps": "Bool::DisplayNameAnnotation", "level2uri": "String::URIAnnotation::DisplayNameAnnotation", "level3uri": "String::URIAnnotation::DisplayNameAnnotation", "level4uri": "String::URIAnnotation::DisplayNameAnnotation", "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" }, "TextureExternal": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", "objectID": "String::HiddenProperty", - "objectName": "String::DisplayNameAnnotation" + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Timer": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "inputs": "TimerInput::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "outputs": "TimerOutput::DisplayNameAnnotation" + "outputs": "TimerOutput::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" } } } diff --git a/doc/basics/multisampling/shaders/multisampler.frag b/doc/basics/multisampling/shaders/multisampler.frag index ff8ac91a..3f0002ed 100644 --- a/doc/basics/multisampling/shaders/multisampler.frag +++ b/doc/basics/multisampling/shaders/multisampler.frag @@ -4,7 +4,7 @@ precision highp float; uniform highp sampler2DMS textureSampler; uniform highp int sampleCount; -in lowp vec2 v_TextureCoordinate; +in highp vec2 v_TextureCoordinate; out vec4 fragColor; void main(void) diff --git a/doc/debugging/profiling/README.md b/doc/debugging/profiling/README.md index 69b61e17..e7d907b8 100644 --- a/doc/debugging/profiling/README.md +++ b/doc/debugging/profiling/README.md @@ -50,7 +50,7 @@ the Graphics memory section can provide a hint towards the video memory required Most hardware vendors provide specialized tools for GPU Debugging and profiling. To list a few examples: * [NVidia NSight](https://developer.nvidia.com/nsight-graphics) -* [Intel GPA](https://www.intel.com/content/www/us/en/developer/tools/graphics-performance-analyzers/download.html) * [Snapdragon profiler](https://developer.qualcomm.com/software/snapdragon-profiler) +* Intel GPA Those tools are very powerful and usually give device-specific hints about optimization potentials in your app. diff --git a/doc/debugging/versions/README.md b/doc/debugging/versions/README.md index 111cc6f3..80e937c2 100644 --- a/doc/debugging/versions/README.md +++ b/doc/debugging/versions/README.md @@ -17,7 +17,7 @@ We also mention changes to the shipped library versions in the CHANGELOG file in For a comprehensive list of the Ramses Toolchain releases (of which the Ramses Composer is a part of) alongside upgrade hints and future plans, please refer to the -[Ramses SDK docs](https://ramses-sdk.readthedocs.io/en/latest/versions.html). +[Ramses SDK docs](https://ramses-sdk.readthedocs.io/en/latest/). ## Switching to a newer version of the Composer (Project files) diff --git a/gui/libCommonWidgets/include/common_widgets/DebugLayout.h b/gui/libCommonWidgets/include/common_widgets/DebugLayout.h index 9fdb2fa3..03675d61 100644 --- a/gui/libCommonWidgets/include/common_widgets/DebugLayout.h +++ b/gui/libCommonWidgets/include/common_widgets/DebugLayout.h @@ -32,14 +32,14 @@ inline std::string tabs(size_t amount) { inline void dumpLayoutInfo(const QWidget* widget, size_t depth = 0) { if (widget->inherits("QLabel")) { - LOG_DEBUG(raco::log_system::DUMP, "{}{}: \"{}\" geometry: {} sizeHint: {}", tabs(depth).c_str(), "QLabel", (qobject_cast(widget))->text().toStdString(), widget->geometry(), widget->sizeHint()); + LOG_DEBUG(log_system::DUMP, "{}{}: \"{}\" geometry: {} sizeHint: {}", tabs(depth).c_str(), "QLabel", (qobject_cast(widget))->text().toStdString(), widget->geometry(), widget->sizeHint()); } else if (widget->inherits("QPushButton")) { - LOG_DEBUG(raco::log_system::DUMP, "{}{}: \"{}\" geometry: {} sizeHint: {}", tabs(depth).c_str(), "QPushButton", (qobject_cast(widget))->text().toStdString(), widget->geometry(), widget->sizeHint()); + LOG_DEBUG(log_system::DUMP, "{}{}: \"{}\" geometry: {} sizeHint: {}", tabs(depth).c_str(), "QPushButton", (qobject_cast(widget))->text().toStdString(), widget->geometry(), widget->sizeHint()); } else { - LOG_DEBUG(raco::log_system::DUMP, "{}{}:{} geometry: {} sizeHint: {}", tabs(depth).c_str(), widget->metaObject()->className(), widget->objectName(), widget->geometry(), widget->sizeHint()); + LOG_DEBUG(log_system::DUMP, "{}{}:{} geometry: {} sizeHint: {}", tabs(depth).c_str(), widget->metaObject()->className(), widget->objectName(), widget->geometry(), widget->sizeHint()); } if (widget->layout()) { - LOG_DEBUG(raco::log_system::DUMP, "{}layout -> contentsMargins: {}", tabs(depth).c_str(), widget->layout()->contentsMargins()); + LOG_DEBUG(log_system::DUMP, "{}layout -> contentsMargins: {}", tabs(depth).c_str(), widget->layout()->contentsMargins()); } for (const auto& child : widget->findChildren(QString{}, Qt::FindDirectChildrenOnly)) { dumpLayoutInfo(child, depth + 1); diff --git a/gui/libCommonWidgets/include/common_widgets/ErrorView.h b/gui/libCommonWidgets/include/common_widgets/ErrorView.h index 2934fa29..e8e8c1b3 100644 --- a/gui/libCommonWidgets/include/common_widgets/ErrorView.h +++ b/gui/libCommonWidgets/include/common_widgets/ErrorView.h @@ -40,7 +40,7 @@ class ErrorView : public QWidget { COLUMN_COUNT }; - ErrorView(raco::core::CommandInterface *commandInterface, raco::components::SDataChangeDispatcher dispatcher, bool embeddedInExportView, LogViewModel *logViewModel, QWidget *parent = nullptr); + ErrorView(core::CommandInterface *commandInterface, components::SDataChangeDispatcher dispatcher, bool embeddedInExportView, LogViewModel *logViewModel, QWidget *parent = nullptr); Q_SIGNALS: void objectSelectionRequested(const QString &objectID); @@ -52,7 +52,7 @@ class ErrorView : public QWidget { void filterRows(); void regenerateTable(); - raco::core::CommandInterface *commandInterface_; + core::CommandInterface *commandInterface_; components::Subscription errorChangeSubscription_; components::Subscription objNameChangeSubscription_; components::Subscription objChildrenChangeSubscription_; diff --git a/gui/libCommonWidgets/include/common_widgets/ExportDialog.h b/gui/libCommonWidgets/include/common_widgets/ExportDialog.h index 9fb4d94f..50cf300a 100644 --- a/gui/libCommonWidgets/include/common_widgets/ExportDialog.h +++ b/gui/libCommonWidgets/include/common_widgets/ExportDialog.h @@ -34,7 +34,6 @@ class ExportDialog final : public QDialog { QGridLayout* optionLayout_; QCheckBox* compressEdit_; QLineEdit* ramsesEdit_; - QLineEdit* logicEdit_; QDialogButtonBox* buttonBox_; QComboBox* luaSavingModeCombo_; diff --git a/gui/libCommonWidgets/include/common_widgets/MeshAssetImportDialog.h b/gui/libCommonWidgets/include/common_widgets/MeshAssetImportDialog.h index 8629bac2..808d148b 100644 --- a/gui/libCommonWidgets/include/common_widgets/MeshAssetImportDialog.h +++ b/gui/libCommonWidgets/include/common_widgets/MeshAssetImportDialog.h @@ -25,7 +25,7 @@ namespace raco::common_widgets { class MeshAssetImportDialog final : public QDialog { public: - explicit MeshAssetImportDialog(raco::core::MeshScenegraph& sceneGraph, int projectFeatureLevel, QString fileName, QWidget* parent = nullptr); + explicit MeshAssetImportDialog(core::MeshScenegraph& sceneGraph, QString fileName, QWidget* parent = nullptr); QGridLayout* layout_; QTreeWidget* widget_; @@ -39,7 +39,7 @@ class MeshAssetImportDialog final : public QDialog { void applyChangesToScenegraph(); void checkAll(Qt::CheckState state); - raco::core::MeshScenegraph& sceneGraph_; + core::MeshScenegraph& sceneGraph_; std::vector nodeTreeList_; std::map>*> widgetItemToSubmeshIndexMap_; std::map primitiveToMeshIndexMap_; diff --git a/gui/libCommonWidgets/include/common_widgets/TracePlayerWidget.h b/gui/libCommonWidgets/include/common_widgets/TracePlayerWidget.h index 3dff3eae..cb87faa8 100644 --- a/gui/libCommonWidgets/include/common_widgets/TracePlayerWidget.h +++ b/gui/libCommonWidgets/include/common_widgets/TracePlayerWidget.h @@ -49,7 +49,7 @@ class TracePlayerWidget : public QWidget { TracePlayerWidget& operator=(const TracePlayerWidget&) = delete; TracePlayerWidget(const TracePlayerWidget&&) = delete; TracePlayerWidget& operator=(const TracePlayerWidget&&) = delete; - TracePlayerWidget(const QString& widgetName, raco::components::TracePlayer* tracePlayer); + TracePlayerWidget(const QString& widgetName, components::TracePlayer* tracePlayer); protected: bool eventFilter(QObject* object, QEvent* event) override; @@ -75,10 +75,10 @@ class TracePlayerWidget : public QWidget { void clearLog(); void reportLog(const std::vector& tracePlayerReport, core::ErrorLevel highestCriticality, bool widgetMsg = false); void logCleared(); - void stateChanged(raco::components::TracePlayer::PlayerState state); + void stateChanged(components::TracePlayer::PlayerState state); void loopClicked(); - raco::components::TracePlayer* tracePlayer_{nullptr}; + components::TracePlayer* tracePlayer_{nullptr}; QString defaultDir_{}; /// UI Controls QGridLayout* layout_{nullptr}; diff --git a/gui/libCommonWidgets/include/common_widgets/UndoView.h b/gui/libCommonWidgets/include/common_widgets/UndoView.h index ab6d6011..33f5f39b 100644 --- a/gui/libCommonWidgets/include/common_widgets/UndoView.h +++ b/gui/libCommonWidgets/include/common_widgets/UndoView.h @@ -20,14 +20,14 @@ namespace raco::common_widgets { class UndoView : public QWidget { public: - explicit UndoView(raco::core::UndoStack* undoStack, raco::components::SDataChangeDispatcher dispatcher, QWidget* parent); + explicit UndoView(core::UndoStack* undoStack, components::SDataChangeDispatcher dispatcher, QWidget* parent); protected: void rebuild(); private: - raco::components::Subscription sub_; - raco::core::UndoStack* undoStack_; + components::Subscription sub_; + core::UndoStack* undoStack_; QListView* list_; QStandardItemModel* model_; }; diff --git a/gui/libCommonWidgets/src/ErrorView.cpp b/gui/libCommonWidgets/src/ErrorView.cpp index ae81feb3..eacd88fb 100644 --- a/gui/libCommonWidgets/src/ErrorView.cpp +++ b/gui/libCommonWidgets/src/ErrorView.cpp @@ -32,17 +32,19 @@ namespace { +using namespace raco; + inline const int extRefProjectIdUserRole = Qt::UserRole; -QString errorLevelToString(const raco::core::ErrorLevel &level) { +QString errorLevelToString(const core::ErrorLevel &level) { switch (level) { - case raco::core::ErrorLevel::NONE: + case core::ErrorLevel::NONE: return "None"; - case raco::core::ErrorLevel::INFORMATION: + case core::ErrorLevel::INFORMATION: return "Information"; - case raco::core::ErrorLevel::WARNING: + case core::ErrorLevel::WARNING: return "Warning"; - case raco::core::ErrorLevel::ERROR: + case core::ErrorLevel::ERROR: return "Error"; default: assert(false && "Unknown error level detected when trying to regenerate Error View"); @@ -59,15 +61,15 @@ class ErrorViewModel : public QStandardItemModel { auto column = index.column(); if (role == Qt::ForegroundRole) { if (QStandardItemModel::data(index, extRefProjectIdUserRole).isValid()) { - if (column == raco::common_widgets::ErrorView::ErrorViewColumns::OBJECT) { - return raco::style::Colors::color(raco::style::Colormap::externalReference); + if (column == common_widgets::ErrorView::ErrorViewColumns::OBJECT) { + return style::Colors::color(style::Colormap::externalReference); } } } auto originalData = QStandardItemModel::data(index, role); - if (column == raco::common_widgets::ErrorView::ErrorViewColumns::MESSAGE && role == Qt::DisplayRole) { + if (column == common_widgets::ErrorView::ErrorViewColumns::MESSAGE && role == Qt::DisplayRole) { // no multi-line error messages in Error View. return originalData.toString().replace('\n', ' '); } @@ -81,7 +83,7 @@ class ErrorViewModel : public QStandardItemModel { namespace raco::common_widgets { -ErrorView::ErrorView(raco::core::CommandInterface* commandInterface, raco::components::SDataChangeDispatcher dispatcher, bool embeddedInExportView, LogViewModel* logViewModel, QWidget* parent) : +ErrorView::ErrorView(core::CommandInterface* commandInterface, components::SDataChangeDispatcher dispatcher, bool embeddedInExportView, LogViewModel* logViewModel, QWidget* parent) : QWidget{parent}, commandInterface_{commandInterface}, logViewModel_(logViewModel), showFilterLayout_(!embeddedInExportView) { auto* errorViewLayout{new NoContentMarginsLayout{this}}; @@ -190,7 +192,7 @@ void ErrorView::filterRows() { auto warningsVisible = !showWarningsCheckBox_ || showWarningsCheckBox_->isChecked(); auto errorsVisible = !showErrorsCheckBox_ || showErrorsCheckBox_->isChecked(); auto extRefsVisible = !showExternalReferencesCheckBox_ || showExternalReferencesCheckBox_->isChecked(); - const auto WARNING = errorLevelToString(raco::core::ErrorLevel::WARNING); + const auto WARNING = errorLevelToString(core::ErrorLevel::WARNING); for (auto row = 0; row < tableModel_->rowCount(); ++row) { auto modelIndex = proxyModel_->mapToSource(proxyModel_->index(row, LEVEL)); diff --git a/gui/libCommonWidgets/src/ExportDialog.cpp b/gui/libCommonWidgets/src/ExportDialog.cpp index 5386fc03..ca6cd783 100644 --- a/gui/libCommonWidgets/src/ExportDialog.cpp +++ b/gui/libCommonWidgets/src/ExportDialog.cpp @@ -39,19 +39,21 @@ namespace { +using namespace raco; + const std::vector userTypesAllowedInSceneGraph { - raco::user_types::Node::typeDescription.typeName, - raco::user_types::MeshNode::typeDescription.typeName, - raco::user_types::Prefab::typeDescription.typeName, - raco::user_types::PrefabInstance::typeDescription.typeName, - raco::user_types::OrthographicCamera::typeDescription.typeName, - raco::user_types::PerspectiveCamera::typeDescription.typeName, -// raco::user_types::Animation::typeDescription.typeName, // Animations currently aren't properly parented inside the Scene Graph -// raco::user_types::LuaScript::typeDescription.typeName, // LuaScripts currently aren't properly parented inside the Scene Graph -// raco::user_types::LuaInterface::typeDescription.typeName // LuaInterfaces currently aren't properly parented inside the Scene Graph + user_types::Node::typeDescription.typeName, + user_types::MeshNode::typeDescription.typeName, + user_types::Prefab::typeDescription.typeName, + user_types::PrefabInstance::typeDescription.typeName, + user_types::OrthographicCamera::typeDescription.typeName, + user_types::PerspectiveCamera::typeDescription.typeName, +// user_types::Animation::typeDescription.typeName, // Animations currently aren't properly parented inside the Scene Graph +// user_types::LuaScript::typeDescription.typeName, // LuaScripts currently aren't properly parented inside the Scene Graph +// user_types::LuaInterface::typeDescription.typeName // LuaInterfaces currently aren't properly parented inside the Scene Graph }; -QStandardItemModel* createSummaryModel(const std::vector& sceneItems, QObject* parent) { +QStandardItemModel* createSummaryModel(const std::vector& sceneItems, QObject* parent) { auto* listViewModel = new QStandardItemModel{parent}; listViewModel->setColumnCount(2); listViewModel->setHorizontalHeaderItem(0, new QStandardItem{"Name"}); @@ -62,7 +64,7 @@ QStandardItemModel* createSummaryModel(const std::vectorappendRow(sceneGraphParent); listViewModel->appendRow(resourceParent); - std::map parents{}; + std::map parents{}; for (const auto& item : sceneItems) { using ItemList = QList; auto* col0 = new QStandardItem{QString::fromStdString(item.objectName_)}; @@ -101,15 +103,7 @@ ExportDialog::ExportDialog(application::RaCoApplication* application, LogViewMod auto* selectRamsesDirectoryButton = new PropertyBrowserButton(" ... ", this); contentLayout->addWidget(selectRamsesDirectoryButton, 0, 2); - setupFilePickerButton(selectRamsesDirectoryButton, ramsesEdit_, raco::names::FILE_EXTENSION_RAMSES_EXPORT); - - logicEdit_ = new QLineEdit(content); - contentLayout->addWidget(new QLabel{"Logic file:", content}, 1, 0); - contentLayout->addWidget(logicEdit_, 1, 1); - - auto* selectLogicDirectoryButton = new PropertyBrowserButton(" ... ", this); - contentLayout->addWidget(selectLogicDirectoryButton, 1, 2); - setupFilePickerButton(selectLogicDirectoryButton, logicEdit_, raco::names::FILE_EXTENSION_LOGIC_EXPORT); + setupFilePickerButton(selectRamsesDirectoryButton, ramsesEdit_, names::FILE_EXTENSION_RAMSES_EXPORT); compressEdit_ = new QCheckBox(content); contentLayout->addWidget(new QLabel{"Compress:", content}, 2, 0); @@ -118,24 +112,18 @@ ExportDialog::ExportDialog(application::RaCoApplication* application, LogViewMod contentLayout->addWidget(new QLabel{"Lua saving mode:", content}, 3, 0); luaSavingModeCombo_ = new QComboBox(content); - luaSavingModeCombo_->addItem("SourceCodeOnly", static_cast(raco::application::ELuaSavingMode::SourceCodeOnly)); - luaSavingModeCombo_->addItem("ByteCodeOnly", static_cast(raco::application::ELuaSavingMode::ByteCodeOnly)); - luaSavingModeCombo_->addItem("SourceAndByteCode", static_cast(raco::application::ELuaSavingMode::SourceAndByteCode)); + luaSavingModeCombo_->addItem("SourceCodeOnly", static_cast(application::ELuaSavingMode::SourceCodeOnly)); + luaSavingModeCombo_->addItem("ByteCodeOnly", static_cast(application::ELuaSavingMode::ByteCodeOnly)); + luaSavingModeCombo_->addItem("SourceAndByteCode", static_cast(application::ELuaSavingMode::SourceAndByteCode)); // SourceCodeOnly is default setting luaSavingModeCombo_->setCurrentIndex(0); contentLayout->addWidget(luaSavingModeCombo_, 3, 1); - if (application->activeRaCoProject().project()->featureLevel() < 2) { - luaSavingModeCombo_->setEnabled(false); - } - if (!application_->activeProjectPath().empty()) { - ramsesEdit_->setText(application_->activeRaCoProject().name() + "." + raco::names::FILE_EXTENSION_RAMSES_EXPORT); - logicEdit_->setText(application_->activeRaCoProject().name() + "." + raco::names::FILE_EXTENSION_LOGIC_EXPORT); + ramsesEdit_->setText(application_->activeRaCoProject().name() + "." + names::FILE_EXTENSION_RAMSES_EXPORT); } else { - auto currentPath = QString::fromStdString(raco::utils::u8path::current().string() + "/"); - ramsesEdit_->setText(currentPath + QString("unknown.").append(raco::names::FILE_EXTENSION_RAMSES_EXPORT)); - logicEdit_->setText(currentPath + QString("unknown.").append(raco::names::FILE_EXTENSION_LOGIC_EXPORT)); + auto currentPath = QString::fromStdString(utils::u8path::current().string() + "/"); + ramsesEdit_->setText(currentPath + QString("unknown.").append(names::FILE_EXTENSION_RAMSES_EXPORT)); } auto* summaryBox = new QGroupBox{"Summary", this}; @@ -163,21 +151,21 @@ ExportDialog::ExportDialog(application::RaCoApplication* application, LogViewMod tabWidget->addTab(sceneDescriptionView, QString{"Scene ID: %1"}.arg(application->sceneBackend()->currentSceneIdValue())); auto racoErrorLevel = application->activeRaCoProject().errors()->maxErrorLevel(); - bool showExportWithErrors = racoErrorLevel == raco::core::ErrorLevel::ERROR; - if (racoErrorLevel >= raco::core::ErrorLevel::WARNING) { + bool showExportWithErrors = racoErrorLevel == core::ErrorLevel::ERROR; + if (racoErrorLevel >= core::ErrorLevel::WARNING) { auto* commandInterface = application->activeRaCoProject().commandInterface(); auto* errorView = new ErrorView(commandInterface, application->dataChangeDispatcher(), true, logViewModel, this); - tabWidget->setCurrentIndex(tabWidget->addTab(errorView, racoErrorLevel == raco::core::ErrorLevel::ERROR ? "Composer Errors" : "Composer Warnings")); + tabWidget->setCurrentIndex(tabWidget->addTab(errorView, racoErrorLevel == core::ErrorLevel::ERROR ? "Composer Errors" : "Composer Warnings")); } - if (sceneStatus != raco::core::ErrorLevel::NONE) { + if (sceneStatus != core::ErrorLevel::NONE) { auto* textBox = new QTextEdit(summaryBox); textBox->setAcceptRichText(false); textBox->setText(QString::fromStdString(message)); showExportWithErrors = true; - tabWidget->setCurrentIndex(tabWidget->addTab(textBox, sceneStatus == raco::core::ErrorLevel::ERROR ? "Ramses Errors" : "Ramses Warnings")); + tabWidget->setCurrentIndex(tabWidget->addTab(textBox, sceneStatus == core::ErrorLevel::ERROR ? "Ramses Errors" : "Ramses Warnings")); } buttonBox_ = new QDialogButtonBox{QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this}; @@ -193,7 +181,6 @@ ExportDialog::ExportDialog(application::RaCoApplication* application, LogViewMod connect(buttonBox_, SIGNAL(rejected()), this, SLOT(reject())); QObject::connect(ramsesEdit_, &QLineEdit::textChanged, this, &ExportDialog::updatePaths); - QObject::connect(logicEdit_, &QLineEdit::textChanged, this, &ExportDialog::updatePaths); updatePaths(); buttonBox_->button(QDialogButtonBox::Ok)->setText(showExportWithErrors ? "Export (with errors)" : "Export"); @@ -202,16 +189,14 @@ ExportDialog::ExportDialog(application::RaCoApplication* application, LogViewMod void ExportDialog::exportProject() { auto ramsesFilePath = getAbsoluteExportFilePath(ramsesEdit_); - auto logicFilePath = getAbsoluteExportFilePath(logicEdit_); std::string error; if (application_->exportProject( ramsesFilePath.string(), - logicFilePath.string(), compressEdit_->isChecked(), error, true, - static_cast(luaSavingModeCombo_->currentData().toInt()))) { + static_cast(luaSavingModeCombo_->currentData().toInt()))) { accept(); } else { QMessageBox::critical( @@ -220,7 +205,7 @@ void ExportDialog::exportProject() { } utils::u8path ExportDialog::getAbsoluteExportFilePath(QLineEdit* path) { - auto dir = raco::utils::u8path(path->text().toStdString()); + auto dir = utils::u8path(path->text().toStdString()); if (dir.is_relative()) { if (!application_->activeProjectPath().empty()){ dir = dir.normalizedAbsolutePath(application_->activeProjectFolder()); @@ -234,14 +219,11 @@ void ExportDialog::updatePaths() { auto ramsesPath = getAbsoluteExportFilePath(ramsesEdit_); ramsesEdit_->setToolTip(QString::fromStdString(ramsesPath.string())); - auto logicPath = getAbsoluteExportFilePath(logicEdit_); - logicEdit_->setToolTip(QString::fromStdString(logicPath.string())); - updateButtonStates(); } void ExportDialog::updateButtonStates() { - const bool enableButton = !ramsesEdit_->text().isEmpty() && !logicEdit_->text().isEmpty(); + const bool enableButton = !ramsesEdit_->text().isEmpty(); buttonBox_->button(QDialogButtonBox::Ok)->setEnabled(enableButton); } @@ -254,7 +236,7 @@ void ExportDialog::setupFilePickerButton(PropertyBrowserButton* button, QLineEdi auto result = QFileDialog::getSaveFileName(this, caption, dir, filter); if (!result.isEmpty()) { if (!application_->activeProjectPath().empty()) { - auto newPath = raco::utils::u8path(result.toStdString()); + auto newPath = utils::u8path(result.toStdString()); auto projectFolder = application_->activeProjectFolder(); auto relativePath = newPath.normalizedRelativePath(projectFolder); pathEdit->setText(QString::fromStdString(relativePath.string())); diff --git a/gui/libCommonWidgets/src/LogView.cpp b/gui/libCommonWidgets/src/LogView.cpp index ccbb2490..98b08417 100644 --- a/gui/libCommonWidgets/src/LogView.cpp +++ b/gui/libCommonWidgets/src/LogView.cpp @@ -73,22 +73,22 @@ LogView::LogView(LogViewModel* model, QWidget* parent) : model_(model) { auto filterCategoryBox = new QComboBox(this); filterCategoryBox->addItem("All Categories", ""); - filterCategoryBox->addItem(raco::log_system::DEFAULT, raco::log_system::DEFAULT); - filterCategoryBox->addItem(raco::log_system::COMMON, raco::log_system::COMMON); - filterCategoryBox->addItem(raco::log_system::CONTEXT, raco::log_system::CONTEXT); - filterCategoryBox->addItem(raco::log_system::USER_TYPES, raco::log_system::USER_TYPES); - filterCategoryBox->addItem(raco::log_system::PROPERTY_BROWSER, raco::log_system::PROPERTY_BROWSER); - filterCategoryBox->addItem(raco::log_system::OBJECT_TREE_VIEW, raco::log_system::OBJECT_TREE_VIEW); - filterCategoryBox->addItem(raco::log_system::LOGGING, raco::log_system::LOGGING); - filterCategoryBox->addItem(raco::log_system::PREVIEW_WIDGET, raco::log_system::PREVIEW_WIDGET); - filterCategoryBox->addItem(raco::log_system::RAMSES_BACKEND, raco::log_system::RAMSES_BACKEND); - filterCategoryBox->addItem(raco::log_system::RAMSES_ADAPTOR, raco::log_system::RAMSES_ADAPTOR); - filterCategoryBox->addItem(raco::log_system::DESERIALIZATION, raco::log_system::DESERIALIZATION); - filterCategoryBox->addItem(raco::log_system::PROJECT, raco::log_system::PROJECT); - filterCategoryBox->addItem(raco::log_system::PYTHON, raco::log_system::PYTHON); - filterCategoryBox->addItem(raco::log_system::MESH_LOADER, raco::log_system::MESH_LOADER); - filterCategoryBox->addItem(raco::log_system::RAMSES, raco::log_system::RAMSES); - filterCategoryBox->addItem(raco::log_system::RAMSES_LOGIC, raco::log_system::RAMSES_LOGIC); + filterCategoryBox->addItem(log_system::DEFAULT, log_system::DEFAULT); + filterCategoryBox->addItem(log_system::COMMON, log_system::COMMON); + filterCategoryBox->addItem(log_system::CONTEXT, log_system::CONTEXT); + filterCategoryBox->addItem(log_system::USER_TYPES, log_system::USER_TYPES); + filterCategoryBox->addItem(log_system::PROPERTY_BROWSER, log_system::PROPERTY_BROWSER); + filterCategoryBox->addItem(log_system::OBJECT_TREE_VIEW, log_system::OBJECT_TREE_VIEW); + filterCategoryBox->addItem(log_system::LOGGING, log_system::LOGGING); + filterCategoryBox->addItem(log_system::PREVIEW_WIDGET, log_system::PREVIEW_WIDGET); + filterCategoryBox->addItem(log_system::RAMSES_BACKEND, log_system::RAMSES_BACKEND); + filterCategoryBox->addItem(log_system::RAMSES_ADAPTOR, log_system::RAMSES_ADAPTOR); + filterCategoryBox->addItem(log_system::DESERIALIZATION, log_system::DESERIALIZATION); + filterCategoryBox->addItem(log_system::PROJECT, log_system::PROJECT); + filterCategoryBox->addItem(log_system::PYTHON, log_system::PYTHON); + filterCategoryBox->addItem(log_system::MESH_LOADER, log_system::MESH_LOADER); + filterCategoryBox->addItem(log_system::RAMSES, log_system::RAMSES); + filterCategoryBox->addItem(log_system::RAMSES_LOGIC, log_system::RAMSES_LOGIC); QObject::connect(filterCategoryBox, qOverload(&QComboBox::activated), this, [this, filterCategoryBox](int index) { auto filter = filterCategoryBox->itemData(index, Qt::UserRole).toString(); proxyModel_->setFilterCategory(filter); diff --git a/gui/libCommonWidgets/src/MeshAssetImportDialog.cpp b/gui/libCommonWidgets/src/MeshAssetImportDialog.cpp index 7e3a01ea..b10d16ff 100644 --- a/gui/libCommonWidgets/src/MeshAssetImportDialog.cpp +++ b/gui/libCommonWidgets/src/MeshAssetImportDialog.cpp @@ -22,7 +22,7 @@ namespace raco::common_widgets { -MeshAssetImportDialog::MeshAssetImportDialog(raco::core::MeshScenegraph& sceneGraph, int projectFeatureLevel, QString fileName, QWidget* parent) +MeshAssetImportDialog::MeshAssetImportDialog(core::MeshScenegraph& sceneGraph, QString fileName, QWidget* parent) : sceneGraph_{sceneGraph}, nodeTreeList_{sceneGraph_.nodes.size()}, meshTreeList_{sceneGraph_.meshes.size()}, @@ -103,27 +103,27 @@ MeshAssetImportDialog::MeshAssetImportDialog(raco::core::MeshScenegraph& sceneGr for (auto i = 0; i < sceneGraph_.nodes.size(); ++i) { auto& node = sceneGraph_.nodes[i].value(); - auto& item = nodeTreeList_[i] = new QTreeWidgetItem({QString::fromStdString(node.name), QString::fromStdString((node.subMeshIndices.size() == 1) ? raco::user_types::MeshNode::typeDescription.typeName : raco::user_types::Node::typeDescription.typeName)}); + auto& item = nodeTreeList_[i] = new QTreeWidgetItem({QString::fromStdString(node.name), QString::fromStdString((node.subMeshIndices.size() == 1) ? user_types::MeshNode::typeDescription.typeName : user_types::Node::typeDescription.typeName)}); widgetItemToSubmeshIndexMap_[item] = &node.subMeshIndices; - item->setIcon(0, node.subMeshIndices.size() == 1 ? raco::style::Icons::instance().typeMesh : raco::style::Icons::instance().typeNode); + item->setIcon(0, node.subMeshIndices.size() == 1 ? style::Icons::instance().typeMesh : style::Icons::instance().typeNode); item->setCheckState(0, Qt::CheckState::Checked); - if (node.parentIndex == raco::core::MeshScenegraphNode::NO_PARENT) { + if (node.parentIndex == core::MeshScenegraphNode::NO_PARENT) { sceneGraphRootItem->addChild(item); } // Handle edge case of a node containing multiple primitives: // We currently split those into separate MeshNodes under a singular, separate Node if (node.subMeshIndices.size() > 1) { - auto primitiveParent = new QTreeWidgetItem({QString::fromStdString(fmt::format("{}_meshnodes", node.name)), QString::fromStdString(raco::user_types::Node::typeDescription.typeName)}); - primitiveParent->setIcon(0, raco::style::Icons::instance().typeNode); + auto primitiveParent = new QTreeWidgetItem({QString::fromStdString(fmt::format("{}_meshnodes", node.name)), QString::fromStdString(user_types::Node::typeDescription.typeName)}); + primitiveParent->setIcon(0, style::Icons::instance().typeNode); primitiveParent->setCheckState(0, Qt::CheckState::Checked); item->addChild(primitiveParent); // first element in primitive tree list is the aforementioned singular Node (primitive parent) nodeToPrimitiveTreeList_[i].emplace_back(primitiveParent); for (auto primitiveIndex = 0; primitiveIndex < node.subMeshIndices.size(); ++primitiveIndex) { - auto* primitive = new QTreeWidgetItem({QString::fromStdString(fmt::format("{}_meshnode_{}", node.name, primitiveIndex)), QString::fromStdString(raco::user_types::MeshNode::typeDescription.typeName)}); - primitive->setIcon(0, raco::style::Icons::instance().typeMesh); + auto* primitive = new QTreeWidgetItem({QString::fromStdString(fmt::format("{}_meshnode_{}", node.name, primitiveIndex)), QString::fromStdString(user_types::MeshNode::typeDescription.typeName)}); + primitive->setIcon(0, style::Icons::instance().typeMesh); primitive->setCheckState(0, Qt::CheckState::Checked); nodeToPrimitiveTreeList_[i].emplace_back(primitive); primitiveToMeshIndexMap_[primitive] = *node.subMeshIndices[primitiveIndex]; @@ -137,7 +137,7 @@ MeshAssetImportDialog::MeshAssetImportDialog(raco::core::MeshScenegraph& sceneGr for (auto i = 0; i < sceneGraph_.nodes.size(); ++i) { auto& node = sceneGraph_.nodes[i].value(); - if (node.parentIndex != raco::core::MeshScenegraphNode::NO_PARENT) { + if (node.parentIndex != core::MeshScenegraphNode::NO_PARENT) { auto* child = nodeTreeList_[i]; nodeTreeList_[node.parentIndex]->addChild(child); } @@ -145,38 +145,37 @@ MeshAssetImportDialog::MeshAssetImportDialog(raco::core::MeshScenegraph& sceneGr for (auto i = 0; i < sceneGraph_.meshes.size(); ++i) { auto& mesh = sceneGraph_.meshes[i].value(); - auto item = meshTreeList_[i] = new QTreeWidgetItem({QString::fromStdString(mesh), QString::fromStdString(raco::user_types::Mesh::typeDescription.typeName)}); - item->setIcon(0, raco::style::Icons::instance().typeMesh); + auto item = meshTreeList_[i] = new QTreeWidgetItem({QString::fromStdString(mesh), QString::fromStdString(user_types::Mesh::typeDescription.typeName)}); + item->setIcon(0, style::Icons::instance().typeMesh); item->setCheckState(0, Qt::CheckState::Checked); resourcesRootItem->addChild(item); } for (auto animIndex = 0; animIndex < sceneGraph_.animations.size(); ++animIndex) { auto& anim = sceneGraph_.animations[animIndex].value(); - auto animItem = animTreeList_[animIndex] = new QTreeWidgetItem({QString::fromStdString(anim.name), QString::fromStdString(raco::user_types::Animation::typeDescription.typeName)}); - animItem->setIcon(0, raco::style::Icons::instance().typeAnimation); + auto animItem = animTreeList_[animIndex] = new QTreeWidgetItem({QString::fromStdString(anim.name), QString::fromStdString(user_types::Animation::typeDescription.typeName)}); + animItem->setIcon(0, style::Icons::instance().typeAnimation); animItem->setCheckState(0, Qt::CheckState::Checked); resourcesRootItem->addChild(animItem); for (auto samplerIndex = 0; samplerIndex < sceneGraph_.animationSamplers[animIndex].size(); ++samplerIndex) { auto& sampler = sceneGraph_.animationSamplers[animIndex][samplerIndex]; - auto sampItem = new QTreeWidgetItem({QString::fromStdString(*sampler), QString::fromStdString(raco::user_types::AnimationChannel::typeDescription.typeName)}); + auto sampItem = new QTreeWidgetItem({QString::fromStdString(*sampler), QString::fromStdString(user_types::AnimationChannel::typeDescription.typeName)}); animSamplerItemMap_[animIndex].emplace_back(sampItem); - sampItem->setIcon(0, raco::style::Icons::instance().typeAnimationChannel); + sampItem->setIcon(0, style::Icons::instance().typeAnimationChannel); sampItem->setCheckState(0, Qt::CheckState::Checked); resourcesRootItem->addChild(sampItem); } } - if (projectFeatureLevel >= user_types::Skin::typeDescription.featureLevel) { - for (auto index = 0; index < sceneGraph_.skins.size(); index++) { - const auto& skin = sceneGraph_.skins[index].value(); - auto item = new QTreeWidgetItem({QString::fromStdString(skin.name), QString::fromStdString(raco::user_types::Skin::typeDescription.typeName)}); - skinTreeList_.emplace_back(item); - item->setCheckState(0, Qt::CheckState::Checked); - resourcesRootItem->addChild(item); - } + for (auto index = 0; index < sceneGraph_.skins.size(); index++) { + const auto& skin = sceneGraph_.skins[index].value(); + auto item = new QTreeWidgetItem({QString::fromStdString(skin.name), QString::fromStdString(user_types::Skin::typeDescription.typeName)}); + skinTreeList_.emplace_back(item); + item->setCheckState(0, Qt::CheckState::Checked); + resourcesRootItem->addChild(item); } + sceneGraphRootItem->setExpanded(true); resourcesRootItem->setExpanded(true); } diff --git a/gui/libCommonWidgets/src/PreferencesView.cpp b/gui/libCommonWidgets/src/PreferencesView.cpp index 0fbce64e..104c3894 100644 --- a/gui/libCommonWidgets/src/PreferencesView.cpp +++ b/gui/libCommonWidgets/src/PreferencesView.cpp @@ -29,7 +29,7 @@ namespace raco::common_widgets { -using RaCoPreferences = raco::components::RaCoPreferences; +using RaCoPreferences = components::RaCoPreferences; PreferencesView::PreferencesView(QWidget* parent) : QDialog{parent} { auto layout = new QVBoxLayout{this}; @@ -63,9 +63,9 @@ PreferencesView::PreferencesView(QWidget* parent) : QDialog{parent} { } featureLevelEdit_ = new QSpinBox(this); - featureLevelEdit_->setRange(raco::application::RaCoApplication::minFeatureLevel(), raco::application::RaCoApplication::maxFeatureLevel()); + featureLevelEdit_->setRange(application::RaCoApplication::minFeatureLevel(), application::RaCoApplication::maxFeatureLevel()); featureLevelEdit_->setValue(RaCoPreferences::instance().featureLevel); - featureLevelEdit_->setToolTip(QString::fromStdString(raco::application::RaCoApplication::featureLevelDescriptions())); + featureLevelEdit_->setToolTip(QString::fromStdString(application::RaCoApplication::featureLevelDescriptions())); formLayout->addRow("New Project Feature Level", featureLevelEdit_); QObject::connect(featureLevelEdit_, QOverload::of(&QSpinBox::valueChanged), this, [this]() { @@ -121,7 +121,7 @@ PreferencesView::PreferencesView(QWidget* parent) : QDialog{parent} { auto cancelButton{new QPushButton{"Close", buttonBox}}; QObject::connect(cancelButton, &QPushButton::clicked, this, &PreferencesView::close); auto saveButton{new QPushButton{"Save", buttonBox}}; - saveButton->setDisabled(raco::utils::u8path(RaCoPreferences::instance().userProjectsDirectory.toStdString()).existsDirectory()); + saveButton->setDisabled(utils::u8path(RaCoPreferences::instance().userProjectsDirectory.toStdString()).existsDirectory()); QObject::connect(this, &PreferencesView::dirtyChanged, saveButton, &QPushButton::setEnabled); QObject::connect(saveButton, &QPushButton::clicked, this, &PreferencesView::save); buttonBox->addButton(cancelButton, QDialogButtonBox::RejectRole); @@ -130,7 +130,7 @@ PreferencesView::PreferencesView(QWidget* parent) : QDialog{parent} { } void PreferencesView::save() { - auto newUserProjectPath = raco::utils::u8path(userProjectEdit_->text().toStdString()); + auto newUserProjectPath = utils::u8path(userProjectEdit_->text().toStdString()); auto newUserProjectPathString = QString::fromStdString(newUserProjectPath.string()); if (!newUserProjectPath.existsDirectory()) { @@ -158,8 +158,8 @@ void PreferencesView::save() { prefs.screenshotDirectory = screenshotDirectoryEdit_->text(); if (!prefs.save()) { - LOG_ERROR(raco::log_system::COMMON, "Saving settings failed: {}", raco::core::PathManager::preferenceFilePath().string()); - QMessageBox::critical(this, "Saving settings failed", QString("Settings could not be saved. Check whether the application can write to its config directory.\nFile: ") + QString::fromStdString(raco::core::PathManager::preferenceFilePath().string())); + LOG_ERROR(log_system::COMMON, "Saving settings failed: {}", core::PathManager::preferenceFilePath().string()); + QMessageBox::critical(this, "Saving settings failed", QString("Settings could not be saved. Check whether the application can write to its config directory.\nFile: ") + QString::fromStdString(core::PathManager::preferenceFilePath().string())); } Q_EMIT dirtyChanged(false); diff --git a/gui/libCommonWidgets/src/RunScriptDialog.cpp b/gui/libCommonWidgets/src/RunScriptDialog.cpp index 6718e61e..07ebe81a 100644 --- a/gui/libCommonWidgets/src/RunScriptDialog.cpp +++ b/gui/libCommonWidgets/src/RunScriptDialog.cpp @@ -46,14 +46,14 @@ RunScriptDialog::RunScriptDialog(std::map& scriptEntries, std:: QObject::connect(scriptPathURIButton_, &QPushButton::clicked, [this]() { auto pythonPath = scriptPathEdit_->currentText(); if (pythonPath.isEmpty()) { - auto cachedScriptPath = raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Script, pythonPath.toStdString()); + auto cachedScriptPath = core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Script, pythonPath.toStdString()); pythonPath = QString::fromStdString(cachedScriptPath.string()); } auto pythonScriptPath = QFileDialog::getOpenFileName(this, "Open Python Script", pythonPath, "Python Scripts (*.py);; All files (*.*)"); if (!pythonScriptPath.isEmpty()) { scriptPathEdit_->setCurrentText(pythonScriptPath); - raco::core::PathManager::setCachedPath(raco::core::PathManager::FolderTypeKeys::Script, QFileInfo(pythonScriptPath).absoluteDir().absolutePath().toStdString()); + core::PathManager::setCachedPath(core::PathManager::FolderTypeKeys::Script, QFileInfo(pythonScriptPath).absoluteDir().absolutePath().toStdString()); } }); @@ -84,7 +84,7 @@ RunScriptDialog::RunScriptDialog(std::map& scriptEntries, std:: void RunScriptDialog::addPythonOutput(const std::string& outBuffer, const std::string& errorBuffer) { auto launchTime = QDateTime::currentDateTime(); - statusTextBlock_->appendHtml(QString("===== SCRIPT RUN AT %2 =====
").arg(raco::style::Colors::color(raco::style::Colormap::externalReference).name()).arg(launchTime.toString("hh:mm:ss.zzz"))); + statusTextBlock_->appendHtml(QString("===== SCRIPT RUN AT %2 =====
").arg(style::Colors::color(style::Colormap::externalReference).name()).arg(launchTime.toString("hh:mm:ss.zzz"))); auto vbar = statusTextBlock_->verticalScrollBar(); auto atBottom = vbar->value() == vbar->maximum(); @@ -98,9 +98,9 @@ void RunScriptDialog::addPythonOutput(const std::string& outBuffer, const std::s } if (!errorBuffer.empty()) { - statusTextBlock_->appendHtml(QString("%2
").arg(raco::style::Colors::color(raco::style::Colormap::errorColorLight).name()).arg(QString::fromStdString(errorBuffer).toHtmlEscaped())); + statusTextBlock_->appendHtml(QString("%2
").arg(style::Colors::color(style::Colormap::errorColorLight).name()).arg(QString::fromStdString(errorBuffer).toHtmlEscaped())); } - statusTextBlock_->appendHtml(QString("===== SCRIPT RUN AT %2 FINISHED =====
").arg(raco::style::Colors::color(raco::style::Colormap::externalReference).name()).arg(launchTime.toString("hh:mm:ss.zzz"))); + statusTextBlock_->appendHtml(QString("===== SCRIPT RUN AT %2 FINISHED =====
").arg(style::Colors::color(style::Colormap::externalReference).name()).arg(launchTime.toString("hh:mm:ss.zzz"))); } void RunScriptDialog::setScriptIsRunning(bool isRunning) { diff --git a/gui/libCommonWidgets/src/TracePlayerWidget.cpp b/gui/libCommonWidgets/src/TracePlayerWidget.cpp index 744f64ac..bf728e22 100644 --- a/gui/libCommonWidgets/src/TracePlayerWidget.cpp +++ b/gui/libCommonWidgets/src/TracePlayerWidget.cpp @@ -57,11 +57,11 @@ constexpr int STEP_DEFAULT{1}; namespace raco::common_widgets { -TracePlayerWidget::TracePlayerWidget(const QString& widgetName, raco::components::TracePlayer* tracePlayer) +TracePlayerWidget::TracePlayerWidget(const QString& widgetName, components::TracePlayer* tracePlayer) : tracePlayer_(tracePlayer), - defaultDir_(QString::fromStdString(raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Project).string())) { + defaultDir_(QString::fromStdString(core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Project).string())) { tracePlayer_->setCallbacks( - [this](raco::components::TracePlayer::PlayerState s) { stateChanged(s); }, + [this](components::TracePlayer::PlayerState s) { stateChanged(s); }, [this](int index) { updateCtrls(index); }, [this](std::vector log, core::ErrorLevel c) { reportLog(log, c); }); configCtrls(); @@ -90,19 +90,19 @@ void TracePlayerWidget::configCtrls() { fileNameLineEdt_->setPlaceholderText("trace file absolute path"); browseBtn_ = new QPushButton(this); - browseBtn_->setIcon(raco::style::Icons::instance().browse); + browseBtn_->setIcon(style::Icons::instance().browse); browseBtn_->setToolTip("Browse"); reloadBtn_ = new QPushButton(this); - reloadBtn_->setIcon(raco::style::Icons::instance().refresh); + reloadBtn_->setIcon(style::Icons::instance().refresh); reloadBtn_->setToolTip("Reload"); editBtn_ = new QPushButton(this); - editBtn_->setIcon(raco::style::Icons::instance().openInNew); + editBtn_->setIcon(style::Icons::instance().openInNew); editBtn_->setToolTip("Edit"); loopBtn_ = new QPushButton(this); - loopBtn_->setIcon(raco::style::Icons::instance().loopingInactive); + loopBtn_->setIcon(style::Icons::instance().loopingInactive); loopBtn_->setToolTip("Loop playback"); statusIndicator_ = new QLabel(this); @@ -127,23 +127,23 @@ void TracePlayerWidget::configCtrls() { " (" + QString::number(SPEED_SINGLE_STEP) + ")"); playBtn_ = new QPushButton(this); - playBtn_->setIcon(raco::style::Icons::instance().playInactive); + playBtn_->setIcon(style::Icons::instance().playInactive); playBtn_->setToolTip("Play"); pauseBtn_ = new QPushButton(this); - pauseBtn_->setIcon(raco::style::Icons::instance().pauseInactive); + pauseBtn_->setIcon(style::Icons::instance().pauseInactive); pauseBtn_->setToolTip("Pause"); stopBtn_ = new QPushButton(this); - stopBtn_->setIcon(raco::style::Icons::instance().stopInactive); + stopBtn_->setIcon(style::Icons::instance().stopInactive); stopBtn_->setToolTip("Stop"); stepForwardBtn_ = new QPushButton(this); - stepForwardBtn_->setIcon(raco::style::Icons::instance().skipNext); + stepForwardBtn_->setIcon(style::Icons::instance().skipNext); stepForwardBtn_->setToolTip("Step Forward"); stepBackwardBtn_ = new QPushButton(this); - stepBackwardBtn_->setIcon(raco::style::Icons::instance().skipPrevious); + stepBackwardBtn_->setIcon(style::Icons::instance().skipPrevious); stepBackwardBtn_->setToolTip("Step Backward"); stepSpin_ = new QSpinBox(this); @@ -246,12 +246,12 @@ void TracePlayerWidget::parseTraceFile() { jumpToSpin_->setRange(0, lastFrameIndex); timelineSlider_->setToolTip(QString::number(traceLen) + " frames"); jumpToSpin_->setToolTip(QString::number(0) + " ... " + QString::number(lastFrameIndex)); - reloadBtn_->setIcon(raco::style::Icons::instance().refresh); + reloadBtn_->setIcon(style::Icons::instance().refresh); loadedTraceFileChangeListener_ = loadedTraceFileChangeMonitor_.registerFileChangedHandler( filename, [this]() { reportLog({"Loaded trace file has been modified! Press Reload to reparse file."}, core::ErrorLevel::WARNING); - reloadBtn_->setIcon(raco::style::Icons::instance().refreshNeeded); }); + reloadBtn_->setIcon(style::Icons::instance().refreshNeeded); }); } else { /* do nothing */ } @@ -355,14 +355,14 @@ void TracePlayerWidget::reportLog(const std::vector& tracePlayerRep logCleared(); break; case core::ErrorLevel::INFORMATION: - statusIndicator_->setPixmap(raco::style::Icons::instance().info.pixmap(reloadBtn_->iconSize())); + statusIndicator_->setPixmap(style::Icons::instance().info.pixmap(reloadBtn_->iconSize())); break; case core::ErrorLevel::WARNING: - statusIndicator_->setPixmap(raco::style::Icons::instance().warning.pixmap(reloadBtn_->iconSize())); + statusIndicator_->setPixmap(style::Icons::instance().warning.pixmap(reloadBtn_->iconSize())); statusIndicator_->show(); break; case core::ErrorLevel::ERROR: - statusIndicator_->setPixmap(raco::style::Icons::instance().error.pixmap(reloadBtn_->iconSize())); + statusIndicator_->setPixmap(style::Icons::instance().error.pixmap(reloadBtn_->iconSize())); statusIndicator_->show(); break; default: @@ -388,25 +388,25 @@ void TracePlayerWidget::clearLog() { } } -void TracePlayerWidget::stateChanged(raco::components::TracePlayer::PlayerState state) { +void TracePlayerWidget::stateChanged(components::TracePlayer::PlayerState state) { enableCtrls(Ctrl::All); - playBtn_->setIcon(raco::style::Icons::instance().playInactive); - pauseBtn_->setIcon(raco::style::Icons::instance().pauseInactive); - stopBtn_->setIcon(raco::style::Icons::instance().stopInactive); + playBtn_->setIcon(style::Icons::instance().playInactive); + pauseBtn_->setIcon(style::Icons::instance().pauseInactive); + stopBtn_->setIcon(style::Icons::instance().stopInactive); switch (state) { - case raco::components::TracePlayer::PlayerState::Init: + case components::TracePlayer::PlayerState::Init: break; - case raco::components::TracePlayer::PlayerState::Faulty: + case components::TracePlayer::PlayerState::Faulty: enableCtrls(Ctrl::EditButton); break; - case raco::components::TracePlayer::PlayerState::Playing: - playBtn_->setIcon(raco::style::Icons::instance().playActive); + case components::TracePlayer::PlayerState::Playing: + playBtn_->setIcon(style::Icons::instance().playActive); break; - case raco::components::TracePlayer::PlayerState::Paused: - pauseBtn_->setIcon(raco::style::Icons::instance().pauseActive); + case components::TracePlayer::PlayerState::Paused: + pauseBtn_->setIcon(style::Icons::instance().pauseActive); break; - case raco::components::TracePlayer::PlayerState::Stopped: - stopBtn_->setIcon(raco::style::Icons::instance().stopActive); + case components::TracePlayer::PlayerState::Stopped: + stopBtn_->setIcon(style::Icons::instance().stopActive); updateCtrls(0); break; default: @@ -419,9 +419,9 @@ void TracePlayerWidget::loopClicked() { if (tracePlayer_) { tracePlayer_->toggleLooping(); if (tracePlayer_->getLoopingStatus()) { - loopBtn_->setIcon(raco::style::Icons::instance().loopingActive); + loopBtn_->setIcon(style::Icons::instance().loopingActive); } else { - loopBtn_->setIcon(raco::style::Icons::instance().loopingInactive); + loopBtn_->setIcon(style::Icons::instance().loopingInactive); } } } diff --git a/gui/libCommonWidgets/src/UndoView.cpp b/gui/libCommonWidgets/src/UndoView.cpp index bb9e2bda..cdb4507c 100644 --- a/gui/libCommonWidgets/src/UndoView.cpp +++ b/gui/libCommonWidgets/src/UndoView.cpp @@ -16,7 +16,7 @@ namespace raco::common_widgets { -UndoView::UndoView(raco::core::UndoStack* undoStack, raco::components::SDataChangeDispatcher dispatcher, QWidget* parent) : QWidget{parent}, undoStack_{undoStack}, sub_{dispatcher->registerOnUndoChanged([this]() { rebuild(); })} { +UndoView::UndoView(core::UndoStack* undoStack, components::SDataChangeDispatcher dispatcher, QWidget* parent) : QWidget{parent}, undoStack_{undoStack}, sub_{dispatcher->registerOnUndoChanged([this]() { rebuild(); })} { auto* layout{new NoContentMarginsLayout{this}}; list_ = new QListView{this}; model_ = new QStandardItemModel{list_}; diff --git a/gui/libCommonWidgets/tests/ErrorView_test.cpp b/gui/libCommonWidgets/tests/ErrorView_test.cpp index 700054af..dbbf3f62 100644 --- a/gui/libCommonWidgets/tests/ErrorView_test.cpp +++ b/gui/libCommonWidgets/tests/ErrorView_test.cpp @@ -12,8 +12,8 @@ #include "user_types/Node.h" TEST_F(ErrorViewTest, ErrorViewWorksWithObjectValueHandle) { - auto node = commandInterface.createObject(raco::user_types::Node::typeDescription.typeName); - commandInterface.errors().addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::ERROR, {node}, "Object Error"); + auto node = commandInterface.createObject(user_types::Node::typeDescription.typeName); + commandInterface.errors().addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, {node}, "Object Error"); dataChangeDispatcher_->dispatch(recorder); // no crash ASSERT_EQ(commandInterface.errors().getAllErrors().size(), 1); @@ -24,24 +24,24 @@ TEST_F(ErrorViewTest, ErrorViewWorksWithObjectValueHandle) { } TEST_F(ErrorViewTest, ErrorViewWorksWithPropertyValueHandle) { - auto node = commandInterface.createObject(raco::user_types::Node::typeDescription.typeName); - commandInterface.errors().addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::ERROR, raco::core::ValueHandle{node}.get("rotation"), "Property Error"); + auto node = commandInterface.createObject(user_types::Node::typeDescription.typeName); + commandInterface.errors().addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, core::ValueHandle{node}.get("rotation"), "Property Error"); dataChangeDispatcher_->dispatch(recorder); // no crash ASSERT_EQ(commandInterface.errors().getAllErrors().size(), 1); - commandInterface.errors().removeError(raco::core::ValueHandle{node}.get("rotation")); + commandInterface.errors().removeError(core::ValueHandle{node}.get("rotation")); dataChangeDispatcher_->dispatch(recorder); ASSERT_TRUE(commandInterface.errors().getAllErrors().empty()); } TEST_F(ErrorViewTest, ErrorViewWorksWithProjectGlobalValueHandle) { - commandInterface.errors().addError(raco::core::ErrorCategory::GENERAL, raco::core::ErrorLevel::ERROR, raco::core::ValueHandle{}, "Project-Global Error"); + commandInterface.errors().addError(core::ErrorCategory::GENERAL, core::ErrorLevel::ERROR, core::ValueHandle{}, "Project-Global Error"); dataChangeDispatcher_->dispatch(recorder); // no crash ASSERT_EQ(commandInterface.errors().getAllErrors().size(), 1); - commandInterface.errors().removeError(raco::core::ValueHandle{}); + commandInterface.errors().removeError(core::ValueHandle{}); dataChangeDispatcher_->dispatch(recorder); ASSERT_TRUE(commandInterface.errors().getAllErrors().empty()); } \ No newline at end of file diff --git a/gui/libCommonWidgets/tests/ErrorView_test.h b/gui/libCommonWidgets/tests/ErrorView_test.h index 8f86e12c..08eb7414 100644 --- a/gui/libCommonWidgets/tests/ErrorView_test.h +++ b/gui/libCommonWidgets/tests/ErrorView_test.h @@ -20,6 +20,6 @@ class ErrorViewTest : public TestEnvironmentCore { protected: int argc{0}; QApplication fakeApp_{argc, nullptr}; - raco::components::SDataChangeDispatcher dataChangeDispatcher_{std::make_shared()}; - raco::common_widgets::ErrorView errorView_{&commandInterface, dataChangeDispatcher_, true, nullptr}; + components::SDataChangeDispatcher dataChangeDispatcher_{std::make_shared()}; + common_widgets::ErrorView errorView_{&commandInterface, dataChangeDispatcher_, true, nullptr}; }; diff --git a/gui/libGUIPythonAPI/tests/GUIPythonAPI_test.cpp b/gui/libGUIPythonAPI/tests/GUIPythonAPI_test.cpp index d763e849..cfbeea6a 100644 --- a/gui/libGUIPythonAPI/tests/GUIPythonAPI_test.cpp +++ b/gui/libGUIPythonAPI/tests/GUIPythonAPI_test.cpp @@ -33,21 +33,21 @@ namespace py = pybind11; class GUIPythonTest : public RaCoApplicationTest { public: GUIPythonTest() { - objectTreeDockManager = new raco::object_tree::view::ObjectTreeDockManager(); - objectTreeDock = std::make_unique("Dock"); + objectTreeDockManager = new object_tree::view::ObjectTreeDockManager(); + objectTreeDock = std::make_unique("Dock"); objectTreeDockManager->addTreeDock(objectTreeDock.get()); - objectTreeViewModel = new raco::object_tree::model::ObjectTreeViewDefaultModel(&commandInterface(), application.dataChangeDispatcher(), nullptr, {raco::user_types::Node::typeDescription.typeName}); - objectTreeDock->setTreeView(new raco::object_tree::view::ObjectTreeView("TreeView", objectTreeViewModel)); + objectTreeViewModel = new object_tree::model::ObjectTreeViewDefaultModel(&commandInterface(), application.dataChangeDispatcher(), nullptr, {user_types::Node::typeDescription.typeName}); + objectTreeDock->setTreeView(new object_tree::view::ObjectTreeView("TreeView", objectTreeViewModel)); - raco::python_api::preparePythonEnvironment(QCoreApplication::applicationFilePath().toStdWString(), {}, true); + python_api::preparePythonEnvironment(QCoreApplication::applicationFilePath().toStdWString(), {}, true); pyGuard = std::make_unique(); - raco::python_api::setup(&application); + python_api::setup(&application); raco::gui_python_api::setupObjectTree(objectTreeDockManager); } - raco::object_tree::model::ObjectTreeViewDefaultModel* objectTreeViewModel; - std::unique_ptr objectTreeDock; - raco::object_tree::view::ObjectTreeDockManager* objectTreeDockManager; + object_tree::model::ObjectTreeViewDefaultModel* objectTreeViewModel; + std::unique_ptr objectTreeDock; + object_tree::view::ObjectTreeDockManager* objectTreeDockManager; std::unique_ptr pyGuard; @@ -59,7 +59,7 @@ class GUIPythonTest : public RaCoApplicationTest { } std::string createNode(std::string name) { - auto obj = objectTreeViewModel->createNewObject(raco::user_types::Node::typeDescription.typeName, name); + auto obj = objectTreeViewModel->createNewObject(user_types::Node::typeDescription.typeName, name); dispatch(); return obj->objectID(); } diff --git a/gui/libObjectTree/CMakeLists.txt b/gui/libObjectTree/CMakeLists.txt index 00ff2993..492df031 100644 --- a/gui/libObjectTree/CMakeLists.txt +++ b/gui/libObjectTree/CMakeLists.txt @@ -12,6 +12,8 @@ set(LIB_NAME libObjectTree) raco_find_qt_components(Widgets) add_library(libObjectTree + include/object_tree_view/FilterResult.h + src/object_tree_view/ObjectTreeFilter.h src/object_tree_view/ObjectTreeFilter.cpp include/object_tree_view/ObjectTreeDock.h src/object_tree_view/ObjectTreeDock.cpp include/object_tree_view/ObjectTreeDockManager.h src/object_tree_view/ObjectTreeDockManager.cpp include/object_tree_view/ObjectTreeView.h src/object_tree_view/ObjectTreeView.cpp @@ -28,6 +30,8 @@ add_library(libObjectTree target_include_directories(libObjectTree PUBLIC include/ + PRIVATE + src/ ) enable_warnings_as_errors(libObjectTree) @@ -44,6 +48,8 @@ target_link_libraries(libObjectTree raco::Style Qt5::Widgets qtadvanceddocking + PRIVATE + Boost::spirit ) add_library(raco::ObjectTree ALIAS libObjectTree) diff --git a/components/libRamsesBase/include/ramses_base/LogicEngine.h b/gui/libObjectTree/include/object_tree_view/FilterResult.h similarity index 65% rename from components/libRamsesBase/include/ramses_base/LogicEngine.h rename to gui/libObjectTree/include/object_tree_view/FilterResult.h index 7076d033..c7efc2fa 100644 --- a/components/libRamsesBase/include/ramses_base/LogicEngine.h +++ b/gui/libObjectTree/include/object_tree_view/FilterResult.h @@ -9,12 +9,12 @@ */ #pragma once -#include +namespace raco::object_tree::view { + +enum class FilterResult : int { + Failed, + PartialSuccess, + Success +}; -namespace raco::ramses_base { -/** - * Alias for the [rlogic::LogicEngine]. - * If needed extend to a wrapper. - */ -using LogicEngine = rlogic::LogicEngine; } diff --git a/gui/libObjectTree/include/object_tree_view/ObjectTreeDock.h b/gui/libObjectTree/include/object_tree_view/ObjectTreeDock.h index c4ce5069..201677bc 100644 --- a/gui/libObjectTree/include/object_tree_view/ObjectTreeDock.h +++ b/gui/libObjectTree/include/object_tree_view/ObjectTreeDock.h @@ -10,16 +10,15 @@ #pragma once #include "object_tree_view/ObjectTreeView.h" #include "components/DebugInstanceCounter.h" +#include "core/ErrorItem.h" #include #include -#include -#include #include #include #include -#include +#include namespace raco::object_tree::view { @@ -38,23 +37,24 @@ public Q_SLOTS: Q_SIGNALS: void externalObjectSelected(ObjectTreeDock *srcDock); - void newObjectTreeItemsSelected(const core::SEditorObjectSet &objects, ObjectTreeDock *srcDock); + void newObjectTreeItemsSelected(const core::SEditorObjectSet &objects, ObjectTreeDock *srcDock, const QString &property); void dockClosed(ObjectTreeDock *closedDock); void dockSelectionFocusRequested(ObjectTreeDock *focusDock); private: void filterTreeViewObjects(); + void setLineEditErrorLevel(FilterResult filterResult); QWidget *treeDockContent_; QVBoxLayout *treeDockLayout_; - + QLineEdit *filterLineEdit_; QComboBox *filterByComboBox_; QHBoxLayout *treeDockSettingsLayout_; QStackedWidget *treeViewStack_; - std::shared_ptr currentContext_; + std::shared_ptr currentContext_; }; diff --git a/gui/libObjectTree/include/object_tree_view/ObjectTreeDockManager.h b/gui/libObjectTree/include/object_tree_view/ObjectTreeDockManager.h index bfeacff1..c0ba707e 100644 --- a/gui/libObjectTree/include/object_tree_view/ObjectTreeDockManager.h +++ b/gui/libObjectTree/include/object_tree_view/ObjectTreeDockManager.h @@ -34,13 +34,14 @@ class ObjectTreeDockManager : public QObject { Q_SIGNALS: void treeDockListChanged(); - void newObjectTreeItemsSelected(const core::SEditorObjectSet& objects); + void newObjectTreeItemsSelected(const core::SEditorObjectSet& objects, const QString& property); void selectionCleared(); public Q_SLOTS: void eraseTreeDock(ObjectTreeDock* dockToErase); void setFocusedDock(ObjectTreeDock* dockToFocus); void selectObjectAcrossAllTreeDocks(const QString& objectID); + void selectObjectAndPropertyAcrossAllTreeDocks(const QString& objectID, const QString& objectProperty); private: std::vector docks_; diff --git a/gui/libObjectTree/include/object_tree_view/ObjectTreeView.h b/gui/libObjectTree/include/object_tree_view/ObjectTreeView.h index 1f7766b8..d4c06c7b 100644 --- a/gui/libObjectTree/include/object_tree_view/ObjectTreeView.h +++ b/gui/libObjectTree/include/object_tree_view/ObjectTreeView.h @@ -9,6 +9,8 @@ */ #pragma once +#include "FilterResult.h" + #include "core/EditorObject.h" #include @@ -30,7 +32,7 @@ class ObjectTreeView : public QTreeView { using SEditorObject = core::SEditorObject; public: - ObjectTreeView(const QString &viewTitle, raco::object_tree::model::ObjectTreeViewDefaultModel *viewModel, raco::object_tree::model::ObjectTreeViewDefaultSortFilterProxyModel *sortFilterProxyModel = nullptr, QWidget *parent = nullptr); + ObjectTreeView(const QString &viewTitle, object_tree::model::ObjectTreeViewDefaultModel *viewModel, object_tree::model::ObjectTreeViewDefaultSortFilterProxyModel *sortFilterProxyModel = nullptr, QWidget *parent = nullptr); core::SEditorObjectSet getSelectedObjects() const; std::vector getSortedSelectedEditorObjects() const; @@ -43,7 +45,7 @@ class ObjectTreeView : public QTreeView { bool canProgrammaticallyGoToObject(); bool containsObject(const QString &objectID) const; void setFilterKeyColumn(int column); - void filterObjects(const QString &filterString); + FilterResult filterObjects(const QString &filterString); bool hasProxyModel() const; @@ -54,7 +56,7 @@ class ObjectTreeView : public QTreeView { Q_SIGNALS: void dockSelectionFocusRequested(ObjectTreeView *focusTree); void newNodeRequested(EditorObject::TypeDescriptor nodeType, const std::string &nodeName, const QModelIndex &parent); - void newObjectTreeItemsSelected(const core::SEditorObjectSet &objects); + void newObjectTreeItemsSelected(const core::SEditorObjectSet &objects, const QString &property); void externalObjectSelected(); public Q_SLOTS: @@ -65,8 +67,14 @@ public Q_SLOTS: void cutObjects(); void deleteObjects(); void duplicateObjects(); + void pasteAsExtRef(); + + void isolateNodes(); + void hideNodes(); + void showAllNodes(); void selectObject(const QString &objectID); + void setPropertyToSelect(const QString &property); void expandAllParentsOfObject(const QString &objectID); void expanded(const QModelIndex &index); void collapsed(const QModelIndex &index); @@ -74,11 +82,12 @@ public Q_SLOTS: protected: static inline auto SELECTION_MODE = QItemSelectionModel::Select | QItemSelectionModel::Rows; - raco::object_tree::model::ObjectTreeViewDefaultModel *treeModel_; - raco::object_tree::model::ObjectTreeViewDefaultSortFilterProxyModel *proxyModel_; + object_tree::model::ObjectTreeViewDefaultModel *treeModel_; + object_tree::model::ObjectTreeViewDefaultSortFilterProxyModel *proxyModel_; QString viewTitle_; std::unordered_set expandedItemIDs_; std::unordered_set selectedItemIDs_; + QString property_; virtual QMenu* createCustomContextMenu(const QPoint &p); diff --git a/gui/libObjectTree/include/object_tree_view_model/ObjectTreeNode.h b/gui/libObjectTree/include/object_tree_view_model/ObjectTreeNode.h index fd8c883c..bcf474a1 100644 --- a/gui/libObjectTree/include/object_tree_view_model/ObjectTreeNode.h +++ b/gui/libObjectTree/include/object_tree_view_model/ObjectTreeNode.h @@ -56,7 +56,9 @@ class ObjectTreeNode { std::string getTypeName() const; std::string getExternalProjectName() const; std::string getExternalProjectPath() const; - VisibilityState getVisibility() const; + VisibilityState getPreviewVisibility() const; + VisibilityState getAbstractViewVisibility() const; + void setBelongsToExternalProject(const std::string &path, const std::string &name); protected: diff --git a/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewDefaultModel.h b/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewDefaultModel.h index f4e2355f..d33c7937 100644 --- a/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewDefaultModel.h +++ b/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewDefaultModel.h @@ -44,7 +44,8 @@ class ObjectTreeViewDefaultModel : public QAbstractItemModel { public: enum ColumnIndex { COLUMNINDEX_NAME, - COLUMNINDEX_VISIBILITY, + COLUMNINDEX_PREVIEW_VISIBILITY, + COLUMNINDEX_ABSTRACT_VIEW_VISIBILITY, COLUMNINDEX_TYPE, // invisible column that is used for ID-based filtering in the tree views COLUMNINDEX_ID, @@ -54,7 +55,7 @@ class ObjectTreeViewDefaultModel : public QAbstractItemModel { COLUMNINDEX_COLUMN_COUNT }; - ObjectTreeViewDefaultModel(raco::core::CommandInterface* commandInterface, components::SDataChangeDispatcher dispatcher, core::ExternalProjectsStoreInterface* externalProjectStore, const std::vector &allowedCreatableUserTypes, + ObjectTreeViewDefaultModel(core::CommandInterface* commandInterface, components::SDataChangeDispatcher dispatcher, core::ExternalProjectsStoreInterface* externalProjectStore, const std::vector &allowedCreatableUserTypes, bool groupExternalReferences = false, bool groupByType = false); int columnCount(const QModelIndex& parent = QModelIndex()) const override; @@ -83,8 +84,10 @@ class ObjectTreeViewDefaultModel : public QAbstractItemModel { core::UserObjectFactoryInterface* objectFactory() const; core::Project* project() const; - - std::set externalProjectPathsAtIndices(const QModelIndexList& indices); + + std::string objectIdAtIndex(const QModelIndex& index) const; + std::string externalProjectPathAtIndex(const QModelIndex& index) const; + std::set externalProjectPathsAtIndices(const QModelIndexList& indices) const; void setAcceptableFileExtensions(const QStringList& extensions); void setAcceptLuaModules(bool accept); @@ -129,6 +132,10 @@ public Q_SLOTS: void importMeshScenegraph(const QString& filePath, const QModelIndex& selectedIndex); void deleteUnusedResources(); + void isolateNodes(const QModelIndexList& indices); + void hideNodes(const QModelIndexList& indices); + void showAllNodes(); + protected: components::SDataChangeDispatcher dispatcher_; std::unique_ptr invisibleRootNode_; @@ -141,6 +148,7 @@ public Q_SLOTS: components::Subscription objectNameSubscription_; components::Subscription visibilitySubscription_; components::Subscription enabledSubscription_; + components::Subscription editorVisibilitySubscription_; components::Subscription childrenSubscription_; components::Subscription rootOrderSubscription_; components::Subscription lifeCycleSubscription_; @@ -161,38 +169,39 @@ public Q_SLOTS: void updateTreeIndexes(); QVariant getNodeIcon(ObjectTreeNode* treeNode) const; - QVariant getVisibilityIcon(ObjectTreeNode* treeNode) const; + QVariant getPreviewVisibilityIcon(ObjectTreeNode* treeNode) const; + QVariant getAbstractViewVisibilityIcon(ObjectTreeNode* treeNode) const; static inline constexpr const char* OBJECT_EDITOR_ID_MIME_TYPE = "application/editorobject.id"; const std::map typeIconMap{ - {"PerspectiveCamera", raco::style::Icons::instance().typeCamera}, - {"OrthographicCamera", raco::style::Icons::instance().typeCamera}, - {"Texture", raco::style::Icons::instance().typeTexture}, - {"TextureExternal", raco::style::Icons::instance().typeTexture}, - {"CubeMap", raco::style::Icons::instance().typeCubemap}, - {"LuaScript", raco::style::Icons::instance().typeLuaScript}, - {"LuaInterface", raco::style::Icons::instance().typeLuaInterface}, - {"Material", raco::style::Icons::instance().typeMaterial}, - {"Mesh", raco::style::Icons::instance().typeMesh}, - {"MeshNode", raco::style::Icons::instance().typeMesh}, - {"Node", raco::style::Icons::instance().typeNode}, - {"Prefab", raco::style::Icons::instance().typePrefabInternal}, - {"ExtrefPrefab", raco::style::Icons::instance().typePrefabExternal}, - {"PrefabInstance", raco::style::Icons::instance().typePrefabInstance}, - {"LuaScriptModule", raco::style::Icons::instance().typeLuaScriptModule}, - {"AnimationChannel", raco::style::Icons::instance().typeAnimationChannel}, - {"Animation", raco::style::Icons::instance().typeAnimation}, - {"Timer", raco::style::Icons::instance().typeTimer}, - {"AnchorPoint", raco::style::Icons::instance().typeAnchorPoint}, - {"BlitPass", raco::style::Icons::instance().typeBlitPass}, - {"Skin", raco::style::Icons::instance().typeSkin} + {"PerspectiveCamera", style::Icons::instance().typeCamera}, + {"OrthographicCamera", style::Icons::instance().typeCamera}, + {"Texture", style::Icons::instance().typeTexture}, + {"TextureExternal", style::Icons::instance().typeTexture}, + {"CubeMap", style::Icons::instance().typeCubemap}, + {"LuaScript", style::Icons::instance().typeLuaScript}, + {"LuaInterface", style::Icons::instance().typeLuaInterface}, + {"Material", style::Icons::instance().typeMaterial}, + {"Mesh", style::Icons::instance().typeMesh}, + {"MeshNode", style::Icons::instance().typeMesh}, + {"Node", style::Icons::instance().typeNode}, + {"Prefab", style::Icons::instance().typePrefabInternal}, + {"ExtrefPrefab", style::Icons::instance().typePrefabExternal}, + {"PrefabInstance", style::Icons::instance().typePrefabInstance}, + {"LuaScriptModule", style::Icons::instance().typeLuaScriptModule}, + {"AnimationChannel", style::Icons::instance().typeAnimationChannel}, + {"Animation", style::Icons::instance().typeAnimation}, + {"Timer", style::Icons::instance().typeTimer}, + {"AnchorPoint", style::Icons::instance().typeAnchorPoint}, + {"BlitPass", style::Icons::instance().typeBlitPass}, + {"Skin", style::Icons::instance().typeSkin} }; const std::map visibilityIconMap_{ - {VisibilityState::Disabled, raco::style::Icons::instance().visibilityDisabled}, - {VisibilityState::Visible, raco::style::Icons::instance().visibilityOn}, - {VisibilityState::Invisible, raco::style::Icons::instance().visibilityOff}, + {VisibilityState::Disabled, style::Icons::instance().visibilityDisabled}, + {VisibilityState::Visible, style::Icons::instance().visibilityOn}, + {VisibilityState::Invisible, style::Icons::instance().visibilityOff}, }; QStringList acceptableFileExtensions_; diff --git a/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewExternalProjectModel.h b/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewExternalProjectModel.h index d92583a4..5723d9ed 100644 --- a/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewExternalProjectModel.h +++ b/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewExternalProjectModel.h @@ -18,7 +18,7 @@ class ObjectTreeViewExternalProjectModel : public ObjectTreeViewDefaultModel { Q_OBJECT public: - ObjectTreeViewExternalProjectModel(raco::core::CommandInterface* commandInterface, components::SDataChangeDispatcher dispatcher, core::ExternalProjectsStoreInterface* externalProjectsStoreInterface); + ObjectTreeViewExternalProjectModel(core::CommandInterface* commandInterface, components::SDataChangeDispatcher dispatcher, core::ExternalProjectsStoreInterface* externalProjectsStoreInterface); QVariant data(const QModelIndex& index, int role) const override; diff --git a/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewPrefabModel.h b/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewPrefabModel.h index e184801d..96a0265c 100644 --- a/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewPrefabModel.h +++ b/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewPrefabModel.h @@ -18,7 +18,7 @@ class ObjectTreeViewPrefabModel : public ObjectTreeViewDefaultModel { Q_OBJECT public: - ObjectTreeViewPrefabModel(raco::core::CommandInterface* commandInterface, components::SDataChangeDispatcher dispatcher, core::ExternalProjectsStoreInterface* externalProjectsStore, const std::vector& allowedCreatableUserTypes = {}); + ObjectTreeViewPrefabModel(core::CommandInterface* commandInterface, components::SDataChangeDispatcher dispatcher, core::ExternalProjectsStoreInterface* externalProjectsStore, const std::vector& allowedCreatableUserTypes = {}); QVariant data(const QModelIndex& index, int role) const override; }; diff --git a/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewResourceModel.h b/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewResourceModel.h index 9e7a0506..eea8f3c2 100644 --- a/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewResourceModel.h +++ b/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewResourceModel.h @@ -20,7 +20,7 @@ class ObjectTreeViewResourceModel : public ObjectTreeViewDefaultModel { public: - ObjectTreeViewResourceModel(raco::core::CommandInterface* commandInterface, components::SDataChangeDispatcher dispatcher, core::ExternalProjectsStoreInterface* externalProjectStore, const std::vector& allowedCreatableUserTypes = {}); + ObjectTreeViewResourceModel(core::CommandInterface* commandInterface, components::SDataChangeDispatcher dispatcher, core::ExternalProjectsStoreInterface* externalProjectStore, const std::vector& allowedCreatableUserTypes = {}); bool pasteObjectAtIndex(const QModelIndex& index, bool pasteAsExtref, std::string* outError, const std::string& serializedObjects = RaCoClipboard::get()) override; diff --git a/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewSortProxyModels.h b/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewSortProxyModels.h index fc6700a9..491216b6 100644 --- a/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewSortProxyModels.h +++ b/gui/libObjectTree/include/object_tree_view_model/ObjectTreeViewSortProxyModels.h @@ -10,18 +10,30 @@ #pragma once +#include "ObjectTreeNode.h" #include namespace raco::object_tree::model { class ObjectTreeViewDefaultSortFilterProxyModel : public QSortFilterProxyModel { + std::function customFilter = nullptr; + public: ObjectTreeViewDefaultSortFilterProxyModel(QObject *parent = nullptr, bool enableSorting = true); + using FilterFunction = std::function; + bool sortingEnabled() const; + + void setCustomFilter(std::function filterFunc); + void removeCustomFilter(); + + QString getDataAtIndex(const QModelIndex &index) const; + protected: QVariant data(const QModelIndex &index, int role) const override; + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; bool sortingEnabled_; }; diff --git a/gui/libObjectTree/src/object_creator/ObjectCreator.cpp b/gui/libObjectTree/src/object_creator/ObjectCreator.cpp index 993c8a4e..34655ba6 100644 --- a/gui/libObjectTree/src/object_creator/ObjectCreator.cpp +++ b/gui/libObjectTree/src/object_creator/ObjectCreator.cpp @@ -19,7 +19,7 @@ namespace raco::object_tree::object_creator { -raco::core::SEditorObject ObjectCreator::createNewObjectFromFile(const QFileInfo& fileInfo) { +core::SEditorObject ObjectCreator::createNewObjectFromFile(const QFileInfo& fileInfo) { const auto absolutePath = fileInfo.absoluteFilePath(); const auto relativePath{utils::u8path(absolutePath.toStdString()).normalizedRelativePath(utils::u8path(commandInterface_->project()->currentFolder())).string()}; const auto fileName = fileInfo.fileName(); diff --git a/gui/libObjectTree/src/object_tree_view/ObjectTreeDock.cpp b/gui/libObjectTree/src/object_tree_view/ObjectTreeDock.cpp index 52d3112d..2d349f6a 100644 --- a/gui/libObjectTree/src/object_tree_view/ObjectTreeDock.cpp +++ b/gui/libObjectTree/src/object_tree_view/ObjectTreeDock.cpp @@ -15,10 +15,7 @@ #include "object_tree_view/ObjectTreeView.h" #include -#include #include -#include -#include namespace raco::object_tree::view { @@ -29,19 +26,19 @@ ObjectTreeDock::ObjectTreeDock(const char *dockTitle, QWidget *parent) setAttribute(Qt::WA_DeleteOnClose); setFeature(ads::CDockWidget::DockWidgetDeleteOnClose, true); - treeDockLayout_ = new raco::common_widgets::NoContentMarginsLayout(treeDockContent_); + treeDockLayout_ = new common_widgets::NoContentMarginsLayout(treeDockContent_); treeDockContent_->setLayout(treeDockLayout_); filterLineEdit_ = new QLineEdit(this); filterLineEdit_->setPlaceholderText("Filter Objects..."); filterByComboBox_ = new QComboBox(this); - filterByComboBox_->addItem("Filter by Name", QVariant(raco::object_tree::model::ObjectTreeViewDefaultModel::ColumnIndex::COLUMNINDEX_NAME)); - filterByComboBox_->addItem("Filter by Type", QVariant(raco::object_tree::model::ObjectTreeViewDefaultModel::ColumnIndex::COLUMNINDEX_TYPE)); - filterByComboBox_->addItem("Filter by Object ID", QVariant(raco::object_tree::model::ObjectTreeViewDefaultModel::ColumnIndex::COLUMNINDEX_ID)); - filterByComboBox_->addItem("Filter by User Tag", QVariant(raco::object_tree::model::ObjectTreeViewDefaultModel::ColumnIndex::COLUMNINDEX_USERTAGS)); + filterByComboBox_->addItem("Filter by Name", QVariant(object_tree::model::ObjectTreeViewDefaultModel::ColumnIndex::COLUMNINDEX_NAME)); + filterByComboBox_->addItem("Filter by Type", QVariant(object_tree::model::ObjectTreeViewDefaultModel::ColumnIndex::COLUMNINDEX_TYPE)); + filterByComboBox_->addItem("Filter by Object ID", QVariant(object_tree::model::ObjectTreeViewDefaultModel::ColumnIndex::COLUMNINDEX_ID)); + filterByComboBox_->addItem("Filter by User Tag", QVariant(object_tree::model::ObjectTreeViewDefaultModel::ColumnIndex::COLUMNINDEX_USERTAGS)); auto treeDockSettingsWidget = new QWidget(treeDockContent_); - treeDockSettingsLayout_ = new raco::common_widgets::NoContentMarginsLayout(treeDockSettingsWidget); + treeDockSettingsLayout_ = new common_widgets::NoContentMarginsLayout(treeDockSettingsWidget); treeDockSettingsLayout_->setContentsMargins(2, 3, 2, 0); treeDockSettingsLayout_->addWidget(filterLineEdit_); treeDockSettingsLayout_->addWidget(filterByComboBox_); @@ -67,7 +64,7 @@ ObjectTreeDock::ObjectTreeDock(const char *dockTitle, QWidget *parent) } -raco::object_tree::view::ObjectTreeDock::~ObjectTreeDock() { +ObjectTreeDock::~ObjectTreeDock() { Q_EMIT dockClosed(this); } @@ -77,8 +74,8 @@ void ObjectTreeDock::setTreeView(ObjectTreeView *treeView) { filterLineEdit_->setVisible(treeView->hasProxyModel()); filterByComboBox_->setVisible(treeView->hasProxyModel()); - connect(treeView, &ObjectTreeView::newObjectTreeItemsSelected, [this](const auto &objects) { - Q_EMIT newObjectTreeItemsSelected(objects, this); + connect(treeView, &ObjectTreeView::newObjectTreeItemsSelected, [this](const auto &objects, const auto &property) { + Q_EMIT newObjectTreeItemsSelected(objects, this, property); }); connect(treeView, &ObjectTreeView::externalObjectSelected, [this]() { Q_EMIT externalObjectSelected(this); @@ -100,7 +97,18 @@ void ObjectTreeDock::resetSelection() { } void ObjectTreeDock::filterTreeViewObjects() { - getActiveTreeView()->filterObjects(filterLineEdit_->text()); + const auto filterResult = getActiveTreeView()->filterObjects(filterLineEdit_->text()); + setLineEditErrorLevel(filterResult); +} + +void ObjectTreeDock::setLineEditErrorLevel(FilterResult filterResult) { + if (filterResult == FilterResult::Failed) { + filterLineEdit_->setProperty("errorLevel", static_cast(core::ErrorLevel::ERROR)); + } else if (filterResult == FilterResult::PartialSuccess) { + filterLineEdit_->setProperty("errorLevel", static_cast(core::ErrorLevel::WARNING)); + } else { + filterLineEdit_->setProperty("errorLevel", static_cast(core::ErrorLevel::NONE)); + } } } // namespace raco::object_tree::view diff --git a/gui/libObjectTree/src/object_tree_view/ObjectTreeDockManager.cpp b/gui/libObjectTree/src/object_tree_view/ObjectTreeDockManager.cpp index e0ebe23b..2fb282dd 100644 --- a/gui/libObjectTree/src/object_tree_view/ObjectTreeDockManager.cpp +++ b/gui/libObjectTree/src/object_tree_view/ObjectTreeDockManager.cpp @@ -45,6 +45,10 @@ void ObjectTreeDockManager::setFocusedDock(ObjectTreeDock* dock) { } void ObjectTreeDockManager::selectObjectAcrossAllTreeDocks(const QString& objectID) { + selectObjectAndPropertyAcrossAllTreeDocks(objectID, {}); +} + +void ObjectTreeDockManager::selectObjectAndPropertyAcrossAllTreeDocks(const QString& objectID, const QString& objectProperty) { // always favor the first created active tree view of any type (e.g. the first "Scene Graph", the first "Resources") std::set viewTitles; @@ -53,6 +57,7 @@ void ObjectTreeDockManager::selectObjectAcrossAllTreeDocks(const QString& object auto viewTitle = activeTreeView->getViewTitle(); if (activeTreeView->canProgrammaticallyGoToObject() && viewTitles.count(viewTitle) == 0) { + activeTreeView->setPropertyToSelect(objectProperty); activeTreeView->selectObject(objectID); activeTreeView->expandAllParentsOfObject(objectID); viewTitles.insert(viewTitle); @@ -90,7 +95,7 @@ bool ObjectTreeDockManager::docksContainObject(const QString& objID) const { std::vector ObjectTreeDockManager::getSelection() const { auto activeDockWhichHasSelection = getActiveDockWithSelection(); if (activeDockWhichHasSelection == nullptr || activeDockWhichHasSelection->windowTitle().toStdString() == "Project Browser") { - return std::vector(); + return std::vector(); } return activeDockWhichHasSelection->getActiveTreeView()->getSortedSelectedEditorObjects(); @@ -103,12 +108,12 @@ void ObjectTreeDockManager::connectTreeDockSignals(ObjectTreeDock* dock) { Q_EMIT selectionCleared(); }); - QObject::connect(dock, &ObjectTreeDock::newObjectTreeItemsSelected, [this](auto& objects, auto* selectionSrcDock) { + QObject::connect(dock, &ObjectTreeDock::newObjectTreeItemsSelected, [this](auto& objects, auto* selectionSrcDock, auto& property) { setFocusedDock(selectionSrcDock); if (objects.empty()) { Q_EMIT selectionCleared(); } else { - Q_EMIT newObjectTreeItemsSelected(objects); + Q_EMIT newObjectTreeItemsSelected(objects, property); } }); QObject::connect(dock, &ObjectTreeDock::dockSelectionFocusRequested, this, &ObjectTreeDockManager::setFocusedDock); diff --git a/gui/libObjectTree/src/object_tree_view/ObjectTreeFilter.cpp b/gui/libObjectTree/src/object_tree_view/ObjectTreeFilter.cpp new file mode 100644 index 00000000..15d6e9bc --- /dev/null +++ b/gui/libObjectTree/src/object_tree_view/ObjectTreeFilter.cpp @@ -0,0 +1,205 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#include "object_tree_view/ObjectTreeFilter.h" + +using namespace raco::object_tree::view; +using namespace raco; + +ObjectTreeFilter::ObjectTreeFilter() : ObjectTreeFilter::base_type(start) { + // keywords + name = qi::lit("name"); + type = qi::lit("type"); + id = qi::lit("id"); + tag = qi::lit("tag"); + keyword = name | type | id | tag; + + // operations + equal = qi::lit("="); + not_equal = qi::lit("!="); + operation = equal | not_equal; + + // values + value_single_quoted = qi::lexeme['\'' >> +(qi::char_ - '\'') >> '\'']; + value_double_quoted = qi::lexeme['\"' >> +(qi::char_ - '\"') >> '\"']; + value = qi::lexeme[+(qi::char_ - '(' - ')' - '|' - '&' - '!' - '=' - '\'' - '\"' - ' ')] | value_single_quoted; + + // expressions + expression = (keyword >> operation >> value) + [qi::_val = phx::bind(&ObjectTreeFilter::filterExpression, this, qi::_1, qi::_2, qi::_3, false)]; + expression_exact = (keyword >> operation >> value_double_quoted) + [qi::_val = phx::bind(&ObjectTreeFilter::filterExpression, this, qi::_1, qi::_2, qi::_3, true)]; + + expression_no_key = (operation >> value) + [qi::_val = phx::bind(&ObjectTreeFilter::filterExpressionByDefaultKey, this, qi::_1, qi::_2, false)]; + expression_exact_no_key = (operation >> value_double_quoted) + [qi::_val = phx::bind(&ObjectTreeFilter::filterExpressionByDefaultKey, this, qi::_1, qi::_2, true)]; + + expression_no_key_no_op = value + [qi::_val = phx::bind(&ObjectTreeFilter::filterExpressionByDefaultKey, this, "=", qi::_1, false)]; + expression_exact_no_key_no_op = value_double_quoted + [qi::_val = phx::bind(&ObjectTreeFilter::filterExpressionByDefaultKey, this, "=", qi::_1, true)]; + + // factor / term / start + factor = (expression_exact | expression_exact_no_key | expression_exact_no_key_no_op) | + (expression | expression_no_key | expression_no_key_no_op) | ('(' >> start >> ')'); + + term = factor[qi::_val = qi::_1] >> *('&' >> factor[qi::_val = phx::bind(&ObjectTreeFilter::filterAND, this, qi::_val, qi::_1)]); + + start = term[qi::_val = qi::_1] >> *(-qi::lit('|') >> term[qi::_val = phx::bind(&ObjectTreeFilter::filterOR, this, qi::_val, qi::_1)]); +} + +std::string ObjectTreeFilter::toLower(const std::string& input) const { + std::string lowered = input; + std::transform(input.begin(), input.end(), lowered.begin(), [](unsigned char c) { return std::tolower(c); }); + return lowered; +} + +void ObjectTreeFilter::removeQuotes(std::string& s) const { + s.erase(std::remove(s.begin(), s.end(), '\''), s.end()); +} + + + +void ObjectTreeFilter::removeTrailingSpaces(std::string& s) { + std::size_t pos = s.find_last_not_of(' '); + if (pos != std::string::npos) { + s.erase(pos + 1); + } else { + // The string only contains spaces or is empty + s.clear(); + } +} + +std::function ObjectTreeFilter::filterOR( + const std::function& lhs, + const std::function& rhs) const { + // Define a lambda function for the filtering logic + auto filterFunc = [lhs, rhs](const model::ObjectTreeNode& objectTreeNode) { + return lhs(objectTreeNode) || rhs(objectTreeNode); + }; + + return filterFunc; +} + +std::function ObjectTreeFilter::filterAND( + const std::function& lhs, + const std::function& rhs) const { + // Define a lambda function for the filtering logic + auto filterFunc = [lhs, rhs](const model::ObjectTreeNode& objectTreeNode) { + return lhs(objectTreeNode) && rhs(objectTreeNode); + }; + + return filterFunc; +} + +std::function ObjectTreeFilter::filterExpressionByDefaultKey(std::string op, std::string value, bool exact) const { + switch (defaultFilterKeyColumn_) { + case model::ObjectTreeViewDefaultModel::ColumnIndex::COLUMNINDEX_NAME: { + return filterExpression("name", op, value, exact); + } + case model::ObjectTreeViewDefaultModel::ColumnIndex::COLUMNINDEX_TYPE: { + return filterExpression("type", op, value, exact); + } + case model::ObjectTreeViewDefaultModel::ColumnIndex::COLUMNINDEX_ID: { + return filterExpression("id", op, value, exact); + } + case model::ObjectTreeViewDefaultModel::ColumnIndex::COLUMNINDEX_USERTAGS: { + return filterExpression("tag", op, value, exact); + } + default: { + return {}; + } + } +} + +std::function ObjectTreeFilter::filterExpression(std::string keyword, std::string op, std::string value, bool exact) const { + // Remove the single quotes from the parsed value if present + removeQuotes(value); + removeTrailingSpaces(value); + + // Define a lambda function for the filtering logic + auto filterFunc = [this, keyword, op, value, exact](const model::ObjectTreeNode& objectTreeNode) { + if (keyword == "tag") { + const auto tags = objectTreeNode.getUserTags(); + if (op == "=" && exact == true) { + return std::any_of(tags.begin(), tags.end(), [this, &value](const std::string& tag) { + return toLower(tag) == toLower(value); + }); + } + if (op == "!=" && exact == true) { + return std::all_of(tags.begin(), tags.end(), [this, &value](const std::string& tag) { + return toLower(tag) != toLower(value); + }); + } + if (op == "=") { + return std::any_of(tags.begin(), tags.end(), [this, &value](const std::string& tag) { + return toLower(tag).find(toLower(value)) != std::string::npos; + }); + } + if (op == "!=") { + return std::all_of(tags.begin(), tags.end(), [this, &value](const std::string& tag) { + return toLower(tag).find(toLower(value)) == std::string::npos; + }); + } + } else { + std::string objValue; + if (keyword == "name") objValue = objectTreeNode.getDisplayName(); + if (keyword == "type") objValue = objectTreeNode.getDisplayType(); + if (keyword == "id") objValue = objectTreeNode.getID(); + + if (!objValue.empty()) { + if (op == "=" && exact == true) { + return toLower(objValue) == toLower(value); + } + if (op == "!=" && exact == true) { + return toLower(objValue) != toLower(value); + } + if (op == "=") { + return toLower(objValue).find(toLower(value)) != std::string::npos; + } + if (op == "!=") { + return toLower(objValue).find(toLower(value)) == std::string::npos; + } + } + } + + return false; + }; + + return filterFunc; +} + +void ObjectTreeFilter::setDefaultFilterKeyColumn(const int column) { + defaultFilterKeyColumn_ = column; +} + +std::function ObjectTreeFilter::parse(const std::string& input, FilterResult& filterResult) { + std::function output{}; + filterResult = FilterResult::Failed; + + try { + std::string::const_iterator iterator = input.begin(); + std::string::const_iterator end = input.end(); + + if (phrase_parse(iterator, end, *this, qi::space, output)) { + if (iterator == end) { + filterResult = FilterResult::Success; + } else { + filterResult = FilterResult::PartialSuccess; + } + } + } catch (...) { + } + + return output; +} + + + diff --git a/gui/libObjectTree/src/object_tree_view/ObjectTreeFilter.h b/gui/libObjectTree/src/object_tree_view/ObjectTreeFilter.h new file mode 100644 index 00000000..dde3b92d --- /dev/null +++ b/gui/libObjectTree/src/object_tree_view/ObjectTreeFilter.h @@ -0,0 +1,199 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * + * PARSING USING BOOST.SPIRIT LIBRARY + * + * Ramses Composer supports complex filter expressions inside of the Scene Graph as well as the Resources and Prefabs views. + * This section explains some parts of the code which handles such filter expressions. Because the filtering expressions can be nested and in general + * arbitrarily complex we cannot use regex expressions to parse them. For this reason the more complex tool called Boost.Spirit - a parsing library is used. + * Some of its main concepts are explained here together with its syntax. + * + * The first step in dealing with the complex expressions is to define a grammar - a set of rules which define what we are looking inside the text + * and what we are doing after we have found it. + * + * + * 1. Literal parser + * + * Let's start with the simple example: + * qi::rule name = qi::lit("name"); + * + * Now let's take a closer look at the line above: + * qi::rule<> is a class which tells as that this is a grammar rule which will be used by the parser to find something in the text which we call "name". + * This rule will iterate through any string (std::string::const_iterator) omitting white spaces (qi::space_type) and will put the result into a string (std::string()). + * What exactly we are looking for is stated on the right hand side: qi::lit("name"). This part tells that we will be looking for literal constant which + * has the exact sequence of letters "name". + * Because we want to distinguish between several keywords in our text we declare 4 of such constants: + * name = qi::lit("name"); + * type = qi::lit("type"); + * id = qi::lit("id"); + * tag = qi::lit("tag"); + * + * + * 2. Alternates + * + * Alternates: e.g. a | b. Try a first. If it succeeds, good. If not, try the next alternative, b. + * + * In our example the alternate is our keyword which can be either name OR type OR id OR tag: + * keyword = name | type | id | tag; + * + * Analogously to the keywords we want to extract operations like equal OR not equal: + * equal = qi::lit("="); + * not_equal = qi::lit("!="); + * operation = equal | not_equal; + * + * + * 3. Lexeme and Optionals + * + * Sometimes it is important to omit some characters or strings inside the text. There are some modifiers in Boost.Spirit library which can be used for these purposes. + * Let's assume we don't want the rounded brackets to be the part of the parsed value. We could write the grammar rule as follows: + * value = qi::lexeme[+(qi::char_ - '(' - ')')]; + * + * qi::lit() is for strict literal matching, useful for fixed keywords or character sequences + * qi::lexeme[] is used to treat a sequence of characters as a single lexeme, ignoring any intervening whitespace or other irrelevant characters. + * - operator tells that '(' and ')' should exclude the rounded brackets from the parsing result + * + operator tells us that there must be 1 or more characters in a sequence + * * operator tells us that there must be 0 or more characters in a sequence + * + * + * 4. Sequences + * + * The next important part is to detect some specific sequences of the keywords, operations and values. For example we want to detect cases when a keyword is followed by + * an operation which itself is followed by some value. In Boost.Spirit this can be expressed by the following expression, where ">>" can be read as "followed by": + * expression = keyword >> operation >> value; + * As soon as such a sequence is found it is classified as an expression (for example: name = myName) + * + * + * 5. Semantic actions + * + * The examples in the previous section were very simplistic. They only recognized data, but did nothing with it. They answered the question: "Did the input match?". + * Now, we want to extract information from what was parsed and perform some manipulations with it, in other words we will do semantic actions. + * + * Semantic actions may be attached to any point in the grammar specification. These actions are C++ functions or function objects that are called whenever a part + * of the parser successfully recognizes a portion of the input. Say you have a parser P, and a C++ function F. + * You can make the parser call F whenever it matches an input by attaching F: + * P[F] + * + * Boost.Phoenix, a companion library bundled with Spirit, is specifically suited for binding semantic actions. It is like Boost.Lambda with special custom features + * that make it easy to integrate semantic actions with Spirit. Let's look at a concrete example from the code: + * expression = (keyword >> operation >> value) + * [qi::_val = phx::bind(&ObjectTreeFilter::filterExpression, this, qi::_1, qi::_2, qi::_3, false)]; + * + * The expression in the square brackets is the semantic action. Here we see that the results of parsing are stored in the placeholders + * qi::_1(keyword), qi::_2(operation) and qi::_3(value). + * All of them including "false" are used as the arguments for the "filterExpression" function. The result of this function is stored in qi::_val. + * This is done to keep the result for the later usage. That's the only way to use the previous parsed results later, + * otherwise the parsing process keeps iterating through the next symbols and previous results are lost. + * + * + * 6. Nested expressions + * + * In Boost.Spirit, parsing of nested expressions is achieved through recursive grammar rules. This involves defining parsing rules in terms of themselves + * or in terms of other rules that refer back to the original rule. This recursive structure allows for the parsing of nested constructs. + * Here is a simple example to parse the arithmetic expression like this "(1 + (2 + 3))": + * + * qi::rule expression; + * qi::rule factor; + * + * expression = factor >> *(qi::char_('+') >> factor); + * factor = qi::int_ | ('(' >> expression >> ')'); + * + * + * 7. qi::phrase_parse function + * + * The parse function returns true or false depending on the result of the parse. + * One overload of this function accepts five arguments: + * + * 1. An iterator pointing to the start of the input + * 2. An iterator pointing to one past the end of the input + * 3. The parser object + * 4. Another parser called the skip parser. In our example, we wish to skip spaces and tabs. Another parser named space is included in Spirit's repertoire + * of predefined parsers. It is a very simple parser that simply recognizes whitespace. We will use space as our skip parser. + * 5. Variable which stores the parsing result + * + * Example: + * bool r = phrase_parse( + * first, 1 + * last, 2 + * *this, 3 + * space, 4 + * output 5 + * ); + * + * + * 8. Parser class definition + * + * The types of the local variables like qi::_1 should be also declared.This is done using the template arguments qi::locals. + * See the example : + * class ObjectTreeFilter : public qi::grammar(), + * qi::space_type, + * qi::locals>> { + * }; + * + * The result of the parsing as well as the type of the arguments are also defined here using the template arguments : + * std::function() + * The separator between the words here is default and defined to be a white space : qi::space_type + * + */ + +#pragma once + +#include "object_tree_view/FilterResult.h" + +#include "core/EditorObject.h" + +#include +#include +#include + +#include + +#include "object_tree_view_model/ObjectTreeViewDefaultModel.h" +#include "object_tree_view_model/ObjectTreeViewSortProxyModels.h" + +namespace raco::object_tree::view { + +using EditorObject = core::EditorObject; +namespace qi = boost::spirit::qi; +namespace phx = boost::phoenix; + +class ObjectTreeFilter : public qi::grammar(), + qi::space_type, qi::locals>> { +public: + ObjectTreeFilter(); + + void setDefaultFilterKeyColumn(const int column); + std::function parse(const std::string& input, FilterResult& filterResult); + +private: + qi::rule name, type, id, tag, keyword; + qi::rule equal, not_equal, operation; + qi::rule value, value_single_quoted, value_double_quoted; + qi::rule(), qi::space_type, qi::locals>> expression, expression_no_key, expression_no_key_no_op; + qi::rule(), qi::space_type, qi::locals>> expression_exact, expression_exact_no_key, expression_exact_no_key_no_op; + qi::rule(), qi::space_type, qi::locals>> term, factor, start; + + inline static int defaultFilterKeyColumn_ = 0; + + std::string toLower(const std::string& input) const; + void removeQuotes(std::string& s) const; + static void removeTrailingSpaces(std::string& s); + + std::function filterOR( + const std::function& lhs, + const std::function& rhs) const; + std::function filterAND( + const std::function& lhs, + const std::function& rhs) const; + std::function filterExpressionByDefaultKey(std::string op, std::string value, bool exact) const; + std::function filterExpression(std::string keyword, std::string op, std::string value, bool exact) const; +}; + +} // namespace raco::object_tree::view diff --git a/gui/libObjectTree/src/object_tree_view/ObjectTreeView.cpp b/gui/libObjectTree/src/object_tree_view/ObjectTreeView.cpp index f14d3bb8..a29f475d 100644 --- a/gui/libObjectTree/src/object_tree_view/ObjectTreeView.cpp +++ b/gui/libObjectTree/src/object_tree_view/ObjectTreeView.cpp @@ -9,12 +9,12 @@ */ #include "object_tree_view/ObjectTreeView.h" +#include "ObjectTreeFilter.h" #include "components/RaCoPreferences.h" #include "core/EditorObject.h" #include "core/PathManager.h" #include "core/Project.h" -#include "core/UserObjectFactoryInterface.h" #include "user_types/Node.h" #include "object_tree_view_model/ObjectTreeViewDefaultModel.h" @@ -36,7 +36,7 @@ namespace raco::object_tree::view { -using namespace raco::object_tree::model; +using namespace object_tree::model; ObjectTreeView::ObjectTreeView(const QString &viewTitle, ObjectTreeViewDefaultModel *viewModel, ObjectTreeViewDefaultSortFilterProxyModel *sortFilterProxyModel, QWidget *parent) : QTreeView(parent), treeModel_(viewModel), proxyModel_(sortFilterProxyModel), viewTitle_(viewTitle) { @@ -74,17 +74,18 @@ ObjectTreeView::ObjectTreeView(const QString &viewTitle, ObjectTreeViewDefaultMo return; } - auto selectedObjects = indicesToSEditorObjects(selectedItemList.indexes()); + auto selectedObjects = indicesToSEditorObjects(selectedItemList.indexes()); for (const auto &selObj : selectedObjects) { selectedItemIDs_.emplace(selObj->objectID()); } - auto deselectedObjects = indicesToSEditorObjects(deselectedItemList.indexes()); + auto deselectedObjects = indicesToSEditorObjects(deselectedItemList.indexes()); for (const auto &deselObj : deselectedObjects) { selectedItemIDs_.erase(deselObj->objectID()); } - Q_EMIT newObjectTreeItemsSelected(getSelectedObjects()); + Q_EMIT newObjectTreeItemsSelected(getSelectedObjects(), property_); + property_.clear(); }); connect(treeModel_, &ObjectTreeViewDefaultModel::modelReset, this, &ObjectTreeView::restoreItemExpansionStates); @@ -107,6 +108,18 @@ ObjectTreeView::ObjectTreeView(const QString &viewTitle, ObjectTreeViewDefaultMo auto duplicateShortcut = new QShortcut({"Ctrl+D"}, this, nullptr, nullptr, Qt::WidgetShortcut); QObject::connect(duplicateShortcut, &QShortcut::activated, this, &ObjectTreeView::duplicateObjects); + + auto isolateShortcut = new QShortcut({"Ctrl+I"}, this, nullptr, nullptr, Qt::WidgetShortcut); + QObject::connect(isolateShortcut, &QShortcut::activated, this, &ObjectTreeView::isolateNodes); + + auto hideShortcut = new QShortcut({"Ctrl+H"}, this, nullptr, nullptr, Qt::WidgetShortcut); + QObject::connect(hideShortcut, &QShortcut::activated, this, &ObjectTreeView::hideNodes); + + auto showAllShortcut = new QShortcut({"Ctrl+U"}, this, nullptr, nullptr, Qt::WidgetShortcut); + QObject::connect(showAllShortcut, &QShortcut::activated, this, &ObjectTreeView::showAllNodes); + + auto extrefPasteShortcut = new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_V, this, nullptr, nullptr, Qt::WidgetShortcut); + QObject::connect(extrefPasteShortcut, &QShortcut::activated, this, &ObjectTreeView::pasteAsExtRef); } core::SEditorObjectSet ObjectTreeView::getSelectedObjects() const { @@ -210,13 +223,39 @@ void ObjectTreeView::deleteObjects() { } } -void raco::object_tree::view::ObjectTreeView::duplicateObjects() { +void object_tree::view::ObjectTreeView::duplicateObjects() { auto selectedIndices = getSelectedIndices(true); if (!selectedIndices.isEmpty() && treeModel_->canDuplicateAtIndices(selectedIndices)) { treeModel_->duplicateObjectsAtIndices(selectedIndices); } } +void ObjectTreeView::isolateNodes() { + auto selectedIndices = getSelectedIndices(true); + if (!selectedIndices.isEmpty()) { + treeModel_->isolateNodes(selectedIndices); + } +} + +void ObjectTreeView::hideNodes() { + auto selectedIndices = getSelectedIndices(true); + if (!selectedIndices.isEmpty()) { + treeModel_->hideNodes(selectedIndices); + } +} + +void ObjectTreeView::pasteAsExtRef() { + std::string error; + if (!treeModel_->pasteObjectAtIndex({}, true, &error)) { + QMessageBox::warning(this, "Paste As External Reference", + fmt::format("Update of pasted external references failed!\n\n{}", error).c_str()); + } +} + +void ObjectTreeView::showAllNodes() { + treeModel_->showAllNodes(); +} + void ObjectTreeView::selectObject(const QString &objectID) { if (objectID.isEmpty()) { resetSelection(); @@ -231,6 +270,10 @@ void ObjectTreeView::selectObject(const QString &objectID) { } } +void ObjectTreeView::setPropertyToSelect(const QString &property) { + property_ = property; +} + void ObjectTreeView::expandAllParentsOfObject(const QString &objectID) { auto objectIndex = indexFromTreeNodeID(objectID.toStdString()); if (objectIndex.isValid()) { @@ -307,18 +350,26 @@ void ObjectTreeView::setFilterKeyColumn(int column) { } } -void ObjectTreeView::filterObjects(const QString &filterString) { +FilterResult ObjectTreeView::filterObjects(const QString &filterString) { + FilterResult filterResult = filterString.isEmpty() ? FilterResult::Success : FilterResult::Failed; + if (proxyModel_) { - auto filterStrings = filterString.split(" ", Qt::SkipEmptyParts); - for (auto &filterString : filterStrings) { - filterString = QRegularExpression::escape(filterString); + proxyModel_->removeCustomFilter(); + + if (!filterString.isEmpty()) { + const auto input = filterString.toStdString(); + ObjectTreeFilter objectTreeFilter; + objectTreeFilter.setDefaultFilterKeyColumn(proxyModel_->filterKeyColumn()); + const auto filterFunction = objectTreeFilter.parse(input, filterResult); + + if (filterFunction && filterResult != FilterResult::Failed) { + proxyModel_->setCustomFilter(filterFunction); + restoreItemExpansionStates(); + viewport()->update(); + } } - auto filterStringRegex = "(" + filterStrings.join("|") + ")"; - - proxyModel_->setFilterRegularExpression(filterStringRegex); - restoreItemExpansionStates(); - viewport()->update(); } + return filterResult; } bool ObjectTreeView::hasProxyModel() const { @@ -343,6 +394,7 @@ QMenu* ObjectTreeView::createCustomContextMenu(const QPoint &p) { auto externalProjectModel = (dynamic_cast(treeModel_)); auto prefabModel = (dynamic_cast(treeModel_)); auto resourceModel = (dynamic_cast(treeModel_)); + bool isScenegraphView = !(prefabModel || resourceModel || externalProjectModel); bool canInsertMeshAsset = false; bool haveCreatableTypes = false; @@ -351,7 +403,7 @@ QMenu* ObjectTreeView::createCustomContextMenu(const QPoint &p) { requestNewNode(typeName, "", insertionTargetIndex); }); haveCreatableTypes = true; - if (typeName == raco::user_types::Node::typeDescription.typeName) { + if (typeName == user_types::Node::typeDescription.typeName) { canInsertMeshAsset = true; } } @@ -360,7 +412,7 @@ QMenu* ObjectTreeView::createCustomContextMenu(const QPoint &p) { treeViewMenu->addSeparator(); auto actionImport = treeViewMenu->addAction("Import glTF Assets...", [this, insertionTargetIndex]() { - auto sceneFolder = raco::core::PathManager::getCachedPath(raco::core::PathManager::FolderTypeKeys::Mesh, treeModel_->project()->currentFolder()); + auto sceneFolder = core::PathManager::getCachedPath(core::PathManager::FolderTypeKeys::Mesh, treeModel_->project()->currentFolder()); auto file = QFileDialog::getOpenFileName(this, "Load Asset File", QString::fromStdString(sceneFolder.string()), "glTF files (*.gltf *.glb);; All files (*.*)"); if (!file.isEmpty()) { treeModel_->importMeshScenegraph(file, insertionTargetIndex); @@ -439,15 +491,28 @@ QMenu* ObjectTreeView::createCustomContextMenu(const QPoint &p) { auto actionDeleteUnrefResources = treeViewMenu->addAction("Delete Unused Resources", [this] { treeModel_->deleteUnusedResources(); }); actionDeleteUnrefResources->setEnabled(treeModel_->canDeleteUnusedResources()); + if (isScenegraphView) { + treeViewMenu->addSeparator(); + treeViewMenu->addAction("Isolate Subtree", [this] () { + isolateNodes(); + }, + QKeySequence("Ctrl+I")); + + treeViewMenu->addAction( + "Hide Subtree", [this]() { + hideNodes(); + }, + QKeySequence("Ctrl+H")); + + treeViewMenu->addAction( + "Show All Nodes", [this]() { + showAllNodes(); + }, + QKeySequence("Ctrl+U")); + } + treeViewMenu->addSeparator(); - auto extrefPasteAction = treeViewMenu->addAction( - "Paste As External Reference", [this]() { - std::string error; - if (!treeModel_->pasteObjectAtIndex({}, true, &error)) { - QMessageBox::warning(this, "Paste As External Reference", - fmt::format("Update of pasted external references failed!\n\n{}", error).c_str()); - } - }); + auto extrefPasteAction = treeViewMenu->addAction("Paste As External Reference", this, &ObjectTreeView::pasteAsExtRef); // Pasting extrefs will ignore the current selection and always paste on top level. extrefPasteAction->setEnabled(treeModel_->canPasteIntoIndex({}, pasteObjects, sourceProjectTopLevelObjectIds, true)); @@ -456,7 +521,7 @@ QMenu* ObjectTreeView::createCustomContextMenu(const QPoint &p) { if (externalProjectModel) { treeViewMenu->addSeparator(); treeViewMenu->addAction("Add Project...", [this, externalProjectModel]() { - auto projectFile = QFileDialog::getOpenFileName(this, tr("Import Project"), raco::components::RaCoPreferences::instance().userProjectsDirectory, tr("Ramses Composer Assembly (*.rca);; All files (*.*)")); + auto projectFile = QFileDialog::getOpenFileName(this, tr("Import Project"), components::RaCoPreferences::instance().userProjectsDirectory, tr("Ramses Composer Assembly (*.rca);; All files (*.*)")); if (projectFile.isEmpty()) { return; } @@ -471,19 +536,28 @@ QMenu* ObjectTreeView::createCustomContextMenu(const QPoint &p) { auto actionCloseImportedProject = treeViewMenu->addAction("Remove Project", [this, selectedItemIndices, externalProjectModel]() { externalProjectModel->removeProjectsAtIndices(selectedItemIndices); }); actionCloseImportedProject->setEnabled(externalProjectModel->canRemoveProjectsAtIndices(selectedItemIndices)); + } + std::map externalProjects; + for (const auto &index : selectedItemIndices) { + const auto path = treeModel_->externalProjectPathAtIndex(index); + if (!path.empty() && externalProjects.find(path) == externalProjects.end()) { + const auto id = treeModel_->objectIdAtIndex(index); + if (!id.empty()) { + externalProjects[path] = id; + } + } } - auto paths = externalProjectModel->externalProjectPathsAtIndices(selectedItemIndices); - auto actionOpenProject = treeViewMenu->addAction("Open External Projects", [this, paths, externalProjectModel]() { - if (!paths.empty()) { - auto appPath = QCoreApplication::applicationFilePath(); - for (auto projectPath : paths) { - QProcess::startDetached(appPath, QStringList(QString::fromStdString(projectPath))); + const auto actionOpenProject = treeViewMenu->addAction("Open External Projects", [this, externalProjects]() { + if (!externalProjects.empty()) { + const auto appPath = QCoreApplication::applicationFilePath(); + for (const auto [path, id] : externalProjects) { + QProcess::startDetached(appPath, {QString::fromStdString(path), "-i", QString::fromStdString(id)}); } } }); - actionOpenProject->setEnabled(!paths.empty()); + actionOpenProject->setEnabled(!externalProjects.empty()); return treeViewMenu; } @@ -506,7 +580,7 @@ void ObjectTreeView::mousePressEvent(QMouseEvent *event) { QTreeView::mousePressEvent(event); if (!indexAt(event->pos()).isValid()) { resetSelection(); - Q_EMIT newObjectTreeItemsSelected({}); + Q_EMIT newObjectTreeItemsSelected({}, {}); } } diff --git a/gui/libObjectTree/src/object_tree_view_model/ObjectTreeNode.cpp b/gui/libObjectTree/src/object_tree_view_model/ObjectTreeNode.cpp index c83f7210..9303b2ff 100644 --- a/gui/libObjectTree/src/object_tree_view_model/ObjectTreeNode.cpp +++ b/gui/libObjectTree/src/object_tree_view_model/ObjectTreeNode.cpp @@ -9,6 +9,7 @@ */ #include "object_tree_view_model/ObjectTreeNode.h" #include "user_types/Node.h" +#include "user_types/MeshNode.h" #include #include @@ -98,10 +99,10 @@ ObjectTreeNodeType ObjectTreeNode::getType() const { namespace { std::map irregularObjectTypePluralNames{ - {raco::serialization::proxy::meshTypeName, "Meshes"}, - {raco::serialization::proxy::renderPassTypeName, "RenderPasses"}, - {raco::serialization::proxy::blitPassTypeName, "BlitPasses"}, - {raco::serialization::proxy::renderBufferMSTypeName, "RenderBufferMS"}}; + {serialization::proxy::meshTypeName, "Meshes"}, + {serialization::proxy::renderPassTypeName, "RenderPasses"}, + {serialization::proxy::blitPassTypeName, "BlitPasses"}, + {serialization::proxy::renderBufferMSTypeName, "RenderBufferMS"}}; } std::string ObjectTreeNode::getDisplayName() const { @@ -145,10 +146,10 @@ std::string ObjectTreeNode::getExternalProjectName() const { return externalProjectName_; } -VisibilityState ObjectTreeNode::getVisibility() const { +VisibilityState ObjectTreeNode::getPreviewVisibility() const { auto visibility = VisibilityState::Missing; if (representedObject_) { - if (auto node = representedObject_->as()) { + if (auto node = representedObject_->as()) { // If Enabled property is set to False, Visibility is ignored by runtime. if (*node->enabled_) { visibility = *node->visibility_ ? VisibilityState::Visible : VisibilityState::Invisible; @@ -160,6 +161,15 @@ VisibilityState ObjectTreeNode::getVisibility() const { return visibility; } +VisibilityState ObjectTreeNode::getAbstractViewVisibility() const { + if (representedObject_) { + if (auto node = representedObject_->as()) { + return *node->editorVisibility_ ? VisibilityState::Visible : VisibilityState::Invisible; + } + } + return VisibilityState::Missing; +} + void ObjectTreeNode::setBelongsToExternalProject(const std::string& path, const std::string& name) { assert(type_ == ObjectTreeNodeType::EditorObject || type_ == ObjectTreeNodeType::ExternalProject); externalProjectPath_ = path; @@ -187,7 +197,7 @@ std::string ObjectTreeNode::getID() const { std::vector ObjectTreeNode::getUserTags() const { if (type_ == ObjectTreeNodeType::EditorObject) { - return representedObject_->userTags_->asVector(); + return representedObject_->as()->userTags_->asVector(); } return {}; } diff --git a/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewDefaultModel.cpp b/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewDefaultModel.cpp index 4171ad03..8e2fcff9 100644 --- a/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewDefaultModel.cpp +++ b/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewDefaultModel.cpp @@ -35,10 +35,10 @@ namespace raco::object_tree::model { using namespace raco::core; using namespace raco::style; -ObjectTreeViewDefaultModel::ObjectTreeViewDefaultModel(raco::core::CommandInterface* commandInterface, - components::SDataChangeDispatcher dispatcher, - core::ExternalProjectsStoreInterface* externalProjectStore, - const std::vector& allowedCreatableUserTypes, +ObjectTreeViewDefaultModel::ObjectTreeViewDefaultModel(core::CommandInterface* commandInterface, + components::SDataChangeDispatcher dispatcher, + core::ExternalProjectsStoreInterface* externalProjectStore, + const std::vector& allowedCreatableUserTypes, bool groupExternalReferences, bool groupByType) : dispatcher_{dispatcher}, @@ -46,7 +46,7 @@ ObjectTreeViewDefaultModel::ObjectTreeViewDefaultModel(raco::core::CommandInterf externalProjectStore_{externalProjectStore}, allowedUserCreatableUserTypes_(allowedCreatableUserTypes), groupExternalReferences_(groupExternalReferences), - groupByType_(groupByType){ + groupByType_(groupByType) { resetInvisibleRootNode(); std::sort(allowedUserCreatableUserTypes_.begin(), allowedUserCreatableUserTypes_.end()); @@ -65,18 +65,20 @@ ObjectTreeViewDefaultModel::ObjectTreeViewDefaultModel(raco::core::CommandInterf // Small optimization: Only set model dirty if the object with the changed name is actually in the model. if (indexes_.count(handle.rootObject()->objectID()) > 0) { dirty_ = true; - } + } }; objectNameSubscription_ = dispatcher_->registerOnPropertyChange("objectName", setDirtyAction); - visibilitySubscription_ = dispatcher_->registerOnPropertyChange("visibility", setDirtyAction); - enabledSubscription_ = dispatcher_->registerOnPropertyChange("enabled", setDirtyAction); + visibilitySubscription_ = dispatcher_->registerOnPropertyChange("visibility", setDirtyAction); + enabledSubscription_ = dispatcher_->registerOnPropertyChange("enabled", setDirtyAction); + editorVisibilitySubscription_ = dispatcher_->registerOnPropertyChange("editorVisibility", setDirtyAction); + childrenSubscription_ = dispatcher_->registerOnPropertyChange("children", [this](ValueHandle handle) { dirty_ = true; }); rootOrderSubscription_ = dispatcher_->registerOnRootOrderChanged([this]() { dirty_ = true; - }); + }); extProjectChangedSubscription_ = dispatcher_->registerOnExternalProjectMapChanged([this]() { dirty_ = true; }); @@ -108,8 +110,13 @@ QVariant ObjectTreeViewDefaultModel::getNodeIcon(ObjectTreeNode* treeNode) const return QVariant(); } -QVariant ObjectTreeViewDefaultModel::getVisibilityIcon(ObjectTreeNode* treeNode) const { - auto it = visibilityIconMap_.find(treeNode->getVisibility()); +QVariant ObjectTreeViewDefaultModel::getPreviewVisibilityIcon(ObjectTreeNode* treeNode) const { + auto it = visibilityIconMap_.find(treeNode->getPreviewVisibility()); + return it != visibilityIconMap_.end() ? it->second : QVariant(); +} + +QVariant ObjectTreeViewDefaultModel::getAbstractViewVisibilityIcon(ObjectTreeNode* treeNode) const { + auto it = visibilityIconMap_.find(treeNode->getAbstractViewVisibility()); return it != visibilityIconMap_.end() ? it->second : QVariant(); } @@ -124,8 +131,10 @@ QVariant ObjectTreeViewDefaultModel::data(const QModelIndex& index, int role) co case Qt::DecorationRole: { if (index.column() == COLUMNINDEX_NAME) { return getNodeIcon(treeNode); - } else if (index.column() == COLUMNINDEX_VISIBILITY) { - return getVisibilityIcon(treeNode); + } else if (index.column() == COLUMNINDEX_PREVIEW_VISIBILITY) { + return getPreviewVisibilityIcon(treeNode); + } else if (index.column() == COLUMNINDEX_ABSTRACT_VIEW_VISIBILITY) { + return getAbstractViewVisibilityIcon(treeNode); } return QVariant(); } @@ -154,8 +163,8 @@ QVariant ObjectTreeViewDefaultModel::data(const QModelIndex& index, int role) co if (treeNode->getType() == ObjectTreeNodeType::TypeParent) { return treeNode->getParent()->getType() == ObjectTreeNodeType::ExtRefGroup - ? QVariant(Colors::color(Colormap::externalReferenceDisabled)) - : QVariant(Colors::color(Colormap::textDisabled)); + ? QVariant(Colors::color(Colormap::externalReferenceDisabled)) + : QVariant(Colors::color(Colormap::textDisabled)); } return QVariant(Colors::color(Colormap::text)); @@ -177,7 +186,9 @@ QVariant ObjectTreeViewDefaultModel::data(const QModelIndex& index, int role) co } case COLUMNINDEX_PROJECT: return QVariant(QString::fromStdString(treeNode->getExternalProjectName())); - case COLUMNINDEX_VISIBILITY: + case COLUMNINDEX_PREVIEW_VISIBILITY: + return QVariant(QString()); + case COLUMNINDEX_ABSTRACT_VIEW_VISIBILITY: return QVariant(QString()); } } @@ -204,7 +215,14 @@ QVariant ObjectTreeViewDefaultModel::headerData(int section, Qt::Orientation ori case COLUMNINDEX_PROJECT: return QVariant("Project Name"); } - } + } break; + case Qt::DecorationRole: + if (section == COLUMNINDEX_PREVIEW_VISIBILITY) { + return style::Icons::instance().screenshot; + } else if (section == COLUMNINDEX_ABSTRACT_VIEW_VISIBILITY) { + return style::Icons::instance().abstractSceneView; + } + break; } return QVariant(); @@ -236,7 +254,7 @@ QList ObjectTreeViewDefaultModel::getAcceptableFilesInfo(const QMimeD } } } - + return fileInfos; } @@ -246,26 +264,26 @@ bool ObjectTreeViewDefaultModel::canDropMimeData(const QMimeData* data, Qt::Drop } if (data->hasFormat(OBJECT_EDITOR_ID_MIME_TYPE)) { - auto idList{decodeMimeData(data)}; - auto dragDroppingProjectNode = externalProjectStore_->isExternalProject(idList.front().toStdString()); + auto idList{decodeMimeData(data)}; + auto dragDroppingProjectNode = externalProjectStore_->isExternalProject(idList.front().toStdString()); - if (dragDroppingProjectNode) { + if (dragDroppingProjectNode) { return false; - } - - auto originPath = getOriginPathFromMimeData(data); - auto droppingFromOtherProject = originPath != project()->currentPath(); - auto parentType = indexToTreeNode(parent)->getType(); - auto droppingAsExternalReference = QGuiApplication::queryKeyboardModifiers().testFlag(Qt::KeyboardModifier::AltModifier) || - parentType == ObjectTreeNodeType::ExtRefGroup; - if (droppingAsExternalReference && (!droppingFromOtherProject || parentType == ObjectTreeNodeType::EditorObject)) { + } + + auto originPath = getOriginPathFromMimeData(data); + auto droppingFromOtherProject = originPath != project()->currentPath(); + auto parentType = indexToTreeNode(parent)->getType(); + auto droppingAsExternalReference = QGuiApplication::queryKeyboardModifiers().testFlag(Qt::KeyboardModifier::AltModifier) || + parentType == ObjectTreeNodeType::ExtRefGroup; + if (droppingAsExternalReference && (!droppingFromOtherProject || parentType == ObjectTreeNodeType::EditorObject)) { return false; - } + } - if (idList.empty()) { + if (idList.empty()) { return false; - } - + } + if (!droppingFromOtherProject) { std::vector objs; for (const auto& id : idList) { @@ -273,7 +291,7 @@ bool ObjectTreeViewDefaultModel::canDropMimeData(const QMimeData* data, Qt::Drop } return (std::any_of(objs.begin(), objs.end(), [this, parent](auto obj) { return isObjectAllowedIntoIndex(parent, obj); }) && - !Queries::filterForMoveableScenegraphChildren(*project(), objs, indexToSEditorObject(parent)).empty()); + !Queries::filterForMoveableScenegraphChildren(*project(), objs, indexToSEditorObject(parent)).empty()); } else { std::vector objectsFromId; @@ -330,7 +348,7 @@ std::string ObjectTreeViewDefaultModel::getOriginPathFromMimeData(const QMimeDat return mimeDataOriginProjectPath.toStdString(); } -QMimeData* raco::object_tree::model::ObjectTreeViewDefaultModel::generateMimeData(const QModelIndexList& indexes, const std::string& originPath) const { +QMimeData* object_tree::model::ObjectTreeViewDefaultModel::generateMimeData(const QModelIndexList& indexes, const std::string& originPath) const { QMimeData* mimeData = new QMimeData(); QByteArray encodedData; @@ -528,7 +546,7 @@ SEditorObject ObjectTreeViewDefaultModel::createNewObject(const std::string& typ return obj->getParent() == parentObj; }); - auto name = project()->findAvailableUniqueName(nodes.begin(), nodes.end(), nullptr, nodeName.empty() ? raco::components::Naming::format(typeName) : nodeName); + auto name = project()->findAvailableUniqueName(nodes.begin(), nodes.end(), nullptr, nodeName.empty() ? components::Naming::format(typeName) : nodeName); auto newObj = commandInterface_->createObject(typeName, name, parent.isValid() ? parentObj : nullptr); return newObj; @@ -567,7 +585,7 @@ bool ObjectTreeViewDefaultModel::isObjectAllowedIntoIndex(const QModelIndex& ind } std::pair, std::set> ObjectTreeViewDefaultModel::getObjectsAndRootIdsFromClipboardString(const std::string& serializedObjs) const { - auto deserialization{raco::serialization::deserializeObjects(serializedObjs)}; + auto deserialization{serialization::deserializeObjects(serializedObjs)}; if (deserialization) { auto objects = BaseContext::getTopLevelObjectsFromDeserializedObjects(*deserialization, project()); return {objects, deserialization->rootObjectIDs}; @@ -638,6 +656,34 @@ void ObjectTreeViewDefaultModel::deleteUnusedResources() { commandInterface_->deleteUnreferencedResources(); } +void ObjectTreeViewDefaultModel::isolateNodes(const QModelIndexList& indices) { + auto objects = Queries::collectAllChildren(indicesToSEditorObjects(indices)); + for (auto instance : commandInterface_->project()->instances()) { + if (auto node = instance->as()) { + if (std::find(objects.begin(), objects.end(), node) == objects.end()) { + commandInterface_->set({node, &user_types::Node::editorVisibility_}, false); + } + } + } +} + +void ObjectTreeViewDefaultModel::hideNodes(const QModelIndexList& indices) { + auto objects = Queries::collectAllChildren(indicesToSEditorObjects(indices)); + for (auto object : objects) { + if (auto node = object->as()) { + commandInterface_->set({node, &user_types::Node::editorVisibility_}, false); + } + } +} + +void ObjectTreeViewDefaultModel::showAllNodes() { + for (auto instance : commandInterface_->project()->instances()) { + if (auto node = instance->as()) { + commandInterface_->set({node, &user_types::Node::editorVisibility_}, true); + } + } +} + void ObjectTreeViewDefaultModel::copyObjectsAtIndices(const QModelIndexList& indices, bool deepCopy) { auto objects = indicesToSEditorObjects(indices); RaCoClipboard::set(commandInterface_->copyObjects(objects, deepCopy)); @@ -647,7 +693,7 @@ bool ObjectTreeViewDefaultModel::pasteObjectAtIndex(const QModelIndex& index, bo bool success = true; try { commandInterface_->pasteObjects(serializedObjects, indexToSEditorObject(index), pasteAsExtref); - } catch (std::exception &error) { + } catch (std::exception& error) { success = false; if (outError) { *outError = error.what(); @@ -693,7 +739,7 @@ void ObjectTreeViewDefaultModel::importMeshScenegraph(const QString& filePath, c auto dummyCacheEntry = commandInterface_->meshCache()->registerFileChangedHandler(absPath, {nullptr, nullptr}); if (auto sceneGraphPtr = commandInterface_->meshCache()->getMeshScenegraph(absPath)) { MeshScenegraph sceneGraph{*sceneGraphPtr}; - auto importStatus = raco::common_widgets::MeshAssetImportDialog(sceneGraph, project()->featureLevel(), QFileInfo(filePath).fileName(), nullptr).exec(); + auto importStatus = common_widgets::MeshAssetImportDialog(sceneGraph, QFileInfo(filePath).fileName(), nullptr).exec(); if (importStatus == QDialog::Accepted) { commandInterface_->insertAssetScenegraph(sceneGraph, absPath, selectedObject); } @@ -756,7 +802,7 @@ void ObjectTreeViewDefaultModel::resetInvisibleRootNode() { invisibleRootNode_ = std::make_unique(ObjectTreeNodeType::Root, nullptr); } -void raco::object_tree::model::ObjectTreeViewDefaultModel::updateTreeIndexes() { +void object_tree::model::ObjectTreeViewDefaultModel::updateTreeIndexes() { indexes_.clear(); iterateThroughTree([&](const auto& modelIndex) { indexes_[indexToTreeNode(modelIndex)->getID()] = modelIndex; @@ -791,7 +837,7 @@ bool ObjectTreeViewDefaultModel::isIndexAboveInHierachyOrPosition(QModelIndex le return left.row() < right.row(); } -std::vector raco::object_tree::model::ObjectTreeViewDefaultModel::typesAllowedIntoIndex(const QModelIndex& index) const { +std::vector object_tree::model::ObjectTreeViewDefaultModel::typesAllowedIntoIndex(const QModelIndex& index) const { auto object = indexToSEditorObject(index); if (!object) { return allowedUserCreatableUserTypes_; @@ -804,7 +850,23 @@ std::vector raco::object_tree::model::ObjectTreeViewDefaultModel::t } } -std::set ObjectTreeViewDefaultModel::externalProjectPathsAtIndices(const QModelIndexList& indices) { +std::string ObjectTreeViewDefaultModel::objectIdAtIndex(const QModelIndex& index) const { + auto id = indexToTreeNode(index)->getID(); + if (!id.empty()) { + return id; + } + return {}; +} + +std::string ObjectTreeViewDefaultModel::externalProjectPathAtIndex(const QModelIndex& index) const { + auto path = indexToTreeNode(index)->getExternalProjectPath(); + if (!path.empty()) { + return path; + } + return {}; +} + +std::set ObjectTreeViewDefaultModel::externalProjectPathsAtIndices(const QModelIndexList& indices) const { std::set projectPaths; for (const auto& index : indices) { auto path = indexToTreeNode(index)->getExternalProjectPath(); @@ -819,11 +881,11 @@ void ObjectTreeViewDefaultModel::setAcceptableFileExtensions(const QStringList& acceptableFileExtensions_ = extensions; } -void ObjectTreeViewDefaultModel::setAcceptLuaModules(bool accept){ +void ObjectTreeViewDefaultModel::setAcceptLuaModules(bool accept) { acceptLuaModules_ = accept; } -void ObjectTreeViewDefaultModel::setAcceptLuaScripts(bool accept){ +void ObjectTreeViewDefaultModel::setAcceptLuaScripts(bool accept) { acceptLuaScripts_ = accept; } diff --git a/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewExternalProjectModel.cpp b/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewExternalProjectModel.cpp index 3322bfec..b1a4d687 100644 --- a/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewExternalProjectModel.cpp +++ b/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewExternalProjectModel.cpp @@ -21,7 +21,7 @@ namespace raco::object_tree::model { -ObjectTreeViewExternalProjectModel::ObjectTreeViewExternalProjectModel(raco::core::CommandInterface* commandInterface, components::SDataChangeDispatcher dispatcher, core::ExternalProjectsStoreInterface* externalProjectsStore) +ObjectTreeViewExternalProjectModel::ObjectTreeViewExternalProjectModel(core::CommandInterface* commandInterface, components::SDataChangeDispatcher dispatcher, core::ExternalProjectsStoreInterface* externalProjectsStore) : ObjectTreeViewDefaultModel(commandInterface, dispatcher, externalProjectsStore, {}, true) { // don't rebuild tree when creating/deleting local objects lifeCycleSubscription_ = components::Subscription{}; @@ -38,9 +38,9 @@ QVariant ObjectTreeViewExternalProjectModel::data(const QModelIndex& index, int if (treeNode->getType() == ObjectTreeNodeType::ExternalProject) { if (role == Qt::ForegroundRole) { if (commandInterface_->project()->usesExternalProjectByPath(indexToTreeNode(index)->getExternalProjectPath())) { - return QVariant(raco::style::Colors::color(raco::style::Colormap::externalReference)); + return QVariant(style::Colors::color(style::Colormap::externalReference)); } else { - return QVariant(raco::style::Colors::color(raco::style::Colormap::text)); + return QVariant(style::Colors::color(style::Colormap::text)); } } @@ -55,7 +55,7 @@ QVariant ObjectTreeViewExternalProjectModel::data(const QModelIndex& index, int } if (failed) { - return QVariant(raco::style::Icons::instance().error); + return QVariant(style::Icons::instance().error); } else { return QVariant(QIcon()); } @@ -70,7 +70,7 @@ void ObjectTreeViewExternalProjectModel::addProject(const QString& projectPath) loadContext.featureLevel = commandInterface_->project()->featureLevel(); loadContext.pathStack.emplace_back(commandInterface_->project()->currentPath()); if (externalProjectStore_->addExternalProject(projectPath.toStdString(), loadContext)) { - LOG_INFO(raco::log_system::OBJECT_TREE_VIEW, "Added Project {} to Project Browser", projectPath.toStdString()); + LOG_INFO(log_system::OBJECT_TREE_VIEW, "Added Project {} to Project Browser", projectPath.toStdString()); } } @@ -102,9 +102,9 @@ bool ObjectTreeViewExternalProjectModel::canRemoveProjectsAtIndices(const QModel void ObjectTreeViewExternalProjectModel::copyObjectsAtIndices(const QModelIndexList& indices, bool deepCopy) { - raco::core::CommandInterface* commandInterface = nullptr; + core::CommandInterface* commandInterface = nullptr; - std::vector objects; + std::vector objects; for (const auto& index : indices) { auto treeNode = indexToTreeNode(index); @@ -137,7 +137,7 @@ void ObjectTreeViewExternalProjectModel::setNodeExternalProjectInfo(ObjectTreeNo auto projectPath = parent->getExternalProjectPath(); auto projectName = parent->getExternalProjectName(); if (auto obj = node->getRepresentedObject()) { - if (auto extrefAnno = obj->query()) { + if (auto extrefAnno = obj->query()) { if (auto originCommandInterface = externalProjectStore_->getExternalProjectCommandInterface(projectPath)) { auto project = originCommandInterface->project(); // Keep the project path from the root project, even in case of extrefs. @@ -169,7 +169,7 @@ void ObjectTreeViewExternalProjectModel::buildObjectTree() { } std::vector ObjectTreeViewExternalProjectModel::filterForTopLevelObjects(const std::vector& objects) const { - return raco::core::Queries::filterForVisibleTopLevelObjects(objects); + return core::Queries::filterForVisibleTopLevelObjects(objects); } Qt::ItemFlags ObjectTreeViewExternalProjectModel::flags(const QModelIndex& index) const { diff --git a/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewPrefabModel.cpp b/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewPrefabModel.cpp index 024f314b..6c81ea15 100644 --- a/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewPrefabModel.cpp +++ b/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewPrefabModel.cpp @@ -17,7 +17,7 @@ namespace raco::object_tree::model { -ObjectTreeViewPrefabModel::ObjectTreeViewPrefabModel(raco::core::CommandInterface* commandInterface, components::SDataChangeDispatcher dispatcher, core::ExternalProjectsStoreInterface* externalProjectsStore, const std::vector& allowedCreatableUserTypes) +ObjectTreeViewPrefabModel::ObjectTreeViewPrefabModel(core::CommandInterface* commandInterface, components::SDataChangeDispatcher dispatcher, core::ExternalProjectsStoreInterface* externalProjectsStore, const std::vector& allowedCreatableUserTypes) : ObjectTreeViewDefaultModel(commandInterface, dispatcher, externalProjectsStore, allowedCreatableUserTypes, true) { } @@ -26,7 +26,7 @@ QVariant ObjectTreeViewPrefabModel::data(const QModelIndex& index, int role) con if (role == Qt::ItemDataRole::DecorationRole && index.column() == COLUMNINDEX_NAME) { auto editorObj = indexToSEditorObject(index); - if (editorObj && editorObj->query() && editorObj->as()) { + if (editorObj && editorObj->query() && editorObj->as()) { return QVariant(typeIconMap.at("ExtrefPrefab")); } } diff --git a/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewResourceModel.cpp b/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewResourceModel.cpp index b173306b..6fc105fd 100644 --- a/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewResourceModel.cpp +++ b/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewResourceModel.cpp @@ -19,7 +19,7 @@ namespace raco::object_tree::model { -ObjectTreeViewResourceModel::ObjectTreeViewResourceModel(raco::core::CommandInterface* commandInterface, components::SDataChangeDispatcher dispatcher, core::ExternalProjectsStoreInterface* externalProjectStore, const std::vector& allowedCreatableUserTypes) +ObjectTreeViewResourceModel::ObjectTreeViewResourceModel(core::CommandInterface* commandInterface, components::SDataChangeDispatcher dispatcher, core::ExternalProjectsStoreInterface* externalProjectStore, const std::vector& allowedCreatableUserTypes) : ObjectTreeViewDefaultModel(commandInterface, dispatcher, externalProjectStore, allowedCreatableUserTypes, true, true) {} diff --git a/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewSortProxyModels.cpp b/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewSortProxyModels.cpp index d351d1cd..b49e1965 100644 --- a/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewSortProxyModels.cpp +++ b/gui/libObjectTree/src/object_tree_view_model/ObjectTreeViewSortProxyModels.cpp @@ -8,9 +8,9 @@ * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - #include "object_tree_view_model/ObjectTreeViewSortProxyModels.h" #include "object_tree_view_model/ObjectTreeNode.h" +#include "object_tree_view_model/ObjectTreeViewDefaultModel.h" #include "style/Colors.h" #include @@ -27,22 +27,31 @@ bool ObjectTreeViewDefaultSortFilterProxyModel::sortingEnabled() const { return sortingEnabled_; } +void ObjectTreeViewDefaultSortFilterProxyModel::setCustomFilter(std::function filterFunc) { + customFilter = filterFunc; + invalidateFilter(); +} + +void ObjectTreeViewDefaultSortFilterProxyModel::removeCustomFilter() { + customFilter = nullptr; + invalidateFilter(); +} + +QString ObjectTreeViewDefaultSortFilterProxyModel::getDataAtIndex(const QModelIndex& index) const { + return data(index, Qt::DisplayRole).toString(); +} + QVariant ObjectTreeViewDefaultSortFilterProxyModel::data(const QModelIndex& index, int role) const { if (index.isValid()) { - auto nodeType = static_cast(mapToSource(index).internalPointer())->getType(); + ObjectTreeNode* treeNode = static_cast(mapToSource(index).internalPointer()); + const auto nodeType = treeNode->getType(); if (nodeType == ObjectTreeNodeType::ExtRefGroup || nodeType == ObjectTreeNodeType::TypeParent) { return QSortFilterProxyModel::data(index, role); } - auto filterRegex = filterRegularExpression(); - if (role == Qt::ForegroundRole) { - if (!filterRegex.pattern().isEmpty()) { - auto filteredIndexData = index.sibling(index.row(), filterKeyColumn()).data().toString(); - - if (!filteredIndexData.contains(filterRegex)) { - return QVariant(raco::style::Colors::color(raco::style::Colormap::textDisabled).darker(175)); - } + if (customFilter && treeNode && !customFilter(*treeNode)) { + return QVariant(style::Colors::color(style::Colormap::textDisabled).darker(175)); } } } @@ -50,6 +59,15 @@ QVariant ObjectTreeViewDefaultSortFilterProxyModel::data(const QModelIndex& inde return QSortFilterProxyModel::data(index, role); } +bool ObjectTreeViewDefaultSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const { + const auto treeNodeIndex = sourceModel()->index(sourceRow, 0, sourceParent); + const auto treeNode = static_cast(treeNodeIndex.internalPointer()); + if (customFilter && treeNode) { + return customFilter(*treeNode); + } + return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent); +} + bool ObjectTreeViewResourceSortFilterProxyModel::lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const { auto leftType = static_cast(source_left.internalPointer())->getType(); if (leftType == ObjectTreeNodeType::ExtRefGroup) { diff --git a/gui/libObjectTree/tests/CMakeLists.txt b/gui/libObjectTree/tests/CMakeLists.txt index 3b6963ec..28b31f65 100644 --- a/gui/libObjectTree/tests/CMakeLists.txt +++ b/gui/libObjectTree/tests/CMakeLists.txt @@ -9,6 +9,7 @@ If a copy of the MPL was not distributed with this file, You can obtain one at h ]] set(TEST_SOURCES ObjectTreeDockManager_test.h ObjectTreeDockManager_test.cpp + ObjectTreeFilter_test.h ObjectTreeFilter_test.cpp ObjectTreeNode_test.cpp ObjectTreeViewExternalProjectModel_test.cpp ObjectTreeViewDefaultModel_test.h ObjectTreeViewDefaultModel_test.cpp @@ -30,3 +31,9 @@ raco_package_add_gui_test( "${TEST_LIBRARIES}" ${CMAKE_CURRENT_BINARY_DIR} ) + +get_target_property(object_tree_private_includes raco::ObjectTree INCLUDE_DIRECTORIES) +get_target_property(object_tree_private_libraries raco::ObjectTree LINK_LIBRARIES) + +target_include_directories(libObjectTree_test PRIVATE ${object_tree_private_includes}) +target_link_libraries(libObjectTree_test ${object_tree_private_libraries}) diff --git a/gui/libObjectTree/tests/ObjectTreeDockManager_test.cpp b/gui/libObjectTree/tests/ObjectTreeDockManager_test.cpp index 46457e80..c9505d76 100644 --- a/gui/libObjectTree/tests/ObjectTreeDockManager_test.cpp +++ b/gui/libObjectTree/tests/ObjectTreeDockManager_test.cpp @@ -14,7 +14,7 @@ #include "object_tree_view/ObjectTreeDock.h" #include "object_tree_view_model/ObjectTreeViewDefaultModel.h" -using namespace raco::object_tree::view; +using namespace object_tree::view; TEST_F(ObjectDefaultTreeDockManagerTest, DockCachingEmpty) { ASSERT_EQ(manager_.getTreeDockAmount(), 0); } @@ -54,9 +54,9 @@ TEST_F(ObjectDefaultTreeDockManagerTest, DockRemovalTwoDocksOneRemovedByDealloca TEST_F(ObjectDefaultTreeDockManagerTest, DockWithUnselectedItemIsNotConsideredSelectedAnymore) { auto firstDock = generateDockInManager(); - auto model = new raco::object_tree::model::ObjectTreeViewDefaultModel(&commandInterface, dispatcher_, nullptr, {raco::user_types::Node::typeDescription.typeName}); - firstDock->setTreeView(new raco::object_tree::view::ObjectTreeView("TreeView", model)); - auto obj = model->createNewObject(raco::user_types::Node::typeDescription.typeName, "name"); + auto model = new object_tree::model::ObjectTreeViewDefaultModel(&commandInterface, dispatcher_, nullptr, {user_types::Node::typeDescription.typeName}); + firstDock->setTreeView(new object_tree::view::ObjectTreeView("TreeView", model)); + auto obj = model->createNewObject(user_types::Node::typeDescription.typeName, "name"); dispatcher_->dispatch(recorder); firstDock->getActiveTreeView()->selectObject(QString::fromStdString(obj->objectID())); ASSERT_TRUE(manager_.getActiveDockWithSelection() == firstDock.get()); diff --git a/gui/libObjectTree/tests/ObjectTreeDockManager_test.h b/gui/libObjectTree/tests/ObjectTreeDockManager_test.h index d9a3dbe7..22990d69 100644 --- a/gui/libObjectTree/tests/ObjectTreeDockManager_test.h +++ b/gui/libObjectTree/tests/ObjectTreeDockManager_test.h @@ -17,14 +17,14 @@ class ObjectDefaultTreeDockManagerTest : public TestEnvironmentCore { protected: - raco::object_tree::view::ObjectTreeDockManager manager_; + object_tree::view::ObjectTreeDockManager manager_; int argc = 0; QApplication fakeApp_{argc, nullptr}; - raco::components::SDataChangeDispatcher dispatcher_{std::make_shared()}; + components::SDataChangeDispatcher dispatcher_{std::make_shared()}; - std::unique_ptr generateDockInManager() { + std::unique_ptr generateDockInManager() { auto dockName = std::string("Dock").append(std::to_string(manager_.getTreeDockAmount())); - auto newDock = std::make_unique(dockName.c_str()); + auto newDock = std::make_unique(dockName.c_str()); manager_.addTreeDock(newDock.get()); diff --git a/gui/libObjectTree/tests/ObjectTreeFilter_test.cpp b/gui/libObjectTree/tests/ObjectTreeFilter_test.cpp new file mode 100644 index 00000000..7d4da1cc --- /dev/null +++ b/gui/libObjectTree/tests/ObjectTreeFilter_test.cpp @@ -0,0 +1,81 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include +#include "gtest/gtest.h" +#include "ObjectTreeFilter_test.h" +#include "object_tree_view/ObjectTreeFilter.h" + + +using namespace object_tree::model; +using namespace raco::core; + +TEST_P(ObjectTreeFilterTestFixture, ParametricParsingTest) { + using FilterResult = object_tree::view::FilterResult; + const auto valid = std::get<0>(GetParam()); + const auto input = std::get<1>(GetParam()); + const auto ids = std::get<2>(GetParam()); + + FilterResult filterResult = input.isEmpty() ? FilterResult::Success : FilterResult::Failed; + object_tree::view::ObjectTreeFilter filter; + const auto filterFunction = filter.parse(input.toStdString(), filterResult); + + ASSERT_EQ(filterFunction != nullptr, valid); + proxyModel_.setCustomFilter(filterFunction); + + QStringList parsedIds{}; + for (int row = 0; row < proxyModel_.rowCount(); ++row) { + const auto idIndex = proxyModel_.index(row, ObjectTreeViewDefaultModel::ColumnIndex::COLUMNINDEX_ID); + const auto id = proxyModel_.getDataAtIndex(idIndex); + + parsedIds.append(id); + } + EXPECT_EQ(parsedIds, ids); +} + +// Define the parameter values for the test cases +INSTANTIATE_TEST_SUITE_P(ParametricTests, ObjectTreeFilterTestFixture, + ::testing::Values( + // Pair: Parsing string / IDs list + std::make_tuple(true, QString("name = \"name1\" | type != \"Node\""), QStringList({"id_01", "id_02", "id_03", "id_04", "id_06", "id_07", "id_08", "id_09", "id_10"})), + std::make_tuple(true, QString("name = \"name1\" | type != \"Node\" & name != \"name2\""), QStringList({"id_01", "id_02", "id_06", "id_07", "id_08", "id_09", "id_10"})), + std::make_tuple(true, QString("(name = \"name1\" | type != \"Node\") & name != \"name2\""), QStringList({"id_01", "id_02", "id_06", "id_07", "id_08", "id_09", "id_10"})), + std::make_tuple(true, QString("(name = \"name1\" & type != \"Node\") & name != \"name4\""), QStringList({"id_02"})), + std::make_tuple(true, QString("(name = \"name1\" & (type != \"Node\")) & name != \"name4\""), QStringList({"id_02"})), + + std::make_tuple(true, QString("(name = \"name1\" & (type != \"Node\")) & tag != tag1"), QStringList({"id_02"})), + std::make_tuple(true, QString("(name = \"name1\" & (type != \"Node\")) | tag != tag1"), QStringList({"id_02", "id_03", "id_04", "id_06", "id_09", "id_10"})), + std::make_tuple(true, QString("(name = \"name1\" | (tag != tag1))"), QStringList({"id_01", "id_02", "id_03", "id_04", "id_06", "id_09", "id_10"})), + std::make_tuple(true, QString("(name != \"name1\" & tag != tag3)"), QStringList({"id_04", "id_08", "id_09", "id_10"})), + std::make_tuple(true, QString("name != \"name1\" & id != \"id_04\""), QStringList({"id_03", "id_05", "id_06", "id_07", "id_08", "id_09", "id_10"})), + + std::make_tuple(true, QString("name != \"name1\" & id != \"id_04\""), QStringList({"id_03", "id_05", "id_06", "id_07", "id_08", "id_09", "id_10"})), + std::make_tuple(true, QString("name != \"name3\" & (type = \"Node\") & tag != tag1"), QStringList({})), + std::make_tuple(true, QString("(name != \"name3\" & (type = \"Node\")) | tag != tag1"), QStringList({"id_01", "id_02", "id_03", "id_04", "id_06", "id_09", "id_10"})), + std::make_tuple(true, QString("(name != \"name3\" | type = \"Node\") & tag != tag1"), QStringList({"id_02", "id_03", "id_04", "id_09", "id_10"})), + std::make_tuple(true, QString("(name != \"name3\" | (type = \"Node\")) | (tag != tag1)"), QStringList({"id_01", "id_02", "id_03", "id_04", "id_05", "id_06", "id_07", "id_08", "id_09", "id_10"})), + + std::make_tuple(true, QString("name != \"name3\" | type = \"Node\" | (tag != tag1)"), QStringList({"id_01", "id_02", "id_03", "id_04", "id_05", "id_06", "id_07", "id_08", "id_09", "id_10"})), + std::make_tuple(true, QString("name = name1 | type != \"Node\""), QStringList({"id_01", "id_02", "id_03", "id_04", "id_06", "id_07", "id_08", "id_09", "id_10"})), + std::make_tuple(true, QString("name = name1 | type != Node"), QStringList({"id_01", "id_02", "id_03", "id_04", "id_07", "id_08", "id_09", "id_10"})), + std::make_tuple(true, QString("name = name1 | type != \"Node\" & name != \"name2\""), QStringList({"id_01", "id_02", "id_06", "id_07", "id_08", "id_09", "id_10"})), + std::make_tuple(true, QString("name = name1 | type != Node & name != \"name2\""), QStringList({"id_01", "id_02", "id_07", "id_08", "id_09", "id_10"})), + + std::make_tuple(true, QString("name = name1 | type != Node & name != name2"), QStringList({"id_01", "id_02", "id_07", "id_08", "id_09", "id_10"})), + std::make_tuple(true, QString("(name = name1 | type != \"Node\") & name != \"name2\""), QStringList({"id_01", "id_02", "id_06", "id_07", "id_08", "id_09", "id_10"})), + std::make_tuple(true, QString("(name = name1 & type != \"Node\") & name != name4"), QStringList({"id_02"})), + std::make_tuple(true, QString("(name = name1 & (type != Node)) & name != name4"), QStringList({})), + std::make_tuple(true, QString("(name = name1 & (type != \"Node\")) & tag != \"tag1\""), QStringList({"id_02"})), + + std::make_tuple(true, QString("(name = name1 & (type != Node)) | tag != \"tag1\""), QStringList({"id_02", "id_03", "id_04", "id_06", "id_09", "id_10"})), + std::make_tuple(true, QString("(name = name1 & (type != Node)) | tag = \"tag1\""), QStringList({"id_01", "id_05", "id_07", "id_08"})), + std::make_tuple(false, QString("(name = \"name5 (1)\" & (type ! Node)) | tag = 3"), QStringList({"id_01", "id_02", "id_03", "id_04", "id_05", "id_06", "id_07", "id_08", "id_09", "id_10"})), + std::make_tuple(true, QString("(name = '(1)' & (type != Node)) | tag = 'tag7 (3)'"), QStringList({"id_09", "id_10"}))) +); diff --git a/gui/libObjectTree/tests/ObjectTreeFilter_test.h b/gui/libObjectTree/tests/ObjectTreeFilter_test.h new file mode 100644 index 00000000..a53fd466 --- /dev/null +++ b/gui/libObjectTree/tests/ObjectTreeFilter_test.h @@ -0,0 +1,95 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include +#include "application/RaCoApplication.h" +#include "ramses_base/BaseEngineBackend.h" + +#include "user_types/Node.h" +#include "user_types/MeshNode.h" +#include "user_types/PrefabInstance.h" +#include "user_types/OrthographicCamera.h" +#include "user_types/PerspectiveCamera.h" +#include "user_types/Animation.h" +#include "user_types/LuaInterface.h" +#include "user_types/Skin.h" + +#include "object_tree_view_model/ObjectTreeViewDefaultModel.h" +#include "object_tree_view_model/ObjectTreeViewSortProxyModels.h" + +#include + +class ObjectTreeFilterTestFixture : public RacoBaseTest<::testing::TestWithParam>> { + +public: + ObjectTreeFilterTestFixture() : RacoBaseTest < ::testing::TestWithParam < std::tuple >> () { + static const std::vector allowedCreateableUserTypes{ + user_types::Node::typeDescription.typeName, + user_types::MeshNode::typeDescription.typeName, + user_types::PrefabInstance::typeDescription.typeName, + user_types::OrthographicCamera::typeDescription.typeName, + user_types::PerspectiveCamera::typeDescription.typeName, + user_types::Animation::typeDescription.typeName, + user_types::LuaInterface::typeDescription.typeName, + user_types::Skin::typeDescription.typeName}; + + sourceModel_ = std::make_unique(commandInterface(), dataChangeDispatcher(), externalProjects(), allowedCreateableUserTypes); + + // Create data for the sample source model + const std::vector names = {"name1", "name1", "name2", "name2", "name3", "name3", "name4", "name4", "'name5 (1)'", "'name 6(1)'"}; + const std::vector types = {"Node", "MeshNode", "PrefabInstance", "PerspectiveCamera", "Node", "MeshNode", "PrefabInstance", "PerspectiveCamera", "OrthographicCamera", "OrthographicCamera"}; + const std::vector ids = {"id_01", "id_02", "id_03", "id_04", "id_05", "id_06", "id_07", "id_08", "id_09", "id_10"}; + const std::vector> tags = { {"tag1", "tag4"}, {"tag2", "tag4"}, {"tag3", "tag2"}, {"tag4", "tag2"}, {"tag1", "tag3"}, {"tag2", "tag3"}, {"tag3", "tag1"}, {"tag4", "tag1"}, {"tag5", "tag6"}, {"tag5", "'tag7 (3)'"}}; + + // Fill the sample source model with the data + for (int i = 0; i < names.size(); ++i) { + const auto object = commandInterface()->createObject(types.at(i), names.at(i)); + + const auto tagsHandle = core::ValueHandle(object, {"userTags"}); + const auto idHandle = core::ValueHandle(object, {"objectID"}); + + commandInterface()->setTags(tagsHandle, tags.at(i)); + commandInterface()->set(idHandle, ids.at(i)); + + application.dataChangeDispatcher()->dispatch(recorder().release()); + } + + proxyModel_.setSourceModel(sourceModel_.get()); + } + +protected: + std::unique_ptr sourceModel_; + object_tree::model::ObjectTreeViewDefaultSortFilterProxyModel proxyModel_; + +private: + // ObjectTreeViewDefaultModel icons initialization uses QPixmap, which requires existing QGuiApplication. + int argc_ = 0; + QGuiApplication fakeGuiApp_{argc_, nullptr}; + + ramses_base::HeadlessEngineBackend backend{}; + raco::application::RaCoApplication application{backend, {{}, false, false, -1, -1, false}}; + + core::ExternalProjectsStoreInterface* externalProjects() { + return application.externalProjects(); + } + + core::CommandInterface* commandInterface() { + return application.activeRaCoProject().commandInterface(); + } + + core::DataChangeRecorder& recorder() { + return *application.activeRaCoProject().recorder(); + } + + components::SDataChangeDispatcher dataChangeDispatcher() { + return application.dataChangeDispatcher(); + } +}; \ No newline at end of file diff --git a/gui/libObjectTree/tests/ObjectTreeViewDefaultModel_test.cpp b/gui/libObjectTree/tests/ObjectTreeViewDefaultModel_test.cpp index dcb1a0f5..1c9f81f7 100644 --- a/gui/libObjectTree/tests/ObjectTreeViewDefaultModel_test.cpp +++ b/gui/libObjectTree/tests/ObjectTreeViewDefaultModel_test.cpp @@ -29,20 +29,20 @@ #include using namespace raco::core; -using namespace raco::object_tree::model; +using namespace object_tree::model; using namespace raco::user_types; ObjectTreeViewDefaultModelTest::ObjectTreeViewDefaultModelTest() - : viewModel_{new raco::object_tree::model::ObjectTreeViewDefaultModel(&commandInterface(), application.dataChangeDispatcher(), externalProjectStore(), - {raco::user_types::Animation::typeDescription.typeName, - raco::user_types::Node::typeDescription.typeName, - raco::user_types::MeshNode::typeDescription.typeName, - raco::user_types::PrefabInstance::typeDescription.typeName, - raco::user_types::OrthographicCamera::typeDescription.typeName, - raco::user_types::PerspectiveCamera::typeDescription.typeName, - raco::user_types::LuaScript::typeDescription.typeName, - raco::user_types::LuaInterface::typeDescription.typeName, - raco::user_types::Skin::typeDescription.typeName})} { + : viewModel_{new object_tree::model::ObjectTreeViewDefaultModel(&commandInterface(), application.dataChangeDispatcher(), externalProjectStore(), + {user_types::Animation::typeDescription.typeName, + user_types::Node::typeDescription.typeName, + user_types::MeshNode::typeDescription.typeName, + user_types::PrefabInstance::typeDescription.typeName, + user_types::OrthographicCamera::typeDescription.typeName, + user_types::PerspectiveCamera::typeDescription.typeName, + user_types::LuaScript::typeDescription.typeName, + user_types::LuaInterface::typeDescription.typeName, + user_types::Skin::typeDescription.typeName})} { } @@ -58,11 +58,13 @@ void ObjectTreeViewDefaultModelTest::compareValuesInTree(const SEditorObject &ob objValue = obj->objectName(); break; } - case ObjectTreeViewDefaultModel::COLUMNINDEX_VISIBILITY: { - auto visibilityTreeValue = objTreeNode->getVisibility(); + case ObjectTreeViewDefaultModel::COLUMNINDEX_PREVIEW_VISIBILITY: { + auto visibilityTreeValue = objTreeNode->getPreviewVisibility(); auto visibilityObjValue = obj->get("visibility")->asBool() ? VisibilityState::Visible : VisibilityState::Invisible; ASSERT_EQ(visibilityTreeValue, visibilityObjValue); } break; + case ObjectTreeViewDefaultModel::COLUMNINDEX_ABSTRACT_VIEW_VISIBILITY: { + } break; case (ObjectTreeViewDefaultModel::COLUMNINDEX_TYPE): { treeValue = objTreeNode->getRepresentedObject()->getTypeDescription().typeName; objValue = obj->getTypeDescription().typeName; @@ -80,7 +82,7 @@ void ObjectTreeViewDefaultModelTest::compareValuesInTree(const SEditorObject &ob break; case ObjectTreeViewDefaultModel::COLUMNINDEX_USERTAGS: { auto treeValue = objTreeNode->getUserTags(); - auto objValue = obj->userTags_->asVector(); + auto objValue = obj->as()->userTags_->asVector(); ASSERT_EQ(treeValue, objValue); } break; @@ -93,7 +95,7 @@ void ObjectTreeViewDefaultModelTest::compareValuesInTree(const SEditorObject &ob } } -std::vector ObjectTreeViewDefaultModelTest::createAllSceneGraphObjects() { +std::vector ObjectTreeViewDefaultModelTest::createAllSceneGraphObjects() { std::vector allSceneGraphNodes; for (const auto &typeName : getTypes()) { auto newNode = createNodes(typeName, {typeName}); @@ -105,11 +107,11 @@ std::vector ObjectTreeViewDefaultModelTest::createAll return allSceneGraphNodes; } -std::vector ObjectTreeViewDefaultModelTest::createAllResources() { - std::vector allResources; +std::vector ObjectTreeViewDefaultModelTest::createAllResources() { + std::vector allResources; for (const auto &typeName : getTypes()) { auto newNode = createNodes(typeName, {typeName}); - if (raco::core::Queries::isResource(newNode.front())) { + if (core::Queries::isResource(newNode.front())) { allResources.emplace_back(newNode.front()); } } @@ -988,7 +990,7 @@ TEST_F(ObjectTreeViewDefaultModelTest, AllowedObjsDeepCopiedSceneGraphWithResour auto meshNode = createNodes(MeshNode::typeDescription.typeName, {MeshNode::typeDescription.typeName}).front(); auto mesh = createNodes(Mesh::typeDescription.typeName, {Mesh::typeDescription.typeName}).front(); - commandInterface().set(raco::core::ValueHandle{meshNode, {"mesh"}}, mesh); + commandInterface().set(core::ValueHandle{meshNode, {"mesh"}}, mesh); dispatch(); auto cutObjs = commandInterface().cutObjects({meshNode}, true); @@ -1002,7 +1004,7 @@ TEST_F(ObjectTreeViewDefaultModelTest, AllowedObjsDeepCopiedPrefabInstanceWithPr auto prefabInstance = createNodes(PrefabInstance::typeDescription.typeName, {PrefabInstance::typeDescription.typeName}).front(); auto prefab = createNodes(Prefab::typeDescription.typeName, {Prefab::typeDescription.typeName}).front(); - commandInterface().set(raco::core::ValueHandle{prefabInstance, {"template"}}, prefab); + commandInterface().set(core::ValueHandle{prefabInstance, {"template"}}, prefab); dispatch(); auto cutObjs = commandInterface().cutObjects({prefabInstance}, true); @@ -1014,7 +1016,7 @@ TEST_F(ObjectTreeViewDefaultModelTest, AllowedObjsDeepCopiedPrefabInstanceWithPr TEST_F(ObjectTreeViewDefaultModelTest, AllowedObjsLuaScriptIsAllowedAsExtRefOnTopLevel) { auto luaScript = createNodes(LuaScript::typeDescription.typeName, {LuaScript::typeDescription.typeName}).front(); - luaScript->addAnnotation(std::make_shared("differentProject")); + luaScript->addAnnotation(std::make_shared("differentProject")); dispatch(); auto cutObjs = commandInterface().cutObjects({luaScript}, true); @@ -1031,8 +1033,8 @@ TEST_F(ObjectTreeViewDefaultModelTest, AllowedObjsChildLuaScriptIsNotAllowedAsEx auto localParentNode = createNodes(Node::typeDescription.typeName, {"localParent"}).front(); moveScenegraphChildren({luaScript}, externalParentNode); - externalParentNode->addAnnotation(std::make_shared("differentProject")); - luaScript->addAnnotation(std::make_shared("differentProject")); + externalParentNode->addAnnotation(std::make_shared("differentProject")); + luaScript->addAnnotation(std::make_shared("differentProject")); dispatch(); auto cutObjs = commandInterface().cutObjects({luaScript}, true); @@ -1047,7 +1049,7 @@ TEST_F(ObjectTreeViewDefaultModelTest, AllowedObjsChildLuaScriptIsNotAllowedAsEx TEST_F(ObjectTreeViewDefaultModelTest, PasteLuaScriptAsExtRefNotAllowedAsChild) { auto luaScript = createNodes(LuaScript::typeDescription.typeName, {LuaScript::typeDescription.typeName}).front(); auto localParentNode = createNodes(Node::typeDescription.typeName, {"localParent"}).front(); - luaScript->addAnnotation(std::make_shared("differentProject")); + luaScript->addAnnotation(std::make_shared("differentProject")); dispatch(); auto cutObjs = commandInterface().cutObjects({luaScript}, true); @@ -1063,7 +1065,7 @@ TEST_F(ObjectTreeViewDefaultModelTest, PasteLuaScriptAsExtRefNotAllowedWhenChild auto externalParentNode = createNodes(Node::typeDescription.typeName, {"externalParentNode"}).front(); auto localParentNode = createNodes(Node::typeDescription.typeName, {"localParent"}).front(); moveScenegraphChildren({luaScript}, externalParentNode); - luaScript->addAnnotation(std::make_shared("differentProject")); + luaScript->addAnnotation(std::make_shared("differentProject")); dispatch(); auto cutObjs = commandInterface().cutObjects({luaScript}, true); @@ -1090,7 +1092,7 @@ TEST_F(ObjectTreeViewDefaultModelTest, CanNotMoveNodesInsidePrefabInstance) { moveScenegraphChildren({node}, prefab); dispatch(); - commandInterface().set({prefabInstance, &raco::user_types::PrefabInstance::template_}, prefab); + commandInterface().set({prefabInstance, &user_types::PrefabInstance::template_}, prefab); dispatch(); auto mimeData = viewModel_->mimeData({viewModel_->indexFromTreeNodeID(prefabInstance->children_->asVector().front()->objectID())}); diff --git a/gui/libObjectTree/tests/ObjectTreeViewDefaultModel_test.h b/gui/libObjectTree/tests/ObjectTreeViewDefaultModel_test.h index 8938d5dd..54a49ca1 100644 --- a/gui/libObjectTree/tests/ObjectTreeViewDefaultModel_test.h +++ b/gui/libObjectTree/tests/ObjectTreeViewDefaultModel_test.h @@ -31,8 +31,8 @@ class ObjectTreeViewDefaultModelTest : public RaCoApplicationTest { public: - std::vector createNodes(const std::string &type, const std::vector &nodeNames) { - std::vector createdNodes; + std::vector createNodes(const std::string &type, const std::vector &nodeNames) { + std::vector createdNodes; for (const auto &name : nodeNames) { createdNodes.emplace_back(commandInterface().createObject(type, name)); @@ -42,7 +42,7 @@ class ObjectTreeViewDefaultModelTest : public RaCoApplicationTest { return createdNodes; } - void moveScenegraphChildren(std::vector const &objects, raco::core::SEditorObject parent, int row = -1) { + void moveScenegraphChildren(std::vector const &objects, core::SEditorObject parent, int row = -1) { viewModel_->moveScenegraphChildren(objects, parent, row); application.dataChangeDispatcher()->dispatch(recorder().release()); } @@ -53,7 +53,7 @@ class ObjectTreeViewDefaultModelTest : public RaCoApplicationTest { return delObjAmount; } - std::string modelIndexToString(raco::object_tree::model::ObjectTreeViewDefaultModel &viewModel, const QModelIndex ¤tIndex, Qt::ItemDataRole role = Qt::DisplayRole) { + std::string modelIndexToString(object_tree::model::ObjectTreeViewDefaultModel &viewModel, const QModelIndex ¤tIndex, Qt::ItemDataRole role = Qt::DisplayRole) { return viewModel.data((currentIndex), role).toString().toStdString(); } @@ -64,7 +64,7 @@ class ObjectTreeViewDefaultModelTest : public RaCoApplicationTest { std::vector getTypes() { std::vector names; for (const auto &[typeName, typeInfo] : viewModel_->objectFactory()->getTypes()) { - if (viewModel_->objectFactory()->isUserCreatable(typeName, raco::ramses_base::BaseEngineBackend::maxFeatureLevel)) { + if (viewModel_->objectFactory()->isUserCreatable(typeName, ramses_base::BaseEngineBackend::maxFeatureLevel)) { names.emplace_back(typeName); } } @@ -77,12 +77,12 @@ class ObjectTreeViewDefaultModelTest : public RaCoApplicationTest { QGuiApplication fakeGuiApp_{argc_, nullptr}; std::vector nodeNames_; - std::unique_ptr viewModel_; + std::unique_ptr viewModel_; ObjectTreeViewDefaultModelTest(); - void compareValuesInTree(const raco::core::SEditorObject &obj, const QModelIndex &objIndex, const raco::object_tree::model::ObjectTreeViewDefaultModel &viewModel); + void compareValuesInTree(const core::SEditorObject &obj, const QModelIndex &objIndex, const object_tree::model::ObjectTreeViewDefaultModel &viewModel); - std::vector createAllSceneGraphObjects(); - std::vector createAllResources(); + std::vector createAllSceneGraphObjects(); + std::vector createAllResources(); }; diff --git a/gui/libObjectTree/tests/ObjectTreeViewExternalProjectModel_test.cpp b/gui/libObjectTree/tests/ObjectTreeViewExternalProjectModel_test.cpp index 9b75ace7..42b4c56f 100644 --- a/gui/libObjectTree/tests/ObjectTreeViewExternalProjectModel_test.cpp +++ b/gui/libObjectTree/tests/ObjectTreeViewExternalProjectModel_test.cpp @@ -46,12 +46,12 @@ class ExposedObjectTreeViewExternalProjectModel : public model::ObjectTreeViewEx class ObjectTreeViewExternalProjectModelTest : public ObjectTreeViewDefaultModelTest { protected: - raco::ramses_base::HeadlessEngineBackend otherBackend{raco::ramses_base::BaseEngineBackend::maxFeatureLevel}; + ramses_base::HeadlessEngineBackend otherBackend; raco::application::RaCoApplication otherApplication{otherBackend}; ExposedObjectTreeViewExternalProjectModel externalProjectModel{application}; - void generateExternalProject(const std::vector &instances, std::string projectPath = "projectPath.rca") { - application.externalProjectsStore_.externalProjects_[projectPath] = raco::application::RaCoProject::createNew(&otherApplication, true, static_cast(raco::ramses_base::BaseEngineBackend::maxFeatureLevel)); + void generateExternalProject(const std::vector &instances, std::string projectPath = "projectPath.rca") { + application.externalProjectsStore_.externalProjects_[projectPath] = raco::application::RaCoProject::createNew(&otherApplication, true, static_cast(ramses_base::BaseEngineBackend::maxFeatureLevel)); auto project = application.externalProjectsStore_.externalProjects_[projectPath]->project(); for (const auto &instance : instances) { @@ -62,7 +62,7 @@ class ObjectTreeViewExternalProjectModelTest : public ObjectTreeViewDefaultModel TEST_F(ObjectTreeViewExternalProjectModelTest, InstantiationNoLocalInstancesInModel) { - commandInterface().createObject(raco::user_types::Node::typeDescription.typeName); + commandInterface().createObject(user_types::Node::typeDescription.typeName); externalProjectModel.triggerObjectTreeRebuilding(); ASSERT_TRUE(externalProjectModel.indexes().empty()); } @@ -82,9 +82,9 @@ TEST_F(ObjectTreeViewExternalProjectModelTest, LoadingProjectEmpty) { TEST_F(ObjectTreeViewExternalProjectModelTest, LoadingProjectTenTopLevelNodes) { constexpr size_t CHILD_NODE_AMOUNT = 10; - std::vector instances; + std::vector instances; for (size_t i{0}; i < CHILD_NODE_AMOUNT; ++i) { - instances.emplace_back(std::make_shared()); + instances.emplace_back(std::make_shared()); } generateExternalProject(instances); @@ -97,10 +97,10 @@ TEST_F(ObjectTreeViewExternalProjectModelTest, LoadingProjectTenTopLevelNodes) { TEST_F(ObjectTreeViewExternalProjectModelTest, LoadingProjectHierarchyParentsCreatedFirst) { constexpr size_t NODE_AMOUNT = 5; - std::vector instances; + std::vector instances; for (size_t i{0}; i < NODE_AMOUNT; ++i) { - instances.emplace_back(otherApplication.activeRaCoProject().commandInterface()->createObject(raco::user_types::Node::typeDescription.typeName, "node_" + std::to_string(i))); + instances.emplace_back(otherApplication.activeRaCoProject().commandInterface()->createObject(user_types::Node::typeDescription.typeName, "node_" + std::to_string(i))); } for (size_t i{0}; i < NODE_AMOUNT - 1; ++i) { @@ -122,10 +122,10 @@ TEST_F(ObjectTreeViewExternalProjectModelTest, LoadingProjectHierarchyParentsCre TEST_F(ObjectTreeViewExternalProjectModelTest, LoadingProjectHierarchyChildrenCreatedFirst) { constexpr size_t NODE_AMOUNT = 5; - std::vector instances; + std::vector instances; for (int i{NODE_AMOUNT - 1}; i >= 0; --i) { - instances.emplace_back(otherApplication.activeRaCoProject().commandInterface()->createObject(raco::user_types::Node::typeDescription.typeName, "node_" + std::to_string(i))); + instances.emplace_back(otherApplication.activeRaCoProject().commandInterface()->createObject(user_types::Node::typeDescription.typeName, "node_" + std::to_string(i))); } for (size_t i{1}; i < NODE_AMOUNT; ++i) { @@ -147,12 +147,12 @@ TEST_F(ObjectTreeViewExternalProjectModelTest, LoadingProjectHierarchyChildrenCr TEST_F(ObjectTreeViewExternalProjectModelTest, LoadingProjectHierarchyRetainChildrenOrder) { constexpr size_t CHILD_NODE_AMOUNT = 3; - std::vector instances; + std::vector instances; - auto rootNode = instances.emplace_back(otherApplication.activeRaCoProject().commandInterface()->createObject(raco::user_types::Node::typeDescription.typeName, "myRoot")); + auto rootNode = instances.emplace_back(otherApplication.activeRaCoProject().commandInterface()->createObject(user_types::Node::typeDescription.typeName, "myRoot")); for (size_t i{0}; i < CHILD_NODE_AMOUNT; ++i) { - auto childNode = instances.emplace_back(otherApplication.activeRaCoProject().commandInterface()->createObject(raco::user_types::Node::typeDescription.typeName, "node_" + std::to_string(i))); + auto childNode = instances.emplace_back(otherApplication.activeRaCoProject().commandInterface()->createObject(user_types::Node::typeDescription.typeName, "node_" + std::to_string(i))); otherApplication.activeRaCoProject().commandInterface()->moveScenegraphChildren({childNode}, rootNode, 0); } @@ -169,10 +169,10 @@ TEST_F(ObjectTreeViewExternalProjectModelTest, LoadingProjectHierarchyRetainChil TEST_F(ObjectTreeViewExternalProjectModelTest, CanCopyAtIndicesMultiSelection) { std::string project1Path = "project1Path.rca"; - auto project1Node = std::make_shared(); + auto project1Node = std::make_shared(); generateExternalProject({project1Node}, project1Path); - auto project2Node = std::make_shared(); + auto project2Node = std::make_shared(); std::string project2Path = "project2Path.rca"; generateExternalProject({project2Node}, project2Path); @@ -205,7 +205,7 @@ TEST_F(ObjectTreeViewExternalProjectModelTest, CanCopyAtIndicesMultiSelection) { TEST_F(ObjectTreeViewExternalProjectModelTest, CanDeleteAtIndicesNever) { std::string project1Path = "project1Path.rca"; - auto project1Node = std::make_shared(); + auto project1Node = std::make_shared(); generateExternalProject({project1Node}, project1Path); externalProjectModel.triggerObjectTreeRebuilding(); @@ -222,7 +222,7 @@ TEST_F(ObjectTreeViewExternalProjectModelTest, CanDeleteAtIndicesNever) { TEST_F(ObjectTreeViewExternalProjectModelTest, CanNeverDuplicate) { std::string project1Path = "project1Path.rca"; - auto project1Node = std::make_shared(); + auto project1Node = std::make_shared(); generateExternalProject({project1Node}, project1Path); externalProjectModel.triggerObjectTreeRebuilding(); diff --git a/gui/libObjectTree/tests/ObjectTreeViewMultipleModels_test.cpp b/gui/libObjectTree/tests/ObjectTreeViewMultipleModels_test.cpp index 6f60d116..45841b34 100644 --- a/gui/libObjectTree/tests/ObjectTreeViewMultipleModels_test.cpp +++ b/gui/libObjectTree/tests/ObjectTreeViewMultipleModels_test.cpp @@ -11,12 +11,12 @@ #include "ObjectTreeViewMultipleModels_test.h" using namespace raco::core; -using namespace raco::object_tree::model; +using namespace object_tree::model; using namespace raco::user_types; TEST_F(ObjectTreeViewMultipleModelsTest, MoveTopLevelNodeUnderPrefab) { - auto node = createNodes(raco::user_types::Node::typeDescription.typeName, {"Node"}).front(); + auto node = createNodes(user_types::Node::typeDescription.typeName, {"Node"}).front(); moveScenegraphChildren({node}, prefab_); auto *prefabNode = prefabModel_.indexToTreeNode(prefabModel_.index(0, 0, {})); @@ -28,7 +28,7 @@ TEST_F(ObjectTreeViewMultipleModelsTest, MoveTopLevelNodeUnderPrefab) { } TEST_F(ObjectTreeViewMultipleModelsTest, MovePrefabNodeToTopLevel) { - auto node = createNodes(raco::user_types::Node::typeDescription.typeName, {"Node"}).front(); + auto node = createNodes(user_types::Node::typeDescription.typeName, {"Node"}).front(); moveScenegraphChildren({node}, prefab_); moveScenegraphChildren({node}, nullptr); @@ -42,8 +42,8 @@ TEST_F(ObjectTreeViewMultipleModelsTest, MovePrefabNodeToTopLevel) { TEST_F(ObjectTreeViewMultipleModelsTest, MoveChildNodeUnderPrefab) { - auto nodeParent = createNodes(raco::user_types::Node::typeDescription.typeName, {"NodeParent"}).front(); - auto node = createNodes(raco::user_types::Node::typeDescription.typeName, {"Node"}).front(); + auto nodeParent = createNodes(user_types::Node::typeDescription.typeName, {"NodeParent"}).front(); + auto node = createNodes(user_types::Node::typeDescription.typeName, {"Node"}).front(); moveScenegraphChildren({node}, nodeParent); moveScenegraphChildren({node}, prefab_); @@ -59,8 +59,8 @@ TEST_F(ObjectTreeViewMultipleModelsTest, MoveChildNodeUnderPrefab) { } TEST_F(ObjectTreeViewMultipleModelsTest, MovePrefabNodeToNodeParent) { - auto nodeParent = createNodes(raco::user_types::Node::typeDescription.typeName, {"NodeParent"}).front(); - auto node = createNodes(raco::user_types::Node::typeDescription.typeName, {"Node"}).front(); + auto nodeParent = createNodes(user_types::Node::typeDescription.typeName, {"NodeParent"}).front(); + auto node = createNodes(user_types::Node::typeDescription.typeName, {"Node"}).front(); moveScenegraphChildren({node}, prefab_); moveScenegraphChildren({node}, nodeParent); diff --git a/gui/libObjectTree/tests/ObjectTreeViewMultipleModels_test.h b/gui/libObjectTree/tests/ObjectTreeViewMultipleModels_test.h index f81c28d6..7600e4f9 100644 --- a/gui/libObjectTree/tests/ObjectTreeViewMultipleModels_test.h +++ b/gui/libObjectTree/tests/ObjectTreeViewMultipleModels_test.h @@ -18,14 +18,14 @@ class ObjectTreeViewMultipleModelsTest : public ObjectTreeViewDefaultModelTest { protected: - raco::object_tree::model::ObjectTreeViewPrefabModel prefabModel_; - raco::core::SEditorObject prefab_; + object_tree::model::ObjectTreeViewPrefabModel prefabModel_; + core::SEditorObject prefab_; ObjectTreeViewMultipleModelsTest() : ObjectTreeViewDefaultModelTest(), - prefabModel_(&commandInterface(), application.dataChangeDispatcher(), nullptr, {raco::user_types::Prefab::typeDescription.typeName}) { + prefabModel_(&commandInterface(), application.dataChangeDispatcher(), nullptr, {user_types::Prefab::typeDescription.typeName}) { } void SetUp() override { - prefab_ = createNodes(raco::user_types::Prefab::typeDescription.typeName, {"Prefab"}).front(); + prefab_ = createNodes(user_types::Prefab::typeDescription.typeName, {"Prefab"}).front(); } }; diff --git a/gui/libObjectTree/tests/ObjectTreeViewPrefabModel_test.cpp b/gui/libObjectTree/tests/ObjectTreeViewPrefabModel_test.cpp index 1b57d622..a98e8327 100644 --- a/gui/libObjectTree/tests/ObjectTreeViewPrefabModel_test.cpp +++ b/gui/libObjectTree/tests/ObjectTreeViewPrefabModel_test.cpp @@ -21,7 +21,7 @@ using namespace raco::user_types; class ObjectTreeViewPrefabModelTest : public ObjectTreeViewDefaultModelTest { public: ObjectTreeViewPrefabModelTest() : ObjectTreeViewDefaultModelTest() { - viewModel_.reset(new raco::object_tree::model::ObjectTreeViewPrefabModel(&commandInterface(), application.dataChangeDispatcher(), externalProjectStore(), + viewModel_.reset(new object_tree::model::ObjectTreeViewPrefabModel(&commandInterface(), application.dataChangeDispatcher(), externalProjectStore(), { Prefab::typeDescription.typeName })); @@ -71,7 +71,7 @@ TEST_F(ObjectTreeViewPrefabModelTest, TypesAllowedIntoIndexNode) { TEST_F(ObjectTreeViewPrefabModelTest, AllowedObjsResourcesAreNotAllowedOnTopLevel) { for (const auto &typeName : getTypes()) { auto newObj = commandInterface().createObject(typeName); - if (raco::core::Queries::isResource(newObj)) { + if (core::Queries::isResource(newObj)) { ASSERT_FALSE(viewModel_->isObjectAllowedIntoIndex({}, newObj)); } } @@ -82,7 +82,7 @@ TEST_F(ObjectTreeViewPrefabModelTest, AllowedObjsResourcesAreNotAllowedUnderPref for (const auto &typeName : getTypes()) { auto newObj = commandInterface().createObject(typeName); - if (raco::core::Queries::isResource(newObj)) { + if (core::Queries::isResource(newObj)) { ASSERT_FALSE(viewModel_->isObjectAllowedIntoIndex(viewModel_->indexFromTreeNodeID(prefab->objectID()), newObj)); } } @@ -91,7 +91,7 @@ TEST_F(ObjectTreeViewPrefabModelTest, AllowedObjsResourcesAreNotAllowedUnderPref TEST_F(ObjectTreeViewPrefabModelTest, AllowedObjsCheckSceneGraphObjectsOnTopLevel) { for (const auto &typeName : getTypes()) { auto newObj = commandInterface().createObject(typeName); - if (!raco::core::Queries::isResource(newObj)) { + if (!core::Queries::isResource(newObj)) { if (typeName == Prefab::typeDescription.typeName) { ASSERT_TRUE(viewModel_->isObjectAllowedIntoIndex({}, newObj)); } else { @@ -107,7 +107,7 @@ TEST_F(ObjectTreeViewPrefabModelTest, AllowedObjsCheckExternalSceneGraphObjectsU for (const auto &typeName : getTypes()) { auto newObj = commandInterface().createObject(typeName); - if (!raco::core::Queries::isResource(newObj) && !raco::core::Queries::isProjectSettings(newObj)) { + if (!core::Queries::isResource(newObj) && !core::Queries::isProjectSettings(newObj)) { if (newObj->as()) { ASSERT_FALSE(viewModel_->isObjectAllowedIntoIndex(prefabIndex, newObj)); } else { @@ -129,7 +129,7 @@ TEST_F(ObjectTreeViewPrefabModelTest, AllowedObjsDeepCopiedSceneGraphWithResourc auto meshNode = createNodes(MeshNode::typeDescription.typeName, {MeshNode::typeDescription.typeName}).front(); auto mesh = createNodes(Mesh::typeDescription.typeName, {Mesh::typeDescription.typeName}).front(); - commandInterface().set(raco::core::ValueHandle{meshNode, {"mesh"}}, mesh); + commandInterface().set(core::ValueHandle{meshNode, {"mesh"}}, mesh); dispatch(); auto cutObjs = commandInterface().cutObjects({meshNode}, true); @@ -144,7 +144,7 @@ TEST_F(ObjectTreeViewPrefabModelTest, AllowedObjsDeepCopiedSceneGraphWithResourc auto mesh = createNodes(Mesh::typeDescription.typeName, {Mesh::typeDescription.typeName}).front(); auto prefab = createNodes(Prefab::typeDescription.typeName, {Prefab::typeDescription.typeName}).front(); - commandInterface().set(raco::core::ValueHandle{meshNode, {"mesh"}}, mesh); + commandInterface().set(core::ValueHandle{meshNode, {"mesh"}}, mesh); dispatch(); auto copiedObjs = commandInterface().copyObjects({meshNode}, true); @@ -158,7 +158,7 @@ TEST_F(ObjectTreeViewPrefabModelTest, AllowedObjsDeepCopiedPrefabInstanceWithPre auto prefabInstance = createNodes(PrefabInstance::typeDescription.typeName, {PrefabInstance::typeDescription.typeName}).front(); auto prefab = createNodes(Prefab::typeDescription.typeName, {Prefab::typeDescription.typeName}).front(); - commandInterface().set(raco::core::ValueHandle{prefabInstance, {"template"}}, prefab); + commandInterface().set(core::ValueHandle{prefabInstance, {"template"}}, prefab); dispatch(); auto cutObjs = commandInterface().cutObjects({prefabInstance}, true); @@ -173,7 +173,7 @@ TEST_F(ObjectTreeViewPrefabModelTest, AllowedObjsDeepCopiedPrefabIsAllowedInEmpt auto mesh = createNodes(Mesh::typeDescription.typeName, {Mesh::typeDescription.typeName}).front(); auto prefab = createNodes(Prefab::typeDescription.typeName, {Prefab::typeDescription.typeName}).front(); - commandInterface().set(raco::core::ValueHandle{meshNode, {"mesh"}}, mesh); + commandInterface().set(core::ValueHandle{meshNode, {"mesh"}}, mesh); dispatch(); commandInterface().moveScenegraphChildren({meshNode}, prefab); @@ -191,7 +191,7 @@ TEST_F(ObjectTreeViewPrefabModelTest, AllowedObjsDeepCopiedPrefabIsNotAllowedUnd auto mesh = createNodes(Mesh::typeDescription.typeName, {Mesh::typeDescription.typeName}).front(); auto prefabs = createNodes(Prefab::typeDescription.typeName, {"prefab", "prefab2"}); - commandInterface().set(raco::core::ValueHandle{meshNode, {"mesh"}}, mesh); + commandInterface().set(core::ValueHandle{meshNode, {"mesh"}}, mesh); dispatch(); commandInterface().moveScenegraphChildren({meshNode}, prefabs.front()); @@ -206,7 +206,7 @@ TEST_F(ObjectTreeViewPrefabModelTest, AllowedObjsDeepCopiedPrefabIsNotAllowedUnd TEST_F(ObjectTreeViewPrefabModelTest, AllowedObjsNothingIsAllowedUnderExtRef) { auto extRefPrefab = createNodes(Prefab::typeDescription.typeName, {Prefab::typeDescription.typeName}).front(); - extRefPrefab->addAnnotation(std::make_shared("differentProject")); + extRefPrefab->addAnnotation(std::make_shared("differentProject")); viewModel_->buildObjectTree(); auto extRefPrefabIndex = viewModel_->indexFromTreeNodeID(extRefPrefab->objectID()); @@ -217,18 +217,18 @@ TEST_F(ObjectTreeViewPrefabModelTest, AllowedObjsNothingIsAllowedUnderExtRef) { } auto extRefGroupIndex = viewModel_->index(0, 0); - ASSERT_EQ(viewModel_->indexToTreeNode(extRefGroupIndex)->getType(), raco::object_tree::model::ObjectTreeNodeType::ExtRefGroup); + ASSERT_EQ(viewModel_->indexToTreeNode(extRefGroupIndex)->getType(), object_tree::model::ObjectTreeNodeType::ExtRefGroup); ASSERT_FALSE(viewModel_->isObjectAllowedIntoIndex(extRefGroupIndex, commandInterface().createObject(Node::typeDescription.typeName))); ASSERT_TRUE(viewModel_->isObjectAllowedIntoIndex(extRefGroupIndex, commandInterface().createObject(Prefab::typeDescription.typeName))); } TEST_F(ObjectTreeViewPrefabModelTest, CanNotDoAnythingButPasteWithExtRefGroup) { auto extRefPrefab = createNodes(Prefab::typeDescription.typeName, {Prefab::typeDescription.typeName}).front(); - extRefPrefab->addAnnotation(std::make_shared("differentProject")); + extRefPrefab->addAnnotation(std::make_shared("differentProject")); viewModel_->buildObjectTree(); auto extRefGroupIndex = viewModel_->index(0, 0); - ASSERT_EQ(viewModel_->indexToTreeNode(extRefGroupIndex)->getType(), raco::object_tree::model::ObjectTreeNodeType::ExtRefGroup); + ASSERT_EQ(viewModel_->indexToTreeNode(extRefGroupIndex)->getType(), object_tree::model::ObjectTreeNodeType::ExtRefGroup); ASSERT_FALSE(viewModel_->canDeleteAtIndices({extRefGroupIndex})); ASSERT_FALSE(viewModel_->canCopyAtIndices({extRefGroupIndex})); @@ -267,9 +267,9 @@ TEST_F(ObjectTreeViewPrefabModelTest, DuplicationExtrefPrefabCanNotBeDuplicated) moveScenegraphChildren(allSceneGraphNodes, extRefPrefab); - extRefPrefab->addAnnotation(std::make_shared("differentProject")); + extRefPrefab->addAnnotation(std::make_shared("differentProject")); for (auto &node : allSceneGraphNodes) { - node->addAnnotation(std::make_shared("differentProject")); + node->addAnnotation(std::make_shared("differentProject")); } ASSERT_FALSE(viewModel_->canDuplicateAtIndices({viewModel_->indexFromTreeNodeID(extRefPrefab->objectID())})); diff --git a/gui/libObjectTree/tests/ObjectTreeViewResourceModel_test.cpp b/gui/libObjectTree/tests/ObjectTreeViewResourceModel_test.cpp index 1da7f638..3732c2e3 100644 --- a/gui/libObjectTree/tests/ObjectTreeViewResourceModel_test.cpp +++ b/gui/libObjectTree/tests/ObjectTreeViewResourceModel_test.cpp @@ -31,7 +31,7 @@ using namespace raco::user_types; class ObjectTreeViewResourceModelTest : public ObjectTreeViewDefaultModelTest { public: ObjectTreeViewResourceModelTest() : ObjectTreeViewDefaultModelTest() { - viewModel_.reset(new raco::object_tree::model::ObjectTreeViewResourceModel(&commandInterface(), application.dataChangeDispatcher(), nullptr, + viewModel_.reset(new object_tree::model::ObjectTreeViewResourceModel(&commandInterface(), application.dataChangeDispatcher(), nullptr, { AnchorPoint::typeDescription.typeName, AnimationChannel::typeDescription.typeName, @@ -46,6 +46,7 @@ class ObjectTreeViewResourceModelTest : public ObjectTreeViewDefaultModelTest { RenderBuffer::typeDescription.typeName, RenderBufferMS::typeDescription.typeName, RenderTarget::typeDescription.typeName, + RenderTargetMS::typeDescription.typeName, RenderLayer::typeDescription.typeName, RenderPass::typeDescription.typeName})); } @@ -66,6 +67,7 @@ TEST_F(ObjectTreeViewResourceModelTest, TypesAllowedIntoIndexEmptyIndex) { RenderLayer::typeDescription.typeName, RenderPass::typeDescription.typeName, RenderTarget::typeDescription.typeName, + RenderTargetMS::typeDescription.typeName, Texture::typeDescription.typeName, TextureExternal::typeDescription.typeName, Timer::typeDescription.typeName}; @@ -90,7 +92,7 @@ TEST_F(ObjectTreeViewResourceModelTest, TypesAllowedIntoIndexAnyTypeBehavesLikeE TEST_F(ObjectTreeViewResourceModelTest, AllowedObjsResourcesAreAllowedOnTopLevel) { for (const auto &typeName : getTypes()) { auto newObj = commandInterface().createObject(typeName); - if (raco::core::Queries::isResource(newObj)) { + if (core::Queries::isResource(newObj)) { ASSERT_TRUE(viewModel_->isObjectAllowedIntoIndex({}, newObj)); } } @@ -103,7 +105,7 @@ TEST_F(ObjectTreeViewResourceModelTest, DuplicationCanNotDuplicateNothing) { TEST_F(ObjectTreeViewResourceModelTest, DuplicationResourcesCanBeDuplicated) { for (const auto &typeName : getTypes()) { auto newObj = commandInterface().createObject(typeName); - if (raco::core::Queries::isResource(newObj)) { + if (core::Queries::isResource(newObj)) { auto newObj = createNodes(typeName, {typeName}).front(); ASSERT_TRUE(viewModel_->canDuplicateAtIndices({viewModel_->indexFromTreeNodeID(newObj->objectID())})); } @@ -113,9 +115,9 @@ TEST_F(ObjectTreeViewResourceModelTest, DuplicationResourcesCanBeDuplicated) { TEST_F(ObjectTreeViewResourceModelTest, DuplicationExtRefResourcesCanNotBeDuplicated) { for (const auto &typeName : getTypes()) { auto newObj = commandInterface().createObject(typeName); - if (raco::core::Queries::isResource(newObj)) { + if (core::Queries::isResource(newObj)) { auto newObj = createNodes(typeName, {typeName}).front(); - newObj->addAnnotation(std::make_shared("differentProject")); + newObj->addAnnotation(std::make_shared("differentProject")); ASSERT_FALSE(viewModel_->canDuplicateAtIndices({viewModel_->indexFromTreeNodeID(newObj->objectID())})); } @@ -125,8 +127,8 @@ TEST_F(ObjectTreeViewResourceModelTest, DuplicationExtRefResourcesCanNotBeDuplic TEST_F(ObjectTreeViewResourceModelTest, AllowedObjsResourcesAreAllowedOnTopLevelAsExtRefs) { for (const auto &typeName : getTypes()) { auto newObj = commandInterface().createObject(typeName); - if (raco::core::Queries::isResource(newObj)) { - newObj->addAnnotation(std::make_shared("differentProject")); + if (core::Queries::isResource(newObj)) { + newObj->addAnnotation(std::make_shared("differentProject")); auto copiedObjs = commandInterface().copyObjects({newObj}, true); dispatch(); @@ -141,7 +143,7 @@ TEST_F(ObjectTreeViewResourceModelTest, AllowedObjsResourcesAreAllowedWithResour auto allResources = createAllResources(); for (const auto &typeName : getTypes()) { auto newObj = commandInterface().createObject(typeName); - if (raco::core::Queries::isResource(newObj)) { + if (core::Queries::isResource(newObj)) { for (const auto &resourceInScene : allResources) { ASSERT_FALSE(viewModel_->isObjectAllowedIntoIndex(viewModel_->indexFromTreeNodeID(resourceInScene->objectID()), newObj)); ASSERT_TRUE(viewModel_->isObjectAllowedIntoIndex({}, newObj)); @@ -154,8 +156,8 @@ TEST_F(ObjectTreeViewResourceModelTest, AllowedObjsResourcesAreAllowedAsExtRef) auto allResources = createAllResources(); for (const auto &typeName : getTypes()) { auto newObj = commandInterface().createObject(typeName); - if (raco::core::Queries::isResource(newObj)) { - newObj->addAnnotation(std::make_shared("differentProject")); + if (core::Queries::isResource(newObj)) { + newObj->addAnnotation(std::make_shared("differentProject")); auto copyObjs = commandInterface().copyObjects({newObj}, true); dispatch(); @@ -170,7 +172,7 @@ TEST_F(ObjectTreeViewResourceModelTest, AllowedObjsSceneGraphObjectsAreNotAllowe auto allResources = createAllResources(); for (const auto &typeName : getTypes()) { auto newObj = commandInterface().createObject(typeName); - if (!raco::core::Queries::isResource(newObj)) { + if (!core::Queries::isResource(newObj)) { ASSERT_FALSE(viewModel_->isObjectAllowedIntoIndex({}, newObj)); } } @@ -203,7 +205,7 @@ TEST_F(ObjectTreeViewResourceModelTest, AllowedObjsDeepCopiedSceneGraphWithResou auto meshNode = createNodes(MeshNode::typeDescription.typeName, {MeshNode::typeDescription.typeName}).front(); auto mesh = createNodes(Mesh::typeDescription.typeName, {Mesh::typeDescription.typeName}).front(); - commandInterface().set(raco::core::ValueHandle{meshNode, {"mesh"}}, mesh); + commandInterface().set(core::ValueHandle{meshNode, {"mesh"}}, mesh); dispatch(); auto cutObjs = commandInterface().cutObjects({meshNode}, true); @@ -217,7 +219,7 @@ TEST_F(ObjectTreeViewResourceModelTest, AllowedObjsDeepCopiedPrefabInstanceWithP auto prefabInstance = createNodes(PrefabInstance::typeDescription.typeName, {PrefabInstance::typeDescription.typeName}).front(); auto prefab = createNodes(Prefab::typeDescription.typeName, {Prefab::typeDescription.typeName}).front(); - commandInterface().set(raco::core::ValueHandle{prefabInstance, {"template"}}, prefab); + commandInterface().set(core::ValueHandle{prefabInstance, {"template"}}, prefab); dispatch(); auto cutObjs = commandInterface().cutObjects({prefabInstance}, true); @@ -229,27 +231,27 @@ TEST_F(ObjectTreeViewResourceModelTest, AllowedObjsDeepCopiedPrefabInstanceWithP TEST_F(ObjectTreeViewResourceModelTest, AllowedObjsNoSceneGraphObjectsAreAllowedUnderExtRef) { auto extRefMesh = createNodes(Mesh::typeDescription.typeName, {Mesh::typeDescription.typeName}).front(); - extRefMesh->addAnnotation(std::make_shared("differentProject")); + extRefMesh->addAnnotation(std::make_shared("differentProject")); viewModel_->buildObjectTree(); auto extRefMeshIndex = viewModel_->indexFromTreeNodeID(extRefMesh->objectID()); auto extRefGroupIndex = viewModel_->index(0, 0); - ASSERT_EQ(viewModel_->indexToTreeNode(extRefGroupIndex)->getType(), raco::object_tree::model::ObjectTreeNodeType::ExtRefGroup); + ASSERT_EQ(viewModel_->indexToTreeNode(extRefGroupIndex)->getType(), object_tree::model::ObjectTreeNodeType::ExtRefGroup); for (const auto &typeName : getTypes()) { auto newObj = commandInterface().createObject(typeName); ASSERT_FALSE(viewModel_->isObjectAllowedIntoIndex(extRefMeshIndex, newObj)); - ASSERT_EQ(viewModel_->isObjectAllowedIntoIndex(extRefGroupIndex, newObj), raco::core::Queries::isResource(newObj)); + ASSERT_EQ(viewModel_->isObjectAllowedIntoIndex(extRefGroupIndex, newObj), core::Queries::isResource(newObj)); } } TEST_F(ObjectTreeViewResourceModelTest, CanNotDoAnythingButPasteWithExtRefGroup) { auto extRefMesh = createNodes(Mesh::typeDescription.typeName, {Mesh::typeDescription.typeName}).front(); - extRefMesh->addAnnotation(std::make_shared("differentProject")); + extRefMesh->addAnnotation(std::make_shared("differentProject")); viewModel_->buildObjectTree(); auto extRefGroupIndex = viewModel_->index(0, 0); - ASSERT_EQ(viewModel_->indexToTreeNode(extRefGroupIndex)->getType(), raco::object_tree::model::ObjectTreeNodeType::ExtRefGroup); + ASSERT_EQ(viewModel_->indexToTreeNode(extRefGroupIndex)->getType(), object_tree::model::ObjectTreeNodeType::ExtRefGroup); ASSERT_FALSE(viewModel_->canDeleteAtIndices({extRefGroupIndex})); ASSERT_FALSE(viewModel_->canCopyAtIndices({extRefGroupIndex})); diff --git a/gui/libPropertyBrowser/CMakeLists.txt b/gui/libPropertyBrowser/CMakeLists.txt index 8f296696..50070129 100644 --- a/gui/libPropertyBrowser/CMakeLists.txt +++ b/gui/libPropertyBrowser/CMakeLists.txt @@ -11,11 +11,16 @@ If a copy of the MPL was not distributed with this file, You can obtain one at h find_package(Qt5 COMPONENTS Widgets Test REQUIRED) add_library(libPropertyBrowser + include/property_browser/controls/ColorChannelInfo.h + include/property_browser/controls/ColorChannelListWidget.h src/controls/ColorChannelListWidget.cpp include/property_browser/controls/ExpandButton.h src/controls/ExpandButton.cpp + include/property_browser/controls/ImageWidget.h src/controls/ImageWidget.cpp include/property_browser/controls/MouseWheelGuard.h src/controls/MouseWheelGuard.cpp include/property_browser/controls/ScalarSlider.h src/controls/ScalarSlider.cpp include/property_browser/controls/SpinBox.h src/controls/SpinBox.cpp + include/property_browser/controls/TexturePreviewWidget.h src/controls/TexturePreviewWidget.cpp + include/property_browser/editors/ArrayEditor.h src/editors/ArrayEditor.cpp include/property_browser/editors/BoolEditor.h src/editors/BoolEditor.cpp include/property_browser/editors/DoubleEditor.h src/editors/DoubleEditor.cpp include/property_browser/editors/EnumerationEditor.h src/editors/EnumerationEditor.cpp @@ -27,6 +32,7 @@ add_library(libPropertyBrowser include/property_browser/editors/RefEditor.h src/editors/RefEditor.cpp include/property_browser/editors/StringEditor.h src/editors/StringEditor.cpp include/property_browser/editors/TagContainerEditor.h src/editors/TagContainerEditor.cpp + include/property_browser/editors/TexturePreviewEditor.h src/editors/TexturePreviewEditor.cpp include/property_browser/editors/URIEditor.h src/editors/URIEditor.cpp include/property_browser/editors/VecNTEditor.h src/editors/VecNTEditor.cpp @@ -37,6 +43,7 @@ add_library(libPropertyBrowser include/property_browser/PropertyBrowserCache.h src/PropertyBrowserCache.cpp include/property_browser/PropertyBrowserEditorPopup.h src/PropertyBrowserEditorPopup.cpp include/property_browser/PropertyBrowserItem.h src/PropertyBrowserItem.cpp + include/property_browser/PropertyCopyPaste.h src/PropertyCopyPaste.cpp include/property_browser/PropertyBrowserLayouts.h include/property_browser/PropertyBrowserModel.h include/property_browser/PropertyBrowserRef.h src/PropertyBrowserRef.cpp @@ -44,6 +51,7 @@ add_library(libPropertyBrowser include/property_browser/PropertyBrowserWidget.h src/PropertyBrowserWidget.cpp include/property_browser/PropertySubtreeChildrenContainer.h src/PropertySubtreeChildrenContainer.cpp include/property_browser/PropertySubtreeView.h src/PropertySubtreeView.cpp + include/property_browser/Utilities.h include/property_browser/WidgetFactory.h src/WidgetFactory.cpp src/editors/TagContainerEditor/TagContainerEditor_AppliedTagModel.h src/editors/TagContainerEditor/TagContainerEditor_AppliedTagModel.cpp diff --git a/gui/libPropertyBrowser/include/property_browser/LinkStartSearchView.h b/gui/libPropertyBrowser/include/property_browser/LinkStartSearchView.h index d83a90bb..5e0be2d7 100644 --- a/gui/libPropertyBrowser/include/property_browser/LinkStartSearchView.h +++ b/gui/libPropertyBrowser/include/property_browser/LinkStartSearchView.h @@ -41,7 +41,7 @@ class LinkStartSearchView : public ObjectSearchView { std::set objects_; components::Subscription projectChanges_; - std::map outputsChanges_; + std::map outputsChanges_; }; } // namespace raco::property_browser \ No newline at end of file diff --git a/gui/libPropertyBrowser/include/property_browser/PropertyBrowserItem.h b/gui/libPropertyBrowser/include/property_browser/PropertyBrowserItem.h index 556235c4..ecf11f90 100644 --- a/gui/libPropertyBrowser/include/property_browser/PropertyBrowserItem.h +++ b/gui/libPropertyBrowser/include/property_browser/PropertyBrowserItem.h @@ -13,6 +13,7 @@ #include "core/Context.h" #include "core/CommandInterface.h" #include "core/CoreFormatter.h" +#include "core/SceneBackendInterface.h" #include "components/EditorObjectFormatter.h" #include "core/ErrorItem.h" #include "core/Handles.h" @@ -31,6 +32,8 @@ class PropertyBrowserModel; class PropertyBrowserRef; +// TODO create AbstractPropertyBrowserItem interface + /** * Indirection wrapper around ValueHandle. */ @@ -40,7 +43,7 @@ class PropertyBrowserItem final : public QObject { public: inline static const QString MultipleValueText = "Multiple values"; - PropertyBrowserItem(const std::set& valueHandles, components::SDataChangeDispatcher dispatcher, core::CommandInterface* commandInterface, PropertyBrowserModel* model, PropertyBrowserItem* parent = nullptr); + PropertyBrowserItem(const std::set& valueHandles, components::SDataChangeDispatcher dispatcher, core::CommandInterface* commandInterface, PropertyBrowserModel* model, core::SceneBackendInterface* sceneBackend = nullptr, PropertyBrowserItem* parent = nullptr); core::PrimitiveType type() const noexcept; std::string luaTypeName() const noexcept; std::string displayName() const noexcept; @@ -58,6 +61,19 @@ class PropertyBrowserItem final : public QObject { return valueHandles_.begin()->query(); } + // Query this item and all parent items excluding the root item which is not a real property: + template + core::AnnotationHandle searchAnnotationInParents() const { + auto current = this; + while (current->parentItem()) { + if (auto anno = current->query()) { + return anno; + } + current = current->parentItem(); + } + return core::AnnotationHandle(*valueHandles_.begin(), static_cast(nullptr)); + } + template void set(T v) { if constexpr (std::is_same::value) { @@ -84,6 +100,8 @@ class PropertyBrowserItem final : public QObject { void setTags(std::vector const& tags); void setTags(std::vector> const& prioritizedTags); + void resizeArray(size_t newSize); + core::Project* project() const; const core::CommandInterface* commandInterface() const; core::CommandInterface* commandInterface(); @@ -104,7 +122,8 @@ class PropertyBrowserItem final : public QObject { const std::set& valueHandles() noexcept; const QList& children(); - PropertyBrowserItem* findNamedChild(const std::string& propertyName); + PropertyBrowserItem* findNamedChild(std::string_view propertyName); + PropertyBrowserItem* findNamedChildByPropertyPath(std::string_view propertyPath); PropertyBrowserItem* parentItem() const noexcept; PropertyBrowserItem* rootItem() noexcept; PropertyBrowserItem* siblingItem(std::string_view propertyName) const noexcept; @@ -136,6 +155,10 @@ class PropertyBrowserItem final : public QObject { bool hasSingleValue() const; bool isObject() const; bool isProperty() const; + /** + * @brief Root of the item hierarchy for which special layout rules apply. + */ + bool isRootItem() const; void getTagsInfo(std::set>& renderedBy, bool& isMultipleRenderedBy, std::set>& addedTo, bool& isMultipleAddedTo) const; bool isTagContainerProperty() const; @@ -144,6 +167,31 @@ class PropertyBrowserItem final : public QObject { std::string getPropertyPath() const; std::string getPropertyPathWithoutObject() const; + void highlightProperty(const QString& propertyName); + std::string labelToolTipText() const; + QString propertyControlToolTipText() const; + + QStringList objectNames() const; + QString displayObjectNames() const; + + struct ContextMenuAction { + std::string description; + bool enabled; + std::function action; + }; + + /** + * @brief Return current context menu actions for the property browser label + */ + virtual std::vector contextMenuActions(); // override + + struct DisplayErrorItem { + core::ErrorLevel level; + QString message; + }; + + virtual std::vector getDisplayErrorItems() const; + Q_SIGNALS: void linkStateChanged(); void childrenChangedOrCollapsedChildChanged(); @@ -154,6 +202,10 @@ class PropertyBrowserItem final : public QObject { void childrenChanged(const QList& children); void editableChanged(bool editable); void widgetRequestFocus(); + void highlighted(); + void propertyControlToolTipTextChanged(const QString& text); + + void displayErrorChanged(); protected: Q_SLOT void updateLinkState() noexcept; @@ -183,8 +235,7 @@ class PropertyBrowserItem final : public QObject { } bool allHandlesHaveSamePropName() const; - bool isHidden(core::ValueHandle handle) const; - + bool isHidden(core::ValueHandle handle, bool isMultiSelect) const; PropertyBrowserItem* parentItem_{nullptr}; PropertyBrowserRef* refItem_{nullptr}; @@ -200,9 +251,13 @@ class PropertyBrowserItem final : public QObject { std::vector linkLifecycleStartSubs_; std::vector linkLifecycleEndSubs_; std::vector childrenChangeSubs_; + // TOOD maybe find a better way!? currently needed for the object name display "error" item + std::vector objectNameChangeSubscriptions_; + core::CommandInterface* commandInterface_; components::SDataChangeDispatcher dispatcher_; PropertyBrowserModel* model_; + core::SceneBackendInterface* sceneBackend_; QList children_; bool expanded_; bool editable_ = true; diff --git a/gui/libPropertyBrowser/include/property_browser/PropertyBrowserLayouts.h b/gui/libPropertyBrowser/include/property_browser/PropertyBrowserLayouts.h index a0f4e4c3..15a19d58 100644 --- a/gui/libPropertyBrowser/include/property_browser/PropertyBrowserLayouts.h +++ b/gui/libPropertyBrowser/include/property_browser/PropertyBrowserLayouts.h @@ -17,8 +17,8 @@ namespace raco::property_browser { -using PropertyBrowserGridLayout = raco::common_widgets::NoContentMarginsLayout; -using PropertyBrowserVBoxLayout = raco::common_widgets::NoContentMarginsLayout; -using PropertyBrowserHBoxLayout = raco::common_widgets::NoContentMarginsLayout; +using PropertyBrowserGridLayout = common_widgets::NoContentMarginsLayout; +using PropertyBrowserVBoxLayout = common_widgets::NoContentMarginsLayout; +using PropertyBrowserHBoxLayout = common_widgets::NoContentMarginsLayout; } // namespace raco::property_browser diff --git a/gui/libPropertyBrowser/include/property_browser/PropertyBrowserModel.h b/gui/libPropertyBrowser/include/property_browser/PropertyBrowserModel.h index 5d72c164..0bcee7b2 100644 --- a/gui/libPropertyBrowser/include/property_browser/PropertyBrowserModel.h +++ b/gui/libPropertyBrowser/include/property_browser/PropertyBrowserModel.h @@ -24,11 +24,7 @@ class PropertyBrowserModel final : public QObject { explicit PropertyBrowserModel(QObject* parent = nullptr) noexcept : QObject{parent} {} Q_SIGNALS: - void addNotVisible(QWidget* source); - void removeNotVisible(QWidget* source); - void beforeStructuralChange(QWidget* toChange = nullptr); - void beforeRemoveWidget(QWidget* toRemove); - void objectSelectionRequested(const QString objectID); + void selectionRequested(const QString objectID, const QString objectProperty = {}); }; } // namespace raco::property_browser diff --git a/gui/libPropertyBrowser/include/property_browser/PropertyBrowserWidget.h b/gui/libPropertyBrowser/include/property_browser/PropertyBrowserWidget.h index 646d2458..7ddf4c40 100644 --- a/gui/libPropertyBrowser/include/property_browser/PropertyBrowserWidget.h +++ b/gui/libPropertyBrowser/include/property_browser/PropertyBrowserWidget.h @@ -9,12 +9,12 @@ */ #pragma once -#include -#include - #include "core/SceneBackendInterface.h" #include "property_browser/PropertyBrowserItem.h" #include "property_browser/PropertyBrowserLayouts.h" +#include "property_browser/PropertySubtreeView.h" + +#include class QPushButton; @@ -26,16 +26,6 @@ namespace raco::property_browser { class PropertyBrowserItem; class PropertyBrowserModel; -class PropertyBrowserView final : public QWidget { -public: - explicit PropertyBrowserView(core::SceneBackendInterface* sceneBackend, PropertyBrowserItem* item, PropertyBrowserModel* model, QWidget* parent = nullptr); - -private: - QPoint verticalPivot_{0, 0}; - QWidget* verticalPivotWidget_{nullptr}; - core::SceneBackendInterface* sceneBackend_; -}; - class PropertyBrowserWidget final : public QWidget { public: explicit PropertyBrowserWidget( @@ -48,28 +38,36 @@ class PropertyBrowserWidget final : public QWidget { PropertyBrowserModel* model() const; public Q_SLOTS: - void setObjectFromObjectId(const QString& objectID); - void setObjects(const core::SEditorObjectSet& objects); + void setObjectFromObjectId(const QString& objectID, const QString& objectProperty); + void setObjects(const core::SEditorObjectSet& objects, const QString& property); + void highlightProperty(const QString& property); void clear(); - void setLockable(bool lockable); + void setLockable(bool lockable) const; + +private Q_SLOTS: + void showRefToThis(); private: + void showScrollBar(bool isAlwaysOn); void setLocked(bool locked); void setObjectsImpl(const core::SEditorObjectSet& objects, bool forceExpandStateUpdate); - + std::string getObjectIdInPrefab() const; + components::SDataChangeDispatcher dispatcher_; core::CommandInterface* commandInterface_; core::SceneBackendInterface* sceneBackend_; object_tree::view::ObjectTreeDockManager* treeDockManager_; PropertyBrowserGridLayout layout_; - std::unique_ptr propertyBrowser_{}; + std::unique_ptr propertyBrowser_{}; PropertyBrowserItem* rootItem_ = nullptr; core::SEditorObjectSet currentObjects_; - components::Subscription subscription_; + components::Subscription lifecycleSubs_; QWidget* emptyLabel_; bool locked_; PropertyBrowserModel* model_; QPushButton* lockButton_; + QPushButton* refButton_; + QPushButton* prefabLookupButton_; }; } // namespace raco::property_browser diff --git a/gui/libPropertyBrowser/include/property_browser/PropertyCopyPaste.h b/gui/libPropertyBrowser/include/property_browser/PropertyCopyPaste.h new file mode 100644 index 00000000..3942165d --- /dev/null +++ b/gui/libPropertyBrowser/include/property_browser/PropertyCopyPaste.h @@ -0,0 +1,48 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "property_browser/PropertyBrowserItem.h" + +namespace raco::property_browser { + +class PropertyCopyPaste { +public: + static bool canCopyValue(PropertyBrowserItem* item); + static bool canPasteValue(PropertyBrowserItem* item); + + static void pasteValue(PropertyBrowserItem* item); + static void copyValue(PropertyBrowserItem* item); + + static void copyValuePlainText(PropertyBrowserItem* item); + static void copyChildValuePlainText(PropertyBrowserItem* item, int index); + + // Used only in unit tests + static void pasteProperty(PropertyBrowserItem* item, data_storage::ValueBase* value); + +private: + static void pasteInt(PropertyBrowserItem* item, core::ValueBase* value); + static void pasteInt64(PropertyBrowserItem* item, core::ValueBase* value); + static void pasteDouble(PropertyBrowserItem* item, core::ValueBase* value); + static void pasteBool(PropertyBrowserItem* item, core::ValueBase* value); + static void pasteString(PropertyBrowserItem* item, core::ValueBase* value); + static void pasteRef(PropertyBrowserItem* item, core::ValueBase* value); + static void pasteStruct(PropertyBrowserItem* item, core::ValueBase* value); + static void pasteTable(PropertyBrowserItem* item, core::ValueBase* value); + + static bool isVector(PropertyBrowserItem* item); + static bool isVector(core::ValueBase* value); + template + static void pasteVector(PropertyBrowserItem* item, core::ValueBase* value); + static void pastePropertyOfSameType(PropertyBrowserItem* item, data_storage::ValueBase* value); + static void copyValuePlainText(const core::ValueBase* valueBase); +}; + +} // namespace raco::property_browser \ No newline at end of file diff --git a/gui/libPropertyBrowser/include/property_browser/PropertySubtreeChildrenContainer.h b/gui/libPropertyBrowser/include/property_browser/PropertySubtreeChildrenContainer.h index 9e48496e..30428611 100644 --- a/gui/libPropertyBrowser/include/property_browser/PropertySubtreeChildrenContainer.h +++ b/gui/libPropertyBrowser/include/property_browser/PropertySubtreeChildrenContainer.h @@ -19,17 +19,23 @@ namespace raco::property_browser { +class PropertySubtreeView; + class PropertySubtreeChildrenContainer final : public QWidget { Q_OBJECT public: explicit PropertySubtreeChildrenContainer(PropertyBrowserItem* item, QWidget* parent); + void addWidget(QWidget* child); - void removeWidget(QWidget* child); - void insertWidget(size_t index, QWidget* child); + void deleteAllChildren(); + + std::vector getChildSubtreeViews() const; + public Q_SLOTS: void setOffset(int offset); private: + void removeWidget(QWidget* child); PropertyBrowserVBoxLayout* layout_; }; diff --git a/gui/libPropertyBrowser/include/property_browser/PropertySubtreeView.h b/gui/libPropertyBrowser/include/property_browser/PropertySubtreeView.h index 15e34b2a..41c75494 100644 --- a/gui/libPropertyBrowser/include/property_browser/PropertySubtreeView.h +++ b/gui/libPropertyBrowser/include/property_browser/PropertySubtreeView.h @@ -9,12 +9,6 @@ */ #pragma once -#include -#include -#include -#include -#include - #include "core/SceneBackendInterface.h" #include "property_browser/PropertyBrowserItem.h" #include "property_browser/PropertyBrowserLayouts.h" @@ -25,48 +19,55 @@ namespace raco::property_browser { class PropertyControl; class PropertyEditor; -class EmbeddedPropertyBrowserView final : public QFrame { -public: - explicit EmbeddedPropertyBrowserView(PropertyBrowserItem* item, QWidget* parent); -}; - +// TODO use AbstractPropertyBrowserItem instead of the PropertyBrowserItem everywhere in the PropertySubtreeView class PropertySubtreeView final : public QWidget { Q_OBJECT Q_PROPERTY(float highlight MEMBER highlight_ NOTIFY update) public: - explicit PropertySubtreeView(raco::core::SceneBackendInterface* sceneBackend, PropertyBrowserModel* model, PropertyBrowserItem* item, QWidget* parent); - PropertyBrowserItem const* item() { return item_; } + explicit PropertySubtreeView(core::SceneBackendInterface* sceneBackend, PropertyBrowserModel* model, PropertyBrowserItem* item, QWidget* parent, PropertySubtreeView* parentSubtree); + PropertyBrowserItem const* item() const { return item_; } public Q_SLOTS: - void playStructureChangeAnimation(); - void setLabelAreaWidth(int offset); + void playHighlightAnimation(int duration, float start, float end); void updateChildrenContainer(); + void ensurePropertyVisible(); protected: void paintEvent(QPaintEvent* event) override; - int getLabelAreaWidthHint() const; - Q_SLOT void updateError(); + Q_SLOT void updateErrors(); + private: - void updateObjectNameDisplay(); - void recalculateLabelWidth(); + enum LayoutRows{ + ErrorRow = 0, + LabelRow = 1, + ChildrenContainerRow = 2 + }; + + void setLabelAreaWidth(int labelAreaWidth); + int getLabelAreaWidth() const; + bool updateLabelAreaWidth(bool initialize = true); void collectTabWidgets(QObject* item, QWidgetList& tabWidgets); void recalculateTabOrder(); - void registerCopyPasteContextMenu(QWidget* widget); - QStringList objectNames() const; + void registerLabelContextMenu(QWidget* labelWidget, PropertyBrowserItem* item); + void drawHighlight(float intensity); - raco::core::SceneBackendInterface* sceneBackend_; + core::SceneBackendInterface* sceneBackend_; PropertyBrowserItem* item_{nullptr}; - PropertyBrowserModel* model_ {nullptr}; - PropertyBrowserGridLayout layout_{nullptr}; + PropertyBrowserModel* model_{nullptr}; + PropertyBrowserVBoxLayout layout_{nullptr}; + PropertyBrowserVBoxLayout* errorLayout_{nullptr}; QWidget* decorationWidget_{nullptr}; - QLabel* label_{nullptr}; - PropertyEditor* propertyControl_{nullptr}; + QWidget* label_{nullptr}; + QWidget* controlWidget_{nullptr}; + QWidget* errorContainer_{nullptr}; + + PropertySubtreeView* parentSubtree_{nullptr}; PropertySubtreeChildrenContainer* childrenContainer_{nullptr}; - int labelWidth_{0}; - float highlight_{0}; - void generateItemTooltip(PropertyBrowserItem* item, bool connectWithChangeEvents); + int labelAreaWidth_{0}; + int labelMinWidth_{0}; + int subtreeMaxWidth_{0}; - std::vector objectNameChangeSubscriptions_; + float highlight_{0}; }; } // namespace raco::property_browser diff --git a/gui/libPropertyBrowser/include/property_browser/Utilities.h b/gui/libPropertyBrowser/include/property_browser/Utilities.h new file mode 100644 index 00000000..6e47651e --- /dev/null +++ b/gui/libPropertyBrowser/include/property_browser/Utilities.h @@ -0,0 +1,27 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include + +namespace raco::property_browser { + +template +T* findAncestor(QWidget* widget) { + while (widget) { + if (const auto typedWidget = qobject_cast(widget)) { + return typedWidget; + } + widget = widget->parentWidget(); + } + return nullptr; +} + +} // namespace raco::property_browser diff --git a/gui/libPropertyBrowser/include/property_browser/WidgetFactory.h b/gui/libPropertyBrowser/include/property_browser/WidgetFactory.h index 0c2e61e0..9db9421e 100644 --- a/gui/libPropertyBrowser/include/property_browser/WidgetFactory.h +++ b/gui/libPropertyBrowser/include/property_browser/WidgetFactory.h @@ -10,7 +10,6 @@ #pragma once -#include #include namespace raco::property_browser { @@ -24,8 +23,12 @@ class PropertyEditor; */ class WidgetFactory { public: - static PropertyEditor* createPropertyEditor(PropertyBrowserItem* item, QWidget* parent = nullptr); - static QLabel* createPropertyLabel(PropertyBrowserItem* item, QWidget* parent = nullptr); - static LinkEditor* createLinkControl(PropertyBrowserItem* item, QWidget* parent = nullptr); + static std::tuple createPropertyWidgets(PropertyBrowserItem* item, QWidget* parent); + +private: + static PropertyEditor* createPropertyEditor(PropertyBrowserItem* item, QWidget* label, QWidget* parent); + static QWidget* createPropertyLabel(PropertyBrowserItem* item, QWidget* parent); + static LinkEditor* createLinkControl(PropertyBrowserItem* item, QWidget* parent, QWidget* propertyEditor); + static PropertyEditor* createPropertyControl(PropertyBrowserItem* item, QWidget* label, QWidget* parent); }; } // namespace raco::property_browser \ No newline at end of file diff --git a/gui/libPropertyBrowser/include/property_browser/controls/ColorChannelInfo.h b/gui/libPropertyBrowser/include/property_browser/controls/ColorChannelInfo.h new file mode 100644 index 00000000..ef4a0b5e --- /dev/null +++ b/gui/libPropertyBrowser/include/property_browser/controls/ColorChannelInfo.h @@ -0,0 +1,41 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include +#include +#include +#include + +#include + +namespace raco::property_browser { + +struct ColorChannels { + typedef std::list> ChannelOperations; + + struct ChannelExtractOperation { + std::string displayName_; + std::function extractFunction_; + std::function channelExistsPredicate_; + }; + + // Ordered named operations leaving only specific channel in RGBA value. + inline const static std::vector channels_ = { + {"Gray", [](QRgb c) { return qRgba(qRed(c), qGreen(c), qBlue(c), 0); }, [](const QImage& q) { return q.isGrayscale(); }}, + {"Red", [](QRgb c) { return qRgba(qRed(c), 0, 0, 0); }, [](const QImage& q) { return !q.isGrayscale(); }}, + {"Green", [](QRgb c) { return qRgba(0, qGreen(c), 0, 0); }, [](const QImage& q) { return !q.isGrayscale(); }}, + {"Blue", [](QRgb c) { return qRgba(0, 0, qBlue(c), 0); }, [](const QImage& q) { return !q.isGrayscale(); }}, + {"Alpha", [](QRgb c) { return qRgba(0, 0, 0, qAlpha(c)); }, [](const QImage& q) { return q.hasAlphaChannel(); }}, + }; +}; + +} // namespace raco::property_browser \ No newline at end of file diff --git a/gui/libPropertyBrowser/include/property_browser/controls/ColorChannelListWidget.h b/gui/libPropertyBrowser/include/property_browser/controls/ColorChannelListWidget.h new file mode 100644 index 00000000..0b7aaadf --- /dev/null +++ b/gui/libPropertyBrowser/include/property_browser/controls/ColorChannelListWidget.h @@ -0,0 +1,42 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "common_widgets/NoContentMarginsLayout.h" +#include "ColorChannelInfo.h" + +#include +#include + +class QCheckBox; + +namespace raco::property_browser { + +class ColorChannelListWidget : public QWidget { + Q_OBJECT + +public: + explicit ColorChannelListWidget(QWidget* parent = nullptr); + void refreshChannelList(const QImage& image); + std::tuple getSelectedOperations() const; + +Q_SIGNALS: + void selectionChanged(); + +private: + QCheckBox* checkbox(size_t index) const; + bool isChannelPresent(size_t index) const; + + // Checkbox and its color channel presence flag + std::vector> checkBoxes_; + common_widgets::NoContentMarginsLayout layout_; +}; + +} // namespace raco::property_browser \ No newline at end of file diff --git a/gui/libPropertyBrowser/include/property_browser/controls/ImageWidget.h b/gui/libPropertyBrowser/include/property_browser/controls/ImageWidget.h new file mode 100644 index 00000000..705d5594 --- /dev/null +++ b/gui/libPropertyBrowser/include/property_browser/controls/ImageWidget.h @@ -0,0 +1,53 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "style/Colors.h" + +#include +#include + +namespace raco::property_browser { + +class ImageWidget : public QWidget { + Q_OBJECT + +public: + explicit ImageWidget(QWidget* parent = nullptr); + + bool hasHeightForWidth() const override; + int heightForWidth(int w) const override; + bool eventFilter(QObject* obj, QEvent* event) override; + + void setHeightSourceWidget(QWidget* widget); + void setPixmap(const QPixmap& pixmap); + void setCheckerEnabled(bool enabled); + +protected: + void paintEvent(QPaintEvent* event) override; + +private: + QPixmap createCheckerTilePixmap() const; + int getMaximumHeight() const; + int widthForHeight(int h) const; + + // ErrorBox palette. + QBrush checkerLightBrush_ = style::Colors::brush(style::Colormap::grayButton); + QBrush checkerDarkBrush_ = style::Colors::brush(style::Colormap::grayEdit); + + bool isCheckerEnabled_ = true; + QPixmap imagePixmap_; + + QWidget* heightSourceWidget_ = nullptr; + inline static constexpr double maxHeightShare_ = 0.75; + inline static constexpr double checkerTileSizeFactor_ = 1.2; +}; + +} // namespace raco::property_browser \ No newline at end of file diff --git a/gui/libPropertyBrowser/include/property_browser/controls/SpinBox.h b/gui/libPropertyBrowser/include/property_browser/controls/SpinBox.h index 06336ef8..b7cc906a 100644 --- a/gui/libPropertyBrowser/include/property_browser/controls/SpinBox.h +++ b/gui/libPropertyBrowser/include/property_browser/controls/SpinBox.h @@ -19,7 +19,7 @@ namespace raco::property_browser { template -std::optional evaluateLuaExpression(QString expression, T min = raco::data_storage::numericalLimitMin(), T max = raco::data_storage::numericalLimitMax()); +std::optional evaluateLuaExpression(QString expression, T min = data_storage::numericalLimitMin(), T max = data_storage::numericalLimitMax()); template class InternalSpinBox : public QAbstractSpinBox { diff --git a/gui/libPropertyBrowser/include/property_browser/controls/TexturePreviewWidget.h b/gui/libPropertyBrowser/include/property_browser/controls/TexturePreviewWidget.h new file mode 100644 index 00000000..e9564cab --- /dev/null +++ b/gui/libPropertyBrowser/include/property_browser/controls/TexturePreviewWidget.h @@ -0,0 +1,63 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "core/EditorObject.h" + +#include "property_browser/PropertyBrowserItem.h" + +#include + +namespace raco { +namespace core { +class Project; +} +} + +class QCheckBox; +class QComboBox; +class QListWidget; +class QListWidgetItem; +class QPushButton; + +namespace raco::property_browser { +class ColorChannelListWidget; +class ImageWidget; + +class TexturePreviewWidget : public QWidget { + Q_OBJECT + +public: + explicit TexturePreviewWidget(PropertyBrowserItem* item, QWidget* parent = nullptr); + + void setFiles(std::vector> files); + void setImageWidget(ImageWidget* widget); + static std::vector> collectValidTextureUris(const core::Project* project, const core::Errors& errors, const core::SEditorObject& texture); + +private slots: + void levelSelected(int); + +private: + QImage getProcessedImage() const; + void refreshPreview() const; + + PropertyBrowserItem* item_; + + QImage currentImage_; + ImageWidget* imageWidget_ = nullptr; + ColorChannelListWidget* channelList_ = nullptr; + QCheckBox* checkerCheck_ = nullptr; + QComboBox* uriCombo_ = nullptr; + + components::Subscription previewSubscription_; + components::Subscription mipMapLevelSubscription_; +}; + +} // namespace raco::property_browser diff --git a/gui/libPropertyBrowser/include/property_browser/editors/ArrayEditor.h b/gui/libPropertyBrowser/include/property_browser/editors/ArrayEditor.h new file mode 100644 index 00000000..b34a8521 --- /dev/null +++ b/gui/libPropertyBrowser/include/property_browser/editors/ArrayEditor.h @@ -0,0 +1,33 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "PropertyEditor.h" +#include "property_browser/PropertyBrowserItem.h" + +#include +#include + +namespace raco::property_browser { + +class ArrayEditor : public PropertyEditor { +public: + explicit ArrayEditor(PropertyBrowserItem* item, QWidget* parent = nullptr); + +protected: + void updateLabel(); + + QLabel* descriptionLabel_; + QPushButton* shrinkButton_; + QPushButton* growButton_; + QLabel* sizeLabel_; +}; + +} // namespace raco::property_browser \ No newline at end of file diff --git a/gui/libPropertyBrowser/include/property_browser/editors/LinkEditor.h b/gui/libPropertyBrowser/include/property_browser/editors/LinkEditor.h index 26e10d1e..1299a147 100644 --- a/gui/libPropertyBrowser/include/property_browser/editors/LinkEditor.h +++ b/gui/libPropertyBrowser/include/property_browser/editors/LinkEditor.h @@ -79,8 +79,8 @@ protected Q_SLOTS: {LinkIcon::goToLeftRight, style::Icons::instance().goToLeftRight} }; - void addLinkEndpointMenuItems(const std::vector& startingLinks, QMenu* endsMenu, QString& requestedLinkEndObj); - std::map generateSortedLinkPoints(const std::vector links); + void addLinkEndpointMenuItems(const std::vector& startingLinks, QMenu* endsMenu, QString& requestedLinkEndObj, QString& requestedLinkEndObjProperty); + std::map> generateSortedLinkPoints(const std::vector links); bool validDropTarget_ { false }; PropertyBrowserItem* item_; diff --git a/gui/libPropertyBrowser/include/property_browser/editors/PropertyEditor.h b/gui/libPropertyBrowser/include/property_browser/editors/PropertyEditor.h index 9bf44bc0..99488688 100644 --- a/gui/libPropertyBrowser/include/property_browser/editors/PropertyEditor.h +++ b/gui/libPropertyBrowser/include/property_browser/editors/PropertyEditor.h @@ -14,43 +14,24 @@ #include #include +class QMenu; + namespace raco::property_browser { class PropertyBrowserItem; class PropertyEditor : public QWidget { public: - explicit PropertyEditor( - PropertyBrowserItem* item, - QWidget* parent = nullptr); - - bool canCopyValue(); - bool canPasteValue(); - - void pasteValue(); - virtual void copyValue(); + explicit PropertyEditor(PropertyBrowserItem* item, QWidget* parent = nullptr); + bool eventFilter(QObject* watched, QEvent* event) override; + virtual void displayCopyContextMenu(); protected: + bool canDisplayCopyDialog = false; PropertyBrowserItem* item_; + QMenu* propertyMenu_{nullptr}; - // Made protected to enable unit testing: - static void pasteProperty(PropertyBrowserItem* item, data_storage::ValueBase* value); - -private: - static void pasteInt(PropertyBrowserItem* item, core::ValueBase* value); - static void pasteInt64(PropertyBrowserItem* item, core::ValueBase* value); - static void pasteDouble(PropertyBrowserItem* item, core::ValueBase* value); - static void pasteBool(PropertyBrowserItem* item, core::ValueBase* value); - static void pasteString(PropertyBrowserItem* item, core::ValueBase* value); - static void pasteRef(PropertyBrowserItem* item, core::ValueBase* value); - static void pasteStruct(PropertyBrowserItem* item, core::ValueBase* value); - static void pasteTable(PropertyBrowserItem* item, core::ValueBase* value); - - static bool isVector(PropertyBrowserItem* item); - static bool isVector(core::ValueBase* value); - template - static void pasteVector(PropertyBrowserItem* item, core::ValueBase* value); - static void pastePropertyOfSameType(PropertyBrowserItem* item, data_storage::ValueBase* value); + virtual void menuCopyAction(); }; } // namespace raco::property_browser diff --git a/gui/libPropertyBrowser/include/property_browser/editors/StringEditor.h b/gui/libPropertyBrowser/include/property_browser/editors/StringEditor.h index 87dfeb7a..b0515f53 100644 --- a/gui/libPropertyBrowser/include/property_browser/editors/StringEditor.h +++ b/gui/libPropertyBrowser/include/property_browser/editors/StringEditor.h @@ -24,18 +24,22 @@ class PropertyBrowserItem; class StringEditorLineEdit : public QLineEdit { Q_OBJECT + Q_PROPERTY(int errorLevel READ errorLevel WRITE setErrorLevel) public: StringEditorLineEdit(QWidget* parent = nullptr) : QLineEdit(parent) { } + + int errorLevel() const noexcept; void setDragAndDropFilter(const QString& filter) { dragAndDropFilter_ = filter; } - bool hasMultipleValues() const; - void set(std::optional value); protected: + core::ErrorLevel errorLevel_{core::ErrorLevel::NONE}; + + void setErrorLevel(int level); void focusInEvent(QFocusEvent* event); void keyPressEvent(QKeyEvent* event); void dragEnterEvent(QDragEnterEvent* event) override; @@ -56,12 +60,10 @@ class StringEditorLineEdit : public QLineEdit { class StringEditor : public PropertyEditor { Q_OBJECT Q_PROPERTY(bool updatedInBackground READ updatedInBackground); - Q_PROPERTY(int errorLevel READ errorLevel); public: explicit StringEditor(PropertyBrowserItem* item, QWidget* parent = nullptr); bool updatedInBackground() const; - int errorLevel() const noexcept; public Q_SLOTS: void setText(const QString&); @@ -72,7 +74,6 @@ public Q_SLOTS: void updateErrorState(); bool updatedInBackground_ = false; - core::ErrorLevel errorLevel_{core::ErrorLevel::NONE}; StringEditorLineEdit* lineEdit_; std::map focusInValues_; diff --git a/gui/libPropertyBrowser/include/property_browser/editors/TagContainerEditor.h b/gui/libPropertyBrowser/include/property_browser/editors/TagContainerEditor.h index 7fcb7522..bfda860c 100644 --- a/gui/libPropertyBrowser/include/property_browser/editors/TagContainerEditor.h +++ b/gui/libPropertyBrowser/include/property_browser/editors/TagContainerEditor.h @@ -25,7 +25,6 @@ namespace raco::core { namespace raco::property_browser { class PropertyBrowserItem; -class TagDataCache; class TagContainerEditor : public PropertyEditor { Q_OBJECT @@ -48,7 +47,6 @@ class TagContainerEditor : public PropertyEditor { QPushButton* editButton_{}; QLabel* renderedBy_ {}; - //std::unique_ptr tagDataCache_; std::array renderLayerSubscriptions_; std::vector materialPropertySubscriptions_; }; diff --git a/gui/libPropertyBrowser/include/property_browser/editors/TexturePreviewEditor.h b/gui/libPropertyBrowser/include/property_browser/editors/TexturePreviewEditor.h new file mode 100644 index 00000000..4d04abeb --- /dev/null +++ b/gui/libPropertyBrowser/include/property_browser/editors/TexturePreviewEditor.h @@ -0,0 +1,30 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "PropertyEditor.h" + +namespace raco::property_browser { + +class ImageWidget; +class PropertyBrowserItem; + +class TexturePreviewEditor : public PropertyEditor { + +public: + explicit TexturePreviewEditor(PropertyBrowserItem* item, QWidget* label, QWidget* parent = nullptr); + + ImageWidget* getImageWidget() const; + +private: + ImageWidget* imageWidget_; +}; + +} // namespace raco::property_browser diff --git a/gui/libPropertyBrowser/include/property_browser/editors/URIEditor.h b/gui/libPropertyBrowser/include/property_browser/editors/URIEditor.h index 250fc7ab..3783a118 100644 --- a/gui/libPropertyBrowser/include/property_browser/editors/URIEditor.h +++ b/gui/libPropertyBrowser/include/property_browser/editors/URIEditor.h @@ -15,20 +15,19 @@ #include namespace raco::property_browser { - + class PropertyBrowserItem; class URIEditor : public StringEditor { Q_OBJECT - Q_PROPERTY(bool updatedInBackground READ updatedInBackground); - Q_PROPERTY(int errorLevel READ errorLevel); + Q_PROPERTY(bool updatedInBackground READ updatedInBackground) public: explicit URIEditor(PropertyBrowserItem* item, QWidget* parent = nullptr); protected: - // Returns - // - the unique absolute path of all the handles if the absolute paths of the individual handles are + // Returns + // - the unique absolute path of all the handles if the absolute paths of the individual handles are // all non-empty and equal. // - nullopt otherwise. std::optional uniqueAbsolutePath(); diff --git a/gui/libPropertyBrowser/include/property_browser/editors/VecNTEditor.h b/gui/libPropertyBrowser/include/property_browser/editors/VecNTEditor.h index c96a8bea..eefa453b 100644 --- a/gui/libPropertyBrowser/include/property_browser/editors/VecNTEditor.h +++ b/gui/libPropertyBrowser/include/property_browser/editors/VecNTEditor.h @@ -60,6 +60,8 @@ class VecNTEditor : public PropertyEditor { explicit VecNTEditor( PropertyBrowserItem* item, QWidget* parent = nullptr); + bool eventFilter(QObject* watched, QEvent* event) override; + void displayCopyContextMenu(size_t spinboxIndex); public Q_SLOTS: void setEnabled(bool val); diff --git a/gui/libPropertyBrowser/src/PropertyBrowserItem.cpp b/gui/libPropertyBrowser/src/PropertyBrowserItem.cpp index af03db58..2f36768a 100644 --- a/gui/libPropertyBrowser/src/PropertyBrowserItem.cpp +++ b/gui/libPropertyBrowser/src/PropertyBrowserItem.cpp @@ -18,12 +18,14 @@ #include "core/Queries_Tags.h" #include "property_browser/PropertyBrowserRef.h" #include "property_browser/PropertyBrowserCache.h" +#include "property_browser/PropertyCopyPaste.h" #include "user_types/EngineTypeAnnotation.h" #include "user_types/LuaInterface.h" #include "user_types/LuaScript.h" #include "user_types/MeshNode.h" #include "user_types/RenderPass.h" +#include "user_types/Texture.h" #include #include @@ -40,6 +42,7 @@ PropertyBrowserItem::PropertyBrowserItem( SDataChangeDispatcher dispatcher, core::CommandInterface* commandInterface, PropertyBrowserModel* model, + core::SceneBackendInterface* sceneBackend, PropertyBrowserItem* parent) : QObject{parent}, parentItem_{parent}, @@ -48,6 +51,7 @@ PropertyBrowserItem::PropertyBrowserItem( commandInterface_{commandInterface}, dispatcher_{dispatcher}, model_{model}, + sceneBackend_(sceneBackend), expanded_{getDefaultExpanded()} { assert(std::all_of(valueHandles_.begin(), valueHandles_.end(), [](const core::ValueHandle& handle) { @@ -64,7 +68,7 @@ PropertyBrowserItem::PropertyBrowserItem( const auto commonValueHandles = getCommonValueHandles(valueHandles_); for (auto& commonHandleForSeveralObjects : commonValueHandles) { - children_.push_back(new PropertyBrowserItem(commonHandleForSeveralObjects, dispatcher_, commandInterface_, model_, this)); + children_.push_back(new PropertyBrowserItem(commonHandleForSeveralObjects, dispatcher_, commandInterface_, model_, sceneBackend_, this)); } if (isProperty() && valueHandles_.begin()->type() == PrimitiveType::Ref) { @@ -78,7 +82,7 @@ PropertyBrowserItem::PropertyBrowserItem( std::for_each(valueHandles_.begin(), valueHandles_.end(), [this, &dispatcher](const core::ValueHandle& handle) { if (handle.isObject()) { structureChangeSubs_.emplace_back(dispatcher->registerOnChildren(handle, [this, &handle](auto changedHandle) { - if (changedHandle.type() == PrimitiveType::Table) { + if (changedHandle.type() == PrimitiveType::Table || changedHandle.type() == PrimitiveType::Array) { if (!findNamedChild(changedHandle.getPropertyNamesVector().front())) { syncChildrenWithValueHandle(); } @@ -86,7 +90,14 @@ PropertyBrowserItem::PropertyBrowserItem( })); } else if (hasTypeSubstructure(handle.type())) { structureChangeSubs_.emplace_back(dispatcher->registerOn(handle, [this, &handle]() { - syncChildrenWithValueHandle(); + if (handle.type() == PrimitiveType::Table || handle.type() == PrimitiveType::Array) { + syncChildrenWithValueHandle(); + } else { + // TODO this doesn't work for nested structs: + for (auto childItem : children_) { + Q_EMIT childItem->valueChanged(); + } + } })); } @@ -98,12 +109,23 @@ PropertyBrowserItem::PropertyBrowserItem( Q_EMIT editableChanged(editable()); Q_EMIT linkStateChanged(); } + if (handle.isRefToProp(&core::EditorObject::objectName_)) { + Q_EMIT propertyControlToolTipTextChanged(propertyControlToolTipText()); + } } }))); errorSubs_.emplace_back(components::Subscription(dispatcher->registerOnErrorChanged(handle, [this]() { Q_EMIT errorChanged(); + Q_EMIT displayErrorChanged(); }))); + if (isObject() && valueHandles_.size() > 1) { + auto nameHandle = handle.get("objectName"); + objectNameChangeSubscriptions_.push_back(dispatcher->registerOn(nameHandle, [this]() { + Q_EMIT displayErrorChanged(); + })); + } + // links bool linkEnd = core::Queries::isValidLinkEnd(*project(), handle); bool linkStart = core::Queries::isValidLinkStart(handle); @@ -183,11 +205,27 @@ PropertyBrowserItem::PropertyBrowserItem( } })); } + + // The private flag in the meshnode material container is used to determine visibility of the options children, + // see Queries::isHiddenInPropertyBrowser + if (handle.rootObject()->isType()) { + auto meshnode = handle.rootObject()->as(); + for (size_t matIndex = 0; matIndex < meshnode->numMaterialSlots(); matIndex++) { + if (handle == meshnode->getMaterialOptionsHandle(matIndex)) { + childrenChangeSubs_.emplace_back(dispatcher->registerOn(meshnode->getMaterialPrivateHandle(matIndex), [this]() { + if (isValid()) { + syncChildrenWithValueHandle(); + } + })); + } + } + } + }); } -bool PropertyBrowserItem::isHidden(core::ValueHandle handle) const { - if (core::Queries::isHiddenInPropertyBrowser(*commandInterface_->project(), handle)) { +bool PropertyBrowserItem::isHidden(core::ValueHandle handle, bool isMultiSelect) const { + if (core::Queries::isHiddenInPropertyBrowser(*commandInterface_->project(), handle, isMultiSelect)) { return true; } @@ -268,6 +306,11 @@ bool PropertyBrowserItem::match(const core::ValueHandle& left, const core::Value return left.constValueRef()->baseTypeName() == right.constValueRef()->baseTypeName(); break; + case PrimitiveType::Array: + return left.constValueRef()->asArray().elementType() == right.constValueRef()->asArray().elementType() && + left.constValueRef()->asArray().size() == right.constValueRef()->asArray().size(); + break; + default: return true; } @@ -289,14 +332,15 @@ std::vector> PropertyBrowserItem::getCommonValueHand if (refHandle.isProperty() && (refHandle.query() || refHandle.query())) { return {}; } - + + bool isMultiSelect = handles.size() > 1; for (size_t index = 0; index < refHandle.size(); index++) { auto refChildHandle = refHandle[index]; auto propName = refChildHandle.getPropName(); - if (!isHidden(refChildHandle)) { - if (std::all_of(++handles.begin(), handles.end(), [this, refChildHandle, propName](auto handle) { - return handle.hasProperty(propName) && !isHidden(handle.get(propName)) && match(refChildHandle, handle.get(propName)); + if (!isHidden(refChildHandle, isMultiSelect)) { + if (std::all_of(++handles.begin(), handles.end(), [this, refChildHandle, propName, isMultiSelect](auto handle) { + return handle.hasProperty(propName) && !isHidden(handle.get(propName), isMultiSelect) && match(refChildHandle, handle.get(propName)); })) { std::set childHandleSet; for (auto handle : handles) { @@ -350,11 +394,66 @@ std::string PropertyBrowserItem::getPropertyPathWithoutObject() const { return fmt::format("{}", fmt::join(valueHandles_.begin()->getPropertyNamesVector(), ".")); } +void PropertyBrowserItem::highlightProperty(const QString& propertyName) { + const auto item = findNamedChildByPropertyPath(propertyName.toStdString()); + if (item) { + auto parentItem = item->parentItem(); + while (parentItem) { + if (parentItem->expandable()) { + parentItem->setExpanded(true, false); + } + parentItem = parentItem->parentItem(); + } + item->Q_EMIT highlighted(); + } +} + +QStringList PropertyBrowserItem::objectNames() const { + QStringList items; + for (auto handle : valueHandles_) { + auto object = handle.rootObject(); + std::string labelText = fmt::format("{} [{}]", object->objectName(), object->getTypeDescription().typeName); + items.push_back(QString::fromStdString(labelText)); + } + items.sort(); + return items; +} + +QString PropertyBrowserItem::displayObjectNames() const { + QStringList items = objectNames(); + items.push_front("Current objects:"); + return items.join("\n"); +} + +std::string PropertyBrowserItem::labelToolTipText() const { + if (searchAnnotationInParents()) { + return {}; + } + + if (isLuaProperty()) { + return fmt::format("{} [{}]", getPropertyName(), luaTypeName()); + } + return getPropertyName(); +} + +QString PropertyBrowserItem::propertyControlToolTipText() const { + if (valueHandles_.begin()->isRefToProp(&core::EditorObject::objectName_)) { + if (valueHandles_.size() == 1 && sceneBackend_) { + return QString::fromStdString(sceneBackend_->getExportedObjectNames(valueHandles_.begin()->rootObject())); + } else { + return displayObjectNames(); + } + } + return {}; +} + void PropertyBrowserItem::updateLinkState() noexcept { Q_EMIT linkStateChanged(); Q_EMIT editableChanged(editable()); for (auto* child_ : children_) { - child_->updateLinkState(); + if (child_->isValid()) { + child_->updateLinkState(); + } } } @@ -398,7 +497,7 @@ const QList& PropertyBrowserItem::children() { return children_; } -PropertyBrowserItem* PropertyBrowserItem::findNamedChild(const std::string& propertyName) { +PropertyBrowserItem* PropertyBrowserItem::findNamedChild(std::string_view propertyName) { auto it = std::find_if(children_.begin(), children_.end(), [propertyName](auto child) { return child->getPropertyName() == propertyName; }); @@ -408,6 +507,29 @@ PropertyBrowserItem* PropertyBrowserItem::findNamedChild(const std::string& prop return nullptr; } +PropertyBrowserItem* PropertyBrowserItem::findNamedChildByPropertyPath(std::string_view propertyPath) { + const auto path = QString::fromStdString(std::string(propertyPath.begin(), propertyPath.end())); + auto names = path.split("."); // get names of all nested children + names.removeAt(0); // remove object name + + if (names.empty()) { + return nullptr; + } + + auto root = this; + while (!names.empty()) { + auto name = names[0].toStdString(); + if (const auto it = root->findNamedChild(name)) { + root = it; + } else { + return nullptr; + } + names.removeAt(0); + } + + return root; +} + bool PropertyBrowserItem::hasError() const { return std::any_of(valueHandles_.begin(), valueHandles_.end(), [this](const core::ValueHandle& handle) { return commandInterface_->errors().hasError(handle); @@ -467,6 +589,35 @@ std::string PropertyBrowserItem::errorMessage() const { return {}; } +std::vector PropertyBrowserItem::getDisplayErrorItems() const { + std::vector errorItems; + + // Object name display: only shown for top-level object in multiselection mode + if (isObject() && valueHandles_.size() > 1) { + errorItems.emplace_back(DisplayErrorItem{core::ErrorLevel::INFORMATION, displayObjectNames()}); + } + + // Error item + if (hasError()) { + std::string errorMsg; + auto optCategory = errorCategory(); + if (!optCategory.has_value()) { + errorMsg = "Multiple Erorrs"; + } else { + auto category = optCategory.value(); + if (category == core::ErrorCategory::RAMSES_LOGIC_RUNTIME || category == core::ErrorCategory::PARSING || category == core::ErrorCategory::GENERAL || category == core::ErrorCategory::MIGRATION) { + errorMsg = errorMessage().c_str(); + } + } + if (!errorMsg.empty()) { + errorItems.emplace_back(DisplayErrorItem{maxErrorLevel(), QString::fromStdString(errorMsg)}); + } + } + + return errorItems; +} + + void PropertyBrowserItem::markForDeletion() { // prevent crashes caused by delayed subscription callbacks handleChangeSubs_.clear(); @@ -727,6 +878,17 @@ void PropertyBrowserItem::setTags(std::vector> const desc); } +void PropertyBrowserItem::resizeArray(size_t newSize) { + std::string desc = fmt::format("Resize property '{}' to {}", getPropertyPath(), newSize); + commandInterface_->executeCompositeCommand( + [this, newSize]() { + for (auto& handle : valueHandles_) { + commandInterface_->resizeArray(handle, newSize); + } + }, + desc); +} + void PropertyBrowserItem::syncChildrenWithValueHandle() { if (isProperty() && !matchCurrent()) { // matching has failed @@ -748,11 +910,12 @@ void PropertyBrowserItem::syncChildrenWithValueHandle() { if (!commonValueHandles.empty()) { children_.reserve(static_cast(commonValueHandles.size())); for (const auto& commonHandleForSeveralObjects : commonValueHandles) { - children_.push_back(new PropertyBrowserItem(commonHandleForSeveralObjects, dispatcher_, commandInterface_, model_, this)); + children_.push_back(new PropertyBrowserItem(commonHandleForSeveralObjects, dispatcher_, commandInterface_, model_, sceneBackend_, this)); } } Q_EMIT childrenChanged(children_); + // TODO why multiple signals here?? // notify first not collapsed item about the structural changed { @@ -764,7 +927,6 @@ void PropertyBrowserItem::syncChildrenWithValueHandle() { // notify the view state accordingly if (children_.size() <= 1) { Q_EMIT expandedChanged(expanded()); - Q_EMIT showChildrenChanged(showChildren()); } } } @@ -783,15 +945,15 @@ bool PropertyBrowserItem::canBeChosenByColorPicker() const { const auto rootTypeRef = &handle.rootObject()->getTypeDescription(); - if (!(rootTypeRef == &raco::user_types::ProjectSettings::typeDescription || - rootTypeRef == &raco::user_types::LuaScript::typeDescription || - rootTypeRef == &raco::user_types::LuaInterface::typeDescription || - rootTypeRef == &raco::user_types::MeshNode::typeDescription || - rootTypeRef == &raco::user_types::Material::typeDescription)) { + if (!(rootTypeRef == &user_types::ProjectSettings::typeDescription || + rootTypeRef == &user_types::LuaScript::typeDescription || + rootTypeRef == &user_types::LuaInterface::typeDescription || + rootTypeRef == &user_types::MeshNode::typeDescription || + rootTypeRef == &user_types::Material::typeDescription)) { return false; } - if (handle.isRefToProp(&raco::user_types::Node::translation_) || handle.isRefToProp(&raco::user_types::Node::rotation_) || handle.isRefToProp(&raco::user_types::Node::scaling_)) { + if (handle.isRefToProp(&user_types::Node::translation_) || handle.isRefToProp(&user_types::Node::rotation_) || handle.isRefToProp(&user_types::Node::scaling_)) { return false; } @@ -823,6 +985,10 @@ bool PropertyBrowserItem::isProperty() const { return valueHandles_.begin()->isProperty(); } +bool PropertyBrowserItem::isRootItem() const { + return isObject(); +} + bool PropertyBrowserItem::isTagContainerProperty() const { return core::Queries::isTagContainerProperty(*valueHandles_.begin()); } @@ -882,4 +1048,22 @@ bool PropertyBrowserItem::getDefaultExpanded() const { }); } +std::vector PropertyBrowserItem::contextMenuActions() { + if (searchAnnotationInParents()) { + return {}; + } + + return { + {"Copy", + PropertyCopyPaste::canCopyValue(this), + [this]() { + PropertyCopyPaste::copyValue(this); + }}, + {"Paste", + PropertyCopyPaste::canPasteValue(this), + [this]() { + PropertyCopyPaste::pasteValue(this); + }}}; +} + } // namespace raco::property_browser diff --git a/gui/libPropertyBrowser/src/PropertyBrowserWidget.cpp b/gui/libPropertyBrowser/src/PropertyBrowserWidget.cpp index 5af43dca..b69b899c 100644 --- a/gui/libPropertyBrowser/src/PropertyBrowserWidget.cpp +++ b/gui/libPropertyBrowser/src/PropertyBrowserWidget.cpp @@ -11,24 +11,25 @@ #include "common_widgets/QtGuiFormatter.h" #include "core/CoreFormatter.h" +#include "core/Errors.h" +#include "core/PrefabOperations.h" #include "core/Project.h" -#include "core/ProjectSettings.h" #include "core/SceneBackendInterface.h" -#include "log_system/log.h" #include "object_tree_view/ObjectTreeDockManager.h" #include "property_browser/PropertyBrowserItem.h" #include "property_browser/PropertyBrowserLayouts.h" #include "property_browser/PropertyBrowserModel.h" -#include "property_browser/PropertySubtreeView.h" +#include "property_browser/Utilities.h" +#include "user_types/PrefabInstance.h" +#include "user_types/Texture.h" + #include "style/Icons.h" + #include -#include #include -#include +#include #include -#include -#include -#include +#include namespace raco::property_browser { @@ -36,94 +37,6 @@ using namespace style; using SDataChangeDispatcher = components::SDataChangeDispatcher; -template -constexpr bool playEdgeAnimationForPosition(const QPoint& modificationPosition) { - static_assert(Edge == Qt::BottomEdge || Edge == Qt::TopEdge, "Edge as to be Qt::TopEdget or Qt::BottomEdget"); - // play edge animation regardless of modification position - return true; -} - -template -constexpr QLabel* createNotificationWidget(PropertyBrowserModel* model, QWidget* parent) { - auto* widget = new QLabel{parent}; - widget->setMinimumHeight(0); - widget->setMaximumHeight(0); - auto notificationWidgetPalette = widget->palette(); - notificationWidgetPalette.setColor(QPalette::ColorRole::Window, QColor{25, 25, 200, 60}); - widget->setPalette(notificationWidgetPalette); - - QObject::connect(model, &PropertyBrowserModel::addNotVisible, widget, [widget, parent](QWidget* source) { - if (playEdgeAnimationForPosition(parent->mapFromGlobal(source->mapToGlobal({0, 0})))) { - auto* group = new QSequentialAnimationGroup{widget}; - auto* outAnimation = new QPropertyAnimation(widget, "maximumHeight"); - outAnimation->setDuration(50); - outAnimation->setStartValue(0); - outAnimation->setEndValue(5); - auto* inAnimation = new QPropertyAnimation(widget, "maximumHeight"); - inAnimation->setDuration(200); - inAnimation->setStartValue(5); - inAnimation->setEndValue(0); - group->addAnimation(outAnimation); - group->addAnimation(inAnimation); - group->start(QSequentialAnimationGroup::DeleteWhenStopped); - } - }); - return widget; -} - -PropertyBrowserView::PropertyBrowserView(core::SceneBackendInterface* sceneBackend, PropertyBrowserItem* item, PropertyBrowserModel* model, QWidget* parent) - : sceneBackend_{sceneBackend}, QWidget{parent} { - item->setParent(this); - auto* layout = new PropertyBrowserGridLayout{this}; - auto* content = new QWidget{this}; - auto* contentLayout = new PropertyBrowserVBoxLayout{content}; - contentLayout->setContentsMargins(0, 0, 5, 0); - content->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding); - - layout->addWidget(content, 0, 0); - - auto* topNotificationWidget = createNotificationWidget(model, this); - layout->addWidget(topNotificationWidget, 0, 0); - auto* bottomNotificationWidget = createNotificationWidget(model, this); - layout->addWidget(bottomNotificationWidget, 2, 0); - - QObject::connect(model, &PropertyBrowserModel::beforeStructuralChange, this, [this, content](QWidget* toChange) { - auto focusWidget = QApplication::focusWidget(); - - if (!focusWidget || !content->isAncestorOf(focusWidget) || focusWidget->visibleRegion().isEmpty()) { - focusWidget = nullptr; - // Search for the first label visible in our content - for (auto label : content->findChildren()) { - if (!label->visibleRegion().isEmpty()) { - if (!focusWidget || focusWidget->mapToGlobal({0, 0}).y() > label->mapToGlobal({0, 0}).y()) { - focusWidget = label; - } - } - } - } - - // if the focsed widget is inside the widget which will structurally change - // then we can only keep that widget focused - if (toChange->isAncestorOf(focusWidget)) { - focusWidget = toChange; - } - // if we have more than one changed valueHandle in the property browser we need to find the common widget. - // If we get more complex cases we may also need an afterStructuralChange to clean up the verticalPivotWidget. - if (verticalPivotWidget_ && verticalPivotWidget_->isAncestorOf(focusWidget)) { - // Currently we only need to check for hierarchy case - // e.g. if we have an error the EditorObject and associated engine property table will change (parent -> child) - focusWidget = verticalPivotWidget_; - } - - if (focusWidget) { - verticalPivot_ = mapFromGlobal(focusWidget->mapToGlobal({0, 0})); - verticalPivotWidget_ = focusWidget; - } - }); - - contentLayout->addWidget(new PropertySubtreeView{sceneBackend_, model, item, this}); -} - PropertyBrowserWidget::PropertyBrowserWidget( SDataChangeDispatcher dispatcher, core::CommandInterface* commandInterface, @@ -143,16 +56,40 @@ PropertyBrowserWidget::PropertyBrowserWidget( lockButton_->setContentsMargins(0, 0, 0, 0); lockButton_->setFlat(true); lockButton_->setIcon(Icons::instance().unlocked); + lockButton_->setToolTip("Lock current property browser"); lockButton_->connect(lockButton_, &QPushButton::clicked, this, [this]() { setLocked(!locked_); }); - layout_.addWidget(lockButton_, 0, 0, Qt::AlignLeft); + refButton_ = new QPushButton{this}; + refButton_->setContentsMargins(0, 0, 0, 0); + refButton_->setFlat(true); + refButton_->setIcon(Icons::instance().goToLeft); + refButton_->setToolTip("Show objects referencing current object"); + connect(refButton_, &QPushButton::clicked, this, &PropertyBrowserWidget::showRefToThis); + + prefabLookupButton_ = new QPushButton{this}; + prefabLookupButton_->setContentsMargins(0, 0, 0, 0); + prefabLookupButton_->setFlat(true); + prefabLookupButton_->setIcon(Icons::instance().prefabLookup); + prefabLookupButton_->setToolTip("Show object in prefab"); + prefabLookupButton_->setEnabled(false); + connect(prefabLookupButton_, &QPushButton::clicked, this, [this]() { + rootItem_->model()->Q_EMIT selectionRequested(QString::fromStdString(getObjectIdInPrefab())); + }); + + const auto buttonsLayout = new PropertyBrowserHBoxLayout(this); + buttonsLayout->addWidget(lockButton_, 0, Qt::AlignLeft); + buttonsLayout->addWidget(refButton_, 0, Qt::AlignLeft); + buttonsLayout->addWidget(prefabLookupButton_, 0, Qt::AlignLeft); + + layout_.addLayout(buttonsLayout, 0, 0, Qt::AlignLeft); layout_.addWidget(emptyLabel_, 1, 0, Qt::AlignCenter); layout_.setColumnStretch(0, 1); layout_.setRowStretch(1, 1); + layout_.setContentsMargins(0, 0, 5, 0); - subscription_ = dispatcher_->registerOnObjectsLifeCycle([](auto) {}, [this](core::SEditorObject obj) { + lifecycleSubs_ = dispatcher_->registerOnObjectsLifeCycle([](auto) {}, [this](core::SEditorObject obj) { if (propertyBrowser_) { if (currentObjects_.find(obj) != currentObjects_.end()) { if (locked_) { @@ -160,12 +97,56 @@ PropertyBrowserWidget::PropertyBrowserWidget( } clear(); } - } + } }); } -void PropertyBrowserWidget::setLockable(bool lockable) { - layout_.itemAtPosition(0, 0)->widget()->setVisible(lockable); +void PropertyBrowserWidget::showRefToThis() { + QMenu refMenu; + if (!currentObjects_.empty() && *currentObjects_.begin() && rootItem_ && currentObjects_.size() == 1) { + // get list of ref objects sorted by name + std::vector> refObjects; + + for (const auto& refObject : (*currentObjects_.begin())->referencesToThis()) { + const auto refObjectName = QString::fromStdString(core::Queries::getFullObjectHierarchyPath(refObject.lock())); + const auto refObjectID = QString::fromStdString(refObject.lock()->objectID()); + refObjects.emplace_back(refObjectName, refObjectID); + } + std::sort(refObjects.begin(), refObjects.end(), [](const auto& lhs, const auto& rhs) { + return lhs.first < rhs.first; + }); + + // add ref menu items + for (const auto& [refObjectName, refObjectID] : refObjects) { + const auto id = refObjectID; + refMenu.addAction(refObjectName, [this, id]() { + rootItem_->model()->Q_EMIT selectionRequested(id); + }); + } + } + + if (refMenu.isEmpty()) { + refMenu.addAction("No references", []() {}); + } + + refMenu.exec(mapToGlobal(refButton_->pos() + QPoint(refButton_->width(), 0))); +} + +std::string PropertyBrowserWidget::getObjectIdInPrefab() const { + if (rootItem_ && currentObjects_.size() == 1) { + const auto selectedObject = *currentObjects_.begin(); + if (const auto prefabInstance = core::PrefabOperations::findContainingPrefabInstance(selectedObject)) { + if(const auto prefab = *prefabInstance->template_) { + return user_types::PrefabInstance::mapObjectIDFromInstance(selectedObject, prefab, prefabInstance); + } + } + } + return std::string{}; +} + +void PropertyBrowserWidget::setLockable(bool lockable) const { + lockButton_->setVisible(lockable); + refButton_->setVisible(lockable); } void PropertyBrowserWidget::clear() { @@ -173,13 +154,15 @@ void PropertyBrowserWidget::clear() { propertyBrowser_.reset(); currentObjects_.clear(); emptyLabel_->setVisible(true); + showScrollBar(false); } } void PropertyBrowserWidget::setLocked(bool locked) { - bool isLockChanged = locked_ != locked; + const bool isLockChanged = locked_ != locked; locked_ = locked; lockButton_->setIcon(locked_ ? Icons::instance().locked : Icons::instance().unlocked); + lockButton_->setToolTip(locked_ ? "Unlock current property browser" : "Lock current property browser"); if (!locked_ && treeDockManager_) { auto selection = treeDockManager_->getSelection(); if (!selection.empty()) { @@ -195,15 +178,25 @@ void PropertyBrowserWidget::setLocked(bool locked) { } } -void PropertyBrowserWidget::setObjectFromObjectId(const QString& objectID) { +void PropertyBrowserWidget::setObjectFromObjectId(const QString& objectID, const QString& objectProperty) { const auto handle = core::ValueHandle{commandInterface_->project()->getInstanceByID(objectID.toStdString())}; - setObjects({handle.rootObject()}); + if (handle) { + setObjects({handle.rootObject()}, objectProperty); + } } PropertyBrowserModel* PropertyBrowserWidget::model() const { return model_; } + +void PropertyBrowserWidget::showScrollBar(bool isAlwaysOn) { + auto scrollArea = findAncestor(parentWidget()); + if (scrollArea) { + scrollArea->setVerticalScrollBarPolicy(isAlwaysOn ? Qt::ScrollBarAlwaysOn : Qt::ScrollBarAsNeeded); + } +} + void PropertyBrowserWidget::setObjectsImpl(const core::SEditorObjectSet& objects, bool forceExpandStateUpdate) { if (propertyBrowser_ && currentObjects_ == objects) { // No need to update if we still are referencing to the same objects. @@ -220,17 +213,36 @@ void PropertyBrowserWidget::setObjectsImpl(const core::SEditorObjectSet& objects emptyLabel_->setVisible(false); std::set valueHandles(objects.begin(), objects.end()); - rootItem_ = new PropertyBrowserItem{valueHandles, dispatcher_, commandInterface_, model_}; - propertyBrowser_.reset(new PropertyBrowserView{sceneBackend_, rootItem_, model_, this}); + rootItem_ = new PropertyBrowserItem{valueHandles, dispatcher_, commandInterface_, model_, sceneBackend_}; + + showScrollBar(objects.size() == 1 && (*objects.begin())->isType()); + + propertyBrowser_.reset(new PropertySubtreeView{sceneBackend_, model_, rootItem_, this, nullptr}); + rootItem_->setParent(propertyBrowser_.get()); + propertyBrowser_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding); + currentObjects_ = objects; layout_.addWidget(propertyBrowser_.get(), 1, 0); + prefabLookupButton_->setEnabled(!getObjectIdInPrefab().empty()); } } -void PropertyBrowserWidget::setObjects(const core::SEditorObjectSet& objects) { +void PropertyBrowserWidget::setObjects(const core::SEditorObjectSet& objects, const QString& property) { setObjectsImpl(objects, false); + + if ((locked_ && currentObjects_ == objects) || !locked_) { + highlightProperty(property); + } } +void PropertyBrowserWidget::highlightProperty(const QString& property) { + if (!property.isEmpty()) { + // We need to call updateGeometry otherwise the scrolling does not work correctly + updateGeometry(); + + rootItem_->highlightProperty(property); + } +} } // namespace raco::property_browser diff --git a/gui/libPropertyBrowser/src/PropertyCopyPaste.cpp b/gui/libPropertyBrowser/src/PropertyCopyPaste.cpp new file mode 100644 index 00000000..4da0ab64 --- /dev/null +++ b/gui/libPropertyBrowser/src/PropertyCopyPaste.cpp @@ -0,0 +1,390 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "property_browser/PropertyCopyPaste.h" + +#include "common_widgets/RaCoClipboard.h" + +namespace raco::property_browser { + +bool PropertyCopyPaste::canCopyValue(PropertyBrowserItem* item) { + return item->hasSingleValue(); +} + +void PropertyCopyPaste::copyValue(PropertyBrowserItem* item) { + if (item->hasSingleValue()) { + RaCoClipboard::set(serialization::serializeProperty(*item->project(), *item->valueHandles().begin()->constValueRef()), MimeTypes::PROPERTY); + } +} + +void PropertyCopyPaste::copyValuePlainText(PropertyBrowserItem* item) { + const auto valueRef = item->valueHandles().cbegin()->constValueRef(); + copyValuePlainText(valueRef); +} + +void PropertyCopyPaste::copyChildValuePlainText(PropertyBrowserItem* item, int index) { + const auto valueRef = item->children().at(index)->valueHandles().cbegin()->constValueRef(); + copyValuePlainText(valueRef); +} + +void PropertyCopyPaste::copyValuePlainText(const core::ValueBase* valueBase) { + std::string value{}; + + switch (valueBase->type()) { + case serialization::PrimitiveType::Bool: + value = std::to_string(valueBase->asBool()); + break; + case serialization::PrimitiveType::Double: + value = std::to_string(valueBase->asDouble()); + break; + case serialization::PrimitiveType::Int: + value = std::to_string(valueBase->asInt()); + break; + case serialization::PrimitiveType::Int64: + value = std::to_string(valueBase->asInt64()); + break; + case serialization::PrimitiveType::String: + value = valueBase->asString(); + break; + } + + if (!value.empty()) { + const auto mimeType = "text/plain"; + RaCoClipboard::set(value, mimeType); + } +} + +void PropertyCopyPaste::pasteInt(PropertyBrowserItem* item, core::ValueBase* value) { + std::optional newValue; + switch (value->type()) { + case data_storage::PrimitiveType::Int: { + newValue = value->asInt(); + break; + } + case data_storage::PrimitiveType::Int64: + newValue = static_cast(value->asInt64()); + break; + case data_storage::PrimitiveType::String: + try { + newValue = std::stoi(value->asString()); + } catch (std::invalid_argument&) { + break; + } catch (std::out_of_range&) { + break; + } + break; + case data_storage::PrimitiveType::Double: + newValue = static_cast(value->asDouble()); + break; + case data_storage::PrimitiveType::Bool: + case data_storage::PrimitiveType::Ref: + case data_storage::PrimitiveType::Table: + case data_storage::PrimitiveType::Struct: + break; + } + + if (newValue.has_value()) { + // Target property may be an enum so we have to check: + if (std::all_of(item->valueHandles().begin(), item->valueHandles().end(), [&item, &newValue](const core::ValueHandle& handle) { + return item->commandInterface()->canSet(handle, newValue.value()); + })) { + item->set(newValue.value()); + } + } +} + +void PropertyCopyPaste::pasteBool(PropertyBrowserItem* item, core::ValueBase* value) { + switch (value->type()) { + case data_storage::PrimitiveType::Bool: + item->set(value->asBool()); + break; + case data_storage::PrimitiveType::String: + if (value->asString() == "true") { + item->set(true); + } else if (value->asString() == "false") { + item->set(false); + } + case data_storage::PrimitiveType::Int: + case data_storage::PrimitiveType::Int64: + case data_storage::PrimitiveType::Double: + case data_storage::PrimitiveType::Ref: + case data_storage::PrimitiveType::Table: + case data_storage::PrimitiveType::Struct: + break; + } +} + +void PropertyCopyPaste::pasteInt64(PropertyBrowserItem* item, core::ValueBase* value) { + switch (value->type()) { + case data_storage::PrimitiveType::Int: + item->set(static_cast(value->asInt())); + break; + case data_storage::PrimitiveType::Int64: + item->set(value->asInt64()); + break; + case data_storage::PrimitiveType::String: + try { + int64_t result = std::stol(value->asString()); + item->set(result); + } catch (std::invalid_argument&) { + break; + } catch (std::out_of_range&) { + break; + } + break; + case data_storage::PrimitiveType::Double: + item->set(static_cast(value->asDouble())); + break; + case data_storage::PrimitiveType::Bool: + case data_storage::PrimitiveType::Ref: + case data_storage::PrimitiveType::Table: + case data_storage::PrimitiveType::Struct: + break; + } +} + +void PropertyCopyPaste::pasteDouble(PropertyBrowserItem* item, core::ValueBase* value) { + switch (value->type()) { + case data_storage::PrimitiveType::Int: + item->set(static_cast(value->asInt())); + break; + case data_storage::PrimitiveType::Int64: + item->set(static_cast(value->asInt64())); + break; + case data_storage::PrimitiveType::String: + try { + double result = std::stod(value->asString()); + item->set(result); + } catch (std::invalid_argument&) { + break; + } catch (std::out_of_range&) { + break; + } + break; + case data_storage::PrimitiveType::Double: + item->set(value->asDouble()); + break; + case data_storage::PrimitiveType::Bool: + case data_storage::PrimitiveType::Ref: + case data_storage::PrimitiveType::Table: + case data_storage::PrimitiveType::Struct: + break; + } +} + +void PropertyCopyPaste::pasteString(PropertyBrowserItem* item, core::ValueBase* value) { + switch (value->type()) { + case data_storage::PrimitiveType::Int: + item->set(std::to_string(value->asInt())); + break; + case data_storage::PrimitiveType::Int64: + item->set(std::to_string(value->asInt64())); + break; + case data_storage::PrimitiveType::String: + item->set(value->asString()); + break; + case data_storage::PrimitiveType::Double: + item->set(std::to_string(value->asDouble())); + break; + case data_storage::PrimitiveType::Bool: + item->set(value->asBool() ? "true" : "false"); + break; + case data_storage::PrimitiveType::Ref: + case data_storage::PrimitiveType::Table: + case data_storage::PrimitiveType::Struct: + break; + } +} + +void PropertyCopyPaste::pasteRef(PropertyBrowserItem* item, core::ValueBase* value) { + if (value->type() == data_storage::PrimitiveType::Ref) { + auto valueRef = value->asRef(); + if (std::all_of(item->valueHandles().begin(), item->valueHandles().end(), [&item, &valueRef](const core::ValueHandle& handle) { + return core::Queries::isValidReferenceTarget(*item->project(), handle, valueRef); + })) { + item->set(valueRef); + } + } +} + +template +void PropertyCopyPaste::pasteVector(PropertyBrowserItem* item, core::ValueBase* value) { + size_t childCount = item->children().length(); + switch (value->type()) { + case data_storage::PrimitiveType::Struct: { + data_storage::ReflectionInterface& substructure = value->getSubstructure(); + auto substructureChildCount = substructure.size(); + for (int i = 0; i < std::min(childCount, substructureChildCount); ++i) { + switch (substructure[i]->type()) { + case data_storage::PrimitiveType::Int: { + item->children().at(i)->set(static_cast(substructure[i]->asInt())); + break; + } + case data_storage::PrimitiveType::Double: { + item->children().at(i)->set(static_cast(substructure[i]->asDouble())); + break; + } + default: + break; + } + } + return; + } + case data_storage::PrimitiveType::Int: + case data_storage::PrimitiveType::Int64: + case data_storage::PrimitiveType::String: + case data_storage::PrimitiveType::Double: + case data_storage::PrimitiveType::Bool: + case data_storage::PrimitiveType::Ref: + case data_storage::PrimitiveType::Table: + return; + } +} + +bool PropertyCopyPaste::isVector(PropertyBrowserItem* item) { + return std::all_of(item->valueHandles().begin(), item->valueHandles().end(), [](const core::ValueHandle& handle) { + return handle.isVec2f() || handle.isVec3f() || handle.isVec4f() || handle.isVec2i() || handle.isVec3i() || handle.isVec4i(); + }); +} + +bool PropertyCopyPaste::isVector(core::ValueBase* value) { + auto* td = &value->asStruct().getTypeDescription(); + return td == &core::Vec2f::typeDescription || + td == &core::Vec3f::typeDescription || + td == &core::Vec4f::typeDescription || + td == &core::Vec2i::typeDescription || + td == &core::Vec3i::typeDescription || + td == &core::Vec4i::typeDescription; +} + +void PropertyCopyPaste::pasteStruct(PropertyBrowserItem* item, core::ValueBase* value) { + if (value->type() != data_storage::PrimitiveType::Struct) { + return; + } + + if (isVector(item) && isVector(value)) { + if (item->children().at(0)->type() == data_storage::PrimitiveType::Int) { + pasteVector(item, value); + } else { + pasteVector(item, value); + } + } else { + for (const auto& child : item->children()) { + auto propName = child->getPropertyName(); + if (value->asStruct().hasProperty(propName)) { + pastePropertyOfSameType(child, value->asStruct()[propName]); + } + } + } +} + +void PropertyCopyPaste::pasteTable(PropertyBrowserItem* item, core::ValueBase* value) { + if (value->type() != data_storage::PrimitiveType::Table) { + return; + } + + if (item->query()) { + if (value->query()) { + auto srcTags = value->asTable().asVector(); + if (std::all_of(item->valueHandles().begin(), item->valueHandles().end(), [&item, &srcTags](const core::ValueHandle& handle) { + return item->commandInterface()->canSetTags(handle, srcTags); + })) { + item->setTags(srcTags); + } + } + return; + } + + if (value->query()) { + return; + } + + if (item->query()) { + if (value->query()) { + std::vector> renderableTags; + const auto& table = value->asTable(); + for (size_t index = 0; index < table.size(); index++) { + renderableTags.emplace_back(std::make_pair(table.name(index), table.get(index)->asInt())); + } + if (std::all_of(item->valueHandles().begin(), item->valueHandles().end(), [&item, &renderableTags](const core::ValueHandle& handle) { + return item->commandInterface()->canSetRenderableTags(handle, renderableTags); + })) { + item->setTags(renderableTags); + } + } + return; + } + + if (value->query()) { + return; + } + + auto& substructure = value->getSubstructure(); + for (const auto& child : item->children()) { + auto propName = child->getPropertyName(); + if (substructure.hasProperty(propName)) { + pastePropertyOfSameType(child, substructure[propName]); + } + } +} + +void PropertyCopyPaste::pastePropertyOfSameType(PropertyBrowserItem* item, data_storage::ValueBase* value) { + if (value->type() == item->type()) { + pasteProperty(item, value); + } +} + +void PropertyCopyPaste::pasteProperty(PropertyBrowserItem* item, data_storage::ValueBase* value) { + switch (item->type()) { + case data_storage::PrimitiveType::Bool: + pasteBool(item, value); + break; + case data_storage::PrimitiveType::Int: + pasteInt(item, value); + break; + case data_storage::PrimitiveType::Int64: + pasteInt64(item, value); + break; + case data_storage::PrimitiveType::Double: + pasteDouble(item, value); + break; + case data_storage::PrimitiveType::String: + pasteString(item, value); + break; + case data_storage::PrimitiveType::Ref: + pasteRef(item, value); + break; + case data_storage::PrimitiveType::Table: + pasteTable(item, value); + break; + case data_storage::PrimitiveType::Struct: + pasteStruct(item, value); + break; + } +} + +bool PropertyCopyPaste::canPasteValue(PropertyBrowserItem* item) { + auto json = RaCoClipboard::get(MimeTypes::PROPERTY); + return serialization::deserializeProperty(*item->project(), json) != nullptr; +} + +void PropertyCopyPaste::pasteValue(PropertyBrowserItem* item) { + auto json = RaCoClipboard::get(MimeTypes::PROPERTY); + if (auto value = serialization::deserializeProperty(*item->project(), json)) { + std::string desc = fmt::format("Paste value into property '{}'", item->getPropertyPath()); + item->commandInterface()->executeCompositeCommand( + [item, &value]() { + pasteProperty(item, value.get()); + }, + desc); + } +} + +} // namespace raco::property_browser diff --git a/gui/libPropertyBrowser/src/PropertySubtreeChildrenContainer.cpp b/gui/libPropertyBrowser/src/PropertySubtreeChildrenContainer.cpp index 4874c364..983e1207 100644 --- a/gui/libPropertyBrowser/src/PropertySubtreeChildrenContainer.cpp +++ b/gui/libPropertyBrowser/src/PropertySubtreeChildrenContainer.cpp @@ -19,7 +19,6 @@ namespace raco::property_browser { PropertySubtreeChildrenContainer::PropertySubtreeChildrenContainer(PropertyBrowserItem* item, QWidget* parent) : QWidget{parent}, layout_{new PropertyBrowserVBoxLayout{this}} { - layout_->setAlignment(Qt::AlignTop); } void PropertySubtreeChildrenContainer::setOffset(int offset) { @@ -34,8 +33,22 @@ void PropertySubtreeChildrenContainer::removeWidget(QWidget* child) { layout_->removeWidget(child); } -void PropertySubtreeChildrenContainer::insertWidget(size_t index, QWidget* child) { - layout_->insertWidget(static_cast(index), child, 0, Qt::AlignTop); +void PropertySubtreeChildrenContainer::deleteAllChildren() { + for (const auto& child : getChildSubtreeViews()) { + removeWidget(child); + child->deleteLater(); + } +} + +std::vector PropertySubtreeChildrenContainer::getChildSubtreeViews() const { + std::vector result; + for (int index = 0; index < layout_->count(); index++) { + auto widget = dynamic_cast(layout_->itemAt(index)->widget()); + if (widget) { + result.emplace_back(widget); + } + } + return result; } } // namespace raco::property_browser diff --git a/gui/libPropertyBrowser/src/PropertySubtreeView.cpp b/gui/libPropertyBrowser/src/PropertySubtreeView.cpp index 5d39f97a..50882a8f 100644 --- a/gui/libPropertyBrowser/src/PropertySubtreeView.cpp +++ b/gui/libPropertyBrowser/src/PropertySubtreeView.cpp @@ -12,63 +12,42 @@ #include "ErrorBox.h" #include "core/CoreFormatter.h" #include "property_browser/PropertyBrowserLayouts.h" +#include "property_browser/PropertyBrowserUtilities.h" #include "property_browser/PropertyBrowserWidget.h" +#include "property_browser/Utilities.h" #include "property_browser/WidgetFactory.h" #include "property_browser/controls/ExpandButton.h" #include "property_browser/editors/LinkEditor.h" #include "property_browser/editors/PropertyEditor.h" #include "user_types/LuaScript.h" -#include "user_types/LuaScriptModule.h" #include -#include #include -#include #include #include #include +#include +#include namespace raco::property_browser { -void drawHighlight(QWidget* widget, float intensity) { - if (intensity > 0) { - QPainter painter{widget}; - QPen pen = painter.pen(); - pen.setStyle(Qt::PenStyle::NoPen); - painter.setPen(pen); - painter.setBrush(qApp->palette().highlight()); - painter.drawRect(widget->rect()); - } -} +void PropertySubtreeView::registerLabelContextMenu(QWidget* labelWidget, PropertyBrowserItem* item) { + labelWidget->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); -EmbeddedPropertyBrowserView::EmbeddedPropertyBrowserView(PropertyBrowserItem* item, QWidget* parent) - : QFrame{parent} { -} + connect(labelWidget, &PropertyEditor::customContextMenuRequested, [this, labelWidget, item](const QPoint& p) { + auto* menu = new QMenu(this); -void PropertySubtreeView::registerCopyPasteContextMenu(QWidget* widget) { - widget->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); - connect(widget, &PropertyEditor::customContextMenuRequested, [this, widget](const QPoint& p) { - auto* treeViewMenu = new QMenu(this); - // TODO shouldn't we disable this is we can't copy since we have a multiple value? - // see PropertyEditor::copyValue - auto copyAction = treeViewMenu->addAction("Copy", this, [this]() { - propertyControl_->copyValue(); - }); - copyAction->setEnabled(propertyControl_->canCopyValue()); - // TODO disable when clipboard doesn't contain property !? - auto pasteAction = treeViewMenu->addAction("Paste", this, [this]() { - propertyControl_->pasteValue(); - }); - pasteAction->setEnabled(propertyControl_->canPasteValue()); + for (const auto& entry : item->contextMenuActions()) { + auto action = menu->addAction(QString::fromStdString(entry.description), entry.action); + action->setEnabled(entry.enabled); + } - treeViewMenu->exec(widget->mapToGlobal(p)); + menu->exec(labelWidget->mapToGlobal(p)); }); } -PropertySubtreeView::PropertySubtreeView(raco::core::SceneBackendInterface* sceneBackend, PropertyBrowserModel* model, PropertyBrowserItem* item, QWidget* parent) - : QWidget{parent}, item_{item}, model_{model}, sceneBackend_{sceneBackend}, layout_{this} { - layout_.setAlignment(Qt::AlignTop); - +PropertySubtreeView::PropertySubtreeView(core::SceneBackendInterface* sceneBackend, PropertyBrowserModel* model, PropertyBrowserItem* item, QWidget *parent, PropertySubtreeView* parentSubtree) + : QWidget{parent}, sceneBackend_{sceneBackend}, item_{item}, model_{model}, layout_{this}, parentSubtree_(parentSubtree) { // .PropertySubtreeView--------------------------------------------------------------. // | expand button | label + margin | link control | property / value control | // .PropertySubtreeChildrenContainer-------------------------------------------------. @@ -79,9 +58,12 @@ PropertySubtreeView::PropertySubtreeView(raco::core::SceneBackendInterface* scen auto* labelContainer = new QWidget{this}; auto* labelLayout = new PropertyBrowserHBoxLayout{labelContainer}; labelLayout->setAlignment(Qt::AlignLeft); - if (item->isProperty()) { - label_ = WidgetFactory::createPropertyLabel(item, labelContainer); - label_->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + if (!item->isRootItem()) { + // Note: the factory function might return a label that is not a QLabel but some other widget. + // The code below is still expected to work with this. + std::tie(label_, controlWidget_) = WidgetFactory::createPropertyWidgets(item, labelContainer); + label_->setToolTip(QString::fromStdString(item->labelToolTipText())); + registerLabelContextMenu(label_, item); if (item->expandable()) { decorationWidget_ = new ExpandButton(item, labelContainer); @@ -92,25 +74,12 @@ PropertySubtreeView::PropertySubtreeView(raco::core::SceneBackendInterface* scen } decorationWidget_->setFixedWidth(28); - auto* linkControl = WidgetFactory::createLinkControl(item, labelContainer); - - propertyControl_ = WidgetFactory::createPropertyEditor(item, labelContainer); - - if (propertyControl_ != nullptr) { - registerCopyPasteContextMenu(label_); - } - labelLayout->addWidget(decorationWidget_, 0); labelLayout->addWidget(label_, 0); - labelLayout->addWidget(linkControl, 1); - - generateItemTooltip(item, true); - - linkControl->setControl(propertyControl_); - label_->setEnabled(item->editable()); - QObject::connect(item, &PropertyBrowserItem::editableChanged, label_, &QWidget::setEnabled); + labelLayout->addWidget(controlWidget_, 0); } else { - // Dummy label for the case that we are an object. + // Root items show only the children but no expand button, label, or link/property controls. + // We setup dummy button & label widgets anyway since they are used in the layout calculation. decorationWidget_ = new QWidget{this}; label_ = new QLabel{this}; decorationWidget_->setFixedWidth(0); @@ -121,228 +90,196 @@ PropertySubtreeView::PropertySubtreeView(raco::core::SceneBackendInterface* scen labelLayout->addWidget(label_, 0); } - if (item->isObject() && item->valueHandles().size() > 1) { - for (auto handle : item->valueHandles()) { - auto nameHandle = handle.get("objectName"); - objectNameChangeSubscriptions_.push_back(item->dispatcher()->registerOn(nameHandle, [this]() { - updateObjectNameDisplay(); - })); - } - updateObjectNameDisplay(); - } + errorContainer_ = new QWidget(this); + errorLayout_ = new PropertyBrowserVBoxLayout(errorContainer_); + layout_.insertWidget(ErrorRow, errorContainer_); + QObject::connect(item, &PropertyBrowserItem::displayErrorChanged, this, &PropertySubtreeView::updateErrors); + updateErrors(); - QObject::connect(item, &PropertyBrowserItem::errorChanged, this, &PropertySubtreeView::updateError); - updateError(); + layout_.insertWidget(LabelRow, labelContainer); - layout_.addWidget(labelContainer, 2, 0); + // Since the horizontal layouting is done via label_->setFixedWidth we have to cache the minimum size + // hint before calling setFixedWidth because the size hint will just be the fixed width afterwards. + labelMinWidth_ = label_->minimumSizeHint().width(); + + if (parentSubtree_) { + // We need to initialize things here before performing the layout recalculation below + parentSubtree_->childrenContainer_->addWidget(this); + setLabelAreaWidth(parentSubtree_->label_->width()); + } + updateLabelAreaWidth(); if (item->expandable()) { // Events which can cause a build or destroy of the childrenContainer_ QObject::connect(item, &PropertyBrowserItem::childrenChanged, this, &PropertySubtreeView::updateChildrenContainer); QObject::connect(item, &PropertyBrowserItem::showChildrenChanged, this, &PropertySubtreeView::updateChildrenContainer); - QObject::connect(item, &PropertyBrowserItem::childrenChangedOrCollapsedChildChanged, this, &PropertySubtreeView::playStructureChangeAnimation); + QObject::connect(item, &PropertyBrowserItem::childrenChangedOrCollapsedChildChanged, [this]() { + playHighlightAnimation(250, 0.0f, 1.0f); + }); updateChildrenContainer(); } -} - - -void PropertySubtreeView::generateItemTooltip(PropertyBrowserItem* item, bool connectWithChangeEvents) { - auto labelToolTip = QString::fromStdString(item->getPropertyName()); - - if (item->isLuaProperty()) { - labelToolTip.append(" [" + QString::fromStdString(item->luaTypeName()) + "]"); - } - label_->setToolTip(labelToolTip); - if (item->valueHandles().begin()->isRefToProp(&core::EditorObject::objectName_)) { - QString tooltipText; - if (item->valueHandles().size() == 1) { - tooltipText = QString::fromStdString(sceneBackend_->getExportedObjectNames(item->valueHandles().begin()->rootObject())); - } else { - QStringList items = objectNames(); - items.push_front("Current objects:"); - tooltipText = items.join("\n"); - } - if (!tooltipText.isEmpty()) { - propertyControl_->setToolTip(tooltipText); - } - - if (connectWithChangeEvents) { - connect(item, &PropertyBrowserItem::valueChanged, this, [this, item] { generateItemTooltip(item, false); }); - } - } + layout_.addStretch(1); } -QStringList PropertySubtreeView::objectNames() const { - QStringList items; - for (auto handle : item_->valueHandles()) { - auto object = handle.rootObject(); - std::string labelText = fmt::format("{} [{}]", object->objectName(), object->getTypeDescription().typeName); - items.push_back(QString::fromStdString(labelText)); - } - items.sort(); - return items; -} - -void PropertySubtreeView::updateObjectNameDisplay() { - QStringList items = objectNames(); - items.push_front("Current objects:"); - QString description = items.join("\n"); - - if (layout_.itemAtPosition(0, 0) && layout_.itemAtPosition(0, 0)->widget()) { - auto* widget = layout_.itemAtPosition(0, 0)->widget(); - dynamic_cast(widget)->updateContent(description); - } else { - layout_.addWidget(new ErrorBox(description, core::ErrorLevel::INFORMATION, this), 0, 0); +void PropertySubtreeView::updateErrors() { + while (errorLayout_->count()) { + errorLayout_->removeItem(errorLayout_->itemAt(0)); } -} - -void PropertySubtreeView::updateError() { - if (layout_.itemAtPosition(1, 0) && layout_.itemAtPosition(1, 0)->widget()) { - auto* widget = layout_.itemAtPosition(1, 0)->widget(); - layout_.removeWidget(widget); - widget->hide(); - widget->deleteLater(); - } - - if (item_->hasError()) { - std::string errorMsg; - auto optCategory = item_->errorCategory(); - if (!optCategory.has_value()) { - errorMsg = "Multiple Erorrs"; - } else { - auto category = optCategory.value(); - if (category == core::ErrorCategory::RAMSES_LOGIC_RUNTIME || category == core::ErrorCategory::PARSING || category == core::ErrorCategory::GENERAL || category == core::ErrorCategory::MIGRATION) { - errorMsg = item_->errorMessage().c_str(); - } - } - if (!errorMsg.empty()) { - layout_.addWidget(new ErrorBox(QString::fromStdString(errorMsg), item_->maxErrorLevel(), this), 1, 0); - // It is unclear why this is needed - but without it, the error box does not appear immediately when an incompatible render buffer is assigned to a render target and the scene error view is in the background. - // The error box does appear later, e. g. when the mouse cursor is moved over the preview or when the left mouse button is clicked in a different widget. - update(); + const auto errorItems = item_->getDisplayErrorItems(); + if (!errorItems.empty()) { + errorContainer_->show(); + for (const auto& item : errorItems) { + errorLayout_->addWidget(new ErrorBox(item.message, item.level, this)); } + // TODO figure out if this is actually needed; it used to be + update(); + } else { + errorContainer_->hide(); } } void PropertySubtreeView::collectTabWidgets(QObject* item, QWidgetList& tabWidgets) { - if (auto itemWidget = qobject_cast(item)) { + if (const auto itemWidget = qobject_cast(item)) { if (itemWidget->focusPolicy() & Qt::TabFocus) { tabWidgets.push_back(itemWidget); } } - for (auto child : item->children()) { + for (const auto child : item->children()) { collectTabWidgets(child, tabWidgets); } } - void PropertySubtreeView::recalculateTabOrder() { QWidgetList tabWidgets; collectTabWidgets(this, tabWidgets); auto lastWidget = previousInFocusChain(); - for (auto widget : tabWidgets) { + for (const auto widget : tabWidgets) { setTabOrder(lastWidget, widget); lastWidget = widget; } } void PropertySubtreeView::updateChildrenContainer() { - if (item_->showChildren() && !childrenContainer_) { - if (item_->isProperty() && item_->type() == core::PrimitiveType::Ref) { - childrenContainer_ = new PropertySubtreeChildrenContainer{item_, this}; - childrenContainer_->addWidget(new EmbeddedPropertyBrowserView{item_, this}); - layout_.addWidget(childrenContainer_, 3, 0); - } else - if (item_->isObject() || hasTypeSubstructure(item_->type())) { + if (item_->showChildren()) { + if (childrenContainer_) { + childrenContainer_->deleteAllChildren(); + } else { childrenContainer_ = new PropertySubtreeChildrenContainer{item_, this}; + childrenContainer_->setOffset(decorationWidget_->width()); + layout_.insertWidget(ChildrenContainerRow, childrenContainer_); + } - for (const auto& child : item_->children()) { - auto* subtree = new PropertySubtreeView{sceneBackend_, model_, child, childrenContainer_}; - childrenContainer_->addWidget(subtree); - } - QObject::connect(item_, &PropertyBrowserItem::childrenChanged, childrenContainer_, [this](const QList items) { - Q_EMIT model_->beforeStructuralChange(this); - for (auto& childWidget : childrenContainer_->findChildren(QString{}, Qt::FindDirectChildrenOnly)) { - Q_EMIT model_->beforeRemoveWidget(childWidget); - childrenContainer_->removeWidget(childWidget); - childWidget->deleteLater(); - } - for (auto& child : items) { - auto* subtree = new PropertySubtreeView{sceneBackend_, model_, child, childrenContainer_}; - childrenContainer_->addWidget(subtree); - } - recalculateTabOrder(); + for (const auto& child : item_->children()) { + // The PropertySubtreeView will add itself as a child to the childrenContainer_ of its parent + // and perform a relayouting afterwards + auto subtree = new PropertySubtreeView{sceneBackend_, model_, child, childrenContainer_, this}; + + QObject::connect(child, &PropertyBrowserItem::highlighted, [this, subtree]() { + // We need to use a timer otherwise the scrolling does not work correctly + QTimer::singleShot(1, this, [this, subtree]() { + subtree->ensurePropertyVisible(); + subtree->playHighlightAnimation(2000, 1.0f, 0.0f); + }); }); - recalculateLabelWidth(); - layout_.addWidget(childrenContainer_, 3, 0); } - } else if (!item_->showChildren() && childrenContainer_) { - delete childrenContainer_; - childrenContainer_ = nullptr; - } + recalculateTabOrder(); + } else { + if (childrenContainer_) { + delete childrenContainer_; + childrenContainer_ = nullptr; - recalculateTabOrder(); + updateLabelAreaWidth(); + recalculateTabOrder(); + } + } } -void PropertySubtreeView::setLabelAreaWidth(int width) { - if (labelWidth_ != width) { - labelWidth_ = width; - recalculateLabelWidth(); +void PropertySubtreeView::ensurePropertyVisible() { + if (const auto scrollArea = property_browser::findAncestor(this)) { + scrollArea->ensureWidgetVisible(this); } } -void PropertySubtreeView::recalculateLabelWidth() { - if (childrenContainer_ != nullptr) { - childrenContainer_->setOffset(decorationWidget_->width()); - } - const int labelWidthHint = std::max(labelWidth_, getLabelAreaWidthHint() - decorationWidget_->width()); - if (label_->width() != labelWidthHint) { - label_->setFixedWidth(labelWidthHint); - } +void PropertySubtreeView::setLabelAreaWidth(int labelAreaWidth) { + const auto labelWidth = labelAreaWidth - decorationWidget_->width(); + if (labelAreaWidth_ != labelAreaWidth) { + labelAreaWidth_ = labelAreaWidth; + label_->setFixedWidth(labelWidth); - for (const auto& child : childrenContainer_->findChildren(QString{}, Qt::FindDirectChildrenOnly)) { - child->setLabelAreaWidth(labelWidthHint - decorationWidget_->width()); + if (childrenContainer_ != nullptr) { + for (const auto& child : childrenContainer_->getChildSubtreeViews()) { + child->setLabelAreaWidth(labelWidth); + } + } } } -int PropertySubtreeView::getLabelAreaWidthHint() const { - int labelWidthHint = label_->fontMetrics().boundingRect(label_->text()).width(); - if (childrenContainer_ != nullptr && childrenContainer_->size().height() > 0) { - for (const auto& child : childrenContainer_->findChildren(QString{}, Qt::FindDirectChildrenOnly)) { - const auto childLabelWidthHint = child->getLabelAreaWidthHint(); - if (labelWidthHint < childLabelWidthHint) { - labelWidthHint = childLabelWidthHint; +bool PropertySubtreeView::updateLabelAreaWidth(bool initialize) { + int newWidth = getLabelAreaWidth(); + if (newWidth != subtreeMaxWidth_) { + subtreeMaxWidth_ = newWidth; + // If the subtree width changed we propagate upwards + if (parentSubtree_) { + bool status = parentSubtree_->updateLabelAreaWidth(false); + if (!status && initialize) { + setLabelAreaWidth(labelAreaWidth_); } + return status; + } else { + setLabelAreaWidth(subtreeMaxWidth_); + return true; + } + } + return false; +} + +int PropertySubtreeView::getLabelAreaWidth() const { + int labelWidthHint = labelMinWidth_; + if (childrenContainer_ != nullptr) { + for (const auto& child : childrenContainer_->getChildSubtreeViews()) { + labelWidthHint = std::max(labelWidthHint, child->subtreeMaxWidth_); } } return labelWidthHint + decorationWidget_->width(); } +void PropertySubtreeView::drawHighlight(float intensity) { + if (intensity > 0) { + QPainter painter{this}; + QPen pen = painter.pen(); + pen.setStyle(Qt::PenStyle::NoPen); + painter.setPen(pen); + + QColor highlightColor = qApp->palette().highlight().color(); + highlightColor.setAlphaF(intensity); + QBrush highlightBrush = qApp->palette().highlight(); + highlightBrush.setColor(highlightColor); + + painter.setBrush(highlightBrush); + painter.drawRect(rect()); + } +} + void PropertySubtreeView::paintEvent(QPaintEvent* event) { - drawHighlight(this, highlight_); - recalculateLabelWidth(); + drawHighlight(highlight_); QWidget::paintEvent(event); } -void PropertySubtreeView::playStructureChangeAnimation() { +void PropertySubtreeView::playHighlightAnimation(int duration, float start, float end) { if (!item_->hasCollapsedParent()) { - if (visibleRegion().isEmpty()) { - Q_EMIT model_->addNotVisible(this); - } else { + if (!visibleRegion().isEmpty()) { auto* animation = new QPropertyAnimation(this, "highlight"); - animation->setDuration(250); - animation->setStartValue(0.0); - animation->setEndValue(1.0); + animation->setDuration(duration); + animation->setStartValue(start); + animation->setEndValue(end); QObject::connect(animation, &QPropertyAnimation::destroyed, this, [this]() { highlight_ = 0.0; update(); }); animation->start(QPropertyAnimation::DeleteWhenStopped); } - } else { - Q_EMIT model_->addNotVisible(this); } } diff --git a/gui/libPropertyBrowser/src/WidgetFactory.cpp b/gui/libPropertyBrowser/src/WidgetFactory.cpp index 45ece3a6..ab41fce7 100644 --- a/gui/libPropertyBrowser/src/WidgetFactory.cpp +++ b/gui/libPropertyBrowser/src/WidgetFactory.cpp @@ -9,8 +9,12 @@ */ #include "property_browser/WidgetFactory.h" +#include "DockWidget.h" +#include "property_browser/controls/ImageWidget.h" +#include "property_browser/controls/TexturePreviewWidget.h" #include "property_browser/PropertyBrowserItem.h" +#include "property_browser/editors/ArrayEditor.h" #include "property_browser/editors/BoolEditor.h" #include "property_browser/editors/DoubleEditor.h" #include "property_browser/editors/EnumerationEditor.h" @@ -20,28 +24,39 @@ #include "property_browser/editors/RefEditor.h" #include "property_browser/editors/StringEditor.h" #include "property_browser/editors/TagContainerEditor.h" +#include "property_browser/editors/TexturePreviewEditor.h" #include "property_browser/editors/URIEditor.h" #include "property_browser/editors/VecNTEditor.h" -#include "user_types/RenderLayer.h" +#include "user_types/UserTypeAnnotations.h" #include +#include #include namespace raco::property_browser { -QLabel* WidgetFactory::createPropertyLabel(PropertyBrowserItem* item, QWidget* parent) { +QWidget* WidgetFactory::createPropertyLabel(PropertyBrowserItem* item, QWidget* parent) { + if (item->query()) { + return new TexturePreviewWidget{item, parent}; + } QLabel* label = new QLabel{item->displayName().c_str(), parent}; label->setForegroundRole(QPalette::BrightText); + label->setEnabled(item->editable()); + QObject::connect(item, &PropertyBrowserItem::editableChanged, label, &QWidget::setEnabled); return label; } -PropertyEditor* WidgetFactory::createPropertyEditor(PropertyBrowserItem* item, QWidget* parent) { +PropertyEditor* WidgetFactory::createPropertyEditor(PropertyBrowserItem* item, QWidget* label, QWidget* parent) { using PrimitiveType = core::PrimitiveType; switch (item->type()) { case PrimitiveType::Bool: - return new BoolEditor{item, parent}; + if (item->query()) { + return new TexturePreviewEditor{item, label, parent}; + } else { + return new BoolEditor{item, parent}; + } case PrimitiveType::Int: if (item->query()) { return new EnumerationEditor{item, parent}; @@ -79,14 +94,37 @@ PropertyEditor* WidgetFactory::createPropertyEditor(PropertyBrowserItem* item, Q return new TagContainerEditor{ item, parent }; } return new PropertyEditor{ item, parent }; + case PrimitiveType::Array: + if (item->query()) { + return new ArrayEditor{item, parent}; + } + return new PropertyEditor{item, parent}; default: // used for group headlines return new PropertyEditor{item, parent}; }; } -LinkEditor* WidgetFactory::createLinkControl(PropertyBrowserItem* item, QWidget* parent) { - return new LinkEditor(item, parent); +LinkEditor* WidgetFactory::createLinkControl(PropertyBrowserItem* item, QWidget* parent, QWidget* propertyEditor) { + const auto linkEditor{new LinkEditor(item, parent)}; + linkEditor->setControl(propertyEditor); + return linkEditor; +} + +PropertyEditor* WidgetFactory::createPropertyControl(PropertyBrowserItem* item, QWidget* label, QWidget* parent) { + auto propertyEditor = createPropertyEditor(item, label, parent); + propertyEditor->setToolTip(item->propertyControlToolTipText()); + QObject::connect(item, &PropertyBrowserItem::propertyControlToolTipTextChanged, propertyEditor, [propertyEditor](const QString& text) { + propertyEditor->setToolTip(text); + }); + return propertyEditor; +} + +std::tuple WidgetFactory::createPropertyWidgets(PropertyBrowserItem* item, QWidget* parent) { + QWidget* label = createPropertyLabel(item, parent); + PropertyEditor* editor = createPropertyControl(item, label, parent); + + return {label, createLinkControl(item, parent, editor)}; } } // namespace raco::property_browser diff --git a/gui/libPropertyBrowser/src/controls/ColorChannelListWidget.cpp b/gui/libPropertyBrowser/src/controls/ColorChannelListWidget.cpp new file mode 100644 index 00000000..3345f91c --- /dev/null +++ b/gui/libPropertyBrowser/src/controls/ColorChannelListWidget.cpp @@ -0,0 +1,75 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "property_browser/controls/ColorChannelListWidget.h" +#include "property_browser/controls/ColorChannelInfo.h" + +#include +#include + +namespace raco::property_browser { + +ColorChannelListWidget::ColorChannelListWidget(QWidget* parent) : QWidget(parent), layout_(this) { + for (size_t i = 0; i < ColorChannels::channels_.size(); ++i) { + auto checkBox = new QCheckBox(ColorChannels::channels_[i].displayName_.c_str()); + checkBox->setCheckState(Qt::Checked); + + connect(checkBox, &QCheckBox::stateChanged, this, [this]() { + Q_EMIT selectionChanged(); + }); + + layout_.addWidget(checkBox); + checkBoxes_.emplace_back(checkBox, false); + } + + setLayout(&layout_); +} + +QCheckBox* ColorChannelListWidget::checkbox(size_t index) const { + return checkBoxes_[index].first; +} + +bool ColorChannelListWidget::isChannelPresent(size_t index) const { + return checkBoxes_[index].second; +} + +void ColorChannelListWidget::refreshChannelList(const QImage& image) { + for (size_t i = 0; i < checkBoxes_.size(); ++i) { + const auto imageHasChannel = ColorChannels::channels_[i].channelExistsPredicate_(image); + checkbox(i)->setCheckState(Qt::Checked); + checkbox(i)->setVisible(imageHasChannel); + checkBoxes_[i].second = imageHasChannel; + } +} + +std::tuple ColorChannelListWidget::getSelectedOperations() const { + bool isAlphaEnabled{false}, isSomeColorEnabled{false}; + + // Collect enabled channels + std::list> operations; + for (size_t i = 0; i < checkBoxes_.size(); ++i) { + // Take only visible checkboxes state into account + if (checkbox(i)->checkState() == Qt::Checked && isChannelPresent(i)) { + auto title = checkbox(i)->text(); + if (title == "Alpha") { + isAlphaEnabled = true; + } else { + isSomeColorEnabled = true; + } + + // Collect enabled channel operations + operations.emplace_back(ColorChannels::channels_[i].extractFunction_); + } + } + + return {isAlphaEnabled, isSomeColorEnabled, operations}; +} + +} // namespace raco::property_browser \ No newline at end of file diff --git a/gui/libPropertyBrowser/src/controls/ImageWidget.cpp b/gui/libPropertyBrowser/src/controls/ImageWidget.cpp new file mode 100644 index 00000000..b4fdce05 --- /dev/null +++ b/gui/libPropertyBrowser/src/controls/ImageWidget.cpp @@ -0,0 +1,107 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "property_browser/controls/ImageWidget.h" + +#include +#include +#include + +#include + +namespace raco::property_browser { + +ImageWidget::ImageWidget(QWidget* parent) + : QWidget(parent) { +} + +void ImageWidget::setHeightSourceWidget(QWidget* widget) { + heightSourceWidget_ = widget; + heightSourceWidget_->installEventFilter(this); +} + +bool ImageWidget::eventFilter(QObject* obj, QEvent* event) { + if (event->type() == QEvent::Resize) { + updateGeometry(); + } + return QObject::eventFilter(obj, event); +} + +int ImageWidget::getMaximumHeight() const { + return heightSourceWidget_ ? static_cast(heightSourceWidget_->height() * maxHeightShare_) : std::numeric_limits::max(); +} + +void ImageWidget::setPixmap(const QPixmap& pixmap) { + imagePixmap_ = pixmap; + + // Size might have changed + updateGeometry(); + + // Schedule repaint + update(); +} + +bool ImageWidget::hasHeightForWidth() const { + return true; +} + +int ImageWidget::heightForWidth(int w) const { + if (!imagePixmap_.width()) { + return 0; + } + return std::min(static_cast(std::floor(w * static_cast(imagePixmap_.height()) / imagePixmap_.width())), getMaximumHeight()); +} + +int ImageWidget::widthForHeight(int h) const { + if (!imagePixmap_.height()) { + return 0; + } + return static_cast(std::round(h * static_cast(imagePixmap_.width()) / imagePixmap_.height())); +} + +QPixmap ImageWidget::createCheckerTilePixmap() const { + const int checkerTileSize = static_cast(checkerTileSizeFactor_ * QApplication::fontMetrics().height()); + + QPixmap tilePixmap{checkerTileSize, checkerTileSize}; + QPainter painter{&tilePixmap}; + painter.fillRect(0, 0, checkerTileSize, checkerTileSize, checkerLightBrush_); + const auto squareSize = checkerTileSize / 2; + painter.fillRect(0, 0, squareSize, squareSize, checkerDarkBrush_); + painter.fillRect(squareSize, squareSize, squareSize, squareSize, checkerDarkBrush_); + painter.end(); + return tilePixmap; +} + +void ImageWidget::setCheckerEnabled(bool enabled) { + isCheckerEnabled_ = enabled; + update(); +} + +void ImageWidget::paintEvent(QPaintEvent* paintEvent) { + QPainter painter{this}; + + if (imagePixmap_.isNull() || !imagePixmap_.width() || !imagePixmap_.height()) { + return; + } + + const auto verticalScale = static_cast(height()) / imagePixmap_.height(); + const auto sx{static_cast(imagePixmap_.width() * verticalScale)}; + const QRect fillRect{(width() - sx) / 2, 0, sx, static_cast(imagePixmap_.height() * verticalScale)}; + + if (isCheckerEnabled_) { + painter.drawTiledPixmap(fillRect, createCheckerTilePixmap()); + } else { + painter.fillRect(fillRect, Qt::black); + } + + painter.drawPixmap(fillRect, imagePixmap_, imagePixmap_.rect()); +} + +} // namespace raco::property_browser \ No newline at end of file diff --git a/gui/libPropertyBrowser/src/controls/SpinBox.cpp b/gui/libPropertyBrowser/src/controls/SpinBox.cpp index 885a4189..e1738285 100644 --- a/gui/libPropertyBrowser/src/controls/SpinBox.cpp +++ b/gui/libPropertyBrowser/src/controls/SpinBox.cpp @@ -281,17 +281,17 @@ std::optional evaluateLuaExpression(QString expression, T min, T max) { if (!luaL_dostring(l, ("return " + expression.toStdString()).c_str())) { auto result = lua_tonumber(l, -1); if (result < min) { - LOG_INFO(raco::log_system::PROPERTY_BROWSER, "Lua result {} is under numerical limit {} and will be clamped.", result, min); + LOG_INFO(log_system::PROPERTY_BROWSER, "Lua result {} is under numerical limit {} and will be clamped.", result, min); result = min; } else if (result > max) { - LOG_INFO(raco::log_system::PROPERTY_BROWSER, "Lua result {} is over numerical limit {} and will be clamped.", result, max); + LOG_INFO(log_system::PROPERTY_BROWSER, "Lua result {} is over numerical limit {} and will be clamped.", result, max); result = max; } lua_close(l); return (T)result; } else { - LOG_INFO(raco::log_system::PROPERTY_BROWSER, "Could not evaluate Lua Expression: {}", lua_tostring(l, -1)); + LOG_INFO(log_system::PROPERTY_BROWSER, "Could not evaluate Lua Expression: {}", lua_tostring(l, -1)); lua_close(l); return {}; } diff --git a/gui/libPropertyBrowser/src/controls/TexturePreviewWidget.cpp b/gui/libPropertyBrowser/src/controls/TexturePreviewWidget.cpp new file mode 100644 index 00000000..1a3575a7 --- /dev/null +++ b/gui/libPropertyBrowser/src/controls/TexturePreviewWidget.cpp @@ -0,0 +1,163 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + + +#include "property_browser/controls/TexturePreviewWidget.h" +#include "property_browser/controls/ColorChannelListWidget.h" +#include "property_browser/controls/ImageWidget.h" +#include "common_widgets/NoContentMarginsLayout.h" + +#include "core/Errors.h" +#include "user_types/Texture.h" + +#include +#include +#include +#include +#include + +namespace raco::property_browser { + +TexturePreviewWidget::TexturePreviewWidget(PropertyBrowserItem* item, QWidget* parent) : QWidget(parent), item_(item) { + assert(item->valueHandles().size() == 1); + + const auto verticalLayout = new common_widgets::NoContentMarginsLayout(parent); + + uriCombo_ = new QComboBox(this); + connect(uriCombo_, QOverload::of(&QComboBox::currentIndexChanged), this, &TexturePreviewWidget::levelSelected); + verticalLayout->addWidget(uriCombo_); + + channelList_ = new ColorChannelListWidget(this); + connect(channelList_, &ColorChannelListWidget::selectionChanged, this, [this]() { + refreshPreview(); + }); + verticalLayout->addWidget(channelList_); + + checkerCheck_ = new QCheckBox("Checker Background", this); + checkerCheck_->setCheckState(Qt::CheckState::Checked); + connect(checkerCheck_, &QCheckBox::stateChanged, this, [this]() { + if (imageWidget_) { + imageWidget_->setCheckerEnabled(checkerCheck_->isChecked()); + } + }); + verticalLayout->addWidget(checkerCheck_); + + // Allow widget to stretch down + verticalLayout->addStretch(1); + + setLayout(verticalLayout); + refreshPreview(); + + const auto textureObject{item->valueHandles().begin()->rootObject()}; + previewSubscription_ = item->dispatcher()->registerOnPreviewDirty(textureObject, [this, item, textureObject]() { + setFiles(TexturePreviewWidget::collectValidTextureUris(item->project(), item->commandInterface()->errors(), textureObject)); + }); + mipMapLevelSubscription_ = item->dispatcher()->registerOn({textureObject, &user_types::Texture::mipmapLevel_}, [this, item, textureObject]() { + setFiles(TexturePreviewWidget::collectValidTextureUris(item->project(), item->commandInterface()->errors(), textureObject)); + }); +} + +void TexturePreviewWidget::levelSelected(int) { + const auto file = uriCombo_->currentData().toString(); + currentImage_.load(file); + channelList_->refreshChannelList(currentImage_); + refreshPreview(); +} + +QImage TexturePreviewWidget::getProcessedImage() const { + auto processedImage = QImage(currentImage_.size(), QImage::Format_ARGB32); + auto [isAlphaEnabled, isSomeColorEnabled, operations] = channelList_->getSelectedOperations(); + + // Apply operations + for (int y = 0; y < currentImage_.size().height(); ++y) { + for (int x = 0; x < currentImage_.size().width(); ++x) { + QRgb pixel = 0; + for (const auto& op: operations) { + pixel += op(currentImage_.pixel(x, y)); + } + if (!isAlphaEnabled && isSomeColorEnabled) { + // Set opaque alpha to make color components visible + pixel = qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel), 255); + } else if (!isSomeColorEnabled && isAlphaEnabled) { + // Make Alpha visible by setting color to white + pixel = qRgba(255, 255, 255, qAlpha(pixel)); + } + processedImage.setPixel(x, y, pixel); + } + } + + return processedImage; +} + +void TexturePreviewWidget::refreshPreview() const { + if (imageWidget_) { + imageWidget_->setPixmap(QPixmap::fromImage(getProcessedImage())); + } +} + +void TexturePreviewWidget::setFiles(std::vector> files) { + { + const QSignalBlocker blocker{uriCombo_}; + const auto oldText = uriCombo_->currentText(); + uriCombo_->clear(); + for (auto [caption, path] : files) { + uriCombo_->addItem(caption, {path}); + } + const auto index = uriCombo_->findText(oldText); + if (index != -1) { + uriCombo_->setCurrentIndex(index); + } + } + + // Load uri selected in combo + const auto currentIndex{uriCombo_->currentIndex()}; + if (!files.empty() && currentIndex >= 0 && currentIndex < static_cast(files.size())) { + currentImage_.load(files[currentIndex].second); + } else { + currentImage_ = QImage{}; + } + + channelList_->refreshChannelList(currentImage_); + refreshPreview(); +} + +void TexturePreviewWidget::setImageWidget(ImageWidget* widget) { + imageWidget_ = widget; + + const auto textureObject{item_->valueHandles().begin()->rootObject()}; + setFiles(TexturePreviewWidget::collectValidTextureUris(item_->project(), item_->commandInterface()->errors(), textureObject)); +} + +std::vector> TexturePreviewWidget::collectValidTextureUris(const core::Project* project, const core::Errors& errors, const core::SEditorObject& texture) { + std::vector> uris; + const auto mipmapLevelCount = core::ValueHandle{texture, &user_types::Texture::mipmapLevel_}.asInt(); + int currentLevel = 0; + + // Collect only valid URIs + static std::list uriProperties{"uri", "level2uri", "level3uri", "level4uri"}; + for (const auto& property : uriProperties) { + if (currentLevel++ == mipmapLevelCount) { + break; + } + const auto uriHandle = core::ValueHandle{texture, {property}}; + const auto absPath = core::PathQueries::resolveUriPropertyToAbsolutePath(*project, uriHandle); + if (!absPath.empty() && (!errors.hasError(uriHandle) || errors.getError(uriHandle).level() < core::ErrorLevel::ERROR)) { + std::string displayName = property; + if (auto displayNameAnnotation = uriHandle.query()) { + displayName = displayNameAnnotation->name_.asString(); + } + uris.emplace_back(QString::fromStdString(displayName), QString::fromStdString(absPath)); + } + } + + return uris; +} + +} // namespace raco::common_widgets diff --git a/gui/libPropertyBrowser/src/editors/ArrayEditor.cpp b/gui/libPropertyBrowser/src/editors/ArrayEditor.cpp new file mode 100644 index 00000000..3ce51c52 --- /dev/null +++ b/gui/libPropertyBrowser/src/editors/ArrayEditor.cpp @@ -0,0 +1,59 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "property_browser/editors/ArrayEditor.h" +#include "property_browser/PropertyBrowserLayouts.h" + +#include "common_widgets/PropertyBrowserButton.h" + +#include "style/Icons.h" + +#include + +namespace raco::property_browser { + +ArrayEditor::ArrayEditor(PropertyBrowserItem* item, QWidget* parent) + : PropertyEditor(item, parent) { + auto layout{new PropertyBrowserHBoxLayout{this}}; + layout->addStretch(1); + this->setLayout(layout); + + descriptionLabel_ = new QLabel("Array Size:", this); + layout->addWidget(descriptionLabel_); + + shrinkButton_ = new common_widgets::PropertyBrowserButton(style::Icons::instance().decrement, {}, this); + layout->addWidget(shrinkButton_); + + sizeLabel_ = new QLabel(this); + layout->addWidget(sizeLabel_); + + growButton_ = new common_widgets::PropertyBrowserButton(style::Icons::instance().increment, {}, this); + layout->addWidget(growButton_); + + QObject::connect(shrinkButton_, &QPushButton::clicked, [this]() { + if (item_->size() > 1) { + item_->resizeArray(item_->size() - 1); + } + }); + + QObject::connect(growButton_, &QPushButton::clicked, [this]() { + item_->resizeArray(item_->size() + 1); + }); + + QObject::connect(item_, &PropertyBrowserItem::childrenChanged, this, &ArrayEditor::updateLabel); + + updateLabel(); +} + +void ArrayEditor::updateLabel() { + sizeLabel_->setText(fmt::format("{}", item_->size()).c_str()); +} + +} // namespace raco::property_browser \ No newline at end of file diff --git a/gui/libPropertyBrowser/src/editors/DoubleEditor.cpp b/gui/libPropertyBrowser/src/editors/DoubleEditor.cpp index ec393030..544e616f 100644 --- a/gui/libPropertyBrowser/src/editors/DoubleEditor.cpp +++ b/gui/libPropertyBrowser/src/editors/DoubleEditor.cpp @@ -81,6 +81,11 @@ DoubleEditor::DoubleEditor( stack_->setCurrentWidget(slider_); layout->addWidget(stack_); + + // eventFilter to capture right click for showing copy dialog. + installEventFilter(this); + canDisplayCopyDialog = true; + setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); } void DoubleEditor::setValueToControls(DoubleSlider* slider, DoubleSpinBox* spinBox) const { diff --git a/gui/libPropertyBrowser/src/editors/Int64Editor.cpp b/gui/libPropertyBrowser/src/editors/Int64Editor.cpp index 2abbf2a9..74ff1c97 100644 --- a/gui/libPropertyBrowser/src/editors/Int64Editor.cpp +++ b/gui/libPropertyBrowser/src/editors/Int64Editor.cpp @@ -78,6 +78,11 @@ Int64Editor::Int64Editor( stack_->setCurrentWidget(slider); layout->addWidget(stack_); + + // eventFilter to capture right click for showing copy dialog. + installEventFilter(this); + canDisplayCopyDialog = true; + setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); } void Int64Editor::setValueToControls(Int64Slider* slider, Int64SpinBox* spinBox) const { diff --git a/gui/libPropertyBrowser/src/editors/IntEditor.cpp b/gui/libPropertyBrowser/src/editors/IntEditor.cpp index 9b57aed9..03efc5d4 100644 --- a/gui/libPropertyBrowser/src/editors/IntEditor.cpp +++ b/gui/libPropertyBrowser/src/editors/IntEditor.cpp @@ -81,6 +81,11 @@ IntEditor::IntEditor( stack_->setCurrentWidget(slider_); layout->addWidget(stack_); + + // eventFilter to capture right click for showing copy dialog. + installEventFilter(this); + canDisplayCopyDialog = true; + setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); } void IntEditor::setValueToControls(IntSlider* slider, IntSpinBox* spinBox) const { diff --git a/gui/libPropertyBrowser/src/editors/LinkEditor.cpp b/gui/libPropertyBrowser/src/editors/LinkEditor.cpp index 61889f36..9927e493 100644 --- a/gui/libPropertyBrowser/src/editors/LinkEditor.cpp +++ b/gui/libPropertyBrowser/src/editors/LinkEditor.cpp @@ -160,14 +160,15 @@ void LinkEditor::setLinkState() { if (endingLink) { auto linkStartObj = *endingLink->startObject_; auto linkStartPropName = endingLink->descriptor().start.getFullPropertyPath(); + auto linkStartPropertyPath = QString::fromStdString(endingLink->descriptor().start.getPropertyPath(false)); if (startingLinks.empty()) { goToLinkButton_->setDisabled(false); goToLinkButtonIcon_ = *endingLink->isWeak_ ? LinkIcon::singleArrowLeft : LinkIcon::doubleArrowLeft; goToLinkButton_->setToolTip(QString("Go to link start (%1)").arg(QString::fromStdString(linkStartPropName))); - QObject::connect(goToLinkButton_, &QPushButton::clicked, [this, linkStartObj]() { - item_->model()->Q_EMIT objectSelectionRequested(QString::fromStdString(linkStartObj->objectID())); + QObject::connect(goToLinkButton_, &QPushButton::clicked, [this, linkStartObj, linkStartPropertyPath]() { + item_->model()->Q_EMIT selectionRequested(QString::fromStdString(linkStartObj->objectID()), linkStartPropertyPath); }); } else { @@ -175,21 +176,23 @@ void LinkEditor::setLinkState() { goToLinkButtonIcon_ = LinkIcon::goToLeftRight; goToLinkButton_->setToolTip("Go to..."); - goToLinkButtonConnection_ = QObject::connect(goToLinkButton_, &QPushButton::clicked, [this, linkStartObj, linkStartPropName, startingLinks]() { + goToLinkButtonConnection_ = QObject::connect(goToLinkButton_, &QPushButton::clicked, [this, linkStartObj, linkStartPropName, linkStartPropertyPath, startingLinks]() { auto* linkMenu = new QMenu(this); QString requestedLinkEndObj; + QString requestedLinkEndObjProperty; - auto startAction = linkMenu->addAction(QString("Link start (%1)").arg(QString::fromStdString(linkStartPropName)), [this, linkStartObj, &requestedLinkEndObj]() { + linkMenu->addAction(QString("Link start (%1)").arg(QString::fromStdString(linkStartPropName)), [this, linkStartObj, linkStartPropertyPath, &requestedLinkEndObj, &requestedLinkEndObjProperty]() { requestedLinkEndObj = QString::fromStdString(linkStartObj->objectID()); + requestedLinkEndObjProperty = linkStartPropertyPath; }); auto endsMenu = linkMenu->addMenu("Link ends..."); - addLinkEndpointMenuItems(startingLinks, endsMenu, requestedLinkEndObj); + addLinkEndpointMenuItems(startingLinks, endsMenu, requestedLinkEndObj, requestedLinkEndObjProperty); linkMenu->exec(mapToGlobal(goToLinkButton_->pos() + QPoint(goToLinkButton_->width(), 0))); if (!requestedLinkEndObj.isEmpty()) { - item_->model()->Q_EMIT objectSelectionRequested(requestedLinkEndObj); + item_->model()->Q_EMIT selectionRequested(requestedLinkEndObj, requestedLinkEndObjProperty); } }); } @@ -201,12 +204,13 @@ void LinkEditor::setLinkState() { goToLinkButtonConnection_ = QObject::connect(goToLinkButton_, &QPushButton::clicked, [this, startingLinks]() { auto* linkEndMenu = new QMenu(this); QString requestedLinkEndObj; + QString requestedLinkEndObjProperty; - addLinkEndpointMenuItems(startingLinks, linkEndMenu, requestedLinkEndObj); + addLinkEndpointMenuItems(startingLinks, linkEndMenu, requestedLinkEndObj, requestedLinkEndObjProperty); linkEndMenu->exec(mapToGlobal(goToLinkButton_->pos() + QPoint(goToLinkButton_->width(), 0))); if (!requestedLinkEndObj.isEmpty()) { - item_->model()->Q_EMIT objectSelectionRequested(requestedLinkEndObj); + item_->model()->Q_EMIT selectionRequested(requestedLinkEndObj, requestedLinkEndObjProperty); } }); } @@ -215,25 +219,27 @@ void LinkEditor::setLinkState() { goToLinkButton_->setIcon(LinkStateIcons_[goToLinkButtonIcon_]); } -void LinkEditor::addLinkEndpointMenuItems(const std::vector& startingLinks, QMenu* endsMenu, QString& requestedLinkEndObj) { +void LinkEditor::addLinkEndpointMenuItems(const std::vector& startingLinks, QMenu* endsMenu, QString& requestedLinkEndObj, QString& requestedLinkEndObjProperty) { auto sortedLinkEnds = generateSortedLinkPoints(startingLinks); for (const auto& linkEnd : sortedLinkEnds) { auto linkEndPath = linkEnd.first; - auto linkEndObjID = linkEnd.second; + auto linkEndObjID = linkEnd.second.first; + auto linkEndObjProperty = linkEnd.second.second; endsMenu->addAction(QString::fromStdString(linkEndPath), - [this, linkEndObjID, &requestedLinkEndObj]() { + [this, linkEndObjID, linkEndObjProperty, &requestedLinkEndObj, &requestedLinkEndObjProperty]() { requestedLinkEndObj = QString::fromStdString(linkEndObjID); + requestedLinkEndObjProperty = QString::fromStdString(linkEndObjProperty); }); } } -std::map LinkEditor::generateSortedLinkPoints(const std::vector links) { - std::map sortedLinkEnds; +std::map> LinkEditor::generateSortedLinkPoints(const std::vector links) { + std::map> sortedLinkEnds; for (const auto& link : links) { auto linkDesc = link->descriptor(); auto actionText = fmt::format("{} -> {}", (*link->startObject_)->objectName(), linkDesc.end.getFullPropertyPath()); - sortedLinkEnds[actionText] = linkDesc.end.object()->objectID(); + sortedLinkEnds[actionText] = {linkDesc.end.object()->objectID(), linkDesc.end.getPropertyPath(false)}; } return sortedLinkEnds; diff --git a/gui/libPropertyBrowser/src/editors/PropertyEditor.cpp b/gui/libPropertyBrowser/src/editors/PropertyEditor.cpp index 2e5355c4..8cd6cd46 100644 --- a/gui/libPropertyBrowser/src/editors/PropertyEditor.cpp +++ b/gui/libPropertyBrowser/src/editors/PropertyEditor.cpp @@ -8,355 +8,44 @@ * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "property_browser/editors/PropertyEditor.h" -#include "common_widgets/RaCoClipboard.h" -#include "core/EngineInterface.h" -#include "core/Serialization.h" #include "property_browser/PropertyBrowserItem.h" +#include "property_browser/PropertyCopyPaste.h" +#include +#include namespace raco::property_browser { -PropertyEditor::PropertyEditor( - PropertyBrowserItem* item, - QWidget* parent) - : QWidget{parent}, item_{item} { +PropertyEditor::PropertyEditor(PropertyBrowserItem* item, QWidget* parent) + : QWidget{parent}, + item_{item} { setEnabled(item->editable()); QObject::connect(item, &PropertyBrowserItem::editableChanged, this, &QWidget::setEnabled); -} - -bool PropertyEditor::canCopyValue() { - return item_->hasSingleValue(); -} - -void PropertyEditor::copyValue() { - if (item_->hasSingleValue()) { - RaCoClipboard::set(serialization::serializeProperty(*item_->project(), *item_->valueHandles().begin()->constValueRef()), MimeTypes::PROPERTY); - } -} - -void PropertyEditor::pasteInt(PropertyBrowserItem* item, core::ValueBase* value) { - std::optional newValue; - switch (value->type()) { - case data_storage::PrimitiveType::Int: { - newValue = value->asInt(); - break; - } - case data_storage::PrimitiveType::Int64: - newValue = static_cast(value->asInt64()); - break; - case data_storage::PrimitiveType::String: - try { - newValue = std::stoi(value->asString()); - } catch (std::invalid_argument&) { - break; - } catch (std::out_of_range&) { - break; - } - break; - case data_storage::PrimitiveType::Double: - newValue = static_cast(value->asDouble()); - break; - case data_storage::PrimitiveType::Bool: - case data_storage::PrimitiveType::Ref: - case data_storage::PrimitiveType::Table: - case data_storage::PrimitiveType::Struct: - break; - } - - if (newValue.has_value()) { - // Target property may be an enum so we have to check: - if (std::all_of(item->valueHandles().begin(), item->valueHandles().end(), [&item, &newValue](const core::ValueHandle& handle) { - return item->commandInterface()->canSet(handle, newValue.value()); - })) { - item->set(newValue.value()); - } - } -} - -void PropertyEditor::pasteBool(PropertyBrowserItem* item, core::ValueBase* value) { - switch (value->type()) { - case data_storage::PrimitiveType::Bool: - item->set(value->asBool()); - break; - case data_storage::PrimitiveType::String: - if (value->asString() == "true") { - item->set(true); - } else if (value->asString() == "false") { - item->set(false); - } - case data_storage::PrimitiveType::Int: - case data_storage::PrimitiveType::Int64: - case data_storage::PrimitiveType::Double: - case data_storage::PrimitiveType::Ref: - case data_storage::PrimitiveType::Table: - case data_storage::PrimitiveType::Struct: - break; - } -} - -void PropertyEditor::pasteInt64(PropertyBrowserItem* item, core::ValueBase* value) { - switch (value->type()) { - case data_storage::PrimitiveType::Int: - item->set(static_cast(value->asInt())); - break; - case data_storage::PrimitiveType::Int64: - item->set(value->asInt64()); - break; - case data_storage::PrimitiveType::String: - try { - int64_t result = std::stol(value->asString()); - item->set(result); - } catch (std::invalid_argument&) { - break; - } catch (std::out_of_range&) { - break; - } - break; - case data_storage::PrimitiveType::Double: - item->set(static_cast(value->asDouble())); - break; - case data_storage::PrimitiveType::Bool: - case data_storage::PrimitiveType::Ref: - case data_storage::PrimitiveType::Table: - case data_storage::PrimitiveType::Struct: - break; - } -} - -void PropertyEditor::pasteDouble(PropertyBrowserItem* item, core::ValueBase* value) { - switch (value->type()) { - case data_storage::PrimitiveType::Int: - item->set(static_cast(value->asInt())); - break; - case data_storage::PrimitiveType::Int64: - item->set(static_cast(value->asInt64())); - break; - case data_storage::PrimitiveType::String: - try { - double result = std::stod(value->asString()); - item->set(result); - } catch (std::invalid_argument&) { - break; - } catch (std::out_of_range&) { - break; - } - break; - case data_storage::PrimitiveType::Double: - item->set(value->asDouble()); - break; - case data_storage::PrimitiveType::Bool: - case data_storage::PrimitiveType::Ref: - case data_storage::PrimitiveType::Table: - case data_storage::PrimitiveType::Struct: - break; - } -} - -void PropertyEditor::pasteString(PropertyBrowserItem* item, core::ValueBase* value) { - switch (value->type()) { - case data_storage::PrimitiveType::Int: - item->set(std::to_string(value->asInt())); - break; - case data_storage::PrimitiveType::Int64: - item->set(std::to_string(value->asInt64())); - break; - case data_storage::PrimitiveType::String: - item->set(value->asString()); - break; - case data_storage::PrimitiveType::Double: - item->set(std::to_string(value->asDouble())); - break; - case data_storage::PrimitiveType::Bool: - item->set(value->asBool() ? "true" : "false"); - break; - case data_storage::PrimitiveType::Ref: - case data_storage::PrimitiveType::Table: - case data_storage::PrimitiveType::Struct: - break; - } -} - -void PropertyEditor::pasteRef(PropertyBrowserItem* item, core::ValueBase* value) { - if (value->type() == data_storage::PrimitiveType::Ref) { - auto valueRef = value->asRef(); - if (std::all_of(item->valueHandles().begin(), item->valueHandles().end(), [&item, &valueRef](const core::ValueHandle& handle) { - return core::Queries::isValidReferenceTarget(*item->project(), handle, valueRef); - })) { - item->set(valueRef); - } - } -} - -template -void PropertyEditor::pasteVector(PropertyBrowserItem* item, core::ValueBase* value) { - size_t childCount = item->children().length(); - switch (value->type()) { - case data_storage::PrimitiveType::Struct: { - data_storage::ReflectionInterface& substructure = value->getSubstructure(); - auto substructureChildCount = substructure.size(); - for (int i = 0; i < std::min(childCount, substructureChildCount); ++i) { - switch (substructure[i]->type()) { - case data_storage::PrimitiveType::Int: { - item->children().at(i)->set(static_cast(substructure[i]->asInt())); - break; - } - case data_storage::PrimitiveType::Double: { - item->children().at(i)->set(static_cast(substructure[i]->asDouble())); - break; - } - default: - break; - } - } - return; - } - case data_storage::PrimitiveType::Int: - case data_storage::PrimitiveType::Int64: - case data_storage::PrimitiveType::String: - case data_storage::PrimitiveType::Double: - case data_storage::PrimitiveType::Bool: - case data_storage::PrimitiveType::Ref: - case data_storage::PrimitiveType::Table: - return; - } -} -bool PropertyEditor::isVector(PropertyBrowserItem* item) { - return std::all_of(item->valueHandles().begin(), item->valueHandles().end(), [](const core::ValueHandle& handle) { - return handle.isVec2f() || handle.isVec3f() || handle.isVec4f() || handle.isVec2i() || handle.isVec3i() || handle.isVec4i(); - }); + propertyMenu_ = new QMenu(this); + propertyMenu_->addAction("Copy", this, &PropertyEditor::menuCopyAction); } -bool PropertyEditor::isVector(core::ValueBase* value) { - auto* td = &value->asStruct().getTypeDescription(); - return td == &core::Vec2f::typeDescription || - td == &core::Vec3f::typeDescription || - td == &core::Vec4f::typeDescription || - td == &core::Vec2i::typeDescription || - td == &core::Vec3i::typeDescription || - td == &core::Vec4i::typeDescription; -} - -void PropertyEditor::pasteStruct(PropertyBrowserItem* item, core::ValueBase* value) { - if (value->type() != data_storage::PrimitiveType::Struct) { - return; - } - - if (isVector(item) && isVector(value)) { - if (item->children().at(0)->type() == data_storage::PrimitiveType::Int) { - pasteVector(item, value); - } else { - pasteVector(item, value); - } - } else { - for (const auto& child : item->children()) { - auto propName = child->getPropertyName(); - if (value->asStruct().hasProperty(propName)) { - pastePropertyOfSameType(child, value->asStruct()[propName]); - } - } - } -} - -void PropertyEditor::pasteTable(PropertyBrowserItem* item, core::ValueBase* value) { - if (value->type() != data_storage::PrimitiveType::Table) { - return; - } - - if (item->query()) { - if (value->query()) { - auto srcTags = value->asTable().asVector(); - if (std::all_of(item->valueHandles().begin(), item->valueHandles().end(), [&item, &srcTags](const core::ValueHandle& handle) { - return item->commandInterface()->canSetTags(handle, srcTags); - })) { - item->setTags(srcTags); - } - } - return; - } - - if (value->query()) { - return; - } - - if (item->query()) { - if (value->query()) { - std::vector> renderableTags; - const auto& table = value->asTable(); - for (size_t index = 0; index < table.size(); index++) { - renderableTags.emplace_back(std::make_pair(table.name(index), table.get(index)->asInt())); - } - if (std::all_of(item->valueHandles().begin(), item->valueHandles().end(), [&item, &renderableTags](const core::ValueHandle& handle) { - return item->commandInterface()->canSetRenderableTags(handle, renderableTags); - })) { - item->setTags(renderableTags); +bool PropertyEditor::eventFilter(QObject* watched, QEvent* event) { + if (canDisplayCopyDialog && event->type() == QEvent::MouseButtonRelease) { + const auto* mouseEvent = dynamic_cast(event); + if (mouseEvent != nullptr && mouseEvent->button() == Qt::RightButton) { + const auto* widget = dynamic_cast(watched); + if (widget != nullptr && !widget->isEnabled()) { + displayCopyContextMenu(); + return true; } } - return; - } - - if (value->query()) { - return; - } - - auto& substructure = value->getSubstructure(); - for (const auto& child : item->children()) { - auto propName = child->getPropertyName(); - if (substructure.hasProperty(propName)) { - pastePropertyOfSameType(child, substructure[propName]); - } - } -} - -void PropertyEditor::pastePropertyOfSameType(PropertyBrowserItem* item, data_storage::ValueBase* value) { - if (value->type() == item->type()) { - pasteProperty(item, value); } + return QWidget::eventFilter(watched, event); } -void PropertyEditor::pasteProperty(PropertyBrowserItem* item, data_storage::ValueBase* value) { - switch (item->type()) { - case data_storage::PrimitiveType::Bool: - pasteBool(item, value); - break; - case data_storage::PrimitiveType::Int: - pasteInt(item, value); - break; - case data_storage::PrimitiveType::Int64: - pasteInt64(item, value); - break; - case data_storage::PrimitiveType::Double: - pasteDouble(item, value); - break; - case data_storage::PrimitiveType::String: - pasteString(item, value); - break; - case data_storage::PrimitiveType::Ref: - pasteRef(item, value); - break; - case data_storage::PrimitiveType::Table: - pasteTable(item, value); - break; - case data_storage::PrimitiveType::Struct: - pasteStruct(item, value); - break; - } +void PropertyEditor::displayCopyContextMenu() { + propertyMenu_->exec(QCursor::pos()); } -bool PropertyEditor::canPasteValue() { - auto json = RaCoClipboard::get(MimeTypes::PROPERTY); - return serialization::deserializeProperty(*item_->project(), json) != nullptr; +void PropertyEditor::menuCopyAction() { + PropertyCopyPaste::copyValuePlainText(item_); } -void PropertyEditor::pasteValue() { - auto json = RaCoClipboard::get(MimeTypes::PROPERTY); - if (auto value = serialization::deserializeProperty(*item_->project(), json)) { - std::string desc = fmt::format("Paste value into property '{}'", item_->getPropertyPath()); - item_->commandInterface()->executeCompositeCommand( - [this, &value]() { - pasteProperty(item_, value.get()); - }, - desc); - } -} } // namespace raco::property_browser diff --git a/gui/libPropertyBrowser/src/editors/RefEditor.cpp b/gui/libPropertyBrowser/src/editors/RefEditor.cpp index 5c7fd709..fd97b2a7 100644 --- a/gui/libPropertyBrowser/src/editors/RefEditor.cpp +++ b/gui/libPropertyBrowser/src/editors/RefEditor.cpp @@ -140,7 +140,7 @@ RefEditor::RefEditor( QObject::connect(currentRef_, &QLineEdit::customContextMenuRequested, this, &RefEditor::createCustomContextMenu); QObject::connect(goToRefObjectButton_, &QPushButton::clicked, [this, item]() { - item->model()->Q_EMIT objectSelectionRequested(ref_->items().at(ref_->currentIndex()).objId); + item->model()->Q_EMIT selectionRequested(ref_->items().at(ref_->currentIndex()).objId); }); QObject::connect(ref_, &PropertyBrowserRef::indexChanged, [this](auto index) { @@ -176,7 +176,8 @@ void RefEditor::updateRef() { bool RefEditor::unexpectedEmptyReference() const noexcept { return std::any_of(item_->valueHandles().begin(), item_->valueHandles().end(), [this](const core::ValueHandle& handle) { - return handle.asRef() == nullptr && !handle.query(); + return handle.asRef() == nullptr && !(handle.query() || + handle.parent().isProperty() && handle.parent().type() == data_storage::PrimitiveType::Array && handle.parent().query()); }); } diff --git a/gui/libPropertyBrowser/src/editors/StringEditor.cpp b/gui/libPropertyBrowser/src/editors/StringEditor.cpp index c105589d..f52b5a26 100644 --- a/gui/libPropertyBrowser/src/editors/StringEditor.cpp +++ b/gui/libPropertyBrowser/src/editors/StringEditor.cpp @@ -24,7 +24,7 @@ namespace raco::property_browser { StringEditor::StringEditor(PropertyBrowserItem* item, QWidget* parent) : PropertyEditor(item, parent) { - this->setLayout(new raco::common_widgets::NoContentMarginsLayout(this)); + this->setLayout(new common_widgets::NoContentMarginsLayout(this)); lineEdit_ = new StringEditorLineEdit(this); layout()->addWidget(lineEdit_); @@ -78,6 +78,11 @@ StringEditor::StringEditor(PropertyBrowserItem* item, QWidget* parent) QObject::connect(lineEdit_, &QLineEdit::editingFinished, this, [this]() { updatedInBackground_ = false; }); + + // eventFilter to capture right click for showing copy dialog. + installEventFilter(this); + canDisplayCopyDialog = true; + setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); } void StringEditor::updateLineEdit() { @@ -87,10 +92,10 @@ void StringEditor::updateLineEdit() { void StringEditor::updateErrorState() { if (item_->hasError()) { - errorLevel_ = item_->maxErrorLevel(); + lineEdit_->setProperty("errorLevel", static_cast(item_->maxErrorLevel())); lineEdit_->setToolTip(item_->errorMessage().c_str()); } else { - errorLevel_ = core::ErrorLevel::NONE; + lineEdit_->setProperty("errorLevel", static_cast(core::ErrorLevel::NONE)); lineEdit_->setToolTip({}); } } @@ -111,16 +116,20 @@ bool StringEditor::updatedInBackground() const { return updatedInBackground_; } -int StringEditor::errorLevel() const noexcept { - return static_cast(errorLevel_); -} - void StringEditorLineEdit::focusInEvent(QFocusEvent* event) { this->selectAll(); Q_EMIT saveFocusInValues(); QLineEdit::focusInEvent(event); } +int StringEditorLineEdit::errorLevel() const noexcept { + return static_cast(errorLevel_); +} + +void StringEditorLineEdit::setErrorLevel(int level) { + errorLevel_ = static_cast(level); +} + bool StringEditorLineEdit::hasMultipleValues() const { return multiValue_; } diff --git a/gui/libPropertyBrowser/src/editors/TagContainerEditor.cpp b/gui/libPropertyBrowser/src/editors/TagContainerEditor.cpp index 9a95acb5..e0f7bebe 100644 --- a/gui/libPropertyBrowser/src/editors/TagContainerEditor.cpp +++ b/gui/libPropertyBrowser/src/editors/TagContainerEditor.cpp @@ -9,7 +9,6 @@ */ #include "property_browser/editors/TagContainerEditor.h" #include "TagContainerEditor/TagContainerEditor_Popup.h" -#include "core/TagDataCache.h" #include "core/Queries_Tags.h" #include "property_browser/PropertyBrowserItem.h" diff --git a/gui/libPropertyBrowser/src/editors/TagContainerEditor/TagContainerEditor_AppliedTagModel.cpp b/gui/libPropertyBrowser/src/editors/TagContainerEditor/TagContainerEditor_AppliedTagModel.cpp index 1d610f54..2913f3b7 100644 --- a/gui/libPropertyBrowser/src/editors/TagContainerEditor/TagContainerEditor_AppliedTagModel.cpp +++ b/gui/libPropertyBrowser/src/editors/TagContainerEditor/TagContainerEditor_AppliedTagModel.cpp @@ -15,7 +15,7 @@ namespace raco::property_browser { - TagContainerEditor_AppliedTagModel::TagContainerEditor_AppliedTagModel(QWidget* parent, raco::core::TagType tagType) : QStandardItemModel(parent), tagType_(tagType) { + TagContainerEditor_AppliedTagModel::TagContainerEditor_AppliedTagModel(QWidget* parent, core::TagType tagType) : QStandardItemModel(parent), tagType_(tagType) { addTreeItemForAddTag(); QObject::connect(this, &QStandardItemModel::itemChanged, this, &TagContainerEditor_AppliedTagModel::tagChanged); @@ -145,7 +145,7 @@ namespace raco::property_browser { QStandardItem* TagContainerEditor_AppliedTagModel::addTreeItemForAddTag() { auto* treeWidgetItem = new QStandardItem(addItemText_); - if (tagType_ == raco::core::TagType::NodeTags_Referencing) { + if (tagType_ == core::TagType::NodeTags_Referencing) { auto* orderIndexItem = new QStandardItem(); appendRow({treeWidgetItem, orderIndexItem}); } else { @@ -161,7 +161,7 @@ namespace raco::property_browser { void TagContainerEditor_AppliedTagModel::tagChanged(QStandardItem* item) { if (isAddTagItem(item) && item->text() != addItemText_) { - if (tagType_ == raco::core::TagType::NodeTags_Referencing) { + if (tagType_ == core::TagType::NodeTags_Referencing) { setData(index(rowCount() - 1, 1), QVariant::fromValue(orderIndexForLastRow()), Qt::DisplayRole); } addTreeItemForAddTag(); @@ -180,7 +180,7 @@ namespace raco::property_browser { std::vector> TagContainerEditor_AppliedTagModel::renderableTags() const { std::vector> sortedTags; - if (tagType_ == raco::core::TagType::NodeTags_Referencing) { + if (tagType_ == core::TagType::NodeTags_Referencing) { for (int i = 0; i < rowCount(); ++i) { if (isAddTagItem(item(i, 0))) continue; std::string tagName = tagForRow(i).toStdString(); diff --git a/gui/libPropertyBrowser/src/editors/TagContainerEditor/TagContainerEditor_Popup.cpp b/gui/libPropertyBrowser/src/editors/TagContainerEditor/TagContainerEditor_Popup.cpp index a03b77d6..a0c1c3c8 100644 --- a/gui/libPropertyBrowser/src/editors/TagContainerEditor/TagContainerEditor_Popup.cpp +++ b/gui/libPropertyBrowser/src/editors/TagContainerEditor/TagContainerEditor_Popup.cpp @@ -178,7 +178,7 @@ namespace raco::property_browser { availableTagsItemModel_->addTag(tag, listOfRenderLayerNames, forbiddenTags_.find(tag.toStdString()) == forbiddenTags_.end()); } listOfAvailableTags_.setModel(availableTagsItemModel_); - if (tagType_ == raco::core::TagType::UserTags) { + if (tagType_ == core::TagType::UserTags) { listOfAvailableTags_.header()->hideSection(1); } @@ -267,7 +267,7 @@ namespace raco::property_browser { }); break; } - case raco::core::TagType::UserTags: { + case core::TagType::UserTags: { break; } } diff --git a/gui/libPropertyBrowser/src/editors/TexturePreviewEditor.cpp b/gui/libPropertyBrowser/src/editors/TexturePreviewEditor.cpp new file mode 100644 index 00000000..5b59bfc4 --- /dev/null +++ b/gui/libPropertyBrowser/src/editors/TexturePreviewEditor.cpp @@ -0,0 +1,42 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "property_browser/editors/TexturePreviewEditor.h" +#include "property_browser/controls/ImageWidget.h" +#include "property_browser/controls/TexturePreviewWidget.h" +#include "property_browser/Utilities.h" + +#include "common_widgets/NoContentMarginsLayout.h" + +#include "DockWidget.h" + +#include + +namespace raco::property_browser { + +TexturePreviewEditor::TexturePreviewEditor(PropertyBrowserItem* item, QWidget* label, QWidget* parent) : PropertyEditor(item, parent) { + const auto verticalLayout = new common_widgets::NoContentMarginsLayout(parent); + imageWidget_ = new ImageWidget(this); + verticalLayout->addWidget(imageWidget_); + verticalLayout->addStretch(1); + setLayout(verticalLayout); + + getImageWidget()->setHeightSourceWidget(findAncestor(parent)); + + auto pseudoLabel = qobject_cast(label); + assert(pseudoLabel != nullptr); + pseudoLabel->setImageWidget(getImageWidget()); +} + +ImageWidget* TexturePreviewEditor::getImageWidget() const { + return imageWidget_; +} + +} // namespace raco::property_browser diff --git a/gui/libPropertyBrowser/src/editors/URIEditor.cpp b/gui/libPropertyBrowser/src/editors/URIEditor.cpp index b13fae4b..936cd18f 100644 --- a/gui/libPropertyBrowser/src/editors/URIEditor.cpp +++ b/gui/libPropertyBrowser/src/editors/URIEditor.cpp @@ -98,6 +98,9 @@ URIEditor::URIEditor(PropertyBrowserItem* item, QWidget* parent) : StringEditor( loadFileButton->setEnabled(item_->editable()); lineEdit_->setEnabled(item_->editable()); }); + + removeEventFilter(this); + lineEdit_->installEventFilter(this); } void URIEditor::showCustomLineEditContextMenu(const QPoint& p, PropertyBrowserItem* item) { diff --git a/gui/libPropertyBrowser/src/editors/VecNTEditor.cpp b/gui/libPropertyBrowser/src/editors/VecNTEditor.cpp index da10f30c..36e91d81 100644 --- a/gui/libPropertyBrowser/src/editors/VecNTEditor.cpp +++ b/gui/libPropertyBrowser/src/editors/VecNTEditor.cpp @@ -9,8 +9,9 @@ */ #include "property_browser/editors/VecNTEditor.h" - +#include "property_browser/PropertyCopyPaste.h" #include +#include namespace raco::property_browser { @@ -107,10 +108,15 @@ VecNTEditor::VecNTEditor( QWidget* parent) : PropertyEditor(item, parent) { static_assert(std::is_floating_point::value || std::is_integral::value, "VecNTEditor requires floating point or integral type"); + + // removing actions added in the parent constructor. + for (const auto& action : propertyMenu_->actions()) { + propertyMenu_->removeAction(action); + } auto* layout = new PropertyBrowserGridLayout{this}; for (int i = 0; i < N; i++) { spinboxes_[i].reset(new SpinBoxType{this}); - if (auto rangeAnnotation = item->children().at(i)->query>()) { + if (auto rangeAnnotation = item->children().at(i)->query>()) { spinboxes_[i]->setSoftRange(*rangeAnnotation->min_, *rangeAnnotation->max_); } QObject::connect(spinboxes_[i].get(), &SpinBoxType::valueEdited, this, [this, item, i](T value) { @@ -127,6 +133,12 @@ VecNTEditor::VecNTEditor( } layout->addWidget(spinboxes_[i].get(), 0, i); + + // eventFilter to capture right click for showing copy dialog. + spinboxes_[i].get()->installEventFilter(this); + propertyMenu_->addAction("Copy", this, [this, i] { + PropertyCopyPaste::copyChildValuePlainText(item_, i); + }); } QObject::connect(item, &PropertyBrowserItem::childrenChanged, this, &VecNTEditor::updateSpinBoxesAndColorPicker); QObject::connect(item, &PropertyBrowserItem::childrenChanged, this, [this](const QList& children) { @@ -141,6 +153,37 @@ VecNTEditor::VecNTEditor( QObject::connect(item, &PropertyBrowserItem::expandedChanged, this, &VecNTEditor::setExpandedMode); setExpandedMode(item->expanded()); + + canDisplayCopyDialog = true; + setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); +} + +template +bool VecNTEditor::eventFilter(QObject* watched, QEvent* event) { + if (canDisplayCopyDialog && event->type() == QEvent::MouseButtonRelease) { + const auto* mouseEvent = dynamic_cast(event); + if (mouseEvent != nullptr && mouseEvent->button() == Qt::RightButton) { + const auto* widget = dynamic_cast(watched); + if (widget != nullptr && !widget->isEnabled()) { + for (auto i = 0; i < spinboxes_.size(); ++i) { + if (widget == spinboxes_[i].get()) { + displayCopyContextMenu(i); + return true; + } + } + } + } + } + return PropertyEditor::eventFilter(watched, event); +} + +template +void VecNTEditor::displayCopyContextMenu(size_t spinboxIndex) { + auto actions = propertyMenu_->actions(); + for (auto i = 0; i < actions.size(); ++i) { + actions[i]->setVisible(i == spinboxIndex); + } + propertyMenu_->exec(QCursor::pos()); } template diff --git a/gui/libPropertyBrowser/tests/ArrayEditor_test.cpp b/gui/libPropertyBrowser/tests/ArrayEditor_test.cpp new file mode 100644 index 00000000..17f7d70a --- /dev/null +++ b/gui/libPropertyBrowser/tests/ArrayEditor_test.cpp @@ -0,0 +1,116 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#include "property_browser/editors/ArrayEditor.h" +#include "EditorTestFixture.h" + +#include "application/RaCoProject.h" +#include "property_browser/PropertyBrowserItem.h" + +#include + +using namespace raco::core; +using namespace raco::user_types; + +namespace raco::property_browser { + +class ExposedArrayEditor : public ArrayEditor { +public: + ExposedArrayEditor(PropertyBrowserItem* item) : ArrayEditor(item) {} + + QString sizeLabel() const { + return sizeLabel_->text(); + } + + void grow() { + Q_EMIT growButton_->clicked(); + } + + void shrink() { + Q_EMIT shrinkButton_->clicked(); + } +}; + +class ArrayEditorTest : public EditorTestFixture { +public: + ArrayEditorTest() : EditorTestFixture(&TestObjectFactory::getInstance()) {} + + using SObjectWithArrays = std::shared_ptr; + + SObjectWithArrays object_1 = this->create("object1"); + SObjectWithArrays object_2 = this->create("object2"); + const ValueHandle arrayHandle_1{object_1, &ObjectWithArrays::array_ref_resizable_}; + const ValueHandle arrayHandle_2{object_2, &ObjectWithArrays::array_ref_resizable_}; + + PropertyBrowserItem propertyBrowserItem{{arrayHandle_1, arrayHandle_2}, this->dataChangeDispatcher, &this->commandInterface, &this->model}; + ExposedArrayEditor editor{&propertyBrowserItem}; + + void grow() { + editor.grow(); + dispatch(); + } + + void shrink() { + editor.shrink(); + dispatch(); + } +}; + +TEST_F(ArrayEditorTest, update_model) { + dispatch(); + + EXPECT_EQ(editor.sizeLabel(), "0"); + + commandInterface.resizeArray(arrayHandle_1, 3); + commandInterface.resizeArray(arrayHandle_2, 3); + dispatch(); + + EXPECT_EQ(editor.sizeLabel(), "3"); +} + +TEST_F(ArrayEditorTest, editor_activate_grow) { + dispatch(); + + EXPECT_EQ(object_1->array_ref_resizable_->size(), 0); + EXPECT_EQ(object_2->array_ref_resizable_->size(), 0); + EXPECT_EQ(editor.sizeLabel(), "0"); + + editor.grow(); + dispatch(); + + EXPECT_EQ(object_1->array_ref_resizable_->size(), 1); + EXPECT_EQ(object_2->array_ref_resizable_->size(), 1); + EXPECT_EQ(editor.sizeLabel(), "1"); +} + +TEST_F(ArrayEditorTest, editor_activate_shrink) { + commandInterface.resizeArray(arrayHandle_1, 2); + commandInterface.resizeArray(arrayHandle_2, 2); + dispatch(); + + EXPECT_EQ(object_1->array_ref_resizable_->size(), 2); + EXPECT_EQ(object_2->array_ref_resizable_->size(), 2); + EXPECT_EQ(editor.sizeLabel(), "2"); + + editor.shrink(); + dispatch(); + + EXPECT_EQ(object_1->array_ref_resizable_->size(), 1); + EXPECT_EQ(object_2->array_ref_resizable_->size(), 1); + EXPECT_EQ(editor.sizeLabel(), "1"); + + editor.shrink(); + dispatch(); + + EXPECT_EQ(object_1->array_ref_resizable_->size(), 1); + EXPECT_EQ(object_2->array_ref_resizable_->size(), 1); + EXPECT_EQ(editor.sizeLabel(), "1"); +} + +} // namespace raco::property_browser diff --git a/gui/libPropertyBrowser/tests/BoolEditor_test.cpp b/gui/libPropertyBrowser/tests/BoolEditor_test.cpp index 1031538f..5469d424 100644 --- a/gui/libPropertyBrowser/tests/BoolEditor_test.cpp +++ b/gui/libPropertyBrowser/tests/BoolEditor_test.cpp @@ -35,10 +35,6 @@ class ExposedBoolEditor : public BoolEditor { bool isTristate() const { return checkBox_->checkState() == Qt::CheckState::PartiallyChecked && checkBox_->isTristate(); } - - static void pasteProperty(PropertyBrowserItem* item, data_storage::ValueBase* value) { - BoolEditor::pasteProperty(item, value); - } }; class BoolEditorTest : public EditorTestFixture { @@ -122,14 +118,14 @@ TEST_F(BoolEditorTest, paste_property_from_bool) { dispatch(); Value value{true}; - boolEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); EXPECT_EQ(*node_1->visibility_, true); EXPECT_EQ(*node_2->visibility_, true); commandInterface.set(boolHandleNode_2, false); dispatch(); - boolEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); EXPECT_EQ(*node_1->visibility_, true); EXPECT_EQ(*node_2->visibility_, true); } @@ -140,14 +136,14 @@ TEST_F(BoolEditorTest, paste_property_from_string) { dispatch(); Value value{"true"}; - boolEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); EXPECT_EQ(*node_1->visibility_, true); EXPECT_EQ(*node_2->visibility_, true); commandInterface.set(boolHandleNode_2, false); dispatch(); - boolEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); EXPECT_EQ(*node_1->visibility_, true); EXPECT_EQ(*node_2->visibility_, true); } diff --git a/gui/libPropertyBrowser/tests/CMakeLists.txt b/gui/libPropertyBrowser/tests/CMakeLists.txt index 4680c8cd..74de9257 100644 --- a/gui/libPropertyBrowser/tests/CMakeLists.txt +++ b/gui/libPropertyBrowser/tests/CMakeLists.txt @@ -13,6 +13,7 @@ If a copy of the MPL was not distributed with this file, You can obtain one at h set(TEST_SOURCES PropertyBrowserItem_test.cpp + ArrayEditor_test.cpp BoolEditor_test.cpp DoubleEditor_test.cpp EditorTestFixture.h diff --git a/gui/libPropertyBrowser/tests/DoubleEditor_test.cpp b/gui/libPropertyBrowser/tests/DoubleEditor_test.cpp index ba758d8b..34fc0476 100644 --- a/gui/libPropertyBrowser/tests/DoubleEditor_test.cpp +++ b/gui/libPropertyBrowser/tests/DoubleEditor_test.cpp @@ -42,10 +42,6 @@ class ExposedDoubleEditor : public DoubleEditor { bool sliderHasMultipleValues() const { return slider_->hasMultipleValues(); } - - static void pasteProperty(PropertyBrowserItem* item, data_storage::ValueBase* value) { - DoubleEditor::pasteProperty(item, value); - } }; class DoubleEditorTest : public EditorTestFixture { @@ -132,14 +128,14 @@ TEST_F(DoubleEditorTest, check_multiple_values_text_displayed) { TEST_F(DoubleEditorTest, paste_property_from_double) { Value value{13.2}; - doubleEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); EXPECT_DOUBLE_EQ(*node_1->translation_->x, 13.2); EXPECT_DOUBLE_EQ(*node_2->translation_->x, 13.2); commandInterface.set(doubleHandleNode_2, 5.0); dispatch(); - doubleEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); EXPECT_DOUBLE_EQ(*node_1->translation_->x, 13.2); EXPECT_DOUBLE_EQ(*node_2->translation_->x, 13.2); } @@ -147,14 +143,14 @@ TEST_F(DoubleEditorTest, paste_property_from_double) { TEST_F(DoubleEditorTest, paste_property_from_int) { Value value{13}; - doubleEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); EXPECT_DOUBLE_EQ(*node_1->translation_->x, 13.0); EXPECT_DOUBLE_EQ(*node_2->translation_->x, 13.0); commandInterface.set(doubleHandleNode_2, 5.0); dispatch(); - doubleEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); EXPECT_DOUBLE_EQ(*node_1->translation_->x, 13.0); EXPECT_DOUBLE_EQ(*node_2->translation_->x, 13.0); } @@ -162,14 +158,14 @@ TEST_F(DoubleEditorTest, paste_property_from_int) { TEST_F(DoubleEditorTest, paste_property_from_string) { Value value{"13.2"}; - doubleEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); EXPECT_DOUBLE_EQ(*node_1->translation_->x, 13.2); EXPECT_DOUBLE_EQ(*node_2->translation_->x, 13.2); commandInterface.set(doubleHandleNode_2, 5.0); dispatch(); - doubleEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); EXPECT_DOUBLE_EQ(*node_1->translation_->x, 13.2); EXPECT_DOUBLE_EQ(*node_2->translation_->x, 13.2); } @@ -177,7 +173,7 @@ TEST_F(DoubleEditorTest, paste_property_from_string) { TEST_F(DoubleEditorTest, paste_property_from_bool) { Value value{true}; - doubleEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); EXPECT_DOUBLE_EQ(*node_1->translation_->x, 0.0); EXPECT_DOUBLE_EQ(*node_2->translation_->x, 0.0); } diff --git a/gui/libPropertyBrowser/tests/EditorTestFixture.h b/gui/libPropertyBrowser/tests/EditorTestFixture.h index 9ad031ac..472e63ba 100644 --- a/gui/libPropertyBrowser/tests/EditorTestFixture.h +++ b/gui/libPropertyBrowser/tests/EditorTestFixture.h @@ -10,6 +10,7 @@ #pragma once #include "property_browser/PropertyBrowserModel.h" +#include "property_browser/PropertyCopyPaste.h" #include "components/DataChangeDispatcher.h" #include "core/UserObjectFactoryInterface.h" #include "testing/TestEnvironmentCore.h" @@ -18,19 +19,23 @@ template class EditorTestFixtureT : public TestEnvironmentCoreT { public: - using DataChangeDispatcher = raco::components::DataChangeDispatcher; + using DataChangeDispatcher = components::DataChangeDispatcher; int argc{0}; QApplication application{argc, nullptr}; std::shared_ptr dataChangeDispatcher; - raco::property_browser::PropertyBrowserModel model; + property_browser::PropertyBrowserModel model; EditorTestFixtureT() : TestEnvironmentCoreT{}, dataChangeDispatcher{std::make_shared()} {} - EditorTestFixtureT(raco::core::UserObjectFactoryInterface* objectFactory) : TestEnvironmentCoreT{objectFactory}, dataChangeDispatcher{std::make_shared()} {} + EditorTestFixtureT(core::UserObjectFactoryInterface* objectFactory) : TestEnvironmentCoreT{objectFactory}, dataChangeDispatcher{std::make_shared()} {} void dispatch() { dataChangeDispatcher->dispatch(this->recorder.release()); application.processEvents(); } + + static void pasteProperty(property_browser::PropertyBrowserItem* item, data_storage::ValueBase* value) { + property_browser::PropertyCopyPaste::pasteProperty(item, value); + } }; using EditorTestFixture = EditorTestFixtureT<::testing::Test>; diff --git a/gui/libPropertyBrowser/tests/EnumerationEditor_test.cpp b/gui/libPropertyBrowser/tests/EnumerationEditor_test.cpp index b72554ac..0133c66e 100644 --- a/gui/libPropertyBrowser/tests/EnumerationEditor_test.cpp +++ b/gui/libPropertyBrowser/tests/EnumerationEditor_test.cpp @@ -16,13 +16,13 @@ #include "user_types/Material.h" #include "user_types/Texture.h" -#include +#include #include -class ExposedEnumerationEditor : public raco::property_browser::EnumerationEditor { +class ExposedEnumerationEditor : public property_browser::EnumerationEditor { public: - ExposedEnumerationEditor(raco::property_browser::PropertyBrowserItem* item, QWidget* parent) : EnumerationEditor(item, parent) {} + ExposedEnumerationEditor(property_browser::PropertyBrowserItem* item, QWidget* parent) : EnumerationEditor(item, parent) {} QComboBox* comboBox() { return comboBox_; @@ -32,21 +32,17 @@ class ExposedEnumerationEditor : public raco::property_browser::EnumerationEdito comboBox_->setCurrentIndex(index); comboBox_->Q_EMIT activated(index); } - - static void pasteProperty(raco::property_browser::PropertyBrowserItem* item, raco::data_storage::ValueBase* value) { - raco::property_browser::EnumerationEditor::pasteProperty(item, value); - } }; class EnumerationEditorFixture : public EditorTestFixture {}; TEST_F(EnumerationEditorFixture, noValueChangeRecorded_onForeignSet) { - auto material{context.createObject(raco::user_types::Material::typeDescription.typeName)}; - raco::core::ValueHandle handle{material, {"options", "blendOperationAlpha"}}; + auto material{context.createObject(user_types::Material::typeDescription.typeName)}; + core::ValueHandle handle{material, {"options", "blendOperationAlpha"}}; std::set handles{handle}; - raco::property_browser::PropertyBrowserItem item{handles, dataChangeDispatcher, &commandInterface, &model}; - raco::property_browser::EnumerationEditor editor{&item, nullptr}; + property_browser::PropertyBrowserItem item{handles, dataChangeDispatcher, &commandInterface, &model}; + property_browser::EnumerationEditor editor{&item, nullptr}; dispatch(); ASSERT_EQ(0, editor.currentIndex()); @@ -58,22 +54,22 @@ TEST_F(EnumerationEditorFixture, noValueChangeRecorded_onForeignSet) { } TEST_F(EnumerationEditorFixture, nonContinuousEnum) { - auto texture{context.createObject(raco::user_types::Texture::typeDescription.typeName)}; - raco::core::ValueHandle handle{texture, {"textureFormat"}}; + auto texture{context.createObject(user_types::Texture::typeDescription.typeName)}; + core::ValueHandle handle{texture, {"textureFormat"}}; const std::set handles{handle}; - raco::property_browser::PropertyBrowserItem item{handles, dataChangeDispatcher, &commandInterface, &model}; - raco::property_browser::EnumerationEditor editor{&item, nullptr}; + property_browser::PropertyBrowserItem item{handles, dataChangeDispatcher, &commandInterface, &model}; + property_browser::EnumerationEditor editor{&item, nullptr}; dispatch(); ASSERT_EQ(3, editor.currentIndex()); - commandInterface.set({texture, {"textureFormat"}}, static_cast(ramses::ETextureFormat::RGBA16F)); + commandInterface.set({texture, {"textureFormat"}}, static_cast(user_types::ETextureFormat::RGBA16F)); dispatch(); ASSERT_EQ(5, editor.currentIndex()); ASSERT_FALSE(recorder.hasValueChanged({texture, {"textureFormat"}})); - commandInterface.set({texture, {"textureFormat"}}, static_cast(ramses::ETextureFormat::R8)); + commandInterface.set({texture, {"textureFormat"}}, static_cast(user_types::ETextureFormat::R8)); dispatch(); ASSERT_EQ(0, editor.currentIndex()); @@ -81,14 +77,14 @@ TEST_F(EnumerationEditorFixture, nonContinuousEnum) { } TEST_F(EnumerationEditorFixture, multiselection_setup_single_value) { - const auto material_1{context.createObject(raco::user_types::Material::typeDescription.typeName, "material_1")}; - const auto material_2{context.createObject(raco::user_types::Material::typeDescription.typeName, "material_2")}; + const auto material_1{context.createObject(user_types::Material::typeDescription.typeName, "material_1")}; + const auto material_2{context.createObject(user_types::Material::typeDescription.typeName, "material_2")}; - const raco::core::ValueHandle handle_1{material_1, {"options", "blendOperationAlpha"}}; - const raco::core::ValueHandle handle_2{material_2, {"options", "blendOperationAlpha"}}; + const core::ValueHandle handle_1{material_1, {"options", "blendOperationAlpha"}}; + const core::ValueHandle handle_2{material_2, {"options", "blendOperationAlpha"}}; - raco::property_browser::PropertyBrowserItem item{{handle_1, handle_2}, dataChangeDispatcher, &commandInterface, &model}; - raco::property_browser::EnumerationEditor editor{&item, nullptr}; + property_browser::PropertyBrowserItem item{{handle_1, handle_2}, dataChangeDispatcher, &commandInterface, &model}; + property_browser::EnumerationEditor editor{&item, nullptr}; dispatch(); application.processEvents(); ASSERT_EQ(0, editor.currentIndex()); @@ -107,17 +103,17 @@ TEST_F(EnumerationEditorFixture, multiselection_setup_single_value) { } TEST_F(EnumerationEditorFixture, multiselection_setup_multiple_value) { - const auto material_1{context.createObject(raco::user_types::Material::typeDescription.typeName, "material_1")}; - const auto material_2{context.createObject(raco::user_types::Material::typeDescription.typeName, "material_2")}; + const auto material_1{context.createObject(user_types::Material::typeDescription.typeName, "material_1")}; + const auto material_2{context.createObject(user_types::Material::typeDescription.typeName, "material_2")}; - const raco::core::ValueHandle handle_1{material_1, {"options", "blendOperationAlpha"}}; - const raco::core::ValueHandle handle_2{material_2, {"options", "blendOperationAlpha"}}; + const core::ValueHandle handle_1{material_1, {"options", "blendOperationAlpha"}}; + const core::ValueHandle handle_2{material_2, {"options", "blendOperationAlpha"}}; // Set multiple values commandInterface.set({material_1, {"options", "blendOperationAlpha"}}, 4); - raco::property_browser::PropertyBrowserItem item{{handle_1, handle_2}, dataChangeDispatcher, &commandInterface, &model}; - raco::property_browser::EnumerationEditor editor{&item, nullptr}; + property_browser::PropertyBrowserItem item{{handle_1, handle_2}, dataChangeDispatcher, &commandInterface, &model}; + property_browser::EnumerationEditor editor{&item, nullptr}; dispatch(); application.processEvents(); ASSERT_EQ(-1, editor.currentIndex()); @@ -130,13 +126,13 @@ TEST_F(EnumerationEditorFixture, multiselection_setup_multiple_value) { } TEST_F(EnumerationEditorFixture, set_from_single_value) { - const auto material_1{context.createObject(raco::user_types::Material::typeDescription.typeName, "material_1")}; - const auto material_2{context.createObject(raco::user_types::Material::typeDescription.typeName, "material_2")}; + const auto material_1{context.createObject(user_types::Material::typeDescription.typeName, "material_1")}; + const auto material_2{context.createObject(user_types::Material::typeDescription.typeName, "material_2")}; - const raco::core::ValueHandle handle_1{material_1, {"options", "blendOperationAlpha"}}; - const raco::core::ValueHandle handle_2{material_2, {"options", "blendOperationAlpha"}}; + const core::ValueHandle handle_1{material_1, {"options", "blendOperationAlpha"}}; + const core::ValueHandle handle_2{material_2, {"options", "blendOperationAlpha"}}; - raco::property_browser::PropertyBrowserItem item{{handle_1, handle_2}, dataChangeDispatcher, &commandInterface, &model}; + property_browser::PropertyBrowserItem item{{handle_1, handle_2}, dataChangeDispatcher, &commandInterface, &model}; ExposedEnumerationEditor editor{&item, nullptr}; dispatch(); application.processEvents(); @@ -151,16 +147,16 @@ TEST_F(EnumerationEditorFixture, set_from_single_value) { } TEST_F(EnumerationEditorFixture, set_from_multi_value) { - const auto material_1{context.createObject(raco::user_types::Material::typeDescription.typeName, "material_1")}; - const auto material_2{context.createObject(raco::user_types::Material::typeDescription.typeName, "material_2")}; + const auto material_1{context.createObject(user_types::Material::typeDescription.typeName, "material_1")}; + const auto material_2{context.createObject(user_types::Material::typeDescription.typeName, "material_2")}; - const raco::core::ValueHandle handle_1{material_1, {"options", "blendOperationAlpha"}}; - const raco::core::ValueHandle handle_2{material_2, {"options", "blendOperationAlpha"}}; + const core::ValueHandle handle_1{material_1, {"options", "blendOperationAlpha"}}; + const core::ValueHandle handle_2{material_2, {"options", "blendOperationAlpha"}}; // Set multiple values commandInterface.set({material_1, {"options", "blendOperationAlpha"}}, 4); - raco::property_browser::PropertyBrowserItem item{{handle_1, handle_2}, dataChangeDispatcher, &commandInterface, &model}; + property_browser::PropertyBrowserItem item{{handle_1, handle_2}, dataChangeDispatcher, &commandInterface, &model}; ExposedEnumerationEditor editor{&item, nullptr}; dispatch(); application.processEvents(); @@ -176,54 +172,54 @@ TEST_F(EnumerationEditorFixture, set_from_multi_value) { TEST_F(EnumerationEditorFixture, paste_property_from_int_in_range) { - const auto material_1{context.createObject(raco::user_types::Material::typeDescription.typeName, "material_1")}; - const auto material_2{context.createObject(raco::user_types::Material::typeDescription.typeName, "material_2")}; + const auto material_1{context.createObject(user_types::Material::typeDescription.typeName, "material_1")}; + const auto material_2{context.createObject(user_types::Material::typeDescription.typeName, "material_2")}; - const raco::core::ValueHandle handle_1{material_1, {"options", "blendOperationAlpha"}}; - const raco::core::ValueHandle handle_2{material_2, {"options", "blendOperationAlpha"}}; + const core::ValueHandle handle_1{material_1, {"options", "blendOperationAlpha"}}; + const core::ValueHandle handle_2{material_2, {"options", "blendOperationAlpha"}}; // Set multiple values commandInterface.set({material_1, {"options", "blendOperationAlpha"}}, 4); - raco::property_browser::PropertyBrowserItem item{{handle_1, handle_2}, dataChangeDispatcher, &commandInterface, &model}; + property_browser::PropertyBrowserItem item{{handle_1, handle_2}, dataChangeDispatcher, &commandInterface, &model}; ExposedEnumerationEditor editor{&item, nullptr}; dispatch(); application.processEvents(); ASSERT_EQ(-1, editor.currentIndex()); - raco::data_storage::Value value{2}; + data_storage::Value value{2}; - editor.pasteProperty(&item, &value); + pasteProperty(&item, &value); EXPECT_EQ(handle_1.asInt(), 2); EXPECT_EQ(handle_2.asInt(), 2); commandInterface.set({material_1, {"options", "blendOperationAlpha"}}, 3); dispatch(); - editor.pasteProperty(&item, &value); + pasteProperty(&item, &value); EXPECT_EQ(handle_1.asInt(), 2); EXPECT_EQ(handle_2.asInt(), 2); } TEST_F(EnumerationEditorFixture, paste_property_from_int_out_of_range) { - const auto material_1{context.createObject(raco::user_types::Material::typeDescription.typeName, "material_1")}; - const auto material_2{context.createObject(raco::user_types::Material::typeDescription.typeName, "material_2")}; + const auto material_1{context.createObject(user_types::Material::typeDescription.typeName, "material_1")}; + const auto material_2{context.createObject(user_types::Material::typeDescription.typeName, "material_2")}; - const raco::core::ValueHandle handle_1{material_1, {"options", "blendOperationAlpha"}}; - const raco::core::ValueHandle handle_2{material_2, {"options", "blendOperationAlpha"}}; + const core::ValueHandle handle_1{material_1, {"options", "blendOperationAlpha"}}; + const core::ValueHandle handle_2{material_2, {"options", "blendOperationAlpha"}}; // Set multiple values commandInterface.set({material_1, {"options", "blendOperationAlpha"}}, 4); - raco::property_browser::PropertyBrowserItem item{{handle_1, handle_2}, dataChangeDispatcher, &commandInterface, &model}; + property_browser::PropertyBrowserItem item{{handle_1, handle_2}, dataChangeDispatcher, &commandInterface, &model}; ExposedEnumerationEditor editor{&item, nullptr}; dispatch(); application.processEvents(); ASSERT_EQ(-1, editor.currentIndex()); - raco::data_storage::Value value{12}; + data_storage::Value value{12}; - editor.pasteProperty(&item, &value); + pasteProperty(&item, &value); EXPECT_EQ(handle_1.asInt(), 4); EXPECT_EQ(handle_2.asInt(), 0); } diff --git a/gui/libPropertyBrowser/tests/IntEditor_test.cpp b/gui/libPropertyBrowser/tests/IntEditor_test.cpp index 1ba0d4a3..efe4ac43 100644 --- a/gui/libPropertyBrowser/tests/IntEditor_test.cpp +++ b/gui/libPropertyBrowser/tests/IntEditor_test.cpp @@ -41,10 +41,6 @@ class ExposedIntEditor : public IntEditor { bool sliderHasMultipleValues() const { return slider_->hasMultipleValues(); } - - static void pasteProperty(PropertyBrowserItem* item, data_storage::ValueBase* value) { - IntEditor::pasteProperty(item, value); - } }; @@ -111,14 +107,14 @@ TEST_F(IntEditorTest, check_multiple_values_text_displayed) { TEST_F(IntEditorTest, paste_property_from_int) { Value value{13}; - intEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); EXPECT_EQ(*meshNode_1->instanceCount_, 13); EXPECT_EQ(*meshNode_2->instanceCount_, 13); commandInterface.set(intHandleMeshNode_2, 5); dispatch(); - intEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); EXPECT_EQ(*meshNode_1->instanceCount_, 13); EXPECT_EQ(*meshNode_2->instanceCount_, 13); } @@ -126,14 +122,14 @@ TEST_F(IntEditorTest, paste_property_from_int) { TEST_F(IntEditorTest, paste_property_from_double) { Value value{13.2}; - intEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); EXPECT_EQ(*meshNode_1->instanceCount_, 13); EXPECT_EQ(*meshNode_2->instanceCount_, 13); commandInterface.set(intHandleMeshNode_2, 5); dispatch(); - intEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); EXPECT_EQ(*meshNode_1->instanceCount_, 13); EXPECT_EQ(*meshNode_2->instanceCount_, 13); } @@ -141,7 +137,7 @@ TEST_F(IntEditorTest, paste_property_from_double) { TEST_F(IntEditorTest, paste_property_from_bool) { Value value{true}; - intEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); EXPECT_EQ(*meshNode_1->instanceCount_, 1); EXPECT_EQ(*meshNode_2->instanceCount_, 1); } @@ -149,14 +145,14 @@ TEST_F(IntEditorTest, paste_property_from_bool) { TEST_F(IntEditorTest, paste_property_from_string) { Value value{"13"}; - intEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); EXPECT_EQ(*meshNode_1->instanceCount_, 13); EXPECT_EQ(*meshNode_2->instanceCount_, 13); commandInterface.set(intHandleMeshNode_2, 5); dispatch(); - intEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); EXPECT_EQ(*meshNode_1->instanceCount_, 13); EXPECT_EQ(*meshNode_2->instanceCount_, 13); } diff --git a/gui/libPropertyBrowser/tests/PrimitiveEditorsDataChange_test.cpp b/gui/libPropertyBrowser/tests/PrimitiveEditorsDataChange_test.cpp index b6b6104d..1a1e4ee2 100644 --- a/gui/libPropertyBrowser/tests/PrimitiveEditorsDataChange_test.cpp +++ b/gui/libPropertyBrowser/tests/PrimitiveEditorsDataChange_test.cpp @@ -24,9 +24,9 @@ #include "user_types/MeshNode.h" #include "user_types/Node.h" -using raco::core::CommandInterface; -using raco::core::ValueHandle; -using raco::property_browser::PropertyBrowserItem; +using core::CommandInterface; +using core::ValueHandle; +using property_browser::PropertyBrowserItem; struct TestParam { std::string testName; @@ -81,59 +81,59 @@ TEST_P(PrimitiveEditorDataChangeFixture, noValueChangeRecorded_onForeignSet) { delete editor; } -using raco::user_types::Material; -using raco::user_types::MeshNode; -using raco::user_types::Mesh; -using raco::user_types::Node; +using user_types::Material; +using user_types::MeshNode; +using user_types::Mesh; +using user_types::Node; INSTANTIATE_TEST_SUITE_P( PrimitiveEditorsDataChangeTest, PrimitiveEditorDataChangeFixture, ::testing::Values( TestParam{ "BoolEditor", - [](PropertyBrowserItem* item) -> QWidget* { return new raco::property_browser::BoolEditor(item, nullptr); }, + [](PropertyBrowserItem* item) -> QWidget* { return new property_browser::BoolEditor(item, nullptr); }, Node::typeDescription.typeName, {"visibility"}, [](CommandInterface& commandInterface, const ValueHandle& handle) { commandInterface.set(handle, false); }}, TestParam{ "DoubleEditor", - [](PropertyBrowserItem* item) -> QWidget* { return new raco::property_browser::DoubleEditor(item, nullptr); }, + [](PropertyBrowserItem* item) -> QWidget* { return new property_browser::DoubleEditor(item, nullptr); }, Node::typeDescription.typeName, {"translation", "x"}, [](CommandInterface& commandInterface, const ValueHandle& handle) { commandInterface.set(handle, 5.0); }}, TestParam{ "EnumerationEditor", - [](PropertyBrowserItem* item) -> QWidget* { return new raco::property_browser::EnumerationEditor(item, nullptr); }, + [](PropertyBrowserItem* item) -> QWidget* { return new property_browser::EnumerationEditor(item, nullptr); }, Material::typeDescription.typeName, {"options", "blendOperationColor"}, [](CommandInterface& commandInterface, const ValueHandle& handle) { commandInterface.set(handle, 4); }}, TestParam{ "IntEditor", - [](PropertyBrowserItem* item) -> QWidget* { return new raco::property_browser::IntEditor(item, nullptr); }, + [](PropertyBrowserItem* item) -> QWidget* { return new property_browser::IntEditor(item, nullptr); }, MeshNode::typeDescription.typeName, {"instanceCount"}, [](CommandInterface& commandInterface, const ValueHandle& handle) { commandInterface.set(handle, 4); }}, TestParam{ "RefEditor", - [](PropertyBrowserItem* item) -> QWidget* { return new raco::property_browser::RefEditor(item, nullptr); }, + [](PropertyBrowserItem* item) -> QWidget* { return new property_browser::RefEditor(item, nullptr); }, MeshNode::typeDescription.typeName, {"mesh"}, [](CommandInterface& commandInterface, const ValueHandle& handle) { commandInterface.set(handle, commandInterface.createObject(Mesh::typeDescription.typeName)); }}, TestParam{ "StringEditor", - [](PropertyBrowserItem* item) -> QWidget* { return new raco::property_browser::StringEditor(item, nullptr); }, + [](PropertyBrowserItem* item) -> QWidget* { return new property_browser::StringEditor(item, nullptr); }, Node::typeDescription.typeName, {"objectName"}, [](CommandInterface& commandInterface, const ValueHandle& handle) { commandInterface.set(handle, std::string{"New Object Name"}); }}, TestParam{ "URIEditor", - [](PropertyBrowserItem* item) -> QWidget* { return new raco::property_browser::URIEditor(item, nullptr); }, + [](PropertyBrowserItem* item) -> QWidget* { return new property_browser::URIEditor(item, nullptr); }, Material::typeDescription.typeName, {"uriVertex"}, [](CommandInterface& commandInterface, const ValueHandle& handle) { commandInterface.set(handle, std::string{"some_uri"}); }}, TestParam{ "VecNTEditor", - [](PropertyBrowserItem* item) -> QWidget* { return new raco::property_browser::Vec3fEditor(item, nullptr); }, + [](PropertyBrowserItem* item) -> QWidget* { return new property_browser::Vec3fEditor(item, nullptr); }, Node::typeDescription.typeName, {"translation"}, [](CommandInterface& commandInterface, const ValueHandle& handle) { commandInterface.set(handle, 5.0); }, diff --git a/gui/libPropertyBrowser/tests/PropertyBrowserItem_test.cpp b/gui/libPropertyBrowser/tests/PropertyBrowserItem_test.cpp index 445e3216..33a6cac0 100644 --- a/gui/libPropertyBrowser/tests/PropertyBrowserItem_test.cpp +++ b/gui/libPropertyBrowser/tests/PropertyBrowserItem_test.cpp @@ -33,7 +33,7 @@ class PropertyBrowserItemTestT : public EditorTestFixtureT { PropertyBrowserItemTestT() : EditorTestFixtureT(&TestObjectFactory::getInstance()) {} void addProperty(ValueHandle handle, std::string name, PrimitiveType type) { - this->context.addProperty(handle, name, raco::core::ValueBase::create(type)); + this->context.addProperty(handle, name, core::ValueBase::create(type)); this->dispatch(); } @@ -81,10 +81,10 @@ class PropertyBrowserItemTestT : public EditorTestFixtureT { } bool testNestedMatching(ValueBase* property_1, ValueBase* property_2) { - raco::data_storage::Table table_1; + data_storage::Table table_1; table_1.addProperty("nested", property_1); - raco::data_storage::Table table_2; + data_storage::Table table_2; table_2.addProperty("nested", property_2); return testMatching(new Value
(table_1), new Value
(table_2)); @@ -134,14 +134,14 @@ INSTANTIATE_TEST_SUITE_P( ::testing::Values( MatchingTestParams{ "display_name_annotation_same", - []() { return new Property({}, { "Cat"}); }, - []() { return new Property({}, { "Cat"}); }, + []() { return new Property({}, {"Cat"}); }, + []() { return new Property({}, {"Cat"}); }, true}, MatchingTestParams{ "display_name_annotation_different", - []() { return new Property({}, { "Cat"}); }, - []() { return new Property({}, { "Dog"}); }, + []() { return new Property({}, {"Cat"}); }, + []() { return new Property({}, {"Dog"}); }, false}, MatchingTestParams{ @@ -268,10 +268,59 @@ INSTANTIATE_TEST_SUITE_P( "struct_ref_vs_table", []() { return new Value(); }, []() { - raco::data_storage::Table table; + data_storage::Table table; table.addProperty("ref", new Value()); return new Value
(table); }, + false}, + + MatchingTestParams{ + "array_vs_scalar", + []() { return new Value>(); }, + []() { return new Value(); }, + false}, + + MatchingTestParams{ + "array_double_vs_double_same_size", + []() { + auto v = new Value>(); + (*v)->addProperty(); + return v; + }, + []() { + auto v = new Value>(); + (*v)->addProperty(); + return v; + }, + true}, + + MatchingTestParams{ + "array_double_vs_double_diff_size", + []() { + auto v = new Value>(); + (*v)->addProperty(); + (*v)->addProperty(); + return v; + }, + []() { + auto v = new Value>(); + (*v)->addProperty(); + return v; + }, + false}, + + MatchingTestParams{ + "array_double_vs_int_same_size", + []() { + auto v = new Value>(); + (*v)->addProperty(); + return v; + }, + []() { + auto v = new Value>(); + (*v)->addProperty(); + return v; + }, false} ), @@ -409,6 +458,94 @@ TEST_F(PropertyBrowserItemTest, signal_childrenChanged_multi_selection_add_value } + +TEST_F(PropertyBrowserItemTest, signal_childrenChanged_multi_selection_resize_array_single_to_single) { + auto object_1 = this->create("test"); + auto object_2 = this->create("test"); + const ValueHandle arrayHandle_1{object_1, {"array_double"}}; + const ValueHandle arrayHandle_2{object_2, {"array_double"}}; + + PropertyBrowserItem rootItem{{{object_1}, {object_2}}, dataChangeDispatcher, &commandInterface, nullptr}; + PropertyBrowserItem* childItem{rootItem.findNamedChild("array_double")}; + QSignalSpy spyRoot{&rootItem, SIGNAL(childrenChanged(const QList&))}; + QSignalSpy spyChild{childItem, SIGNAL(childrenChanged(const QList&))}; + + EXPECT_EQ(childItem->size(), 0); + + context.resizeArray(arrayHandle_1, 2); + context.resizeArray(arrayHandle_2, 2); + dispatch(); + + ASSERT_EQ(childItem, rootItem.findNamedChild("array_double")); + EXPECT_EQ(spyRoot.count(), 0); + EXPECT_EQ(spyChild.count(), 2); + EXPECT_EQ(childItem->size(), 2); +} + +TEST_F(PropertyBrowserItemTest, signal_childrenChanged_multi_selection_resize_array_single_to_multi) { + auto object_1 = this->create("test"); + auto object_2 = this->create("test"); + const ValueHandle arrayHandle_1{object_1, {"array_double"}}; + const ValueHandle arrayHandle_2{object_2, {"array_double"}}; + + PropertyBrowserItem rootItem{{{object_1}, {object_2}}, dataChangeDispatcher, &commandInterface, nullptr}; + QSignalSpy spyRoot{&rootItem, SIGNAL(childrenChanged(const QList&))}; + + context.resizeArray(arrayHandle_1, 2); + dispatch(); + + EXPECT_EQ(spyRoot.count(), 1); + ASSERT_EQ(rootItem.findNamedChild("array_double"), nullptr); +} + +TEST_F(PropertyBrowserItemTest, signal_childrenChanged_multi_selection_resize_array_multi_to_single) { + auto object_1 = this->create("test"); + auto object_2 = this->create("test"); + const ValueHandle arrayHandle_1{object_1, {"array_double"}}; + const ValueHandle arrayHandle_2{object_2, {"array_double"}}; + + context.resizeArray(arrayHandle_1, 2); + dispatch(); + + PropertyBrowserItem rootItem{{{object_1}, {object_2}}, dataChangeDispatcher, &commandInterface, nullptr}; + QSignalSpy spyRoot{&rootItem, SIGNAL(childrenChanged(const QList&))}; + + ASSERT_EQ(rootItem.findNamedChild("array_double"), nullptr); + + context.resizeArray(arrayHandle_2, 2); + dispatch(); + + PropertyBrowserItem* childItem{rootItem.findNamedChild("array_double")}; + + ASSERT_NE(nullptr, rootItem.findNamedChild("array_double")); + EXPECT_EQ(spyRoot.count(), 1); + EXPECT_EQ(childItem->size(), 2); +} + +TEST_F(PropertyBrowserItemTest, signal_childrenChanged_multi_selection_resize_array_multi_to_multi) { + auto object_1 = this->create("test"); + auto object_2 = this->create("test"); + const ValueHandle arrayHandle_1{object_1, {"array_double"}}; + const ValueHandle arrayHandle_2{object_2, {"array_double"}}; + + context.resizeArray(arrayHandle_1, 2); + dispatch(); + + PropertyBrowserItem rootItem{{{object_1}, {object_2}}, dataChangeDispatcher, &commandInterface, nullptr}; + QSignalSpy spyRoot{&rootItem, SIGNAL(childrenChanged(const QList&))}; + + ASSERT_EQ(rootItem.findNamedChild("tarray_doubleable"), nullptr); + + context.resizeArray(arrayHandle_2, 3); + dispatch(); + + PropertyBrowserItem* childItem{rootItem.findNamedChild("array_double")}; + + ASSERT_EQ(nullptr, rootItem.findNamedChild("array_double")); + EXPECT_EQ(spyRoot.count(), 1); +} + + TEST_F(PropertyBrowserItemTest, signal_childrenChanged_multi_selection_renderBuffer_hide_value_single_to_single) { auto object_1 = this->create("test"); auto object_2 = this->create("test"); @@ -489,6 +626,33 @@ TEST_F(PropertyBrowserItemTest, signal_childrenChanged_multi_selection_renderBuf EXPECT_EQ(spyRoot.count(), 2); } +TEST_F(PropertyBrowserItemTest, signal_childrenChanged_multi_selection_meshnode_options_private_changed) { + auto mesh = create_mesh("Mesh", "meshes/Duck.glb"); + auto meshnode_1 = create_meshnode("MeshNode 1", mesh, nullptr); + auto meshnode_2 = create_meshnode("MeshNode 2", mesh, nullptr); + + commandInterface.set(meshnode_1->getMaterialPrivateHandle(0), true); + commandInterface.set(meshnode_2->getMaterialPrivateHandle(0), true); + dispatch(); + + PropertyBrowserItem rootItem{{{meshnode_1}, {meshnode_2}}, dataChangeDispatcher, &commandInterface, nullptr}; + PropertyBrowserItem* materialItem{rootItem.findNamedChild("materials")}; + PropertyBrowserItem* matSlotItem{materialItem->findNamedChild("material")}; + PropertyBrowserItem* optionsItem{matSlotItem->findNamedChild("options")}; + + QSignalSpy spy{optionsItem, SIGNAL(childrenChanged(const QList&))}; + + commandInterface.set(meshnode_1->getMaterialPrivateHandle(0), false); + dispatch(); + + ASSERT_EQ(spy.count(), 1); + + undoStack.undo(); + dispatch(); + + ASSERT_EQ(spy.count(), 2); +} + TEST_F(PropertyBrowserItemTest, signal_childrenChanged_single_selection_add) { auto object = create("test"); @@ -508,7 +672,7 @@ TEST_F(PropertyBrowserItemTest, signal_childrenChanged_single_selection_add) { TEST_F(PropertyBrowserItemTest, signal_childrenChanged_single_selection_remove) { auto object = create("test"); const ValueHandle tableHandle{object, {"table"}}; - + addProperty(tableHandle, "double_prop", PrimitiveType::Double); PropertyBrowserItem itemUnderTest{{tableHandle}, dataChangeDispatcher, &commandInterface, nullptr}; @@ -683,4 +847,19 @@ TEST_F(PropertyBrowserItemTest, cacheExpandedState) { EXPECT_EQ(tableItem_3.expanded(), true); } +TEST_F(PropertyBrowserItemTest, highlight_property) { + const SLuaInterface interface = create_lua_interface("interface", "scripts/interface-scalar-types.lua"); + const ValueHandle interfaceHandle{interface}; + + PropertyBrowserItem root_item{{interfaceHandle}, dataChangeDispatcher, &commandInterface, nullptr}; + const auto propertyItem = root_item.findNamedChildByPropertyPath("interface.inputs.bool"); + const QSignalSpy spy{propertyItem, SIGNAL(highlighted())}; + + root_item.highlightProperty("non_existing_property"); + EXPECT_EQ(spy.count(), 0); + + root_item.highlightProperty("interface.inputs.bool"); + EXPECT_EQ(spy.count(), 1); +} + } // namespace raco::property_browser diff --git a/gui/libPropertyBrowser/tests/RefEditor_test.cpp b/gui/libPropertyBrowser/tests/RefEditor_test.cpp index ea47d785..61afe6da 100644 --- a/gui/libPropertyBrowser/tests/RefEditor_test.cpp +++ b/gui/libPropertyBrowser/tests/RefEditor_test.cpp @@ -62,10 +62,6 @@ class ExposedRefEditor : public RefEditor { return refItems; } - - static void pasteProperty(PropertyBrowserItem* item, data_storage::ValueBase* value) { - RefEditor::pasteProperty(item, value); - } }; class RefEditorTest : public EditorTestFixture { @@ -106,13 +102,13 @@ TEST_F(RefEditorTest, single_selection_setup_empty_expected) { dispatch(); - PropertyBrowserItem item0 {{ValueHandle(renderpass, &RenderPass::layer0_)}, dataChangeDispatcher, &commandInterface, nullptr}; + PropertyBrowserItem item0 {{ValueHandle(renderpass, &RenderPass::camera_)}, dataChangeDispatcher, &commandInterface, nullptr}; const auto refEditor0 = ExposedRefEditor(&item0); - PropertyBrowserItem item1{{ValueHandle(renderpass, &RenderPass::layer1_)}, dataChangeDispatcher, &commandInterface, nullptr}; + PropertyBrowserItem item1{{ValueHandle(renderpass, &RenderPass::target_)}, dataChangeDispatcher, &commandInterface, nullptr}; const auto refEditor1 = ExposedRefEditor(&item1); EXPECT_EQ(refEditor0.getCurrentRefText(), ""); - EXPECT_EQ(refEditor1.getCurrentRefText(), ""); + EXPECT_EQ(refEditor1.getCurrentRefText(), "Default Framebuffer"); EXPECT_TRUE(refEditor0.isRefEmpty()); EXPECT_FALSE(refEditor1.isRefEmpty()); } @@ -214,7 +210,7 @@ TEST_F(RefEditorTest, paste_property_target_valid) { EXPECT_FALSE(refEditor.isRefEmpty()); Value value{prefab_4}; - refEditor.pasteProperty(&item, &value); + pasteProperty(&item, &value); dispatch(); EXPECT_EQ(*inst_1->template_, prefab_4); @@ -249,7 +245,7 @@ TEST_F(RefEditorTest, paste_property_target_invalid) { EXPECT_FALSE(refEditor.isRefEmpty()); Value value{prefab_1}; - refEditor.pasteProperty(&item, &value); + pasteProperty(&item, &value); dispatch(); EXPECT_EQ(*inst_1->template_, prefab_3); diff --git a/gui/libPropertyBrowser/tests/URIEditor_test.cpp b/gui/libPropertyBrowser/tests/URIEditor_test.cpp index 72f6bca5..b8a45ed9 100644 --- a/gui/libPropertyBrowser/tests/URIEditor_test.cpp +++ b/gui/libPropertyBrowser/tests/URIEditor_test.cpp @@ -60,13 +60,13 @@ class URIEditorTest : public EditorTestFixture { std::string projectPath{(this->test_path() / "project" / "projectFileName").string()}; std::string absoluteMeshPath_1{(this->test_path() / "meshes" / "Duck.glb").string()}; - std::string relativeMeshPath_1{raco::utils::u8path(absoluteMeshPath_1).normalizedRelativePath(raco::utils::u8path(projectPath).parent_path()).string()}; + std::string relativeMeshPath_1{utils::u8path(absoluteMeshPath_1).normalizedRelativePath(utils::u8path(projectPath).parent_path()).string()}; std::string absoluteMeshPath_2{(this->test_path() / "meshes" / "defaultQuad.gltf").string()}; - std::string relativeMeshPath_2{raco::utils::u8path(absoluteMeshPath_2).normalizedRelativePath(raco::utils::u8path(projectPath).parent_path()).string()}; + std::string relativeMeshPath_2{utils::u8path(absoluteMeshPath_2).normalizedRelativePath(utils::u8path(projectPath).parent_path()).string()}; std::string absoluteMeshPath_3{(this->test_path() / "meshes" / "ToyCar/ToyCar.gltf").string()}; - std::string relativeMeshPath_3{raco::utils::u8path(absoluteMeshPath_3).normalizedRelativePath(raco::utils::u8path(projectPath).parent_path()).string()}; + std::string relativeMeshPath_3{utils::u8path(absoluteMeshPath_3).normalizedRelativePath(utils::u8path(projectPath).parent_path()).string()}; URIEditorTest() { this->project.setCurrentPath(projectPath); @@ -327,11 +327,11 @@ TEST_F(URIEditorTest, switch_to_rel_start_mixed) { TEST_F(URIEditorTest, ModificationRerootRelativePath) { auto newProjectPath = test_path() / "project" / "projectSubFolder" / "projectFileName"; - auto newRelativeMeshPath = raco::utils::u8path(absoluteMeshPath_1).normalizedRelativePath(newProjectPath.parent_path()); + auto newRelativeMeshPath = utils::u8path(absoluteMeshPath_1).normalizedRelativePath(newProjectPath.parent_path()); setLineEditText(relativeMeshPath_1); - propertyBrowserItem.set(raco::utils::u8path(relativeMeshPath_1).rerootRelativePath(projectPath, newProjectPath).string()); + propertyBrowserItem.set(utils::u8path(relativeMeshPath_1).rerootRelativePath(projectPath, newProjectPath).string()); dispatch(); ASSERT_EQ(uriEditor.getLineEdit()->text().toStdString(), newRelativeMeshPath); diff --git a/gui/libPropertyBrowser/tests/VecNTEditor_test.cpp b/gui/libPropertyBrowser/tests/VecNTEditor_test.cpp index fcdebedf..c39e6c94 100644 --- a/gui/libPropertyBrowser/tests/VecNTEditor_test.cpp +++ b/gui/libPropertyBrowser/tests/VecNTEditor_test.cpp @@ -47,10 +47,6 @@ class ExposedVecNTEditor : public VecNTEditor { return spinBox->hasMultipleValues(); }); } - - static void pasteProperty(PropertyBrowserItem* item, data_storage::ValueBase* value) { - VecNTEditor::pasteProperty(item, value); - } }; class VecNTEditorTest : public EditorTestFixture { @@ -131,7 +127,7 @@ TEST_F(VecNTEditorTest, paste_property_from_vec4f) { dispatch(); Value value{5.0}; - vecNTEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); checkVec4fValue({material_1, {"options", "blendColor"}}, {5.0, 5.0, 5.0, 5.0}); checkVec4fValue({material_2, {"options", "blendColor"}}, {5.0, 5.0, 5.0, 5.0}); @@ -143,7 +139,7 @@ TEST_F(VecNTEditorTest, paste_property_from_vec3f) { dispatch(); Value value{5.0}; - vecNTEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); checkVec4fValue({material_1, {"options", "blendColor"}}, {5.0, 5.0, 5.0, 3.0}); checkVec4fValue({material_2, {"options", "blendColor"}}, {5.0, 5.0, 5.0, 3.0}); @@ -155,7 +151,7 @@ TEST_F(VecNTEditorTest, paste_property_from_vec4i) { dispatch(); Value value{5}; - vecNTEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); checkVec4fValue({material_1, {"options", "blendColor"}}, {5.0, 5.0, 5.0, 5.0}); checkVec4fValue({material_2, {"options", "blendColor"}}, {5.0, 5.0, 5.0, 5.0}); @@ -167,7 +163,7 @@ TEST_F(VecNTEditorTest, paste_property_from_vec3i) { dispatch(); Value value{5}; - vecNTEditor.pasteProperty(&propertyBrowserItem, &value); + pasteProperty(&propertyBrowserItem, &value); checkVec4fValue({material_1, {"options", "blendColor"}}, {5.0, 5.0, 5.0, 3.0}); checkVec4fValue({material_2, {"options", "blendColor"}}, {5.0, 5.0, 5.0, 3.0}); diff --git a/gui/libRamsesWidgets/CMakeLists.txt b/gui/libRamsesWidgets/CMakeLists.txt index c6d0cbfe..89c742e8 100644 --- a/gui/libRamsesWidgets/CMakeLists.txt +++ b/gui/libRamsesWidgets/CMakeLists.txt @@ -11,14 +11,18 @@ If a copy of the MPL was not distributed with this file, You can obtain one at h raco_find_qt_components(Widgets) add_library(libRamsesWidgets + include/ramses_widgets/AbstractViewContentWidget.h src/AbstractViewContentWidget.cpp + include/ramses_widgets/AbstractViewMainWindow.h src/AbstractViewMainWindow.cpp include/ramses_widgets/BuildOptions.h include/ramses_widgets/PreviewContentWidget.h src/PreviewContentWidget.cpp include/ramses_widgets/PreviewFramebufferScene.h src/PreviewFramebufferScene.cpp include/ramses_widgets/PreviewMainWindow.h src/PreviewMainWindow.cpp include/ramses_widgets/PreviewScrollAreaWidget.h src/PreviewScrollAreaWidget.cpp include/ramses_widgets/RamsesPreviewWindow.h src/RamsesPreviewWindow.cpp + include/ramses_widgets/RamsesAbstractViewWindow.h src/RamsesAbstractViewWindow.cpp include/ramses_widgets/RendererBackend.h src/RendererBackend.cpp include/ramses_widgets/SceneStateEventHandler.h src/SceneStateEventHandler.cpp + include/ramses_widgets/TransformationController.h src/TransformationController.cpp src/PreviewMainWindow.ui ) @@ -38,10 +42,11 @@ target_link_libraries(libRamsesWidgets raco::LogSystem raco::UserTypes raco::Style + raco::ObjectTree Qt5::Widgets PRIVATE - raco::ramses-logic-lib raco::ramses-lib + raco::Style ) add_library(raco::RamsesWidgets ALIAS libRamsesWidgets) \ No newline at end of file diff --git a/gui/libRamsesWidgets/include/ramses_widgets/AbstractViewContentWidget.h b/gui/libRamsesWidgets/include/ramses_widgets/AbstractViewContentWidget.h new file mode 100644 index 00000000..f65eeee4 --- /dev/null +++ b/gui/libRamsesWidgets/include/ramses_widgets/AbstractViewContentWidget.h @@ -0,0 +1,110 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "ramses_widgets/RamsesAbstractViewWindow.h" +#include "ramses_widgets/RendererBackend.h" +#include "ramses_widgets/TransformationController.h" +#include "ramses_adaptor/AbstractSceneAdaptor.h" + +#include "object_tree_view/ObjectTreeDockManager.h" +#include +#include +#include + +namespace raco::ramses_adaptor { +class AbstractSceneAdaptor; +} + +namespace raco::ramses_widgets { + +class AbstractViewContentWidget final : public QWidget { + Q_OBJECT + Q_DISABLE_COPY(AbstractViewContentWidget) +public: + explicit AbstractViewContentWidget(RendererBackend& rendererBackend, ramses_adaptor::AbstractSceneAdaptor* abstractScene, object_tree::view::ObjectTreeDockManager* objectTreeDockManager, core::CommandInterface* commandInterface, QWidget* parent = nullptr); + virtual QPaintEngine* paintEngine() const override { return nullptr; } + void setSceneId(ramses::sceneId_t id); + +Q_SIGNALS: + void newMousePosition(const QPoint globalPosition); + void selectionRequested(const QString objectID); + void modeChanged(const QString& modeDescription); + +protected: + void paintEvent(QPaintEvent* event) override; + bool event(QEvent* event) override; + + void keyPressEvent(QKeyEvent* event) override; + void keyReleaseEvent(QKeyEvent* event) override; + void mousePressEvent(QMouseEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; + void mouseMoveEvent(QMouseEvent* event) override; + void wheelEvent(QWheelEvent* event) override; + + void resizeEvent(QResizeEvent* /*event*/) override; + + void updateCameraViewport(); + void handlePickRequest(std::vector pickIds); + +private: + enum class DragMode { + None = 0, + + PickRequested, + + CameraOrbit, + CameraPan, + CameraZoom, + + Translate, + Rotate, + Scale + }; + + using TransformMode = TransformationController::TransformMode; + using Axis = TransformationController::Axis; + + void emitModeChanged(); + void setMode(DragMode dragMode, TransformMode transformMode = TransformMode::Free); + void setupMode(const std::vector& selection, DragMode dragMode); + void setupTransformMode(TransformMode mode, Axis axis = Axis::X); + void beginDrag(); + void endDrag(); + void abortDrag(); + + void updateFromText(); + + RendererBackend& rendererBackend_; + std::unique_ptr ramsesPreview_; + ramses_adaptor::AbstractSceneAdaptor* abstractScene_; + object_tree::view::ObjectTreeDockManager* treeDockManager_; + core::CommandInterface* commandInterface_; + TransformationController transformationController_; + + QPoint mouseLastPos_; + + DragMode dragMode_ = DragMode::None; + Axis axis_; + TransformMode transformMode_; + + // Direct numeric input of transformation value: current input string + std::string text_; + // Direct numeric input of transformation value: current value + // This is the latest valid value converted from text_ + float value_; + + std::optional gizmoMode_; + + core::SEditorObject activeObject_; + std::optional dragInitialPos_; +}; + +} // namespace raco::ramses_widgets diff --git a/gui/libRamsesWidgets/include/ramses_widgets/AbstractViewMainWindow.h b/gui/libRamsesWidgets/include/ramses_widgets/AbstractViewMainWindow.h new file mode 100644 index 00000000..0821460f --- /dev/null +++ b/gui/libRamsesWidgets/include/ramses_widgets/AbstractViewMainWindow.h @@ -0,0 +1,66 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "components/DataChangeDispatcher.h" +#include "components/DebugInstanceCounter.h" +#include "object_tree_view/ObjectTreeDockManager.h" +#include "ramses_widgets/RendererBackend.h" +#include +#include +#include +#include + +namespace raco::ramses_adaptor { +class AbstractSceneAdaptor; +} + +namespace raco::ramses_widgets { + +class AbstractViewContentWidget; + +class AbstractViewMainWindow final : public QMainWindow { + Q_OBJECT + DEBUG_INSTANCE_COUNTER(AbstractViewMainWindow); + +public: + AbstractViewMainWindow(RendererBackend& rendererBackend, + ramses_adaptor::AbstractSceneAdaptor* abstractScene, + object_tree::view::ObjectTreeDockManager* objectTreeDockManager, + core::CommandInterface* commandInterface, + QWidget* parent = nullptr); + ~AbstractViewMainWindow(); + + void focusCamera(const std::vector& objects); + +Q_SIGNALS: + void selectionRequested(const QString objectID, const QString objectProperty = {}); + +public Q_SLOTS: + void onSelectionChanged(const core::SEditorObjectSet& objects); + void onSelectionCleared(); + +private: + enum class HighlightMode { + None, + Color, + Transparency + }; + + void updateHighlighted(); + + AbstractViewContentWidget* previewWidget_; + ramses_adaptor::AbstractSceneAdaptor* abstractScene_; + object_tree::view::ObjectTreeDockManager* treeDockManager_; + + HighlightMode highlightMode_ = HighlightMode::None; +}; + +} // namespace raco::ramses_widgets \ No newline at end of file diff --git a/gui/libRamsesWidgets/include/ramses_widgets/BuildOptions.h b/gui/libRamsesWidgets/include/ramses_widgets/BuildOptions.h index 5c25816e..6c1f0d61 100644 --- a/gui/libRamsesWidgets/include/ramses_widgets/BuildOptions.h +++ b/gui/libRamsesWidgets/include/ramses_widgets/BuildOptions.h @@ -18,11 +18,11 @@ #endif #ifndef RACO_INTERNAL_SCENE_IDS_START -#define RACO_INTERNAL_SCENE_IDS_START 1337 +#define RACO_INTERNAL_SCENE_IDS_START 1000000 #endif #ifndef RACO_INTERNAL_SCENE_IDS_END -#define RACO_INTERNAL_SCENE_IDS_END 50000 +#define RACO_INTERNAL_SCENE_IDS_END 1000100 #endif struct BuildOptions { diff --git a/gui/libRamsesWidgets/include/ramses_widgets/PreviewContentWidget.h b/gui/libRamsesWidgets/include/ramses_widgets/PreviewContentWidget.h index 3dd526c0..71a2571d 100644 --- a/gui/libRamsesWidgets/include/ramses_widgets/PreviewContentWidget.h +++ b/gui/libRamsesWidgets/include/ramses_widgets/PreviewContentWidget.h @@ -29,6 +29,7 @@ class PreviewContentWidget final : public QWidget { void setSceneId(ramses::sceneId_t id); void setBackgroundColor(core::Vec4f backgroundColor); void setMsaaSampleRate(PreviewMultiSampleRate sampleRate); + PreviewMultiSampleRate getMsaaSampleRate(); void commit(bool forceUpdate); bool saveScreenshot(const std::string& fullPath); diff --git a/gui/libRamsesWidgets/include/ramses_widgets/PreviewFramebufferScene.h b/gui/libRamsesWidgets/include/ramses_widgets/PreviewFramebufferScene.h index f79be65c..1f938f8a 100644 --- a/gui/libRamsesWidgets/include/ramses_widgets/PreviewFramebufferScene.h +++ b/gui/libRamsesWidgets/include/ramses_widgets/PreviewFramebufferScene.h @@ -40,26 +40,26 @@ class PreviewFramebufferScene final { private: // Scene - raco::ramses_base::RamsesScene scene_; - raco::ramses_base::RamsesOrthographicCamera camera_; + ramses_base::RamsesScene scene_; + ramses_base::RamsesOrthographicCamera camera_; std::shared_ptr renderGroup_; std::shared_ptr renderPass_; - raco::ramses_base::RamsesEffect effect_; - raco::ramses_base::RamsesEffect effectMS_; - raco::ramses_base::RamsesAppearance appearance_; - raco::ramses_base::RamsesAppearance appearanceMS_; - raco::ramses_base::RamsesArrayResource indexDataBuffer_; - raco::ramses_base::RamsesArrayResource vertexDataBuffer_; - raco::ramses_base::RamsesArrayResource uvDataBuffer_; - raco::ramses_base::RamsesGeometryBinding geometryBinding_; - raco::ramses_base::RamsesGeometryBinding geometryBindingMS_; - raco::ramses_base::RamsesMeshNode meshNode_; + ramses_base::RamsesEffect effect_; + ramses_base::RamsesEffect effectMS_; + ramses_base::RamsesAppearance appearance_; + ramses_base::RamsesAppearance appearanceMS_; + ramses_base::RamsesArrayResource indexDataBuffer_; + ramses_base::RamsesArrayResource vertexDataBuffer_; + ramses_base::RamsesArrayResource uvDataBuffer_; + ramses_base::RamsesGeometry geometry_; + ramses_base::RamsesGeometry geometryMS_; + ramses_base::RamsesMeshNode meshNode_; // Offscreen texture and consumer - raco::ramses_base::RamsesTexture2D framebufferTexture_; - raco::ramses_base::RamsesTextureSampler sampler_; - raco::ramses_base::RamsesRenderBuffer renderbufferMS_; - raco::ramses_base::RamsesTextureSamplerMS samplerMS_; + ramses_base::RamsesTexture2D framebufferTexture_; + ramses_base::RamsesTextureSampler sampler_; + ramses_base::RamsesRenderBuffer renderbufferMS_; + ramses_base::RamsesTextureSamplerMS samplerMS_; ramses::dataConsumerId_t framebufferSampleId_; int currentSampleCount_ = 0; diff --git a/gui/libRamsesWidgets/include/ramses_widgets/PreviewMainWindow.h b/gui/libRamsesWidgets/include/ramses_widgets/PreviewMainWindow.h index dd711aee..1541e71e 100644 --- a/gui/libRamsesWidgets/include/ramses_widgets/PreviewMainWindow.h +++ b/gui/libRamsesWidgets/include/ramses_widgets/PreviewMainWindow.h @@ -16,6 +16,7 @@ #include #include #include +#include namespace raco::user_types { @@ -45,14 +46,15 @@ class PreviewContentWidget; class PreviewScrollAreaWidget; class PreviewMainWindow final : public QMainWindow { + Q_OBJECT DEBUG_INSTANCE_COUNTER(PreviewMainWindow); public: PreviewMainWindow(RendererBackend& rendererBackend, - raco::ramses_adaptor::SceneBackend* sceneBackend, + ramses_adaptor::SceneBackend* sceneBackend, const QSize& sceneSize, - raco::core::Project* project, - raco::components::SDataChangeDispatcher dispatcher, + core::Project* project, + components::SDataChangeDispatcher dispatcher, QWidget* parent = nullptr); ~PreviewMainWindow(); void displayScene(ramses::sceneId_t sceneId, core::Vec4f const& backgroundColor); diff --git a/gui/libRamsesWidgets/include/ramses_widgets/RamsesAbstractViewWindow.h b/gui/libRamsesWidgets/include/ramses_widgets/RamsesAbstractViewWindow.h new file mode 100644 index 00000000..cc45d9ac --- /dev/null +++ b/gui/libRamsesWidgets/include/ramses_widgets/RamsesAbstractViewWindow.h @@ -0,0 +1,48 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "RendererBackend.h" +#include + +namespace raco::ramses_widgets { + +class RamsesAbstractViewWindow final { +public: + struct State { + ramses::sceneId_t sceneId{ramses::sceneId_t::Invalid()}; + QSize viewportSize{0, 0}; + + bool operator!=(const State& other) const { + return this->sceneId != other.sceneId || this->viewportSize != other.viewportSize; + } + }; + + explicit RamsesAbstractViewWindow(void* windowHandle, RendererBackend& rendererBackend); + ~RamsesAbstractViewWindow(); + + const State& currentState(); + State& nextState(); + + void commit(bool forceUpdate = false); + +private: + void reset(); + + void* windowHandle_; + RendererBackend& rendererBackend_; + + ramses::displayId_t displayId_; + + State current_{}; + State next_{}; +}; + +} // namespace raco::ramses_widgets \ No newline at end of file diff --git a/gui/libRamsesWidgets/include/ramses_widgets/RamsesPreviewWindow.h b/gui/libRamsesWidgets/include/ramses_widgets/RamsesPreviewWindow.h index e7b7c60c..4de389a2 100644 --- a/gui/libRamsesWidgets/include/ramses_widgets/RamsesPreviewWindow.h +++ b/gui/libRamsesWidgets/include/ramses_widgets/RamsesPreviewWindow.h @@ -14,7 +14,7 @@ #include #include #include -#include +#include namespace raco::ramses_widgets { @@ -70,7 +70,7 @@ class RamsesPreviewWindow final { ramses::displayId_t displayId_; ramses::displayBufferId_t offscreenBufferId_; - std::unique_ptr framebufferScene_; + std::unique_ptr framebufferScene_; State current_{}; State next_{}; diff --git a/gui/libRamsesWidgets/include/ramses_widgets/RendererBackend.h b/gui/libRamsesWidgets/include/ramses_widgets/RendererBackend.h index 73b55347..bd041e5b 100644 --- a/gui/libRamsesWidgets/include/ramses_widgets/RendererBackend.h +++ b/gui/libRamsesWidgets/include/ramses_widgets/RendererBackend.h @@ -21,12 +21,11 @@ namespace raco::ramses_widgets { class SceneStateEventHandler; -class RendererBackend final : public raco::ramses_base::BaseEngineBackend { +class RendererBackend final : public ramses_base::BaseEngineBackend { Q_DISABLE_COPY(RendererBackend) public: typedef std::unique_ptr> UniqueRenderer; - static ramses::RamsesFrameworkConfig& ramsesFrameworkConfig(const std::string& frameworkArgs) noexcept; - explicit RendererBackend(rlogic::EFeatureLevel featureLevel, const std::string& frameworkArgs = {}); + explicit RendererBackend(const ramses::RamsesFrameworkConfig& frameworkConfig = defaultRamsesFrameworkConfig()); ~RendererBackend(); ramses::RamsesRenderer& renderer() const; @@ -39,6 +38,13 @@ class RendererBackend final : public raco::ramses_base::BaseEngineBackend { ramses::dataConsumerId_t internalDataConsumerId(); void doOneLoop() const; +protected: + void reset() override; + void setup(ramses::EFeatureLevel featureLevel) override; + +Q_SIGNALS: + void screenshotSaved(bool success); + private: UniqueRenderer renderer_; std::unique_ptr eventHandler_; // we don't want to include SceneStateEventHandler (with its explicit Ramses renderer headers, hence the pointer) diff --git a/gui/libRamsesWidgets/include/ramses_widgets/SceneStateEventHandler.h b/gui/libRamsesWidgets/include/ramses_widgets/SceneStateEventHandler.h index 40c494af..0d5ca42c 100644 --- a/gui/libRamsesWidgets/include/ramses_widgets/SceneStateEventHandler.h +++ b/gui/libRamsesWidgets/include/ramses_widgets/SceneStateEventHandler.h @@ -9,16 +9,19 @@ */ #pragma once -#include -#include -#include -#include +#include +#include +#include +#include #include #include +#include + namespace raco::ramses_widgets { -class SceneStateEventHandler final : public ramses::RendererEventHandlerEmpty, public ramses::RendererSceneControlEventHandlerEmpty { +class SceneStateEventHandler final : public QObject, public ramses::RendererEventHandlerEmpty, public ramses::RendererSceneControlEventHandlerEmpty { + Q_OBJECT public: explicit SceneStateEventHandler(ramses::RamsesRenderer& renderer); @@ -32,7 +35,16 @@ class SceneStateEventHandler final : public ramses::RendererEventHandlerEmpty, p void sceneStateChanged(ramses::sceneId_t sceneId, ramses::RendererSceneState state) override; void sceneFlushed(ramses::sceneId_t sceneId, ramses::sceneVersionTag_t sceneVersion) override; - void waitForSceneState(ramses::sceneId_t sceneId, ramses::RendererSceneState state); + enum class ECompareFunc { + Equal, + LessEqual, + GreaterEqual + }; + + void waitForSceneState(ramses::sceneId_t sceneId, ramses::RendererSceneState state, ECompareFunc compFunc = ECompareFunc::Equal); + + void objectsPicked(ramses::sceneId_t sceneId, const ramses::pickableObjectId_t* pickedObjects, size_t pickedObjectsCount) override; + bool waitForFlush(ramses::sceneId_t sceneId, ramses::sceneVersionTag_t sceneVersion); bool waitForDisplayCreation(ramses::displayId_t displayId); bool waitForDisplayDestruction(ramses::displayId_t displayId); @@ -46,6 +58,9 @@ class SceneStateEventHandler final : public ramses::RendererEventHandlerEmpty, p bool saveScreenshot(const std::string& filename, ramses::displayId_t displayId, ramses::displayBufferId_t screenshotBuf, uint32_t x, uint32_t y, uint32_t width, uint32_t height); +Q_SIGNALS: + void pickRequest(std::vector pickIds); + private: struct SceneInfo { ramses::RendererSceneState state = ramses::RendererSceneState::Unavailable; diff --git a/gui/libRamsesWidgets/include/ramses_widgets/TransformationController.h b/gui/libRamsesWidgets/include/ramses_widgets/TransformationController.h new file mode 100644 index 00000000..b9fc1cbd --- /dev/null +++ b/gui/libRamsesWidgets/include/ramses_widgets/TransformationController.h @@ -0,0 +1,105 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "core/EditorObject.h" + +#include +#include +#include + +#include +#include + +#include + +namespace raco::core { +class CommandInterface; +} + +namespace raco::ramses_adaptor { +class AbstractSceneAdaptor; +} + +namespace raco::ramses_widgets { + +class TransformationController { +public: + enum class DragMode { + None, + Translate, + Rotate, + Scale + }; + + enum class Axis { + X = 0, + Y, + Z + }; + + enum class TransformMode { + Free, + Axis, + Plane + }; + + TransformationController(ramses_adaptor::AbstractSceneAdaptor* abstractScene, core::CommandInterface* commandInterface); + + void beginDrag(core::SEditorObject object, DragMode mode, TransformMode transformMode, Axis axis); + void abortDrag(); + void endDrag(); + + void translate(float distance); + void dragTranslate(QPoint initialPos, QPoint currentPos, int widgetWidth, int widgetHeight, bool snap, double snapScale); + + void scale(float scalingFactor); + void dragScale(QPoint initialPos, QPoint currentPos, int widgetWidth, int widgetHeight, bool snap); + + void rotate(float angleDegrees); + void dragRotate(QPoint initialPos, QPoint currentPos, int widgetWidth, int widgetHeight, bool snap); + +private: + struct Ray { + glm::vec3 origin; + glm::vec3 direction; + }; + + struct Plane { + glm::vec3 normal; + float dist; + }; + + static glm::vec3 axisVector(Axis axis); + + Ray unproject(QPoint pos, glm::mat4 world, glm::mat4 projection, glm::ivec4 viewport); + std::optional intersect(const Ray& ray, const Plane& plane); + + QPoint project(QPoint point, glm::vec2 rayOrigin, glm::vec2 rayDirection); + + ramses_adaptor::AbstractSceneAdaptor* abstractScene_; + core::CommandInterface* commandInterface_; + + core::SEditorObject activeObject_; + DragMode dragMode_ = DragMode::None; + Axis axis_; + TransformMode transformMode_; + + glm::vec3 dragInitialObjectTranslation_; + glm::vec3 dragInitialObjectScaling_; + glm::vec3 dragInitialObjectRotation_; + + Plane plane_; + glm::vec3 refAxis_; + glm::vec3 refAxis2_; + glm::vec3 initialWorldOrigin_; +}; + +} // namespace raco::ramses_widgets diff --git a/gui/libRamsesWidgets/src/AbstractViewContentWidget.cpp b/gui/libRamsesWidgets/src/AbstractViewContentWidget.cpp new file mode 100644 index 00000000..b2270378 --- /dev/null +++ b/gui/libRamsesWidgets/src/AbstractViewContentWidget.cpp @@ -0,0 +1,439 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#include "ramses_widgets/AbstractViewContentWidget.h" + +#include "core/CommandInterface.h" + +#include "ramses_widgets/SceneStateEventHandler.h" + +#include "ramses_adaptor/utilities.h" + +#include +#include +#include +#include + +#include +#include + +#include +#include + +namespace raco::ramses_widgets { + +AbstractViewContentWidget::AbstractViewContentWidget(RendererBackend& rendererBackend, ramses_adaptor::AbstractSceneAdaptor* abstractScene, object_tree::view::ObjectTreeDockManager* objectTreeDockManager, core::CommandInterface* commandInterface, QWidget* parent) + : QWidget(parent), + rendererBackend_(rendererBackend), + ramsesPreview_{std::make_unique(reinterpret_cast(winId()), rendererBackend)}, + abstractScene_(abstractScene), + treeDockManager_(objectTreeDockManager), + commandInterface_(commandInterface), + transformationController_(abstractScene, commandInterface) { + // In order to prevent Qt from interfering with Ramses rendering into the window we need to set these flags + // and also override the QWidget::paintEngine method (returning a nullptr). + setAttribute(Qt::WA_PaintOnScreen, true); + setAttribute(Qt::WA_OpaquePaintEvent, true); + setAttribute(Qt::WA_NoSystemBackground, true); + setSceneId(abstractScene_->sceneId()); + setFocusPolicy(Qt::StrongFocus); + setMouseTracking(true); + + QObject::connect(&rendererBackend_.eventHandler(), &SceneStateEventHandler::pickRequest, this, &AbstractViewContentWidget::handlePickRequest); +} + +void AbstractViewContentWidget::setSceneId(ramses::sceneId_t id) { + if (ramsesPreview_) { + ramsesPreview_->nextState().sceneId = id; + update(); + } +} + +bool AbstractViewContentWidget::event(QEvent* event) { + if (event->type() == QEvent::Type::PlatformSurface) { + switch (dynamic_cast(event)->surfaceEventType()) { + case QPlatformSurfaceEvent::SurfaceEventType::SurfaceAboutToBeDestroyed: + ramsesPreview_.reset(); + break; + } + } + return QWidget::event(event); +} + +void AbstractViewContentWidget::resizeEvent(QResizeEvent* event) { + QWidget::resizeEvent(event); + updateCameraViewport(); + if (ramsesPreview_) { + ramsesPreview_->nextState().viewportSize = size() * window()->screen()->devicePixelRatio(); + update(); + } +} + +void AbstractViewContentWidget::updateCameraViewport() { + auto ramsesSize = size() * window()->screen()->devicePixelRatio(); + abstractScene_->rescaleCameraToViewport(ramsesSize.width(), ramsesSize.height()); +} + +void AbstractViewContentWidget::paintEvent(QPaintEvent* e) { + if (ramsesPreview_->currentState() != ramsesPreview_->nextState()) { + ramsesPreview_->commit(); + } +} + +void AbstractViewContentWidget::emitModeChanged() { + std::map modeDesc = { + {DragMode::None, ""}, + {DragMode::CameraOrbit, "Orbit"}, + {DragMode::CameraPan, "Pan"}, + {DragMode::CameraZoom, "Zoom"}, + {DragMode::Translate, "Translate"}, + {DragMode::Rotate, "Rotate"}, + {DragMode::Scale, "Scale"}}; + + std::map axisLabel = { + {Axis::X, "X"}, + {Axis::Y, "Y"}, + {Axis::Z, "Z"}}; + std::map planeLabel = { + {Axis::X, "YZ"}, + {Axis::Y, "XZ"}, + {Axis::Z, "XY"}}; + + QString text = modeDesc.find(dragMode_)->second; + if (dragMode_ >= DragMode::Translate) { + switch (transformMode_) { + case TransformMode::Axis: + text = text + " " + axisLabel[axis_]; + break; + case TransformMode::Plane: + text = text + " " + planeLabel[axis_]; + break; + case TransformMode::Free: + break; + } + } + + if (!text_.empty()) { + std::string msg = fmt::format(" by '{}' -> {}", text_, value_); + text = text + QString::fromStdString(msg); + } + + Q_EMIT modeChanged(text); +} + +void AbstractViewContentWidget::setMode(DragMode dragMode, TransformMode transformMode) { + dragMode_ = dragMode; + transformMode_ = transformMode; + text_.clear(); + value_ = 0.0; + emitModeChanged(); +} + +void AbstractViewContentWidget::beginDrag() { + dragInitialPos_.reset(); + + switch (dragMode_) { + case DragMode::Translate: + transformationController_.beginDrag(activeObject_, TransformationController::DragMode::Translate, transformMode_, axis_); + break; + case DragMode::Scale: + transformationController_.beginDrag(activeObject_, TransformationController::DragMode::Scale, transformMode_, axis_); + break; + case DragMode::Rotate: + transformationController_.beginDrag(activeObject_, TransformationController::DragMode::Rotate, transformMode_, axis_); + break; + } + if (abstractScene_->gizmoMode() != ramses_adaptor::AbstractSceneAdaptor::GizmoMode::None) { + gizmoMode_ = abstractScene_->gizmoMode(); + } + abstractScene_->setGizmoMode(ramses_adaptor::AbstractSceneAdaptor::GizmoMode::None); +} + +void AbstractViewContentWidget::endDrag() { + setMode(DragMode::None); + transformationController_.endDrag(); + if (gizmoMode_) { + abstractScene_->setGizmoMode(gizmoMode_.value()); + gizmoMode_.reset(); + } +} + +void AbstractViewContentWidget::abortDrag() { + setMode(DragMode::None); + transformationController_.abortDrag(); + if (gizmoMode_) { + abstractScene_->setGizmoMode(gizmoMode_.value()); + gizmoMode_.reset(); + } +} + +void AbstractViewContentWidget::setupMode(const std::vector& selection, DragMode dragMode) { + if (selection.size() != 1) { + return; + } + activeObject_ = selection.front(); + + bool canSetProperty = false; + switch (dragMode) { + case DragMode::Translate: + canSetProperty = commandInterface_->canSetHandle({activeObject_, &user_types::Node::translation_}); + break; + case DragMode::Rotate: + canSetProperty = commandInterface_->canSetHandle({activeObject_, &user_types::Node::rotation_}); + break; + case DragMode::Scale: + canSetProperty = commandInterface_->canSetHandle({activeObject_, &user_types::Node::scaling_}); + break; + } + if (!abstractScene_->hasModelMatrix(activeObject_)) { + canSetProperty = false; + } + if (canSetProperty) { + setMode(dragMode); + beginDrag(); + } else { + setMode(DragMode::None); + } +} + +void AbstractViewContentWidget::setupTransformMode(TransformMode mode, Axis axis) { + if (dragMode_ != DragMode::None) { + transformMode_ = mode; + axis_ = axis; + emitModeChanged(); + + beginDrag(); + } +} + +void AbstractViewContentWidget::updateFromText() { + size_t numProcessed = 0; + float value; + try { + value = std::stof(text_, &numProcessed); + } catch (std::exception&) { + } + if (numProcessed > 0 && numProcessed == text_.length()) { + value_ = value; + + switch (dragMode_) { + case DragMode::Translate: + transformationController_.translate(value_); + break; + case DragMode::Rotate: + transformationController_.rotate(value_); + break; + case DragMode::Scale: + transformationController_.scale(value_); + break; + } + } + emitModeChanged(); +} + +void AbstractViewContentWidget::keyPressEvent(QKeyEvent* event) { + if (event->key() == Qt::Key_Escape) { + abortDrag(); + } else { + switch (dragMode_) { + case DragMode::None: + switch (event->key()) { + case Qt::Key_G: + setupMode(treeDockManager_->getSelection(), DragMode::Translate); + return; + case Qt::Key_S: + setupMode(treeDockManager_->getSelection(), DragMode::Scale); + break; + case Qt::Key_R: + setupMode(treeDockManager_->getSelection(), DragMode::Rotate); + break; + } + break; + + case DragMode::Translate: + case DragMode::Rotate: + case DragMode::Scale: { + TransformMode transformationMode = TransformMode::Axis; + if (dragMode_ != DragMode::Rotate && event->modifiers() == Qt::ShiftModifier) { + transformationMode = TransformMode::Plane; + } + switch (event->key()) { + case Qt::Key_X: + setupTransformMode(transformationMode, Axis::X); + break; + case Qt::Key_Y: + setupTransformMode(transformationMode, Axis::Y); + break; + case Qt::Key_Z: + setupTransformMode(transformationMode, Axis::Z); + break; + + case Qt::Key_Backspace: + if (!text_.empty()) { + text_.resize(text_.size() - 1); + updateFromText(); + } + break; + + case Qt::Key_Return: + endDrag(); + break; + + default: { + // Exclude free and plane translation from numeric input since they need 2 input values and we only have 1: + if (dragMode_ != DragMode::Translate || transformMode_ == TransformMode::Axis) { + std::string text = event->text().toStdString(); + if (text.size() == 1) { + auto c = text[0]; + if (std::string("1234567890.-").find(c) != std::string::npos) { + text_ = text_ + c; + updateFromText(); + } + } + } + } break; + } + break; + } + } + } + + QWidget::keyPressEvent(event); +} + +void AbstractViewContentWidget::keyReleaseEvent(QKeyEvent* event) { + QWidget::keyReleaseEvent(event); +} + +void AbstractViewContentWidget::mousePressEvent(QMouseEvent* event) { + mouseLastPos_ = event->pos(); + + if (event->button() == Qt::MiddleButton || event->button() == Qt::RightButton) { + if (event->modifiers() == Qt::NoModifier) { + setMode(DragMode::CameraOrbit); + } else if (event->modifiers() == Qt::ShiftModifier) { + setMode(DragMode::CameraPan); + } else if (event->modifiers() == Qt::ControlModifier) { + setMode(DragMode::CameraZoom); + } + } + + if (dragMode_ == DragMode::None && event->button() == Qt::LeftButton) { + // Picking + auto pos = event->localPos(); + float relX = 2.0 * pos.x() / width() - 1.0; + float relY = 1.0 - 2.0 * pos.y() / height(); + + auto sceneControl = rendererBackend_.renderer().getSceneControlAPI(); + sceneControl->handlePickEvent(ramsesPreview_->currentState().sceneId, relX, relY); + sceneControl->flush(); + + dragMode_ = DragMode::PickRequested; + } +} + +void AbstractViewContentWidget::mouseReleaseEvent(QMouseEvent* event) { + if (event->button() == Qt::LeftButton) { + endDrag(); + } else { + abortDrag(); + } +} + +void AbstractViewContentWidget::mouseMoveEvent(QMouseEvent* event) { + // camera controls as in Blender: + // - no modifier -> orbit + // - Shift -> pan + // - Ctrl -> zoom + + if (!dragInitialPos_) { + dragInitialPos_ = event->pos(); + } + + bool snap = event->modifiers() & Qt::ControlModifier; + + auto deltaPos = event->pos() - mouseLastPos_; + switch (dragMode_) { + case DragMode::CameraOrbit: + abstractScene_->cameraController().orbitCamera(deltaPos); + break; + case DragMode::CameraPan: + abstractScene_->cameraController().panCamera(deltaPos); + break; + case DragMode::CameraZoom: + abstractScene_->cameraController().zoomCameraMove(deltaPos); + break; + + case DragMode::Translate: + if (text_.empty()) { + transformationController_.dragTranslate(dragInitialPos_.value(), event->pos(), width(), height(), snap, abstractScene_->gridScale()); + } + break; + case DragMode::Scale: + if (text_.empty()) { + transformationController_.dragScale(dragInitialPos_.value(), event->pos(), width(), height(), snap); + } + break; + case DragMode::Rotate: + if (text_.empty()) { + transformationController_.dragRotate(dragInitialPos_.value(), event->pos(), width(), height(), snap); + } + break; + } + mouseLastPos_ = event->pos(); +} + +void AbstractViewContentWidget::wheelEvent(QWheelEvent* event) { + if (!event->angleDelta().isNull()) { + abstractScene_->cameraController().zoomCameraWheel(event->angleDelta()); + } +} + +void AbstractViewContentWidget::handlePickRequest(std::vector pickIds) { + auto [axis, element] = abstractScene_->getPickedGizmoElement(pickIds); + if (axis != -1) { + if (dragMode_ == DragMode::PickRequested) { + using GizmoMode = ramses_adaptor::AbstractSceneAdaptor::GizmoMode; + auto gizmoMode = abstractScene_->gizmoMode(); + if (gizmoMode == GizmoMode::Translate || gizmoMode == GizmoMode::Rotate || gizmoMode == GizmoMode::Scale) { + std::map modeMap = { + {GizmoMode::Translate, DragMode::Translate}, + {GizmoMode::Rotate, DragMode::Rotate}, + {GizmoMode::Scale, DragMode::Scale}}; + DragMode dragMode = modeMap[abstractScene_->gizmoMode()]; + switch (element) { + case ramses_adaptor::GizmoTriad::PickElement::Axis: + setupMode(treeDockManager_->getSelection(), dragMode); + setupTransformMode(TransformMode::Axis, static_cast(axis)); + break; + case ramses_adaptor::GizmoTriad::PickElement::Plane: + if (dragMode != DragMode::Rotate) { + setupMode(treeDockManager_->getSelection(), dragMode); + setupTransformMode(TransformMode::Plane, static_cast(axis)); + } + break; + case ramses_adaptor::GizmoTriad::PickElement::Central: + // Don't enable free scaling or rotation when picking central gizmo element since the mouse is too close to the origin + // and this would lead to erratic behaviour. + if (dragMode == DragMode::Translate) { + setupMode(treeDockManager_->getSelection(), dragMode); + } + break; + } + } + } + } else { + auto obj = abstractScene_->getPickedObject(pickIds.front()); + if (obj) { + Q_EMIT selectionRequested(QString::fromStdString(obj->objectID())); + } + } +} + +} // namespace raco::ramses_widgets \ No newline at end of file diff --git a/gui/libRamsesWidgets/src/AbstractViewMainWindow.cpp b/gui/libRamsesWidgets/src/AbstractViewMainWindow.cpp new file mode 100644 index 00000000..05d05c49 --- /dev/null +++ b/gui/libRamsesWidgets/src/AbstractViewMainWindow.cpp @@ -0,0 +1,175 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#include "ramses_widgets/AbstractViewMainWindow.h" + +#include "ramses_adaptor/AbstractSceneAdaptor.h" +#include "ramses_widgets/AbstractViewContentWidget.h" + +#include +#include +#include +#include +#include + +namespace raco::ramses_widgets { + +AbstractViewMainWindow::AbstractViewMainWindow(RendererBackend& rendererBackend, ramses_adaptor::AbstractSceneAdaptor* abstractScene, object_tree::view::ObjectTreeDockManager* objectTreeDockManager, core::CommandInterface *commandInterface, QWidget* parent) + : QMainWindow{parent}, + abstractScene_(abstractScene), + treeDockManager_(objectTreeDockManager) { + previewWidget_ = new AbstractViewContentWidget{rendererBackend, abstractScene, objectTreeDockManager, commandInterface}; + setCentralWidget(previewWidget_); + + auto toolBar = new QToolBar(this); + toolBar->setMovable(false); + addToolBar(Qt::TopToolBarArea, toolBar); + + auto statusBar = new QStatusBar(this); + setStatusBar(statusBar); + + auto modeLabel = new QLabel("Mode: ", statusBar); + statusBar->addWidget(modeLabel); + + QObject::connect(previewWidget_, &AbstractViewContentWidget::modeChanged, [modeLabel](const QString& description) { + modeLabel->setText(description); + }); + + auto scaleLabel = new QLabel{QString(fmt::format("scale: {}", abstractScene_->gridScale()).c_str()), statusBar}; + statusBar->addPermanentWidget(scaleLabel); + + QObject::connect(abstractScene, &ramses_adaptor::AbstractSceneAdaptor::scaleChanged, [scaleLabel](float newScale) { + scaleLabel->setText(QString(fmt::format("scale: {}", newScale).c_str())); + }); + + connect(previewWidget_, &AbstractViewContentWidget::selectionRequested, this, [this](const QString objectID) { + Q_EMIT selectionRequested(objectID, {}); + }); + + // TODO for whatever reason using an Qt::WidgetWithChildrenShortcut won't work. figure out why! + auto focusAction = toolBar->addAction("focus", [this]() { + auto objects = treeDockManager_->getSelection(); + if (objects.empty()) { + objects = abstractScene_->project().instances(); + } + focusCamera(objects); + }); + focusAction->setShortcut(QKeySequence("Ctrl+F")); + focusAction->setShortcutContext(Qt::ApplicationShortcut); + + auto resetAction = toolBar->addAction("reset", [this]() { + abstractScene_->cameraController().reset(); + }); + resetAction->setShortcut(QKeySequence("Ctrl+0")); + resetAction->setShortcutContext(Qt::ApplicationShortcut); + + { + auto menu = new QMenu(toolBar); + auto highlightGroup = new QActionGroup(this); + auto actionHighlightNone = menu->addAction("None"); + auto actionHighlightColor = menu->addAction("Color"); + auto actionHighlightTransparency = menu->addAction("Transparency"); + actionHighlightNone->setCheckable(true); + actionHighlightColor->setCheckable(true); + actionHighlightTransparency->setCheckable(true); + highlightGroup->addAction(actionHighlightNone); + highlightGroup->addAction(actionHighlightColor); + highlightGroup->addAction(actionHighlightTransparency); + actionHighlightNone->setChecked(true); + + QObject::connect(highlightGroup, &QActionGroup::triggered, [this, actionHighlightNone, actionHighlightColor](QAction* action) { + highlightMode_ = action == actionHighlightNone ? HighlightMode::None : (action == actionHighlightColor ? HighlightMode::Color : HighlightMode::Transparency); + updateHighlighted(); + }); + + auto button = new QToolButton(this); + button->setMenu(menu); + button->setPopupMode(QToolButton::InstantPopup); + button->setText("Highlight"); + toolBar->addWidget(button); + } + + { + auto menu = new QMenu(toolBar); + auto gizmoGroup = new QActionGroup(this); + auto actionGizmoLocator = menu->addAction("Select"); + auto actionGizmoTranslate = menu->addAction("Translate"); + auto actionGizmoRotate = menu->addAction("Rotate"); + auto actionGizmoScale = menu->addAction("Scale"); + actionGizmoLocator->setCheckable(true); + actionGizmoTranslate->setCheckable(true); + actionGizmoRotate->setCheckable(true); + actionGizmoScale->setCheckable(true); + gizmoGroup->addAction(actionGizmoLocator); + gizmoGroup->addAction(actionGizmoTranslate); + gizmoGroup->addAction(actionGizmoRotate); + gizmoGroup->addAction(actionGizmoScale); + actionGizmoLocator->setChecked(true); + + using GizmoMode = ramses_adaptor::AbstractSceneAdaptor::GizmoMode; + std::map modeMap = { + {actionGizmoLocator, GizmoMode::Locator}, + {actionGizmoTranslate, GizmoMode::Translate}, + {actionGizmoRotate, GizmoMode::Rotate}, + {actionGizmoScale, GizmoMode::Scale}}; + + QObject::connect(gizmoGroup, &QActionGroup::triggered, [this, modeMap](QAction* action) { + auto it = modeMap.find(action); + if (it != modeMap.end()) { + abstractScene_->setGizmoMode(it->second); + } + }); + + auto button = new QToolButton(this); + button->setMenu(menu); + button->setPopupMode(QToolButton::InstantPopup); + button->setText("Gizmo Mode"); + toolBar->addWidget(button); + } +} + +AbstractViewMainWindow::~AbstractViewMainWindow() { + delete previewWidget_; +} + +void AbstractViewMainWindow::focusCamera(const std::vector& objects) { + auto bbox = abstractScene_->getBoundingBox(objects); + if (!bbox.empty()) { + abstractScene_->cameraController().focus(bbox); + } +} + +void AbstractViewMainWindow::onSelectionChanged(const core::SEditorObjectSet& objects) { + updateHighlighted(); + abstractScene_->attachGizmo(treeDockManager_->getSelection()); +} + +void AbstractViewMainWindow::onSelectionCleared() { + updateHighlighted(); + abstractScene_->attachGizmo({}); +} + +void AbstractViewMainWindow::updateHighlighted() { + switch (highlightMode_) { + case HighlightMode::None: + abstractScene_->setHighlightedObjects({}); + abstractScene_->setHighlightUsingTransparency(false); + break; + case HighlightMode::Color: + abstractScene_->setHighlightedObjects(treeDockManager_->getSelection()); + abstractScene_->setHighlightUsingTransparency(false); + break; + case HighlightMode::Transparency: + abstractScene_->setHighlightedObjects(treeDockManager_->getSelection()); + abstractScene_->setHighlightUsingTransparency(true); + break; + } +} + +} // namespace raco::ramses_widgets diff --git a/gui/libRamsesWidgets/src/PreviewContentWidget.cpp b/gui/libRamsesWidgets/src/PreviewContentWidget.cpp index 6154f08e..ab43c40b 100644 --- a/gui/libRamsesWidgets/src/PreviewContentWidget.cpp +++ b/gui/libRamsesWidgets/src/PreviewContentWidget.cpp @@ -42,6 +42,10 @@ void PreviewContentWidget::setBackgroundColor(core::Vec4f backgroundColor) { } } +PreviewMultiSampleRate PreviewContentWidget::getMsaaSampleRate() { + return ramsesPreview_->nextState().sampleRate; +} + void PreviewContentWidget::setMsaaSampleRate(PreviewMultiSampleRate sampleRate) { if (ramsesPreview_) { ramsesPreview_->nextState().sampleRate = sampleRate; diff --git a/gui/libRamsesWidgets/src/PreviewFramebufferScene.cpp b/gui/libRamsesWidgets/src/PreviewFramebufferScene.cpp index b1335fa7..0a8d8ed2 100644 --- a/gui/libRamsesWidgets/src/PreviewFramebufferScene.cpp +++ b/gui/libRamsesWidgets/src/PreviewFramebufferScene.cpp @@ -20,10 +20,10 @@ PreviewFramebufferScene::PreviewFramebufferScene( ramses::RamsesClient& client, ramses::sceneId_t sceneId) : scene_{ramsesScene(sceneId, &client)}, - camera_{ramsesOrthographicCamera(scene_.get())}, - renderGroup_{std::shared_ptr(scene_.get()->createRenderGroup(), raco::ramses_base::createRamsesObjectDeleter(scene_.get()))}, - renderPass_{scene_->createRenderPass(), raco::ramses_base::createRamsesObjectDeleter(scene_.get())} { - (*camera_)->setTranslation(0, 0, 10.0f); + camera_{ramsesOrthographicCamera(scene_.get(), {0, 0})}, + renderGroup_{std::shared_ptr(scene_.get()->createRenderGroup(), ramses_base::createRamsesObjectDeleter(scene_.get()))}, + renderPass_{scene_->createRenderPass(), ramses_base::createRamsesObjectDeleter(scene_.get())} { + (*camera_)->setTranslation({0, 0, 10.0f}); (*camera_)->setFrustum(-1.0f, 1.0f, -1.0f, 1.0f, 0.1f, 100.0f); // we need to have an inital viewport (*camera_)->setViewport(0, 0, 1, 1); @@ -33,7 +33,7 @@ PreviewFramebufferScene::PreviewFramebufferScene( // Ramses ignores the clear flags/clear color because we are rendering to the default framebuffer. // Still: apply some sensible default here. We expect every pixel to be covered by the blit operation // so disable clearing the buffers. - renderPass_->setClearFlags(ramses::EClearFlags_None); + renderPass_->setClearFlags(ramses::EClearFlag::None); static const std::string vertexShader = "#version 310 es\n\ @@ -87,74 +87,65 @@ PreviewFramebufferScene::PreviewFramebufferScene( effectDescription.setVertexShader(vertexShader.c_str()); effectDescription.setFragmentShader(fragmentShader.c_str()); effectDescription.setUniformSemantic("mvpMatrix", ramses::EEffectUniformSemantic::ModelViewProjectionMatrix); - effect_ = ramsesEffect(scene_.get(), effectDescription); - appearance_ = ramsesAppearance(scene_.get(), effect_); + effect_ = ramsesEffect(scene_.get(), effectDescription, {}, {0, 0}); + appearance_ = ramsesAppearance(scene_.get(), effect_, {0, 0}); ramses::EffectDescription effectDescriptionMS{}; effectDescriptionMS.setVertexShader(vertexShader.c_str()); effectDescriptionMS.setFragmentShader(fragmentShaderMS.c_str()); effectDescriptionMS.setUniformSemantic("mvpMatrix", ramses::EEffectUniformSemantic::ModelViewProjectionMatrix); - effectMS_ = ramsesEffect(scene_.get(), effectDescriptionMS); - appearanceMS_ = ramsesAppearance(scene_.get(), effectMS_); + effectMS_ = ramsesEffect(scene_.get(), effectDescriptionMS, {}, {0, 0}); + appearanceMS_ = ramsesAppearance(scene_.get(), effectMS_, {0, 0}); // buffers - static std::vector vertex_data = { - 0.0f, 0.0f, 0.f, - 0.0f, 1.0f, 0.f, - 1.0f, 0.0f, 0.f, - 1.0f, 1.0f, 0.f}; - static std::vector uv_data = { - 0.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, - 1.0f, 1.0f}; + static std::vector vertex_data = { + {0.0f, 0.0f, 0.f}, + {0.0f, 1.0f, 0.f}, + {1.0f, 0.0f, 0.f}, + {1.0f, 1.0f, 0.f}}; + static std::vector uv_data = { + {0.0f, 0.0f}, + {0.0f, 1.0f}, + {1.0f, 0.0f}, + {1.0f, 1.0f}}; static std::vector index_data = { 0, 2, 1, 1, 2, 3}; - const uint32_t indexSize = static_cast(sizeof(uint32_t) * index_data.size()); - indexDataBuffer_ = ramsesArrayResource(scene_.get(), ramses::EDataType::UInt32, indexSize, index_data.data()); - - const uint32_t vertexSize = static_cast(sizeof(float) * vertex_data.size()); - vertexDataBuffer_ = ramsesArrayResource(scene_.get(), ramses::EDataType::Vector3F, vertexSize, vertex_data.data()); - - const uint32_t uvSize = static_cast(sizeof(float) * uv_data.size()); - uvDataBuffer_ = ramsesArrayResource(scene_.get(), ramses::EDataType::Vector2F, uvSize, uv_data.data()); + indexDataBuffer_ = ramsesArrayResource(scene_.get(), index_data); + vertexDataBuffer_ = ramsesArrayResource(scene_.get(), vertex_data); + uvDataBuffer_ = ramsesArrayResource(scene_.get(), uv_data); { - geometryBinding_ = ramsesGeometryBinding(scene_.get(), effect_); - (*geometryBinding_)->setIndices(*indexDataBuffer_.get()); + geometry_ = ramsesGeometry(scene_.get(), effect_, {0, 0}); + (*geometry_)->setIndices(*indexDataBuffer_.get()); - ramses::AttributeInput vertexInput; - effect_->findAttributeInput("a_Position", vertexInput); - (*geometryBinding_)->setInputBuffer(vertexInput, *vertexDataBuffer_.get()); + ramses::AttributeInput vertexInput = effect_->findAttributeInput("a_Position").value(); + (*geometry_)->setInputBuffer(vertexInput, *vertexDataBuffer_.get()); - ramses::AttributeInput uvInput; - effect_->findAttributeInput("a_TextureCoordinate", uvInput); - (*geometryBinding_)->setInputBuffer(uvInput, *uvDataBuffer_.get()); + ramses::AttributeInput uvInput = effect_->findAttributeInput("a_TextureCoordinate").value(); + (*geometry_)->setInputBuffer(uvInput, *uvDataBuffer_.get()); } { - geometryBindingMS_ = ramsesGeometryBinding(scene_.get(), effectMS_); - (*geometryBindingMS_)->setIndices(*indexDataBuffer_.get()); + geometryMS_ = ramsesGeometry(scene_.get(), effectMS_, {0, 0}); + (*geometryMS_)->setIndices(*indexDataBuffer_.get()); - ramses::AttributeInput vertexInput; - effectMS_->findAttributeInput("a_Position", vertexInput); - (*geometryBindingMS_)->setInputBuffer(vertexInput, *vertexDataBuffer_.get()); + ramses::AttributeInput vertexInput = effectMS_->findAttributeInput("a_Position").value(); + (*geometryMS_)->setInputBuffer(vertexInput, *vertexDataBuffer_.get()); - ramses::AttributeInput uvInput; - effectMS_->findAttributeInput("a_TextureCoordinate", uvInput); - (*geometryBindingMS_)->setInputBuffer(uvInput, *uvDataBuffer_.get()); + ramses::AttributeInput uvInput = effectMS_->findAttributeInput("a_TextureCoordinate").value(); + (*geometryMS_)->setInputBuffer(uvInput, *uvDataBuffer_.get()); } - meshNode_ = ramsesMeshNode(scene_.get()); - meshNode_->setGeometryBinding(geometryBinding_); + meshNode_ = ramsesMeshNode(scene_.get(), {0, 0}); + meshNode_->setGeometry(geometry_); meshNode_->setAppearance(appearance_); renderGroup_->addMeshNode(**meshNode_); scene_->flush(); - scene_->publish(); + scene_->publish(ramses::EScenePublicationMode::LocalAndRemote); } void PreviewFramebufferScene::setViewport(const QPoint& viewportPosition, const QSize& viewportSize, const QSize& virtualSize) { @@ -176,9 +167,9 @@ ramses::sceneId_t PreviewFramebufferScene::getSceneId() const { } ramses::dataConsumerId_t PreviewFramebufferScene::setupFramebufferTexture(RendererBackend& backend, const QSize& size, PreviewFilteringMode filteringMode, PreviewMultiSampleRate sampleRate) { - ramses::ETextureSamplingMethod samplingMethod = ramses::ETextureSamplingMethod_Nearest; + ramses::ETextureSamplingMethod samplingMethod = ramses::ETextureSamplingMethod::Nearest; if (filteringMode == PreviewFilteringMode::Linear) { - samplingMethod = ramses::ETextureSamplingMethod_Linear; + samplingMethod = ramses::ETextureSamplingMethod::Linear; } if (currentSampleCount_ == sampleRate) { @@ -198,20 +189,18 @@ ramses::dataConsumerId_t PreviewFramebufferScene::setupFramebufferTexture(Render framebufferTexture_.reset(); sampler_.reset(); - renderbufferMS_ = ramsesRenderBuffer(scene_.get(), size.width(), size.height(), ramses::ERenderBufferType_Color, ramses::ERenderBufferFormat_RGBA8, ramses::ERenderBufferAccessMode_ReadWrite, sampleRate); + renderbufferMS_ = ramsesRenderBuffer(scene_.get(), size.width(), size.height(), ramses::ERenderBufferFormat::RGBA8, ramses::ERenderBufferAccessMode::ReadWrite, sampleRate, {}, {0, 0}); - samplerMS_ = ramsesTextureSamplerMS(scene_.get(), renderbufferMS_); + samplerMS_ = ramsesTextureSamplerMS(scene_.get(), renderbufferMS_, {}, {0, 0}); - ramses::UniformInput texUniformInput; - (*appearanceMS_)->getEffect().findUniformInput("uTex0", texUniformInput); + ramses::UniformInput texUniformInput = (*appearanceMS_)->getEffect().findUniformInput("uTex0").value(); (*appearanceMS_)->setInputTexture(texUniformInput, *samplerMS_.get()); - ramses::UniformInput sampleRateUniformInput; - (*appearanceMS_)->getEffect().findUniformInput("sampleCount", sampleRateUniformInput); - (*appearanceMS_)->setInputValueInt32(sampleRateUniformInput, sampleRate); + ramses::UniformInput sampleRateUniformInput = (*appearanceMS_)->getEffect().findUniformInput("sampleCount").value(); + (*appearanceMS_)->setInputValue(sampleRateUniformInput, static_cast(sampleRate)); meshNode_->removeAppearanceAndGeometry(); - meshNode_->setGeometryBinding(geometryBindingMS_); + meshNode_->setGeometry(geometryMS_); meshNode_->setAppearance(appearanceMS_); } else { renderbufferMS_.reset(); @@ -219,19 +208,19 @@ ramses::dataConsumerId_t PreviewFramebufferScene::setupFramebufferTexture(Render std::vector data(4 * size.width() * size.height(), 0); - ramses::MipLevelData mipData(static_cast(data.size()), data.data()); + std::vector mipDatas; + mipDatas.emplace_back(reinterpret_cast(data.data()), reinterpret_cast(data.data()) + data.size()); const ramses::TextureSwizzle textureSwizzle{}; - framebufferTexture_ = ramsesTexture2D(scene_.get(), ramses::ETextureFormat::RGBA8, size.width(), size.height(), 1, &mipData, false, textureSwizzle, ramses::ResourceCacheFlag_DoNotCache, "framebuffer texture"); + framebufferTexture_ = ramsesTexture2D(scene_.get(), ramses::ETextureFormat::RGBA8, size.width(), size.height(), mipDatas, false, textureSwizzle, "framebuffer texture", {0, 0}); - sampler_ = ramsesTextureSampler(scene_.get(), ramses::ETextureAddressMode_Clamp, ramses::ETextureAddressMode_Clamp, samplingMethod, samplingMethod, framebufferTexture_.get(), 1, "framebuffer sampler"); + sampler_ = ramsesTextureSampler(scene_.get(), ramses::ETextureAddressMode::Clamp, ramses::ETextureAddressMode::Clamp, samplingMethod, samplingMethod, framebufferTexture_.get(), 1, "framebuffer sampler", {0, 0}); - ramses::UniformInput texUniformInput; - (*appearance_)->getEffect().findUniformInput("uTex0", texUniformInput); + ramses::UniformInput texUniformInput = (*appearance_)->getEffect().findUniformInput("uTex0").value(); (*appearance_)->setInputTexture(texUniformInput, *sampler_.get()); meshNode_->removeAppearanceAndGeometry(); - meshNode_->setGeometryBinding(geometryBinding_); + meshNode_->setGeometry(geometry_); meshNode_->setAppearance(appearance_); } currentSampleCount_ = sampleRate; diff --git a/gui/libRamsesWidgets/src/PreviewMainWindow.cpp b/gui/libRamsesWidgets/src/PreviewMainWindow.cpp index c96abb5e..e46c1546 100644 --- a/gui/libRamsesWidgets/src/PreviewMainWindow.cpp +++ b/gui/libRamsesWidgets/src/PreviewMainWindow.cpp @@ -22,15 +22,14 @@ #include #include #include -#include #include #include namespace raco::ramses_widgets { -PreviewMainWindow::PreviewMainWindow(RendererBackend& rendererBackend, raco::ramses_adaptor::SceneBackend* sceneBackend, const QSize& sceneSize, raco::core::Project* project, - raco::components::SDataChangeDispatcher dispatcher, QWidget* parent) +PreviewMainWindow::PreviewMainWindow(RendererBackend& rendererBackend, ramses_adaptor::SceneBackend* sceneBackend, const QSize& sceneSize, core::Project* project, + components::SDataChangeDispatcher dispatcher, QWidget* parent) : QMainWindow{parent}, ui_{new Ui::PreviewMainWindow()}, project_(project) { @@ -116,6 +115,7 @@ PreviewMainWindow::PreviewMainWindow(RendererBackend& rendererBackend, raco::ram }); ui_->toolBar->insertWidget(ui_->actionSelectSizeMode, sizeMenuButton); } + // MSAA button { auto* msaaMenu = new QMenu{ui_->toolBar}; @@ -146,39 +146,50 @@ PreviewMainWindow::PreviewMainWindow(RendererBackend& rendererBackend, raco::ram connect(ui_->actionSetMSAAx0, &QAction::triggered, this, [this, msaaMenuButton, updateMsaaSelection]() { previewWidget_->setMsaaSampleRate(PreviewMultiSampleRate::MSAA_0X); updateMsaaSelection(ui_->actionSetMSAAx0); + ui_->screenshotButton->setEnabled(true); }); connect(ui_->actionSetMSAAx2, &QAction::triggered, this, [this, msaaMenuButton, updateMsaaSelection]() { previewWidget_->setMsaaSampleRate(PreviewMultiSampleRate::MSAA_2X); updateMsaaSelection(ui_->actionSetMSAAx2); + ui_->screenshotButton->setEnabled(false); }); connect(ui_->actionSetMSAAx4, &QAction::triggered, this, [this, msaaMenuButton, updateMsaaSelection]() { previewWidget_->setMsaaSampleRate(PreviewMultiSampleRate::MSAA_4X); updateMsaaSelection(ui_->actionSetMSAAx4); + ui_->screenshotButton->setEnabled(false); }); connect(ui_->actionSetMSAAx8, &QAction::triggered, this, [this, msaaMenuButton, updateMsaaSelection]() { previewWidget_->setMsaaSampleRate(PreviewMultiSampleRate::MSAA_8X); updateMsaaSelection(ui_->actionSetMSAAx8); + ui_->screenshotButton->setEnabled(false); }); ui_->toolBar->insertWidget(ui_->actionSelectSizeMode, msaaMenuButton); } // Screenshot button - { - auto* screenshotButton = new QPushButton{}; - screenshotButton->setIcon(style::Icons::instance().screenshot); - screenshotButton->setToolTip("Save Screenshot"); + ui_->screenshotButton->setIcon(style::Icons::instance().screenshot); + ui_->screenshotButton->setToolTip("Save Screenshot (F12)"); + connect(ui_->screenshotButton, &QPushButton::clicked, [this]() { + saveScreenshot(); + }); + // Refresh button + ui_->refreshButton->setIcon(style::Icons::instance().refresh); + ui_->refreshButton->setToolTip("Refresh"); + connect(ui_->refreshButton, &QPushButton::clicked, [this]() { + previewWidget_->commit(true); + }); + + // Buttons layout + { auto* stretchedWidget = new QWidget(ui_->toolBar); auto* layout = new QHBoxLayout(stretchedWidget); layout->setContentsMargins(0, 0, 0, 0); layout->addStretch(); - layout->addWidget(screenshotButton); + layout->addWidget(ui_->screenshotButton); + layout->addWidget(ui_->refreshButton); stretchedWidget->setLayout(layout); ui_->toolBar->addWidget(stretchedWidget); - - connect(screenshotButton, &QPushButton::clicked, [this]() { - saveScreenshot(); - }); } } @@ -203,6 +214,11 @@ void PreviewMainWindow::commit(bool forceUpdate) { } void PreviewMainWindow::saveScreenshot() { + if (previewWidget_->getMsaaSampleRate() > MSAA_0X) { + QMessageBox::warning(this, "Could not save the screenshot", "Screenshots are only possible for non-MSAA buffers!", QMessageBox::Ok); + return; + } + const auto screenshotDir = components::RaCoPreferences::instance().screenshotDirectory.toStdString(); if (screenshotDir.empty()) { QMessageBox::warning(this, "Could not save the screenshot", "Please make sure that the directory specified in \"File > Preferences > Screenshot Directory\" is not empty.", QMessageBox::Ok); @@ -224,6 +240,11 @@ void PreviewMainWindow::saveScreenshot() { } void PreviewMainWindow::saveScreenshot(const std::string& fullPath) { + if (previewWidget_->getMsaaSampleRate() > MSAA_0X) { + throw std::runtime_error{"Could not save screenshot to \"" + fullPath + "\". Screenshots are only possible for non-MSAA buffers!"}; + return; + } + const auto saved = previewWidget_->saveScreenshot(fullPath); if (!saved) { throw std::runtime_error {"Could not save screenshot to \"" + fullPath + "\". Please make sure that the path specified is correct and accessable."}; diff --git a/gui/libRamsesWidgets/src/PreviewMainWindow.ui b/gui/libRamsesWidgets/src/PreviewMainWindow.ui index c43bd064..8ec085ed 100644 --- a/gui/libRamsesWidgets/src/PreviewMainWindow.ui +++ b/gui/libRamsesWidgets/src/PreviewMainWindow.ui @@ -13,7 +13,12 @@ Qt::NoContextMenu - + + + + + + Qt::NoContextMenu diff --git a/gui/libRamsesWidgets/src/PreviewScrollAreaWidget.cpp b/gui/libRamsesWidgets/src/PreviewScrollAreaWidget.cpp index 1cfde3ec..a465a19e 100644 --- a/gui/libRamsesWidgets/src/PreviewScrollAreaWidget.cpp +++ b/gui/libRamsesWidgets/src/PreviewScrollAreaWidget.cpp @@ -64,9 +64,10 @@ void PreviewScrollAreaWidget::resizeEvent(QResizeEvent* /*event*/) { std::optional PreviewScrollAreaWidget::globalPositionToPreviewPosition(const QPoint& p) { auto localPosition = viewport()->mapFromGlobal(p); + auto devicePixelScaleFactor = window()->screen()->devicePixelRatio(); auto result = QPoint{ - static_cast((horizontalScrollBar()->value() + localPosition.x() - std::max(0, viewportPosition_.x())) / scaleValue_), - static_cast(sceneSize_.height() - ((verticalScrollBar()->value() + localPosition.y() - std::max(0, viewportPosition_.y())) / scaleValue_))}; + static_cast(devicePixelScaleFactor * (horizontalScrollBar()->value() + localPosition.x() - std::max(0, viewportPosition_.x())) / scaleValue_), + static_cast(sceneSize_.height() - devicePixelScaleFactor * (verticalScrollBar()->value() + localPosition.y() - std::max(0, viewportPosition_.y())) / scaleValue_)}; if (result.x() >= 0 && result.y() >= 0 && result.x() < sceneSize_.width() && result.y() < sceneSize_.height()) { return result; } else { diff --git a/gui/libRamsesWidgets/src/RamsesAbstractViewWindow.cpp b/gui/libRamsesWidgets/src/RamsesAbstractViewWindow.cpp new file mode 100644 index 00000000..f5f78171 --- /dev/null +++ b/gui/libRamsesWidgets/src/RamsesAbstractViewWindow.cpp @@ -0,0 +1,129 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#include "ramses_widgets/RamsesAbstractViewWindow.h" + +#include "ramses_widgets/SceneStateEventHandler.h" + +#include +#include + +#include "style/Colors.h" + +namespace { + +using namespace raco::ramses_widgets; + +void setAndWaitSceneState( + RendererBackend& backend, + const ramses::RendererSceneState state, + const ramses::sceneId_t sceneId) { + auto& sceneControlAPI = *backend.renderer().getSceneControlAPI(); + + if (sceneId.isValid()) { + auto status = sceneControlAPI.setSceneState(sceneId, state); + if (sceneControlAPI.flush()) { + backend.eventHandler().waitForSceneState(sceneId, state); + } + } +} + +/** + * Sets and await's current scene state for frambuffer and conditionally for scene. The scene state is only set if the current scene state is greater than the request scene state. + */ +void reduceAndWaitSceneState( + RendererBackend& backend, + const ramses::RendererSceneState state, + const ramses::sceneId_t sceneId) { + auto& eventHandler = backend.eventHandler(); + auto& sceneControlAPI = *backend.renderer().getSceneControlAPI(); + + bool scene_success = false; + + if (sceneId.isValid() && eventHandler.sceneState(sceneId) > state) { + auto status = sceneControlAPI.setSceneState(sceneId, state); + if (sceneControlAPI.flush()) { + // Wait for a state that is <= the desired state: + // Apparently the renderer may already be in a lower state but the event handler hasn't caught up with the state yet which + // leads to the scene state comparison above being true which triggers a setSceneState which then has no effect since the + // real state is already lower than the set state which leads to no callback being invoked which leads to waiting forever + // of using an exact scene state comparison. + backend.eventHandler().waitForSceneState(sceneId, state, SceneStateEventHandler::ECompareFunc::LessEqual); + } + } +} + +} // namespace + +namespace raco::ramses_widgets { + +RamsesAbstractViewWindow::RamsesAbstractViewWindow(void* windowHandle, RendererBackend& rendererBackend) + : windowHandle_{windowHandle}, rendererBackend_{rendererBackend}, displayId_{ramses::displayId_t::Invalid()} { +} + +RamsesAbstractViewWindow::~RamsesAbstractViewWindow() { + reset(); +} + +void RamsesAbstractViewWindow::reset() { + reduceAndWaitSceneState(rendererBackend_, ramses::RendererSceneState::Available, current_.sceneId); + if (displayId_.isValid()) { + rendererBackend_.renderer().destroyDisplay(displayId_); + rendererBackend_.renderer().flush(); + rendererBackend_.eventHandler().waitForDisplayDestruction(displayId_); + displayId_ = ramses::displayId_t::Invalid(); + current_ = State{}; + } +} + +const RamsesAbstractViewWindow::State& RamsesAbstractViewWindow::currentState() { + return current_; +} + +RamsesAbstractViewWindow::State& RamsesAbstractViewWindow::nextState() { + return next_; +} + +void RamsesAbstractViewWindow::commit(bool forceUpdate) { + if (forceUpdate || !displayId_.isValid() || next_ != current_) { + // Unload current scenes + reset(); + + auto& sceneControlAPI = *rendererBackend_.renderer().getSceneControlAPI(); + + if (!displayId_.isValid()) { + ramses::DisplayConfig displayConfig = {}; + auto backgroundColor = style::Colors::color(style::Colormap::abstractSceneViewBackground); + displayConfig.setWindowRectangle(0, 0, next_.viewportSize.width(), next_.viewportSize.height()); + displayConfig.setClearColor({backgroundColor.redF(), backgroundColor.greenF(), backgroundColor.blueF(), backgroundColor.alphaF()}); + displayConfig.setWindowIviVisible(); + if constexpr (!BuildOptions::nativeRamsesDisplayWindow) { +#if (defined(__WIN32) || defined(_WIN32)) + displayConfig.setWindowsWindowHandle(windowHandle_); +#else + displayConfig.setX11WindowHandle(ramses::X11WindowHandle(reinterpret_cast(windowHandle_))); +#endif + } + displayId_ = rendererBackend_.renderer().createDisplay(displayConfig); + rendererBackend_.renderer().flush(); + rendererBackend_.eventHandler().waitForDisplayCreation(displayId_); + + if (next_.sceneId.isValid()) { + /// @todo maybe we need to reset old scene mapping? + sceneControlAPI.setSceneMapping(next_.sceneId, displayId_); + sceneControlAPI.flush(); + setAndWaitSceneState(rendererBackend_, ramses::RendererSceneState::Rendered, next_.sceneId); + } + + current_ = next_; + } + } +} + +} // namespace raco::ramses_widgets diff --git a/gui/libRamsesWidgets/src/RamsesPreviewWindow.cpp b/gui/libRamsesWidgets/src/RamsesPreviewWindow.cpp index 3325ccaa..3898e5aa 100644 --- a/gui/libRamsesWidgets/src/RamsesPreviewWindow.cpp +++ b/gui/libRamsesWidgets/src/RamsesPreviewWindow.cpp @@ -13,8 +13,8 @@ #include -#include -#include +#include +#include #include using raco::log_system::PREVIEW_WIDGET; @@ -26,22 +26,32 @@ using namespace raco::ramses_widgets; void setAndWaitSceneState( RendererBackend& backend, const ramses::RendererSceneState state, - const std::unique_ptr& framebufferScene, + const std::unique_ptr& framebufferScene, const ramses::sceneId_t sceneId) { + auto& sceneControlAPI = *backend.renderer().getSceneControlAPI(); + + bool fb_success = false; + bool scene_success = false; + if (framebufferScene && framebufferScene->getSceneId().isValid()) { - sceneControlAPI.setSceneState(framebufferScene->getSceneId(), state); + // If a setSceneState call fails, no callback is invoked! + if (sceneControlAPI.setSceneState(framebufferScene->getSceneId(), state)) { + fb_success = true; + } } if (sceneId.isValid()) { - sceneControlAPI.setSceneState(sceneId, state); + if (sceneControlAPI.setSceneState(sceneId, state)) { + scene_success = true; + } } sceneControlAPI.flush(); - if (framebufferScene && framebufferScene->getSceneId().isValid()) { + if (fb_success) { backend.eventHandler().waitForSceneState(framebufferScene->getSceneId(), state); } - if (sceneId.isValid()) { + if (scene_success) { backend.eventHandler().waitForSceneState(sceneId, state); } } @@ -52,24 +62,38 @@ void setAndWaitSceneState( void reduceAndWaitSceneState( RendererBackend& backend, const ramses::RendererSceneState state, - const std::unique_ptr& framebufferScene, + const std::unique_ptr& framebufferScene, const ramses::sceneId_t sceneId) { + auto& eventHandler = backend.eventHandler(); auto& sceneControlAPI = *backend.renderer().getSceneControlAPI(); + + bool fb_success = false; + bool scene_success = false; + if (framebufferScene && framebufferScene->getSceneId().isValid() && eventHandler.sceneState(framebufferScene->getSceneId()) > state) { - sceneControlAPI.setSceneState(framebufferScene->getSceneId(), state); + if (sceneControlAPI.setSceneState(framebufferScene->getSceneId(), state)) { + fb_success = true; + } } if (sceneId.isValid() && eventHandler.sceneState(sceneId) > state) { - sceneControlAPI.setSceneState(sceneId, state); + if (sceneControlAPI.setSceneState(sceneId, state)) { + scene_success = true; + } } sceneControlAPI.flush(); - if (framebufferScene && framebufferScene->getSceneId().isValid()) { - backend.eventHandler().waitForSceneState(framebufferScene->getSceneId(), state); + // Wait for a state that is <= the desired state: + // Apparently the renderer may already be in a lower state but the event handler hasn't caught up with the state yet which + // leads to the scene state comparison above being true which triggers a setSceneState which then has no effect since the + // real state is already lower than the set state which leads to no callback being invoked which leads to waiting forever + // of using an exact scene state comparison. + if (fb_success) { + backend.eventHandler().waitForSceneState(framebufferScene->getSceneId(), state, SceneStateEventHandler::ECompareFunc::LessEqual); } - if (sceneId.isValid() && eventHandler.sceneState(sceneId) > state) { - backend.eventHandler().waitForSceneState(sceneId, state); + if (scene_success) { + backend.eventHandler().waitForSceneState(sceneId, state, SceneStateEventHandler::ECompareFunc::LessEqual); } } @@ -80,11 +104,11 @@ namespace raco::ramses_widgets { RamsesPreviewWindow::RamsesPreviewWindow( void* windowHandle, RendererBackend& rendererBackend) - : windowHandle_{windowHandle}, rendererBackend_{rendererBackend}, displayId_{ramses::displayId_t::Invalid()}, offscreenBufferId_{ramses::displayBufferId_t::Invalid()}, framebufferScene_{std::make_unique(rendererBackend_.client(), rendererBackend.internalSceneId())} { + : windowHandle_{windowHandle}, rendererBackend_{rendererBackend}, displayId_{ramses::displayId_t::Invalid()}, offscreenBufferId_{ramses::displayBufferId_t::Invalid()}, framebufferScene_{std::make_unique(rendererBackend_.client(), rendererBackend.internalSceneId())} { } RamsesPreviewWindow::~RamsesPreviewWindow() { - setAndWaitSceneState(rendererBackend_, ramses::RendererSceneState::Available, framebufferScene_, current_.sceneId); + reduceAndWaitSceneState(rendererBackend_, ramses::RendererSceneState::Available, framebufferScene_, current_.sceneId); if (offscreenBufferId_.isValid()) { rendererBackend_.renderer().destroyOffscreenBuffer(displayId_, offscreenBufferId_); rendererBackend_.renderer().flush(); @@ -121,7 +145,7 @@ RamsesPreviewWindow::State& RamsesPreviewWindow::nextState() { void RamsesPreviewWindow::commit(bool forceUpdate) { if (forceUpdate || !displayId_.isValid() || next_.viewportSize != current_.viewportSize || next_.sceneId != current_.sceneId || next_.targetSize != current_.targetSize || next_.sampleRate != current_.sampleRate || next_.filteringMode != current_.filteringMode) { // Unload current scenes - reduceAndWaitSceneState(rendererBackend_, (displayId_.isValid()) ? ramses::RendererSceneState::Available : ramses::RendererSceneState::Unavailable, framebufferScene_, current_.sceneId); + reduceAndWaitSceneState(rendererBackend_, ramses::RendererSceneState::Available, framebufferScene_, current_.sceneId); if (next_.viewportSize.width() > 0 && next_.viewportSize.height() > 0 || next_.sampleRate != current_.sampleRate || next_.filteringMode != current_.filteringMode) { auto& sceneControlAPI = *rendererBackend_.renderer().getSceneControlAPI(); @@ -132,18 +156,14 @@ void RamsesPreviewWindow::commit(bool forceUpdate) { constexpr auto displayX = 100; constexpr auto displayY = 100; displayConfig.setWindowRectangle(displayX, displayY, next_.viewportSize.width(), next_.viewportSize.height()); - constexpr auto clearColorR = 0.25; - constexpr auto clearColorG = 0.25; - constexpr auto clearColorB = 0.25; - constexpr auto clearColorA = 1.0; - displayConfig.setClearColor(clearColorR, clearColorG, clearColorB, clearColorA); - displayConfig.setIntegrityRGLDeviceUnit(0); + glm::vec4 clearColor{0.25, 0.25, 0.25, 1.0}; + displayConfig.setClearColor(clearColor); displayConfig.setWindowIviVisible(); if constexpr (!BuildOptions::nativeRamsesDisplayWindow) { #if (defined(__WIN32) || defined(_WIN32)) displayConfig.setWindowsWindowHandle(windowHandle_); #else - displayConfig.setX11WindowHandle((unsigned long)windowHandle_); + displayConfig.setX11WindowHandle(ramses::X11WindowHandle(reinterpret_cast(windowHandle_))); #endif } displayId_ = rendererBackend_.renderer().createDisplay(displayConfig); @@ -168,8 +188,7 @@ void RamsesPreviewWindow::commit(bool forceUpdate) { // the framebuffer - that we use it later on to blit it into our preview makes for the Ramses scene no difference). const ramses::dataConsumerId_t dataConsumerId = framebufferScene_->setupFramebufferTexture(rendererBackend_, next_.targetSize, next_.filteringMode, next_.sampleRate); offscreenBufferId_ = rendererBackend_.renderer().createOffscreenBuffer(displayId_, next_.targetSize.width(), next_.targetSize.height(), next_.sampleRate); - rendererBackend_.renderer().setDisplayBufferClearColor(displayId_, offscreenBufferId_, next_.backgroundColor.redF(), next_.backgroundColor.greenF(), - next_.backgroundColor.blueF(), next_.backgroundColor.alphaF()); + rendererBackend_.renderer().setDisplayBufferClearColor(displayId_, offscreenBufferId_, {next_.backgroundColor.redF(), next_.backgroundColor.greenF(), next_.backgroundColor.blueF(), next_.backgroundColor.alphaF()}); rendererBackend_.renderer().flush(); rendererBackend_.eventHandler().waitForOffscreenBufferCreation(offscreenBufferId_); current_.targetSize = next_.targetSize; @@ -191,7 +210,7 @@ void RamsesPreviewWindow::commit(bool forceUpdate) { } if (displayId_.isValid() && offscreenBufferId_.isValid() && (forceUpdate || next_.backgroundColor != current_.backgroundColor)) { - rendererBackend_.renderer().setDisplayBufferClearColor(displayId_, offscreenBufferId_, next_.backgroundColor.redF(), next_.backgroundColor.greenF(), next_.backgroundColor.blueF(), next_.backgroundColor.alphaF()); + rendererBackend_.renderer().setDisplayBufferClearColor(displayId_, offscreenBufferId_, {next_.backgroundColor.redF(), next_.backgroundColor.greenF(), next_.backgroundColor.blueF(), next_.backgroundColor.alphaF()}); rendererBackend_.renderer().flush(); current_.backgroundColor = next_.backgroundColor; } diff --git a/gui/libRamsesWidgets/src/RendererBackend.cpp b/gui/libRamsesWidgets/src/RendererBackend.cpp index c834a897..4149ce1f 100644 --- a/gui/libRamsesWidgets/src/RendererBackend.cpp +++ b/gui/libRamsesWidgets/src/RendererBackend.cpp @@ -15,38 +15,25 @@ namespace raco::ramses_widgets { -ramses::RamsesFrameworkConfig& RendererBackend::ramsesFrameworkConfig(const std::string& frameworkArgs) noexcept { - if (frameworkArgs.empty()) { - char const* argv[] = {"RamsesComposer.exe", - "--log-level-contexts-filter", "trace:RAPI,off:RPER,debug:RRND,off:RFRA,off:RDSM,info:RCOM", - "--log-level-console", "warn", - "--log-level-dlt", "warn", - "--disablePeriodicLogs"}; - static ramses::RamsesFrameworkConfig config(sizeof(argv) / sizeof(argv[0]), argv); - return config; - } else { - std::istringstream is(frameworkArgs); - // Vector to store tokens - std::vector args{"RamsesComposer.exe"}; - const std::vector tokens = std::vector(std::istream_iterator(is), std::istream_iterator()); - for (const auto& token : tokens) args.push_back(token.c_str()); - static ramses::RamsesFrameworkConfig config(static_cast(args.size()), args.data()); - return config; - } +RendererBackend::RendererBackend(const ramses::RamsesFrameworkConfig& frameworkConfig) + : BaseEngineBackend{frameworkConfig} { } -RendererBackend::RendererBackend(rlogic::EFeatureLevel featureLevel, const std::string& frameworkArgs) - : BaseEngineBackend{featureLevel, ramsesFrameworkConfig(frameworkArgs)}, - renderer_{framework().createRenderer(ramses::RendererConfig{}), [=](ramses::RamsesRenderer* c) { framework().destroyRenderer(*c); }}, - eventHandler_{std::make_unique(*renderer_.get())} { - // Connect needs to be called after the renderer is created - // Additonally there can only be one renderer per framework - BaseEngineBackend::connect(); - renderer_->setSkippingOfUnmodifiedBuffers(false); +RendererBackend::~RendererBackend() { } -RendererBackend::~RendererBackend() { - framework().disconnect(); +void RendererBackend::reset() { + renderer_.reset(); + eventHandler_.reset(); + BaseEngineBackend::reset(); +} + +void RendererBackend::setup(ramses::EFeatureLevel featureLevel) { + BaseEngineBackend::setup(featureLevel); + renderer_ = UniqueRenderer(framework().createRenderer(ramses::RendererConfig{}), [=](ramses::RamsesRenderer* c) { framework().destroyRenderer(*c); }); + eventHandler_ = std::make_unique(*renderer_.get()); + + renderer_->setSkippingOfUnmodifiedBuffers(false); } ramses::RamsesRenderer& RendererBackend::renderer() const { @@ -73,6 +60,7 @@ ramses::dataConsumerId_t RendererBackend::internalDataConsumerId() { void RendererBackend::doOneLoop() const { renderer().doOneLoop(); renderer().dispatchEvents(*eventHandler_); + renderer().getSceneControlAPI()->dispatchEvents(*eventHandler_); } } // namespace raco::ramses_widgets diff --git a/gui/libRamsesWidgets/src/SceneStateEventHandler.cpp b/gui/libRamsesWidgets/src/SceneStateEventHandler.cpp index 842a1048..0fe0d7d7 100644 --- a/gui/libRamsesWidgets/src/SceneStateEventHandler.cpp +++ b/gui/libRamsesWidgets/src/SceneStateEventHandler.cpp @@ -15,7 +15,7 @@ using raco::log_system::RAMSES_BACKEND; -#include +#include #include namespace raco::ramses_widgets { @@ -27,7 +27,7 @@ SceneStateEventHandler::SceneStateEventHandler(ramses::RamsesRenderer& renderer) void SceneStateEventHandler::framebufferPixelsRead(const uint8_t* pixelData, const uint32_t pixelDataSize, ramses::displayId_t displayId, ramses::displayBufferId_t displayBuffer, ramses::ERendererEventResult result) { if (!screenshot_.empty()) { screenshotSaved_ = false; - if (result == ramses::ERendererEventResult_OK) { + if (result == ramses::ERendererEventResult::Ok) { std::vector buffer; buffer.insert(buffer.end(), &pixelData[0], &pixelData[pixelDataSize]); screenshotSaved_ = ramses::RamsesUtils::SaveImageBufferToPng(screenshot_, buffer, screenshotWidth_, screenshotHeight_, true); @@ -45,7 +45,7 @@ void SceneStateEventHandler::offscreenBufferLinked(ramses::displayBufferId_t off void SceneStateEventHandler::offscreenBufferCreated(ramses::displayId_t displayId, ramses::displayBufferId_t offscreenBufferId, ramses::ERendererEventResult result) { LOG_TRACE(RAMSES_BACKEND, "offscreenBufferCreated({}, {}, {})", displayId, offscreenBufferId, result); - if (result == ramses::ERendererEventResult_OK) { + if (result == ramses::ERendererEventResult::Ok) { offscreenBuffers_.insert(offscreenBufferId); } } @@ -57,7 +57,7 @@ void SceneStateEventHandler::offscreenBufferDestroyed(ramses::displayId_t displa void SceneStateEventHandler::displayCreated(ramses::displayId_t displayId, ramses::ERendererEventResult result) { LOG_TRACE(RAMSES_BACKEND, "displayCreated({}, {})", displayId, result); - if (result == ramses::ERendererEventResult::ERendererEventResult_OK) + if (result == ramses::ERendererEventResult::Ok) displays_.insert(displayId); } @@ -76,8 +76,31 @@ void SceneStateEventHandler::sceneFlushed(ramses::sceneId_t sceneId, ramses::sce scenes_[sceneId].version = sceneVersion; } -void SceneStateEventHandler::waitForSceneState(ramses::sceneId_t sceneId, ramses::RendererSceneState state) { - waitUntilOrTimeout([&] { return scenes_[sceneId].state == state; }); +void SceneStateEventHandler::waitForSceneState(ramses::sceneId_t sceneId, ramses::RendererSceneState state, ECompareFunc compFunc) { + waitUntilOrTimeout([this, sceneId, state, compFunc] { + switch (compFunc) { + case ECompareFunc::LessEqual: + return scenes_[sceneId].state <= state; + case ECompareFunc::Equal: + return scenes_[sceneId].state == state; + case ECompareFunc::GreaterEqual: + return scenes_[sceneId].state >= state; + default: + return false; + } + }); +} + +void SceneStateEventHandler::objectsPicked(ramses::sceneId_t sceneId, const ramses::pickableObjectId_t* pickedObjects, size_t pickedObjectsCount) { + std::string ids; + std::vector pickIds; + for (int index = 0; index < pickedObjectsCount; index++) { + ids.append(std::to_string(pickedObjects[index].getValue())); + ids.append(", "); + pickIds.emplace_back(pickedObjects[index]); + } + LOG_TRACE(RAMSES_BACKEND, "objectsPicked({})", ids); + Q_EMIT pickRequest(pickIds); } bool SceneStateEventHandler::waitForFlush(ramses::sceneId_t sceneId, ramses::sceneVersionTag_t sceneVersion) { diff --git a/gui/libRamsesWidgets/src/TransformationController.cpp b/gui/libRamsesWidgets/src/TransformationController.cpp new file mode 100644 index 00000000..18a9085f --- /dev/null +++ b/gui/libRamsesWidgets/src/TransformationController.cpp @@ -0,0 +1,420 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of Ramses Composer + * (see https://github.com/bmwcarit/ramses-composer). + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "ramses_widgets/TransformationController.h" + +#include "core/CommandInterface.h" + +#include "ramses_adaptor/utilities.h" +#include "ramses_adaptor/AbstractSceneAdaptor.h" + +#include "user_types/Node.h" + +#include +#include + +namespace { + +inline std::array toArray(glm::vec3 v) { + return {v.x, v.y, v.z}; +} + +bool isRightHanded(glm::vec3 u, glm::vec3 v, glm::vec3 w) { + return glm::dot(glm::cross(u, v), w) > 0.0; +} + +} // namespace + +namespace raco::ramses_widgets { + +glm::vec3 TransformationController::axisVector(Axis axis) { + return glm::vec3(axis == Axis::X ? 1.0 : 0.0, axis == Axis::Y ? 1.0 : 0.0, axis == Axis::Z ? 1.0 : 0.0); +} + +TransformationController::TransformationController(ramses_adaptor::AbstractSceneAdaptor* abstractScene, core::CommandInterface* commandInterface) + : abstractScene_(abstractScene), + commandInterface_(commandInterface) { +} + +void TransformationController::beginDrag(core::SEditorObject object, DragMode mode, TransformMode transformMode, Axis axis) { + activeObject_ = object; + dragMode_ = mode; + transformMode_ = transformMode; + axis_ = axis; + + dragInitialObjectTranslation_ = ramses_adaptor::getRacoTranslation(activeObject_->as()); + dragInitialObjectScaling_ = ramses_adaptor::getRacoScaling(activeObject_->as()); + dragInitialObjectRotation_ = ramses_adaptor::getRacoRotation(activeObject_->as()); + + auto modelMatrix = abstractScene_->modelMatrix(activeObject_); + glm::vec3 worldOrigin = modelMatrix * glm::vec4(0, 0, 0, 1); + + if (dragMode_ == DragMode::Rotate) { + switch (transformMode_) { + case TransformMode::Axis: { + glm::vec3 objectAxis = axisVector(axis_); + glm::vec3 worldAxis = glm::normalize(glm::vec3(modelMatrix * glm::vec4(objectAxis, 0.0))); + plane_.normal = worldAxis; + refAxis_ = worldAxis; + + auto cameraModelMatrix = abstractScene_->cameraController().modelMatrix(); + glm::vec3 worldViewAxis = glm::normalize(cameraModelMatrix * glm::vec4(0, 0, -1, 0)); + + Axis axis_1 = static_cast((static_cast(axis_) + 1) % 3); + Axis axis_2 = static_cast((static_cast(axis_) + 2) % 3); + + auto selectAuxAxis = [worldViewAxis, modelMatrix](Axis axis1, Axis axis2) -> glm::vec3 { + glm::vec3 w1 = glm::normalize(glm::vec3(modelMatrix * glm::vec4(axisVector(axis1), 0.0))); + glm::vec3 w2 = glm::normalize(glm::vec3(modelMatrix * glm::vec4(axisVector(axis2), 0.0))); + if (abs(glm::dot(w1, worldViewAxis)) > abs(glm::dot(w2, worldViewAxis))) { + return w2; + } + return w1; + }; + + glm::vec3 auxAxis = selectAuxAxis(axis_1, axis_2); + abstractScene_->enableGuides(worldOrigin, refAxis_, auxAxis, static_cast(axis_), 0, false, glm::vec2(1, 0)); + } break; + case TransformMode::Free: { + auto cameraModelMatrix = abstractScene_->cameraController().modelMatrix(); + plane_.normal = glm::normalize(cameraModelMatrix * glm::vec4(0, 0, -1, 0)); + refAxis_ = plane_.normal; + break; + } break; + } + } else { + switch (transformMode_) { + case TransformMode::Plane: { + // Translation along plane: the plane is defined by the 2 axes not selected. + Axis axis_1 = static_cast((static_cast(axis_) + 1) % 3); + Axis axis_2 = static_cast((static_cast(axis_) + 2) % 3); + + glm::vec3 worldAxis_1 = glm::normalize(glm::vec3(modelMatrix * glm::vec4(axisVector(axis_1), 0.0))); + glm::vec3 worldAxis_2 = glm::normalize(glm::vec3(modelMatrix * glm::vec4(axisVector(axis_2), 0.0))); + refAxis_ = worldAxis_1; + refAxis2_ = worldAxis_2; + plane_.normal = glm::normalize(glm::cross(worldAxis_1, worldAxis_2)); + + abstractScene_->enableGuides(worldOrigin, worldAxis_1, worldAxis_2, static_cast(axis_1), static_cast(axis_2), false, glm::vec2(1, 1)); + } break; + + case TransformMode::Free: { + auto cameraModelMatrix = abstractScene_->cameraController().modelMatrix(); + plane_.normal = glm::normalize(cameraModelMatrix * glm::vec4(0, 0, -1, 0)); + } break; + case TransformMode::Axis: { + glm::vec3 objectAxis = axisVector(axis_); + glm::vec3 worldAxis = glm::normalize(glm::vec3(modelMatrix * glm::vec4(objectAxis, 0.0))); + refAxis_ = worldAxis; + + Axis axis_1 = static_cast((static_cast(axis_) + 1) % 3); + Axis axis_2 = static_cast((static_cast(axis_) + 2) % 3); + + auto cameraModelMatrix = abstractScene_->cameraController().modelMatrix(); + glm::vec3 worldViewAxis = glm::normalize(cameraModelMatrix * glm::vec4(0, 0, -1, 0)); + + auto selectNormal = [worldViewAxis, modelMatrix](Axis axis1, Axis axis2) -> glm::vec3 { + glm::vec3 w1 = glm::normalize(glm::vec3(modelMatrix * glm::vec4(axisVector(axis1), 0.0))); + glm::vec3 w2 = glm::normalize(glm::vec3(modelMatrix * glm::vec4(axisVector(axis2), 0.0))); + if (abs(glm::dot(w1, worldViewAxis)) < abs(glm::dot(w2, worldViewAxis))) { + return w2; + } + return w1; + }; + + plane_.normal = selectNormal(axis_1, axis_2); + + auto refAxis = glm::cross(plane_.normal, worldAxis); + abstractScene_->enableGuides(worldOrigin, worldAxis, refAxis, static_cast(axis_), 0, false, glm::vec2(1, 0)); + + } break; + } + } + initialWorldOrigin_ = worldOrigin; + plane_.dist = glm::dot(worldOrigin, plane_.normal); +} + +void TransformationController::abortDrag() { + switch (dragMode_) { + case DragMode::Translate: + commandInterface_->set({activeObject_, &user_types::Node::translation_}, toArray(dragInitialObjectTranslation_)); + break; + case DragMode::Scale: + commandInterface_->set({activeObject_, &user_types::Node::scaling_}, toArray(dragInitialObjectScaling_)); + break; + case DragMode::Rotate: + commandInterface_->set({activeObject_, &user_types::Node::rotation_}, toArray(dragInitialObjectRotation_)); + break; + } + endDrag(); +} + +void TransformationController::endDrag() { + dragMode_ = DragMode::None; + abstractScene_->disableGuides(); +} + +TransformationController::Ray TransformationController::unproject(QPoint pos, glm::mat4 view, glm::mat4 projection, glm::ivec4 viewport) { + auto near = glm::unProject(glm::vec3(pos.x(), pos.y(), 0.0), view, projection, viewport); + auto far = glm::unProject(glm::vec3(pos.x(), pos.y(), +1.0), view, projection, viewport); + + auto test_near = projection * view * glm::vec4(near, 1.0); + auto test_far = projection * view * glm::vec4(far, 1.0); + + return Ray{near, glm::normalize(far - near)}; +} + +std::optional TransformationController::intersect(const Ray& ray, const Plane& plane) { + float t = (plane.dist - glm::dot(plane.normal, ray.origin)) / glm::dot(plane.normal, ray.direction); + + if (t > 0) { + return ray.origin + t * ray.direction; + } + return {}; +} + +QPoint TransformationController::project(QPoint qpoint, glm::vec2 rayOrigin, glm::vec2 rayDirection) { + glm::vec2 point(qpoint.x(), qpoint.y()); + glm::vec2 q = rayOrigin + rayDirection * (glm::dot(point - rayOrigin, rayDirection) / glm::dot(rayDirection, rayDirection)); + return {static_cast(q[0]), static_cast(q[1])}; +} + +void TransformationController::translate(float distance) { + glm::mat4 parentModelMatrix = abstractScene_->modelMatrix(activeObject_->getParent()); + if (transformMode_ == TransformMode::Axis) { + auto worldMovement = distance * refAxis_; + + glm::vec3 objectMovement = inverse(parentModelMatrix) * glm::vec4(worldMovement, 0.0); + + auto objectTranslation = dragInitialObjectTranslation_ + objectMovement; + commandInterface_->set({activeObject_, &user_types::Node::translation_}, toArray(objectTranslation)); + } +} + +void TransformationController::dragTranslate(QPoint initialPos_, QPoint currentPos_, int widgetWidth, int widgetHeight, bool snap, double snapScale) { + // currentPos (0,0) = top left + QPoint currentPos(currentPos_.x(), widgetHeight - currentPos_.y()); + QPoint initialPos(initialPos_.x(), widgetHeight - initialPos_.y()); + + glm::mat4 parentModelMatrix = abstractScene_->modelMatrix(activeObject_->getParent()); + auto viewMatrix = abstractScene_->cameraController().viewMatrix(); + auto projectionMatrix = abstractScene_->cameraController().projectionMatrix(); + glm::ivec4 viewport{0, 0, widgetWidth, widgetHeight}; + + if (transformMode_ == TransformMode::Axis) { + // Project current and original mouse position to screen axis + glm::vec2 screenOrigin = glm::project(initialWorldOrigin_, viewMatrix, projectionMatrix, viewport); + glm::vec2 screenRefAxis = glm::vec2(glm::project(initialWorldOrigin_ + refAxis_, viewMatrix, projectionMatrix, viewport)) - screenOrigin; + + auto initialProjScreen = project(initialPos, screenOrigin, screenRefAxis); + auto currentProjScreen = project(currentPos, screenOrigin, screenRefAxis); + + // Raycast screen project coordinates into scene and calculate intersection + auto rayInitial = unproject(initialProjScreen, viewMatrix, projectionMatrix, viewport); + auto rayCurrent = unproject(currentProjScreen, viewMatrix, projectionMatrix, viewport); + + auto worldPosInitial = intersect(rayInitial, plane_); + auto worldPosCurrent = intersect(rayCurrent, plane_); + + if (worldPosInitial.has_value() && worldPosCurrent.has_value()) { + // To ensure that the movement vector doesn't have components perpendicular to the reference axis due to rounding erorrs + // we transform the original movement vector back to the plane coordinates, pick the coordinate along the + // reference axis, and reconstruct the world movement vector from the reference axis and the coordinate: + glm::vec3 orthoAxis = glm::normalize(glm::cross(refAxis_, plane_.normal)); + auto dist = (glm::inverse(glm::mat3(refAxis_, orthoAxis, plane_.normal)) * (worldPosCurrent.value() - worldPosInitial.value())).x; + + if (snap) { + dist = snapScale * round(dist/snapScale); + } + + auto worldMovement = dist * refAxis_; + + glm::vec3 objectMovement = inverse(parentModelMatrix) * glm::vec4(worldMovement, 0.0); + + auto objectTranslation = dragInitialObjectTranslation_ + objectMovement; + commandInterface_->set({activeObject_, &user_types::Node::translation_}, toArray(objectTranslation)); + } + + } else { + auto rayInitial = unproject(initialPos, viewMatrix, projectionMatrix, viewport); + auto rayCurrent = unproject(currentPos, viewMatrix, projectionMatrix, viewport); + + auto worldPosInitial = intersect(rayInitial, plane_); + auto worldPosCurrent = intersect(rayCurrent, plane_); + + if (worldPosInitial.has_value() && worldPosCurrent.has_value()) { + auto worldMovement = worldPosCurrent.value() - worldPosInitial.value(); + if (snap && transformMode_ == TransformMode::Plane) { + // Snap both coordinates separately: + // to do this we first need to determine the coordinates from the world movement and the transformation matrix built + // from the 2 plane axes and the plane normal: + glm::vec3 coords = (glm::inverse(glm::mat3(refAxis_, refAxis2_, plane_.normal)) * worldMovement); + glm::vec2 snappedCoords(snapScale * round(coords.x / snapScale), snapScale * round(coords.y / snapScale)); + worldMovement = snappedCoords.x * refAxis_ + snappedCoords.y * refAxis2_; + } + + glm::vec3 objectMovement = inverse(parentModelMatrix) * glm::vec4(worldMovement, 0.0); + + auto objectTranslation = dragInitialObjectTranslation_ + objectMovement; + + std::array objectTranslationArray({objectTranslation[0], objectTranslation[1], objectTranslation[2]}); + commandInterface_->set({activeObject_, &user_types::Node::translation_}, objectTranslationArray); + } + } +} + +void TransformationController::scale(float scalingFactor) { + if (transformMode_ == TransformMode::Axis) { + glm::vec3 scale = dragInitialObjectScaling_; + scale[static_cast(axis_)] *= scalingFactor; + + commandInterface_->set({activeObject_, &user_types::Node::scaling_}, toArray(scale)); + } else { + if (transformMode_ == TransformMode::Plane) { + glm::vec3 scale = scalingFactor * dragInitialObjectScaling_; + scale[static_cast(axis_)] = dragInitialObjectScaling_[static_cast(axis_)]; + + commandInterface_->set({activeObject_, &user_types::Node::scaling_}, toArray(scale)); + } else if (transformMode_ == TransformMode::Free) { + glm::vec3 scale = scalingFactor * dragInitialObjectScaling_; + + commandInterface_->set({activeObject_, &user_types::Node::scaling_}, toArray(scale)); + } + } +} + +void TransformationController::dragScale(QPoint initialPos_, QPoint currentPos_, int widgetWidth, int widgetHeight, bool snap) { + const double snapScale = 0.1; + + QPoint currentPos(currentPos_.x(), widgetHeight - currentPos_.y()); + QPoint initialPos(initialPos_.x(), widgetHeight - initialPos_.y()); + + auto viewMatrix = abstractScene_->cameraController().viewMatrix(); + auto projectionMatrix = abstractScene_->cameraController().projectionMatrix(); + glm::ivec4 viewport{0, 0, widgetWidth, widgetHeight}; + + if (transformMode_ == TransformMode::Axis) { + glm::vec2 screenOrigin = glm::project(initialWorldOrigin_, viewMatrix, projectionMatrix, viewport); + glm::vec2 screenRefAxis = glm::vec2(glm::project(initialWorldOrigin_ + refAxis_, viewMatrix, projectionMatrix, viewport)) - screenOrigin; + + auto initialProjScreen = project(initialPos, screenOrigin, screenRefAxis); + auto currentProjScreen = project(currentPos, screenOrigin, screenRefAxis); + + auto rayInitial = unproject(initialProjScreen, viewMatrix, projectionMatrix, viewport); + auto rayCurrent = unproject(currentProjScreen, viewMatrix, projectionMatrix, viewport); + + auto worldPosInitial = intersect(rayInitial, plane_); + auto worldPosCurrent = intersect(rayCurrent, plane_); + + if (worldPosInitial.has_value() && worldPosCurrent.has_value()) { + float scalingFactor = glm::length(worldPosCurrent.value() - initialWorldOrigin_) / glm::length(worldPosInitial.value() - initialWorldOrigin_); + if (snap) { + scalingFactor = snapScale * round(scalingFactor / snapScale); + } + + glm::vec3 scale = dragInitialObjectScaling_; + scale[static_cast(axis_)] *= scalingFactor; + + std::array objectScaling({scale[0], scale[1], scale[2]}); + commandInterface_->set({activeObject_, &user_types::Node::scaling_}, objectScaling); + } + } else { + auto rayInitial = unproject(initialPos, viewMatrix, projectionMatrix, viewport); + auto rayCurrent = unproject(currentPos, viewMatrix, projectionMatrix, viewport); + + auto worldPosInitial = intersect(rayInitial, plane_); + auto worldPosCurrent = intersect(rayCurrent, plane_); + + if (transformMode_ == TransformMode::Plane) { + if (worldPosInitial.has_value() && worldPosCurrent.has_value()) { + float scalingFactor = glm::length(worldPosCurrent.value() - initialWorldOrigin_) / glm::length(worldPosInitial.value() - initialWorldOrigin_); + if (snap) { + scalingFactor = snapScale * round(scalingFactor / snapScale); + } + + glm::vec3 scale = scalingFactor * dragInitialObjectScaling_; + scale[static_cast(axis_)] = dragInitialObjectScaling_[static_cast(axis_)]; + + std::array objectScaling({scale[0], scale[1], scale[2]}); + commandInterface_->set({activeObject_, &user_types::Node::scaling_}, objectScaling); + } + } else if (transformMode_ == TransformMode::Free) { + if (worldPosInitial.has_value() && worldPosCurrent.has_value()) { + float scalingFactor = glm::length(worldPosCurrent.value() - initialWorldOrigin_) / glm::length(worldPosInitial.value() - initialWorldOrigin_); + if (snap) { + scalingFactor = snapScale * round(scalingFactor / snapScale); + } + + glm::vec3 scale = scalingFactor * dragInitialObjectScaling_; + + std::array objectScaling({scale[0], scale[1], scale[2]}); + commandInterface_->set({activeObject_, &user_types::Node::scaling_}, objectScaling); + } + } + } +} + +void TransformationController::rotate(float angleDegrees) { + glm::mat4 parentModelMatrix = abstractScene_->modelMatrix(activeObject_->getParent()); + + if (transformMode_ == TransformMode::Axis || transformMode_ == TransformMode::Free) { + glm::mat4 initialRotation = glm::eulerAngleXYZ(glm::radians(dragInitialObjectRotation_[0]), glm::radians(dragInitialObjectRotation_[1]), glm ::radians(dragInitialObjectRotation_[2])); + glm::vec3 objectRefAxis = glm::normalize(glm::inverse(parentModelMatrix) * glm::vec4(refAxis_, 0.0)); + glm::mat4 deltaRotation = glm::rotate(glm::identity(), glm::radians(angleDegrees), objectRefAxis); + glm::mat4 objectRotation = deltaRotation * initialRotation; + float rotX, rotY, rotZ; + glm::extractEulerAngleXYZ(objectRotation, rotX, rotY, rotZ); + std::array rotationEulerAngles({glm::degrees(rotX), glm::degrees(rotY), glm::degrees(rotZ)}); + commandInterface_->set({activeObject_, &user_types::Node::rotation_}, rotationEulerAngles); + } +} + +void TransformationController::dragRotate(QPoint initialPos_, QPoint currentPos_, int widgetWidth, int widgetHeight, bool snap) { + const double snapScaleRadian = glm::radians(5.0); + QPoint currentPos(currentPos_.x(), widgetHeight - currentPos_.y()); + QPoint initialPos(initialPos_.x(), widgetHeight - initialPos_.y()); + + glm::mat4 parentModelMatrix = abstractScene_->modelMatrix(activeObject_->getParent()); + auto viewMatrix = abstractScene_->cameraController().viewMatrix(); + auto projectionMatrix = abstractScene_->cameraController().projectionMatrix(); + glm::ivec4 viewport{0, 0, widgetWidth, widgetHeight}; + + if (transformMode_ == TransformMode::Axis || transformMode_ == TransformMode::Free) { + auto rayInitial = unproject(initialPos, viewMatrix, projectionMatrix, viewport); + auto rayCurrent = unproject(currentPos, viewMatrix, projectionMatrix, viewport); + + auto worldPosInitial = intersect(rayInitial, plane_); + auto worldPosCurrent = intersect(rayCurrent, plane_); + + if (worldPosInitial.has_value() && worldPosCurrent.has_value()) { + glm::vec3 startDirection = glm::normalize(worldPosInitial.value() - initialWorldOrigin_); + glm::vec3 currentDirection = glm::normalize(worldPosCurrent.value() - initialWorldOrigin_); + + float angle = acos(glm::dot(startDirection, currentDirection)); + if (!isRightHanded(startDirection, currentDirection, refAxis_)) { + angle = -angle; + } + if (snap) { + angle = snapScaleRadian * round(angle / snapScaleRadian); + } + + glm::mat4 initialRotation = glm::eulerAngleXYZ(glm::radians(dragInitialObjectRotation_[0]), glm::radians(dragInitialObjectRotation_[1]), glm ::radians(dragInitialObjectRotation_[2])); + glm::vec3 objectRefAxis = glm::normalize(glm::inverse(parentModelMatrix) * glm::vec4(refAxis_, 0.0)); + glm::mat4 deltaRotation = glm::rotate(glm::identity(), angle, objectRefAxis); + glm::mat4 objectRotation = deltaRotation * initialRotation; + float rotX, rotY, rotZ; + glm::extractEulerAngleXYZ(objectRotation, rotX, rotY, rotZ); + std::array rotationEulerAngles({glm::degrees(rotX), glm::degrees(rotY), glm::degrees(rotZ)}); + commandInterface_->set({activeObject_, &user_types::Node::rotation_}, rotationEulerAngles); + } + } +} + +} // namespace raco::ramses_widgets \ No newline at end of file diff --git a/gui/libStyle/include/style/Colors.h b/gui/libStyle/include/style/Colors.h index 70f1a7d3..7564d6ef 100644 --- a/gui/libStyle/include/style/Colors.h +++ b/gui/libStyle/include/style/Colors.h @@ -34,6 +34,8 @@ enum class Colormap { dockTitleBackground, externalReference, externalReferenceDisabled, + + abstractSceneViewBackground }; class Colors { diff --git a/gui/libStyle/include/style/Icons.h b/gui/libStyle/include/style/Icons.h index 3c065727..71d0176e 100644 --- a/gui/libStyle/include/style/Icons.h +++ b/gui/libStyle/include/style/Icons.h @@ -79,6 +79,8 @@ class Icons { const QIcon visibilityDisabled{makeDisabled(":visibilityDisabledIcon")}; const QIcon visibilityOn{makeDisabled(":visibilityOnIcon")}; const QIcon visibilityOff{makeDisabled(":visibilityOffIcon")}; + const QIcon abstractSceneView{":abstractSceneViewIcon"}; + const QIcon prefabLookup{":prefabLookupIcon"}; static const Icons &instance(); static QIcon makeDisabled(const QString &name); diff --git a/gui/libStyle/src/Colors.cpp b/gui/libStyle/src/Colors.cpp index df3c92fb..26517272 100644 --- a/gui/libStyle/src/Colors.cpp +++ b/gui/libStyle/src/Colors.cpp @@ -29,7 +29,10 @@ Colors::Colors() noexcept { {Colormap::errorColorLight, QColor(255, 120, 120)}, {Colormap::dockTitleBackground, QColor(0, 0, 0)}, {Colormap::externalReference, QColor(170, 250, 70)}, - {Colormap::externalReferenceDisabled, QColor(115, 195, 15)}}; + {Colormap::externalReferenceDisabled, QColor(115, 195, 15)}, + + {Colormap::abstractSceneViewBackground, QColor(20, 20, 20)} + }; for (const auto& [key, value] : colors_) { brushes_[key] = QBrush(value); diff --git a/gui/libStyle/src/RaCoStyle.cpp b/gui/libStyle/src/RaCoStyle.cpp index 1938ea59..801861df 100644 --- a/gui/libStyle/src/RaCoStyle.cpp +++ b/gui/libStyle/src/RaCoStyle.cpp @@ -409,13 +409,17 @@ void RaCoStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *opti if (const QStyleOptionFrame *opt = qstyleoption_cast(option)) { QBrush backBrush = opt->palette.brush(QPalette::Base); - auto errorLevel = static_cast(saveGetProperty(widget, "errorLevel", 1).toInt()); - if (errorLevel == core::ErrorLevel::WARNING || saveGetProperty(widget, "unexpectedEmptyReference", 1).toBool()) { + const std::string name = widget->objectName().toStdString(); + const auto errorLevel = static_cast(saveGetProperty(widget, "errorLevel", 0).toInt()); + + if (errorLevel == core::ErrorLevel::WARNING|| + saveGetProperty(widget, "unexpectedEmptyReference", 1).toBool()) { backBrush = Colors::brush(Colormap::warningColor); } if (errorLevel == core::ErrorLevel::ERROR) { backBrush = Colors::brush(Colormap::errorColorDark); } + if (saveGetProperty(widget, "updatedInBackground", 1).toBool()) { backBrush = Colors::brush(Colormap::updatedInBackground); } diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index 88497ddd..77bc3980 100644 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -62,6 +62,11 @@ set(RESOURCE_FILES shaders/uniform-array.vert shaders/uniform-array.frag example_scene.rca + # the following resources are needed by the 3d view + meshes/gizmo-arrow.glb + meshes/gizmo-scale.glb + meshes/gizmo-torus.glb + meshes/sphere-ico.glb ) foreach(relpath ${RESOURCE_FILES}) diff --git a/resources/empty-fl1.rca b/resources/empty-raco-1x-fl1.rca similarity index 100% rename from resources/empty-fl1.rca rename to resources/empty-raco-1x-fl1.rca diff --git a/resources/empty-fl2.rca b/resources/empty-raco-1x-fl2.rca similarity index 100% rename from resources/empty-fl2.rca rename to resources/empty-raco-1x-fl2.rca diff --git a/resources/empty-raco-2x-fl1.rca b/resources/empty-raco-2x-fl1.rca new file mode 100644 index 00000000..00db17d9 --- /dev/null +++ b/resources/empty-raco-2x-fl1.rca @@ -0,0 +1,591 @@ +{ + "externalProjects": { + }, + "featureLevel": 1, + "fileVersion": 2001, + "instances": [ + { + "properties": { + "backgroundColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, + "z": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + } + }, + "defaultResourceFolders": { + "imageSubdirectory": "images", + "interfaceSubdirectory": "interfaces", + "meshSubdirectory": "meshes", + "scriptSubdirectory": "scripts", + "shaderSubdirectory": "shaders" + }, + "featureLevel": 1, + "objectID": "8b3c93d7-63cb-4a0b-9cfd-b115741632a7", + "objectName": "empty-raco-2x-fl1", + "saveAsZip": false, + "sceneId": { + "annotations": [ + { + "properties": { + "max": 1024, + "min": 1 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 123 + }, + "viewport": { + "i1": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + } + } + }, + "typeName": "ProjectSettings" + } + ], + "links": [ + ], + "logicEngineVersion": [ + 28, + 0, + 0 + ], + "racoVersion": [ + 2, + 0, + 0 + ], + "ramsesVersion": [ + 28, + 0, + 0 + ], + "structPropMap": { + "AnchorPointOutputs": { + "depth": "Double::DisplayNameAnnotation::LinkStartAnnotation", + "viewportCoords": "Vec2f::DisplayNameAnnotation::LinkStartAnnotation" + }, + "BlendOptions": { + "blendColor": "Vec4f::DisplayNameAnnotation", + "blendFactorDestAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorDestColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorSrcAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendFactorSrcColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendOperationAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "blendOperationColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "colorWriteMask": "ColorWriteMask::DisplayNameAnnotation", + "cullmode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "depthFunction": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "depthwrite": "Bool::DisplayNameAnnotation", + "scissorOptions": "ScissorOptions::DisplayNameAnnotation", + "stencilOptions": "StencilOptions::DisplayNameAnnotation" + }, + "CameraViewport": { + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "offsetX": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "offsetY": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation" + }, + "ColorWriteMask": { + "alpha": "Bool::DisplayNameAnnotation", + "blue": "Bool::DisplayNameAnnotation", + "green": "Bool::DisplayNameAnnotation", + "red": "Bool::DisplayNameAnnotation" + }, + "DefaultResourceDirectories": { + "imageSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "interfaceSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "meshSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "scriptSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", + "shaderSubdirectory": "String::DisplayNameAnnotation::URIAnnotation" + }, + "LuaStandardModuleSelection": { + "base": "Bool::DisplayNameAnnotation", + "debug": "Bool::DisplayNameAnnotation", + "math": "Bool::DisplayNameAnnotation", + "string": "Bool::DisplayNameAnnotation", + "table": "Bool::DisplayNameAnnotation" + }, + "OrthographicFrustum": { + "bottomPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "farPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "leftPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "nearPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "rightPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "topPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation" + }, + "ScissorOptions": { + "scissorEnable": "Bool::DisplayNameAnnotation", + "scissorRegion": "CameraViewport::DisplayNameAnnotation" + }, + "StencilOptions": { + "stencilFunc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilMask": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "stencilOpDepthFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpDepthSucc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpStencilFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilRef": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "TimerInput": { + "ticker_us": "Int64::DisplayNameAnnotation::LinkEndAnnotation" + }, + "TimerOutput": { + "ticker_us": "Int64::DisplayNameAnnotation::LinkStartAnnotation" + }, + "Vec2f": { + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec2i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "Vec3f": { + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "z": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec3i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i3": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, + "Vec4f": { + "w": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "x": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "y": "Double::DisplayNameAnnotation::RangeAnnotationDouble", + "z": "Double::DisplayNameAnnotation::RangeAnnotationDouble" + }, + "Vec4i": { + "i1": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i2": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i3": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "i4": "Int::DisplayNameAnnotation::RangeAnnotationInt" + } + }, + "userTypePropMap": { + "AnchorPoint": { + "camera": "BaseCamera::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "node": "Node::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "AnchorPointOutputs::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Animation": { + "animationChannels": "Array[AnimationChannel]::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "Table::DisplayNameAnnotation", + "progress": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "AnimationChannel": { + "animationIndex": "Int::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "samplerIndex": "Int::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "BlitPass": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "destinationX": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "destinationY": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "enabled": "Bool::DisplayNameAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderOrder": "Int::DisplayNameAnnotation", + "sourceRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "sourceRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "sourceX": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "sourceY": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "targetRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", + "targetRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" + }, + "CubeMap": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "generateMipmaps": "Bool::DisplayNameAnnotation", + "level2uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level2uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level3uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "level4uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "uriBack": "String::URIAnnotation::DisplayNameAnnotation", + "uriBottom": "String::URIAnnotation::DisplayNameAnnotation", + "uriFront": "String::URIAnnotation::DisplayNameAnnotation", + "uriLeft": "String::URIAnnotation::DisplayNameAnnotation", + "uriRight": "String::URIAnnotation::DisplayNameAnnotation", + "uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "LuaInterface": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "inputs": "Table::DisplayNameAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "LuaScript": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "inputs": "Table::DisplayNameAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "Table::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "LuaScriptModule": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Material": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "options": "BlendOptions::DisplayNameAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "uniforms": "Table::DisplayNameAnnotation", + "uriDefines": "String::URIAnnotation::DisplayNameAnnotation", + "uriFragment": "String::URIAnnotation::DisplayNameAnnotation", + "uriGeometry": "String::URIAnnotation::DisplayNameAnnotation", + "uriVertex": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Mesh": { + "bakeMeshes": "Bool::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "materialNames": "Table::ArraySemanticAnnotation::HiddenProperty", + "meshIndex": "Int::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "MeshNode": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "instanceCount": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", + "materials": "Table::DisplayNameAnnotation", + "mesh": "Mesh::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "Node": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "OrthographicCamera": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "frustum": "OrthographicFrustum::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "PerspectiveCamera": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "frustum": "Table::DisplayNameAnnotation::LinkEndAnnotation", + "frustumType": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "Prefab": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "PrefabInstance": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "template": "Prefab::DisplayNameAnnotation", + "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" + }, + "ProjectSettings": { + "backgroundColor": "Vec4f::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "defaultResourceFolders": "DefaultResourceDirectories::DisplayNameAnnotation", + "featureLevel": "Int::DisplayNameAnnotation::ReadOnlyAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "saveAsZip": "Bool::DisplayNameAnnotation", + "sceneId": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "viewport": "Vec2i::DisplayNameAnnotation" + }, + "RenderBuffer": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "RenderBufferMS": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "sampleCount": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" + }, + "RenderLayer": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "materialFilterMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "materialFilterTags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderableTags": "Table::RenderableTagContainerAnnotation::DisplayNameAnnotation", + "sortOrder": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderPass": { + "camera": "BaseCamera::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "clearColor": "Vec4f::DisplayNameAnnotation::LinkEndAnnotation", + "enableClearColor": "Bool::DisplayNameAnnotation", + "enableClearDepth": "Bool::DisplayNameAnnotation", + "enableClearStencil": "Bool::DisplayNameAnnotation", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "layers": "Array[RenderLayer]::DisplayNameAnnotation::EmptyReferenceAllowable", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "renderOnce": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "renderOrder": "Int::DisplayNameAnnotation::LinkEndAnnotation", + "target": "RenderTargetBase::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderTarget": { + "buffers": "Array[RenderBuffer]::DisplayNameAnnotation::EmptyReferenceAllowable", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderTargetMS": { + "buffers": "Array[RenderBufferMS]::DisplayNameAnnotation::EmptyReferenceAllowable", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Skin": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "joints": "Array[Node]::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "skinIndex": "Int::DisplayNameAnnotation", + "targets": "Array[MeshNode]::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Texture": { + "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "flipTexture": "Bool::DisplayNameAnnotation", + "generateMipmaps": "Bool::DisplayNameAnnotation", + "level2uri": "String::URIAnnotation::DisplayNameAnnotation", + "level3uri": "String::URIAnnotation::DisplayNameAnnotation", + "level4uri": "String::URIAnnotation::DisplayNameAnnotation", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", + "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" + }, + "TextureExternal": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "Timer": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "inputs": "TimerInput::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "outputs": "TimerOutput::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + } + } +} diff --git a/resources/meshes/cube.gltf b/resources/meshes/cube.gltf new file mode 100644 index 00000000..00c82774 --- /dev/null +++ b/resources/meshes/cube.gltf @@ -0,0 +1,166 @@ +{ + "asset" : { + "generator" : "Khronos glTF Blender I/O v1.6.16", + "version" : "2.0" + }, + "scene" : 0, + "scenes" : [ + { + "name" : "Scene", + "nodes" : [ + 0, + 1, + 2 + ] + } + ], + "nodes" : [ + { + "mesh" : 0, + "name" : "Cube", + "rotation" : [ + 0.398443341255188, + 0.15567483007907867, + -0.06882311403751373, + 0.9012611508369446 + ] + }, + { + "name" : "Light", + "rotation" : [ + 0.16907575726509094, + 0.27217137813568115, + 0.7558803558349609, + 0.570947527885437 + ], + "translation" : [ + 4.076245307922363, + 1.0054539442062378, + 5.903861999511719 + ] + }, + { + "camera" : 0, + "name" : "Camera", + "rotation" : [ + 0.483536034822464, + 0.20870360732078552, + 0.33687159419059753, + 0.7804827094078064 + ], + "translation" : [ + 7.358891487121582, + -6.925790786743164, + 4.958309173583984 + ] + } + ], + "cameras" : [ + { + "name" : "Camera", + "perspective" : { + "aspectRatio" : 1.7777777777777777, + "yfov" : 0.39959652046304894, + "zfar" : 100, + "znear" : 0.10000000149011612 + }, + "type" : "perspective" + } + ], + "materials" : [ + { + "doubleSided" : true, + "name" : "Material", + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1 + ], + "metallicFactor" : 0, + "roughnessFactor" : 0.4000000059604645 + } + } + ], + "meshes" : [ + { + "name" : "Cube", + "primitives" : [ + { + "attributes" : { + "POSITION" : 0, + "NORMAL" : 1, + "TEXCOORD_0" : 2 + }, + "indices" : 3, + "material" : 0 + } + ] + } + ], + "accessors" : [ + { + "bufferView" : 0, + "componentType" : 5126, + "count" : 24, + "max" : [ + 1, + 1, + 1 + ], + "min" : [ + -1, + -1, + -1 + ], + "type" : "VEC3" + }, + { + "bufferView" : 1, + "componentType" : 5126, + "count" : 24, + "type" : "VEC3" + }, + { + "bufferView" : 2, + "componentType" : 5126, + "count" : 24, + "type" : "VEC2" + }, + { + "bufferView" : 3, + "componentType" : 5123, + "count" : 36, + "type" : "SCALAR" + } + ], + "bufferViews" : [ + { + "buffer" : 0, + "byteLength" : 288, + "byteOffset" : 0 + }, + { + "buffer" : 0, + "byteLength" : 288, + "byteOffset" : 288 + }, + { + "buffer" : 0, + "byteLength" : 192, + "byteOffset" : 576 + }, + { + "buffer" : 0, + "byteLength" : 72, + "byteOffset" : 768 + } + ], + "buffers" : [ + { + "byteLength" : 840, + "uri" : "data:application/octet-stream;base64,AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIC/AACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AACAvwAAAAAAAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIC/AAAgPwAAAD8AACA/AAAAPwAAID8AAAA/AADAPgAAAD8AAMA+AAAAPwAAwD4AAAA/AAAgPwAAgD4AACA/AACAPgAAID8AAIA+AADAPgAAgD4AAMA+AACAPgAAwD4AAIA+AAAgPwAAQD8AAGA/AAAAPwAAID8AAEA/AADAPgAAQD8AAAA+AAAAPwAAwD4AAEA/AAAgPwAAgD8AACA/AAAAAAAAYD8AAIA+AADAPgAAgD8AAMA+AAAAAAAAAD4AAIA+AAANABQAAAAUAAcACQAGABMACQATABYAFQASAAwAFQAMAA8AEAADAAoAEAAKABcABQACAAgABQAIAAsAEQAOAAEAEQABAAQA" + } + ] +} diff --git a/resources/meshes/gizmo-arrow.glb b/resources/meshes/gizmo-arrow.glb new file mode 100644 index 00000000..9239f884 Binary files /dev/null and b/resources/meshes/gizmo-arrow.glb differ diff --git a/resources/meshes/gizmo-scale.glb b/resources/meshes/gizmo-scale.glb new file mode 100644 index 00000000..d9592754 Binary files /dev/null and b/resources/meshes/gizmo-scale.glb differ diff --git a/resources/meshes/gizmo-torus.glb b/resources/meshes/gizmo-torus.glb new file mode 100644 index 00000000..b90e5971 Binary files /dev/null and b/resources/meshes/gizmo-torus.glb differ diff --git a/resources/meshes/sphere-ico.glb b/resources/meshes/sphere-ico.glb new file mode 100644 index 00000000..7ed65157 Binary files /dev/null and b/resources/meshes/sphere-ico.glb differ diff --git a/resources/scripts/uniform-array.lua b/resources/scripts/uniform-array.lua index bd16d25d..5fab0a36 100644 --- a/resources/scripts/uniform-array.lua +++ b/resources/scripts/uniform-array.lua @@ -1,5 +1,6 @@ function interface(INOUT) + INOUT.bvec = Type:Array(3, Type:Bool()) INOUT.ivec = Type:Array(2, Type:Int32()) INOUT.fvec = Type:Array(5, Type:Float()) diff --git a/resources/scripts/uniform-structs.lua b/resources/scripts/uniform-structs.lua index 9941f48e..b3565b35 100644 --- a/resources/scripts/uniform-structs.lua +++ b/resources/scripts/uniform-structs.lua @@ -1,6 +1,7 @@ function interface(INOUT) local struct_prim = { + b = Type:Bool(), i = Type:Int32(), f = Type:Float(), @@ -14,6 +15,7 @@ function interface(INOUT) } local struct_array_prim = { + bvec = Type:Array(3, Type:Bool()), ivec = Type:Array(2, Type:Int32()), fvec = Type:Array(5, Type:Float()), diff --git a/resources/shaders/include/uniforms_frag.glsl b/resources/shaders/include/uniforms_frag.glsl index 226751c7..90f78b3b 100644 --- a/resources/shaders/include/uniforms_frag.glsl +++ b/resources/shaders/include/uniforms_frag.glsl @@ -1,2 +1,3 @@ +uniform bool b; uniform int i; uniform float f; diff --git a/resources/shaders/uniform-array.frag b/resources/shaders/uniform-array.frag index 5cc80df7..eedb45c8 100644 --- a/resources/shaders/uniform-array.frag +++ b/resources/shaders/uniform-array.frag @@ -4,6 +4,7 @@ precision mediump float; uniform float scalar; +uniform bool bvec[3]; uniform int ivec[2]; uniform float fvec[5]; diff --git a/resources/shaders/uniform-scalar.frag b/resources/shaders/uniform-scalar.frag index cc80675d..f101ee15 100644 --- a/resources/shaders/uniform-scalar.frag +++ b/resources/shaders/uniform-scalar.frag @@ -2,6 +2,7 @@ precision mediump float; +uniform bool b; uniform int i; uniform float f; diff --git a/resources/shaders/uniform-struct.frag b/resources/shaders/uniform-struct.frag index be46af56..f3746fd0 100644 --- a/resources/shaders/uniform-struct.frag +++ b/resources/shaders/uniform-struct.frag @@ -3,6 +3,7 @@ precision mediump float; struct struct_prim { + bool b; int i; float f; @@ -23,6 +24,7 @@ struct struct_sampler { }; struct struct_array_prim { + bool bvec[3]; int ivec[2]; float fvec[5]; diff --git a/screenshot_tests/CMakeLists.txt b/screenshot_tests/CMakeLists.txt index 120eadaa..74d713d8 100644 --- a/screenshot_tests/CMakeLists.txt +++ b/screenshot_tests/CMakeLists.txt @@ -10,10 +10,10 @@ If a copy of the MPL was not distributed with this file, You can obtain one at h if(WIN32) set(RACO_EXE "$") - set(VIEWER_EXE "$/ramses-logic-viewer.exe") + set(VIEWER_EXE "$/ramses-viewer.exe") else() set(RACO_EXE "$.sh") - set(VIEWER_EXE "$/ramses-logic-viewer.sh") + set(VIEWER_EXE "$/ramses-viewer.sh") endif() macro(add_screenshot_test TESTNAME PROJECTPATH) @@ -34,7 +34,6 @@ if(WIN32) generated empty duck - morphing skinning ) @@ -44,16 +43,21 @@ if(WIN32) advanced/external_references/composite_road advanced/external_references/simple_road advanced/modules/modules + advanced/morphing/morphing advanced/nested_prefabs/toy_cars advanced/python_api/broken_link + advanced/skinning/skinning-simple + basics/blitpass/blitpass basics/hello_world/cube basics/monkey/monkey + basics/multisampling/msaa basics/offscreen/offscreen basics/ordering/1_by_scene_graph basics/ordering/2_by_tags_priority basics/ordering/3_by_render_pass_slots basics/ordering/4_by_render_pass basics/ordering/5_nested_render_layers + basics/ordering/6_dynamic_render_order basics/prefabs/lantern_road basics/stencil_testing/stencil ) @@ -72,13 +76,13 @@ if(WIN32) add_custom_command( OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/expected/${projectname}.png MAIN_DEPENDENCY ${projectpath} - DEPENDS ramses-logic-viewer RaCoEditor + DEPENDS ramses-viewer RaCoEditor WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_SOURCE_DIR}/exported/" COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_SOURCE_DIR}/expected/" COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_SOURCE_DIR}/actual/" COMMAND ${RACO_EXE} -p ${projectpath} -e ${CMAKE_CURRENT_SOURCE_DIR}/exported/${projectname} -l 3 - COMMAND ${VIEWER_EXE} "${CMAKE_CURRENT_SOURCE_DIR}/exported/${projectname}.ramses" "${CMAKE_CURRENT_SOURCE_DIR}/exported/${projectname}.rlogic" --exec-lua "rlogic.screenshot('expected/${projectname}.png')" + COMMAND ${VIEWER_EXE} --gui on --exec-lua "R.screenshot('expected/${projectname}.png')" "${CMAKE_CURRENT_SOURCE_DIR}/exported/${projectname}.ramses" ) LIST(APPEND RACO_SCREENSHOT_REF_FILES "${CMAKE_CURRENT_SOURCE_DIR}/expected/${projectname}.png") diff --git a/screenshot_tests/expected/6_dynamic_render_order.png b/screenshot_tests/expected/6_dynamic_render_order.png new file mode 100644 index 00000000..74316c8e --- /dev/null +++ b/screenshot_tests/expected/6_dynamic_render_order.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f266dbcde26e3618e31670a9d6ca53bceac5a9e126cd0cd78e2cb3720dfdab6 +size 1808 diff --git a/screenshot_tests/expected/animations.png b/screenshot_tests/expected/animations.png index 599b55bf..533bac69 100644 --- a/screenshot_tests/expected/animations.png +++ b/screenshot_tests/expected/animations.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4eaf87b7705c6102d69c36ab1395ee87d2b4d8490fdce621871620576028646c +oid sha256:01efeb6d261298ae76b3ab5c88ac208a1122581e0e33bd5cab468b19ecbfb0f4 size 913 diff --git a/screenshot_tests/expected/blitpass.png b/screenshot_tests/expected/blitpass.png new file mode 100644 index 00000000..c9bfad1d --- /dev/null +++ b/screenshot_tests/expected/blitpass.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18476fc7b0432512c53afc154149312e7191611a1b1cf7353a1522c2fa62c556 +size 14142 diff --git a/screenshot_tests/expected/empty.png b/screenshot_tests/expected/empty.png index c044cf86..83fe6e4e 100644 --- a/screenshot_tests/expected/empty.png +++ b/screenshot_tests/expected/empty.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:de677179dfccd187e3f2a753c00e4a88ebb812cd1c173eedd18a86b9ea584d49 -size 413 +oid sha256:8ae0f9e5a601bbcf0230c1be81315284d1b415182aed271907e4b3d128b27e65 +size 7026 diff --git a/screenshot_tests/expected/morphing.png b/screenshot_tests/expected/morphing.png index 5a4ac426..30c2cb7f 100644 --- a/screenshot_tests/expected/morphing.png +++ b/screenshot_tests/expected/morphing.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fda19328cee64f4d7d9a07f22ef5d7b8eaa98a61f9e4d5a52757472839bce273 -size 1017 +oid sha256:18bd518000dba2e056c96827f59f9f91e6c099dd5a178181395847c32baec8ee +size 2238 diff --git a/screenshot_tests/expected/msaa.png b/screenshot_tests/expected/msaa.png new file mode 100644 index 00000000..f1d52840 --- /dev/null +++ b/screenshot_tests/expected/msaa.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55fa4935c6eb944084c9d04737729d70be428bdae16cd106b025aca495ff7c4c +size 7705 diff --git a/screenshot_tests/expected/skinning-simple.png b/screenshot_tests/expected/skinning-simple.png new file mode 100644 index 00000000..2cc14b74 --- /dev/null +++ b/screenshot_tests/expected/skinning-simple.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6687274d68682224cc6be0bed2b430d88a34843b5c76ec34a9a7ac41ed5be734 +size 1792 diff --git a/screenshot_tests/projects/empty.rca b/screenshot_tests/projects/empty.rca index c1db13c0..7ad9ceb2 100644 --- a/screenshot_tests/projects/empty.rca +++ b/screenshot_tests/projects/empty.rca @@ -2,7 +2,7 @@ "externalProjects": { }, "featureLevel": 1, - "fileVersion": 47, + "fileVersion": 2001, "instances": [ { "properties": { @@ -290,125 +290,103 @@ }, { "properties": { - "materialFilterMode": 1, - "objectID": "3256d315-0a3f-47bc-b42b-678a153fdc51", - "objectName": "MainRenderLayer", - "renderableTags": { - "order": [ - "render_main" - ], - "properties": { - "render_main": { - "annotations": [ - { - "properties": { - "featureLevel": 3 - }, - "typeName": "LinkEndAnnotation" - } - ], - "typeName": "Int::LinkEndAnnotation", - "value": 0 - } - } - }, - "sortOrder": 0 - }, - "typeName": "RenderLayer" - }, - { - "properties": { - "camera": "304aaf29-72fb-4108-9df5-9353e234c09c", - "clearColor": { - "w": { + "children": [ + "dd8bcfc1-9c5b-4ace-9735-99daea7f3cad" + ], + "enabled": true, + "objectID": "bcac3fc2-91a4-4be6-a345-1ca055e835f9", + "objectName": "Node", + "rotation": { + "x": { "annotations": [ { "properties": { - "max": 1, - "min": 0 + "max": 360, + "min": -360 }, "typeName": "RangeAnnotationDouble" } ], "value": 0 }, - "x": { + "y": { "annotations": [ { "properties": { - "max": 1, - "min": 0 + "max": 360, + "min": -360 }, "typeName": "RangeAnnotationDouble" } ], "value": 0 }, - "y": { + "z": { "annotations": [ { "properties": { - "max": 1, - "min": 0 + "max": 360, + "min": -360 }, "typeName": "RangeAnnotationDouble" } ], "value": 0 + } + }, + "scaling": { + "x": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 + }, + "y": { + "annotations": [ + { + "properties": { + "max": 100, + "min": 0.1 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 1 }, "z": { "annotations": [ { "properties": { - "max": 1, - "min": 0 + "max": 100, + "min": 0.1 }, "typeName": "RangeAnnotationDouble" } ], - "value": 0 + "value": 1 } }, - "enableClearColor": true, - "enableClearDepth": true, - "enableClearStencil": true, - "enabled": true, - "layer0": "3256d315-0a3f-47bc-b42b-678a153fdc51", - "layer1": null, - "layer2": null, - "layer3": null, - "layer4": null, - "layer5": null, - "layer6": null, - "layer7": null, - "objectID": "79f2e106-038a-4e6e-bdd8-42bd1033ab48", - "objectName": "MainRenderPass", - "renderOnce": false, - "renderOrder": 1, - "target": null - }, - "typeName": "RenderPass" - }, - { - "properties": { - "children": { + "tags": { "properties": [ { - "typeName": "Ref", - "value": "dd8bcfc1-9c5b-4ace-9735-99daea7f3cad" + "typeName": "String", + "value": "render_main" } ] }, - "enabled": true, - "objectID": "bcac3fc2-91a4-4be6-a345-1ca055e835f9", - "objectName": "Node", - "rotation": { + "translation": { "x": { "annotations": [ { "properties": { - "max": 360, - "min": -360 + "max": 100, + "min": -100 }, "typeName": "RangeAnnotationDouble" } @@ -419,8 +397,8 @@ "annotations": [ { "properties": { - "max": 360, - "min": -360 + "max": 100, + "min": -100 }, "typeName": "RangeAnnotationDouble" } @@ -431,8 +409,8 @@ "annotations": [ { "properties": { - "max": 360, - "min": -360 + "max": 100, + "min": -100 }, "typeName": "RangeAnnotationDouble" } @@ -440,59 +418,164 @@ "value": 0 } }, - "scaling": { - "x": { + "visibility": true + }, + "typeName": "Node" + }, + { + "properties": { + "backgroundColor": { + "w": { "annotations": [ { "properties": { - "max": 100, - "min": 0.1 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } ], "value": 1 }, + "x": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, "y": { "annotations": [ { "properties": { - "max": 100, - "min": 0.1 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } ], - "value": 1 + "value": 0 }, "z": { "annotations": [ { "properties": { - "max": 100, - "min": 0.1 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } ], - "value": 1 + "value": 0 } }, - "tags": { - "properties": [ + "defaultResourceFolders": { + "imageSubdirectory": "images", + "interfaceSubdirectory": "interfaces", + "meshSubdirectory": "meshes", + "scriptSubdirectory": "scripts", + "shaderSubdirectory": "shaders" + }, + "featureLevel": 1, + "objectID": "ee85a4d6-4a4d-439e-85fe-e590dd9967cd", + "objectName": "empty", + "saveAsZip": false, + "sceneId": { + "annotations": [ { - "typeName": "String", - "value": "render_main" + "properties": { + "max": 1024, + "min": 1 + }, + "typeName": "RangeAnnotationInt" } - ] + ], + "value": 123 }, - "translation": { + "viewport": { + "i1": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 1440 + }, + "i2": { + "annotations": [ + { + "properties": { + "max": 4096, + "min": 0 + }, + "typeName": "RangeAnnotationInt" + } + ], + "value": 720 + } + } + }, + "typeName": "ProjectSettings" + }, + { + "properties": { + "materialFilterMode": 1, + "objectID": "3256d315-0a3f-47bc-b42b-678a153fdc51", + "objectName": "MainRenderLayer", + "renderableTags": { + "order": [ + "render_main" + ], + "properties": { + "render_main": { + "annotations": [ + { + "properties": { + "featureLevel": 1 + }, + "typeName": "LinkEndAnnotation" + } + ], + "typeName": "Int::LinkEndAnnotation", + "value": 0 + } + } + }, + "sortOrder": 0 + }, + "typeName": "RenderLayer" + }, + { + "properties": { + "camera": "304aaf29-72fb-4108-9df5-9353e234c09c", + "clearColor": { + "w": { + "annotations": [ + { + "properties": { + "max": 1, + "min": 0 + }, + "typeName": "RangeAnnotationDouble" + } + ], + "value": 0 + }, "x": { "annotations": [ { "properties": { - "max": 100, - "min": -100 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } @@ -503,8 +586,8 @@ "annotations": [ { "properties": { - "max": 100, - "min": -100 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } @@ -515,8 +598,8 @@ "annotations": [ { "properties": { - "max": 100, - "min": -100 + "max": 1, + "min": 0 }, "typeName": "RangeAnnotationDouble" } @@ -524,9 +607,27 @@ "value": 0 } }, - "visibility": true + "enableClearColor": true, + "enableClearDepth": true, + "enableClearStencil": true, + "enabled": true, + "layers": [ + "3256d315-0a3f-47bc-b42b-678a153fdc51", + null, + null, + null, + null, + null, + null, + null + ], + "objectID": "79f2e106-038a-4e6e-bdd8-42bd1033ab48", + "objectName": "MainRenderPass", + "renderOnce": false, + "renderOrder": 1, + "target": null }, - "typeName": "Node" + "typeName": "RenderPass" }, { "properties": { @@ -541,7 +642,7 @@ "typeName": "RangeAnnotationInt" } ], - "value": 1 + "value": -1 }, "mesh": null, "objectID": "dd8bcfc1-9c5b-4ace-9735-99daea7f3cad", @@ -663,128 +764,19 @@ "visibility": true }, "typeName": "MeshNode" - }, - { - "properties": { - "backgroundColor": { - "w": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 1 - }, - "x": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "y": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - }, - "z": { - "annotations": [ - { - "properties": { - "max": 1, - "min": 0 - }, - "typeName": "RangeAnnotationDouble" - } - ], - "value": 0 - } - }, - "defaultResourceFolders": { - "imageSubdirectory": "images", - "interfaceSubdirectory": "interfaces", - "meshSubdirectory": "meshes", - "scriptSubdirectory": "scripts", - "shaderSubdirectory": "shaders" - }, - "featureLevel": 1, - "objectID": "ee85a4d6-4a4d-439e-85fe-e590dd9967cd", - "objectName": "empty", - "saveAsZip": false, - "sceneId": { - "annotations": [ - { - "properties": { - "max": 1024, - "min": 1 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 123 - }, - "viewport": { - "i1": { - "annotations": [ - { - "properties": { - "max": 4096, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 1440 - }, - "i2": { - "annotations": [ - { - "properties": { - "max": 4096, - "min": 0 - }, - "typeName": "RangeAnnotationInt" - } - ], - "value": 720 - } - } - }, - "typeName": "ProjectSettings" } ], "links": [ ], - "logicEngineVersion": [ - 1, - 4, - 0 - ], "racoVersion": [ - 1, - 6, + 2, + 0, 0 ], "ramsesVersion": [ - 27, + 28, 0, - 126 + 0 ], "structPropMap": { "AnchorPointOutputs": { @@ -799,9 +791,12 @@ "blendFactorSrcColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", "blendOperationAlpha": "Int::DisplayNameAnnotation::EnumerationAnnotation", "blendOperationColor": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "colorWriteMask": "ColorWriteMask::DisplayNameAnnotation", "cullmode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "depthFunction": "Int::DisplayNameAnnotation::EnumerationAnnotation", - "depthwrite": "Bool::DisplayNameAnnotation" + "depthwrite": "Bool::DisplayNameAnnotation", + "scissorOptions": "ScissorOptions::DisplayNameAnnotation", + "stencilOptions": "StencilOptions::DisplayNameAnnotation" }, "CameraViewport": { "height": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", @@ -809,6 +804,12 @@ "offsetY": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", "width": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation" }, + "ColorWriteMask": { + "alpha": "Bool::DisplayNameAnnotation", + "blue": "Bool::DisplayNameAnnotation", + "green": "Bool::DisplayNameAnnotation", + "red": "Bool::DisplayNameAnnotation" + }, "DefaultResourceDirectories": { "imageSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", "interfaceSubdirectory": "String::DisplayNameAnnotation::URIAnnotation", @@ -831,6 +832,18 @@ "rightPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", "topPlane": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation" }, + "ScissorOptions": { + "scissorEnable": "Bool::DisplayNameAnnotation", + "scissorRegion": "CameraViewport::DisplayNameAnnotation" + }, + "StencilOptions": { + "stencilFunc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilMask": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "stencilOpDepthFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpDepthSucc": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilOpStencilFail": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "stencilRef": "Int::DisplayNameAnnotation::RangeAnnotationInt" + }, "TimerInput": { "ticker_us": "Int64::DisplayNameAnnotation::LinkEndAnnotation" }, @@ -871,34 +884,41 @@ "userTypePropMap": { "AnchorPoint": { "camera": "BaseCamera::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "node": "Node::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "outputs": "AnchorPointOutputs::DisplayNameAnnotation" + "outputs": "AnchorPointOutputs::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Animation": { - "animationChannels": "Table::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "animationChannels": "Array[AnimationChannel]::DisplayNameAnnotation::ResizableArray", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "outputs": "Table::DisplayNameAnnotation", - "progress": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation" + "progress": "Double::DisplayNameAnnotation::RangeAnnotationDouble::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "AnimationChannel": { "animationIndex": "Int::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "samplerIndex": "Int::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "BlitPass": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "destinationX": "Int::RangeAnnotationInt::DisplayNameAnnotation", "destinationY": "Int::RangeAnnotationInt::DisplayNameAnnotation", "enabled": "Bool::DisplayNameAnnotation", "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "renderOrder": "Int::DisplayNameAnnotation", @@ -908,11 +928,12 @@ "sourceY": "Int::RangeAnnotationInt::DisplayNameAnnotation", "targetRenderBuffer": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", "targetRenderBufferMS": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" }, "CubeMap": { "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "generateMipmaps": "Bool::DisplayNameAnnotation", "level2uriBack": "String::URIAnnotation::DisplayNameAnnotation", "level2uriBottom": "String::URIAnnotation::DisplayNameAnnotation", @@ -933,6 +954,7 @@ "level4uriRight": "String::URIAnnotation::DisplayNameAnnotation", "level4uriTop": "String::URIAnnotation::DisplayNameAnnotation", "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", "objectID": "String::HiddenProperty", @@ -944,35 +966,45 @@ "uriLeft": "String::URIAnnotation::DisplayNameAnnotation", "uriRight": "String::URIAnnotation::DisplayNameAnnotation", "uriTop": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" }, "LuaInterface": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "inputs": "Table::DisplayNameAnnotation::LinkStartAnnotation::LinkEndAnnotation", + "luaModules": "Table::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "LuaScript": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "inputs": "Table::DisplayNameAnnotation::LinkEndAnnotation", "luaModules": "Table::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "outputs": "Table::DisplayNameAnnotation", "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "LuaScriptModule": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "stdModules": "LuaStandardModuleSelection::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Material": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "options": "BlendOptions::DisplayNameAnnotation", @@ -981,77 +1013,91 @@ "uriDefines": "String::URIAnnotation::DisplayNameAnnotation", "uriFragment": "String::URIAnnotation::DisplayNameAnnotation", "uriGeometry": "String::URIAnnotation::DisplayNameAnnotation", - "uriVertex": "String::URIAnnotation::DisplayNameAnnotation" + "uriVertex": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Mesh": { "bakeMeshes": "Bool::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "materialNames": "Table::ArraySemanticAnnotation::HiddenProperty", "meshIndex": "Int::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "MeshNode": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", - "instanceCount": "Int::DisplayNameAnnotation::RangeAnnotationInt", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "instanceCount": "Int::RangeAnnotationInt::DisplayNameAnnotation::LinkEndAnnotation", "materials": "Table::DisplayNameAnnotation", "mesh": "Mesh::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "Node": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "OrthographicCamera": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", "frustum": "OrthographicFrustum::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "PerspectiveCamera": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", "frustum": "Table::DisplayNameAnnotation::LinkEndAnnotation", - "frustumType": "Int::DisplayNameAnnotation::EnumerationAnnotation::FeatureLevel", + "frustumType": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "scaling": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "viewport": "CameraViewport::DisplayNameAnnotation::LinkEndAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "Prefab": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", - "objectName": "String::DisplayNameAnnotation" + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "PrefabInstance": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "rotation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", @@ -1059,11 +1105,12 @@ "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", "template": "Prefab::DisplayNameAnnotation", "translation": "Vec3f::DisplayNameAnnotation::LinkEndAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "visibility": "Bool::DisplayNameAnnotation::LinkEndAnnotation" }, "ProjectSettings": { "backgroundColor": "Vec4f::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "defaultResourceFolders": "DefaultResourceDirectories::DisplayNameAnnotation", "featureLevel": "Int::DisplayNameAnnotation::ReadOnlyAnnotation", "objectID": "String::HiddenProperty", @@ -1074,112 +1121,123 @@ }, "RenderBuffer": { "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "width": "Int::RangeAnnotationInt::DisplayNameAnnotation", "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" }, "RenderBufferMS": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "format": "Int::DisplayNameAnnotation::EnumerationAnnotation", "height": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "sampleCount": "Int::RangeAnnotationInt::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "width": "Int::RangeAnnotationInt::DisplayNameAnnotation" }, "RenderLayer": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "materialFilterMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "materialFilterTags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "renderableTags": "Table::RenderableTagContainerAnnotation::DisplayNameAnnotation", "sortOrder": "Int::DisplayNameAnnotation::EnumerationAnnotation", - "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation" + "tags": "Table::ArraySemanticAnnotation::HiddenProperty::TagContainerAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "RenderPass": { "camera": "BaseCamera::DisplayNameAnnotation", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "clearColor": "Vec4f::DisplayNameAnnotation::LinkEndAnnotation", "enableClearColor": "Bool::DisplayNameAnnotation", "enableClearDepth": "Bool::DisplayNameAnnotation", "enableClearStencil": "Bool::DisplayNameAnnotation", "enabled": "Bool::DisplayNameAnnotation::LinkEndAnnotation", - "layer0": "RenderLayer::DisplayNameAnnotation", - "layer1": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer2": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer3": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer4": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer5": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer6": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", - "layer7": "RenderLayer::DisplayNameAnnotation::EmptyReferenceAllowable", + "layers": "Array[RenderLayer]::DisplayNameAnnotation::EmptyReferenceAllowable::ResizableArray", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "renderOnce": "Bool::DisplayNameAnnotation::LinkEndAnnotation::FeatureLevel", + "renderOnce": "Bool::DisplayNameAnnotation::LinkEndAnnotation", "renderOrder": "Int::DisplayNameAnnotation::LinkEndAnnotation", - "target": "RenderTarget::DisplayNameAnnotation::EmptyReferenceAllowable" + "target": "RenderTargetBase::DisplayNameAnnotation::EmptyReferenceAllowable", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "RenderTarget": { - "buffer0": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer1": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer2": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer3": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer4": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer5": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer6": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "buffer7": "RenderBuffer::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS0": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS1": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS2": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS3": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS4": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS5": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS6": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "bufferMS7": "RenderBufferMS::DisplayNameAnnotation::EmptyReferenceAllowable", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "buffers": "Array[RenderBuffer]::DisplayNameAnnotation::EmptyReferenceAllowable::ResizableArray", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, + "RenderTargetMS": { + "buffers": "Array[RenderBufferMS]::DisplayNameAnnotation::EmptyReferenceAllowable::ResizableArray", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", - "objectName": "String::DisplayNameAnnotation" + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Skin": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", - "joints": "Table::DisplayNameAnnotation", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "joints": "Array[Node]::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "skinIndex": "Int::DisplayNameAnnotation", - "targets": "Table::DisplayNameAnnotation", - "uri": "String::URIAnnotation::DisplayNameAnnotation" + "targets": "Array[MeshNode]::DisplayNameAnnotation::ResizableArray", + "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" }, "Texture": { "anisotropy": "Int::DisplayNameAnnotation::RangeAnnotationInt", - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "flipTexture": "Bool::DisplayNameAnnotation", "generateMipmaps": "Bool::DisplayNameAnnotation", "level2uri": "String::URIAnnotation::DisplayNameAnnotation", "level3uri": "String::URIAnnotation::DisplayNameAnnotation", "level4uri": "String::URIAnnotation::DisplayNameAnnotation", "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", "mipmapLevel": "Int::DisplayNameAnnotation::RangeAnnotationInt", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", "textureFormat": "Int::DisplayNameAnnotation::EnumerationAnnotation", "uri": "String::URIAnnotation::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation", "wrapUMode": "Int::DisplayNameAnnotation::EnumerationAnnotation", "wrapVMode": "Int::DisplayNameAnnotation::EnumerationAnnotation" }, + "TextureExternal": { + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", + "magSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "metaData": "Table::DisplayNameAnnotation", + "minSamplingMethod": "Int::DisplayNameAnnotation::EnumerationAnnotation", + "objectID": "String::HiddenProperty", + "objectName": "String::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" + }, "Timer": { - "children": "Table::ArraySemanticAnnotation::HiddenProperty", + "children": "Array[Ref]::ArraySemanticAnnotation::HiddenProperty", "inputs": "TimerInput::DisplayNameAnnotation", + "metaData": "Table::DisplayNameAnnotation", "objectID": "String::HiddenProperty", "objectName": "String::DisplayNameAnnotation", - "outputs": "TimerOutput::DisplayNameAnnotation" + "outputs": "TimerOutput::DisplayNameAnnotation", + "userTags": "Table::ArraySemanticAnnotation::HiddenProperty::UserTagContainerAnnotation::DisplayNameAnnotation" } } } diff --git a/screenshot_tests/projects/shaders/morphing-template.frag b/screenshot_tests/projects/shaders/morphing-template.frag deleted file mode 100644 index 44b0cd4a..00000000 --- a/screenshot_tests/projects/shaders/morphing-template.frag +++ /dev/null @@ -1,13 +0,0 @@ -#version 300 es - -precision highp float; - -in float intensity; - -out vec4 FragColor; - -uniform vec3 u_color; - -void main() { - FragColor = vec4(u_color.rgb * intensity, 1.0); -} diff --git a/screenshot_tests/projects/shaders/morphing-template.vert b/screenshot_tests/projects/shaders/morphing-template.vert deleted file mode 100644 index 0d075ab2..00000000 --- a/screenshot_tests/projects/shaders/morphing-template.vert +++ /dev/null @@ -1,34 +0,0 @@ -#version 300 es - -precision highp float; - -in vec3 a_Position; -in vec3 a_Position_Morph_0; -in vec3 a_Position_Morph_1; - -in vec3 a_Normal; -in vec3 a_Normal_Morph_0; -in vec3 a_Normal_Morph_1; - -uniform mat4 u_MVPMatrix; -uniform mat4 u_NMatrix; - -uniform float weights[2]; - -out float intensity; - -void main() { - vec3 lightdir = (vec4(normalize(vec3(1.5, -2.4, -3.0)), 0.0)).xyz; - - vec3 m_Normal = a_Normal - + weights[0] * a_Normal_Morph_0 - + weights[1] * a_Normal_Morph_1; - vec3 normal = normalize((u_NMatrix * vec4(m_Normal, 0.0)).xyz); - - intensity = max(dot(-lightdir, normal), 0.0); - - gl_Position = u_MVPMatrix * vec4(a_Position - + weights[0] * a_Position_Morph_0 - + weights[1] * a_Position_Morph_1, - 1.0); -} \ No newline at end of file diff --git a/screenshot_tests/screenshot_test.cmake b/screenshot_tests/screenshot_test.cmake index 685dfbae..d62a87ec 100644 --- a/screenshot_tests/screenshot_test.cmake +++ b/screenshot_tests/screenshot_test.cmake @@ -6,7 +6,7 @@ execute_process( COMMAND_ERROR_IS_FATAL ANY ) execute_process( - COMMAND ${VIEWER_EXE} exported/${TEST_NAME}.ramses exported/${TEST_NAME}.rlogic --exec-lua "rlogic.screenshot('actual/${TEST_NAME}.png')" + COMMAND ${VIEWER_EXE} --gui on --exec-lua "R.screenshot('actual/${TEST_NAME}.png')" exported/${TEST_NAME}.ramses COMMAND_ERROR_IS_FATAL ANY ) execute_process( diff --git a/styles/_Default/icons/abstract_scene_view.svg b/styles/_Default/icons/abstract_scene_view.svg new file mode 100644 index 00000000..f5ba654d --- /dev/null +++ b/styles/_Default/icons/abstract_scene_view.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/styles/_Default/icons/prefabLookup.svg b/styles/_Default/icons/prefabLookup.svg new file mode 100644 index 00000000..1e600968 --- /dev/null +++ b/styles/_Default/icons/prefabLookup.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/styles/icons.qrc b/styles/icons.qrc index 661594c5..bcb22efa 100644 --- a/styles/icons.qrc +++ b/styles/icons.qrc @@ -66,5 +66,7 @@ _Default/icons/visibility_white_24dp.svg _Default/icons/visibility_off_white_24dp.svg _Default/icons/visibility_disabled_white_24dp.svg + _Default/icons/abstract_scene_view.svg + _Default/icons/prefabLookup.svg diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index 5c2695de..58f47673 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -8,6 +8,9 @@ This Source Code Form is subject to the terms of the Mozilla Public License, v. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. ]] +set(BOOST_INCLUDE_LIBRARIES spirit) +add_subdirectory(boost/ EXCLUDE_FROM_ALL) + set(SPDLOG_WCHAR_FILENAMES ON CACHE BOOL "" FORCE) add_subdirectory(spdlog/) set_target_properties(spdlog PROPERTIES FOLDER third_party) @@ -35,11 +38,8 @@ set_target_properties(tinygltf PROPERTIES ) ## GLM -add_library(glm INTERFACE) -target_include_directories(glm INTERFACE glm/) -set_target_properties(glm PROPERTIES - FOLDER third_party/glm -) +# Note GLM is now included in Ramses 28 so we don't need this as a submodule anymore + ## pybind11 add_subdirectory(pybind11) @@ -64,84 +64,43 @@ set_target_properties(zip uninstall test_append.out test_entry.out test_extract. ) # Configure ramses-sdk build options -set(ramses-sdk_BUILD_TOOLS OFF CACHE BOOL "" FORCE) -set(ramses-sdk_BUILD_IVI_TEST_APPS OFF CACHE BOOL "" FORCE) -set(ramses-sdk_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) -set(ramses-sdk_BUILD_DEMOS OFF CACHE BOOL "" FORCE) -set(ramses-sdk_BUILD_DEMO_ECM OFF CACHE BOOL "" FORCE) -set(ramses-sdk_BUILD_SMOKE_TESTS OFF CACHE BOOL "" FORCE) -set(ramses-sdk_BUILD_TESTS OFF CACHE BOOL "" FORCE) -set(ramses-sdk_ENABLE_WAYLAND_SHELL OFF CACHE BOOL "" FORCE) -set(ramses-sdk_ENABLE_DLT OFF CACHE BOOL "" FORCE) +set(ramses-sdk_WARNINGS_AS_ERRORS OFF CACHE BOOL "" FORCE) +set(ramses-sdk_ENABLE_INSTALL OFF CACHE BOOL "" FORCE) set(ramses-sdk_BUILD_WITH_LTO OFF CACHE BOOL "" FORCE) -set(ramses-sdk_FORCE_OFF_SOMEIP_IC ON CACHE BOOL "" FORCE) -set(ramses-sdk_FORCE_USE_SOMEIP_IC OFF CACHE BOOL "" FORCE) -# These need to be set -set(ramses-sdk_WARNINGS_AS_ERRORS OFF CACHE BOOL "" FORCE) set(ramses-sdk_BUILD_FULL_SHARED_LIB ON CACHE BOOL "" FORCE) -set(ramses-sdk_BUILD_CLIENT_ONLY_SHARED_LIB ON CACHE BOOL "" FORCE) -set(ramses-sdk_CONSOLE_LOGLEVEL "info" CACHE STRING "" FORCE) -# TODO: why are we building ramses-daemon? -set(ramses-sdk_BUILD_TOOLS ON CACHE BOOL "" FORCE) +set(ramses-sdk_BUILD_HEADLESS_SHARED_LIB ON CACHE BOOL "" FORCE) -# TODO: check if we need to enable this +set(ramses-sdk_ENABLE_LOGIC ON CACHE BOOL "" FORCE) set(ramses-sdk_ENABLE_TCP_SUPPORT OFF CACHE BOOL "" FORCE) +set(ramses-sdk_ENABLE_DLT OFF CACHE BOOL "" FORCE) -add_subdirectory(ramses-logic/external/ramses/ EXCLUDE_FROM_ALL) - -if (CMAKE_SYSTEM_NAME STREQUAL Windows) - # es-3-0 / 4-5 / 4-2-core - add_library(raco::ramses-lib ALIAS ramses-shared-lib-windows-wgl-4-5) -endif() -if (CMAKE_SYSTEM_NAME STREQUAL Linux) - add_library(raco::ramses-lib ALIAS ramses-shared-lib-x11-egl-es-3-0) -endif() - -add_library(raco::ramses-lib-client-only ALIAS ramses-shared-lib-client-only) - - -set(ramses-logic_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) -set(ramses-logic_BUILD_TOOLS ON CACHE BOOL "" FORCE) -set(ramses-logic_ALLOW_RAMSES_BUILD OFF CACHE BOOL "" FORCE) -set(ramses-logic_RAMSES_TARGET "raco::ramses-lib" CACHE STRING "" FORCE) -set(ramses-logic_WARNINGS_AS_ERRORS OFF CACHE BOOL "" FORCE) -add_subdirectory(ramses-logic/ EXCLUDE_FROM_ALL) +set(ramses-sdk_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) +set(ramses-sdk_BUILD_DEMOS OFF CACHE BOOL "" FORCE) +set(ramses-sdk_BUILD_TOOLS ON CACHE BOOL "" FORCE) +set(ramses-sdk_BUILD_TESTS OFF CACHE BOOL "" FORCE) -add_library(ramses-logic-api INTERFACE) -target_include_directories(ramses-logic-api INTERFACE - ramses-logic/include -) +set(ramses-sdk_ALLOW_PLATFORM_GLM OFF CACHE BOOL "" FORCE) -function(add_ramses_logic_target TARGET RAMSES_TARGET) - add_library(${TARGET} SHARED) - target_link_libraries(${TARGET} PRIVATE ramses-logic-obj) - target_link_libraries(${TARGET} PUBLIC ${RAMSES_TARGET}) - target_include_directories(${TARGET} PUBLIC ramses-logic/include) - set_target_properties(${TARGET} PROPERTIES - PUBLIC_HEADER "${public_headers}" - SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} - ) - folderize_target(${TARGET} "third_party/ramses-logic") -endfunction() +add_subdirectory(ramses/ EXCLUDE_FROM_ALL) -add_library(raco::ramses-logic-lib ALIAS ramses-logic) +add_library(raco::ramses-lib ALIAS ramses-shared-lib) +add_library(raco::ramses-lib-client-only ALIAS ramses-shared-lib-headless) -add_ramses_logic_target(ramses-logic-shared-lib-client-only ramses-shared-lib-client-only) -add_library(raco::ramses-logic-lib-client-only ALIAS ramses-logic-shared-lib-client-only) if (CMAKE_SYSTEM_NAME STREQUAL Linux) find_program(LINUXDEPLOYQT linuxdeployqt) if(EXISTS "${LINUXDEPLOYQT}") - add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/ramses-logic-viewer - COMMAND ${CMAKE_COMMAND} -E rm -f "$/ramses-logic-viewer.sh" - COMMAND ${CMAKE_COMMAND} -D TARGET_FILE=$/ramses-logic-viewer -D ROOT_DIR=${CMAKE_SOURCE_DIR} -P "${CMAKE_SOURCE_DIR}/ubuntustartscript.cmake" - COMMAND chmod +x "$/ramses-logic-viewer.sh" - DEPENDS ramses-logic-viewer RaCoEditor + add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/ramses-viewer + COMMAND ${CMAKE_COMMAND} -E rm -f "$/ramses-viewer.sh" + COMMAND ${CMAKE_COMMAND} -D TARGET_FILE=$/ramses-viewer -D ROOT_DIR=${CMAKE_SOURCE_DIR} -P "${CMAKE_SOURCE_DIR}/ubuntustartscript.cmake" + COMMAND chmod +x "$/ramses-viewer.sh" + DEPENDS ramses-viewer RaCoEditor ) - add_custom_target(generate_ramses_logic_viewer_launch_script ALL - DEPENDS ${CMAKE_BINARY_DIR}/ramses-logic-viewer + add_custom_target(generate_ramses_viewer_launch_script ALL + DEPENDS ${CMAKE_BINARY_DIR}/ramses-viewer + ) endif() endif() diff --git a/third_party/boost b/third_party/boost new file mode 160000 index 00000000..549eb04b --- /dev/null +++ b/third_party/boost @@ -0,0 +1 @@ +Subproject commit 549eb04bedbc767ec02be803e79b2ebaa50627a1 diff --git a/third_party/glm b/third_party/glm deleted file mode 160000 index bf71a834..00000000 --- a/third_party/glm +++ /dev/null @@ -1 +0,0 @@ -Subproject commit bf71a834948186f4097caa076cd2663c69a10e1e diff --git a/third_party/ramses b/third_party/ramses new file mode 160000 index 00000000..93d7dc08 --- /dev/null +++ b/third_party/ramses @@ -0,0 +1 @@ +Subproject commit 93d7dc085df3136cfc008b3d52610d1fff43e6f7 diff --git a/third_party/ramses-logic b/third_party/ramses-logic deleted file mode 160000 index a58dd77f..00000000 --- a/third_party/ramses-logic +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a58dd77f2b3f87ed18181a9599e3e697a0451ec8 diff --git a/utils/libLogSystem/include/log_system/log.h b/utils/libLogSystem/include/log_system/log.h index 480e080a..938f1bd7 100644 --- a/utils/libLogSystem/include/log_system/log.h +++ b/utils/libLogSystem/include/log_system/log.h @@ -47,9 +47,9 @@ constexpr const char* LOG_FILE_EXTENSION = ".log"; constexpr size_t MAX_LOG_FILES = 10; -void init(const raco::utils::u8path& logFilePath = {}); +void init(const utils::u8path& logFilePath = {}); -void init(const raco::utils::u8path& logFileDirectory, const std::string& logFileBaseName, int64_t pid); +void init(const utils::u8path& logFileDirectory, const std::string& logFileBaseName, int64_t pid); void deinit(); void registerSink(const SinkPtr sink); diff --git a/utils/libLogSystem/src/log.cpp b/utils/libLogSystem/src/log.cpp index 5393fda3..c8bb1101 100644 --- a/utils/libLogSystem/src/log.cpp +++ b/utils/libLogSystem/src/log.cpp @@ -81,7 +81,7 @@ void setup_loggers() { } -void init(const raco::utils::u8path& logFilePath) { +void init(const utils::u8path& logFilePath) { if (initialized) { LOG_WARNING(LOGGING, "log_system already initialized - call has no effect."); return; @@ -116,7 +116,7 @@ void init(const raco::utils::u8path& logFilePath) { } -void init(const raco::utils::u8path& logFileDirectory, const std::string& logFileBaseName, int64_t pid) { +void init(const utils::u8path& logFileDirectory, const std::string& logFileBaseName, int64_t pid) { if (initialized) { LOG_WARNING(LOGGING, "log_system already initialized - call has no effect."); return; diff --git a/utils/libUtils/tests/ShaderPreprocessor_test.cpp b/utils/libUtils/tests/ShaderPreprocessor_test.cpp index da8409d7..c6d9d1e6 100644 --- a/utils/libUtils/tests/ShaderPreprocessor_test.cpp +++ b/utils/libUtils/tests/ShaderPreprocessor_test.cpp @@ -105,7 +105,7 @@ TEST_F(ShaderPreprocessorTest, missingIncludedFileTest) { } TEST_F(ShaderPreprocessorTest, chinesePathLoaded) { - const u8path chinesePath{std::filesystem::path(L"\u96E8\u4E2D_1.txt")}; // 雨中; + const u8path chinesePath{u8"\u96E8\u4E2D_1.txt"}; // 雨中; const auto chineseFullPath{(test_path() / "shaders/include" / chinesePath).string()}; file::write(chineseFullPath, "contents1"); @@ -116,7 +116,7 @@ TEST_F(ShaderPreprocessorTest, chinesePathLoaded) { } TEST_F(ShaderPreprocessorTest, chineseIncludeProcessed) { - const u8path chinesePath{std::filesystem::path(L"\u96E8\u4E2D_2.txt")}; // 雨中; + const u8path chinesePath{u8"\u96E8\u4E2D_2.txt"}; // 雨中; const auto chineseFullPath{(test_path() / "shaders/include" / chinesePath).string()}; file::write(chineseFullPath, "contents2");