diff --git a/ThirdParty.extra.json b/ThirdParty.extra.json index 8b9a9d5ac..9c2e3e313 100644 --- a/ThirdParty.extra.json +++ b/ThirdParty.extra.json @@ -7,6 +7,15 @@ "version": "0.15.0", "url": "https://github.com/CesiumGS/cesium-native" }, + { + "name": "cmake-conan", + "license": [ + "MIT" + ], + "notes": "conan.cmake was downloaded to work around an SSL issue, see https://github.com/conan-io/cmake-conan/issues/575", + "version": "0.17.0", + "url": "https://github.com/conan-io/cmake-conan" + }, { "name": "glTF-Asset-Generator", "license": [ diff --git a/ThirdParty.json b/ThirdParty.json index 7b4d81d1f..98082e867 100644 --- a/ThirdParty.json +++ b/ThirdParty.json @@ -7,6 +7,15 @@ "version": "0.15.0", "url": "https://github.com/CesiumGS/cesium-native" }, + { + "name": "cmake-conan", + "license": [ + "MIT" + ], + "notes": "conan.cmake was downloaded to work around an SSL issue, see https://github.com/conan-io/cmake-conan/issues/575", + "version": "0.17.0", + "url": "https://github.com/conan-io/cmake-conan" + }, { "name": "cpr", "license": [ diff --git a/apps/cesium.omniverse.dev.kit b/apps/cesium.omniverse.dev.kit index c050db6d0..0149abe8d 100644 --- a/apps/cesium.omniverse.dev.kit +++ b/apps/cesium.omniverse.dev.kit @@ -14,7 +14,7 @@ app = true [settings] app.window.title = "Cesium for Omniverse Testing App" -app.useFabricSceneDelegate = true +app.useFabricSceneDelegate = false app.usdrt.scene_delegate.enableProxyCubes = false app.usdrt.scene_delegate.geometryStreaming.enabled = false omnihydra.parallelHydraSprimSync = false diff --git a/cmake/ConfigureConan.cmake b/cmake/ConfigureConan.cmake index 2c31958b9..5c7ef9641 100644 --- a/cmake/ConfigureConan.cmake +++ b/cmake/ConfigureConan.cmake @@ -16,16 +16,12 @@ macro(configure_conan) message(FATAL_ERROR "REQUIRES was not specified") endif() - if(NOT EXISTS "${_PROJECT_BUILD_DIRECTORY}/conan.cmake") - message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan") - file( - DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/0.17.0/conan.cmake" - "${_PROJECT_BUILD_DIRECTORY}/conan.cmake" - EXPECTED_HASH SHA256=3bef79da16c2e031dc429e1dac87a08b9226418b300ce004cc125a82687baeef - TLS_VERIFY ON) + if(NOT EXISTS "${_PROJECT_BUILD_DIRECTORY}/conan-0.17.0.cmake") + message(STATUS "Copying Conan 0.17.0 into build folder") + file(COPY "${CMAKE_MODULE_PATH}/conan-0.17.0.cmake" DESTINATION "${_PROJECT_BUILD_DIRECTORY}") endif() - include("${_PROJECT_BUILD_DIRECTORY}/conan.cmake") + include("${_PROJECT_BUILD_DIRECTORY}/conan-0.17.0.cmake") # Execute conan config init to ensure ~/.conan/settings.yml exists find_program(CONAN_CMD_PATH conan) diff --git a/cmake/conan-0.17.0.cmake b/cmake/conan-0.17.0.cmake new file mode 100644 index 000000000..725484736 --- /dev/null +++ b/cmake/conan-0.17.0.cmake @@ -0,0 +1,909 @@ +# The MIT License (MIT) + +# Copyright (c) 2018 JFrog + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + + +# This file comes from: https://github.com/conan-io/cmake-conan. Please refer +# to this repository for issues and documentation. + +# Its purpose is to wrap and launch Conan C/C++ Package Manager when cmake is called. +# It will take CMake current settings (os, compiler, compiler version, architecture) +# and translate them to conan settings for installing and retrieving dependencies. + +# It is intended to facilitate developers building projects that have conan dependencies, +# but it is only necessary on the end-user side. It is not necessary to create conan +# packages, in fact it shouldn't be use for that. Check the project documentation. + +# version: 0.17.0 + +include(CMakeParseArguments) + +function(_get_msvc_ide_version result) + set(${result} "" PARENT_SCOPE) + if(NOT MSVC_VERSION VERSION_LESS 1400 AND MSVC_VERSION VERSION_LESS 1500) + set(${result} 8 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1500 AND MSVC_VERSION VERSION_LESS 1600) + set(${result} 9 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1600 AND MSVC_VERSION VERSION_LESS 1700) + set(${result} 10 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1700 AND MSVC_VERSION VERSION_LESS 1800) + set(${result} 11 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1800 AND MSVC_VERSION VERSION_LESS 1900) + set(${result} 12 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1900 AND MSVC_VERSION VERSION_LESS 1910) + set(${result} 14 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1910 AND MSVC_VERSION VERSION_LESS 1920) + set(${result} 15 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1920 AND MSVC_VERSION VERSION_LESS 1930) + set(${result} 16 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1930 AND MSVC_VERSION VERSION_LESS 1940) + set(${result} 17 PARENT_SCOPE) + else() + message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]") + endif() +endfunction() + +macro(_conan_detect_build_type) + conan_parse_arguments(${ARGV}) + + if(ARGUMENTS_BUILD_TYPE) + set(_CONAN_SETTING_BUILD_TYPE ${ARGUMENTS_BUILD_TYPE}) + elseif(CMAKE_BUILD_TYPE) + set(_CONAN_SETTING_BUILD_TYPE ${CMAKE_BUILD_TYPE}) + else() + message(FATAL_ERROR "Please specify in command line CMAKE_BUILD_TYPE (-DCMAKE_BUILD_TYPE=Release)") + endif() + + string(TOUPPER ${_CONAN_SETTING_BUILD_TYPE} _CONAN_SETTING_BUILD_TYPE_UPPER) + if (_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "DEBUG") + set(_CONAN_SETTING_BUILD_TYPE "Debug") + elseif(_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "RELEASE") + set(_CONAN_SETTING_BUILD_TYPE "Release") + elseif(_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "RELWITHDEBINFO") + set(_CONAN_SETTING_BUILD_TYPE "RelWithDebInfo") + elseif(_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "MINSIZEREL") + set(_CONAN_SETTING_BUILD_TYPE "MinSizeRel") + endif() +endmacro() + +macro(_conan_check_system_name) + #handle -s os setting + if(CMAKE_SYSTEM_NAME AND NOT CMAKE_SYSTEM_NAME STREQUAL "Generic") + #use default conan os setting if CMAKE_SYSTEM_NAME is not defined + set(CONAN_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}) + if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") + set(CONAN_SYSTEM_NAME Macos) + endif() + if(${CMAKE_SYSTEM_NAME} STREQUAL "QNX") + set(CONAN_SYSTEM_NAME Neutrino) + endif() + set(CONAN_SUPPORTED_PLATFORMS Windows Linux Macos Android iOS FreeBSD WindowsStore WindowsCE watchOS tvOS FreeBSD SunOS AIX Arduino Emscripten Neutrino) + list (FIND CONAN_SUPPORTED_PLATFORMS "${CONAN_SYSTEM_NAME}" _index) + if (${_index} GREATER -1) + #check if the cmake system is a conan supported one + set(_CONAN_SETTING_OS ${CONAN_SYSTEM_NAME}) + else() + message(FATAL_ERROR "cmake system ${CONAN_SYSTEM_NAME} is not supported by conan. Use one of ${CONAN_SUPPORTED_PLATFORMS}") + endif() + endif() +endmacro() + +macro(_conan_check_language) + get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES) + if (";${_languages};" MATCHES ";CXX;") + set(LANGUAGE CXX) + set(USING_CXX 1) + elseif (";${_languages};" MATCHES ";C;") + set(LANGUAGE C) + set(USING_CXX 0) + else () + message(FATAL_ERROR "Conan: Neither C or C++ was detected as a language for the project. Unabled to detect compiler version.") + endif() +endmacro() + +macro(_conan_detect_compiler) + + conan_parse_arguments(${ARGV}) + + if(ARGUMENTS_ARCH) + set(_CONAN_SETTING_ARCH ${ARGUMENTS_ARCH}) + endif() + + if(USING_CXX) + set(_CONAN_SETTING_COMPILER_CPPSTD ${CMAKE_CXX_STANDARD}) + endif() + + if (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL GNU) + # using GCC + # TODO: Handle other params + string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) + list(GET VERSION_LIST 0 MAJOR) + list(GET VERSION_LIST 1 MINOR) + set(COMPILER_VERSION ${MAJOR}.${MINOR}) + if(${MAJOR} GREATER 4) + set(COMPILER_VERSION ${MAJOR}) + endif() + set(_CONAN_SETTING_COMPILER gcc) + set(_CONAN_SETTING_COMPILER_VERSION ${COMPILER_VERSION}) + if (USING_CXX) + conan_cmake_detect_unix_libcxx(_LIBCXX) + set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) + endif () + elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL Intel) + string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) + list(GET VERSION_LIST 0 MAJOR) + list(GET VERSION_LIST 1 MINOR) + set(COMPILER_VERSION ${MAJOR}.${MINOR}) + set(_CONAN_SETTING_COMPILER intel) + set(_CONAN_SETTING_COMPILER_VERSION ${COMPILER_VERSION}) + if (USING_CXX) + conan_cmake_detect_unix_libcxx(_LIBCXX) + set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) + endif () + elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL AppleClang) + # using AppleClang + string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) + list(GET VERSION_LIST 0 MAJOR) + list(GET VERSION_LIST 1 MINOR) + set(_CONAN_SETTING_COMPILER apple-clang) + set(_CONAN_SETTING_COMPILER_VERSION ${MAJOR}.${MINOR}) + if (USING_CXX) + conan_cmake_detect_unix_libcxx(_LIBCXX) + set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) + endif () + elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL Clang) + string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) + list(GET VERSION_LIST 0 MAJOR) + list(GET VERSION_LIST 1 MINOR) + set(_CONAN_SETTING_COMPILER clang) + set(_CONAN_SETTING_COMPILER_VERSION ${MAJOR}.${MINOR}) + if(APPLE) + cmake_policy(GET CMP0025 APPLE_CLANG_POLICY) + if(NOT APPLE_CLANG_POLICY STREQUAL NEW) + message(STATUS "Conan: APPLE and Clang detected. Assuming apple-clang compiler. Set CMP0025 to avoid it") + set(_CONAN_SETTING_COMPILER apple-clang) + endif() + endif() + if(${_CONAN_SETTING_COMPILER} STREQUAL clang AND ${MAJOR} GREATER 7) + set(_CONAN_SETTING_COMPILER_VERSION ${MAJOR}) + endif() + if (USING_CXX) + conan_cmake_detect_unix_libcxx(_LIBCXX) + set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) + endif () + elseif(${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL MSVC) + set(_VISUAL "Visual Studio") + _get_msvc_ide_version(_VISUAL_VERSION) + if("${_VISUAL_VERSION}" STREQUAL "") + message(FATAL_ERROR "Conan: Visual Studio not recognized") + else() + set(_CONAN_SETTING_COMPILER ${_VISUAL}) + set(_CONAN_SETTING_COMPILER_VERSION ${_VISUAL_VERSION}) + endif() + + if(NOT _CONAN_SETTING_ARCH) + if (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "64") + set(_CONAN_SETTING_ARCH x86_64) + elseif (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "^ARM") + message(STATUS "Conan: Using default ARM architecture from MSVC") + set(_CONAN_SETTING_ARCH armv6) + elseif (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "86") + set(_CONAN_SETTING_ARCH x86) + else () + message(FATAL_ERROR "Conan: Unknown MSVC architecture [${MSVC_${LANGUAGE}_ARCHITECTURE_ID}]") + endif() + endif() + + conan_cmake_detect_vs_runtime(_vs_runtime ${ARGV}) + message(STATUS "Conan: Detected VS runtime: ${_vs_runtime}") + set(_CONAN_SETTING_COMPILER_RUNTIME ${_vs_runtime}) + + if (CMAKE_GENERATOR_TOOLSET) + set(_CONAN_SETTING_COMPILER_TOOLSET ${CMAKE_VS_PLATFORM_TOOLSET}) + elseif(CMAKE_VS_PLATFORM_TOOLSET AND (CMAKE_GENERATOR STREQUAL "Ninja")) + set(_CONAN_SETTING_COMPILER_TOOLSET ${CMAKE_VS_PLATFORM_TOOLSET}) + endif() + else() + message(FATAL_ERROR "Conan: compiler setup not recognized") + endif() + +endmacro() + +function(conan_cmake_settings result) + #message(STATUS "COMPILER " ${CMAKE_CXX_COMPILER}) + #message(STATUS "COMPILER " ${CMAKE_CXX_COMPILER_ID}) + #message(STATUS "VERSION " ${CMAKE_CXX_COMPILER_VERSION}) + #message(STATUS "FLAGS " ${CMAKE_LANG_FLAGS}) + #message(STATUS "LIB ARCH " ${CMAKE_CXX_LIBRARY_ARCHITECTURE}) + #message(STATUS "BUILD TYPE " ${CMAKE_BUILD_TYPE}) + #message(STATUS "GENERATOR " ${CMAKE_GENERATOR}) + #message(STATUS "GENERATOR WIN64 " ${CMAKE_CL_64}) + + message(STATUS "Conan: Automatic detection of conan settings from cmake") + + conan_parse_arguments(${ARGV}) + + _conan_detect_build_type(${ARGV}) + + _conan_check_system_name() + + _conan_check_language() + + _conan_detect_compiler(${ARGV}) + + # If profile is defined it is used + if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND ARGUMENTS_DEBUG_PROFILE) + set(_APPLIED_PROFILES ${ARGUMENTS_DEBUG_PROFILE}) + elseif(CMAKE_BUILD_TYPE STREQUAL "Release" AND ARGUMENTS_RELEASE_PROFILE) + set(_APPLIED_PROFILES ${ARGUMENTS_RELEASE_PROFILE}) + elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" AND ARGUMENTS_RELWITHDEBINFO_PROFILE) + set(_APPLIED_PROFILES ${ARGUMENTS_RELWITHDEBINFO_PROFILE}) + elseif(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel" AND ARGUMENTS_MINSIZEREL_PROFILE) + set(_APPLIED_PROFILES ${ARGUMENTS_MINSIZEREL_PROFILE}) + elseif(ARGUMENTS_PROFILE) + set(_APPLIED_PROFILES ${ARGUMENTS_PROFILE}) + endif() + + foreach(ARG ${_APPLIED_PROFILES}) + set(_SETTINGS ${_SETTINGS} -pr=${ARG}) + endforeach() + foreach(ARG ${ARGUMENTS_PROFILE_BUILD}) + conan_check(VERSION 1.24.0 REQUIRED DETECT_QUIET) + set(_SETTINGS ${_SETTINGS} -pr:b=${ARG}) + endforeach() + + if(NOT _SETTINGS OR ARGUMENTS_PROFILE_AUTO STREQUAL "ALL") + set(ARGUMENTS_PROFILE_AUTO arch build_type compiler compiler.version + compiler.runtime compiler.libcxx compiler.toolset) + endif() + + # remove any manually specified settings from the autodetected settings + foreach(ARG ${ARGUMENTS_SETTINGS}) + string(REGEX MATCH "[^=]*" MANUAL_SETTING "${ARG}") + message(STATUS "Conan: ${MANUAL_SETTING} was added as an argument. Not using the autodetected one.") + list(REMOVE_ITEM ARGUMENTS_PROFILE_AUTO "${MANUAL_SETTING}") + endforeach() + + # Automatic from CMake + foreach(ARG ${ARGUMENTS_PROFILE_AUTO}) + string(TOUPPER ${ARG} _arg_name) + string(REPLACE "." "_" _arg_name ${_arg_name}) + if(_CONAN_SETTING_${_arg_name}) + set(_SETTINGS ${_SETTINGS} -s ${ARG}=${_CONAN_SETTING_${_arg_name}}) + endif() + endforeach() + + foreach(ARG ${ARGUMENTS_SETTINGS}) + set(_SETTINGS ${_SETTINGS} -s ${ARG}) + endforeach() + + message(STATUS "Conan: Settings= ${_SETTINGS}") + + set(${result} ${_SETTINGS} PARENT_SCOPE) +endfunction() + + +function(conan_cmake_detect_unix_libcxx result) + # Take into account any -stdlib in compile options + get_directory_property(compile_options DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_OPTIONS) + string(GENEX_STRIP "${compile_options}" compile_options) + + # Take into account any _GLIBCXX_USE_CXX11_ABI in compile definitions + get_directory_property(defines DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS) + string(GENEX_STRIP "${defines}" defines) + + foreach(define ${defines}) + if(define MATCHES "_GLIBCXX_USE_CXX11_ABI") + if(define MATCHES "^-D") + set(compile_options ${compile_options} "${define}") + else() + set(compile_options ${compile_options} "-D${define}") + endif() + endif() + endforeach() + + # add additional compiler options ala cmRulePlaceholderExpander::ExpandRuleVariable + set(EXPAND_CXX_COMPILER ${CMAKE_CXX_COMPILER}) + if(CMAKE_CXX_COMPILER_ARG1) + # CMake splits CXX="foo bar baz" into CMAKE_CXX_COMPILER="foo", CMAKE_CXX_COMPILER_ARG1="bar baz" + # without this, ccache, winegcc, or other wrappers might lose all their arguments + separate_arguments(SPLIT_CXX_COMPILER_ARG1 NATIVE_COMMAND ${CMAKE_CXX_COMPILER_ARG1}) + list(APPEND EXPAND_CXX_COMPILER ${SPLIT_CXX_COMPILER_ARG1}) + endif() + + if(CMAKE_CXX_COMPILE_OPTIONS_TARGET AND CMAKE_CXX_COMPILER_TARGET) + # without --target= we may be calling the wrong underlying GCC + list(APPEND EXPAND_CXX_COMPILER "${CMAKE_CXX_COMPILE_OPTIONS_TARGET}${CMAKE_CXX_COMPILER_TARGET}") + endif() + + if(CMAKE_CXX_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN AND CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN) + list(APPEND EXPAND_CXX_COMPILER "${CMAKE_CXX_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN}${CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN}") + endif() + + if(CMAKE_CXX_COMPILE_OPTIONS_SYSROOT) + # without --sysroot= we may find the wrong #include + if(CMAKE_SYSROOT_COMPILE) + list(APPEND EXPAND_CXX_COMPILER "${CMAKE_CXX_COMPILE_OPTIONS_SYSROOT}${CMAKE_SYSROOT_COMPILE}") + elseif(CMAKE_SYSROOT) + list(APPEND EXPAND_CXX_COMPILER "${CMAKE_CXX_COMPILE_OPTIONS_SYSROOT}${CMAKE_SYSROOT}") + endif() + endif() + + separate_arguments(SPLIT_CXX_FLAGS NATIVE_COMMAND ${CMAKE_CXX_FLAGS}) + + if(CMAKE_OSX_SYSROOT) + set(xcode_sysroot_option "--sysroot=${CMAKE_OSX_SYSROOT}") + endif() + + execute_process( + COMMAND ${CMAKE_COMMAND} -E echo "#include " + COMMAND ${EXPAND_CXX_COMPILER} ${SPLIT_CXX_FLAGS} -x c++ ${xcode_sysroot_option} ${compile_options} -E -dM - + OUTPUT_VARIABLE string_defines + ) + + if(string_defines MATCHES "#define __GLIBCXX__") + # Allow -D_GLIBCXX_USE_CXX11_ABI=ON/OFF as argument to cmake + if(DEFINED _GLIBCXX_USE_CXX11_ABI) + if(_GLIBCXX_USE_CXX11_ABI) + set(${result} libstdc++11 PARENT_SCOPE) + return() + else() + set(${result} libstdc++ PARENT_SCOPE) + return() + endif() + endif() + + if(string_defines MATCHES "#define _GLIBCXX_USE_CXX11_ABI 1\n") + set(${result} libstdc++11 PARENT_SCOPE) + else() + # Either the compiler is missing the define because it is old, and so + # it can't use the new abi, or the compiler was configured to use the + # old abi by the user or distro (e.g. devtoolset on RHEL/CentOS) + set(${result} libstdc++ PARENT_SCOPE) + endif() + else() + set(${result} libc++ PARENT_SCOPE) + endif() +endfunction() + +function(conan_cmake_detect_vs_runtime result) + + conan_parse_arguments(${ARGV}) + if(ARGUMENTS_BUILD_TYPE) + set(build_type "${ARGUMENTS_BUILD_TYPE}") + elseif(CMAKE_BUILD_TYPE) + set(build_type "${CMAKE_BUILD_TYPE}") + else() + message(FATAL_ERROR "Please specify in command line CMAKE_BUILD_TYPE (-DCMAKE_BUILD_TYPE=Release)") + endif() + + if(build_type) + string(TOUPPER "${build_type}" build_type) + endif() + set(variables CMAKE_CXX_FLAGS_${build_type} CMAKE_C_FLAGS_${build_type} CMAKE_CXX_FLAGS CMAKE_C_FLAGS) + foreach(variable ${variables}) + if(NOT "${${variable}}" STREQUAL "") + string(REPLACE " " ";" flags "${${variable}}") + foreach (flag ${flags}) + if("${flag}" STREQUAL "/MD" OR "${flag}" STREQUAL "/MDd" OR "${flag}" STREQUAL "/MT" OR "${flag}" STREQUAL "/MTd") + string(SUBSTRING "${flag}" 1 -1 runtime) + set(${result} "${runtime}" PARENT_SCOPE) + return() + endif() + endforeach() + endif() + endforeach() + if("${build_type}" STREQUAL "DEBUG") + set(${result} "MDd" PARENT_SCOPE) + else() + set(${result} "MD" PARENT_SCOPE) + endif() +endfunction() + +function(_collect_settings result) + set(ARGUMENTS_PROFILE_AUTO arch build_type compiler compiler.version + compiler.runtime compiler.libcxx compiler.toolset + compiler.cppstd) + foreach(ARG ${ARGUMENTS_PROFILE_AUTO}) + string(TOUPPER ${ARG} _arg_name) + string(REPLACE "." "_" _arg_name ${_arg_name}) + if(_CONAN_SETTING_${_arg_name}) + set(detected_setings ${detected_setings} ${ARG}=${_CONAN_SETTING_${_arg_name}}) + endif() + endforeach() + set(${result} ${detected_setings} PARENT_SCOPE) +endfunction() + +function(conan_cmake_autodetect detected_settings) + _conan_detect_build_type(${ARGV}) + _conan_check_system_name() + _conan_check_language() + _conan_detect_compiler(${ARGV}) + _collect_settings(collected_settings) + set(${detected_settings} ${collected_settings} PARENT_SCOPE) +endfunction() + +macro(conan_parse_arguments) + set(options BASIC_SETUP CMAKE_TARGETS UPDATE KEEP_RPATHS NO_LOAD NO_OUTPUT_DIRS OUTPUT_QUIET NO_IMPORTS SKIP_STD) + set(oneValueArgs CONANFILE ARCH BUILD_TYPE INSTALL_FOLDER CONAN_COMMAND) + set(multiValueArgs DEBUG_PROFILE RELEASE_PROFILE RELWITHDEBINFO_PROFILE MINSIZEREL_PROFILE + PROFILE REQUIRES OPTIONS IMPORTS SETTINGS BUILD ENV GENERATORS PROFILE_AUTO + INSTALL_ARGS CONFIGURATION_TYPES PROFILE_BUILD BUILD_REQUIRES) + cmake_parse_arguments(ARGUMENTS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) +endmacro() + +function(old_conan_cmake_install) + # Calls "conan install" + # Argument BUILD is equivalant to --build={missing, PkgName,...} or + # --build when argument is 'BUILD all' (which builds all packages from source) + # Argument CONAN_COMMAND, to specify the conan path, e.g. in case of running from source + # cmake does not identify conan as command, even if it is +x and it is in the path + conan_parse_arguments(${ARGV}) + + if(CONAN_CMAKE_MULTI) + set(ARGUMENTS_GENERATORS ${ARGUMENTS_GENERATORS} cmake_multi) + else() + set(ARGUMENTS_GENERATORS ${ARGUMENTS_GENERATORS} cmake) + endif() + + set(CONAN_BUILD_POLICY "") + foreach(ARG ${ARGUMENTS_BUILD}) + if(${ARG} STREQUAL "all") + set(CONAN_BUILD_POLICY ${CONAN_BUILD_POLICY} --build) + break() + else() + set(CONAN_BUILD_POLICY ${CONAN_BUILD_POLICY} --build=${ARG}) + endif() + endforeach() + if(ARGUMENTS_CONAN_COMMAND) + set(CONAN_CMD ${ARGUMENTS_CONAN_COMMAND}) + else() + conan_check(REQUIRED) + endif() + set(CONAN_OPTIONS "") + if(ARGUMENTS_CONANFILE) + if(IS_ABSOLUTE ${ARGUMENTS_CONANFILE}) + set(CONANFILE ${ARGUMENTS_CONANFILE}) + else() + set(CONANFILE ${CMAKE_CURRENT_SOURCE_DIR}/${ARGUMENTS_CONANFILE}) + endif() + else() + set(CONANFILE ".") + endif() + foreach(ARG ${ARGUMENTS_OPTIONS}) + set(CONAN_OPTIONS ${CONAN_OPTIONS} -o=${ARG}) + endforeach() + if(ARGUMENTS_UPDATE) + set(CONAN_INSTALL_UPDATE --update) + endif() + if(ARGUMENTS_NO_IMPORTS) + set(CONAN_INSTALL_NO_IMPORTS --no-imports) + endif() + set(CONAN_INSTALL_FOLDER "") + if(ARGUMENTS_INSTALL_FOLDER) + set(CONAN_INSTALL_FOLDER -if=${ARGUMENTS_INSTALL_FOLDER}) + endif() + foreach(ARG ${ARGUMENTS_GENERATORS}) + set(CONAN_GENERATORS ${CONAN_GENERATORS} -g=${ARG}) + endforeach() + foreach(ARG ${ARGUMENTS_ENV}) + set(CONAN_ENV_VARS ${CONAN_ENV_VARS} -e=${ARG}) + endforeach() + set(conan_args install ${CONANFILE} ${settings} ${CONAN_ENV_VARS} ${CONAN_GENERATORS} ${CONAN_BUILD_POLICY} ${CONAN_INSTALL_UPDATE} ${CONAN_INSTALL_NO_IMPORTS} ${CONAN_OPTIONS} ${CONAN_INSTALL_FOLDER} ${ARGUMENTS_INSTALL_ARGS}) + + string (REPLACE ";" " " _conan_args "${conan_args}") + message(STATUS "Conan executing: ${CONAN_CMD} ${_conan_args}") + + if(ARGUMENTS_OUTPUT_QUIET) + execute_process(COMMAND ${CONAN_CMD} ${conan_args} + RESULT_VARIABLE return_code + OUTPUT_VARIABLE conan_output + ERROR_VARIABLE conan_output + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + else() + execute_process(COMMAND ${CONAN_CMD} ${conan_args} + RESULT_VARIABLE return_code + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + endif() + + if(NOT "${return_code}" STREQUAL "0") + message(FATAL_ERROR "Conan install failed='${return_code}'") + endif() + +endfunction() + +function(conan_cmake_install) + if(DEFINED CONAN_COMMAND) + set(CONAN_CMD ${CONAN_COMMAND}) + else() + conan_check(REQUIRED) + endif() + + set(installOptions UPDATE NO_IMPORTS OUTPUT_QUIET ERROR_QUIET) + set(installOneValueArgs PATH_OR_REFERENCE REFERENCE REMOTE LOCKFILE LOCKFILE_OUT LOCKFILE_NODE_ID INSTALL_FOLDER) + set(installMultiValueArgs GENERATOR BUILD ENV ENV_HOST ENV_BUILD OPTIONS_HOST OPTIONS OPTIONS_BUILD PROFILE + PROFILE_HOST PROFILE_BUILD SETTINGS SETTINGS_HOST SETTINGS_BUILD) + cmake_parse_arguments(ARGS "${installOptions}" "${installOneValueArgs}" "${installMultiValueArgs}" ${ARGN}) + foreach(arg ${installOptions}) + if(ARGS_${arg}) + set(${arg} ${${arg}} ${ARGS_${arg}}) + endif() + endforeach() + foreach(arg ${installOneValueArgs}) + if(DEFINED ARGS_${arg}) + if("${arg}" STREQUAL "REMOTE") + set(flag "--remote") + elseif("${arg}" STREQUAL "LOCKFILE") + set(flag "--lockfile") + elseif("${arg}" STREQUAL "LOCKFILE_OUT") + set(flag "--lockfile-out") + elseif("${arg}" STREQUAL "LOCKFILE_NODE_ID") + set(flag "--lockfile-node-id") + elseif("${arg}" STREQUAL "INSTALL_FOLDER") + set(flag "--install-folder") + endif() + set(${arg} ${${arg}} ${flag} ${ARGS_${arg}}) + endif() + endforeach() + foreach(arg ${installMultiValueArgs}) + if(DEFINED ARGS_${arg}) + if("${arg}" STREQUAL "GENERATOR") + set(flag "--generator") + elseif("${arg}" STREQUAL "BUILD") + set(flag "--build") + elseif("${arg}" STREQUAL "ENV") + set(flag "--env") + elseif("${arg}" STREQUAL "ENV_HOST") + set(flag "--env:host") + elseif("${arg}" STREQUAL "ENV_BUILD") + set(flag "--env:build") + elseif("${arg}" STREQUAL "OPTIONS") + set(flag "--options") + elseif("${arg}" STREQUAL "OPTIONS_HOST") + set(flag "--options:host") + elseif("${arg}" STREQUAL "OPTIONS_BUILD") + set(flag "--options:build") + elseif("${arg}" STREQUAL "PROFILE") + set(flag "--profile") + elseif("${arg}" STREQUAL "PROFILE_HOST") + set(flag "--profile:host") + elseif("${arg}" STREQUAL "PROFILE_BUILD") + set(flag "--profile:build") + elseif("${arg}" STREQUAL "SETTINGS") + set(flag "--settings") + elseif("${arg}" STREQUAL "SETTINGS_HOST") + set(flag "--settings:host") + elseif("${arg}" STREQUAL "SETTINGS_BUILD") + set(flag "--settings:build") + endif() + list(LENGTH ARGS_${arg} numargs) + foreach(item ${ARGS_${arg}}) + if(${item} STREQUAL "all" AND ${arg} STREQUAL "BUILD") + set(${arg} "--build") + break() + endif() + set(${arg} ${${arg}} ${flag} ${item}) + endforeach() + endif() + endforeach() + if(DEFINED UPDATE) + set(UPDATE --update) + endif() + if(DEFINED NO_IMPORTS) + set(NO_IMPORTS --no-imports) + endif() + set(install_args install ${PATH_OR_REFERENCE} ${REFERENCE} ${UPDATE} ${NO_IMPORTS} ${REMOTE} ${LOCKFILE} ${LOCKFILE_OUT} ${LOCKFILE_NODE_ID} ${INSTALL_FOLDER} + ${GENERATOR} ${BUILD} ${ENV} ${ENV_HOST} ${ENV_BUILD} ${OPTIONS} ${OPTIONS_HOST} ${OPTIONS_BUILD} + ${PROFILE} ${PROFILE_HOST} ${PROFILE_BUILD} ${SETTINGS} ${SETTINGS_HOST} ${SETTINGS_BUILD}) + + string(REPLACE ";" " " _install_args "${install_args}") + message(STATUS "Conan executing: ${CONAN_CMD} ${_install_args}") + + if(ARGS_OUTPUT_QUIET) + set(OUTPUT_OPT OUTPUT_QUIET) + endif() + if(ARGS_ERROR_QUIET) + set(ERROR_OPT ERROR_QUIET) + endif() + + execute_process(COMMAND ${CONAN_CMD} ${install_args} + RESULT_VARIABLE return_code + ${OUTPUT_OPT} + ${ERROR_OPT} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + + if(NOT "${return_code}" STREQUAL "0") + if (ARGS_ERROR_QUIET) + message(WARNING "Conan install failed='${return_code}'") + else() + message(FATAL_ERROR "Conan install failed='${return_code}'") + endif() + endif() + +endfunction() + +function(conan_cmake_setup_conanfile) + conan_parse_arguments(${ARGV}) + if(ARGUMENTS_CONANFILE) + get_filename_component(_CONANFILE_NAME ${ARGUMENTS_CONANFILE} NAME) + # configure_file will make sure cmake re-runs when conanfile is updated + configure_file(${ARGUMENTS_CONANFILE} ${CMAKE_CURRENT_BINARY_DIR}/${_CONANFILE_NAME}.junk COPYONLY) + file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/${_CONANFILE_NAME}.junk) + else() + conan_cmake_generate_conanfile(ON ${ARGV}) + endif() +endfunction() + +function(conan_cmake_configure) + conan_cmake_generate_conanfile(OFF ${ARGV}) +endfunction() + +# Generate, writing in disk a conanfile.txt with the requires, options, and imports +# specified as arguments +# This will be considered as temporary file, generated in CMAKE_CURRENT_BINARY_DIR) +function(conan_cmake_generate_conanfile DEFAULT_GENERATOR) + + conan_parse_arguments(${ARGV}) + + set(_FN "${CMAKE_CURRENT_BINARY_DIR}/conanfile.txt") + file(WRITE ${_FN} "") + + if(DEFINED ARGUMENTS_REQUIRES) + file(APPEND ${_FN} "[requires]\n") + foreach(REQUIRE ${ARGUMENTS_REQUIRES}) + file(APPEND ${_FN} ${REQUIRE} "\n") + endforeach() + endif() + + if (DEFAULT_GENERATOR OR DEFINED ARGUMENTS_GENERATORS) + file(APPEND ${_FN} "[generators]\n") + if (DEFAULT_GENERATOR) + file(APPEND ${_FN} "cmake\n") + endif() + if (DEFINED ARGUMENTS_GENERATORS) + foreach(GENERATOR ${ARGUMENTS_GENERATORS}) + file(APPEND ${_FN} ${GENERATOR} "\n") + endforeach() + endif() + endif() + + if(DEFINED ARGUMENTS_BUILD_REQUIRES) + file(APPEND ${_FN} "[build_requires]\n") + foreach(BUILD_REQUIRE ${ARGUMENTS_BUILD_REQUIRES}) + file(APPEND ${_FN} ${BUILD_REQUIRE} "\n") + endforeach() + endif() + + if(DEFINED ARGUMENTS_IMPORTS) + file(APPEND ${_FN} "[imports]\n") + foreach(IMPORTS ${ARGUMENTS_IMPORTS}) + file(APPEND ${_FN} ${IMPORTS} "\n") + endforeach() + endif() + + if(DEFINED ARGUMENTS_OPTIONS) + file(APPEND ${_FN} "[options]\n") + foreach(OPTION ${ARGUMENTS_OPTIONS}) + file(APPEND ${_FN} ${OPTION} "\n") + endforeach() + endif() + +endfunction() + + +macro(conan_load_buildinfo) + if(CONAN_CMAKE_MULTI) + set(_CONANBUILDINFO conanbuildinfo_multi.cmake) + else() + set(_CONANBUILDINFO conanbuildinfo.cmake) + endif() + if(ARGUMENTS_INSTALL_FOLDER) + set(_CONANBUILDINFOFOLDER ${ARGUMENTS_INSTALL_FOLDER}) + else() + set(_CONANBUILDINFOFOLDER ${CMAKE_CURRENT_BINARY_DIR}) + endif() + # Checks for the existence of conanbuildinfo.cmake, and loads it + # important that it is macro, so variables defined at parent scope + if(EXISTS "${_CONANBUILDINFOFOLDER}/${_CONANBUILDINFO}") + message(STATUS "Conan: Loading ${_CONANBUILDINFO}") + include(${_CONANBUILDINFOFOLDER}/${_CONANBUILDINFO}) + else() + message(FATAL_ERROR "${_CONANBUILDINFO} doesn't exist in ${CMAKE_CURRENT_BINARY_DIR}") + endif() +endmacro() + + +macro(conan_cmake_run) + conan_parse_arguments(${ARGV}) + + if(ARGUMENTS_CONFIGURATION_TYPES AND NOT CMAKE_CONFIGURATION_TYPES) + message(WARNING "CONFIGURATION_TYPES should only be specified for multi-configuration generators") + elseif(ARGUMENTS_CONFIGURATION_TYPES AND ARGUMENTS_BUILD_TYPE) + message(WARNING "CONFIGURATION_TYPES and BUILD_TYPE arguments should not be defined at the same time.") + endif() + + if(CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE AND NOT CONAN_EXPORTED + AND NOT ARGUMENTS_BUILD_TYPE) + set(CONAN_CMAKE_MULTI ON) + if (NOT ARGUMENTS_CONFIGURATION_TYPES) + set(ARGUMENTS_CONFIGURATION_TYPES "Release;Debug") + endif() + message(STATUS "Conan: Using cmake-multi generator") + else() + set(CONAN_CMAKE_MULTI OFF) + endif() + + if(NOT CONAN_EXPORTED) + conan_cmake_setup_conanfile(${ARGV}) + if(CONAN_CMAKE_MULTI) + foreach(CMAKE_BUILD_TYPE ${ARGUMENTS_CONFIGURATION_TYPES}) + set(ENV{CONAN_IMPORT_PATH} ${CMAKE_BUILD_TYPE}) + conan_cmake_settings(settings ${ARGV}) + old_conan_cmake_install(SETTINGS ${settings} ${ARGV}) + endforeach() + set(CMAKE_BUILD_TYPE) + else() + conan_cmake_settings(settings ${ARGV}) + old_conan_cmake_install(SETTINGS ${settings} ${ARGV}) + endif() + endif() + + if (NOT ARGUMENTS_NO_LOAD) + conan_load_buildinfo() + endif() + + if(ARGUMENTS_BASIC_SETUP) + foreach(_option CMAKE_TARGETS KEEP_RPATHS NO_OUTPUT_DIRS SKIP_STD) + if(ARGUMENTS_${_option}) + if(${_option} STREQUAL "CMAKE_TARGETS") + list(APPEND _setup_options "TARGETS") + else() + list(APPEND _setup_options ${_option}) + endif() + endif() + endforeach() + conan_basic_setup(${_setup_options}) + endif() +endmacro() + +macro(conan_check) + # Checks conan availability in PATH + # Arguments REQUIRED, DETECT_QUIET and VERSION are optional + # Example usage: + # conan_check(VERSION 1.0.0 REQUIRED) + set(options REQUIRED DETECT_QUIET) + set(oneValueArgs VERSION) + cmake_parse_arguments(CONAN "${options}" "${oneValueArgs}" "" ${ARGN}) + if(NOT CONAN_DETECT_QUIET) + message(STATUS "Conan: checking conan executable") + endif() + + find_program(CONAN_CMD conan) + if(NOT CONAN_CMD AND CONAN_REQUIRED) + message(FATAL_ERROR "Conan executable not found! Please install conan.") + endif() + if(NOT CONAN_DETECT_QUIET) + message(STATUS "Conan: Found program ${CONAN_CMD}") + endif() + execute_process(COMMAND ${CONAN_CMD} --version + RESULT_VARIABLE return_code + OUTPUT_VARIABLE CONAN_VERSION_OUTPUT + ERROR_VARIABLE CONAN_VERSION_OUTPUT) + + if(NOT "${return_code}" STREQUAL "0") + message(FATAL_ERROR "Conan --version failed='${return_code}'") + endif() + + if(NOT CONAN_DETECT_QUIET) + string(STRIP "${CONAN_VERSION_OUTPUT}" _CONAN_VERSION_OUTPUT) + message(STATUS "Conan: Version found ${_CONAN_VERSION_OUTPUT}") + endif() + + if(DEFINED CONAN_VERSION) + string(REGEX MATCH ".*Conan version ([0-9]+\\.[0-9]+\\.[0-9]+)" FOO + "${CONAN_VERSION_OUTPUT}") + if(${CMAKE_MATCH_1} VERSION_LESS ${CONAN_VERSION}) + message(FATAL_ERROR "Conan outdated. Installed: ${CMAKE_MATCH_1}, \ + required: ${CONAN_VERSION}. Consider updating via 'pip \ + install conan==${CONAN_VERSION}'.") + endif() + endif() +endmacro() + +function(conan_add_remote) + # Adds a remote + # Arguments URL and NAME are required, INDEX, COMMAND and VERIFY_SSL are optional + # Example usage: + # conan_add_remote(NAME bincrafters INDEX 1 + # URL https://api.bintray.com/conan/bincrafters/public-conan + # VERIFY_SSL True) + set(oneValueArgs URL NAME INDEX COMMAND VERIFY_SSL) + cmake_parse_arguments(CONAN "" "${oneValueArgs}" "" ${ARGN}) + + if(DEFINED CONAN_INDEX) + set(CONAN_INDEX_ARG "-i ${CONAN_INDEX}") + endif() + if(DEFINED CONAN_COMMAND) + set(CONAN_CMD ${CONAN_COMMAND}) + else() + conan_check(REQUIRED DETECT_QUIET) + endif() + set(CONAN_VERIFY_SSL_ARG "True") + if(DEFINED CONAN_VERIFY_SSL) + set(CONAN_VERIFY_SSL_ARG ${CONAN_VERIFY_SSL}) + endif() + message(STATUS "Conan: Adding ${CONAN_NAME} remote repository (${CONAN_URL}) verify ssl (${CONAN_VERIFY_SSL_ARG})") + execute_process(COMMAND ${CONAN_CMD} remote add ${CONAN_NAME} ${CONAN_INDEX_ARG} -f ${CONAN_URL} ${CONAN_VERIFY_SSL_ARG} + RESULT_VARIABLE return_code) + if(NOT "${return_code}" STREQUAL "0") + message(FATAL_ERROR "Conan remote failed='${return_code}'") + endif() +endfunction() + +macro(conan_config_install) + # install a full configuration from a local or remote zip file + # Argument ITEM is required, arguments TYPE, SOURCE, TARGET and VERIFY_SSL are optional + # Example usage: + # conan_config_install(ITEM https://github.com/conan-io/cmake-conan.git + # TYPE git SOURCE source-folder TARGET target-folder VERIFY_SSL false) + set(oneValueArgs ITEM TYPE SOURCE TARGET VERIFY_SSL) + set(multiValueArgs ARGS) + cmake_parse_arguments(CONAN "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + find_program(CONAN_CMD conan) + if(NOT CONAN_CMD AND CONAN_REQUIRED) + message(FATAL_ERROR "Conan executable not found!") + endif() + + if(DEFINED CONAN_VERIFY_SSL) + set(CONAN_VERIFY_SSL_ARG "--verify-ssl=${CONAN_VERIFY_SSL}") + endif() + + if(DEFINED CONAN_TYPE) + set(CONAN_TYPE_ARG "--type=${CONAN_TYPE}") + endif() + + if(DEFINED CONAN_ARGS) + set(CONAN_ARGS_ARGS "--args=\"${CONAN_ARGS}\"") + endif() + + if(DEFINED CONAN_SOURCE) + set(CONAN_SOURCE_ARGS "--source-folder=${CONAN_SOURCE}") + endif() + + if(DEFINED CONAN_TARGET) + set(CONAN_TARGET_ARGS "--target-folder=${CONAN_TARGET}") + endif() + + set (CONAN_CONFIG_INSTALL_ARGS ${CONAN_VERIFY_SSL_ARG} + ${CONAN_TYPE_ARG} + ${CONAN_ARGS_ARGS} + ${CONAN_SOURCE_ARGS} + ${CONAN_TARGET_ARGS}) + + message(STATUS "Conan: Installing config from ${CONAN_ITEM}") + execute_process(COMMAND ${CONAN_CMD} config install ${CONAN_ITEM} ${CONAN_CONFIG_INSTALL_ARGS} + RESULT_VARIABLE return_code) + if(NOT "${return_code}" STREQUAL "0") + message(FATAL_ERROR "Conan config failed='${return_code}'") + endif() +endmacro() diff --git a/exts/cesium.omniverse/mdl/cesium.mdl b/exts/cesium.omniverse/mdl/cesium.mdl index 81b88adcd..53560fc51 100644 --- a/exts/cesium.omniverse/mdl/cesium.mdl +++ b/exts/cesium.omniverse/mdl/cesium.mdl @@ -11,64 +11,215 @@ module [[ anno::display_name("Cesium MDL functions") ]]; -// For internal use only -export gltf_texture_lookup_value cesium_texture_lookup(*) [[ anno::hidden() ]] = gltf_texture_lookup(); -export material cesium_material(*) [[ anno::hidden() ]] = gltf_material(); - -export gltf_texture_lookup_value cesium_texture_array_lookup( - uniform int texture_count = 0, - gltf_texture_lookup_value texture_0 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_1 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_2 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_3 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_4 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_5 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_6 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_7 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_8 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_9 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_10 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_11 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_12 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_13 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_14 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_15 = gltf_texture_lookup() -) [[ anno::hidden() ]] +annotation annotation_not_connectable(); + +export float4 cesium_base_color_texture_float4( + gltf_texture_lookup_value base_color_texture = gltf_texture_lookup_value() + [[ + anno::hidden(), + annotation_not_connectable() + ]] +) +[[ + anno::display_name("Cesium base color texture lookup float4"), + anno::description("Returns the base color texture as a float4. Returns [0, 0, 0, 0] if the base color texture does not exist."), + anno::author("Cesium GS Inc."), + anno::in_group("Cesium") +]] +{ + return base_color_texture.valid ? base_color_texture.value : float4(0.0); +} + +export float4 cesium_imagery_layer_float4( + gltf_texture_lookup_value imagery_layer = gltf_texture_lookup_value() + [[ + anno::hidden(), + annotation_not_connectable() + ]], + int imagery_layer_index = 0 + [[ + anno::unused() + ]] +) +[[ + anno::display_name("Cesium imagery layer lookup float4"), + anno::description("Returns the imagery layer at the given index as a float4. Returns [0, 0, 0, 0] if the imagery layer does not exist."), + anno::author("Cesium GS Inc."), + anno::in_group("Cesium") +]] { - // The array length should match MAX_TEXTURE_LAYER_COUNT in Tokens.h - gltf_texture_lookup_value[16] texture_values( - texture_0, - texture_1, - texture_2, - texture_3, - texture_4, - texture_5, - texture_6, - texture_7, - texture_8, - texture_9, - texture_10, - texture_11, - texture_12, - texture_13, - texture_14, - texture_15, + return imagery_layer.valid ? imagery_layer.value : float4(0.0); +} + +export material cesium_material( + uniform color base_color_factor = color(1.0) + [[ + anno::display_name("Base Color Factor"), + anno::description("The base color of the material.") + ]], + uniform float metallic_factor = 0.0 + [[ + anno::hard_range(0.0, 1.0), + anno::display_name("Metallic Factor"), + anno::description("The metalness of the material. Select between dielectric (0.0) and metallic (1.0).") + ]], + + uniform float roughness_factor = 1.0 + [[ + anno::hard_range(0.0, 1.0), + anno::display_name("Roughness Factor"), + anno::description("The roughness of the material. Select between very glossy (0.0) and dull (1.0).") + ]], + uniform color emissive_factor = color(0.0) + [[ + anno::display_name("Emissive Factor"), + anno::description("The emissive color of the material.") + ]], + uniform gltf_alpha_mode alpha_mode = opaque + [[ + anno::display_name("Alpha Mode"), + anno::description("Select how to interpret the alpha value.") + ]], + uniform float base_alpha = 1.0 + [[ + anno::hard_range(0.0, 1.0), + anno::display_name("Base Alpha"), + anno::description("Select between transparent (0.0) and opaque (1.0)."), + anno::enable_if("alpha_mode!=opaque") + ]], + uniform float alpha_cutoff = 0.5 + [[ + anno::hard_range(0.0, 1.0), + anno::display_name("Alpha Cutoff"), + anno::description("Threshold to decide between fully transparent and fully opaque when alpha mode is 'mask'."), + anno::enable_if("alpha_mode==mask") + ]] +) [[ + anno::display_name("Cesium PBR material"), + anno::description("Cesium metallic-roughness material based off glTF PBR model"), + anno::author("Cesium GS Inc."), + anno::in_group("Cesium") +]] = let { + material base = gltf_material( + base_color_factor: base_color_factor, + metallic_factor: metallic_factor, + roughness_factor: roughness_factor, + emissive_factor: emissive_factor, + alpha_mode: alpha_mode, + base_alpha: base_alpha, + alpha_cutoff: alpha_cutoff + ); + +} in material( + thin_walled: base.thin_walled, + surface: base.surface, + volume: base.volume, + ior: base.ior, + geometry: base.geometry +); + +float4 alpha_blend(float4 src, float4 dst) { + return src * float4(src.w, src.w, src.w, 1.0) + dst * (1.0 - src.w); +} + +float4 compute_base_color( + gltf_texture_lookup_value imagery_layers_texture, + color debug_color, + gltf_texture_lookup_value base_color_texture, + color base_color_factor, + float base_alpha) { + + auto debug_color_float3 = float3(debug_color); + auto base_color_factor_float3 = float3(base_color_factor); + + auto base_color = base_color_texture.valid ? base_color_texture.value : float4(1.0); + base_color *= float4(base_color_factor_float3.x, base_color_factor_float3.y, base_color_factor_float3.z, base_alpha); + base_color = alpha_blend(imagery_layers_texture.value, base_color); + base_color *= float4(debug_color_float3.x, debug_color_float3.y, debug_color_float3.z, 1.0); + + return base_color; +} + +export gltf_texture_lookup_value cesium_internal_texture_lookup(*) [[ anno::hidden() ]] = gltf_texture_lookup(); + +export material cesium_internal_material( + gltf_texture_lookup_value imagery_layers_texture = gltf_texture_lookup_value(true, float4(0.0)), + uniform color debug_color = color(1.0), + // gltf_material inputs below + gltf_texture_lookup_value base_color_texture = gltf_texture_lookup_value(), + uniform color base_color_factor = color(1.0), + uniform float metallic_factor = 1.0, + uniform float roughness_factor = 1.0, + uniform color emissive_factor = color(0.0), + uniform gltf_alpha_mode alpha_mode = opaque, + uniform float base_alpha = 1.0, + uniform float alpha_cutoff = 0.5 +) [[ anno::hidden() ]] = let { + auto base_color = compute_base_color(imagery_layers_texture, debug_color, base_color_texture, base_color_factor, base_alpha); + material base = gltf_material( + base_color_texture: gltf_texture_lookup_value(true, base_color), + metallic_factor: metallic_factor, + roughness_factor: roughness_factor, + emissive_factor: emissive_factor, + alpha_mode: alpha_mode, + alpha_cutoff: alpha_cutoff ); - float3 final = float3(1.0, 1.0, 1.0); +} in material( + thin_walled: base.thin_walled, + surface: base.surface, + volume: base.volume, + ior: base.ior, + geometry: base.geometry +); + +export gltf_texture_lookup_value cesium_internal_imagery_layer_resolver( + uniform int imagery_layers_count = 0, + gltf_texture_lookup_value imagery_layer_0 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_1 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_2 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_3 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_4 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_5 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_6 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_7 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_8 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_9 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_10 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_11 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_12 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_13 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_14 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_15 = gltf_texture_lookup() +) [[ anno::hidden() ]] { + // The array length should match MAX_IMAGERY_LAYERS_COUNT in Tokens.h + gltf_texture_lookup_value[16] imagery_layers( + imagery_layer_0, + imagery_layer_1, + imagery_layer_2, + imagery_layer_3, + imagery_layer_4, + imagery_layer_5, + imagery_layer_6, + imagery_layer_7, + imagery_layer_8, + imagery_layer_9, + imagery_layer_10, + imagery_layer_11, + imagery_layer_12, + imagery_layer_13, + imagery_layer_14, + imagery_layer_15, + ); - for (int i = 0; i < texture_count; i++) { - gltf_texture_lookup_value value = texture_values[i]; - if (value.valid) { - float3 rgb = float3(value.value[0], value.value[1], value.value[2]); - float alpha = value.value[3]; - final = alpha * rgb + (1.0 - alpha) * final; + auto resolved_value = float4(0.0); + + for (int i = 0; i < imagery_layers_count; i++) { + auto imagery_layer = imagery_layers[i]; + if (imagery_layer.valid) { + resolved_value = alpha_blend(imagery_layer.value, resolved_value); } } - gltf_texture_lookup_value tex_ret; - tex_ret.value = float4(final[0], final[1], final[2], 1.0); - tex_ret.valid = true; - - return tex_ret; + return gltf_texture_lookup_value(true, resolved_value); } diff --git a/src/core/include/cesium/omniverse/FabricGeometry.h b/src/core/include/cesium/omniverse/FabricGeometry.h index cf572d14b..22422e6c5 100644 --- a/src/core/include/cesium/omniverse/FabricGeometry.h +++ b/src/core/include/cesium/omniverse/FabricGeometry.h @@ -15,11 +15,7 @@ namespace cesium::omniverse { class FabricGeometry { public: - FabricGeometry( - const omni::fabric::Path& path, - const FabricGeometryDefinition& geometryDefinition, - bool debugRandomColors, - long stageId); + FabricGeometry(const omni::fabric::Path& path, const FabricGeometryDefinition& geometryDefinition, long stageId); ~FabricGeometry(); void setGeometry( @@ -48,7 +44,6 @@ class FabricGeometry { const omni::fabric::Path _path; const FabricGeometryDefinition _geometryDefinition; - const bool _debugRandomColors; const long _stageId; }; diff --git a/src/core/include/cesium/omniverse/FabricGeometryPool.h b/src/core/include/cesium/omniverse/FabricGeometryPool.h index baf4cb075..a710c4b73 100644 --- a/src/core/include/cesium/omniverse/FabricGeometryPool.h +++ b/src/core/include/cesium/omniverse/FabricGeometryPool.h @@ -12,7 +12,6 @@ class FabricGeometryPool final : public ObjectPool { int64_t poolId, const FabricGeometryDefinition& geometryDefinition, uint64_t initialCapacity, - bool debugRandomColors, long stageId); [[nodiscard]] const FabricGeometryDefinition& getGeometryDefinition() const; @@ -24,7 +23,6 @@ class FabricGeometryPool final : public ObjectPool { private: const int64_t _poolId; const FabricGeometryDefinition _geometryDefinition; - const bool _debugRandomColors; const long _stageId; }; diff --git a/src/core/include/cesium/omniverse/FabricMaterial.h b/src/core/include/cesium/omniverse/FabricMaterial.h index 3a0d94ab2..e83e71b99 100644 --- a/src/core/include/cesium/omniverse/FabricMaterial.h +++ b/src/core/include/cesium/omniverse/FabricMaterial.h @@ -21,18 +21,25 @@ class FabricMaterial { const FabricMaterialDefinition& materialDefinition, const pxr::TfToken& defaultTextureAssetPathToken, const pxr::TfToken& defaultTransparentTextureAssetPathToken, + bool debugRandomColors, long stageId); ~FabricMaterial(); void setMaterial(int64_t tilesetId, const MaterialInfo& materialInfo); void setBaseColorTexture( + const pxr::TfToken& textureAssetPathToken, + const TextureInfo& textureInfo, + uint64_t texcoordIndex); + void setImageryLayer( const pxr::TfToken& textureAssetPathToken, const TextureInfo& textureInfo, uint64_t texcoordIndex, - uint64_t textureIndex); + uint64_t imageryLayerIndex); void clearMaterial(); - void clearBaseColorTexture(uint64_t textureIndex); + void clearBaseColorTexture(); + void clearImageryLayer(uint64_t imageryLayerIndex); + void clearImageryLayers(); void setActive(bool active); @@ -41,6 +48,7 @@ class FabricMaterial { private: void initialize(); + void initializeFromExistingMaterial(const omni::fabric::Path& path); void createMaterial(const omni::fabric::Path& materialPath); void createShader(const omni::fabric::Path& shaderPath, const omni::fabric::Path& materialPath); @@ -48,8 +56,8 @@ class FabricMaterial { const omni::fabric::Path& texturePath, const omni::fabric::Path& shaderPath, const omni::fabric::Token& shaderInput); - void createTextureArray( - const omni::fabric::Path& texturePath, + void createImageryLayerResolver( + const omni::fabric::Path& imageryLayerResolverPath, const omni::fabric::Path& shaderPath, const omni::fabric::Token& shaderInput, uint64_t textureCount); @@ -60,19 +68,20 @@ class FabricMaterial { const pxr::TfToken& textureAssetPathToken, const TextureInfo& textureInfo, uint64_t texcoordIndex); - void setTilesetId(int64_t tilesetId); bool stageDestroyed(); - void clearBaseColorTextures(); omni::fabric::Path _materialPath; const FabricMaterialDefinition _materialDefinition; const pxr::TfToken _defaultTextureAssetPathToken; const pxr::TfToken _defaultTransparentTextureAssetPathToken; + const bool _debugRandomColors; const long _stageId; - omni::fabric::Path _shaderPath; - omni::fabric::Path _baseColorTexturePath; - std::vector _baseColorTextureLayerPaths; + std::vector _shaderPaths; + std::vector _baseColorTexturePaths; + std::vector> _imageryLayerPaths; + + std::vector _allPaths; }; } // namespace cesium::omniverse diff --git a/src/core/include/cesium/omniverse/FabricMaterialDefinition.h b/src/core/include/cesium/omniverse/FabricMaterialDefinition.h index 1c5758c45..e2f17ad9a 100644 --- a/src/core/include/cesium/omniverse/FabricMaterialDefinition.h +++ b/src/core/include/cesium/omniverse/FabricMaterialDefinition.h @@ -3,6 +3,7 @@ #include #include #include +#include namespace cesium::omniverse { @@ -10,18 +11,26 @@ struct MaterialInfo; class FabricMaterialDefinition { public: - FabricMaterialDefinition(const MaterialInfo& materialInfo, uint64_t imageryLayerCount, bool disableTextures); + FabricMaterialDefinition( + const MaterialInfo& materialInfo, + uint64_t imageryLayerCount, + bool disableTextures, + const pxr::SdfPath& tilesetMaterialPath); [[nodiscard]] bool hasVertexColors() const; - [[nodiscard]] uint64_t getBaseColorTextureCount() const; - [[nodiscard]] bool hasBaseColorTextures() const; + [[nodiscard]] bool hasBaseColorTexture() const; + [[nodiscard]] uint64_t getImageryLayerCount() const; + [[nodiscard]] bool hasTilesetMaterial() const; + [[nodiscard]] const pxr::SdfPath& getTilesetMaterialPath() const; // Make sure to update this function when adding new fields to the class bool operator==(const FabricMaterialDefinition& other) const; private: bool _hasVertexColors; - uint64_t _baseColorTextureCount; + bool _hasBaseColorTexture; + uint64_t _imageryLayerCount; + pxr::SdfPath _tilesetMaterialPath; }; } // namespace cesium::omniverse diff --git a/src/core/include/cesium/omniverse/FabricMaterialPool.h b/src/core/include/cesium/omniverse/FabricMaterialPool.h index a93c25a6b..a324d3109 100644 --- a/src/core/include/cesium/omniverse/FabricMaterialPool.h +++ b/src/core/include/cesium/omniverse/FabricMaterialPool.h @@ -16,6 +16,7 @@ class FabricMaterialPool final : public ObjectPool { uint64_t initialCapacity, const pxr::TfToken& defaultTextureAssetPathToken, const pxr::TfToken& defaultTransparentTextureAssetPathToken, + bool debugRandomColors, long stageId); [[nodiscard]] const FabricMaterialDefinition& getMaterialDefinition() const; @@ -29,6 +30,7 @@ class FabricMaterialPool final : public ObjectPool { const FabricMaterialDefinition _materialDefinition; const pxr::TfToken _defaultTextureAssetPathToken; const pxr::TfToken _defaultTransparentTextureAssetPathToken; + const bool _debugRandomColors; const long _stageId; }; diff --git a/src/core/include/cesium/omniverse/FabricResourceManager.h b/src/core/include/cesium/omniverse/FabricResourceManager.h index fa405963c..6596a8d62 100644 --- a/src/core/include/cesium/omniverse/FabricResourceManager.h +++ b/src/core/include/cesium/omniverse/FabricResourceManager.h @@ -61,8 +61,12 @@ class FabricResourceManager { bool smoothNormals, long stageId); - std::shared_ptr - acquireMaterial(const MaterialInfo& materialInfo, uint64_t imageryLayerCount, long stageId, int64_t tilesetId); + std::shared_ptr acquireMaterial( + const MaterialInfo& materialInfo, + uint64_t imageryLayerCount, + long stageId, + int64_t tilesetId, + const pxr::SdfPath& tilesetMaterialPath); std::shared_ptr acquireTexture(); diff --git a/src/core/include/cesium/omniverse/FabricUtil.h b/src/core/include/cesium/omniverse/FabricUtil.h index a958d9c30..0f8eb9112 100644 --- a/src/core/include/cesium/omniverse/FabricUtil.h +++ b/src/core/include/cesium/omniverse/FabricUtil.h @@ -34,5 +34,10 @@ void setTilesetTransform(int64_t tilesetId, const glm::dmat4& ecefToUsdTransform void setTilesetId(const omni::fabric::Path& path, int64_t tilesetId); omni::fabric::Path toFabricPath(const pxr::SdfPath& path); omni::fabric::Path joinPaths(const omni::fabric::Path& absolutePath, const omni::fabric::Token& relativePath); +std::vector +copyMaterial(const omni::fabric::Path& srcMaterialPath, const omni::fabric::Path& dstMaterialPath); +bool materialHasCesiumNodes(const omni::fabric::Path& path); +bool isCesiumNode(const omni::fabric::Token& mdlIdentifier); +omni::fabric::Token getMdlIdentifier(const omni::fabric::Path& path); } // namespace cesium::omniverse::FabricUtil diff --git a/src/core/include/cesium/omniverse/OmniTileset.h b/src/core/include/cesium/omniverse/OmniTileset.h index c3e0bcac3..8ba34fa53 100644 --- a/src/core/include/cesium/omniverse/OmniTileset.h +++ b/src/core/include/cesium/omniverse/OmniTileset.h @@ -73,7 +73,8 @@ class OmniTileset { void reload(); void addImageryIon(const pxr::SdfPath& imageryPath); - [[nodiscard]] std::optional findImageryIndex(const Cesium3DTilesSelection::RasterOverlay& overlay) const; + [[nodiscard]] std::optional + findImageryLayerIndex(const Cesium3DTilesSelection::RasterOverlay& overlay) const; [[nodiscard]] uint64_t getImageryLayerCount() const; void onUpdateFrame(const std::vector& viewports); diff --git a/src/core/include/cesium/omniverse/Tokens.h b/src/core/include/cesium/omniverse/Tokens.h index 28fabbb90..b849b614e 100644 --- a/src/core/include/cesium/omniverse/Tokens.h +++ b/src/core/include/cesium/omniverse/Tokens.h @@ -14,32 +14,35 @@ __pragma(warning(push)) __pragma(warning(disable : 4003)) #define USD_TOKENS \ (base_color_texture) \ - (base_color_texture_0) \ - (base_color_texture_1) \ - (base_color_texture_2) \ - (base_color_texture_3) \ - (base_color_texture_4) \ - (base_color_texture_5) \ - (base_color_texture_6) \ - (base_color_texture_7) \ - (base_color_texture_8) \ - (base_color_texture_9) \ - (base_color_texture_10) \ - (base_color_texture_11) \ - (base_color_texture_12) \ - (base_color_texture_13) \ - (base_color_texture_14) \ - (base_color_texture_15) \ - (base_color_texture_array) \ (cesium) \ - (cesium_material) \ - (cesium_texture_array_lookup) \ - (cesium_texture_lookup) \ + (cesium_base_color_texture_float4) \ + (cesium_imagery_layer_float4) \ + (cesium_internal_imagery_layer_resolver) \ + (cesium_internal_material) \ + (cesium_internal_texture_lookup) \ (constant) \ (doubleSided) \ (extent) \ (faceVertexCounts) \ (faceVertexIndices) \ + (imagery_layer) \ + (imagery_layer_0) \ + (imagery_layer_1) \ + (imagery_layer_2) \ + (imagery_layer_3) \ + (imagery_layer_4) \ + (imagery_layer_5) \ + (imagery_layer_6) \ + (imagery_layer_7) \ + (imagery_layer_8) \ + (imagery_layer_9) \ + (imagery_layer_10) \ + (imagery_layer_11) \ + (imagery_layer_12) \ + (imagery_layer_13) \ + (imagery_layer_14) \ + (imagery_layer_15) \ + (imagery_layer_resolver) \ (Material) \ (Mesh) \ (none) \ @@ -50,7 +53,6 @@ __pragma(warning(push)) __pragma(warning(disable : 4003)) (sourceAsset) \ (subdivisionScheme) \ (vertex) \ - (vertexColor) \ (_cesium_localToEcefTransform) \ (_cesium_tilesetId) \ (_deletedPrims) \ @@ -70,6 +72,7 @@ __pragma(warning(push)) __pragma(warning(disable : 4003)) ((inputs_base_alpha, "inputs:base_alpha")) \ ((inputs_base_color_factor, "inputs:base_color_factor")) \ ((inputs_base_color_texture, "inputs:base_color_texture")) \ + ((inputs_debug_color, "inputs:debug_color")) \ ((inputs_emissive_factor, "inputs:emissive_factor")) \ ((inputs_excludeFromWhiteMode, "inputs:excludeFromWhiteMode")) \ ((inputs_metallic_factor, "inputs:metallic_factor")) \ @@ -79,23 +82,26 @@ __pragma(warning(push)) __pragma(warning(disable : 4003)) ((inputs_scale, "inputs:scale")) \ ((inputs_tex_coord_index, "inputs:tex_coord_index")) \ ((inputs_texture, "inputs:texture")) \ - ((inputs_texture_0, "inputs:texture_0")) \ - ((inputs_texture_1, "inputs:texture_1")) \ - ((inputs_texture_2, "inputs:texture_2")) \ - ((inputs_texture_3, "inputs:texture_3")) \ - ((inputs_texture_4, "inputs:texture_4")) \ - ((inputs_texture_5, "inputs:texture_5")) \ - ((inputs_texture_6, "inputs:texture_6")) \ - ((inputs_texture_7, "inputs:texture_7")) \ - ((inputs_texture_8, "inputs:texture_8")) \ - ((inputs_texture_9, "inputs:texture_9")) \ - ((inputs_texture_10, "inputs:texture_10")) \ - ((inputs_texture_11, "inputs:texture_11")) \ - ((inputs_texture_12, "inputs:texture_12")) \ - ((inputs_texture_13, "inputs:texture_13")) \ - ((inputs_texture_14, "inputs:texture_14")) \ - ((inputs_texture_15, "inputs:texture_15")) \ - ((inputs_texture_count, "inputs:texture_count")) \ + ((inputs_imagery_layer, "inputs:imagery_layer")) \ + ((inputs_imagery_layer_0, "inputs:imagery_layer_0")) \ + ((inputs_imagery_layer_1, "inputs:imagery_layer_1")) \ + ((inputs_imagery_layer_2, "inputs:imagery_layer_2")) \ + ((inputs_imagery_layer_3, "inputs:imagery_layer_3")) \ + ((inputs_imagery_layer_4, "inputs:imagery_layer_4")) \ + ((inputs_imagery_layer_5, "inputs:imagery_layer_5")) \ + ((inputs_imagery_layer_6, "inputs:imagery_layer_6")) \ + ((inputs_imagery_layer_7, "inputs:imagery_layer_7")) \ + ((inputs_imagery_layer_8, "inputs:imagery_layer_8")) \ + ((inputs_imagery_layer_9, "inputs:imagery_layer_9")) \ + ((inputs_imagery_layer_10, "inputs:imagery_layer_10")) \ + ((inputs_imagery_layer_11, "inputs:imagery_layer_11")) \ + ((inputs_imagery_layer_12, "inputs:imagery_layer_12")) \ + ((inputs_imagery_layer_13, "inputs:imagery_layer_13")) \ + ((inputs_imagery_layer_14, "inputs:imagery_layer_14")) \ + ((inputs_imagery_layer_15, "inputs:imagery_layer_15")) \ + ((inputs_imagery_layers_count, "inputs:imagery_layers_count")) \ + ((inputs_imagery_layer_index, "inputs:imagery_layer_index")) \ + ((inputs_imagery_layers_texture, "inputs:imagery_layers_texture")) \ ((inputs_vertex_color_name, "inputs:vertex_color_name")) \ ((inputs_wrap_s, "inputs:wrap_s")) \ ((inputs_wrap_t, "inputs:wrap_t")) \ @@ -105,7 +111,6 @@ __pragma(warning(push)) __pragma(warning(disable : 4003)) ((outputs_mdl_volume, "outputs:mdl:volume")) \ ((outputs_out, "outputs:out")) \ ((primvars_displayColor, "primvars:displayColor")) \ - ((primvars_displayOpacity, "primvars:displayOpacity")) \ ((primvars_normals, "primvars:normals")) \ ((primvars_st_0, "primvars:st_0")) \ ((primvars_st_1, "primvars:st_1")) \ @@ -117,7 +122,6 @@ __pragma(warning(push)) __pragma(warning(disable : 4003)) ((primvars_st_7, "primvars:st_7")) \ ((primvars_st_8, "primvars:st_8")) \ ((primvars_st_9, "primvars:st_9")) \ - ((primvars_vertexColor, "primvars:vertexColor")) \ ((xformOp_transform_cesium, "xformOp:transform:cesium")) TF_DECLARE_PUBLIC_TOKENS(UsdTokens, USD_TOKENS); @@ -150,7 +154,7 @@ namespace cesium::omniverse::FabricTokens { FABRIC_DECLARE_TOKENS(USD_TOKENS); const uint64_t MAX_PRIMVAR_ST_COUNT = 10; -const uint64_t MAX_TEXTURE_LAYER_COUNT = 16; +const uint64_t MAX_IMAGERY_LAYERS_COUNT = 16; const std::array primvars_st_n = {{ primvars_st_0, @@ -165,42 +169,42 @@ const std::array primvars_st_n primvars_st_9, }}; -const std::array base_color_texture_n = {{ - base_color_texture_0, - base_color_texture_1, - base_color_texture_2, - base_color_texture_3, - base_color_texture_4, - base_color_texture_5, - base_color_texture_6, - base_color_texture_7, - base_color_texture_8, - base_color_texture_9, - base_color_texture_10, - base_color_texture_11, - base_color_texture_12, - base_color_texture_13, - base_color_texture_14, - base_color_texture_15, +const std::array imagery_layer_n = {{ + imagery_layer_0, + imagery_layer_1, + imagery_layer_2, + imagery_layer_3, + imagery_layer_4, + imagery_layer_5, + imagery_layer_6, + imagery_layer_7, + imagery_layer_8, + imagery_layer_9, + imagery_layer_10, + imagery_layer_11, + imagery_layer_12, + imagery_layer_13, + imagery_layer_14, + imagery_layer_15, }}; -const std::array inputs_texture_n = {{ - inputs_texture_0, - inputs_texture_1, - inputs_texture_2, - inputs_texture_3, - inputs_texture_4, - inputs_texture_5, - inputs_texture_6, - inputs_texture_7, - inputs_texture_8, - inputs_texture_9, - inputs_texture_10, - inputs_texture_11, - inputs_texture_12, - inputs_texture_13, - inputs_texture_14, - inputs_texture_15, +const std::array inputs_imagery_layer_n = {{ + inputs_imagery_layer_0, + inputs_imagery_layer_1, + inputs_imagery_layer_2, + inputs_imagery_layer_3, + inputs_imagery_layer_4, + inputs_imagery_layer_5, + inputs_imagery_layer_6, + inputs_imagery_layer_7, + inputs_imagery_layer_8, + inputs_imagery_layer_9, + inputs_imagery_layer_10, + inputs_imagery_layer_11, + inputs_imagery_layer_12, + inputs_imagery_layer_13, + inputs_imagery_layer_14, + inputs_imagery_layer_15, }}; } @@ -218,6 +222,7 @@ const omni::fabric::Type inputs_alpha_cutoff(omni::fabric::BaseDataType::eFloat, const omni::fabric::Type inputs_alpha_mode(omni::fabric::BaseDataType::eInt, 1, 0, omni::fabric::AttributeRole::eNone); const omni::fabric::Type inputs_base_alpha(omni::fabric::BaseDataType::eFloat, 1, 0, omni::fabric::AttributeRole::eNone); const omni::fabric::Type inputs_base_color_factor(omni::fabric::BaseDataType::eFloat, 3, 0, omni::fabric::AttributeRole::eColor); +const omni::fabric::Type inputs_debug_color(omni::fabric::BaseDataType::eFloat, 3, 0, omni::fabric::AttributeRole::eColor); const omni::fabric::Type inputs_emissive_factor(omni::fabric::BaseDataType::eFloat, 3, 0, omni::fabric::AttributeRole::eColor); const omni::fabric::Type inputs_excludeFromWhiteMode(omni::fabric::BaseDataType::eBool, 1, 0, omni::fabric::AttributeRole::eNone); const omni::fabric::Type inputs_metallic_factor(omni::fabric::BaseDataType::eFloat, 1, 0, omni::fabric::AttributeRole::eNone); @@ -227,7 +232,7 @@ const omni::fabric::Type inputs_roughness_factor(omni::fabric::BaseDataType::eFl const omni::fabric::Type inputs_scale(omni::fabric::BaseDataType::eFloat, 2, 0, omni::fabric::AttributeRole::eNone); const omni::fabric::Type inputs_tex_coord_index(omni::fabric::BaseDataType::eInt, 1, 0, omni::fabric::AttributeRole::eNone); const omni::fabric::Type inputs_texture(omni::fabric::BaseDataType::eAsset, 1, 0, omni::fabric::AttributeRole::eNone); -const omni::fabric::Type inputs_texture_count(omni::fabric::BaseDataType::eInt, 1, 0, omni::fabric::AttributeRole::eNone); +const omni::fabric::Type inputs_imagery_layers_count(omni::fabric::BaseDataType::eInt, 1, 0, omni::fabric::AttributeRole::eNone); const omni::fabric::Type inputs_vertex_color_name(omni::fabric::BaseDataType::eUChar, 1, 1, omni::fabric::AttributeRole::eText); const omni::fabric::Type inputs_wrap_s(omni::fabric::BaseDataType::eInt, 1, 0, omni::fabric::AttributeRole::eNone); const omni::fabric::Type inputs_wrap_t(omni::fabric::BaseDataType::eInt, 1, 0, omni::fabric::AttributeRole::eNone); @@ -239,10 +244,8 @@ const omni::fabric::Type points(omni::fabric::BaseDataType::eFloat, 3, 1, omni:: const omni::fabric::Type primvarInterpolations(omni::fabric::BaseDataType::eToken, 1, 1, omni::fabric::AttributeRole::eNone); const omni::fabric::Type primvars(omni::fabric::BaseDataType::eToken, 1, 1, omni::fabric::AttributeRole::eNone); const omni::fabric::Type primvars_displayColor(omni::fabric::BaseDataType::eFloat, 3, 1, omni::fabric::AttributeRole::eColor); -const omni::fabric::Type primvars_displayOpacity(omni::fabric::BaseDataType::eFloat, 1, 1, omni::fabric::AttributeRole::eNone); const omni::fabric::Type primvars_normals(omni::fabric::BaseDataType::eFloat, 3, 1, omni::fabric::AttributeRole::eNormal); const omni::fabric::Type primvars_st(omni::fabric::BaseDataType::eFloat, 2, 1, omni::fabric::AttributeRole::eTexCoord); -const omni::fabric::Type primvars_vertexColor(omni::fabric::BaseDataType::eFloat, 3, 1, omni::fabric::AttributeRole::eColor); const omni::fabric::Type Shader(omni::fabric::BaseDataType::eTag, 1, 0, omni::fabric::AttributeRole::ePrimTypeName); const omni::fabric::Type subdivisionScheme(omni::fabric::BaseDataType::eToken, 1, 0, omni::fabric::AttributeRole::eNone); const omni::fabric::Type _cesium_localToEcefTransform(omni::fabric::BaseDataType::eDouble, 16, 0, omni::fabric::AttributeRole::eMatrix); diff --git a/src/core/src/FabricGeometry.cpp b/src/core/src/FabricGeometry.cpp index f22a8eb6e..5238a1258 100644 --- a/src/core/src/FabricGeometry.cpp +++ b/src/core/src/FabricGeometry.cpp @@ -17,7 +17,6 @@ #endif #include -#include #include namespace cesium::omniverse { @@ -54,11 +53,9 @@ uint64_t getTexcoordSetCount(const FabricGeometryDefinition& geometryDefinition) FabricGeometry::FabricGeometry( const omni::fabric::Path& path, const FabricGeometryDefinition& geometryDefinition, - bool debugRandomColors, long stageId) : _path(path) , _geometryDefinition(geometryDefinition) - , _debugRandomColors(debugRandomColors) , _stageId(stageId) { if (stageDestroyed()) { return; @@ -137,8 +134,6 @@ void FabricGeometry::initialize() { attributes.addAttribute(FabricTypes::_worldVisibility, FabricTokens::_worldVisibility); attributes.addAttribute(FabricTypes::primvars, FabricTokens::primvars); attributes.addAttribute(FabricTypes::primvarInterpolations, FabricTokens::primvarInterpolations); - attributes.addAttribute(FabricTypes::primvars_displayColor, FabricTokens::primvars_displayColor); - attributes.addAttribute(FabricTypes::primvars_displayOpacity, FabricTokens::primvars_displayOpacity); attributes.addAttribute(FabricTypes::Mesh, FabricTokens::Mesh); attributes.addAttribute(FabricTypes::_cesium_tilesetId, FabricTokens::_cesium_tilesetId); attributes.addAttribute(FabricTypes::_cesium_localToEcefTransform, FabricTokens::_cesium_localToEcefTransform); @@ -158,7 +153,7 @@ void FabricGeometry::initialize() { } if (hasVertexColors) { - attributes.addAttribute(FabricTypes::primvars_vertexColor, FabricTokens::primvars_vertexColor); + attributes.addAttribute(FabricTypes::primvars_displayColor, FabricTokens::primvars_displayColor); } attributes.createAttributes(_path); @@ -176,9 +171,6 @@ void FabricGeometry::initialize() { size_t primvarIndexNormal = 0; size_t primvarIndexVertexColor = 0; - const size_t primvarIndexDisplayColor = primvarsCount++; - const size_t primvarIndexDisplayOpacity = primvarsCount++; - std::vector primvarIndexStArray; primvarIndexStArray.reserve(texcoordSetCount); @@ -196,20 +188,12 @@ void FabricGeometry::initialize() { srw.setArrayAttributeSize(_path, FabricTokens::primvars, primvarsCount); srw.setArrayAttributeSize(_path, FabricTokens::primvarInterpolations, primvarsCount); - srw.setArrayAttributeSize(_path, FabricTokens::primvars_displayColor, 1); - srw.setArrayAttributeSize(_path, FabricTokens::primvars_displayOpacity, 1); // clang-format off auto primvarsFabric = srw.getArrayAttributeWr(_path, FabricTokens::primvars); auto primvarInterpolationsFabric = srw.getArrayAttributeWr(_path, FabricTokens::primvarInterpolations); // clang-format on - primvarsFabric[primvarIndexDisplayColor] = FabricTokens::primvars_displayColor; - primvarsFabric[primvarIndexDisplayOpacity] = FabricTokens::primvars_displayOpacity; - - primvarInterpolationsFabric[primvarIndexDisplayColor] = FabricTokens::constant; - primvarInterpolationsFabric[primvarIndexDisplayOpacity] = FabricTokens::constant; - for (uint64_t i = 0; i < texcoordSetCount; i++) { primvarsFabric[primvarIndexStArray[i]] = FabricTokens::primvars_st_n[i]; primvarInterpolationsFabric[primvarIndexStArray[i]] = FabricTokens::vertex; @@ -221,7 +205,7 @@ void FabricGeometry::initialize() { } if (hasVertexColors) { - primvarsFabric[primvarIndexVertexColor] = FabricTokens::primvars_vertexColor; + primvarsFabric[primvarIndexVertexColor] = FabricTokens::primvars_displayColor; primvarInterpolationsFabric[primvarIndexVertexColor] = FabricTokens::vertex; } } @@ -241,8 +225,6 @@ void FabricGeometry::reset() { auto worldPositionFabric = srw.getAttributeWr(_path, FabricTokens::_worldPosition); auto worldOrientationFabric = srw.getAttributeWr(_path, FabricTokens::_worldOrientation); auto worldScaleFabric = srw.getAttributeWr(_path, FabricTokens::_worldScale); - auto displayColorFabric = srw.getArrayAttributeWr(_path, FabricTokens::primvars_displayColor); - auto displayOpacityFabric = srw.getArrayAttributeWr(_path, FabricTokens::primvars_displayOpacity); // clang-format on *extentFabric = DEFAULT_EXTENT; @@ -252,8 +234,6 @@ void FabricGeometry::reset() { *worldPositionFabric = DEFAULT_POSITION; *worldOrientationFabric = DEFAULT_ORIENTATION; *worldScaleFabric = DEFAULT_SCALE; - displayColorFabric[0] = DEFAULT_VERTEX_COLOR; - displayOpacityFabric[0] = DEFAULT_VERTEX_OPACITY; FabricUtil::setTilesetId(_path, NO_TILESET_ID); @@ -271,7 +251,7 @@ void FabricGeometry::reset() { } if (hasVertexColors) { - srw.setArrayAttributeSize(_path, FabricTokens::primvars_vertexColor, 0); + srw.setArrayAttributeSize(_path, FabricTokens::primvars_displayColor, 0); } } @@ -327,9 +307,9 @@ void FabricGeometry::setGeometry( gsl::span vertexColorsSpan(vertexColorsData); if (hasVertexColors) { vertexColors.fill(vertexColorsSpan); - srw.setArrayAttributeSize(_path, FabricTokens::primvars_vertexColor, numVoxels * 8); + srw.setArrayAttributeSize(_path, FabricTokens::primvars_displayColor, numVoxels * 8); } - auto vertexColorsFabric = srw.getArrayAttributeWr(_path, FabricTokens::primvars_vertexColor); + auto vertexColorsFabric = srw.getArrayAttributeWr(_path, FabricTokens::primvars_displayColor); size_t vertIndex = 0; size_t vertexCountsIndex = 0; @@ -447,9 +427,9 @@ void FabricGeometry::setGeometry( } if (hasVertexColors) { - srw.setArrayAttributeSize(_path, FabricTokens::primvars_vertexColor, vertexColors.size()); + srw.setArrayAttributeSize(_path, FabricTokens::primvars_displayColor, vertexColors.size()); - auto vertexColorsFabric = srw.getArrayAttributeWr(_path, FabricTokens::primvars_vertexColor); + auto vertexColorsFabric = srw.getArrayAttributeWr(_path, FabricTokens::primvars_displayColor); vertexColors.fill(vertexColorsFabric); } @@ -462,8 +442,6 @@ void FabricGeometry::setGeometry( auto worldPositionFabric = srw.getAttributeWr(_path, FabricTokens::_worldPosition); auto worldOrientationFabric = srw.getAttributeWr(_path, FabricTokens::_worldOrientation); auto worldScaleFabric = srw.getAttributeWr(_path, FabricTokens::_worldScale); - auto displayColorFabric = srw.getArrayAttributeWr(_path, FabricTokens::primvars_displayColor); - auto displayOpacityFabric = srw.getArrayAttributeWr(_path, FabricTokens::primvars_displayOpacity); // clang-format on *extentFabric = localExtent; @@ -473,17 +451,6 @@ void FabricGeometry::setGeometry( *worldOrientationFabric = worldOrientation; *worldScaleFabric = worldScale; - if (_debugRandomColors) { - const auto r = glm::linearRand(0.0f, 1.0f); - const auto g = glm::linearRand(0.0f, 1.0f); - const auto b = glm::linearRand(0.0f, 1.0f); - displayColorFabric[0] = pxr::GfVec3f(r, g, b); - } else { - displayColorFabric[0] = DEFAULT_VERTEX_COLOR; - } - - displayOpacityFabric[0] = DEFAULT_VERTEX_OPACITY; - FabricUtil::setTilesetId(_path, tilesetId); } diff --git a/src/core/src/FabricGeometryPool.cpp b/src/core/src/FabricGeometryPool.cpp index eed6d7aea..4514620b9 100644 --- a/src/core/src/FabricGeometryPool.cpp +++ b/src/core/src/FabricGeometryPool.cpp @@ -8,12 +8,10 @@ FabricGeometryPool::FabricGeometryPool( int64_t poolId, const FabricGeometryDefinition& geometryDefinition, uint64_t initialCapacity, - bool debugRandomColors, long stageId) : ObjectPool() , _poolId(poolId) , _geometryDefinition(geometryDefinition) - , _debugRandomColors(debugRandomColors) , _stageId(stageId) { setCapacity(initialCapacity); } @@ -25,7 +23,7 @@ const FabricGeometryDefinition& FabricGeometryPool::getGeometryDefinition() cons std::shared_ptr FabricGeometryPool::createObject(uint64_t objectId) { const auto pathStr = fmt::format("/fabric_geometry_pool_{}_object_{}", _poolId, objectId); const auto path = omni::fabric::Path(pathStr.c_str()); - return std::make_shared(path, _geometryDefinition, _debugRandomColors, _stageId); + return std::make_shared(path, _geometryDefinition, _stageId); } void FabricGeometryPool::setActive(std::shared_ptr geometry, bool active) { diff --git a/src/core/src/FabricMaterial.cpp b/src/core/src/FabricMaterial.cpp index 2bb99df4e..9f19c1a84 100644 --- a/src/core/src/FabricMaterial.cpp +++ b/src/core/src/FabricMaterial.cpp @@ -5,30 +5,37 @@ #include "cesium/omniverse/FabricMaterialDefinition.h" #include "cesium/omniverse/FabricResourceManager.h" #include "cesium/omniverse/FabricUtil.h" +#include "cesium/omniverse/GltfUtil.h" #include "cesium/omniverse/LoggerSink.h" #include "cesium/omniverse/Tokens.h" #include "cesium/omniverse/UsdUtil.h" +#include #include #include namespace cesium::omniverse { namespace { -uint64_t getBaseColorTextureCount(const FabricMaterialDefinition& materialDefinition) { - auto baseColorTextureCount = materialDefinition.getBaseColorTextureCount(); - if (baseColorTextureCount > FabricTokens::MAX_TEXTURE_LAYER_COUNT) { +const auto DEFAULT_DEBUG_COLOR = pxr::GfVec3f(1.0f, 1.0f, 1.0f); + +uint64_t getImageryLayerCount(const FabricMaterialDefinition& materialDefinition) { + uint64_t imageryLayerCount = materialDefinition.getImageryLayerCount(); + + if (imageryLayerCount > FabricTokens::MAX_IMAGERY_LAYERS_COUNT) { CESIUM_LOG_WARN( - "Number of textures ({}) exceeds maximum texture layer count ({}). Excess textures will be ignored.", - baseColorTextureCount, - FabricTokens::MAX_TEXTURE_LAYER_COUNT); + "Number of imagery layers ({}) exceeds maximum imagery layer count ({}). Excess imagery layers will be " + "ignored.", + imageryLayerCount, + FabricTokens::MAX_IMAGERY_LAYERS_COUNT); } - baseColorTextureCount = glm::min(baseColorTextureCount, FabricTokens::MAX_TEXTURE_LAYER_COUNT); + imageryLayerCount = glm::min(imageryLayerCount, FabricTokens::MAX_IMAGERY_LAYERS_COUNT); - return baseColorTextureCount; + return imageryLayerCount; } + } // namespace FabricMaterial::FabricMaterial( @@ -36,18 +43,26 @@ FabricMaterial::FabricMaterial( const FabricMaterialDefinition& materialDefinition, const pxr::TfToken& defaultTextureAssetPathToken, const pxr::TfToken& defaultTransparentTextureAssetPathToken, + bool debugRandomColors, long stageId) : _materialPath(path) , _materialDefinition(materialDefinition) , _defaultTextureAssetPathToken(defaultTextureAssetPathToken) , _defaultTransparentTextureAssetPathToken(defaultTransparentTextureAssetPathToken) + , _debugRandomColors(debugRandomColors) , _stageId(stageId) { if (stageDestroyed()) { return; } - initialize(); + if (materialDefinition.hasTilesetMaterial()) { + const auto tilesetMaterialPath = FabricUtil::toFabricPath(materialDefinition.getTilesetMaterialPath()); + initializeFromExistingMaterial(tilesetMaterialPath); + } else { + initialize(); + } + reset(); } @@ -56,15 +71,8 @@ FabricMaterial::~FabricMaterial() { return; } - FabricUtil::destroyPrim(_materialPath); - FabricUtil::destroyPrim(_shaderPath); - - if (_materialDefinition.hasBaseColorTextures()) { - FabricUtil::destroyPrim(_baseColorTexturePath); - - for (const auto& baseColorTextureLayerPath : _baseColorTextureLayerPaths) { - FabricUtil::destroyPrim(baseColorTextureLayerPath); - } + for (const auto& path : _allPaths) { + FabricUtil::destroyPrim(path); } } @@ -89,38 +97,91 @@ const FabricMaterialDefinition& FabricMaterial::getMaterialDefinition() const { void FabricMaterial::initialize() { const auto& materialPath = _materialPath; createMaterial(materialPath); - auto& fabricResourceManager = FabricResourceManager::getInstance(); - fabricResourceManager.retainPath(materialPath); + _allPaths.push_back(materialPath); const auto shaderPath = FabricUtil::joinPaths(materialPath, FabricTokens::Shader); createShader(shaderPath, materialPath); - fabricResourceManager.retainPath(shaderPath); - _shaderPath = shaderPath; - - const auto baseColorTextureCount = getBaseColorTextureCount(_materialDefinition); + _shaderPaths.push_back(shaderPath); + _allPaths.push_back(shaderPath); - if (baseColorTextureCount == 1) { + if (_materialDefinition.hasBaseColorTexture()) { const auto baseColorTexturePath = FabricUtil::joinPaths(materialPath, FabricTokens::base_color_texture); - fabricResourceManager.retainPath(baseColorTexturePath); - _baseColorTexturePath = baseColorTexturePath; createTexture(baseColorTexturePath, shaderPath, FabricTokens::inputs_base_color_texture); - } else if (baseColorTextureCount > 1) { - const auto baseColorTexturePath = FabricUtil::joinPaths(materialPath, FabricTokens::base_color_texture_array); - fabricResourceManager.retainPath(baseColorTexturePath); - _baseColorTexturePath = baseColorTexturePath; - createTextureArray( - baseColorTexturePath, shaderPath, FabricTokens::inputs_base_color_texture, baseColorTextureCount); - - _baseColorTextureLayerPaths.reserve(baseColorTextureCount); - for (uint64_t i = 0; i < baseColorTextureCount; i++) { - const auto& baseColorTextureToken = FabricTokens::base_color_texture_n[i]; - const auto& inputsBaseColorTextureToken = FabricTokens::inputs_texture_n[i]; - const auto baseColorTextureLayerPath = FabricUtil::joinPaths(materialPath, baseColorTextureToken); - createTexture(baseColorTextureLayerPath, baseColorTexturePath, inputsBaseColorTextureToken); - fabricResourceManager.retainPath(baseColorTextureLayerPath); - _baseColorTextureLayerPaths.push_back(baseColorTextureLayerPath); + _baseColorTexturePaths.push_back(baseColorTexturePath); + _allPaths.push_back(baseColorTexturePath); + } + + const auto imageryLayerCount = getImageryLayerCount(_materialDefinition); + _imageryLayerPaths.resize(imageryLayerCount); + + if (imageryLayerCount == 1) { + // If there's a single imagery layer plug into cesium_material directly + // instead of using a cesium_imagery_layer_resolver + const auto imageryLayerPath = FabricUtil::joinPaths(materialPath, FabricTokens::imagery_layer_n[0]); + createTexture(imageryLayerPath, shaderPath, FabricTokens::inputs_imagery_layers_texture); + _imageryLayerPaths[0].push_back(imageryLayerPath); + _allPaths.push_back(imageryLayerPath); + } else if (imageryLayerCount > 1) { + const auto imageryLayerResolverPath = FabricUtil::joinPaths(materialPath, FabricTokens::imagery_layer_resolver); + createImageryLayerResolver( + imageryLayerResolverPath, shaderPath, FabricTokens::inputs_imagery_layers_texture, imageryLayerCount); + _allPaths.push_back(imageryLayerResolverPath); + + for (uint64_t i = 0; i < imageryLayerCount; i++) { + const auto imageryLayerPath = FabricUtil::joinPaths(materialPath, FabricTokens::imagery_layer_n[i]); + createTexture(imageryLayerPath, imageryLayerResolverPath, FabricTokens::inputs_imagery_layer_n[i]); + _imageryLayerPaths[i].push_back(imageryLayerPath); + _allPaths.push_back(imageryLayerPath); } } + + for (const auto& path : _allPaths) { + FabricResourceManager::getInstance().retainPath(path); + } +} + +void FabricMaterial::initializeFromExistingMaterial(const omni::fabric::Path& srcMaterialPath) { + auto srw = UsdUtil::getFabricStageReaderWriter(); + + const auto& dstMaterialPath = _materialPath; + + const auto dstPaths = FabricUtil::copyMaterial(srcMaterialPath, dstMaterialPath); + + const auto imageryLayerCount = getImageryLayerCount(_materialDefinition); + _imageryLayerPaths.resize(imageryLayerCount); + + for (const auto& dstPath : dstPaths) { + srw.createAttribute(dstPath, FabricTokens::_cesium_tilesetId, FabricTypes::_cesium_tilesetId); + _allPaths.push_back(dstPath); + + const auto mdlIdentifier = FabricUtil::getMdlIdentifier(dstPath); + + if (mdlIdentifier == FabricTokens::cesium_base_color_texture_float4) { + if (_materialDefinition.hasBaseColorTexture()) { + // Create a base color texture node to fill the empty slot + const auto baseColorTexturePath = FabricUtil::joinPaths(dstPath, FabricTokens::base_color_texture); + createTexture(baseColorTexturePath, dstPath, FabricTokens::inputs_base_color_texture); + _baseColorTexturePaths.push_back(baseColorTexturePath); + _allPaths.push_back(baseColorTexturePath); + } + } else if (mdlIdentifier == FabricTokens::cesium_imagery_layer_float4) { + const auto imageryLayerIndexFabric = + srw.getAttributeRd(dstPath, FabricTokens::inputs_imagery_layer_index); + const auto imageryLayerIndex = + static_cast(imageryLayerIndexFabric == nullptr ? 0 : *imageryLayerIndexFabric); + + if (imageryLayerIndex < imageryLayerCount) { + const auto imageryLayerPath = FabricUtil::joinPaths(dstPath, FabricTokens::imagery_layer); + createTexture(imageryLayerPath, dstPath, FabricTokens::inputs_imagery_layer); + _imageryLayerPaths[imageryLayerIndex].push_back(imageryLayerPath); + _allPaths.push_back(imageryLayerPath); + } + } + } + + for (const auto& path : _allPaths) { + FabricResourceManager::getInstance().retainPath(path); + } } void FabricMaterial::createMaterial(const omni::fabric::Path& materialPath) { @@ -136,8 +197,6 @@ void FabricMaterial::createMaterial(const omni::fabric::Path& materialPath) { } void FabricMaterial::createShader(const omni::fabric::Path& shaderPath, const omni::fabric::Path& materialPath) { - const auto hasVertexColors = _materialDefinition.hasVertexColors(); - auto srw = UsdUtil::getFabricStageReaderWriter(); srw.createPrim(shaderPath); @@ -145,6 +204,7 @@ void FabricMaterial::createShader(const omni::fabric::Path& shaderPath, const om FabricAttributesBuilder attributes; // clang-format off + attributes.addAttribute(FabricTypes::inputs_debug_color, FabricTokens::inputs_debug_color); attributes.addAttribute(FabricTypes::inputs_alpha_cutoff, FabricTokens::inputs_alpha_cutoff); attributes.addAttribute(FabricTypes::inputs_alpha_mode, FabricTokens::inputs_alpha_mode); attributes.addAttribute(FabricTypes::inputs_base_alpha, FabricTokens::inputs_base_alpha); @@ -163,10 +223,6 @@ void FabricMaterial::createShader(const omni::fabric::Path& shaderPath, const om attributes.addAttribute(FabricTypes::_cesium_tilesetId, FabricTokens::_cesium_tilesetId); // clang-format on - if (hasVertexColors) { - attributes.addAttribute(FabricTypes::inputs_vertex_color_name, FabricTokens::inputs_vertex_color_name); - } - attributes.createAttributes(shaderPath); srw.setArrayAttributeSize(shaderPath, FabricTokens::_paramColorSpace, 0); @@ -183,15 +239,7 @@ void FabricMaterial::createShader(const omni::fabric::Path& shaderPath, const om *infoImplementationSourceFabric = FabricTokens::sourceAsset; infoMdlSourceAssetFabric->assetPath = Context::instance().getCesiumMdlPathToken(); infoMdlSourceAssetFabric->resolvedPath = pxr::TfToken(); - *infoMdlSourceAssetSubIdentifierFabric = FabricTokens::cesium_material; - - if (hasVertexColors) { - const auto vertexColorPrimvarNameSize = pxr::UsdTokens->vertexColor.GetString().size(); - srw.setArrayAttributeSize(shaderPath, FabricTokens::inputs_vertex_color_name, vertexColorPrimvarNameSize); - auto vertexColorNameFabric = - srw.getArrayAttributeWr(shaderPath, FabricTokens::inputs_vertex_color_name); - memcpy(vertexColorNameFabric.data(), pxr::UsdTokens->vertexColor.GetText(), vertexColorPrimvarNameSize); - } + *infoMdlSourceAssetSubIdentifierFabric = FabricTokens::cesium_internal_material; // Connect the material terminals to the shader. srw.createConnection( @@ -255,7 +303,7 @@ void FabricMaterial::createTexture( *infoImplementationSourceFabric = FabricTokens::sourceAsset; infoMdlSourceAssetFabric->assetPath = Context::instance().getCesiumMdlPathToken(); infoMdlSourceAssetFabric->resolvedPath = pxr::TfToken(); - *infoMdlSourceAssetSubIdentifierFabric = FabricTokens::cesium_texture_lookup; + *infoMdlSourceAssetSubIdentifierFabric = FabricTokens::cesium_internal_texture_lookup; paramColorSpaceFabric[0] = FabricTokens::inputs_texture; paramColorSpaceFabric[1] = FabricTokens::_auto; @@ -263,19 +311,19 @@ void FabricMaterial::createTexture( srw.createConnection(shaderPath, shaderInput, omni::fabric::Connection{texturePath, FabricTokens::outputs_out}); } -void FabricMaterial::createTextureArray( - const omni::fabric::Path& texturePath, +void FabricMaterial::createImageryLayerResolver( + const omni::fabric::Path& imageryLayerResolverPath, const omni::fabric::Path& shaderPath, const omni::fabric::Token& shaderInput, - uint64_t textureCount) { + uint64_t imageryLayerCount) { auto srw = UsdUtil::getFabricStageReaderWriter(); - srw.createPrim(texturePath); + srw.createPrim(imageryLayerResolverPath); FabricAttributesBuilder attributes; // clang-format off - attributes.addAttribute(FabricTypes::inputs_texture_count, FabricTokens::inputs_texture_count); + attributes.addAttribute(FabricTypes::inputs_imagery_layers_count, FabricTokens::inputs_imagery_layers_count); attributes.addAttribute(FabricTypes::inputs_excludeFromWhiteMode, FabricTokens::inputs_excludeFromWhiteMode); attributes.addAttribute(FabricTypes::outputs_out, FabricTokens::outputs_out); attributes.addAttribute(FabricTypes::info_implementationSource, FabricTokens::info_implementationSource); @@ -286,30 +334,32 @@ void FabricMaterial::createTextureArray( attributes.addAttribute(FabricTypes::_cesium_tilesetId, FabricTokens::_cesium_tilesetId); // clang-format on - attributes.createAttributes(texturePath); + attributes.createAttributes(imageryLayerResolverPath); // clang-format off - auto inputsTextureCountFabric = srw.getAttributeWr(texturePath, FabricTokens::inputs_texture_count); - auto inputsExcludeFromWhiteModeFabric = srw.getAttributeWr(texturePath, FabricTokens::inputs_excludeFromWhiteMode); - auto infoImplementationSourceFabric = srw.getAttributeWr(texturePath, FabricTokens::info_implementationSource); - auto infoMdlSourceAssetFabric = srw.getAttributeWr(texturePath, FabricTokens::info_mdl_sourceAsset); - auto infoMdlSourceAssetSubIdentifierFabric = srw.getAttributeWr(texturePath, FabricTokens::info_mdl_sourceAsset_subIdentifier); + auto imageryLayerCountFabric = srw.getAttributeWr(imageryLayerResolverPath, FabricTokens::inputs_imagery_layers_count); + auto inputsExcludeFromWhiteModeFabric = srw.getAttributeWr(imageryLayerResolverPath, FabricTokens::inputs_excludeFromWhiteMode); + auto infoImplementationSourceFabric = srw.getAttributeWr(imageryLayerResolverPath, FabricTokens::info_implementationSource); + auto infoMdlSourceAssetFabric = srw.getAttributeWr(imageryLayerResolverPath, FabricTokens::info_mdl_sourceAsset); + auto infoMdlSourceAssetSubIdentifierFabric = srw.getAttributeWr(imageryLayerResolverPath, FabricTokens::info_mdl_sourceAsset_subIdentifier); // clang-format on - *inputsTextureCountFabric = static_cast(textureCount); + *imageryLayerCountFabric = static_cast(imageryLayerCount); *inputsExcludeFromWhiteModeFabric = false; *infoImplementationSourceFabric = FabricTokens::sourceAsset; infoMdlSourceAssetFabric->assetPath = Context::instance().getCesiumMdlPathToken(); infoMdlSourceAssetFabric->resolvedPath = pxr::TfToken(); - *infoMdlSourceAssetSubIdentifierFabric = FabricTokens::cesium_texture_array_lookup; + *infoMdlSourceAssetSubIdentifierFabric = FabricTokens::cesium_internal_imagery_layer_resolver; - // Create connection from shader to texture. - srw.createConnection(shaderPath, shaderInput, omni::fabric::Connection{texturePath, FabricTokens::outputs_out}); + // Create connection to shader + srw.createConnection( + shaderPath, shaderInput, omni::fabric::Connection{imageryLayerResolverPath, FabricTokens::outputs_out}); } void FabricMaterial::reset() { clearMaterial(); - clearBaseColorTextures(); + clearBaseColorTexture(); + clearImageryLayers(); } void FabricMaterial::setMaterial(int64_t tilesetId, const MaterialInfo& materialInfo) { @@ -319,32 +369,43 @@ void FabricMaterial::setMaterial(int64_t tilesetId, const MaterialInfo& material auto srw = UsdUtil::getFabricStageReaderWriter(); - setShaderValues(_shaderPath, materialInfo); - setTilesetId(tilesetId); + for (auto& shaderPath : _shaderPaths) { + setShaderValues(shaderPath, materialInfo); + } + + for (const auto& path : _allPaths) { + FabricUtil::setTilesetId(path, tilesetId); + } } void FabricMaterial::setBaseColorTexture( const pxr::TfToken& textureAssetPathToken, const TextureInfo& textureInfo, - uint64_t texcoordIndex, - uint64_t textureIndex) { + uint64_t texcoordIndex) { if (stageDestroyed()) { return; } - if (!_materialDefinition.hasBaseColorTextures()) { + for (auto& baseColorTexturePath : _baseColorTexturePaths) { + setTextureValues(baseColorTexturePath, textureAssetPathToken, textureInfo, texcoordIndex); + } +} + +void FabricMaterial::setImageryLayer( + const pxr::TfToken& textureAssetPathToken, + const TextureInfo& textureInfo, + uint64_t texcoordIndex, + uint64_t imageryLayerIndex) { + if (stageDestroyed()) { return; } - if (textureIndex >= FabricTokens::MAX_TEXTURE_LAYER_COUNT) { + if (imageryLayerIndex >= _imageryLayerPaths.size()) { return; } - if (_baseColorTextureLayerPaths.empty()) { - assert(textureIndex == 0); - setTextureValues(_baseColorTexturePath, textureAssetPathToken, textureInfo, texcoordIndex); - } else { - setTextureValues(_baseColorTextureLayerPaths[textureIndex], textureAssetPathToken, textureInfo, texcoordIndex); + for (auto& imageryLayerPath : _imageryLayerPaths[imageryLayerIndex]) { + setTextureValues(imageryLayerPath, textureAssetPathToken, textureInfo, texcoordIndex); } } @@ -352,41 +413,24 @@ void FabricMaterial::clearMaterial() { setMaterial(NO_TILESET_ID, GltfUtil::getDefaultMaterialInfo()); } -void FabricMaterial::clearBaseColorTextures() { - if (!_materialDefinition.hasBaseColorTextures()) { - return; - } - - if (_baseColorTextureLayerPaths.empty()) { - clearBaseColorTexture(0); - } else { - for (uint64_t i = 0; i < _baseColorTextureLayerPaths.size(); i++) { - clearBaseColorTexture(i); - } - } +void FabricMaterial::clearBaseColorTexture() { + setBaseColorTexture(_defaultTextureAssetPathToken, GltfUtil::getDefaultTextureInfo(), 0); } -void FabricMaterial::clearBaseColorTexture(uint64_t textureIndex) { - const auto& token = textureIndex == 0 ? _defaultTextureAssetPathToken : _defaultTransparentTextureAssetPathToken; - setBaseColorTexture(token, GltfUtil::getDefaultTextureInfo(), 0, textureIndex); +void FabricMaterial::clearImageryLayer(uint64_t imageryLayerIndex) { + setImageryLayer(_defaultTransparentTextureAssetPathToken, GltfUtil::getDefaultTextureInfo(), 0, imageryLayerIndex); } -void FabricMaterial::setTilesetId(int64_t tilesetId) { - FabricUtil::setTilesetId(_materialPath, tilesetId); - FabricUtil::setTilesetId(_shaderPath, tilesetId); - - if (_materialDefinition.hasBaseColorTextures()) { - FabricUtil::setTilesetId(_baseColorTexturePath, tilesetId); - - for (const auto& baseColorTextureLayerPath : _baseColorTextureLayerPaths) { - FabricUtil::setTilesetId(baseColorTextureLayerPath, tilesetId); - } +void FabricMaterial::clearImageryLayers() { + for (uint64_t i = 0; i < _imageryLayerPaths.size(); i++) { + clearImageryLayer(i); } } void FabricMaterial::setShaderValues(const omni::fabric::Path& shaderPath, const MaterialInfo& materialInfo) { auto srw = UsdUtil::getFabricStageReaderWriter(); + auto debugColorFabric = srw.getAttributeWr(shaderPath, FabricTokens::inputs_debug_color); auto alphaCutoffFabric = srw.getAttributeWr(shaderPath, FabricTokens::inputs_alpha_cutoff); auto alphaModeFabric = srw.getAttributeWr(shaderPath, FabricTokens::inputs_alpha_mode); auto baseAlphaFabric = srw.getAttributeWr(shaderPath, FabricTokens::inputs_base_alpha); @@ -402,6 +446,15 @@ void FabricMaterial::setShaderValues(const omni::fabric::Path& shaderPath, const *emissiveFactorFabric = UsdUtil::glmToUsdVector(glm::fvec3(materialInfo.emissiveFactor)); *metallicFactorFabric = static_cast(materialInfo.metallicFactor); *roughnessFactorFabric = static_cast(materialInfo.roughnessFactor); + + if (_debugRandomColors) { + const auto r = glm::linearRand(0.0f, 1.0f); + const auto g = glm::linearRand(0.0f, 1.0f); + const auto b = glm::linearRand(0.0f, 1.0f); + *debugColorFabric = pxr::GfVec3f(r, g, b); + } else { + *debugColorFabric = DEFAULT_DEBUG_COLOR; + } } void FabricMaterial::setTextureValues( @@ -410,7 +463,7 @@ void FabricMaterial::setTextureValues( const TextureInfo& textureInfo, uint64_t texcoordIndex) { - if (texcoordIndex >= FabricTokens::MAX_TEXTURE_LAYER_COUNT) { + if (texcoordIndex >= FabricTokens::MAX_PRIMVAR_ST_COUNT) { return; } diff --git a/src/core/src/FabricMaterialDefinition.cpp b/src/core/src/FabricMaterialDefinition.cpp index 0550c2270..f73d9e2d9 100644 --- a/src/core/src/FabricMaterialDefinition.cpp +++ b/src/core/src/FabricMaterialDefinition.cpp @@ -14,32 +14,31 @@ namespace cesium::omniverse { FabricMaterialDefinition::FabricMaterialDefinition( const MaterialInfo& materialInfo, uint64_t imageryLayerCount, - bool disableTextures) { + bool disableTextures, + const pxr::SdfPath& tilesetMaterialPath) + : _hasVertexColors(materialInfo.hasVertexColors) + , _hasBaseColorTexture(disableTextures ? false : materialInfo.baseColorTexture.has_value()) + , _imageryLayerCount(disableTextures ? 0 : imageryLayerCount) + , _tilesetMaterialPath(tilesetMaterialPath) {} - uint64_t baseColorTextureCount = 0; - - if (!disableTextures) { - if (materialInfo.baseColorTexture.has_value()) { - baseColorTextureCount++; - } - - baseColorTextureCount += imageryLayerCount; - } +bool FabricMaterialDefinition::hasVertexColors() const { + return _hasVertexColors; +} - _hasVertexColors = materialInfo.hasVertexColors; - _baseColorTextureCount = baseColorTextureCount; +bool FabricMaterialDefinition::hasBaseColorTexture() const { + return _hasBaseColorTexture; } -uint64_t FabricMaterialDefinition::getBaseColorTextureCount() const { - return _baseColorTextureCount; +uint64_t FabricMaterialDefinition::getImageryLayerCount() const { + return _imageryLayerCount; } -bool FabricMaterialDefinition::hasBaseColorTextures() const { - return _baseColorTextureCount > 0; +bool FabricMaterialDefinition::hasTilesetMaterial() const { + return !_tilesetMaterialPath.IsEmpty(); } -bool FabricMaterialDefinition::hasVertexColors() const { - return _hasVertexColors; +const pxr::SdfPath& FabricMaterialDefinition::getTilesetMaterialPath() const { + return _tilesetMaterialPath; } // In C++ 20 we can use the default equality comparison (= default) @@ -48,7 +47,15 @@ bool FabricMaterialDefinition::operator==(const FabricMaterialDefinition& other) return false; } - if (_baseColorTextureCount != other._baseColorTextureCount) { + if (_hasBaseColorTexture != other._hasBaseColorTexture) { + return false; + } + + if (_imageryLayerCount != other._imageryLayerCount) { + return false; + } + + if (_tilesetMaterialPath != other._tilesetMaterialPath) { return false; } diff --git a/src/core/src/FabricMaterialPool.cpp b/src/core/src/FabricMaterialPool.cpp index 34e0ff682..e860efd4f 100644 --- a/src/core/src/FabricMaterialPool.cpp +++ b/src/core/src/FabricMaterialPool.cpp @@ -10,12 +10,14 @@ FabricMaterialPool::FabricMaterialPool( uint64_t initialCapacity, const pxr::TfToken& defaultTextureAssetPathToken, const pxr::TfToken& defaultTransparentTextureAssetPathToken, + bool debugRandomColors, long stageId) : ObjectPool() , _poolId(poolId) , _materialDefinition(materialDefinition) , _defaultTextureAssetPathToken(defaultTextureAssetPathToken) , _defaultTransparentTextureAssetPathToken(defaultTransparentTextureAssetPathToken) + , _debugRandomColors(debugRandomColors) , _stageId(stageId) { setCapacity(initialCapacity); } @@ -28,7 +30,12 @@ std::shared_ptr FabricMaterialPool::createObject(uint64_t object const auto pathStr = fmt::format("/fabric_material_pool_{}_object_{}", _poolId, objectId); const auto path = omni::fabric::Path(pathStr.c_str()); return std::make_shared( - path, _materialDefinition, _defaultTextureAssetPathToken, _defaultTransparentTextureAssetPathToken, _stageId); + path, + _materialDefinition, + _defaultTextureAssetPathToken, + _defaultTransparentTextureAssetPathToken, + _debugRandomColors, + _stageId); } void FabricMaterialPool::setActive(std::shared_ptr material, bool active) { diff --git a/src/core/src/FabricPrepareRenderResources.cpp b/src/core/src/FabricPrepareRenderResources.cpp index 6fb3e0cc1..c8de2f768 100644 --- a/src/core/src/FabricPrepareRenderResources.cpp +++ b/src/core/src/FabricPrepareRenderResources.cpp @@ -56,22 +56,10 @@ struct TileLoadThreadResult { }; bool hasBaseColorTextureGltf(const FabricMesh& fabricMesh) { - return fabricMesh.material->getMaterialDefinition().hasBaseColorTextures() && + return fabricMesh.material != nullptr && fabricMesh.material->getMaterialDefinition().hasBaseColorTexture() && fabricMesh.materialInfo.baseColorTexture.has_value(); } -uint64_t getBaseColorTextureIndexForGltf() { - return 0; -} - -uint64_t getBaseColorTextureIndexForImagery(const FabricMesh& fabricMesh, uint64_t imageryIndex) { - if (hasBaseColorTextureGltf(fabricMesh)) { - return imageryIndex + 1; - } - - return imageryIndex; -} - std::vector gatherMeshes(const OmniTileset& tileset, const glm::dmat4& tileTransform, const CesiumGltf::Model& model) { CESIUM_TRACE("FabricPrepareRenderResources::gatherMeshes"); @@ -139,8 +127,8 @@ std::vector acquireFabricMeshes( if (shouldAcquireMaterial) { const auto materialInfo = GltfUtil::getMaterialInfo(model, primitive); - const auto fabricMaterial = - fabricResourceManager.acquireMaterial(materialInfo, imageryLayerCount, stageId, tileset.getTilesetId()); + const auto fabricMaterial = fabricResourceManager.acquireMaterial( + materialInfo, imageryLayerCount, stageId, tileset.getTilesetId(), tilesetMaterialPath); fabricMesh.material = fabricMaterial; fabricMesh.materialInfo = materialInfo; @@ -219,9 +207,8 @@ void setFabricMeshes( if (hasBaseColorTextureGltf(mesh)) { const auto& textureInfo = materialInfo.baseColorTexture.value(); const auto texcoordIndex = mesh.texcoordIndexMapping[textureInfo.setIndex]; - const auto textureIndex = getBaseColorTextureIndexForGltf(); const auto& textureAssetPath = baseColorTexture->getAssetPathToken(); - material->setBaseColorTexture(textureAssetPath, textureInfo, texcoordIndex, textureIndex); + material->setBaseColorTexture(textureAssetPath, textureInfo, texcoordIndex); } } else if (!tilesetMaterialPath.IsEmpty()) { geometry->setMaterial(FabricUtil::toFabricPath(tilesetMaterialPath)); @@ -459,8 +446,8 @@ void FabricPrepareRenderResources::attachRasterInMainThread( return; } - auto imageryIndex = _tileset->findImageryIndex(rasterTile.getOverlay()); - if (!imageryIndex.has_value()) { + auto imageryLayerIndex = _tileset->findImageryLayerIndex(rasterTile.getOverlay()); + if (!imageryLayerIndex.has_value()) { return; } @@ -479,9 +466,8 @@ void FabricPrepareRenderResources::attachRasterInMainThread( }; const auto texcoordIndex = mesh.imageryTexcoordIndexMapping.at(gltfSetIndex); - const auto textureIndex = getBaseColorTextureIndexForImagery(mesh, imageryIndex.value()); const auto& textureAssetPath = texture->getAssetPathToken(); - material->setBaseColorTexture(textureAssetPath, textureInfo, texcoordIndex, textureIndex); + material->setImageryLayer(textureAssetPath, textureInfo, texcoordIndex, imageryLayerIndex.value()); } } } @@ -507,16 +493,15 @@ void FabricPrepareRenderResources::detachRasterInMainThread( return; } - auto imageryIndex = _tileset->findImageryIndex(rasterTile.getOverlay()); - if (!imageryIndex.has_value()) { + auto imageryLayerIndex = _tileset->findImageryLayerIndex(rasterTile.getOverlay()); + if (!imageryLayerIndex.has_value()) { return; } for (const auto& mesh : pTileRenderResources->fabricMeshes) { auto& material = mesh.material; if (material != nullptr) { - const auto textureIndex = getBaseColorTextureIndexForImagery(mesh, imageryIndex.value()); - material->clearBaseColorTexture(textureIndex); + material->clearImageryLayer(imageryLayerIndex.value()); } } } diff --git a/src/core/src/FabricResourceManager.cpp b/src/core/src/FabricResourceManager.cpp index 2dbbebb41..86d700eb4 100644 --- a/src/core/src/FabricResourceManager.cpp +++ b/src/core/src/FabricResourceManager.cpp @@ -56,7 +56,7 @@ bool FabricResourceManager::shouldAcquireMaterial( } if (!tilesetMaterialPath.IsEmpty()) { - return false; + return FabricUtil::materialHasCesiumNodes(FabricUtil::toFabricPath(tilesetMaterialPath)); } return hasImagery || GltfUtil::hasMaterial(primitive); @@ -73,7 +73,7 @@ std::shared_ptr FabricResourceManager::acquireGeometry( if (_disableGeometryPool) { const auto pathStr = fmt::format("/fabric_geometry_{}", getNextGeometryId()); const auto path = omni::fabric::Path(pathStr.c_str()); - return std::make_shared(path, geometryDefinition, _debugRandomColors, stageId); + return std::make_shared(path, geometryDefinition, stageId); } std::scoped_lock lock(_poolMutex); @@ -90,7 +90,7 @@ std::shared_ptr FabricResourceManager::acquireGeometry( } bool useSharedMaterial(const FabricMaterialDefinition& materialDefinition) { - if (materialDefinition.hasBaseColorTextures()) { + if (materialDefinition.hasBaseColorTexture() || materialDefinition.getImageryLayerCount() > 0) { return false; } @@ -102,7 +102,12 @@ FabricResourceManager::createMaterial(const FabricMaterialDefinition& materialDe const auto pathStr = fmt::format("/fabric_material_{}", getNextMaterialId()); const auto path = omni::fabric::Path(pathStr.c_str()); return std::make_shared( - path, materialDefinition, _defaultTextureAssetPathToken, _defaultTransparentTextureAssetPathToken, stageId); + path, + materialDefinition, + _defaultTextureAssetPathToken, + _defaultTransparentTextureAssetPathToken, + _debugRandomColors, + stageId); } void FabricResourceManager::removeSharedMaterial(const SharedMaterial& sharedMaterial) { @@ -176,8 +181,9 @@ std::shared_ptr FabricResourceManager::acquireMaterial( const MaterialInfo& materialInfo, uint64_t imageryLayerCount, long stageId, - int64_t tilesetId) { - FabricMaterialDefinition materialDefinition(materialInfo, imageryLayerCount, _disableTextures); + int64_t tilesetId, + const pxr::SdfPath& tilesetMaterialPath) { + FabricMaterialDefinition materialDefinition(materialInfo, imageryLayerCount, _disableTextures, tilesetMaterialPath); if (useSharedMaterial(materialDefinition)) { return acquireSharedMaterial(materialInfo, materialDefinition, stageId, tilesetId); @@ -346,7 +352,7 @@ std::shared_ptr FabricResourceManager::getTexturePool() { std::shared_ptr FabricResourceManager::createGeometryPool(const FabricGeometryDefinition& geometryDefinition, long stageId) { return _geometryPools.emplace_back(std::make_shared( - getNextPoolId(), geometryDefinition, _geometryPoolInitialCapacity, _debugRandomColors, stageId)); + getNextPoolId(), geometryDefinition, _geometryPoolInitialCapacity, stageId)); } std::shared_ptr @@ -357,6 +363,7 @@ FabricResourceManager::createMaterialPool(const FabricMaterialDefinition& materi _materialPoolInitialCapacity, _defaultTextureAssetPathToken, _defaultTransparentTextureAssetPathToken, + _debugRandomColors, stageId)); } diff --git a/src/core/src/FabricUtil.cpp b/src/core/src/FabricUtil.cpp index 9d0e672a0..5d90b7089 100644 --- a/src/core/src/FabricUtil.cpp +++ b/src/core/src/FabricUtil.cpp @@ -680,4 +680,213 @@ omni::fabric::Path joinPaths(const omni::fabric::Path& absolutePath, const omni: return {fmt::format("{}/{}", absolutePath.getText(), relativePath.getText()).c_str()}; } +namespace { + +struct FabricConnection { + omni::fabric::Connection* connection; + omni::fabric::Token attributeName; +}; + +std::vector getConnections(const omni::fabric::Path& path) { + std::vector connections; + + auto srw = UsdUtil::getFabricStageReaderWriter(); + const auto attributes = srw.getAttributeNamesAndTypes(path); + const auto& names = attributes.first; + const auto& types = attributes.second; + + for (size_t i = 0; i < names.size(); i++) { + const auto& name = names[i]; + const auto& type = types[i]; + if (type.baseType == omni::fabric::BaseDataType::eConnection) { + const auto connection = srw.getConnection(path, name); + if (connection != nullptr) { + connections.emplace_back(FabricConnection{connection, name}); + } + } + } + + return connections; +} + +bool isOutput(const omni::fabric::Token& attributeName) { + return attributeName == FabricTokens::outputs_out; +} + +bool isConnection(const omni::fabric::Type& attributeType) { + return attributeType.baseType == omni::fabric::BaseDataType::eConnection; +} + +bool isEmptyToken( + const omni::fabric::Path& path, + const omni::fabric::Token& attributeName, + const omni::fabric::Type& attributeType) { + auto srw = UsdUtil::getFabricStageReaderWriter(); + if (attributeType.baseType == omni::fabric::BaseDataType::eToken) { + const auto attributeValue = srw.getAttributeRd(path, attributeName); + if (attributeValue == nullptr || (*attributeValue).size() == 0) { + return true; + } + } + + return false; +} + +std::vector getAttributesToCopy(const omni::fabric::Path& path) { + std::vector attributeNames; + + auto srw = UsdUtil::getFabricStageReaderWriter(); + + const auto attributes = srw.getAttributeNamesAndTypes(path); + const auto& names = attributes.first; + const auto& types = attributes.second; + + for (size_t i = 0; i < names.size(); i++) { + const auto& name = names[i]; + const auto& type = types[i]; + + if (!isOutput(name) && !isConnection(type) && !isEmptyToken(path, name, type)) { + attributeNames.emplace_back(omni::fabric::TokenC(name)); + } + } + + return attributeNames; +} + +struct FabricAttribute { + omni::fabric::Token name; + omni::fabric::Type type; +}; + +std::vector getAttributesToCreate(const omni::fabric::Path& path) { + std::vector attributeNames; + + auto srw = UsdUtil::getFabricStageReaderWriter(); + + const auto attributes = srw.getAttributeNamesAndTypes(path); + const auto& names = attributes.first; + const auto& types = attributes.second; + + for (size_t i = 0; i < names.size(); i++) { + const auto& name = names[i]; + const auto& type = types[i]; + + if (isOutput(name) || isEmptyToken(path, name, type)) { + attributeNames.emplace_back(FabricAttribute{name, type}); + } + } + + return attributeNames; +} + +void getConnectedPrimsRecursive(const omni::fabric::Path& path, std::vector& connectedPaths) { + const auto connections = getConnections(path); + for (const auto& connection : connections) { + const auto it = std::find(connectedPaths.begin(), connectedPaths.end(), connection.connection->path); + if (it == connectedPaths.end()) { + connectedPaths.emplace_back(connection.connection->path); + getConnectedPrimsRecursive(connection.connection->path, connectedPaths); + } + } +} + +std::vector getPrimsInMaterialNetwork(const omni::fabric::Path& path) { + auto srw = UsdUtil::getFabricStageReaderWriter(); + std::vector paths; + paths.push_back(path); + getConnectedPrimsRecursive(path, paths); + return paths; +} + +} // namespace + +std::vector +copyMaterial(const omni::fabric::Path& srcMaterialPath, const omni::fabric::Path& dstMaterialPath) { + auto srw = UsdUtil::getFabricStageReaderWriter(); + const auto isrw = carb::getCachedInterface(); + + const auto srcPaths = getPrimsInMaterialNetwork(srcMaterialPath); + + std::vector dstPaths; + dstPaths.reserve(srcPaths.size()); + + for (const auto& srcPath : srcPaths) { + auto dstPath = omni::fabric::Path(); + + if (srcPath == srcMaterialPath) { + dstPath = dstMaterialPath; + } else { + dstPath = FabricUtil::joinPaths( + dstMaterialPath, omni::fabric::Token(UsdUtil::getSafeName(srcPath.getText()).c_str())); + } + + dstPaths.push_back(dstPath); + + srw.createPrim(dstPath); + + // This excludes connections, outputs, and empty tokens + // The material network will be reconnected later once all the prims have been copied + // The reason for excluding outputs and empty tokens is so that Omniverse doesn't print the warning + // [Warning] [omni.fabric.plugin] Warning: input has no valid data + const auto attributesToCopy = getAttributesToCopy(srcPath); + + isrw->copySpecifiedAttributes( + srw.getId(), srcPath, attributesToCopy.data(), dstPath, attributesToCopy.data(), attributesToCopy.size()); + + // Add the outputs and empty tokens back. This doesn't print a warning. + const auto attributesToCreate = getAttributesToCreate(srcPath); + for (const auto& attribute : attributesToCreate) { + srw.createAttribute(dstPath, attribute.name, attribute.type); + } + } + + // Reconnect the prims + for (size_t i = 0; i < srcPaths.size(); i++) { + const auto& srcPath = srcPaths[i]; + const auto& dstPath = dstPaths[i]; + const auto connections = getConnections(srcPath); + for (const auto& connection : connections) { + const auto it = std::find(srcPaths.begin(), srcPaths.end(), connection.connection->path); + assert(it != srcPaths.end()); // Ensure that all connections are part of the material network + const auto index = it - srcPaths.begin(); + const auto dstConnection = + omni::fabric::Connection{omni::fabric::PathC(dstPaths[index]), connection.connection->attrName}; + srw.createConnection(dstPath, connection.attributeName, dstConnection); + } + } + + return dstPaths; +} + +bool materialHasCesiumNodes(const omni::fabric::Path& path) { + auto srw = UsdUtil::getFabricStageReaderWriter(); + const auto paths = getPrimsInMaterialNetwork(path); + + for (const auto& p : paths) { + const auto mdlIdentifier = getMdlIdentifier(p); + if (isCesiumNode(mdlIdentifier)) { + return true; + } + } + + return false; +} + +bool isCesiumNode(const omni::fabric::Token& mdlIdentifier) { + return mdlIdentifier == FabricTokens::cesium_base_color_texture_float4 || + mdlIdentifier == FabricTokens::cesium_imagery_layer_float4; +} + +omni::fabric::Token getMdlIdentifier(const omni::fabric::Path& path) { + auto srw = UsdUtil::getFabricStageReaderWriter(); + if (srw.attributeExists(path, FabricTokens::info_mdl_sourceAsset_subIdentifier)) { + const auto infoMdlSourceAssetSubIdentifierFabric = + srw.getAttributeRd(path, FabricTokens::info_mdl_sourceAsset_subIdentifier); + if (infoMdlSourceAssetSubIdentifierFabric != nullptr) { + return *infoMdlSourceAssetSubIdentifierFabric; + } + } + return omni::fabric::Token{}; +} + } // namespace cesium::omniverse::FabricUtil diff --git a/src/core/src/OmniTileset.cpp b/src/core/src/OmniTileset.cpp index ba137a757..ca2742d66 100644 --- a/src/core/src/OmniTileset.cpp +++ b/src/core/src/OmniTileset.cpp @@ -411,7 +411,7 @@ void OmniTileset::addImageryIon(const pxr::SdfPath& imageryPath) { _tileset->getOverlays().add(ionRasterOverlay); } -std::optional OmniTileset::findImageryIndex(const Cesium3DTilesSelection::RasterOverlay& overlay) const { +std::optional OmniTileset::findImageryLayerIndex(const Cesium3DTilesSelection::RasterOverlay& overlay) const { uint64_t overlayIndex = 0; for (const auto& pOverlay : _tileset->getOverlays()) { if (&overlay == pOverlay.get()) {