diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..184f3cc --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,17 @@ +--- +Checks: > + google-*, + performance-*, + portability-*, + readability-*, + modernize-*, + misc-include-cleaner, + -google-build-using-namespace, + -readability-identifier-length, + -readability-math-missing-parentheses, + -readability-uppercase-literal-suffix, + -google-readability-namespace-comments, + -readability-named-parameter, + -readability-implicit-bool-conversion, + -readability-magic-numbers, + -modernize-use-trailing-return-type diff --git a/CMakeLists.txt b/CMakeLists.txt index 9751db7..e9afb86 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,7 @@ cmake_minimum_required(VERSION 3.22) -include(FetchContent) - project(vsgCs - VERSION 0.2.0 + VERSION 0.9.0 DESCRIPTION "VSG library for rendering 3D Tiles and Cesium ion assets" LANGUAGES CXX C ) @@ -15,8 +13,8 @@ SET(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${vsgCs_SOURCE_DIR}/CMakeModules") include("vsgCsMacros") -# set the use of C++17 globally as all examples require it -set(CMAKE_CXX_STANDARD 17) +# set the use of C++20 as Cesium Native requires it +set(CMAKE_CXX_STANDARD 20) if (MSVC) # template madness @@ -28,113 +26,56 @@ endif() option(BUILD_SHARED_LIBS "Build using shared libraries" OFF) option(RUN_CLANG_TIDY "run the clang-tidy checker" OFF) +set(VSGCS_CESIUM_NATIVE_DIRECTORY "" CACHE PATH "directory for Cesium Native source if not installed") # Find Vulkan and the VSG if (VULKAN_SDK) set(ENV{VULKAN_SDK} ${VULKAN_SDK}) endif() -if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24) - SET(USE_FETCHCONTENT_DEFAULT ON) -else() - SET(USE_FETCHCONTENT_DEFAULT OFF) -endif() - -option(VSGCS_USE_FETCHCONTENT "Use FetchContent to build dependencies" ${USE_FETCHCONTENT_DEFAULT}) - set(VSG_MIN_VERSION 1.1.0) -if(VSGCS_USE_FETCHCONTENT) - FetchContent_Declare(vsg - GIT_REPOSITORY https://github.com/vsg-dev/VulkanSceneGraph.git - GIT_TAG master - GIT_PROGRESS TRUE - FIND_PACKAGE_ARGS ${VSG_MIN_VERSION} - ) - - FetchContent_MakeAvailable(vsg) -else() - find_package(vsg ${VSG_MIN_VERSION}) -endif() - -# find_package(vsg) includes vsgMacros -if (vsg_SOURCE_DIR) - SET(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${vsg_SOURCE_DIR}/cmake") - include("vsgMacros") -endif() +find_package(vsg ${VSG_MIN_VERSION} REQUIRED) find_package(vsgXchange) set(VSGIMGUI_MIN_VERSION 0.1.0) -if(VSGCS_USE_FETCHCONTENT) - FetchContent_Declare(vsgImGui - GIT_REPOSITORY https://github.com/vsg-dev/vsgImGui.git - GIT_TAG v0.1.0 - GIT_PROGRESS TRUE - FIND_PACKAGE_ARGS ${VSGIMGUI_MIN_VERSION} - ) +find_package(vsgImGui ${VSGIMGUI_MIN_VERSION} REQUIRED) - FetchContent_MakeAvailable(vsgImGui) +if(VSGCS_CESIUM_NATIVE_DIRECTORY) + add_subdirectory(${VSGCS_CESIUM_NATIVE_DIRECTORY} cesium-native) else() - find_package(vsgImGui ${VSGIMGUI_MIN_VERSION}) -endif() - -if(VSGCS_USE_FETCHCONTENT) - # Wrangle Cesium's dependencies into shape i.e., install them! - option(CESIUM_SPDLOG_HEADER_ONLY "Whether to use the header-only version of spdlog." OFF) - option(GSL_INSTALL "Generate and install GSL target" ON) - # XXX Not ready for cesium-native as a package yet... - FetchContent_Declare(cesium-native - GIT_REPOSITORY https://github.com/timoore/cesium-native.git - GIT_TAG 791a85712cbbb22ef7cd8f13498997d45b108546 # cmake-fixes - GIT_PROGRESS TRUE - ) - - message("Fetching cesium-native. This could take a while...") - FetchContent_MakeAvailable(cesium-native) -else() - # XXX This may not go well. - find_package(cesium-native) + find_package(cesium-native REQUIRED) endif() find_package(PROJ REQUIRED) - -if (RUN_CLANG_TIDY) - find_program(CLANG_TIDY_EXE NAMES "clang-tidy") - if(CLANG_TIDY_EXE) - set(CMAKE_CXX_CLANG_TIDY clang-tidy -checks=google-*,performance-*,portability-*,readability-*,modernize-*,-google-build-using-namespace,-readability-identifier-length,-readability-uppercase-literal-suffix,-google-readability-namespace-comments,-readability-named-parameter,-readability-implicit-bool-conversion,-readability-magic-numbers,-modernize-use-trailing-return-type) +find_package(imgui REQUIRED) +find_package(tinyxml2 REQUIRED) +find_package(spdlog REQUIRED) + +if(PROJECT_IS_TOP_LEVEL) + set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) + + find_program(CLANG_TIDY_EXECUTABLE clang-tidy) + find_program(RUN_CLANG_TIDY_EXECUTABLE run-clang-tidy) + + if(CLANG_TIDY_EXECUTABLE AND RUN_CLANG_TIDY_EXECUTABLE) + add_custom_target(run-clang-tidy + COMMAND ${RUN_CLANG_TIDY_EXECUTABLE} + -clang-tidy-binary ${CLANG_TIDY_EXECUTABLE} + -p ${CMAKE_BINARY_DIR} + ) endif() endif() vsgCs_setup_build_vars() -# This does include(GNUInstallDirs), which sets up all the correct install directories. -vsg_setup_dir_vars() -set(GENERATED_HEADERS_DIR "${PROJECT_BINARY_DIR}/include") +include(GNUInstallDirs) set(VSGCS_DATA_DIR "${CMAKE_INSTALL_DATADIR}/vsgCs") set(VSGCS_FULL_DATA_DIR "${CMAKE_INSTALL_FULL_DATADIR}/vsgCs") -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/vsgCs/Config.h.in" - "${GENERATED_HEADERS_DIR}/vsgCs/Config.h") - -vsg_add_target_clobber() -vsg_add_target_docs( - FILES - ${CMAKE_SOURCE_DIR}/include -) -vsg_add_target_uninstall() - -vsg_add_option_maintainer( - PREFIX ${PROJECT_NAME} - RCLEVEL ${VSGCS_RELEASE_CANDIDATE} -) - -# Make the headers visible to everything. This is not OSG / VSG style, -# but we prefer that include files live next to their source files. -include_directories(${vsgCs_SOURCE_DIR}/src ${GENERATED_HEADERS_DIR}) - if(WIN32) set(CMAKE_INSTALL_UCRT_LIBRARIES YES) @@ -146,7 +87,8 @@ endif() add_subdirectory(src) add_subdirectory(data) -vsg_add_feature_summary() +include(FeatureSummary) +feature_summary(WHAT ALL) option(BUILD_TRACY "build with tracy profiling and server" OFF) diff --git a/CMakeModules/Fedora41Toolchain.cmake b/CMakeModules/Fedora41Toolchain.cmake new file mode 100644 index 0000000..c30f8e4 --- /dev/null +++ b/CMakeModules/Fedora41Toolchain.cmake @@ -0,0 +1,4 @@ +# Work around a bug in patchelf, which doesn't work with the ELF file arrangement in Fedora 41 +set(VCPKG_LINKER_FLAGS "-Wl,-z,noseparate-code") + +include("$ENV{VCPKG_ROOT}/scripts/toolchains/linux.cmake") diff --git a/CMakeModules/vsgCsMacros.cmake b/CMakeModules/vsgCsMacros.cmake index 8be7986..cbc3242 100644 --- a/CMakeModules/vsgCsMacros.cmake +++ b/CMakeModules/vsgCsMacros.cmake @@ -2,11 +2,6 @@ # and will set them up differently macro(vsgCs_setup_build_vars) - set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "add a postfix, usually d on windows") - set(CMAKE_RELEASE_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows") - set(CMAKE_RELWITHDEBINFO_POSTFIX "rd" CACHE STRING "add a postfix, usually empty on windows") - set(CMAKE_MINSIZEREL_POSTFIX "s" CACHE STRING "add a postfix, usually empty on windows") - # Change the default build type to Release if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE) @@ -14,21 +9,11 @@ macro(vsgCs_setup_build_vars) if(CMAKE_COMPILER_IS_GNUCXX) set(VSGCS_WARNING_FLAGS -Wall -Wextra -Wpedantic CACHE STRING "Compile flags to use.") - set(CMAKE_COMPILE_WARNING_AS_ERROR YES CACHE BOOL "Treat warnings as errors") elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") set(VSGCS_WARNING_FLAGS -Wall -Wextra -Wparenthese -Wreturn-type -Wmissing-braces -Wunknown-pragmas -Wshadow -Wunused CACHE STRING "Compile flags to use.") - set(CMAKE_COMPILE_WARNING_AS_ERROR YES CACHE BOOL "Treat warnings as errors") else() set(VSGCS_WARNING_FLAGS CACHE STRING "Compile flags to use.") - set(CMAKE_COMPILE_WARNING_AS_ERROR NO CACHE BOOL "Treat warnings as errors") endif() add_compile_options(${VSGCS_WARNING_FLAGS}) - - # set upper case _VERSION_... variables - string(TOUPPER ${PROJECT_NAME} UPPER_PROJECT_NAME) - set(${UPPER_PROJECT_NAME}_VERSION ${PROJECT_VERSION}) - set(${UPPER_PROJECT_NAME}_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) - set(${UPPER_PROJECT_NAME}_VERSION_MINOR ${PROJECT_VERSION_MINOR}) - set(${UPPER_PROJECT_NAME}_VERSION_PATCH ${PROJECT_VERSION_PATCH}) endmacro() diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..499053f --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,66 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "vcpkg-debug", + "binaryDir": "${sourceDir}/build-debug", + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake", + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "vcpkg", + "inherits": "vcpkg-debug", + "binaryDir": "${sourceDir}/build-release", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "Windows-Devel", + "inherits": "vcpkg-debug", + "generator": "Visual Studio 17 2022", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake", + "VCPKG_TARGET_TRIPLET": "x64-windows-static-md", + "VCPKG_TRIPLET": "x64-windows-static-md" + } + }, + { + "name": "Windows-Devel-Release", + "inherits": "Windows-Devel", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "Strict", + "cacheVariables": { + "CMAKE_COMPILE_WARNING_AS_ERROR": "YES" + } + }, + { + "name": "local-cesium-native", + "cacheVariables": { + "VCPKG_MANIFEST_NO_DEFAULT_FEATURES": true, + "VCPKG_MANIFEST_FEATURES": "cesium-native-local" + } + } + ], + "buildPresets": [ + { + "name": "Windows-Debug", + "displayName": "Windows Debug", + "configurePreset": "Windows-Devel", + "configuration": "Debug" + }, + { + "name": "Windows-Release", + "displayName": "Windows Release", + "configurePreset": "Windows-Devel-Release", + "configuration": "Release" + } + ] +} diff --git a/INSTALL.md b/INSTALL.md index 84f4ae8..7cfe99b 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,16 +1,8 @@ # Build and Installation ## Prerequisites -vsgCs uses the `FetchContent` package of `cmake` to download most -dependencies. This is convenient for casual users, but might be too -inflexible if you want to use your own version of those -dependencies. You can force `FetchContent` to use the source code in a -certain location by setting the corresponding -`FETCHCONTENT_SOURCE_DIR_` variable e.g., to use your own version of -Cesium Native sources, set `FETCHCONTENT_SOURCE_DIR_CESIUM`. - -These dependencies are not downloaded via `FetchContent` and should be -installed manually: + +These dependencies and should be installed manually: - `libcurl` This is best installed via a package manager. - the [Vulkan SDK](https://vulkan.lunarg.com/sdk/home) from LunarG. Follow installation instructions diff --git a/README.md b/README.md index 73ee57f..725af6e 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,9 @@ application (worldviewer) on Linux: The `cmake` part may take a long time to download the Cesium Native library and its dependencies. If you encounter a git error, see [the install instructions](INSTALL.md) for possible workarounds. +## vcpkg + +Install `xorg-macros`, `xproto`, xcb-proto`, `libXdmcp-devel`, `libXau-devel` --- diff --git a/extern/vcpkg-overlays/asyncplusplus/portfile.cmake b/extern/vcpkg-overlays/asyncplusplus/portfile.cmake new file mode 100644 index 0000000..54b343b --- /dev/null +++ b/extern/vcpkg-overlays/asyncplusplus/portfile.cmake @@ -0,0 +1,21 @@ +vcpkg_check_linkage(ONLY_STATIC_LIBRARY) + +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO Amanieu/asyncplusplus + REF 4159da79e20ad6d0eb1f13baa0f10e989edd9fba + SHA512 a7b099ce24184aa56e843d4858228196f8220374585a375a9c0d944832bd68c8aabd6b2efde5aacbb9c73f9dd8e942e97262be04550205b3fbea44d8b972d78e + HEAD_REF master +) + +vcpkg_cmake_configure( + SOURCE_PATH "${SOURCE_PATH}" +) + +vcpkg_cmake_install() + +vcpkg_cmake_config_fixup(CONFIG_PATH cmake PACKAGE_NAME async++) + +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include" "${CURRENT_PACKAGES_DIR}/debug/share") + +file(INSTALL "${SOURCE_PATH}/LICENSE" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright) diff --git a/extern/vcpkg-overlays/asyncplusplus/vcpkg.json b/extern/vcpkg-overlays/asyncplusplus/vcpkg.json new file mode 100644 index 0000000..6b59776 --- /dev/null +++ b/extern/vcpkg-overlays/asyncplusplus/vcpkg.json @@ -0,0 +1,18 @@ +{ + "name": "asyncplusplus", + "version": "1.1", + "port-version": 2, + "description": "Async++ is a lightweight concurrency framework for C++11", + "license": "MIT", + "supports": "!uwp", + "dependencies": [ + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + } + ] +} diff --git a/extern/vcpkg-overlays/cesium-native/portfile.cmake b/extern/vcpkg-overlays/cesium-native/portfile.cmake new file mode 100644 index 0000000..d9b0595 --- /dev/null +++ b/extern/vcpkg-overlays/cesium-native/portfile.cmake @@ -0,0 +1,29 @@ +vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS + FEATURES + dependencies-only CESIUM_NATIVE_DEPS_ONLY +) + +if(CESIUM_NATIVE_DEPS_ONLY) + message(STATUS "skipping installation of cesium-native") + set(VCPKG_POLICY_EMPTY_PACKAGE enabled) + return() +endif() + +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO timoore/cesium-native + REF 6c1b1edd4ee388f6372dcfe1c33de6839696e5b4 + SHA512 1dd74feefe20dc0363c42f5b1a03d271de5d37cc86078ecc1090fa1c3517284c04ee0ae9f6c622f2b6391a48bccbf59a9b0f342e4e21f33a78c1cb85845b8b98 + HEAD_REF vcpkg-pkg + ) + +vcpkg_cmake_configure( + SOURCE_PATH "${SOURCE_PATH}" + OPTIONS + -DCESIUM_USE_EZVCPKG=OFF + ) + +vcpkg_cmake_install() +vcpkg_cmake_config_fixup(CONFIG_PATH lib/cmake/cesium-native PACKAGE_NAME cesium-native) +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include" "${CURRENT_PACKAGES_DIR}/debug/share") + diff --git a/extern/vcpkg-overlays/cesium-native/vcpkg.json b/extern/vcpkg-overlays/cesium-native/vcpkg.json new file mode 100644 index 0000000..a10be2d --- /dev/null +++ b/extern/vcpkg-overlays/cesium-native/vcpkg.json @@ -0,0 +1,43 @@ +{ + "name": "cesium-native", + "version-string": "0.41.0", + "features": { + "dependencies-only": { + "description": "install port's dependencies without the port" + } + }, + "dependencies": [ + "vcpkg-cmake", + "vcpkg-cmake-config", + "asyncplusplus", + "catch2", + "expected-lite", + "fmt", + "glm", + "ms-gsl", + "rapidjson", + "spdlog", + "stb", + "uriparser", + "draco", + { + "name": "ktx", + "default-features": false + }, + "modp-base64", + "meshoptimizer", + "openssl", + "s2geometry", + "libjpeg-turbo", + "sqlite3", + "tinyxml2", + "libwebp", + "zlib-ng", + "picosha2", + "earcut-hpp", + "cpp-httplib", + "libmorton", + "zstd" + ] +} + diff --git a/extern/vcpkg-overlays/vsgimgui/devendor.patch b/extern/vcpkg-overlays/vsgimgui/devendor.patch new file mode 100644 index 0000000..aba25a8 --- /dev/null +++ b/extern/vcpkg-overlays/vsgimgui/devendor.patch @@ -0,0 +1,150 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index a9e6265..96a2ecb 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -22,34 +22,13 @@ if (VULKAN_SDK) + set(ENV{VULKAN_SDK} ${VULKAN_SDK}) + endif() + +-find_package(vsg 1.0.5) ++find_package(vsg REQUIRED) ++find_package(imgui REQUIRED) ++find_package(implot REQUIRED) + + vsg_setup_dir_vars() + vsg_setup_build_vars() + +-if ( (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src/imgui/imgui.h) OR +- (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src/implot/implot.h) ) +- find_package(Git QUIET) +- +- execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive +- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +- RESULT_VARIABLE GIT_SUBMOD_RESULT) +- +- if(NOT GIT_SUBMOD_RESULT EQUAL "0") +- message(FATAL_ERROR "git submodule update --init --recursive failed with ${GIT_SUBMOD_RESULT}, please checkout submodules") +- endif() +-endif() +- +-vsg_copy_imgui_headers( +- FILES +- ${VSGIMGUI_SOURCE_DIR}/src/imgui/imgui.h +- ${VSGIMGUI_SOURCE_DIR}/src/imgui/imconfig.h +- ${VSGIMGUI_SOURCE_DIR}/src/imgui/imgui_internal.h +- ${VSGIMGUI_SOURCE_DIR}/src/imgui/imstb_textedit.h +- ${VSGIMGUI_SOURCE_DIR}/src/imgui//misc/cpp/imgui_stdlib.h +- ${VSGIMGUI_SOURCE_DIR}/src/implot/implot.h +- ${VSGIMGUI_SOURCE_DIR}/src/implot/implot_internal.h +-) + + vsg_add_target_clang_format( + FILES +diff --git a/include/vsgImGui/RenderImGui.h b/include/vsgImGui/RenderImGui.h +index b4210d2..33198e4 100644 +--- a/include/vsgImGui/RenderImGui.h ++++ b/include/vsgImGui/RenderImGui.h +@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include + + #include +-#include ++#include + + namespace vsgImGui + { +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index 41d749d..919159e 100644 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -6,40 +6,21 @@ set(EXTRA_INCLUDES) + SET(HEADER_PATH ${VSGIMGUI_SOURCE_DIR}/include/vsgImGui) + + set(HEADERS +- ${HEADER_PATH}/imgui.h + ${HEADER_PATH}/SendEventsToImGui.h + ${HEADER_PATH}/RenderImGui.h + ${HEADER_PATH}/Texture.h +- imgui/imconfig.h +- imgui/imgui_internal.h +- imgui/imstb_rectpack.h +- imgui/imstb_textedit.h +- imgui/imstb_truetype.h +- imgui/misc/cpp/imgui_stdlib.h +- implot/implot.h +- implot/implot_internal.h + ) + + set(SOURCES + vsgImGui/RenderImGui.cpp + vsgImGui/SendEventsToImGui.cpp + vsgImGui/Texture.cpp +- imgui/imgui.cpp +- imgui/imgui_draw.cpp +- imgui/imgui_tables.cpp +- imgui/imgui_widgets.cpp +- imgui/backends/imgui_impl_vulkan.cpp +- imgui/misc/cpp/imgui_stdlib.cpp +- implot/implot.cpp +- implot/implot_items.cpp + ) + + OPTION(SHOW_DEMO_WINDOW "Toggle the build of the ImGui::ShowDemoWindow(bool*) and ImPlot::ShadowDemoWindow(bool*)" ON) + + if (SHOW_DEMO_WINDOW) + set(SOURCES ${SOURCES} +- imgui/imgui_demo.cpp +- implot/implot_demo.cpp + ) + else() + set(SOURCES ${SOURCES} +@@ -73,6 +54,8 @@ target_include_directories(vsgImGui PUBLIC + target_link_libraries(vsgImGui + PUBLIC + vsg::vsg ++ imgui::imgui ++ implot::implot + PRIVATE + ${EXTRA_LIBRARIES} + ) +diff --git a/src/vsgImGui/RenderImGui.cpp b/src/vsgImGui/RenderImGui.cpp +index 5d7cf06..dac2227 100644 +--- a/src/vsgImGui/RenderImGui.cpp ++++ b/src/vsgImGui/RenderImGui.cpp +@@ -22,9 +22,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + #include +-#include ++#include + +-#include "../imgui/backends/imgui_impl_vulkan.h" ++#include + + #include + #include +diff --git a/src/vsgImGui/SendEventsToImGui.cpp b/src/vsgImGui/SendEventsToImGui.cpp +index 4e83e4c..b1f4d83 100644 +--- a/src/vsgImGui/SendEventsToImGui.cpp ++++ b/src/vsgImGui/SendEventsToImGui.cpp +@@ -22,7 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + #include +-#include ++#include + + #include + #include +diff --git a/src/vsgImGuiConfig.cmake.in b/src/vsgImGuiConfig.cmake.in +index e2c14f2..5cf8bd9 100644 +--- a/src/vsgImGuiConfig.cmake.in ++++ b/src/vsgImGuiConfig.cmake.in +@@ -2,5 +2,7 @@ include(CMakeFindDependencyMacro) + + find_dependency(Vulkan) + find_dependency(vsg) ++find_dependency(imgui) ++find_dependency(implot) + + include("${CMAKE_CURRENT_LIST_DIR}/vsgImGuiTargets.cmake") diff --git a/extern/vcpkg-overlays/vsgimgui/imtextureid.patch b/extern/vcpkg-overlays/vsgimgui/imtextureid.patch new file mode 100644 index 0000000..3db879c --- /dev/null +++ b/extern/vcpkg-overlays/vsgimgui/imtextureid.patch @@ -0,0 +1,25 @@ +diff --git a/include/vsgImGui/Export.h b/include/vsgImGui/Export.h +index f6a3b2e..05884c5 100644 +--- a/include/vsgImGui/Export.h ++++ b/include/vsgImGui/Export.h +@@ -39,4 +39,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #define IMPLOT_API VSGIMGUI_DECLSPEC + + #include +-#define ImTextureID VkDescriptorSet ++namespace vsgImGui ++{ ++ typedef unsigned long long ImTextureID_t; ++} ++#define ImTextureID vsgImGui::ImTextureID_t +diff --git a/src/vsgImGui/Texture.cpp b/src/vsgImGui/Texture.cpp +index ca5e3d7..31a268b 100644 +--- a/src/vsgImGui/Texture.cpp ++++ b/src/vsgImGui/Texture.cpp +@@ -84,5 +84,5 @@ void Texture::compile(vsg::Context& context) + + ImTextureID Texture::id(uint32_t deviceID) const + { +- return descriptorSet ? static_cast(descriptorSet->vk(deviceID)) : ImTextureID{}; ++ return descriptorSet ? reinterpret_cast(descriptorSet->vk(deviceID)) : ImTextureID{}; + } diff --git a/extern/vcpkg-overlays/vsgimgui/portfile.cmake b/extern/vcpkg-overlays/vsgimgui/portfile.cmake new file mode 100644 index 0000000..198f81d --- /dev/null +++ b/extern/vcpkg-overlays/vsgimgui/portfile.cmake @@ -0,0 +1,22 @@ +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO vsg-dev/vsgImGui + REF "v${VERSION}" + SHA512 f27ef25edb95c2129553732054080582a6990b6d84ae6f3ff2007489f02cfcb6ce3f728eb56b584315f5e9835daf74d104962b07b35463ba655bf7aa5c99489c + HEAD_REF master + PATCHES + devendor.patch + remove-manual-font-creation.patch + imtextureid.patch +) + +file(REMOVE "${SOURCE_PATH}/include/vsgImGui/imgui.h") + +vcpkg_cmake_configure(SOURCE_PATH "${SOURCE_PATH}") +vcpkg_cmake_install() +vcpkg_cmake_config_fixup(PACKAGE_NAME "vsgImGui" CONFIG_PATH "lib/cmake/vsgImGui") +vcpkg_copy_pdbs() + +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include") +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/share") +vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE.md") diff --git a/extern/vcpkg-overlays/vsgimgui/remove-manual-font-creation.patch b/extern/vcpkg-overlays/vsgimgui/remove-manual-font-creation.patch new file mode 100644 index 0000000..4ca7e1c --- /dev/null +++ b/extern/vcpkg-overlays/vsgimgui/remove-manual-font-creation.patch @@ -0,0 +1,44 @@ +diff --git a/include/vsgImGui/RenderImGui.h b/include/vsgImGui/RenderImGui.h +index e8186c6..8059d75 100644 +--- a/include/vsgImGui/RenderImGui.h ++++ b/include/vsgImGui/RenderImGui.h +@@ -86,7 +86,6 @@ namespace vsgImGui + vsg::ref_ptr renderPass, + uint32_t minImageCount, uint32_t imageCount, + VkExtent2D imageSize, bool useClearAttachments); +- void _uploadFonts(); + }; + + } // namespace vsgImGui +diff --git a/src/vsgImGui/RenderImGui.cpp b/src/vsgImGui/RenderImGui.cpp +index 306030b..d662531 100644 +--- a/src/vsgImGui/RenderImGui.cpp ++++ b/src/vsgImGui/RenderImGui.cpp +@@ -60,7 +60,6 @@ namespace vsgImGui + RenderImGui::RenderImGui(const vsg::ref_ptr& window, bool useClearAttachments) + { + _init(window, useClearAttachments); +- _uploadFonts(); + } + + RenderImGui::RenderImGui(vsg::ref_ptr device, uint32_t queueFamily, +@@ -69,7 +68,6 @@ RenderImGui::RenderImGui(vsg::ref_ptr device, uint32_t queueFamily, + VkExtent2D imageSize, bool useClearAttachments) + { + _init(device, queueFamily, renderPass, minImageCount, imageCount, imageSize, useClearAttachments); +- _uploadFonts(); + } + + RenderImGui::~RenderImGui() +@@ -184,11 +182,6 @@ void RenderImGui::_init( + } + } + +-void RenderImGui::_uploadFonts() +-{ +- ImGui_ImplVulkan_CreateFontsTexture(); +-} +- + void RenderImGui::accept(vsg::RecordTraversal& rt) const + { + auto& commandBuffer = *(rt.getState()->_commandBuffer); diff --git a/extern/vcpkg-overlays/vsgimgui/vcpkg.json b/extern/vcpkg-overlays/vsgimgui/vcpkg.json new file mode 100644 index 0000000..fb7056c --- /dev/null +++ b/extern/vcpkg-overlays/vsgimgui/vcpkg.json @@ -0,0 +1,25 @@ +{ + "name": "vsgimgui", + "version": "0.3.0", + "description": "Library that integrates VulkanSceneGraph with Dear ImGui & ImPlot.", + "homepage": "https://github.com/vsg-dev/vsgImGui", + "license": "MIT", + "dependencies": [ + { + "name": "imgui", + "features": [ + "vulkan-binding" + ] + }, + "implot", + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + }, + "vsg" + ] +} diff --git a/src/CsApp/CMakeLists.txt b/src/CsApp/CMakeLists.txt index c718bee..d9c06db 100644 --- a/src/CsApp/CMakeLists.txt +++ b/src/CsApp/CMakeLists.txt @@ -29,7 +29,9 @@ else() target_compile_definitions(${LIB_NAME} PUBLIC VSGCS_LIBRARY_STATIC) endif() -target_link_libraries(${LIB_NAME} PUBLIC vsgCs vsg::vsg vsgImGui::vsgImGui Cesium3DTilesSelection CesiumGltfReader CesiumGltf tinyxml2) +target_include_directories(${LIB_NAME} PUBLIC $) + +target_link_libraries(${LIB_NAME} PUBLIC vsgCs vsg::vsg vsgImGui::vsgImGui Cesium3DTilesSelection CesiumGltfReader CesiumGltf tinyxml2::tinyxml2 imgui::imgui) if(BUILD_TRACY) target_link_libraries(${LIB_NAME} PUBLIC Tracy::TracyClient) diff --git a/src/CsApp/CreditComponent.cpp b/src/CsApp/CreditComponent.cpp index 364d3ea..752de64 100644 --- a/src/CsApp/CreditComponent.cpp +++ b/src/CsApp/CreditComponent.cpp @@ -24,7 +24,7 @@ SOFTWARE. #include #include -#include +#include #include "CreditComponent.h" #include "vsgCs/Config.h" diff --git a/src/CsApp/CsViewer.h b/src/CsApp/CsViewer.h index 9e65bc4..6dbb526 100644 --- a/src/CsApp/CsViewer.h +++ b/src/CsApp/CsViewer.h @@ -24,7 +24,7 @@ SOFTWARE. #pragma once -#include "Export.h" +#include "vsgCs/Export.h" #include diff --git a/src/CsApp/MapManipulator.cpp b/src/CsApp/MapManipulator.cpp index 9b1cf18..0a96b3d 100644 --- a/src/CsApp/MapManipulator.cpp +++ b/src/CsApp/MapManipulator.cpp @@ -54,7 +54,8 @@ namespace // normalized linear intep template vsg::dvec3 nlerp(const DVEC3& a, const DVEC3& b, double t) { - double am = length(a), bm = length(b); + double am = length(a); + double bm = length(b); vsg::dvec3 c = a*(1.0-t) + b*t; c = normalize(c); c *= (1.0-t)*am + t*bm; @@ -169,7 +170,7 @@ MapManipulator::Action::init() bool MapManipulator::Action::getBoolOption(int option, bool defaultValue) const { - for (auto& i : _options) + for (const auto& i : _options) if (i.option == option) return i.boolValue; @@ -179,7 +180,7 @@ MapManipulator::Action::getBoolOption(int option, bool defaultValue) const int MapManipulator::Action::getIntOption(int option, int defaultValue) const { - for (auto& i : _options) + for (const auto& i : _options) if (i.option == option) return i.intValue; @@ -189,7 +190,7 @@ MapManipulator::Action::getIntOption(int option, int defaultValue) const double MapManipulator::Action::getDoubleOption(int option, double defaultValue) const { - for (auto& i : _options) + for (const auto& i : _options) if (i.option == option) return i.doubleValue; @@ -202,7 +203,7 @@ MapManipulator::Action MapManipulator::NullAction( MapManipulator::ACTION_NULL ) namespace { - static std::string s_actionNames[] = { + std::string s_actionNames[] = { "null", "home", "goto", @@ -222,7 +223,7 @@ namespace "earth-drag" }; - static std::string s_actionOptionNames[] = { + std::string s_actionOptionNames[] = { "scale-x", "scale-y", "continuous", @@ -242,9 +243,6 @@ namespace MapManipulator::InputSpec::InputSpec(int event_type, int input_mask, int modkey_mask) : _event_type(event_type), _input_mask(input_mask), _modkey_mask(modkey_mask) { } -MapManipulator::InputSpec::InputSpec(const InputSpec& rhs) - : _event_type(rhs._event_type), _input_mask(rhs._input_mask), _modkey_mask(rhs._modkey_mask) { } - bool MapManipulator::InputSpec::operator == (const InputSpec& rhs) const { return @@ -256,10 +254,10 @@ MapManipulator::InputSpec::operator == (const InputSpec& rhs) const { bool MapManipulator::InputSpec::operator < (const InputSpec& rhs) const { if (_event_type < rhs._event_type) return true; - else if (_event_type > rhs._event_type) return false; - else if (_input_mask < rhs._input_mask) return true; - else if (_input_mask > rhs._input_mask) return false; - else return (_modkey_mask < rhs._modkey_mask); + if (_event_type > rhs._event_type) return false; + if (_input_mask < rhs._input_mask) return true; + if (_input_mask > rhs._input_mask) return false; + return (_modkey_mask < rhs._modkey_mask); } @@ -325,7 +323,7 @@ MapManipulator::Settings::Settings(const MapManipulator::Settings& rhs) : // expands one input spec into many if necessary, to deal with modifier key combos. void -MapManipulator::Settings::expandSpec(const InputSpec& input, InputSpecs& output) const +MapManipulator::Settings::expandSpec(const InputSpec& input, InputSpecs& output) { #if 0 int e = input._event_type; @@ -368,7 +366,7 @@ MapManipulator::Settings::bind(const InputSpec& spec, const Action& action) { InputSpecs specs; expandSpec(spec, specs); - for (InputSpecs::const_iterator i = specs.begin(); i != specs.end(); i++) + for (auto i = specs.begin(); i != specs.end(); i++) { _bindings[*i] = action; } @@ -463,7 +461,7 @@ MapManipulator::Settings::getAction(int event_type, int input_mask, int modkey_m //if they are on. So if you bind an action like SCROLL to a modkey mask of 0 or a modkey mask of ctrl it will never match the spec exactly b/c //the modkey mask also includes capslock and numlock. InputSpec spec(event_type, input_mask, modkey_mask & ~vsg::MODKEY_NumLock & ~vsg::MODKEY_CapsLock); - ActionBindings::const_iterator i = _bindings.find(spec); + auto i = _bindings.find(spec); return i != _bindings.end() ? i->second : NullAction; } @@ -515,16 +513,18 @@ MapManipulator::Settings::setAutoViewpointDurationLimits(double minSeconds, doub /************************************************************************/ -MapManipulator::MapManipulator(vsg::ref_ptr mapNode, vsg::ref_ptr camera) : - Inherit(), +MapManipulator::MapManipulator(const vsg::ref_ptr& mapNode, + const vsg::ref_ptr& camera) : _mapNode(mapNode), _camera(camera), _lastAction(ACTION_NULL) { if (mapNode.valid()) + { _geoServices = CsGeospatialServices::create(mapNode); - //_srs = mapNode->mapSRS(); - + /// XXX Otherwise what? Should we even try to continue? + } + reinitializeHome(); reinitialize(); configureDefaultSettings(); @@ -541,15 +541,6 @@ MapManipulator::MapManipulator(vsg::ref_ptr mapNode, vsg::ref_ptrgetTetherMode(); } -MapManipulator::~MapManipulator() -{ - //vsg::ref_ptr mapNode = _mapNode; - //if (mapNode.valid() && _terrainCallback && mapNode->getTerrain()) - //{ - // mapNode->getTerrain()->removeTerrainCallback( _terrainCallback.get() ); - //} -} - void MapManipulator::configureDefaultSettings() { @@ -619,7 +610,7 @@ MapManipulator::configureDefaultSettings() } void -MapManipulator::applySettings(std::shared_ptr settings) +MapManipulator::applySettings(const std::shared_ptr& settings) { if ( settings ) { @@ -1128,7 +1119,7 @@ void MapManipulator::resetLookAt() { double pitch; - getEulerAngles(_localRotation, 0L, &pitch ); + getEulerAngles(_localRotation, nullptr, &pitch ); double maxPitch = vsg::radians(-10.0); if ( pitch > maxPitch ) @@ -1288,25 +1279,43 @@ MapManipulator::intersectAlongLookVector() const return {}; } +std::pair +MapManipulator::getHome() +{ + return {_homePosition, _homeDistance}; +} + void -MapManipulator::home() +MapManipulator::setHome(const vsg::dvec3& position, double distance) { - _state.localRotation.set(0, 0, 0, 1); + _homePosition = position; + _homeDistance = distance; +} +void +MapManipulator::reinitializeHome() +{ double radius; if (_geoServices->isGeocentric()) { radius = _geoServices->semiMajorAxis(); - setCenter(vsg::dvec3(radius, 0, 0)); } else { const auto bounds = _geoServices->bounds(); radius = (bounds.max.x - bounds.min.x) * 0.5; - setCenter(vsg::dvec3(0, 0, 0)); } + _homePosition = vsg::dvec3(radius, 0, 0); + _homeDistance = radius * 3.5; +} + +void +MapManipulator::home() +{ + _state.localRotation.set(0, 0, 0, 1); - setDistance(radius * 3.5); + setCenter(_homePosition); + setDistance(_homeDistance); clearEvents(); } @@ -1562,7 +1571,7 @@ MapManipulator::isMouseClick() const float dy = up.y - down.y; float len = sqrtf(dx * dx + dy * dy); auto dtmillis = std::chrono::duration_cast(_buttonRelease->time - _buttonPress->time); - float dt = (float)dtmillis.count() * 0.001f; + float dt = static_cast(dtmillis.count()) * 0.001f; return (len < dt* velocity); } @@ -1589,7 +1598,7 @@ MapManipulator::recalculateCenterFromLookVector() // simple line/plane intersection vsg::dvec3 P0(0, 0, 0); // point on the plane vsg::dvec3 N(0, 0, 1); // normal to the plane - vsg::dvec3 L = look; // unit direction of the line + const vsg::dvec3& L = look; // unit direction of the line vsg::dvec3 L0 = lookat.eye; // point on the line auto LdotN = vsg::dot(L, N); if (equiv(LdotN, 0)) return false; // parallel @@ -1701,7 +1710,7 @@ MapManipulator::rotate(double dx, double dy) // clamp pitch range: double oldPitch; - getEulerAngles(_state.localRotation, 0L, &oldPitch); + getEulerAngles(_state.localRotation, nullptr, &oldPitch); if ( dy + oldPitch > maxp || dy + oldPitch < minp ) dy = 0; @@ -1729,7 +1738,7 @@ MapManipulator::zoom(double, double dy) // return; //} - if (_settings->getZoomToMouse() == false) + if (!_settings->getZoomToMouse()) { double scale = 1.0f + dy; setDistance(_state.distance * scale); @@ -2229,7 +2238,7 @@ MapManipulator::cameraRenderAreaCoordinates(const vsg::PointerEvent& pointerEven auto itr = _windowOffsets.find(pointerEvent.window); if (itr != _windowOffsets.end()) { - auto& offset = itr->second; + const auto& offset = itr->second; return { pointerEvent.x + offset.x, pointerEvent.y + offset.y }; } } diff --git a/src/CsApp/MapManipulator.h b/src/CsApp/MapManipulator.h index 7c99ab0..48c9150 100644 --- a/src/CsApp/MapManipulator.h +++ b/src/CsApp/MapManipulator.h @@ -5,7 +5,7 @@ */ #pragma once -#include "Export.h" +#include "vsgCs/Export.h" #include "vsgCs/GeospatialServices.h" #include "vsgCs/runtimeSupport.h" @@ -19,6 +19,7 @@ #include #include #include +#include namespace vsg { @@ -55,14 +56,20 @@ namespace vsgCs public: //! Construct a new manipulator MapManipulator( - vsg::ref_ptr mapNode, - vsg::ref_ptr camera); + const vsg::ref_ptr& mapNode, + const vsg::ref_ptr& camera); - virtual ~MapManipulator(); + virtual ~MapManipulator() = default; //! Go to the home position. virtual void home(); + //! Set home position and distance. + virtual void setHome(const vsg::dvec3& position, double distance); + + //! Get current home position and distance. + virtual std::pair getHome(); + //! Move the focal point of the camera using deltas (normalized screen coords). virtual void pan(double dx, double dy); @@ -190,7 +197,7 @@ namespace vsgCs struct InputSpec { InputSpec(int event_type, int input_mask, int modkey_mask); - InputSpec(const InputSpec& rhs); + InputSpec(const InputSpec& rhs) = default; bool operator == (const InputSpec& rhs) const; bool operator < (const InputSpec& rhs) const; int _event_type; @@ -550,7 +557,7 @@ namespace vsgCs // to matching binding. const Action& getAction(int event_type, int input_mask, int modkey_mask) const; - void expandSpec(const InputSpec& input, InputSpecs& output) const; + static void expandSpec(const InputSpec& input, InputSpecs& output); void bind(const InputSpec& spec, const Action& action); private: @@ -590,7 +597,7 @@ namespace vsgCs std::shared_ptr _settings; - void applySettings(std::shared_ptr); + void applySettings(const std::shared_ptr& settings); std::shared_ptr getSettings() const; @@ -741,7 +748,7 @@ namespace vsgCs // This stuff is borrowed from vsg manips, but it's not implemented here (yet): - /// list of windows and theire xy offsets + /// list of windows and their xy offsets std::map, vsg::ivec2> _windowOffsets; /// add a Window to respond events for, with mouse coordinate offset to treat all associated windows @@ -754,6 +761,14 @@ namespace vsgCs vsg::dvec2 ndc(const vsg::PointerEvent&) const; vsg::dvec3 adjustToSameHeight(const vsg::dvec3& reference, const vsg::dvec3& point); + + // Home position and distance. + // Hopefully a temporary measure, to be subsumed by viewpoints + vsg::dvec3 _homePosition; + double _homeDistance; + + void reinitializeHome(); + // For graphical debugging friend class UpdateCenterOperation; }; diff --git a/src/applications/csclient/UI.cpp b/src/applications/csclient/UI.cpp index 3fd9df8..87043f1 100644 --- a/src/applications/csclient/UI.cpp +++ b/src/applications/csclient/UI.cpp @@ -25,7 +25,7 @@ SOFTWARE. #include "UI.h" #include -#include +#include #include "vsgCs/Config.h" #include "vsgCs/runtimeSupport.h" diff --git a/src/applications/csclient/csclient.cpp b/src/applications/csclient/csclient.cpp index b0fac55..74d121c 100644 --- a/src/applications/csclient/csclient.cpp +++ b/src/applications/csclient/csclient.cpp @@ -35,7 +35,7 @@ SOFTWARE. #include #include -#include +#include #include #include @@ -142,11 +142,11 @@ int main(int argc, char** argv) } else if (object) { - std::cout << "Unable to view object of type " << object->className() << std::endl; + std::cout << "Unable to view object of type " << object->className() << '\n'; } else { - std::cout << "Unable to load file " << filename << std::endl; + std::cout << "Unable to load file " << filename << '\n'; } } vsgCs::startup(); @@ -173,7 +173,7 @@ int main(int argc, char** argv) auto viewer = vsg::Viewer::create(); if (!window) { - std::cout << "Could not create windows." << std::endl; + std::cout << "Could not create windows.\n"; return 1; } Cesium3DTilesSelection::TilesetOptions tileOptions; @@ -291,7 +291,7 @@ int main(int argc, char** argv) { std::cerr << argv[i] << " "; } - std::cerr << "\n[Exception] - " << ve.message << " result = " << ve.result << std::endl; + std::cerr << "\n[Exception] - " << ve.message << " result = " << ve.result << '\n'; return 1; } diff --git a/src/applications/gltfviewer/gltfviewer.cpp b/src/applications/gltfviewer/gltfviewer.cpp index fd00e92..fbfe9c4 100644 --- a/src/applications/gltfviewer/gltfviewer.cpp +++ b/src/applications/gltfviewer/gltfviewer.cpp @@ -43,7 +43,7 @@ int main(int argc, char** argv) auto model = vsgCs::ref_ptr_cast(loader->read(filename, vsgCs::RuntimeEnvironment::get()->options)); if (!model) { - std::cout<<"Faled to load "<addChild(model); @@ -147,7 +147,7 @@ int main(int argc, char** argv) if (!window) { - std::cout << "Could not create windows." << std::endl; + std::cout << "Could not create windows.\n"; return 1; } @@ -202,7 +202,7 @@ int main(int argc, char** argv) auto duration = std::chrono::duration(vsg::clock::now() - startTime).count(); if (numFramesCompleted > 0.0) { - std::cout << "Average frame rate = " << (numFramesCompleted / duration) << std::endl; + std::cout << "Average frame rate = " << (numFramesCompleted / duration) << '\n'; } return 0; diff --git a/src/applications/worldviewer/UI.cpp b/src/applications/worldviewer/UI.cpp index d0f408e..67c9b61 100644 --- a/src/applications/worldviewer/UI.cpp +++ b/src/applications/worldviewer/UI.cpp @@ -31,7 +31,7 @@ SOFTWARE. #if defined(vsgXchange_found) #include #endif -#include +#include #include "vsgCs/Config.h" #include "vsgCs/WorldNode.h" @@ -115,11 +115,9 @@ namespace vsgCs return _renderImGui; } - void UI::setViewpoint(const vsg::ref_ptr& lookAt, float duration) + void UI::setViewpoint(const vsg::ref_ptr& lookAt, float) { - if (_trackball) - { - _trackball->setViewpoint(lookAt, duration); - } + _mapManipulator->setHome(lookAt->center, length( lookAt->center - lookAt->eye)); + _mapManipulator->home(); } } diff --git a/src/applications/worldviewer/UI.h b/src/applications/worldviewer/UI.h index d57f4e6..2dc575d 100644 --- a/src/applications/worldviewer/UI.h +++ b/src/applications/worldviewer/UI.h @@ -53,7 +53,6 @@ namespace vsgCs vsg::ref_ptr _renderImGui; vsg::ref_ptr _ionIconComponent; - vsg::ref_ptr _trackball; vsg::ref_ptr _mapManipulator; }; } diff --git a/src/applications/worldviewer/worldviewer.cpp b/src/applications/worldviewer/worldviewer.cpp index c231687..345f855 100644 --- a/src/applications/worldviewer/worldviewer.cpp +++ b/src/applications/worldviewer/worldviewer.cpp @@ -35,18 +35,20 @@ SOFTWARE. #include #include -#include +#include #include #include #include +#include #include #include #include #include "vsgCs/GeoNode.h" #include "vsgCs/jsonUtils.h" +#include "vsgCs/TilesetNode.h" #include "vsgCs/Tracing.h" #include "vsgCs/TracingCommandGraph.h" #include "vsgCs/RuntimeEnvironment.h" @@ -54,6 +56,8 @@ SOFTWARE. #include "UI.h" #include "CsApp/CsViewer.h" +namespace +{ void usage(const char* name) { std::cout @@ -71,6 +75,105 @@ void usage(const char* name) << "--help\t\t\t print this message\n"; } +class VsgCsScenegraphBuilder +{ +public: + VsgCsScenegraphBuilder(vsg::CommandLine& arguments_, vsg::ref_ptr env_) + : arguments(arguments_), env(env_) + { + createScenegraph(); + } + vsg::ref_ptr worldNode; + vsg::ref_ptr xchangeModels; + void createScenegraph() + { + std::vector> tilesetNodes; + for (int i = 1; i < arguments.argc(); ++i) + { + std::string argString(arguments[i]); + if (argString == "--world-file") + { + continue; + } + if (argString.ends_with("tileset.json")) + { + if (auto tilesetNode = createTileset(argString)) + { + tilesetNodes.push_back(tilesetNode); + } + } + else if (argString.ends_with(".json")) + { + auto node = createVsgCsObject(arguments[i]); + if (auto maybeWorldNode = vsgCs::ref_ptr_cast(node)) + { + worldNode = maybeWorldNode; + } + else if (auto modelNode = vsgCs::ref_ptr_cast(node)) + { + if (!xchangeModels) + { + xchangeModels = vsgCs::createModelRoot(env); + } + xchangeModels->addChild(modelNode); + } + } + } + if (!worldNode && !tilesetNodes.empty()) + { + worldNode = vsgCs::WorldNode::create(); + } + worldNode->tilesetNodes().insert(worldNode->tilesetNodes().end(), + tilesetNodes.begin(), tilesetNodes.end()); + } + +private: + vsg::ref_ptr createVsgCsObject(const std::string& fileName) + { + auto jsonSource = vsgCs::readFile(fileName, env->options); + auto object = vsgCs::JSONObjectFactory::get()->buildFromSource(jsonSource); + auto node = vsgCs::ref_ptr_cast(object); + if (!node) + { + std::cout << "Unable to load file " << fileName << '\n'; + } + return node; + } + vsg::ref_ptr createTileset(const std::string& argString) + { + std::string url; + if (argString.starts_with("https:") || argString.starts_with("http:") + || argString.starts_with("file:")) + { + url = argString; + } + else + { + // It's a file, so construct an absolute file url. + auto realPath = vsg::findFile(argString, env->options); + if (realPath.empty()) + { + vsg::fatal("Can't find file ", argString); + } + std::filesystem::path p = realPath.string(); + auto absPath = std::filesystem::absolute(p); + url = "file://" + absPath.string(); + } + std::string tilesetJson(R"({"Type": "Tileset", "tilesetUrl": ")"); + tilesetJson += url + R"("})"; + auto object = vsgCs::JSONObjectFactory::get()->buildFromSource(tilesetJson); + auto maybeTileset = vsgCs::ref_ptr_cast(object); + if (!maybeTileset) + { + std::cout << "Can't create tileset for " << argString << "\n"; + } + return maybeTileset; + } + vsg::CommandLine& arguments; + vsg::ref_ptr env; +}; +} + int main(int argc, char** argv) { try @@ -95,8 +198,6 @@ int main(int argc, char** argv) environment->options->add(vsgXchange::all::create()); arguments.read(environment->options); #endif - // The world file specifies the tilesets to display. - auto worldFile = arguments.value(std::string(), "--world-file"); // numFrames and pathFilename come from vsgViewer. They provide a way to display a // "flythrough." At the moment they are not useful because a scene will usually take some // time to load. @@ -169,35 +270,7 @@ int main(int argc, char** argv) #endif vsg_scene->addChild(directionalLight); } - vsg::ref_ptr modelRoot; - if (argc > 1) - { - modelRoot = createModelRoot(environment); - } - // Read GeoNode json files - for (int i = 1; i < argc; ++i) - { - vsg::Path filename = arguments[i]; - auto jsonSource = vsgCs::readFile(filename, environment->options); - auto object = vsgCs::JSONObjectFactory::get()->buildFromSource(jsonSource); - if (auto node = vsgCs::ref_ptr_cast(object)) - { - modelRoot->addChild(node); - } - else if (object) - { - std::cout << "Unable to view object of type " << object->className() << std::endl; - } - else - { - std::cout << "Unable to load file " << filename << std::endl; - } - } - if (worldFile.empty()) - { - vsg::fatal("no world file"); - } - auto worldJson = vsgCs::readFile(worldFile); + // Do early cesium-native initialization vsgCs::startup(); // create the VSG viewer and assign window(s) to it @@ -205,13 +278,12 @@ int main(int argc, char** argv) if (!window) { - std::cout << "Could not create windows." << std::endl; + std::cout << "Could not create windows.\n"; return 1; } - // Create the World with its tilesets - auto worldNode - = vsgCs::ref_ptr_cast(vsgCs::JSONObjectFactory::get() - ->buildFromSource(worldJson)); + VsgCsScenegraphBuilder graphBuilder(arguments, environment); + auto worldNode = graphBuilder.worldNode; + auto modelRoot = graphBuilder.xchangeModels; // VSG's EllipsoidModel provides ellipsoid parameters (e.g. WGS84), mostly for the benefit // of the trackball manipulator. auto ellipsoidModel = vsg::EllipsoidModel::create(); @@ -338,7 +410,7 @@ int main(int argc, char** argv) { std::cerr << argv[i] << " "; } - std::cerr << "\n[Exception] - " << ve.message << " result = " << ve.result << std::endl; + std::cerr << "\n[Exception] - " << ve.message << " result = " << ve.result << '\n'; return 1; } diff --git a/src/vsgCs/CMakeLists.txt b/src/vsgCs/CMakeLists.txt index b968d97..d6107ba 100644 --- a/src/vsgCs/CMakeLists.txt +++ b/src/vsgCs/CMakeLists.txt @@ -5,7 +5,7 @@ set(LIB_NAME vsgCs) set(LIB_PUBLIC_HEADERS accessorUtils.h accessor_traits.h - ${GENERATED_HEADERS_DIR}/vsgCs/Config.h + ${PROJECT_BINARY_DIR}/include/vsgCs/Config.h CRS.h CsDebugColorizeTilesOverlay.h CsOverlay.h @@ -65,8 +65,9 @@ set_target_properties(${LIB_NAME} PROPERTIES PUBLIC_HEADER "${LIB_PUBLIC_HEADERS}" ) -target_include_directories(${LIB_NAME} PRIVATE ${CURL_INCLUDE_DIRS}) -target_include_directories(${LIB_NAME} PUBLIC $) +target_include_directories(${LIB_NAME} PUBLIC $) +target_include_directories(${LIB_NAME} PUBLIC $) +target_include_directories(${LIB_NAME} PUBLIC $) if(VSGCS_BUILD_SHARED_LIBS) target_compile_definitions(${LIB_NAME} PRIVATE VSGCS_LIBRARY) @@ -83,7 +84,7 @@ target_link_libraries(${LIB_NAME} PUBLIC if(CESIUM_SPDLOG_HEADER_ONLY) target_link_libraries(${LIB_NAME} PUBLIC spdlog::spdlog_header_only) else() - target_link_libraries(${LIB_NAME} PUBLIC spdlog) + target_link_libraries(${LIB_NAME} PUBLIC spdlog::spdlog) endif() target_link_libraries(${LIB_NAME} PRIVATE CURL::libcurl PROJ::proj) @@ -98,9 +99,14 @@ install(TARGETS ${LIB_NAME} EXPORT vsgCsTargets PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${LIB_NAME}" ) -if(WIN32) - install(IMPORTED_RUNTIME_ARTIFACTS CURL::libcurl_shared) -endif() - +configure_file("Config.h.in" + "${PROJECT_BINARY_DIR}/include/vsgCs/Config.h") + include(GenerateExportHeader) generate_export_header(vsgCs EXPORT_FILE_NAME Export.h) + +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/Export.h" + "${PROJECT_BINARY_DIR}/include/vsgCs/Config.h" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${LIB_NAME}" +) diff --git a/src/vsgCs/CRS.cpp b/src/vsgCs/CRS.cpp index c64b294..a22f2f3 100644 --- a/src/vsgCs/CRS.cpp +++ b/src/vsgCs/CRS.cpp @@ -42,6 +42,7 @@ SOFTWARE. #include #include +#include namespace vsgCs { @@ -89,11 +90,11 @@ namespace vsgCs //Instance::log().debug << "SRSRepo: destructor in thread " << util::getCurrentThreadId() // << " destroying " << size() << " objects" << std::endl; - for (auto iter = umap.begin(); iter != umap.end(); ++iter) + for (auto & iter : umap) { - if (iter->second.pj) + if (iter.second.pj) { - proj_destroy(iter->second.pj); + proj_destroy(iter.second.pj); } } @@ -101,7 +102,7 @@ namespace vsgCs proj_context_destroy(g_pj_thread_local_context); } - PJ_CONTEXT* threading_context() + static PJ_CONTEXT* threading_context() { if (g_pj_thread_local_context == nullptr) { @@ -115,9 +116,10 @@ namespace vsgCs { auto iter = umap.find(def); if (iter == umap.end()) + { return empty_string; // shouldn't happen - else - return iter->second.error; + } + return iter->second.error; } //! retrieve or create a PJ projection object based on the provided definition string, @@ -125,7 +127,7 @@ namespace vsgCs //! like "spherical-mercator" or "wgs84". SRSEntry& get_or_create(const std::string& def) { - auto ctx = threading_context(); + auto* ctx = threading_context(); auto iter = umap.find(def); if (iter == umap.end()) @@ -193,7 +195,9 @@ namespace vsgCs PJ* ellps = proj_get_ellipsoid(ctx, pj); if (ellps) { - double semi_major, semi_minor, inv_flattening; + double semi_major; + double semi_minor; + double inv_flattening; int is_semi_minor_computed; proj_ellipsoid_get_parameters(ctx, ellps, &semi_major, &semi_minor, &is_semi_minor_computed, &inv_flattening); proj_destroy(ellps); @@ -213,10 +217,9 @@ namespace vsgCs return new_entry; } - else - { - return iter->second; - } + + return iter->second; + } //! fetch the projection type @@ -311,7 +314,7 @@ namespace vsgCs //! retrieve or create a transformation object PJ* get_or_create_operation(const std::string& firstDef, const std::string& secondDef) { - auto ctx = threading_context(); + auto* ctx = threading_context(); PJ* pj = nullptr; std::string proj; @@ -450,6 +453,7 @@ namespace vsgCs class CRS::ConversionOperation { public: + virtual ~ConversionOperation() = default; virtual vsg::dvec3 getECEF(const vsg::dvec3& coord) = 0; virtual vsg::dmat4 getENU(const vsg::dvec3& coord) = 0; // The inverse operation @@ -518,8 +522,8 @@ namespace vsgCs class ProjConversion : public CRS::ConversionOperation { public: - ProjConversion(const std::string& in_sourceCRS) - : sourceCRS(in_sourceCRS) + ProjConversion(std::string in_sourceCRS) + : sourceCRS(std::move(in_sourceCRS)) { } @@ -527,18 +531,17 @@ namespace vsgCs vsg::dvec3 getECEF(const vsg::dvec3& coord) override { - auto handle = getHandle(); - PJ_COORD out = proj_trans(handle, PJ_FWD, PJ_COORD{ coord.x, coord.y, coord.z }); + auto* handle = getHandle(); + PJ_COORD out = proj_trans(handle, PJ_FWD, PJ_COORD{ {coord.x, coord.y, coord.z} }); int err = proj_errno(handle); vsg::dvec3 result(0.0, 0.0, 0.0); if (err != 0) { throw std::runtime_error(std::string("PROJ error: ") + proj_errno_string(err)); } - else - { - result.set(out.xyz.x, out.xyz.y, out.xyz.z); - } + + result.set(out.xyz.x, out.xyz.y, out.xyz.z); + return result; } @@ -546,7 +549,7 @@ namespace vsgCs { using namespace CesiumGeospatial; vsg::dvec3 origin = getECEF(coord); - auto& ellipsoid = g_srs_factory.get_ellipsoid(sourceCRS); + const auto& ellipsoid = g_srs_factory.get_ellipsoid(sourceCRS); LocalHorizontalCoordinateSystem lhcs(vsg2glm(origin), LocalDirection::East, LocalDirection::North, LocalDirection::Up, @@ -556,25 +559,24 @@ namespace vsgCs vsg::dvec3 getCRSCoord(const vsg::dvec3& ecef) override { - auto handle = getHandle(); - PJ_COORD out = proj_trans(handle, PJ_INV, PJ_COORD{ ecef.x, ecef.y, ecef.z }); + auto* handle = getHandle(); + PJ_COORD out = proj_trans(handle, PJ_INV, PJ_COORD{ {ecef.x, ecef.y, ecef.z} }); int err = proj_errno(handle); vsg::dvec3 result(0.0, 0.0, 0.0); if (err != 0) { throw std::runtime_error(std::string("PROJ error: ") + proj_errno_string(err)); } - else - { - result.set(out.xyz.x, out.xyz.y, out.xyz.z); - } + + result.set(out.xyz.x, out.xyz.y, out.xyz.z); + return result; } protected: - PJ* getHandle() + PJ* getHandle() const { - auto handle = g_srs_factory.get_or_create_operation(sourceCRS, "ecef"); + auto* handle = g_srs_factory.get_or_create_operation(sourceCRS, "ecef"); if (!handle) { throw std::runtime_error("can't create conversion from " + sourceCRS + " to ECEF."); diff --git a/src/vsgCs/CRS.h b/src/vsgCs/CRS.h index af6d997..85ba930 100644 --- a/src/vsgCs/CRS.h +++ b/src/vsgCs/CRS.h @@ -37,7 +37,7 @@ SOFTWARE. TILESET_CRS_GEOCENTRIC, if any. */ -#include "Export.h" +#include "vsgCs/Export.h" #include #include diff --git a/src/vsgCs/CesiumGltfBuilder.cpp b/src/vsgCs/CesiumGltfBuilder.cpp index 69b54df..2447053 100644 --- a/src/vsgCs/CesiumGltfBuilder.cpp +++ b/src/vsgCs/CesiumGltfBuilder.cpp @@ -189,7 +189,7 @@ CesiumGltfBuilder::load(CesiumGltf::Model* model, const CreateModelOptions& opti ExtensionList tilesExtensions{csExtension}; if (options.styling.valid()) { - tilesExtensions.push_back(stylingExtension); + tilesExtensions.emplace_back(stylingExtension); } ModelBuilder builder(_genv, model, options, tilesExtensions); return builder(); @@ -245,7 +245,7 @@ vsg::ref_ptr CesiumGltfBuilder::loadTile(Cesium3DTilesSelection::Tile const CreateModelOptions& modelOptions) { VSGCS_ZONESCOPED; - CesiumGltf::Model* pModel = std::get_if(&tileLoadResult.contentKind); + auto* pModel = std::get_if(&tileLoadResult.contentKind); if (!pModel) { return {}; @@ -318,20 +318,7 @@ CesiumGltfBuilder::attachTileData(Cesium3DTilesSelection::Tile& tile, return {tileStateCommand, node}; } -vsg::ref_ptr CesiumGltfBuilder::loadTexture(CesiumTextureSource&& imageSource, - VkSamplerAddressMode addressX, - VkSamplerAddressMode addressY, - VkFilter minFilter, - VkFilter maxFilter, - bool useMipMaps, - bool sRGB) -{ - CesiumGltf::ImageCesium* pImage = - std::visit(GetImageFromSource{}, imageSource); - return loadTexture(*pImage, addressX, addressY, minFilter, maxFilter, useMipMaps, sRGB); -} - -vsg::ref_ptr CesiumGltfBuilder::loadTexture(CesiumGltf::ImageCesium& image, +vsg::ref_ptr CesiumGltfBuilder::loadTexture(CesiumGltf::ImageAsset& image, VkSamplerAddressMode addressX, VkSamplerAddressMode addressY, VkFilter minFilter, diff --git a/src/vsgCs/CesiumGltfBuilder.h b/src/vsgCs/CesiumGltfBuilder.h index 2496c4c..d96725d 100644 --- a/src/vsgCs/CesiumGltfBuilder.h +++ b/src/vsgCs/CesiumGltfBuilder.h @@ -33,7 +33,7 @@ SOFTWARE. #include #include -#include "Export.h" +#include "vsgCs/Export.h" #include "GraphicsEnvironment.h" #include "ModelBuilder.h" #include "RuntimeEnvironment.h" @@ -78,21 +78,13 @@ namespace vsgCs const CreateModelOptions& options); AttachTileDataResult attachTileData(Cesium3DTilesSelection::Tile& tile, const vsg::ref_ptr& node); - vsg::ref_ptr loadTexture(CesiumGltf::ImageCesium& image, + vsg::ref_ptr loadTexture(CesiumGltf::ImageAsset& image, VkSamplerAddressMode addressX, VkSamplerAddressMode addressY, VkFilter minFilter, VkFilter maxFilter, bool useMipMaps, bool sRGB); - vsg::ref_ptr loadTexture(CesiumTextureSource&& imageSource, - VkSamplerAddressMode addressX, - VkSamplerAddressMode addressY, - VkFilter minFilter, - VkFilter maxFilter, - bool useMipMaps, - bool sRGB); - ModifyRastersResult attachRaster(const Cesium3DTilesSelection::Tile& tile, const vsg::ref_ptr& node, int32_t overlayTextureCoordinateID, diff --git a/src/vsgCs/CsOverlay.h b/src/vsgCs/CsOverlay.h index 1e4541a..f1a4da2 100644 --- a/src/vsgCs/CsOverlay.h +++ b/src/vsgCs/CsOverlay.h @@ -33,7 +33,7 @@ SOFTWARE. #endif #include "CesiumRasterOverlays/RasterOverlay.h" -#include "Export.h" +#include "vsgCs/Export.h" #include "TilesetNode.h" namespace vsgCs diff --git a/src/vsgCs/GeoNode.cpp b/src/vsgCs/GeoNode.cpp index 84c9441..359c89c 100644 --- a/src/vsgCs/GeoNode.cpp +++ b/src/vsgCs/GeoNode.cpp @@ -39,13 +39,13 @@ SOFTWARE. using namespace vsgCs; -GeoNode::GeoNode(const std::string& crs, vsg::ref_ptr worldAnchor) +GeoNode::GeoNode(const std::string& crs, const vsg::ref_ptr& worldAnchor) : _worldAnchor(worldAnchor) { _crs = std::make_shared(crs); } -GeoNode::GeoNode(const std::shared_ptr& crs, vsg::ref_ptr worldAnchor) +GeoNode::GeoNode(const std::shared_ptr& crs, const vsg::ref_ptr& worldAnchor) : _crs(crs), _worldAnchor(worldAnchor) { } diff --git a/src/vsgCs/GeoNode.h b/src/vsgCs/GeoNode.h index f1fa5f1..cec1f97 100644 --- a/src/vsgCs/GeoNode.h +++ b/src/vsgCs/GeoNode.h @@ -25,7 +25,7 @@ SOFTWARE. #pragma once #include "CRS.h" -#include "Export.h" +#include "vsgCs/Export.h" #include "RuntimeEnvironment.h" #include "WorldAnchor.h" @@ -42,8 +42,8 @@ namespace vsgCs class VSGCS_EXPORT GeoNode : public vsg::Inherit { public: - GeoNode(const std::string& crs = "epsg:4979", vsg::ref_ptr worldAnchor = {}); - GeoNode(const std::shared_ptr& crs, vsg::ref_ptr worldAnchor = {}); + GeoNode(const std::string& crs = "epsg:4979", const vsg::ref_ptr& worldAnchor = {}); + GeoNode(const std::shared_ptr& crs, const vsg::ref_ptr& worldAnchor = {}); void setOrigin(const vsg::dvec3& origin); vsg::dvec3 getOrigin() const; void setCRS(const std::string& crs); diff --git a/src/vsgCs/GeospatialServices.cpp b/src/vsgCs/GeospatialServices.cpp index 075b55d..e3fa1c6 100644 --- a/src/vsgCs/GeospatialServices.cpp +++ b/src/vsgCs/GeospatialServices.cpp @@ -91,7 +91,7 @@ QuadraticResult solveQuadratic(double a, double b, double c) result.roots[1] = c / result.roots[0]; return result; } - else if (d == 0.0) + if (d == 0.0) { return {1, {-b / (2.0 * a), 0.0}}; } @@ -157,9 +157,9 @@ vsg::dvec3 CsGeospatialServices::toCartographic(const vsg::dvec3 &worldPos) auto csResult = CesiumGeospatial::Ellipsoid::WGS84.cartesianToCartographic(vsgCs::vsg2glm(worldPos)); if (csResult) { - return vsg::dvec3(csResult->longitude, csResult->latitude, csResult->height); + return {csResult->longitude, csResult->latitude, csResult->height}; } - return vsg::dvec3(0, 0, 0); // XXX Real error result + return {0, 0, 0}; // XXX Real error result } vsg::dvec3 CsGeospatialServices::toWorld(const vsg::dvec3& cartographic) diff --git a/src/vsgCs/GeospatialServices.h b/src/vsgCs/GeospatialServices.h index e814b4e..c162c95 100644 --- a/src/vsgCs/GeospatialServices.h +++ b/src/vsgCs/GeospatialServices.h @@ -24,7 +24,7 @@ SOFTWARE. #pragma once -#include "Export.h" +#include "vsgCs/Export.h" #include #include diff --git a/src/vsgCs/GltfLoader.cpp b/src/vsgCs/GltfLoader.cpp index 134e7ea..cc83cdd 100644 --- a/src/vsgCs/GltfLoader.cpp +++ b/src/vsgCs/GltfLoader.cpp @@ -39,7 +39,7 @@ SOFTWARE. using namespace vsgCs; -GltfLoader::GltfLoader(vsg::ref_ptr in_env) +GltfLoader::GltfLoader(const vsg::ref_ptr& in_env) : env(in_env) { readerOptions.ktx2TranscodeTargets = env->features.ktx2TranscodeTargets; @@ -47,20 +47,18 @@ GltfLoader::GltfLoader(vsg::ref_ptr in_env) struct ParseGltfResult { - ParseGltfResult(const std::string& error, std::shared_ptr in_request) + ParseGltfResult(const std::string& error, const std::shared_ptr& in_request) : request(in_request) { gltfResult.errors.push_back(error); } ParseGltfResult(CesiumGltfReader::GltfReaderResult&& result, - std::shared_ptr in_request) + const std::shared_ptr& in_request) : gltfResult(std::move(result)) ,request(in_request) { } - ParseGltfResult() - { - } + ParseGltfResult() = default; CesiumGltfReader::GltfReaderResult gltfResult; std::shared_ptr request; }; @@ -71,7 +69,7 @@ struct ReadGltfResult std::vector errors; }; -CesiumAsync::Future GltfLoader::loadGltfNode(std::string uri) const +CesiumAsync::Future GltfLoader::loadGltfNode(const std::string& uri) const { std::vector headers; auto accessor = env-> getAssetAccessor(); diff --git a/src/vsgCs/GltfLoader.h b/src/vsgCs/GltfLoader.h index c0703e8..ffc42d0 100644 --- a/src/vsgCs/GltfLoader.h +++ b/src/vsgCs/GltfLoader.h @@ -24,7 +24,7 @@ SOFTWARE. #pragma once -#include "Export.h" +#include "vsgCs/Export.h" #include "RuntimeEnvironment.h" #include @@ -38,16 +38,16 @@ namespace vsgCs class VSGCS_EXPORT GltfLoader : public vsg::Inherit { public: - GltfLoader(vsg::ref_ptr in_env = RuntimeEnvironment::get()); + GltfLoader(const vsg::ref_ptr& in_env = RuntimeEnvironment::get()); vsg::ref_ptr - read(const vsg::Path& /*filename*/, vsg::ref_ptr = {}) const override; + read(const vsg::Path& /*filename*/, vsg::ref_ptr) const override; protected: struct ReadGltfResult { vsg::ref_ptr node; std::vector errors; }; - CesiumAsync::Future loadGltfNode(std::string uri) const; + CesiumAsync::Future loadGltfNode(const std::string& uri) const; vsg::ref_ptr env; CesiumGltfReader::GltfReader reader; CesiumGltfReader::GltfReaderOptions readerOptions; diff --git a/src/vsgCs/GraphicsEnvironment.cpp b/src/vsgCs/GraphicsEnvironment.cpp index 294e3f3..70ef12b 100644 --- a/src/vsgCs/GraphicsEnvironment.cpp +++ b/src/vsgCs/GraphicsEnvironment.cpp @@ -96,8 +96,7 @@ vsg::CompileResult GraphicsEnvironment::miniCompile(vsg::ref_ptr ob result.maxSlot = requirements.maxSlot; result.containsPagedLOD = requirements.containsPagedLOD; result.views = requirements.views; - result.earlyDynamicData = requirements.earlyDynamicData; - result.lateDynamicData = requirements.lateDynamicData; + result.dynamicData= requirements.dynamicData; auto run_compile_traversal = [&]() -> void { for (auto& context : miniCompileTraversal->contexts) diff --git a/src/vsgCs/GraphicsEnvironment.h b/src/vsgCs/GraphicsEnvironment.h index 3b98315..97a74b2 100644 --- a/src/vsgCs/GraphicsEnvironment.h +++ b/src/vsgCs/GraphicsEnvironment.h @@ -24,7 +24,7 @@ SOFTWARE. #pragma once -#include "Export.h" +#include "vsgCs/Export.h" #include "ShaderFactory.h" #include diff --git a/src/vsgCs/ModelBuilder.cpp b/src/vsgCs/ModelBuilder.cpp index 6e6fb3b..03e21af 100644 --- a/src/vsgCs/ModelBuilder.cpp +++ b/src/vsgCs/ModelBuilder.cpp @@ -366,7 +366,7 @@ namespace const AccessorView& indexView) { vsg::ref_ptr result; - if constexpr (std::is_same::value) + if constexpr (std::is_same_v) { if (indexView.status() == AccessorViewStatus::Valid) { @@ -398,7 +398,7 @@ namespace const AccessorView& indexView) { vsg::ref_ptr result; - if constexpr (std::is_same::value) + if constexpr (std::is_same_v) { if (indexView.status() == AccessorViewStatus::Valid) { @@ -445,7 +445,7 @@ namespace const AccessorView& indexView) { vsg::ref_ptr result; - if constexpr (std::is_same::value) + if constexpr (std::is_same_v) { if (indexView.status() == AccessorViewStatus::Valid) { @@ -601,11 +601,11 @@ namespace depthClamp(in_depth_clamp) { } - void apply(vsg::Object& object) + void apply(vsg::Object& object) override { object.traverse(*this); } - void apply(vsg::RasterizationState& rs) + void apply(vsg::RasterizationState& rs) override { if (two_sided) { @@ -616,11 +616,11 @@ namespace rs.depthClampEnable = VK_TRUE; } } - void apply(vsg::InputAssemblyState& ias) + void apply(vsg::InputAssemblyState& ias) override { ias.topology = topology; } - void apply(vsg::ColorBlendState& cbs) + void apply(vsg::ColorBlendState& cbs) override { cbs.configureAttachments(blending); } @@ -775,6 +775,48 @@ makeInstanceData(const Model& model, return result; } +namespace +{ + vsg::dsphere computeBoundsFromGltf(const Accessor* pPositionAccessor, const ModelBuilder::InstanceData* pInstanceData) + { + if (pPositionAccessor->min.size() != 3 || pPositionAccessor->max.size() != 3) + { + return {}; + } + vsg::box posBox(vsg::vec3(pPositionAccessor->min[0], pPositionAccessor->min[1], pPositionAccessor->min[2]), + vsg::vec3(pPositionAccessor->max[0], pPositionAccessor->max[1], pPositionAccessor->max[2])); + vsg::box bounds; + if (!pInstanceData) + { + bounds.add(posBox); + } else + { + const size_t numInstances = (*pInstanceData)[0]->size(); + for (size_t i = 0; i < numInstances; ++i) + { + const vsg::mat4 instanceTranspose((*pInstanceData)[0]->at(i), + (*pInstanceData)[1]->at(i), + (*pInstanceData)[2]->at(i), + vsg::vec4(0.0f, 0.0f, 0.0f, 1.0f)); + mapBox(posBox, + [&bounds, &instanceTranspose](float x, float y, float z) + { + const vsg::vec3 boxPoint(x, y, z); + const vsg::vec3 instancePoint = boxPoint * instanceTranspose; + bounds.add(instancePoint); + }); + } + } + if (!bounds.valid()) + { + return {}; + } + vsg::dvec3 center((bounds.min + bounds.max) * 0.5f); + double radius = length(bounds.max - bounds.min) * 0.5; + + return {center, radius}; + } +} vsg::ref_ptr ModelBuilder::loadPrimitive(const CesiumGltf::MeshPrimitive* primitive, @@ -971,24 +1013,18 @@ ModelBuilder::loadPrimitive(const CesiumGltf::MeshPrimitive* primitive, = pipelineConf->shaderSet->getSuitableArrayState(pipelineConf->shaderHints->defines); stateGroup->addChild(drawCommand); - - vsg::ComputeBounds computeBounds; - drawCommand->accept(computeBounds); - vsg::dvec3 center = (computeBounds.bounds.min + computeBounds.bounds.max) * 0.5; - double radius = vsg::length(computeBounds.bounds.max - computeBounds.bounds.min) * 0.5; - + vsg::dsphere boundingSphere = computeBoundsFromGltf(pPositionAccessor, instanceData); if (descConf->blending) { - auto depthSorted = vsg::DepthSorted::create(); - depthSorted->binNumber = 10; - depthSorted->bound.set(center[0], center[1], center[2], radius); - depthSorted->child = stateGroup; + // XXX Not sure what to do if the boundingSphere isn't valid; emit a warning? + return vsg::DepthSorted::create(10, boundingSphere, stateGroup); + } - return depthSorted; + if (boundingSphere.valid()) + { + return vsg::CullNode::create(boundingSphere, stateGroup); } - auto cullNode = vsg::CullNode::create(vsg::dsphere(center[0], center[1], center[2], radius), - stateGroup); - return cullNode; + return stateGroup; } vsg::ref_ptr @@ -1109,7 +1145,7 @@ ModelBuilder::operator()() vsg::ref_ptr ModelBuilder::loadImage(int i, bool useMipMaps, bool sRGB) { - CesiumGltf::ImageCesium& image = _model->images[i].cesium; + auto image = _model->images[i].pAsset; ImageData& imageData = _loadedImages[i]; if ((imageData.image.valid() || imageData.imageWithMipmap.valid()) && sRGB != imageData.sRGB) @@ -1124,7 +1160,7 @@ vsg::ref_ptr ModelBuilder::loadImage(int i, bool useMipMaps, bool sRG { return imageData.image; } - auto data = vsgCs::loadImage(image, useMipMaps, sRGB); + auto data = vsgCs::loadImage(*image, useMipMaps, sRGB); imageData.sRGB = sRGB; if (useMipMaps) { diff --git a/src/vsgCs/ModelBuilder.h b/src/vsgCs/ModelBuilder.h index 1101de2..2a3bea3 100644 --- a/src/vsgCs/ModelBuilder.h +++ b/src/vsgCs/ModelBuilder.h @@ -24,7 +24,7 @@ SOFTWARE. #pragma once -#include "Export.h" +#include "vsgCs/Export.h" #include "GraphicsEnvironment.h" #include "runtimeSupport.h" diff --git a/src/vsgCs/OpThreadTaskProcessor.h b/src/vsgCs/OpThreadTaskProcessor.h index 43fb9e4..f25c21c 100644 --- a/src/vsgCs/OpThreadTaskProcessor.h +++ b/src/vsgCs/OpThreadTaskProcessor.h @@ -24,7 +24,7 @@ SOFTWARE. #pragma once -#include "Export.h" +#include "vsgCs/Export.h" #include #include #include diff --git a/src/vsgCs/RuntimeEnvironment.cpp b/src/vsgCs/RuntimeEnvironment.cpp index a1f6cc8..b079994 100644 --- a/src/vsgCs/RuntimeEnvironment.cpp +++ b/src/vsgCs/RuntimeEnvironment.cpp @@ -37,6 +37,8 @@ SOFTWARE. #include +#include + using namespace vsgCs; namespace @@ -401,8 +403,8 @@ std::shared_ptr RuntimeEnvironment::ge auto creditSystem = std::make_shared(); using TE = Cesium3DTilesSelection::TilesetExternals; return _externals - = std::shared_ptr(new TE{assetAccessor, resourcePreparer, asyncSystem, creditSystem, - logger, nullptr}); // NOLINT make_shared doesn't take intializer list + = std::make_shared(TE{assetAccessor, resourcePreparer, asyncSystem, creditSystem, + logger, nullptr}); } void RuntimeEnvironment::update() diff --git a/src/vsgCs/RuntimeEnvironment.h b/src/vsgCs/RuntimeEnvironment.h index 15c020e..c61ce34 100644 --- a/src/vsgCs/RuntimeEnvironment.h +++ b/src/vsgCs/RuntimeEnvironment.h @@ -24,7 +24,7 @@ SOFTWARE. #pragma once -#include "Export.h" +#include "vsgCs/Export.h" #include "GraphicsEnvironment.h" #include #include diff --git a/src/vsgCs/Styling.cpp b/src/vsgCs/Styling.cpp index 8757eb2..19db8da 100644 --- a/src/vsgCs/Styling.cpp +++ b/src/vsgCs/Styling.cpp @@ -92,11 +92,7 @@ struct CaseInsensitiveComparator } if (pa == a.end()) { - if (pb == b.end()) - { - return false; - } - return true; + return pb != b.end(); } return false; } @@ -309,7 +305,7 @@ std::optional parseColorString(const std::string_view &color) std::optional parseColorSpec(const std::string_view expr) { - const vsg::vec4 white(1.0f, 1.0f, 1.0f, 1.0f); + static const vsg::vec4 white(1.0f, 1.0f, 1.0f, 1.0f); const std::string colorFunc("color("); if (expr.size() <= colorFunc.size()) { @@ -326,7 +322,7 @@ std::optional parseColorSpec(const std::string_view expr) } if (*match.second == '\'' || *match.second == '"') { - auto closing = std::find(match.second + 1, expr.end(), *match.second); + const auto* closing = std::find(match.second + 1, expr.end(), *match.second); if (closing == expr.end()) { return {}; @@ -440,7 +436,7 @@ Stylist::Stylist(Styling* in_styling, ModelBuilder* builder) { return; } - std::optional schema = metadata->schema; + auto schema = metadata->schema; if (!schema) { return; @@ -548,7 +544,8 @@ Stylist::PrimitiveStyling Stylist::getStyling(const CesiumGltf::MeshPrimitive *p for (int i = 0; i < featureView.size(); ++i) { auto featureIDNum = featureView[i].value[0]; - if ((featureID.nullFeatureId && featureIDNum == *featureID.nullFeatureId) + if ((featureID.nullFeatureId && static_cast(featureIDNum) + == *featureID.nullFeatureId) || !featureColors.at(static_cast(featureIDNum))) { (*result)[i] = colorWhite; diff --git a/src/vsgCs/TilesetNode.h b/src/vsgCs/TilesetNode.h index c33a567..3db0d9a 100644 --- a/src/vsgCs/TilesetNode.h +++ b/src/vsgCs/TilesetNode.h @@ -19,7 +19,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #endif #include "Cesium3DTilesSelection/Tileset.h" #include "Cesium3DTilesSelection/ViewUpdateResult.h" -#include "Export.h" +#include "vsgCs/Export.h" #include "RuntimeEnvironment.h" #include "Styling.h" #include "runtimeSupport.h" diff --git a/src/vsgCs/TracingCommandGraph.cpp b/src/vsgCs/TracingCommandGraph.cpp index be49211..90b6eb6 100644 --- a/src/vsgCs/TracingCommandGraph.cpp +++ b/src/vsgCs/TracingCommandGraph.cpp @@ -9,7 +9,7 @@ namespace vsgCs { - TracingCollectCommand::TracingCollectCommand(vsg::ref_ptr in_tracyCtx) + TracingCollectCommand::TracingCollectCommand(const vsg::ref_ptr& in_tracyCtx) : tracyCtx(in_tracyCtx) { } @@ -26,8 +26,8 @@ namespace vsgCs } TracingCommandGraph::TracingCommandGraph(const vsg::ref_ptr& in_env, - vsg::ref_ptr in_window, - vsg::ref_ptr child) + const vsg::ref_ptr& in_window, + const vsg::ref_ptr& child) : Inherit(in_window, child), features(in_env->features), tracyCtx(in_env->tracyContext) { addChild(TracingCollectCommand::create(tracyCtx)); @@ -93,8 +93,8 @@ namespace vsgCs VertexIndexDraw::accept(visitor); } - TracingRenderGraph::TracingRenderGraph(vsg::ref_ptr in_window, - vsg::ref_ptr view) + TracingRenderGraph::TracingRenderGraph(const vsg::ref_ptr& in_window, + const vsg::ref_ptr& view) : Inherit(in_window, view) { } diff --git a/src/vsgCs/TracingCommandGraph.h b/src/vsgCs/TracingCommandGraph.h index 1774943..63071c2 100644 --- a/src/vsgCs/TracingCommandGraph.h +++ b/src/vsgCs/TracingCommandGraph.h @@ -13,8 +13,8 @@ namespace vsgCs { class TracingCollectCommand : public vsg::Inherit { - public: - TracingCollectCommand(vsg::ref_ptr in_tracyCtx); + public: + TracingCollectCommand(const vsg::ref_ptr& in_tracyCtx); void record(vsg::CommandBuffer& cmd) const override; vsg::ref_ptr tracyCtx; }; @@ -22,7 +22,7 @@ namespace vsgCs class TracingCommandGraph : public vsg::Inherit { public: - explicit TracingCommandGraph(const vsg::ref_ptr& in_env, vsg::ref_ptr in_window, vsg::ref_ptr child = {}); + explicit TracingCommandGraph(const vsg::ref_ptr& in_env, const vsg::ref_ptr& in_window, const vsg::ref_ptr& child = {}); void record(vsg::ref_ptr recordedCommandBuffers, vsg::ref_ptr frameStamp, vsg::ref_ptr databasePager) override; const DeviceFeatures features; vsg::ref_ptr tracyCtx; @@ -43,7 +43,8 @@ namespace vsgCs class TracingRenderGraph : public vsg::Inherit { public: - explicit TracingRenderGraph(vsg::ref_ptr in_window, vsg::ref_ptr view = {}); + explicit TracingRenderGraph(const vsg::ref_ptr& in_window, + const vsg::ref_ptr& view = {}); void accept(vsg::RecordTraversal& visitor) const override; }; diff --git a/src/vsgCs/UrlAssetAccessor.cpp b/src/vsgCs/UrlAssetAccessor.cpp index 7ee95aa..3f2538c 100644 --- a/src/vsgCs/UrlAssetAccessor.cpp +++ b/src/vsgCs/UrlAssetAccessor.cpp @@ -52,7 +52,7 @@ class UrlAssetResponse : public CesiumAsync::IAssetResponse return _headers; } - gsl::span data() const override + std::span data() const override { return {const_cast(_result.data()), _result.size()}; } @@ -263,7 +263,7 @@ UrlAssetAccessor::request(const CesiumAsync::AsyncSystem& asyncSystem, const std::string& verb, const std::string& url, const std::vector& headers, - const gsl::span& contentPayload) + const std::span& contentPayload) { return asyncSystem.createFuture>( [&](const auto& promise) diff --git a/src/vsgCs/UrlAssetAccessor.h b/src/vsgCs/UrlAssetAccessor.h index 926729a..5e9a179 100644 --- a/src/vsgCs/UrlAssetAccessor.h +++ b/src/vsgCs/UrlAssetAccessor.h @@ -24,7 +24,7 @@ SOFTWARE. #pragma once -#include "Export.h" +#include "vsgCs/Export.h" #include "CesiumAsync/AsyncSystem.h" #include "CesiumAsync/IAssetAccessor.h" @@ -109,7 +109,7 @@ namespace vsgCs const std::string& verb, const std::string& url, const std::vector& headers, - const gsl::span& contentPayload) override; + const std::span& contentPayload) override; virtual void tick() noexcept override; CurlCache curlCache; diff --git a/src/vsgCs/WorldAnchor.h b/src/vsgCs/WorldAnchor.h index db186f3..bfe4b10 100644 --- a/src/vsgCs/WorldAnchor.h +++ b/src/vsgCs/WorldAnchor.h @@ -25,7 +25,7 @@ SOFTWARE. #pragma once #include "CRS.h" -#include "Export.h" +#include "vsgCs/Export.h" #include #include diff --git a/src/vsgCs/WorldNode.cpp b/src/vsgCs/WorldNode.cpp index 8a2dade..aeaabe4 100644 --- a/src/vsgCs/WorldNode.cpp +++ b/src/vsgCs/WorldNode.cpp @@ -57,7 +57,7 @@ bool WorldNode::initialize(const vsg::ref_ptr& viewer) { bool result = true; setMainThread(); - for (const auto& node : worldNodes()) + for (const auto& node : tilesetNodes()) { auto tilesetNode = ref_ptr_cast(node); if (!tilesetNode) @@ -92,7 +92,7 @@ bool WorldNode::initialize(const vsg::ref_ptr& viewer) void WorldNode::shutdown() { - for (const auto& node : worldNodes()) + for (const auto& node : tilesetNodes()) { auto tilesetNode = ref_ptr_cast(node); if (!tilesetNode) @@ -108,7 +108,7 @@ void WorldNode::shutdown() const Cesium3DTilesSelection::Tile* WorldNode::getRootTile(size_t tileset) { - auto tilesetNode = ref_ptr_cast(worldNodes().at(tileset)); + auto tilesetNode = ref_ptr_cast(tilesetNodes().at(tileset)); if (tilesetNode) { return tilesetNode->getTileset()->getRootTile(); diff --git a/src/vsgCs/WorldNode.h b/src/vsgCs/WorldNode.h index 7c89692..ced7e6c 100644 --- a/src/vsgCs/WorldNode.h +++ b/src/vsgCs/WorldNode.h @@ -32,7 +32,7 @@ SOFTWARE. #include #include -#include "Export.h" +#include "vsgCs/Export.h" #include "runtimeSupport.h" #include "jsonUtils.h" @@ -55,8 +55,10 @@ namespace vsgCs void shutdown(); // hack for supporting zoom after load const Cesium3DTilesSelection::Tile* getRootTile(size_t tileset = 0); - protected: - vsg::Group::Children& worldNodes() + /** + * @brief Access to the tileset array; not safe! + */ + vsg::Group::Children& tilesetNodes() { auto stateGroup = ref_ptr_cast(children[0]); return stateGroup->children; diff --git a/src/vsgCs/accessorUtils.h b/src/vsgCs/accessorUtils.h index d79f654..0d2e34f 100644 --- a/src/vsgCs/accessorUtils.h +++ b/src/vsgCs/accessorUtils.h @@ -157,7 +157,7 @@ namespace vsgCs } else { - return std::max(static_cast(val) / std::numeric_limits::max(), + return std::max(static_cast(static_cast(val) / std::numeric_limits::max()), static_cast(-1)); } } diff --git a/src/vsgCs/pbr.cpp b/src/vsgCs/pbr.cpp index 951f991..eb4d4be 100644 --- a/src/vsgCs/pbr.cpp +++ b/src/vsgCs/pbr.cpp @@ -33,7 +33,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI namespace vsgCs::pbr { vsg::ref_ptr makeTileData(float geometricError, float maxPointSize, - const gsl::span overlayUniformMem, + const std::span overlayUniformMem, float fadeValue, bool fadeOut) { // All this hair with memcpy is to avoid using reinterpret_cast with a struct, apparently @@ -67,7 +67,7 @@ namespace vsgCs::pbr memcpy(tileBufData->data() + sizeof(float) * 3, &floatFadeOut, sizeof(float)); } - void addBindings(vsg::ref_ptr shaderSet) + void addBindings(const vsg::ref_ptr& shaderSet) { shaderSet->addAttributeBinding("vsg_Vertex", "", 0, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); shaderSet->addAttributeBinding("vsg_Normal", "", 1, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); @@ -115,7 +115,7 @@ namespace vsgCs::pbr shaderSet->customDescriptorSetBindings.push_back(vsg::ViewDependentStateBinding::create(VIEW_DESCRIPTOR_SET)); } - void addTileBindings(vsg::ref_ptr shaderSet) + void addTileBindings(const vsg::ref_ptr& shaderSet) { // XXX Want a VSGCS_LOD_FADE define here, but that to messes up the descriptor defaulting mechanism. shaderSet->addDescriptorBinding("blueNoise", "", WORLD_DESCRIPTOR_SET, 0, diff --git a/src/vsgCs/pbr.h b/src/vsgCs/pbr.h index 06dc4bd..c274f0c 100644 --- a/src/vsgCs/pbr.h +++ b/src/vsgCs/pbr.h @@ -43,7 +43,7 @@ namespace vsgCs const unsigned maxOverlays = 4; vsg::ref_ptr makeTileData(float geometricError, float maxPointSize, - const gsl::span overlayUniformMem, + const std::span overlayUniformMem, float fadeValue = 1.0f, bool fadeOut = false); // Flesh out this API a bit? std::pair getFadeValue(const vsg::ref_ptr& tileData); diff --git a/src/vsgCs/runtimeSupport.cpp b/src/vsgCs/runtimeSupport.cpp index 350b9bc..18456d6 100644 --- a/src/vsgCs/runtimeSupport.cpp +++ b/src/vsgCs/runtimeSupport.cpp @@ -30,9 +30,10 @@ SOFTWARE. #include "RuntimeEnvironment.h" #include +#include #include #include -#include +#include namespace vsgCs { @@ -51,10 +52,10 @@ namespace vsgCs double distance) { auto boundingVolume = tile->getBoundingVolume(); - const auto* boundingRegion = getBoundingRegionFromBoundingVolume(boundingVolume); - if (boundingRegion) + auto globeRectangle = estimateGlobeRectangle(boundingVolume); + if (globeRectangle) { - auto cartoCenter = boundingRegion->getRectangle().computeCenter(); + auto cartoCenter = globeRectangle->computeCenter(); // The geographic coordinates specify a normal to the ellipsoid. How convenient! auto normal = CesiumGeospatial::Ellipsoid::WGS84.geodeticSurfaceNormal(cartoCenter); auto position = CesiumGeospatial::Ellipsoid::WGS84.cartographicToCartesian(cartoCenter); @@ -161,7 +162,7 @@ namespace vsgCs return result; } - vsg::ref_ptr makeImage(gsl::span data, bool useMipMaps, bool sRGB, + vsg::ref_ptr makeImage(std::span data, bool useMipMaps, bool sRGB, VkSamplerAddressMode addressX, VkSamplerAddressMode addressY, VkFilter minFilter, @@ -169,8 +170,8 @@ namespace vsgCs { auto env = RuntimeEnvironment::get(); CesiumGltfReader::ImageReaderResult result - = CesiumGltfReader::GltfReader::readImage(data, env->features.ktx2TranscodeTargets); - if (!result.image.has_value()) + = CesiumGltfReader::ImageDecoder::readImage(data, env->features.ktx2TranscodeTargets); + if (!result.pImage) { vsg::warn("Could not read image data :"); for (auto& msg : result.errors) @@ -179,7 +180,7 @@ namespace vsgCs } return {}; } - auto imageData = loadImage(result.image.value(), useMipMaps, sRGB); + auto imageData = loadImage(*result.pImage, useMipMaps, sRGB); auto sampler = makeSampler(addressX, addressY, minFilter, maxFilter, samplerLOD(imageData, useMipMaps)); env->options->sharedObjects->share(sampler); @@ -281,7 +282,7 @@ namespace vsgCs namespace { - VkFormat cesiumToVk(const CesiumGltf::ImageCesium& image, bool sRGB) + VkFormat cesiumToVk(const CesiumGltf::ImageAsset& image, bool sRGB) { using namespace CesiumGltf; auto chooseSRGB = [sRGB](VkFormat sRGBFormat, VkFormat normFormat) @@ -426,7 +427,7 @@ namespace } } - void* rgbExpand(CesiumGltf::ImageCesium& image) + void* rgbExpand(CesiumGltf::ImageAsset& image) { VSGCS_ZONESCOPED; size_t sourceSize = image.pixelData.size(); @@ -453,7 +454,7 @@ namespace namespace vsgCs { -vsg::ref_ptr loadImage(CesiumGltf::ImageCesium& image, bool useMipMaps, bool sRGB) +vsg::ref_ptr loadImage(CesiumGltf::ImageAsset& image, bool useMipMaps, bool sRGB) { VSGCS_ZONESCOPED; if (image.pixelData.empty() || image.width == 0 || image.height == 0) @@ -522,7 +523,7 @@ vsg::ref_ptr loadImage(CesiumGltf::ImageCesium& image, bool useMipMap for (; ; ) { b = s.find(sub, b); - if (b == s.npos) break; + if (b == std::string::npos) break; s.replace(b, sub.size(), other); b += other.size(); } diff --git a/src/vsgCs/runtimeSupport.h b/src/vsgCs/runtimeSupport.h index 7eb3ab2..c49b4e1 100644 --- a/src/vsgCs/runtimeSupport.h +++ b/src/vsgCs/runtimeSupport.h @@ -31,7 +31,7 @@ SOFTWARE. #include -#include "Export.h" +#include "vsgCs/Export.h" #include "vsgCs/Config.h" #include @@ -159,7 +159,7 @@ namespace vsgCs */ struct GltfImagePtr { - CesiumGltf::ImageCesium* pImage; + CesiumGltf::ImageAsset* pImage; }; /** @@ -172,43 +172,11 @@ namespace vsgCs GltfImagePtr resolveImage(const CesiumGltf::Model& model) const; }; - /** - * @brief An embedded image resource. - */ - struct EmbeddedImageSource - { - CesiumGltf::ImageCesium image; - }; - - typedef std::variant< - GltfImagePtr, - GltfImageIndex, - EmbeddedImageSource> - CesiumTextureSource; - - struct GetImageFromSource - { - CesiumGltf::ImageCesium* - operator()(GltfImagePtr& imagePtr) { - return imagePtr.pImage; - } - - CesiumGltf::ImageCesium* - operator()(EmbeddedImageSource& embeddedImage) { - return &embeddedImage.image; - } - - template - CesiumGltf::ImageCesium* operator()(TSource& /*source*/) { - return nullptr; - } - }; - /** * @brief Create an image from binary data. */ vsg::ref_ptr VSGCS_EXPORT - makeImage(gsl::span data, bool useMipMaps, bool sRGB, + makeImage(std::span data, bool useMipMaps, bool sRGB, VkSamplerAddressMode addressX = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VkSamplerAddressMode addressY = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VkFilter minFilter = VK_FILTER_LINEAR, @@ -220,7 +188,7 @@ namespace vsgCs * This returns vsg::Data because the vsg::Array2D template class does not have a more specific * superclass. */ - vsg::ref_ptr VSGCS_EXPORT loadImage(CesiumGltf::ImageCesium& image, bool useMipMaps, bool sRGB); + vsg::ref_ptr VSGCS_EXPORT loadImage(CesiumGltf::ImageAsset& image, bool useMipMaps, bool sRGB); int samplerLOD(const vsg::ref_ptr& data, bool generateMipMaps); @@ -262,6 +230,7 @@ namespace vsgCs * * The VSG cast() member function templates use typeid, so they won't work if the actual object * is a sublcass of the desired cast. + * XXX This comment is rather sus and needs further investigation... * @param TSubclass the target subclass * @param p the source ref_ptr * @return a ref_ptr that is valid if the cast succeeds, otherwise not. @@ -313,6 +282,19 @@ namespace vsgCs } } + template + void mapBox(const BoxType& box, F&& f) + { + f(box.min.x, box.min.y, box.min.z); + f(box.min.x, box.min.y, box.max.z); + f(box.min.x, box.max.y, box.min.z); + f(box.min.x, box.max.y, box.max.z); + f(box.max.x, box.min.y, box.min.z); + f(box.max.x, box.min.y, box.max.z); + f(box.max.x, box.max.y, box.min.z); + f(box.max.x, box.max.y, box.max.z); + } + std::optional getUintSuffix(const std::string& prefix, const std::string& data); // For debugging diff --git a/src/vsgCs/vsgResourcePreparer.cpp b/src/vsgCs/vsgResourcePreparer.cpp index 85fe8b6..e5b1f79 100644 --- a/src/vsgCs/vsgResourcePreparer.cpp +++ b/src/vsgCs/vsgResourcePreparer.cpp @@ -137,7 +137,7 @@ vsgResourcePreparer::prepareInLoadThread(const CesiumAsync::AsyncSystem& asyncSy const std::any& rendererOptions) { VSGCS_ZONESCOPED; - CesiumGltf::Model* pModel = std::get_if(&tileLoadResult.contentKind); + auto* pModel = std::get_if(&tileLoadResult.contentKind); if (!pModel) { return asyncSystem.createResolvedFuture( @@ -205,7 +205,7 @@ void vsgResourcePreparer::free(Cesium3DTilesSelection::Tile&, } void* -vsgResourcePreparer::prepareRasterInLoadThread(CesiumGltf::ImageCesium& image, +vsgResourcePreparer::prepareRasterInLoadThread(CesiumGltf::ImageAsset& image, const std::any& rendererOptions) { VSGCS_ZONESCOPED; diff --git a/src/vsgCs/vsgResourcePreparer.h b/src/vsgCs/vsgResourcePreparer.h index a45601d..e77d675 100644 --- a/src/vsgCs/vsgResourcePreparer.h +++ b/src/vsgCs/vsgResourcePreparer.h @@ -89,7 +89,7 @@ namespace vsgCs void* pLoadThreadResult, void* pMainThreadResult) noexcept override; - void* prepareRasterInLoadThread(CesiumGltf::ImageCesium& image, + void* prepareRasterInLoadThread(CesiumGltf::ImageAsset& image, const std::any& rendererOptions) override; void* prepareRasterInMainThread(CesiumRasterOverlays::RasterOverlayTile& rasterTile, diff --git a/vcpkg-configuration.json b/vcpkg-configuration.json new file mode 100644 index 0000000..78150f6 --- /dev/null +++ b/vcpkg-configuration.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg-configuration.schema.json", + "default-registry": { + "kind": "git", + "baseline": "b322364f06308bdd24823f9d8f03fe0cc86fd46f", + "repository": "https://github.com/microsoft/vcpkg" + }, + "registries": [ + { + "kind": "artifact", + "location": "https://github.com/microsoft/vcpkg-ce-catalog/archive/refs/heads/main.zip", + "name": "microsoft" + } + ], + "overlay-ports": [ + "extern/vcpkg-overlays" + ], + "overlay-triplets": [ "extern/vcpkg-triplets" ] +} diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 0000000..808c5a4 --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,54 @@ +{ + "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", + "name": "vsgcs", + "version": "0.9.0", + "default-features": [ + "cesium-native-port" + ], + "features": { + "cesium-native-port": { + "description": "Use vckpg overlay for Cesium Native", + "dependencies": [ + { + "name": "cesium-native" + } + ] + }, + "cesium-native-local": { + "description": "Use local source for Cesium Native", + "dependencies": [ + { + "name": "cesium-native", + "features": ["dependencies-only"] + } + ] + } + }, + "dependencies": [ + "vcpkg-cmake", + "vcpkg-cmake-config", + "cesium-native", + "curl", + { + "name": "imgui", + "features": [ + "vulkan-binding" + ] + }, + { + "name": "proj", + "default-features": false + }, + "spdlog", + "tinyxml2", + "vsg", + { + "name": "vsgxchange", + "features": [ + "assimp" + ] + }, + "vsgimgui" + ] +} +