diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 757a6fd7c8..8a3dce98ec 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -14,7 +14,9 @@ env: RELEASE_TYPE: PR RELEASE_NUMBER: ${{ github.event.number }} VERSION_CODE: ${{ github.event.number }} - + # Sentry Crash Reporting + CMAKE_BACKTRACE_URL: ${{ secrets.MINIDUMP_TOKEN }} + CMAKE_BACKTRACE_TOKEN: PR_${{ github.event.number }}_${{ github.sha }} # OSX specific variables DEVELOPER_DIR: /Applications/Xcode_11.2.app/Contents/Developer @@ -169,7 +171,7 @@ jobs: - name: Build for Android + Quest if: matrix.build_type == 'android' shell: bash - working-directory: ${{runner.workspace}}/project-athena + working-directory: ${{runner.workspace}}/vircadia run: | echo "Pre-cache the vcpkg managed dependencies" $PYTHON_EXEC prebuild.py --build-root ${{runner.workspace}}/build --android interface diff --git a/BUILD_ANDROID.md b/BUILD_ANDROID.md index 0bea3e5a90..fc73d7905e 100644 --- a/BUILD_ANDROID.md +++ b/BUILD_ANDROID.md @@ -66,7 +66,7 @@ The above code to suppress modules is not necessary, but will speed up the build ### Clone the repository -`git clone https://github.com/kasenvr/project-athena.git` +`git clone https://github.com/vircadia/vircadia.git` ## Building & Running @@ -119,4 +119,4 @@ Some things you can try if you want to do a clean build * In Android Studio, click _File > Invalidate Caches / Restart_ and select _Invalidate and Restart_ If you see lots of "couldn't acquire lock" errors, -* Open Task Manager and close any running Clang / Gradle processes \ No newline at end of file +* Open Task Manager and close any running Clang / Gradle processes diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index f6287846ed..90782e90b4 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -1,9 +1,11 @@ # Build Linux -*Last Updated on April 11, 2020* +*Last Updated on December 1, 2020* Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only Linux specific instructions are found in this file. +You can use the [Vircadia Builder](https://github.com/vircadia/vircadia-builder) to build on Linux more easily. Alternatively, you can follow the manual steps below. + ## Ubuntu 16.04/18.04 specific build guide ### Ubuntu 16.04 only Add the following line to *.bash_profile* @@ -76,7 +78,7 @@ sudo apt-get install nodejs Clone this repository: ```bash -git clone https://github.com/kasenvr/project-athena.git +git clone https://github.com/vircadia/vircadia.git ``` To compile a DEV version checkout the branch you need. To get a list of all tags: @@ -86,7 +88,7 @@ git fetch -a Then checkout the main branch with: ```bash -git checkout kasen/core +git checkout master ``` ### Using a custom Qt build @@ -103,7 +105,7 @@ Qt must be installed in `$HIFI_QT_BASE/$VIRCADIA_USE_QT_VERSION/qt5-install`. Create the build directory: ```bash -cd project-athena +cd vircadia mkdir build cd build ``` diff --git a/BUILD_WIN.md b/BUILD_WIN.md index c057d9ca5d..1035b1c366 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -107,7 +107,7 @@ Note: You can also run Interface by launching it from command line or File Explo For any problems after Step #6, first try this: * Delete your locally cloned copy of the Vircadia repository * Restart your computer -* Redownload the [repository](https://github.com/kasenvr/project-athena) +* Redownload the [repository](https://github.com/vircadia/vircadia) * Restart directions from Step #6 #### CMake gives you the same error message repeatedly after the build fails diff --git a/CMakeLists.txt b/CMakeLists.txt index 424fbdc940..f111f482ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,12 @@ endif() file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/_env/EXTERNAL_BUILD_ASSETS.txt" "${EXTERNAL_BUILD_ASSETS}") MESSAGE(STATUS "EXTERNAL_BUILD_ASSETS: ${EXTERNAL_BUILD_ASSETS}") +set(GLES_OPTION "$ENV{USE_GLES}") + +# Will affect VCPKG dependencies +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/_env/USE_GLES.txt" "${GLES_OPTION}") +MESSAGE(STATUS "GLES_OPTION: ${GLES_OPTION}") + include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/macros/TargetPython.cmake") target_python() @@ -129,7 +135,6 @@ set(BUILD_TESTS_OPTION OFF) set(BUILD_MANUAL_TESTS_OPTION ${BUILD_TESTS_OPTION}) set(BUILD_TOOLS_OPTION ON) set(BUILD_INSTALLER_OPTION ON) -set(GLES_OPTION OFF) set(DISABLE_QML_OPTION OFF) set(DOWNLOAD_SERVERLESS_CONTENT_OPTION OFF) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aeb6f49280..72f296e92e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,4 @@ + The project embraces distributed development and if you'd like to help, it would be greatly appreciated. Just open a pull request with the revisions. Contributing @@ -6,7 +7,7 @@ Contributing 2. Clone your fork of the repository locally ``` - git clone git://github.com/USERNAME/project-athena.git + git clone git://github.com/USERNAME/vircadia.git ``` 3. Create a new branch @@ -20,7 +21,7 @@ Contributing 6. Update your branch ``` - git remote add upstream https://github.com/kasenvr/project-athena + git remote add upstream https://github.com/vircadia/vircadia git pull upstream master ``` @@ -35,13 +36,22 @@ Contributing *You can follow [GitHub's guide](https://help.github.com/articles/creating-a-pull-request) to find out how to create a pull request.* +Tips for Pull Requests +=== +To make the QA process go as smoothly as possible. + +1. Have a basic description in your pull request. +2. Write a basic test plan if you are altering or adding features. +3. If a new API is added, try to make sure that some level of basic documentation on how you can utilize it is included. +4. If an added API or feature requires an external service, try to document or link to instructions on how to create a basic working setup. + Reporting Bugs === 1. Always update to the latest code on master, we make many merges every day and it is possible the bug has already been fixed! -2. Search [issues](https://github.com/kasenvr/project-athena/issues) to make sure that somebody has not already reported the same bug. -3. [Add](https://github.com/kasenvr/project-athena/issues/new) your report to the issues list! +2. Search [issues](https://github.com/vircadia/vircadia/issues) to make sure that somebody has not already reported the same bug. +3. [Add](https://github.com/vircadia/vircadia/issues/new) your report to the issues list! Requesting a Feature === -1. Search [issues](https://github.com/kasenvr/project-athena/issues) to make sure that somebody has not already requested the same feature. -2. [Add](https://github.com/kasenvr/project-athena/issues/new) your request to the issues list! +1. Search [issues](https://github.com/vircadia/vircadia/issues) to make sure that somebody has not already requested the same feature. +2. [Add](https://github.com/vircadia/vircadia/issues/new) your request to the issues list! diff --git a/INSTALL.md b/INSTALLER.md similarity index 100% rename from INSTALL.md rename to INSTALLER.md diff --git a/README.md b/README.md index baf333d81f..c7a9ee8d52 100644 --- a/README.md +++ b/README.md @@ -8,17 +8,17 @@ Vircadia is a 3D social software project seeking to incrementally bring about a ### Releases -[View Releases here](https://github.com/kasenvr/project-athena/releases/) +[View Releases here](https://github.com/vircadia/vircadia/releases/) ### How to build the Interface -[For Windows](https://github.com/kasenvr/project-athena/blob/master/BUILD_WIN.md) +[For Windows](https://github.com/vircadia/vircadia/blob/master/BUILD_WIN.md) -[For Mac](https://github.com/kasenvr/project-athena/blob/master/BUILD_OSX.md) +[For Mac](https://github.com/vircadia/vircadia/blob/master/BUILD_OSX.md) -[For Linux](https://github.com/kasenvr/project-athena/blob/master/BUILD_LINUX.md) +[For Linux](https://github.com/vircadia/vircadia/blob/master/BUILD_LINUX.md) -[For Linux - Vircadia Builder](https://github.com/kasenvr/vircadia-builder) +[For Linux - Vircadia Builder](https://github.com/vircadia/vircadia-builder) ### How to deploy a Server @@ -26,13 +26,13 @@ Vircadia is a 3D social software project seeking to incrementally bring about a ### How to build a Server -[For Linux - Vircadia Builder](https://github.com/kasenvr/vircadia-builder) +[For Linux - Vircadia Builder](https://github.com/vircadia/vircadia-builder) ### How to generate an Installer -[For Windows](https://github.com/kasenvr/project-athena/blob/master/INSTALL.md) +[For Windows](https://github.com/vircadia/vircadia/blob/master/INSTALLER.md) -[For Linux - AppImage - Vircadia Builder](https://github.com/kasenvr/vircadia-builder/blob/master/README.md#building-appimages) +[For Linux - AppImage - Vircadia Builder](https://github.com/vircadia/vircadia-builder/blob/master/README.md#building-appimages) ### Boot to Metaverse: The Goal diff --git a/android/containerized_build.sh b/android/containerized_build.sh index 94b5b28831..bbf0b605d8 100755 --- a/android/containerized_build.sh +++ b/android/containerized_build.sh @@ -17,7 +17,7 @@ test -z "$STABLE_BUILD" && export STABLE_BUILD=0 docker run \ --rm \ --security-opt seccomp:unconfined \ - -v "${WORKSPACE}":/home/gha/project-athena \ + -v "${WORKSPACE}":/home/gha/vircadia \ -e RELEASE_NUMBER \ -e RELEASE_TYPE \ -e ANDROID_APP \ diff --git a/android/docker/Dockerfile b/android/docker/Dockerfile index 144f6caffa..ab5ddb562d 100644 --- a/android/docker/Dockerfile +++ b/android/docker/Dockerfile @@ -72,17 +72,17 @@ RUN mkdir "$HIFI_BASE" && \ mkdir "$HIFI_ANDROID_PRECOMPILED" # Download the repo -RUN git clone https://github.com/kasenvr/project-athena.git +RUN git clone https://github.com/vircadia/vircadia.git -WORKDIR /home/gha/project-athena +WORKDIR /home/gha/vircadia RUN mkdir build # Pre-cache the vcpkg managed dependencies -WORKDIR /home/gha/project-athena/build +WORKDIR /home/gha/vircadia/build RUN python3 ../prebuild.py --build-root `pwd` --android interface # Pre-cache the gradle dependencies -WORKDIR /home/gha/project-athena/android +WORKDIR /home/gha/vircadia/android RUN ./gradlew -m tasks -PHIFI_ANDROID_PRECOMPILED=$HIFI_ANDROID_PRECOMPILED #RUN ./gradlew extractDependencies -PHIFI_ANDROID_PRECOMPILED=$HIFI_ANDROID_PRECOMPILED diff --git a/cmake/macros/OptionalWinExecutableSigning.cmake b/cmake/macros/OptionalWinExecutableSigning.cmake index cbefdaea8f..8f9fde672c 100644 --- a/cmake/macros/OptionalWinExecutableSigning.cmake +++ b/cmake/macros/OptionalWinExecutableSigning.cmake @@ -10,7 +10,7 @@ # macro(optional_win_executable_signing) - if (WIN32 AND PRODUCTION_BUILD) + if (WIN32 AND PRODUCTION_BUILD AND NOT BYPASS_SIGNING) if (DEFINED ENV{HF_PFX_FILE}) if (DEFINED ENV{HF_PFX_PASSPHRASE}) message(STATUS "Executable for ${TARGET_NAME} will be signed with SignTool.") diff --git a/cmake/macros/SetPackagingParameters.cmake b/cmake/macros/SetPackagingParameters.cmake index 1e05cad109..c9cf91bd3d 100644 --- a/cmake/macros/SetPackagingParameters.cmake +++ b/cmake/macros/SetPackagingParameters.cmake @@ -25,6 +25,7 @@ macro(SET_PACKAGING_PARAMETERS) set_from_env(RELEASE_NUMBER RELEASE_NUMBER "") set_from_env(STABLE_BUILD STABLE_BUILD 0) set_from_env(INITIAL_STARTUP_LOCATION INITIAL_STARTUP_LOCATION "") + set_from_env(BYPASS_SIGNING BYPASS_SIGNING 0) message(STATUS "The RELEASE_TYPE variable is: ${RELEASE_TYPE}") diff --git a/cmake/macros/TargetOculusMobile.cmake b/cmake/macros/TargetOculusMobile.cmake index f5229845a9..34d5e33058 100644 --- a/cmake/macros/TargetOculusMobile.cmake +++ b/cmake/macros/TargetOculusMobile.cmake @@ -1,6 +1,6 @@ macro(target_oculus_mobile) - set(INSTALL_DIR ${HIFI_ANDROID_PRECOMPILED}/oculus_1.22/VrApi) + set(INSTALL_DIR ${HIFI_ANDROID_PRECOMPILED}/ovr_sdk_mobile_1.37.0/VrApi) # Mobile SDK set(OVR_MOBILE_INCLUDE_DIRS ${INSTALL_DIR}/Include) @@ -12,7 +12,7 @@ macro(target_oculus_mobile) target_link_libraries(${TARGET_NAME} ${OVR_MOBILE_LIBRARIES}) # Platform SDK - set(INSTALL_DIR ${HIFI_ANDROID_PRECOMPILED}/oculusPlatform) + set(INSTALL_DIR ${HIFI_ANDROID_PRECOMPILED}/ovr_platform_sdk_23.0.0) set(OVR_PLATFORM_INCLUDE_DIRS ${INSTALL_DIR}/Include) target_include_directories(${TARGET_NAME} PRIVATE ${OVR_PLATFORM_INCLUDE_DIRS}) set(OVR_PLATFORM_LIBRARIES ${INSTALL_DIR}/Android/libs/arm64-v8a/libovrplatformloader.so) diff --git a/cmake/ports/etc2comp/portfile.cmake b/cmake/ports/etc2comp/portfile.cmake index 343f67169b..1369492599 100644 --- a/cmake/ports/etc2comp/portfile.cmake +++ b/cmake/ports/etc2comp/portfile.cmake @@ -19,7 +19,7 @@ include(vcpkg_common_functions) vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH - REPO kasenvr/etc2comp + REPO vircadia/etc2comp REF 7f1843bf07825c21cab711360c1ddbad04641036 SHA512 d747076acda8537d39585858c793a35c3dcc9ef283d723619a47f8c81ec1454c95b3340ad35f0655a939eae5b8271c801c48a9a7568311a01903a344c44af25b HEAD_REF master diff --git a/cmake/ports/glad/portfile.cmake b/cmake/ports/glad/portfile.cmake index 54b1d91c89..6e3118b31e 100644 --- a/cmake/ports/glad/portfile.cmake +++ b/cmake/ports/glad/portfile.cmake @@ -2,13 +2,22 @@ include(vcpkg_common_functions) vcpkg_check_linkage(ONLY_STATIC_LIBRARY) file(READ "${VCPKG_ROOT_DIR}/_env/EXTERNAL_BUILD_ASSETS.txt" EXTERNAL_BUILD_ASSETS) +file(READ "${VCPKG_ROOT_DIR}/_env/USE_GLES.txt" USE_GLES) +# GitHub Actions Android builds fail with `FILENAME` set while desktop builds with GLES fail without a set `FILENAME`. if (ANDROID) vcpkg_download_distfile( SOURCE_ARCHIVE URLS ${EXTERNAL_BUILD_ASSETS}/dependencies/glad/glad32es.zip SHA512 2e02ac633eed8f2ba2adbf96ea85d08998f48dd2e9ec9a88ec3c25f48eaf1405371d258066327c783772fcb3793bdb82bd7375fdabb2ba5e2ce0835468b17f65 ) +elseif (USE_GLES) + vcpkg_download_distfile( + SOURCE_ARCHIVE + URLS ${EXTERNAL_BUILD_ASSETS}/dependencies/glad/glad32es.zip + SHA512 2e02ac633eed8f2ba2adbf96ea85d08998f48dd2e9ec9a88ec3c25f48eaf1405371d258066327c783772fcb3793bdb82bd7375fdabb2ba5e2ce0835468b17f65 + FILENAME glad32es.zip + ) else() # else Linux desktop vcpkg_download_distfile( diff --git a/cmake/ports/hifi-scribe/portfile.cmake b/cmake/ports/hifi-scribe/portfile.cmake index 498e8a455b..19d03b5db4 100644 --- a/cmake/ports/hifi-scribe/portfile.cmake +++ b/cmake/ports/hifi-scribe/portfile.cmake @@ -3,7 +3,7 @@ include(vcpkg_common_functions) vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH - REPO kasenvr/scribe + REPO vircadia/scribe REF 1bd638a36ca771e5a68d01985b6389b71835cbd2 SHA512 dbe241d86df3912e544f6b9839873f9875df54efc93822b145e7b13243eaf2e3d690bc8a28b1e52d05bdcd7e68fca6b0b2f5c43ffd0f56a9b7a50d54dcf9e31e HEAD_REF master diff --git a/cmake/ports/nvtt/portfile.cmake b/cmake/ports/nvtt/portfile.cmake index c7bf068e13..b21bb5609c 100644 --- a/cmake/ports/nvtt/portfile.cmake +++ b/cmake/ports/nvtt/portfile.cmake @@ -9,7 +9,7 @@ include(vcpkg_common_functions) vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH - REPO kasenvr/nvidia-texture-tools + REPO vircadia/nvidia-texture-tools REF 330c4d56274a0f602a5c70596e2eb670a4ed56c2 SHA512 4c0bc2f369120d696cc27710b6d33086b27eef55f537ec66b9a5c8b1839bc2426c0413670b0f65be52c5d353468f0126dfe024be1f0690611d4d7e33ac530127 HEAD_REF master diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index 752fb25d20..4c44ed1fbd 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -837,16 +837,24 @@ Function PostInstallOptionsPage !insertmacro SetInstallOption $DesktopClientCheckbox @CLIENT_DESKTOP_SHORTCUT_REG_KEY@ ${BST_CHECKED} ${EndIf} + ; FIXME: Re-enable or permanently remove system tray "Console" for Interface-only installs. + ;${If} @SERVER_COMPONENT_CONDITIONAL@ + ; ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for @SANDBOX_HF_SHORTCUT_NAME@" + ;${Else} + ; ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for @CONSOLE_HF_SHORTCUT_NAME@" + ;${EndIf} + ;Pop $DesktopConsoleCheckbox + ;IntOp $CurrentOffset $CurrentOffset + 15 + ; + ;; set the checkbox state depending on what is present in the registry + ;!insertmacro SetInstallOption $DesktopConsoleCheckbox @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ ${BST_UNCHECKED} ${If} @SERVER_COMPONENT_CONDITIONAL@ ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for @SANDBOX_HF_SHORTCUT_NAME@" - ${Else} - ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for @CONSOLE_HF_SHORTCUT_NAME@" + Pop $DesktopConsoleCheckbox + IntOp $CurrentOffset $CurrentOffset + 15 + ; set the checkbox state depending on what is present in the registry + !insertmacro SetInstallOption $DesktopConsoleCheckbox @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ ${BST_UNCHECKED} ${EndIf} - - Pop $DesktopConsoleCheckbox - IntOp $CurrentOffset $CurrentOffset + 15 - ; set the checkbox state depending on what is present in the registry - !insertmacro SetInstallOption $DesktopConsoleCheckbox @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ ${BST_UNCHECKED} ${If} @CLIENT_COMPONENT_CONDITIONAL@ ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @INTERFACE_HF_SHORTCUT_NAME@ after install" @@ -861,31 +869,54 @@ Function PostInstallOptionsPage ${EndIf} ${EndIf} + ; FIXME: Re-enable or permanently remove system tray "Console" for Interface-only installs. + ;${If} @SERVER_COMPONENT_CONDITIONAL@ + ; ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @SANDBOX_HF_SHORTCUT_NAME@ after install" + ;${Else} + ; ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @CONSOLE_HF_SHORTCUT_NAME@ after install" + ;${EndIf} + ;Pop $LaunchConsoleNowCheckbox + ; + ;; set the checkbox state depending on what is present in the registry + ;!insertmacro SetInstallOption $LaunchConsoleNowCheckbox @SERVER_LAUNCH_NOW_REG_KEY@ ${BST_UNCHECKED} + ;${StrContains} $substringResult "/forceNoLaunchServer" $CMDLINE + ;${IfNot} $substringResult == "" + ; ${NSD_SetState} $LaunchConsoleNowCheckbox ${BST_UNCHECKED} + ;${EndIf} + ;IntOp $CurrentOffset $CurrentOffset + 15 ${If} @SERVER_COMPONENT_CONDITIONAL@ ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @SANDBOX_HF_SHORTCUT_NAME@ after install" - ${Else} - ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @CONSOLE_HF_SHORTCUT_NAME@ after install" - ${EndIf} - Pop $LaunchConsoleNowCheckbox - - ; set the checkbox state depending on what is present in the registry - !insertmacro SetInstallOption $LaunchConsoleNowCheckbox @SERVER_LAUNCH_NOW_REG_KEY@ ${BST_UNCHECKED} - ${StrContains} $substringResult "/forceNoLaunchServer" $CMDLINE - ${IfNot} $substringResult == "" + Pop $LaunchConsoleNowCheckbox + + ; set the checkbox state depending on what is present in the registry + !insertmacro SetInstallOption $LaunchConsoleNowCheckbox @SERVER_LAUNCH_NOW_REG_KEY@ ${BST_UNCHECKED} + ${StrContains} $substringResult "/forceNoLaunchServer" $CMDLINE + ${IfNot} $substringResult == "" ${NSD_SetState} $LaunchConsoleNowCheckbox ${BST_UNCHECKED} + ${EndIf} + IntOp $CurrentOffset $CurrentOffset + 15 ${EndIf} - IntOp $CurrentOffset $CurrentOffset + 30 - - ${If} @SERVER_COMPONENT_CONDITIONAL@ - ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @SANDBOX_HF_SHORTCUT_NAME@ on startup" - ${Else} - ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @CONSOLE_HF_SHORTCUT_NAME@ on startup" - ${EndIf} - Pop $ConsoleStartupCheckbox IntOp $CurrentOffset $CurrentOffset + 15 - ; set the checkbox state depending on what is present in the registry - !insertmacro SetInstallOption $ConsoleStartupCheckbox @CONSOLE_STARTUP_REG_KEY@ ${BST_UNCHECKED} + ; FIXME: Re-enable or permanently remove system tray "Console" for Interface-only installs. + ;${If} @SERVER_COMPONENT_CONDITIONAL@ + ; ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @SANDBOX_HF_SHORTCUT_NAME@ on startup" + ;${Else} + ; ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @CONSOLE_HF_SHORTCUT_NAME@ on startup" + ;${EndIf} + ;Pop $ConsoleStartupCheckbox + ;IntOp $CurrentOffset $CurrentOffset + 15 + ; + ;; set the checkbox state depending on what is present in the registry + ;!insertmacro SetInstallOption $ConsoleStartupCheckbox @CONSOLE_STARTUP_REG_KEY@ ${BST_UNCHECKED} + ${If} @SERVER_COMPONENT_CONDITIONAL@ + ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @SANDBOX_HF_SHORTCUT_NAME@ on startup" + Pop $ConsoleStartupCheckbox + IntOp $CurrentOffset $CurrentOffset + 15 + + ; set the checkbox state depending on what is present in the registry + !insertmacro SetInstallOption $ConsoleStartupCheckbox @CONSOLE_STARTUP_REG_KEY@ ${BST_UNCHECKED} + ${EndIf} ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Perform a clean install (Delete older settings and content)" Pop $CleanInstallCheckbox @@ -957,13 +988,29 @@ FunctionEnd Function ReadPostInstallOptions - ; check if the user asked for a desktop shortcut to console - ${NSD_GetState} $DesktopConsoleCheckbox $DesktopConsoleState - ${LogText} "Option: Start Desktop Console: $DesktopConsoleState" + ; FIXME: Re-enable or permanently remove system tray "Console" for Interface-only installs. + ;; check if the user asked for a desktop shortcut to console + ;${NSD_GetState} $DesktopConsoleCheckbox $DesktopConsoleState + ;${LogText} "Option: Start Desktop Console: $DesktopConsoleState" + ${If} @SERVER_COMPONENT_CONDITIONAL@ + ; check if the user asked for a desktop shortcut to console + ${NSD_GetState} $DesktopConsoleCheckbox $DesktopConsoleState + ${LogText} "Option: Start Desktop Console: $DesktopConsoleState" + ${Else} + StrCpy $DesktopConsoleState ${BST_UNCHECKED} + ${EndIf} - ; check if the user asked to have console launched every startup - ${NSD_GetState} $ConsoleStartupCheckbox $ConsoleStartupState - ${LogText} "Option: Start Desktop Console On Startup: $ConsoleStartupState" + ; FIXME: Re-enable or permanently remove system tray "Console" for Interface-only installs. + ;; check if the user asked to have console launched every startup + ;${NSD_GetState} $ConsoleStartupCheckbox $ConsoleStartupState + ;${LogText} "Option: Start Desktop Console On Startup: $ConsoleStartupState" + ${If} @SERVER_COMPONENT_CONDITIONAL@ + ; check if the user asked to have console launched every startup + ${NSD_GetState} $ConsoleStartupCheckbox $ConsoleStartupState + ${LogText} "Option: Start Desktop Console On Startup: $ConsoleStartupState" + ${Else} + StrCpy $ConsoleStartupState ${BST_UNCHECKED} + ${EndIf} ${If} @SERVER_COMPONENT_CONDITIONAL@ ${LogText} "Option: Install Server" @@ -1308,10 +1355,13 @@ Section "-Core installation" ${Else} ; handling for interface only console shortcut Delete "$SMPROGRAMS\$STARTMENU_FOLDER\@SANDBOX_HF_SHORTCUT_NAME@.lnk" - CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\@CONSOLE_SHORTCUT_NAME@.lnk" \ - "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@" - ; Set appUserModelId - ApplicationID::Set "$SMPROGRAMS\$STARTMENU_FOLDER\@CONSOLE_SHORTCUT_NAME@.lnk" "@APP_USER_MODEL_ID@" + + ; FIXME: Re-enable or permanently remove system tray "Console" for Interface-only installs. + ;CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\@CONSOLE_SHORTCUT_NAME@.lnk" \ + ; "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@" + ;; Set appUserModelId + ;ApplicationID::Set "$SMPROGRAMS\$STARTMENU_FOLDER\@CONSOLE_SHORTCUT_NAME@.lnk" "@APP_USER_MODEL_ID@" + ${EndIf} CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\@UNINSTALLER_NAME@" diff --git a/domain-server/resources/metadata_exporter/index.html b/domain-server/resources/metadata_exporter/index.html index a22d50fe22..1b18c508cc 100644 --- a/domain-server/resources/metadata_exporter/index.html +++ b/domain-server/resources/metadata_exporter/index.html @@ -2,7 +2,7 @@ // // index.html // -// Created by kasenvr@gmail.com on 21 Jul 2020 +// Created by somnilibertas@gmail.com on 21 Jul 2020 // Copyright 2020 Vircadia and contributors. // // Distributed under the Apache License, Version 2.0. diff --git a/domain-server/resources/web/assignment/placeholder.js b/domain-server/resources/web/assignment/placeholder.js index 95c9903e32..3666396d6e 100644 --- a/domain-server/resources/web/assignment/placeholder.js +++ b/domain-server/resources/web/assignment/placeholder.js @@ -1,3 +1,3 @@ // Here you can put a script that will be run by an assignment-client (AC) -// For examples, please go to https://github.com/kasenvr/project-athena/tree/master/script-archive/acScripts +// For examples, please go to https://github.com/vircadia/vircadia/tree/master/script-archive/acScripts // The directory named acScripts contains assignment-client specific scripts you can try. diff --git a/hifi_android.py b/hifi_android.py index 06640390d4..07ea00d270 100644 --- a/hifi_android.py +++ b/hifi_android.py @@ -39,15 +39,15 @@ ANDROID_PACKAGES = { 'sharedLibFolder': 'lib', 'includeLibs': ['libnvtt.so', 'libnvmath.so', 'libnvimage.so', 'libnvcore.so'] }, - 'oculus_1.22': { - 'file': 'ovr_sdk_mobile_1.22.zip', - 'checksum': '1ac3c5b0521e5406f287f351015daff8', + 'ovr_sdk_mobile_1.37.0': { + 'file': 'ovr_sdk_mobile_1.37.0.zip', + 'checksum': '6040e1966f335a3e5015295154cd7383', 'sharedLibFolder': 'VrApi/Libs/Android/arm64-v8a/Release', 'includeLibs': ['libvrapi.so'] }, - 'oculusPlatform': { - 'file': 'OVRPlatformSDK_v1.34.0.zip', - 'checksum': '16e4c5f39520f122bc49cb6d5bb88289', + 'ovr_platform_sdk_23.0.0': { + 'file': 'ovr_platform_sdk_23.0.0.zip', + 'checksum': '29d02b560f60d0fa7b8a64cd965dd55b', 'sharedLibFolder': 'Android/libs/arm64-v8a', 'includeLibs': ['libovrplatformloader.so'] }, diff --git a/hifi_qt.py b/hifi_qt.py index 10708e4bc9..48e9b337a6 100644 --- a/hifi_qt.py +++ b/hifi_qt.py @@ -12,7 +12,7 @@ import functools print = functools.partial(print, flush=True) -# Encapsulates the vcpkg system +# Encapsulates the vcpkg system class QtDownloader: CMAKE_TEMPLATE = """ # this file auto-generated by hifi_qt.py @@ -72,7 +72,7 @@ endif() self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-18.04.tar.gz' elif u_major == 19 and u_minor == 10: self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.12.6-ubuntu-19.10.tar.xz' - elif u_major > 18 and ( u_major != 19 and u_minor != 4): + elif u_major > 19: print("We don't support " + distro.name(pretty=True) + " yet. Perhaps consider helping us out?") raise Exception('LINUX DISTRO IS NOT SUPPORTED YET!!!') else: @@ -81,7 +81,7 @@ endif() else: print("Sorry, " + distro.name(pretty=True) + " is not supported. Please consider helping us out.") print("It's also possible to build Qt for your distribution, please see the documentation at:") - print("https://github.com/kasenvr/project-athena/tree/kasen/core/tools/qt-builder") + print("https://github.com/vircadia/vircadia/tree/master/tools/qt-builder") raise Exception('UNKNOWN LINUX VERSION!!!') else: print("System : " + platform.system()) diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index 9a9252112c..971fb06414 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -309,8 +309,8 @@ FocusScope { if (child.hasOwnProperty("modality")) { var mappedPoint = mapToItem(child, point.x, point.y); if (child.hasOwnProperty("frame")) { - var outLine = child.frame.children[2]; - var framePoint = outLine.mapFromGlobal(point.x, point.y); + var outLine = child.frame.children[2]; // sizeOutline + var framePoint = mapToItem(outLine, point.x, point.y); if (outLine.contains(framePoint)) { return true; } diff --git a/interface/resources/qml/hifi/dialogs/TabletAboutDialog.qml b/interface/resources/qml/hifi/dialogs/TabletAboutDialog.qml index a943da32a0..f7a4061f45 100644 --- a/interface/resources/qml/hifi/dialogs/TabletAboutDialog.qml +++ b/interface/resources/qml/hifi/dialogs/TabletAboutDialog.qml @@ -54,10 +54,10 @@ Rectangle { textFormat: Text.StyledText linkColor: "#00B4EF" color: "white" - text: "Vircadia Github." + text: "Vircadia Github." size: 20 onLinkActivated: { - About.openUrl("https:/github.com/kasenvr/project-athena"); + About.openUrl("https:/github.com/vircadia/vircadia"); } } diff --git a/interface/resources/qml/hifi/dialogs/security/EntityScriptQMLWhitelist.qml b/interface/resources/qml/hifi/dialogs/security/EntityScriptQMLWhitelist.qml index 9e0b6ba4cf..8180475527 100644 --- a/interface/resources/qml/hifi/dialogs/security/EntityScriptQMLWhitelist.qml +++ b/interface/resources/qml/hifi/dialogs/security/EntityScriptQMLWhitelist.qml @@ -2,8 +2,8 @@ // EntityScriptQMLWhitelist.qml // interface/resources/qml/hifi/dialogs/security // -// Created by Kasen IO on 2019.12.05 | realities.dev | kasenvr@gmail.com -// Copyright 2019 Kasen IO +// Created by Kalila L. on 2019.12.05 | realities.dev | somnilibertas@gmail.com +// Copyright 2019 Kalila L. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/interface/resources/qml/hifi/dialogs/security/Security.qml b/interface/resources/qml/hifi/dialogs/security/Security.qml index 918a0a2ca6..b109f83a23 100644 --- a/interface/resources/qml/hifi/dialogs/security/Security.qml +++ b/interface/resources/qml/hifi/dialogs/security/Security.qml @@ -314,7 +314,7 @@ Rectangle { onClicked: { lightboxPopup.titleText = "Script Plugin Infrastructure"; lightboxPopup.bodyText = "Toggles the activation of scripting plugins in the 'plugins/scripting' folder. \n\n" - + "Created by:\n humbletim@gmail.com\n kasenvr@gmail.com"; + + "Created by:\n humbletim@gmail.com\n somnilibertas@gmail.com"; lightboxPopup.button1text = "OK"; lightboxPopup.button1method = function() { lightboxPopup.visible = false; diff --git a/interface/resources/qml/windows/Frame.qml b/interface/resources/qml/windows/Frame.qml index 7b0fbf8d8c..cfff40bbf6 100644 --- a/interface/resources/qml/windows/Frame.qml +++ b/interface/resources/qml/windows/Frame.qml @@ -27,7 +27,6 @@ Item { readonly property int frameMarginRight: frame.decoration ? frame.decoration.frameMarginRight : 0 readonly property int frameMarginTop: frame.decoration ? frame.decoration.frameMarginTop : 0 readonly property int frameMarginBottom: frame.decoration ? frame.decoration.frameMarginBottom : 0 - readonly property int offsetCorrection: 20 // Frames always fill their parents, but their decorations may extend // beyond the window via negative margin sizes @@ -76,7 +75,7 @@ Item { Rectangle { id: sizeOutline x: -frameMarginLeft - y: -frameMarginTop - offsetCorrection + y: -frameMarginTop width: window ? window.width + frameMarginLeft + frameMarginRight + 2 : 0 height: window ? window.height + frameMarginTop + frameMarginBottom + 2 : 0 color: hifi.colors.baseGrayHighlight15 diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c1f972eb30..cc46d8591b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -8712,7 +8712,7 @@ void Application::notifyPacketVersionMismatch() { } void Application::checkSkeleton() const { - if (getMyAvatar()->getSkeletonModel()->isActive() && !getMyAvatar()->getSkeletonModel()->hasSkeleton()) { + if (getMyAvatar()->getSkeletonModel()->isLoaded() && !getMyAvatar()->getSkeletonModel()->hasSkeleton()) { qCDebug(interfaceapp) << "MyAvatar model has no skeleton"; QString message = "Your selected avatar body has no skeleton.\n\nThe default body will be loaded..."; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index c14d22bdbb..d190e3f3da 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -89,6 +89,7 @@ int main(int argc, const char* argv[]) { QCommandLineOption displayNameOption("displayName", "set user display name ", "string"); QCommandLineOption setBookmarkOption("setBookmark", "set bookmark key=value pair", "string"); QCommandLineOption defaultScriptOverrideOption("defaultScriptsOverride", "override defaultsScripts.js", "string"); + QCommandLineOption forceCrashReportingOption("forceCrashReporting", "Force crash reporting to initialize"); parser.addOption(urlOption); parser.addOption(noLauncherOption); @@ -103,6 +104,7 @@ int main(int argc, const char* argv[]) { parser.addOption(displayNameOption); parser.addOption(setBookmarkOption); parser.addOption(defaultScriptOverrideOption); + parser.addOption(forceCrashReportingOption); if (!parser.parse(arguments)) { std::cout << parser.errorText().toStdString() << std::endl; // Avoid Qt log spam @@ -218,8 +220,9 @@ int main(int argc, const char* argv[]) { } qDebug() << "UserActivityLogger is enabled:" << ual.isEnabled(); - qDebug() << "Crash handler logger is enabled:" << ual.isCrashMonitorEnabled(); - if (ual.isCrashMonitorEnabled()) { + bool isCrashHandlerEnabled = ual.isCrashMonitorEnabled() || parser.isSet(forceCrashReportingOption); + qDebug() << "Crash handler logger is enabled:" << isCrashHandlerEnabled; + if (isCrashHandlerEnabled) { auto crashHandlerStarted = startCrashHandler(argv[0]); qDebug() << "Crash handler started:" << crashHandlerStarted; } diff --git a/interface/src/ui/OverlayConductor.cpp b/interface/src/ui/OverlayConductor.cpp index 8edd8ee3a5..557b4d09bf 100644 --- a/interface/src/ui/OverlayConductor.cpp +++ b/interface/src/ui/OverlayConductor.cpp @@ -23,7 +23,7 @@ OverlayConductor::OverlayConductor() { OverlayConductor::~OverlayConductor() { } -bool OverlayConductor::headOutsideOverlay() const { +bool OverlayConductor::headNotCenteredInOverlay() const { glm::mat4 hmdMat = qApp->getHMDSensorPose(); glm::vec3 hmdPos = extractTranslation(hmdMat); glm::vec3 hmdForward = transformVectorFast(hmdMat, glm::vec3(0.0f, 0.0f, -1.0f)); @@ -32,8 +32,8 @@ bool OverlayConductor::headOutsideOverlay() const { glm::vec3 uiPos = uiTransform.getTranslation(); glm::vec3 uiForward = uiTransform.getRotation() * glm::vec3(0.0f, 0.0f, -1.0f); - const float MAX_COMPOSITOR_DISTANCE = 0.99f; // If you're 1m from center of ui sphere, you're at the surface. - const float MAX_COMPOSITOR_ANGLE = 180.0f; // rotation check is effectively disabled + const float MAX_COMPOSITOR_DISTANCE = 0.33f; + const float MAX_COMPOSITOR_ANGLE = 90.0f; if (glm::distance(uiPos, hmdPos) > MAX_COMPOSITOR_DISTANCE || glm::dot(uiForward, hmdForward) < cosf(glm::radians(MAX_COMPOSITOR_ANGLE))) { return true; @@ -70,6 +70,8 @@ bool OverlayConductor::updateAvatarIsAtRest() { void OverlayConductor::centerUI() { // place the overlay at the current hmd position in sensor space auto camMat = cancelOutRollAndPitch(qApp->getHMDSensorPose()); + // Set its radius. + camMat = glm::scale(camMat, glm::vec3(HUD_RADIUS)); qApp->getApplicationCompositor().setModelTransform(Transform(camMat)); } @@ -83,7 +85,6 @@ void OverlayConductor::update(float dt) { if (!desktop) { return; } - bool currentVisible = !desktop->property("pinned").toBool(); auto myAvatar = DependencyManager::get()->getMyAvatar(); // centerUI when hmd mode is first enabled and mounted @@ -96,24 +97,24 @@ void OverlayConductor::update(float dt) { _hmdMode = false; } - bool shouldRecenter = false; - - if (_suppressedByHead) { - if (updateAvatarIsAtRest()) { - _suppressedByHead = false; - shouldRecenter = true; - } - } else { - if (_hmdMode && headOutsideOverlay()) { - _suppressedByHead = true; - } + bool initiateRecenter = false; + if (_hmdMode && headNotCenteredInOverlay()) { + initiateRecenter = true; } + bool shouldRecenter = false; + if (initiateRecenter || _suppressedByHead) { + _suppressedByHead = !updateAvatarIsAtRest(); + shouldRecenter = !_suppressedByHead; + } + + bool currentVisible = !desktop->property("pinned").toBool(); bool targetVisible = Menu::getInstance()->isOptionChecked(MenuOption::Overlays) && !_suppressedByHead; if (targetVisible != currentVisible) { offscreenUi->setPinned(!targetVisible); } - if (shouldRecenter && !_suppressedByHead) { + + if (shouldRecenter) { centerUI(); } #endif diff --git a/interface/src/ui/OverlayConductor.h b/interface/src/ui/OverlayConductor.h index 6c3732cf3c..7e7cf5bd3c 100644 --- a/interface/src/ui/OverlayConductor.h +++ b/interface/src/ui/OverlayConductor.h @@ -22,7 +22,7 @@ public: void centerUI(); private: - bool headOutsideOverlay() const; + bool headNotCenteredInOverlay() const; bool updateAvatarIsAtRest(); #if !defined(DISABLE_QML) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 16dc99ab49..d859454a99 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -1246,7 +1246,7 @@ glm::quat Avatar::getAbsoluteJointRotationInObjectFrame(int index) const { } case CAMERA_MATRIX_INDEX: { glm::quat rotation; - if (_skeletonModel && _skeletonModel->isActive()) { + if (_skeletonModel && _skeletonModel->isLoaded()) { int headJointIndex = getJointIndex("Head"); if (headJointIndex >= 0) { _skeletonModel->getAbsoluteJointRotationInRigFrame(headJointIndex, rotation); @@ -1298,7 +1298,7 @@ glm::vec3 Avatar::getAbsoluteJointTranslationInObjectFrame(int index) const { } case CAMERA_MATRIX_INDEX: { glm::vec3 translation; - if (_skeletonModel && _skeletonModel->isActive()) { + if (_skeletonModel && _skeletonModel->isLoaded()) { int headJointIndex = getJointIndex("Head"); if (headJointIndex >= 0) { _skeletonModel->getAbsoluteJointTranslationInRigFrame(headJointIndex, translation); @@ -1427,7 +1427,7 @@ void Avatar::withValidJointIndicesCache(std::function const& worker) con QWriteLocker writeLock(&_modelJointIndicesCacheLock); if (!_modelJointsCached) { _modelJointIndicesCache.clear(); - if (_skeletonModel && _skeletonModel->isActive()) { + if (_skeletonModel && _skeletonModel->isLoaded()) { _modelJointIndicesCache = _skeletonModel->getHFMModel().jointIndices; _modelJointsCached = true; } diff --git a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp index ccc87c28f3..4950b86f75 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp @@ -176,7 +176,7 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { updateRenderItems(); } - if (!isActive() || !_owningAvatar->isMyAvatar()) { + if (!isLoaded() || !_owningAvatar->isMyAvatar()) { return; // only simulate for own avatar } @@ -255,19 +255,19 @@ bool SkeletonModel::getRightHandPosition(glm::vec3& position) const { } bool SkeletonModel::getHeadPosition(glm::vec3& headPosition) const { - return isActive() && getJointPositionInWorldFrame(_rig.indexOfJoint("Head"), headPosition); + return isLoaded() && getJointPositionInWorldFrame(_rig.indexOfJoint("Head"), headPosition); } bool SkeletonModel::getNeckPosition(glm::vec3& neckPosition) const { - return isActive() && getJointPositionInWorldFrame(_rig.indexOfJoint("Neck"), neckPosition); + return isLoaded() && getJointPositionInWorldFrame(_rig.indexOfJoint("Neck"), neckPosition); } bool SkeletonModel::getLocalNeckPosition(glm::vec3& neckPosition) const { - return isActive() && getJointPosition(_rig.indexOfJoint("Neck"), neckPosition); + return isLoaded() && getJointPosition(_rig.indexOfJoint("Neck"), neckPosition); } bool SkeletonModel::getEyeModelPositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const { - if (!isActive()) { + if (!isLoaded()) { return false; } @@ -361,7 +361,7 @@ void SkeletonModel::renderBoundingCollisionShapes(RenderArgs* args, gpu::Batch& } bool SkeletonModel::hasSkeleton() { - return isActive() ? _rig.indexOfJoint("Hips") != -1 : false; + return isLoaded() ? _rig.indexOfJoint("Hips") != -1 : false; } void SkeletonModel::onInvalidate() { diff --git a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.h b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.h index 6b0bd79f0b..e24d969461 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.h +++ b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.h @@ -44,10 +44,10 @@ public: bool getIsJointOverridden(int jointIndex) const; /// Returns the index of the left hand joint, or -1 if not found. - int getLeftHandJointIndex() const { return isActive() ? _rig.indexOfJoint("LeftHand") : -1; } + int getLeftHandJointIndex() const { return isLoaded() ? _rig.indexOfJoint("LeftHand") : -1; } /// Returns the index of the right hand joint, or -1 if not found. - int getRightHandJointIndex() const { return isActive() ? _rig.indexOfJoint("RightHand") : -1; } + int getRightHandJointIndex() const { return isLoaded() ? _rig.indexOfJoint("RightHand") : -1; } bool getLeftGrabPosition(glm::vec3& position) const; bool getRightGrabPosition(glm::vec3& position) const; diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp index 9b6946bbcc..c645c39eb4 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp @@ -41,10 +41,10 @@ static const float reticleSize = TWO_PI / 100.0f; //EntityItemID CompositorHelper::_noItemId; static QString _tooltipId; -const uvec2 CompositorHelper::VIRTUAL_SCREEN_SIZE = uvec2(3960, 1188); // ~10% more pixel density than old version, 72dx240d FOV -const QRect CompositorHelper::VIRTUAL_SCREEN_RECOMMENDED_OVERLAY_RECT = QRect(956, 0, 2048, 1188); // don't include entire width only center 2048 +const uvec2 CompositorHelper::VIRTUAL_SCREEN_SIZE = uvec2(2640, 1188); +const QRect CompositorHelper::VIRTUAL_SCREEN_RECOMMENDED_OVERLAY_RECT = QRect(296, 0, 2048, 1188); // Center 2048 pixels. const float CompositorHelper::VIRTUAL_UI_ASPECT_RATIO = (float)VIRTUAL_SCREEN_SIZE.x / (float)VIRTUAL_SCREEN_SIZE.y; -const vec2 CompositorHelper::VIRTUAL_UI_TARGET_FOV = vec2(PI * 3.0f / 2.0f, PI * 3.0f / 2.0f / VIRTUAL_UI_ASPECT_RATIO); +const vec2 CompositorHelper::VIRTUAL_UI_TARGET_FOV = vec2(PI, PI / VIRTUAL_UI_ASPECT_RATIO); const vec2 CompositorHelper::MOUSE_EXTENTS_ANGULAR_SIZE = vec2(PI * 2.0f, PI * 0.95f); // horizontal: full sphere, vertical: ~5deg from poles const vec2 CompositorHelper::MOUSE_EXTENTS_PIXELS = vec2(VIRTUAL_SCREEN_SIZE) * (MOUSE_EXTENTS_ANGULAR_SIZE / VIRTUAL_UI_TARGET_FOV); @@ -384,9 +384,9 @@ bool CompositorHelper::calculateRayUICollisionPoint(const glm::vec3& position, c glm::vec3 localPosition = transformPoint(worldToUi, position); glm::vec3 localDirection = glm::normalize(transformVectorFast(worldToUi, direction)); - const float UI_RADIUS = 1.0f; + const float UNIT_RADIUS = 1.0f; float intersectionDistance; - if (raySphereIntersect(localDirection, localPosition, UI_RADIUS, &intersectionDistance)) { + if (raySphereIntersect(localDirection, localPosition, UNIT_RADIUS, &intersectionDistance)) { result = transformPoint(uiToWorld, localPosition + localDirection * intersectionDistance); #ifdef WANT_DEBUG DebugDraw::getInstance().drawRay(position, result, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); @@ -407,9 +407,8 @@ bool CompositorHelper::calculateParabolaUICollisionPoint(const glm::vec3& origin glm::vec3 localVelocity = glm::normalize(transformVectorFast(worldToUi, velocity)); glm::vec3 localAcceleration = glm::normalize(transformVectorFast(worldToUi, acceleration)); - const float UI_RADIUS = 1.0f; float intersectionDistance; - if (findParabolaSphereIntersection(localOrigin, localVelocity, localAcceleration, glm::vec3(0.0f), UI_RADIUS, intersectionDistance)) { + if (findParabolaSphereIntersection(localOrigin, localVelocity, localAcceleration, glm::vec3(0.0f), HUD_RADIUS, intersectionDistance)) { result = origin + velocity * intersectionDistance + 0.5f * acceleration * intersectionDistance * intersectionDistance; parabolicDistance = intersectionDistance; return true; diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.h b/libraries/display-plugins/src/display-plugins/CompositorHelper.h index c45119fd63..b44d6ffbd9 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.h +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.h @@ -27,7 +27,8 @@ class ReticleInterface; -const float DEFAULT_RETICLE_DEPTH = 1.0f; // FIXME - probably should be based on UI radius +const float HUD_RADIUS = 1.5f; +const float DEFAULT_RETICLE_DEPTH = HUD_RADIUS; const float MAGNIFY_WIDTH = 220.0f; const float MAGNIFY_HEIGHT = 100.0f; @@ -154,7 +155,7 @@ private: std::unique_ptr _alphaPropertyAnimation; std::atomic _reticleVisible { true }; - std::atomic _reticleDepth { 1.0f }; + std::atomic _reticleDepth { DEFAULT_RETICLE_DEPTH }; // NOTE: when the compositor is running in HMD mode, it will control the reticle position as a custom // application specific position, when it's in desktop mode, the reticle position will simply move diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 807a240763..b116423b75 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -431,13 +431,13 @@ void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transa _visible = entity->getVisible(); setIsVisibleInSecondaryCamera(entity->isVisibleInSecondaryCamera()); setRenderLayer(entity->getRenderLayer()); - setPrimitiveMode(entity->getPrimitiveMode()); + _primitiveMode = entity->getPrimitiveMode(); _canCastShadow = entity->getCanCastShadow(); setCullWithParent(entity->getCullWithParent()); _cauterized = entity->getCauterized(); if (entity->needsZoneOcclusionUpdate()) { entity->resetNeedsZoneOcclusionUpdate(); - setRenderWithZones(entity->getRenderWithZones()); + _renderWithZones = entity->getRenderWithZones(); } entity->setNeedsRenderUpdate(false); }); @@ -469,11 +469,13 @@ void EntityRenderer::onRemoveFromScene(const EntityItemPointer& entity) { void EntityRenderer::addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) { std::lock_guard lock(_materialsLock); _materials[parentMaterialName].push(material); + emit requestRenderUpdate(); } void EntityRenderer::removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) { std::lock_guard lock(_materialsLock); _materials[parentMaterialName].remove(material); + emit requestRenderUpdate(); } glm::vec4 EntityRenderer::calculatePulseColor(const glm::vec4& color, const PulsePropertyGroup& pulseProperties, quint64 start) { diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index 69fb9aca23..ca3e024338 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -108,18 +108,7 @@ protected: virtual void setIsVisibleInSecondaryCamera(bool value) { _isVisibleInSecondaryCamera = value; } virtual void setRenderLayer(RenderLayer value) { _renderLayer = value; } - virtual void setPrimitiveMode(PrimitiveMode value) { _primitiveMode = value; } virtual void setCullWithParent(bool value) { _cullWithParent = value; } - virtual void setRenderWithZones(const QVector& renderWithZones) { _renderWithZones = renderWithZones; } - - template - T withReadLockResult(const std::function& f) { - T result; - withReadLock([&] { - result = f(); - }); - return result; - } signals: void requestRenderUpdate(); diff --git a/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp b/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp index 7a36ae2707..6928454eb0 100644 --- a/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp @@ -52,14 +52,11 @@ void GizmoEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce void GizmoEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { bool dirty = false; RingGizmoPropertyGroup ringProperties = entity->getRingProperties(); - withWriteLock([&] { - _gizmoType = entity->getGizmoType(); - if (_ringProperties != ringProperties) { - _ringProperties = ringProperties; - dirty = true; - - } - }); + _gizmoType = entity->getGizmoType(); + if (_ringProperties != ringProperties) { + _ringProperties = ringProperties; + dirty = true; + } if (dirty || _prevPrimitiveMode != _primitiveMode || !_ringGeometryID || !_majorTicksGeometryID || !_minorTicksGeometryID) { _prevPrimitiveMode = _primitiveMode; @@ -242,19 +239,20 @@ void GizmoEntityRenderer::doRender(RenderArgs* args) { if (_gizmoType == GizmoType::RING) { Transform transform; - bool hasTickMarks; - glm::vec4 tickProperties; + bool hasTickMarks = _ringProperties.getHasTickMarks(); + glm::vec4 tickProperties = glm::vec4(_ringProperties.getMajorTickMarksAngle(), _ringProperties.getMajorTickMarksLength(), + _ringProperties.getMinorTickMarksAngle(), _ringProperties.getMinorTickMarksLength()); bool forward; + bool wireframe; + bool transparent; withReadLock([&] { transform = _renderTransform; - hasTickMarks = _ringProperties.getHasTickMarks(); - tickProperties = glm::vec4(_ringProperties.getMajorTickMarksAngle(), _ringProperties.getMajorTickMarksLength(), - _ringProperties.getMinorTickMarksAngle(), _ringProperties.getMinorTickMarksLength()); + transparent = isTransparent(); + wireframe = render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES; forward = _renderLayer != RenderLayer::WORLD || args->_renderMethod == Args::RenderMethod::FORWARD; }); - bool wireframe = render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES; - geometryCache->bindSimpleProgram(batch, false, isTransparent(), wireframe, true, true, forward, graphics::MaterialKey::CULL_NONE); + geometryCache->bindSimpleProgram(batch, false, transparent, wireframe, true, true, forward, graphics::MaterialKey::CULL_NONE); batch.setModelTransform(transform); diff --git a/libraries/entities-renderer/src/RenderableGridEntityItem.cpp b/libraries/entities-renderer/src/RenderableGridEntityItem.cpp index 52900d0798..35702c63e4 100644 --- a/libraries/entities-renderer/src/RenderableGridEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableGridEntityItem.cpp @@ -30,16 +30,6 @@ bool GridEntityRenderer::isTransparent() const { } void GridEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { - withWriteLock([&] { - _color = entity->getColor(); - _alpha = entity->getAlpha(); - _pulseProperties = entity->getPulseProperties(); - - _followCamera = entity->getFollowCamera(); - _majorGridEvery = entity->getMajorGridEvery(); - _minorGridEvery = entity->getMinorGridEvery(); - }); - void* key = (void*)this; AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] { withWriteLock([&] { @@ -49,6 +39,16 @@ void GridEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen }); } +void GridEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { + _color = entity->getColor(); + _alpha = entity->getAlpha(); + _pulseProperties = entity->getPulseProperties(); + + _followCamera = entity->getFollowCamera(); + _majorGridEvery = entity->getMajorGridEvery(); + _minorGridEvery = entity->getMinorGridEvery(); +} + Item::Bound GridEntityRenderer::getBound() { if (_followCamera) { // This is a UI element that should always be in view, lie to the octree to avoid culling @@ -73,13 +73,12 @@ ShapeKey GridEntityRenderer::getShapeKey() { } void GridEntityRenderer::doRender(RenderArgs* args) { - glm::vec4 color; + glm::vec4 color = glm::vec4(toGlm(_color), _alpha); + color = EntityRenderer::calculatePulseColor(color, _pulseProperties, _created); glm::vec3 dimensions; Transform renderTransform; bool forward; withReadLock([&] { - color = glm::vec4(toGlm(_color), _alpha); - color = EntityRenderer::calculatePulseColor(color, _pulseProperties, _created); dimensions = _dimensions; renderTransform = _renderTransform; forward = _renderLayer != RenderLayer::WORLD || args->_renderMethod == Args::RenderMethod::FORWARD; diff --git a/libraries/entities-renderer/src/RenderableGridEntityItem.h b/libraries/entities-renderer/src/RenderableGridEntityItem.h index 2ecff01d01..1958d17136 100644 --- a/libraries/entities-renderer/src/RenderableGridEntityItem.h +++ b/libraries/entities-renderer/src/RenderableGridEntityItem.h @@ -30,10 +30,11 @@ protected: private: virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; + virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; virtual void doRender(RenderArgs* args) override; glm::u8vec3 _color; - float _alpha; + float _alpha { NAN }; PulsePropertyGroup _pulseProperties; bool _followCamera; diff --git a/libraries/entities-renderer/src/RenderableImageEntityItem.cpp b/libraries/entities-renderer/src/RenderableImageEntityItem.cpp index 4d19a83ae6..b9b30ea9c7 100644 --- a/libraries/entities-renderer/src/RenderableImageEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableImageEntityItem.cpp @@ -29,44 +29,7 @@ bool ImageEntityRenderer::isTransparent() const { return Parent::isTransparent() || (_textureIsLoaded && _texture->getGPUTexture() && _texture->getGPUTexture()->getUsage().isAlpha()) || _alpha < 1.0f || _pulseProperties.getAlphaMode() != PulseMode::NONE; } -bool ImageEntityRenderer::needsRenderUpdate() const { - if (resultWithReadLock([&] { - return !_textureIsLoaded; - })) { - return true; - } - - return Parent::needsRenderUpdate(); -} - void ImageEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { - withWriteLock([&] { - auto imageURL = entity->getImageURL(); - if (_imageURL != imageURL) { - _imageURL = imageURL; - if (imageURL.isEmpty()) { - _texture.reset(); - } else { - _texture = DependencyManager::get()->getTexture(_imageURL); - } - _textureIsLoaded = false; - } - - _emissive = entity->getEmissive(); - _keepAspectRatio = entity->getKeepAspectRatio(); - _subImage = entity->getSubImage(); - - _color = entity->getColor(); - _alpha = entity->getAlpha(); - _pulseProperties = entity->getPulseProperties(); - _billboardMode = entity->getBillboardMode(); - - if (!_textureIsLoaded) { - emit requestRenderUpdate(); - } - _textureIsLoaded = _texture && (_texture->isLoaded() || _texture->isFailed()); - }); - void* key = (void*)this; AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] { withWriteLock([&] { @@ -76,6 +39,33 @@ void ImageEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce }); } +void ImageEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { + auto imageURL = entity->getImageURL(); + if (_imageURL != imageURL) { + _imageURL = imageURL; + if (imageURL.isEmpty()) { + _texture.reset(); + } else { + _texture = DependencyManager::get()->getTexture(_imageURL); + } + _textureIsLoaded = false; + } + + _emissive = entity->getEmissive(); + _keepAspectRatio = entity->getKeepAspectRatio(); + _subImage = entity->getSubImage(); + + _color = entity->getColor(); + _alpha = entity->getAlpha(); + _pulseProperties = entity->getPulseProperties(); + _billboardMode = entity->getBillboardMode(); + + if (!_textureIsLoaded) { + emit requestRenderUpdate(); + } + _textureIsLoaded = _texture && (_texture->isLoaded() || _texture->isFailed()); +} + Item::Bound ImageEntityRenderer::getBound() { auto bound = Parent::getBound(); if (_billboardMode != BillboardMode::NONE) { @@ -93,33 +83,26 @@ ShapeKey ImageEntityRenderer::getShapeKey() { builder.withTranslucent(); } - withReadLock([&] { - if (_emissive) { - builder.withUnlit(); - } + if (_emissive) { + builder.withUnlit(); + } - if (_primitiveMode == PrimitiveMode::LINES) { - builder.withWireframe(); - } - }); + if (_primitiveMode == PrimitiveMode::LINES) { + builder.withWireframe(); + } return builder.build(); } void ImageEntityRenderer::doRender(RenderArgs* args) { - NetworkTexturePointer texture; - QRect subImage; - glm::vec4 color; + glm::vec4 color = glm::vec4(toGlm(_color), _alpha); + color = EntityRenderer::calculatePulseColor(color, _pulseProperties, _created); Transform transform; withReadLock([&] { - texture = _texture; - subImage = _subImage; - color = glm::vec4(toGlm(_color), _alpha); - color = EntityRenderer::calculatePulseColor(color, _pulseProperties, _created); transform = _renderTransform; }); - if (!_visible || !texture || !texture->isLoaded() || color.a == 0.0f) { + if (!_visible || !_texture || !_texture->isLoaded() || color.a == 0.0f) { return; } @@ -129,28 +112,28 @@ void ImageEntityRenderer::doRender(RenderArgs* args) { transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->getViewFrustum().getPosition())); batch->setModelTransform(transform); - batch->setResourceTexture(0, texture->getGPUTexture()); + batch->setResourceTexture(0, _texture->getGPUTexture()); - float imageWidth = texture->getWidth(); - float imageHeight = texture->getHeight(); + float imageWidth = _texture->getWidth(); + float imageHeight = _texture->getHeight(); QRect fromImage; - if (subImage.width() <= 0) { + if (_subImage.width() <= 0) { fromImage.setX(0); fromImage.setWidth(imageWidth); } else { - float scaleX = imageWidth / texture->getOriginalWidth(); - fromImage.setX(scaleX * subImage.x()); - fromImage.setWidth(scaleX * subImage.width()); + float scaleX = imageWidth / _texture->getOriginalWidth(); + fromImage.setX(scaleX * _subImage.x()); + fromImage.setWidth(scaleX * _subImage.width()); } - if (subImage.height() <= 0) { + if (_subImage.height() <= 0) { fromImage.setY(0); fromImage.setHeight(imageHeight); } else { - float scaleY = imageHeight / texture->getOriginalHeight(); - fromImage.setY(scaleY * subImage.y()); - fromImage.setHeight(scaleY * subImage.height()); + float scaleY = imageHeight / _texture->getOriginalHeight(); + fromImage.setY(scaleY * _subImage.y()); + fromImage.setHeight(scaleY * _subImage.height()); } float maxSize = glm::max(fromImage.width(), fromImage.height()); diff --git a/libraries/entities-renderer/src/RenderableImageEntityItem.h b/libraries/entities-renderer/src/RenderableImageEntityItem.h index d73bc9bc05..35d60a230f 100644 --- a/libraries/entities-renderer/src/RenderableImageEntityItem.h +++ b/libraries/entities-renderer/src/RenderableImageEntityItem.h @@ -29,8 +29,8 @@ protected: bool isTransparent() const override; private: - virtual bool needsRenderUpdate() const override; virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; + virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; virtual void doRender(RenderArgs* args) override; QString _imageURL; diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index c1b024a478..3d2e59518c 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -16,197 +16,177 @@ using namespace render; using namespace render::entities; -bool MaterialEntityRenderer::needsRenderUpdate() const { - if (_retryApply) { - return true; - } - if (!_texturesLoaded) { - return true; - } - return Parent::needsRenderUpdate(); -} - -bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { - if (resultWithReadLock([&] { - if (entity->getTransform() != _transform) { - return true; - } - if (entity->getUnscaledDimensions() != _dimensions) { - return true; - } - if (entity->getParentID() != _parentID) { - return true; - } - - return false; - })) { - return true; - } - return false; +void MaterialEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { + void* key = (void*)this; + AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] { + withWriteLock([&] { + _renderTransform = getModelTransform(); + // Material entities should fit inside a cube entity of the same size, so a sphere that has dimensions 1x1x1 + // is a half unit sphere. However, the geometry cache renders a UNIT sphere, so we need to scale down. + const float MATERIAL_ENTITY_SCALE = 0.5f; + _renderTransform.postScale(MATERIAL_ENTITY_SCALE); + _renderTransform.postScale(ENTITY_ITEM_DEFAULT_DIMENSIONS); + }); + }); } void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { - withWriteLock([&] { - bool deleteNeeded = false; - bool addNeeded = _retryApply; - bool transformChanged = false; - { - MaterialMappingMode mode = entity->getMaterialMappingMode(); - if (mode != _materialMappingMode) { - _materialMappingMode = mode; - transformChanged = true; - } + bool deleteNeeded = false; + bool addNeeded = _retryApply; + bool transformChanged = false; + { + MaterialMappingMode mode = entity->getMaterialMappingMode(); + if (mode != _materialMappingMode) { + _materialMappingMode = mode; + transformChanged = true; } - { - bool repeat = entity->getMaterialRepeat(); - if (repeat != _materialRepeat) { - _materialRepeat = repeat; - transformChanged = true; - } + } + { + bool repeat = entity->getMaterialRepeat(); + if (repeat != _materialRepeat) { + _materialRepeat = repeat; + transformChanged = true; } - { - glm::vec2 mappingPos = entity->getMaterialMappingPos(); - glm::vec2 mappingScale = entity->getMaterialMappingScale(); - float mappingRot = entity->getMaterialMappingRot(); - if (mappingPos != _materialMappingPos || mappingScale != _materialMappingScale || mappingRot != _materialMappingRot) { - _materialMappingPos = mappingPos; - _materialMappingScale = mappingScale; - _materialMappingRot = mappingRot; - transformChanged |= _materialMappingMode == MaterialMappingMode::UV; - } + } + { + glm::vec2 mappingPos = entity->getMaterialMappingPos(); + glm::vec2 mappingScale = entity->getMaterialMappingScale(); + float mappingRot = entity->getMaterialMappingRot(); + if (mappingPos != _materialMappingPos || mappingScale != _materialMappingScale || mappingRot != _materialMappingRot) { + _materialMappingPos = mappingPos; + _materialMappingScale = mappingScale; + _materialMappingRot = mappingRot; + transformChanged |= _materialMappingMode == MaterialMappingMode::UV; } - { - Transform transform = entity->getTransform(); - glm::vec3 dimensions = entity->getUnscaledDimensions(); - if (transform != _transform || dimensions != _dimensions) { - _transform = transform; - _dimensions = dimensions; - transformChanged |= _materialMappingMode == MaterialMappingMode::PROJECTED; - } + } + { + Transform transform = entity->getTransform(); + glm::vec3 dimensions = entity->getUnscaledDimensions(); + if (transform != _transform || dimensions != _dimensions) { + _transform = transform; + _dimensions = dimensions; + transformChanged |= _materialMappingMode == MaterialMappingMode::PROJECTED; } + } - { - auto material = getMaterial(); - // Update the old material regardless of if it's going to change - if (transformChanged && material && !_parentID.isNull()) { - deleteNeeded = true; - addNeeded = true; - applyTextureTransform(material); - } + { + auto material = getMaterial(); + // Update the old material regardless of if it's going to change + if (transformChanged && material && !_parentID.isNull()) { + deleteNeeded = true; + addNeeded = true; + applyTextureTransform(material); } + } - bool urlChanged = false; - std::string newCurrentMaterialName = _currentMaterialName; - { - QString materialURL = entity->getMaterialURL(); - if (materialURL != _materialURL) { - _materialURL = materialURL; - if (_materialURL.contains("#")) { - auto split = _materialURL.split("#"); - newCurrentMaterialName = split.last().toStdString(); - } else if (_materialURL.contains("?")) { - qDebug() << "DEPRECATED: Use # instead of ? for material URLS:" << _materialURL; - auto split = _materialURL.split("?"); - newCurrentMaterialName = split.last().toStdString(); - } - urlChanged = true; + bool urlChanged = false; + std::string newCurrentMaterialName = _currentMaterialName; + { + QString materialURL = entity->getMaterialURL(); + if (materialURL != _materialURL) { + _materialURL = materialURL; + if (_materialURL.contains("#")) { + auto split = _materialURL.split("#"); + newCurrentMaterialName = split.last().toStdString(); + } else if (_materialURL.contains("?")) { + qDebug() << "DEPRECATED: Use # instead of ? for material URLS:" << _materialURL; + auto split = _materialURL.split("?"); + newCurrentMaterialName = split.last().toStdString(); } + urlChanged = true; } + } - bool usingMaterialData = _materialURL.startsWith("materialData"); - bool materialDataChanged = false; - QUuid oldParentID = _parentID; - QString oldParentMaterialName = _parentMaterialName; - { - QString materialData = entity->getMaterialData(); - if (materialData != _materialData) { - _materialData = materialData; - if (usingMaterialData) { - materialDataChanged = true; - } + bool usingMaterialData = _materialURL.startsWith("materialData"); + bool materialDataChanged = false; + QUuid oldParentID = _parentID; + QString oldParentMaterialName = _parentMaterialName; + { + QString materialData = entity->getMaterialData(); + if (materialData != _materialData) { + _materialData = materialData; + if (usingMaterialData) { + materialDataChanged = true; } } - { - QString parentMaterialName = entity->getParentMaterialName(); - if (parentMaterialName != _parentMaterialName) { - _parentMaterialName = parentMaterialName; - deleteNeeded = true; - addNeeded = true; - } + } + { + QString parentMaterialName = entity->getParentMaterialName(); + if (parentMaterialName != _parentMaterialName) { + _parentMaterialName = parentMaterialName; + deleteNeeded = true; + addNeeded = true; } - { - QUuid parentID = entity->getParentID(); - if (parentID != _parentID) { - _parentID = parentID; - deleteNeeded = true; - addNeeded = true; - } + } + { + QUuid parentID = entity->getParentID(); + if (parentID != _parentID) { + _parentID = parentID; + deleteNeeded = true; + addNeeded = true; } - { - quint16 priority = entity->getPriority(); - if (priority != _priority) { - _priority = priority; - deleteNeeded = true; - addNeeded = true; - } + } + { + quint16 priority = entity->getPriority(); + if (priority != _priority) { + _priority = priority; + deleteNeeded = true; + addNeeded = true; } + } - if (urlChanged && !usingMaterialData) { - _networkMaterial = DependencyManager::get()->getMaterial(_materialURL); - auto onMaterialRequestFinished = [this, entity, oldParentID, oldParentMaterialName, newCurrentMaterialName](bool success) { - if (success) { - deleteMaterial(oldParentID, oldParentMaterialName); - _texturesLoaded = false; - _parsedMaterials = _networkMaterial->parsedMaterials; - setCurrentMaterialName(newCurrentMaterialName); - applyMaterial(entity); - } else { - deleteMaterial(oldParentID, oldParentMaterialName); - _retryApply = false; - _texturesLoaded = true; - } - }; - if (_networkMaterial) { - if (_networkMaterial->isLoaded()) { - onMaterialRequestFinished(!_networkMaterial->isFailed()); - } else { - connect(_networkMaterial.data(), &Resource::finished, this, [this, onMaterialRequestFinished](bool success) { - withWriteLock([&] { - onMaterialRequestFinished(success); - }); - }); - } - } - } else if (materialDataChanged && usingMaterialData) { + if (urlChanged && !usingMaterialData) { + _networkMaterial = DependencyManager::get()->getMaterial(_materialURL); + auto onMaterialRequestFinished = [this, entity, oldParentID, oldParentMaterialName, newCurrentMaterialName](bool success) { deleteMaterial(oldParentID, oldParentMaterialName); - _texturesLoaded = false; - _parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(_materialData.toUtf8()), _materialURL); - // Since our material changed, the current name might not be valid anymore, so we need to update - setCurrentMaterialName(newCurrentMaterialName); - applyMaterial(entity); - } else { - if (deleteNeeded) { - deleteMaterial(oldParentID, oldParentMaterialName); - } - if (addNeeded) { + if (success) { + _texturesLoaded = false; + _parsedMaterials = _networkMaterial->parsedMaterials; + setCurrentMaterialName(newCurrentMaterialName); applyMaterial(entity); + emit requestRenderUpdate(); + } else { + _retryApply = false; + _texturesLoaded = true; + } + }; + if (_networkMaterial) { + if (_networkMaterial->isLoaded()) { + onMaterialRequestFinished(!_networkMaterial->isFailed()); + } else { + connect(_networkMaterial.data(), &Resource::finished, this, [this, onMaterialRequestFinished](bool success) { + onMaterialRequestFinished(success); + }); } } - - { - auto material = getMaterial(); - bool newTexturesLoaded = material ? !material->isMissingTexture() : false; - if (!_texturesLoaded && newTexturesLoaded) { - material->checkResetOpacityMap(); - } - _texturesLoaded = newTexturesLoaded; + } else if (materialDataChanged && usingMaterialData) { + deleteMaterial(oldParentID, oldParentMaterialName); + _texturesLoaded = false; + _parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(_materialData.toUtf8()), _materialURL); + // Since our material changed, the current name might not be valid anymore, so we need to update + setCurrentMaterialName(newCurrentMaterialName); + applyMaterial(entity); + } else { + if (deleteNeeded) { + deleteMaterial(oldParentID, oldParentMaterialName); } + if (addNeeded) { + applyMaterial(entity); + } + } - _renderTransform = getModelTransform(); - const float MATERIAL_ENTITY_SCALE = 0.5f; - _renderTransform.postScale(MATERIAL_ENTITY_SCALE); - _renderTransform.postScale(ENTITY_ITEM_DEFAULT_DIMENSIONS); - }); + { + auto material = getMaterial(); + bool newTexturesLoaded = material ? !material->isMissingTexture() : false; + if (!_texturesLoaded && newTexturesLoaded) { + material->checkResetOpacityMap(); + } + _texturesLoaded = newTexturesLoaded; + } + + if (!_texturesLoaded || _retryApply) { + emit requestRenderUpdate(); + } } ItemKey MaterialEntityRenderer::getKey() { @@ -268,33 +248,30 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) { gpu::Batch& batch = *args->_batch; // Don't render if our parent is set or our material is null - QUuid parentID; - withReadLock([&] { - parentID = _parentID; - }); - if (!parentID.isNull()) { + if (!_parentID.isNull()) { return; } - Transform renderTransform; - graphics::MaterialPointer drawMaterial; + graphics::MaterialPointer drawMaterial = getMaterial(); bool proceduralRender = false; Transform textureTransform; + textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0)); + textureTransform.setRotation(glm::vec3(0, 0, glm::radians(_materialMappingRot))); + textureTransform.setScale(glm::vec3(_materialMappingScale, 1)); + + Transform renderTransform; withReadLock([&] { renderTransform = _renderTransform; - drawMaterial = getMaterial(); - textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0)); - textureTransform.setRotation(glm::vec3(0, 0, glm::radians(_materialMappingRot))); - textureTransform.setScale(glm::vec3(_materialMappingScale, 1)); - - if (drawMaterial && drawMaterial->isProcedural() && drawMaterial->isReady()) { - proceduralRender = true; - } }); + if (!drawMaterial) { return; } + if (drawMaterial->isProcedural() && drawMaterial->isReady()) { + proceduralRender = true; + } + batch.setModelTransform(renderTransform); if (!proceduralRender) { diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h index 3a73c988eb..340d169f29 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h @@ -27,8 +27,7 @@ public: ~MaterialEntityRenderer() { deleteMaterial(_parentID, _parentMaterialName); } private: - virtual bool needsRenderUpdate() const override; - virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; + virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; virtual void doRender(RenderArgs* args) override; diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 8c766d0ab8..e13ab6f837 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -51,12 +51,6 @@ ModelPointer ModelEntityWrapper::getModel() const { }); } -bool ModelEntityWrapper::isModelLoaded() const { - return resultWithReadLock([&] { - return _model.operator bool() && _model->isLoaded(); - }); -} - EntityItemPointer RenderableModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { EntityItemPointer entity(new RenderableModelEntityItem(entityID, properties.getDimensionsInitialized()), [](EntityItem* ptr) { ptr->deleteLater(); }); @@ -69,8 +63,7 @@ EntityItemPointer RenderableModelEntityItem::factory(const EntityItemID& entityI RenderableModelEntityItem::RenderableModelEntityItem(const EntityItemID& entityItemID, bool dimensionsInitialized) : ModelEntityWrapper(entityItemID), _dimensionsInitialized(dimensionsInitialized) { - - + } RenderableModelEntityItem::~RenderableModelEntityItem() { } @@ -83,34 +76,6 @@ void RenderableModelEntityItem::setUnscaledDimensions(const glm::vec3& value) { } } -void RenderableModelEntityItem::doInitialModelSimulation() { - DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__); - ModelPointer model = getModel(); - if (!model) { - return; - } - // The machinery for updateModelBounds will give existing models the opportunity to fix their - // translation/rotation/scale/registration. The first two are straightforward, but the latter two have guards to - // make sure they don't happen after they've already been set. Here we reset those guards. This doesn't cause the - // entity values to change -- it just allows the model to match once it comes in. - model->setScaleToFit(false, getScaledDimensions()); - model->setSnapModelToRegistrationPoint(false, getRegistrationPoint()); - - // now recalculate the bounds and registration - model->setScaleToFit(true, getScaledDimensions()); - model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); - model->setRotation(getWorldOrientation()); - model->setTranslation(getWorldPosition()); - - glm::vec3 scale = model->getScale(); - model->setUseDualQuaternionSkinning(!isNonUniformScale(scale)); - - if (_needsInitialSimulation) { - model->simulate(0.0f); - _needsInitialSimulation = false; - } -} - void RenderableModelEntityItem::autoResizeJointArrays() { ModelPointer model = getModel(); if (model && model->isLoaded() && !_needsInitialSimulation) { @@ -125,7 +90,7 @@ bool RenderableModelEntityItem::needsUpdateModelBounds() const { return false; } - if (!_dimensionsInitialized || !model->isActive()) { + if (!_dimensionsInitialized || !model->isLoaded()) { return false; } @@ -182,22 +147,25 @@ void RenderableModelEntityItem::updateModelBounds() { } bool overridingModelTransform = model->isOverridingModelTransformAndOffset(); + glm::vec3 scaledDimensions = getScaledDimensions(); + glm::vec3 registrationPoint = getRegistrationPoint(); if (!overridingModelTransform && - (model->getScaleToFitDimensions() != getScaledDimensions() || - model->getRegistrationPoint() != getRegistrationPoint() || - !model->getIsScaledToFit())) { + (model->getScaleToFitDimensions() != scaledDimensions || + model->getRegistrationPoint() != registrationPoint || + !model->getIsScaledToFit() || _needsToRescaleModel)) { // The machinery for updateModelBounds will give existing models the opportunity to fix their // translation/rotation/scale/registration. The first two are straightforward, but the latter two // have guards to make sure they don't happen after they've already been set. Here we reset those guards. // This doesn't cause the entity values to change -- it just allows the model to match once it comes in. - model->setScaleToFit(false, getScaledDimensions()); - model->setSnapModelToRegistrationPoint(false, getRegistrationPoint()); + model->setScaleToFit(false, scaledDimensions); + model->setSnapModelToRegistrationPoint(false, registrationPoint); // now recalculate the bounds and registration - model->setScaleToFit(true, getScaledDimensions()); - model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); + model->setScaleToFit(true, scaledDimensions); + model->setSnapModelToRegistrationPoint(true, registrationPoint); updateRenderItems = true; model->scaleToFit(); + _needsToRescaleModel = false; } bool success; @@ -221,6 +189,9 @@ void RenderableModelEntityItem::updateModelBounds() { glm::vec3 scale = model->getScale(); model->setUseDualQuaternionSkinning(!isNonUniformScale(scale)); model->updateRenderItems(); + + markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); + locationChanged(); } } @@ -248,8 +219,6 @@ EntityItemProperties RenderableModelEntityItem::getProperties(const EntityProper } } - - return properties; } @@ -261,7 +230,7 @@ bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& ori OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const { auto model = getModel(); - if (!model || !isModelLoaded()) { + if (!model || !model->isLoaded()) { return false; } @@ -273,7 +242,7 @@ bool RenderableModelEntityItem::findDetailedParabolaIntersection(const glm::vec3 const glm::vec3& acceleration, OctreeElementPointer& element, float& parabolicDistance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const { auto model = getModel(); - if (!model || !isModelLoaded()) { + if (!model || !model->isLoaded()) { return false; } @@ -281,8 +250,23 @@ bool RenderableModelEntityItem::findDetailedParabolaIntersection(const glm::vec3 face, surfaceNormal, extraInfo, precisionPicking, false); } +QString RenderableModelEntityItem::getCollisionShapeURL() const { + return getShapeType() == SHAPE_TYPE_COMPOUND ? getCompoundShapeURL() : getModelURL(); +} + void RenderableModelEntityItem::fetchCollisionGeometryResource() { _collisionGeometryResource = DependencyManager::get()->getCollisionGeometryResource(getCollisionShapeURL()); + if (_collisionGeometryResource) { + if (_collisionGeometryResource->isLoaded()) { + markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); + locationChanged(); + } else { + connect(_collisionGeometryResource.get(), &GeometryResource::finished, this, [&] { + markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); + locationChanged(); + }); + } + } } bool RenderableModelEntityItem::unableToLoadCollisionShape() { @@ -299,7 +283,7 @@ void RenderableModelEntityItem::setShapeType(ShapeType type) { if (!_collisionGeometryResource && !getCollisionShapeURL().isEmpty()) { fetchCollisionGeometryResource(); } - } else if (_collisionGeometryResource && !getCompoundShapeURL().isEmpty()) { + } else if (_collisionGeometryResource) { // the compoundURL has been set but the shapeType does not agree _collisionGeometryResource.reset(); } @@ -308,49 +292,43 @@ void RenderableModelEntityItem::setShapeType(ShapeType type) { void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) { auto currentCompoundShapeURL = getCompoundShapeURL(); ModelEntityItem::setCompoundShapeURL(url); - if (getCompoundShapeURL() != currentCompoundShapeURL || !getModel()) { - if (getShapeType() == SHAPE_TYPE_COMPOUND) { + if (url != currentCompoundShapeURL && !url.isEmpty()) { + auto shapeType = getShapeType(); + if (shapeType == SHAPE_TYPE_COMPOUND) { + fetchCollisionGeometryResource(); + } + } +} + +void RenderableModelEntityItem::setModelURL(const QString& url) { + auto currentModelURL = getModelURL(); + ModelEntityItem::setModelURL(url); + if (url != currentModelURL && !url.isEmpty()) { + auto shapeType = getShapeType(); + if (shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { fetchCollisionGeometryResource(); } } } bool RenderableModelEntityItem::isReadyToComputeShape() const { - ShapeType type = getShapeType(); auto model = getModel(); auto shapeType = getShapeType(); if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { auto shapeURL = getCollisionShapeURL(); - - if (!model || shapeURL.isEmpty()) { - return false; - } - - if (model->getURL().isEmpty() || !_dimensionsInitialized) { - // we need a render geometry with a scale to proceed, so give up. - return false; - } - - if (model->isLoaded()) { - if (!shapeURL.isEmpty() && !_collisionGeometryResource) { + // we need a render geometry with a scale to proceed + if (model && !model->getURL().isEmpty() && !shapeURL.isEmpty() && _dimensionsInitialized && model->isLoaded()) { + if (!_collisionGeometryResource) { const_cast(this)->fetchCollisionGeometryResource(); } - if (_collisionGeometryResource && _collisionGeometryResource->isLoaded()) { - // we have both URLs AND both geometries AND they are both fully loaded. - if (_needsInitialSimulation) { - // the _model's offset will be wrong until _needsInitialSimulation is false - DETAILED_PERFORMANCE_TIMER("_model->simulate"); - const_cast(this)->doInitialModelSimulation(); - } - return true; - } + // do we have both URLs AND both geometries AND they are both fully loaded? + return _collisionGeometryResource && _collisionGeometryResource->isLoaded() && _collisionGeometryResource->isHFMModelLoaded(); } - // the model is still being downloaded. return false; - } else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) { - return isModelLoaded(); + } else if (shapeType >= SHAPE_TYPE_SIMPLE_HULL && shapeType <= SHAPE_TYPE_STATIC_MESH) { + return model && model->isLoaded() && _dimensionsInitialized; } return true; } @@ -362,20 +340,31 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { ShapeType type = getShapeType(); auto model = getModel(); - if (!model || !model->isLoaded()) { - type = SHAPE_TYPE_NONE; + if (type >= SHAPE_TYPE_COMPOUND && type <= SHAPE_TYPE_STATIC_MESH) { + if (!model) { + type = SHAPE_TYPE_NONE; + } else if (!model->isLoaded()) { + type = SHAPE_TYPE_NONE; + if (!model->didVisualGeometryRequestFail()) { + markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); + locationChanged(); + } + } + } + + if (type == SHAPE_TYPE_COMPOUND || type == SHAPE_TYPE_SIMPLE_COMPOUND) { + if (!_collisionGeometryResource || !_collisionGeometryResource->isLoaded() || !_collisionGeometryResource->isHFMModelLoaded()) { + type = SHAPE_TYPE_NONE; + if (!_collisionGeometryResource->isFailed()) { + markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); + locationChanged(); + } + } } if (type == SHAPE_TYPE_COMPOUND) { - if (!_collisionGeometryResource || !_collisionGeometryResource->isLoaded()) { - return; - } - updateModelBounds(); - // should never fall in here when collision model not fully loaded - // TODO: assert that all geometries exist and are loaded - //assert(_model && _model->isLoaded() && _collisionGeometryResource && _collisionGeometryResource->isLoaded()); const HFMModel& collisionGeometry = _collisionGeometryResource->getHFMModel(); ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection(); @@ -452,7 +441,8 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { // collision model's extents). glm::vec3 dimensions = getScaledDimensions(); - glm::vec3 scaleToFit = dimensions / model->getHFMModel().getUnscaledMeshExtents().size(); + glm::vec3 extents = model->getHFMModel().getUnscaledMeshExtents().size(); + glm::vec3 scaleToFit = dimensions / extents; // multiply each point by scale before handing the point-set off to the physics engine. // also determine the extents of the collision model. glm::vec3 registrationOffset = dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()); @@ -462,12 +452,10 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { pointCollection[i][j] = scaleToFit * (pointCollection[i][j] + model->getOffset()) - registrationOffset; } } - shapeInfo.setParams(type, dimensions, getCompoundShapeURL()); + shapeInfo.setParams(type, 0.5f * extents, getCompoundShapeURL()); adjustShapeInfoByRegistration(shapeInfo); } else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) { updateModelBounds(); - // assert we never fall in here when model not fully loaded - assert(model && model->isLoaded()); model->updateGeometry(); // compute meshPart local transforms @@ -476,16 +464,16 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { int numHFMMeshes = hfmModel.meshes.size(); int totalNumVertices = 0; glm::vec3 dimensions = getScaledDimensions(); - glm::mat4 invRegistraionOffset = glm::translate(dimensions * (getRegistrationPoint() - ENTITY_ITEM_DEFAULT_REGISTRATION_POINT)); + glm::mat4 invRegistrationOffset = glm::translate(dimensions * (getRegistrationPoint() - ENTITY_ITEM_DEFAULT_REGISTRATION_POINT)); for (int i = 0; i < numHFMMeshes; i++) { const HFMMesh& mesh = hfmModel.meshes.at(i); if (mesh.clusters.size() > 0) { const HFMCluster& cluster = mesh.clusters.at(0); auto jointMatrix = model->getRig().getJointTransform(cluster.jointIndex); // we backtranslate by the registration offset so we can apply that offset to the shapeInfo later - localTransforms.push_back(invRegistraionOffset * jointMatrix * cluster.inverseBindMatrix); + localTransforms.push_back(invRegistrationOffset * jointMatrix * cluster.inverseBindMatrix); } else { - localTransforms.push_back(invRegistraionOffset); + localTransforms.push_back(invRegistrationOffset); } totalNumVertices += mesh.vertices.size(); } @@ -697,7 +685,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { } } - shapeInfo.setParams(type, 0.5f * dimensions, getModelURL()); + shapeInfo.setParams(type, 0.5f * extents.size(), getModelURL()); adjustShapeInfoByRegistration(shapeInfo); } else { EntityItem::computeShapeInfo(shapeInfo); @@ -716,8 +704,8 @@ void RenderableModelEntityItem::setJointMap(std::vector jointMap) { int RenderableModelEntityItem::avatarJointIndex(int modelJointIndex) { int result = -1; - int mapSize = (int) _jointMap.size(); - if (modelJointIndex >=0 && modelJointIndex < mapSize) { + int mapSize = (int)_jointMap.size(); + if (modelJointIndex >= 0 && modelJointIndex < mapSize) { result = _jointMap[modelJointIndex]; } @@ -726,28 +714,44 @@ int RenderableModelEntityItem::avatarJointIndex(int modelJointIndex) { bool RenderableModelEntityItem::contains(const glm::vec3& point) const { auto model = getModel(); - if (EntityItem::contains(point) && model && _collisionGeometryResource && _collisionGeometryResource->isLoaded()) { - glm::mat4 worldToHFMMatrix = model->getWorldToHFMMatrix(); - glm::vec3 hfmPoint = worldToHFMMatrix * glm::vec4(point, 1.0f); - return _collisionGeometryResource->getHFMModel().convexHullContains(hfmPoint); + if (model && model->isLoaded()) { + auto shapeType = getShapeType(); + if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { + if (_collisionGeometryResource && _collisionGeometryResource->isLoaded() && _collisionGeometryResource->isHFMModelLoaded() && EntityItem::contains(point)) { + glm::mat4 worldToHFMMatrix = model->getWorldToHFMMatrix(); + glm::vec3 hfmPoint = worldToHFMMatrix * glm::vec4(point, 1.0f); + return _collisionGeometryResource->getHFMModel().convexHullContains(hfmPoint); + } + } else if (shapeType >= SHAPE_TYPE_SIMPLE_HULL && shapeType <= SHAPE_TYPE_STATIC_MESH) { + if (EntityItem::contains(point)) { + glm::mat4 worldToHFMMatrix = model->getWorldToHFMMatrix(); + glm::vec3 hfmPoint = worldToHFMMatrix * glm::vec4(point, 1.0f); + return model->getHFMModel().convexHullContains(hfmPoint); + } + } else { + return EntityItem::contains(point); + } } return false; } bool RenderableModelEntityItem::shouldBePhysical() const { - auto model = getModel(); - // If we have a model, make sure it hasn't failed to download. - // If it has, we'll report back that we shouldn't be physical so that physics aren't held waiting for us to be ready. + bool physicalModelLoaded = false; ShapeType shapeType = getShapeType(); - if (model) { - if ((shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) && model->didCollisionGeometryRequestFail()) { - return false; - } else if (shapeType != SHAPE_TYPE_NONE && model->didVisualGeometryRequestFail()) { - return false; + if (shapeType >= SHAPE_TYPE_COMPOUND && shapeType <= SHAPE_TYPE_STATIC_MESH) { + auto model = getModel(); + // If we have a model, make sure it hasn't failed to download. + // If it has, we'll report back that we shouldn't be physical so that physics aren't held waiting for us to be ready. + physicalModelLoaded = model && !model->didVisualGeometryRequestFail(); + if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { + physicalModelLoaded &= _collisionGeometryResource && !_collisionGeometryResource->isFailed(); } + } else if (shapeType != SHAPE_TYPE_NONE) { + physicalModelLoaded = true; } - return !isDead() && shapeType != SHAPE_TYPE_NONE && !isLocalEntity() && QUrl(_modelURL).isValid(); + + return physicalModelLoaded && !isDead() && !isLocalEntity() && QUrl(getModelURL()).isValid(); } int RenderableModelEntityItem::getJointParent(int index) const { @@ -943,13 +947,13 @@ void RenderableModelEntityItem::locationChanged(bool tellPhysics, bool tellChild int RenderableModelEntityItem::getJointIndex(const QString& name) const { auto model = getModel(); - return (model && model->isActive()) ? model->getRig().indexOfJoint(name) : -1; + return (model && model->isLoaded()) ? model->getRig().indexOfJoint(name) : -1; } QStringList RenderableModelEntityItem::getJointNames() const { QStringList result; auto model = getModel(); - if (model && model->isActive()) { + if (model && model->isLoaded()) { const Rig& rig = model->getRig(); int jointCount = rig.getJointStateCount(); for (int jointIndex = 0; jointIndex < jointCount; jointIndex++) { @@ -960,13 +964,13 @@ QStringList RenderableModelEntityItem::getJointNames() const { } scriptable::ScriptableModelBase render::entities::ModelEntityRenderer::getScriptableModel() { - auto model = resultWithReadLock([this]{ return _model; }); + auto model = resultWithReadLock([&] { return _model; }); if (!model || !model->isLoaded()) { return scriptable::ScriptableModelBase(); } - auto result = _model->getScriptableModel(); + auto result = model->getScriptableModel(); result.objectID = getEntity()->getID(); { std::lock_guard lock(_materialsLock); @@ -1036,7 +1040,7 @@ void RenderableModelEntityItem::copyAnimationJointDataToModel() { }); if (changed) { - locationChanged(true, true); + locationChanged(); } } @@ -1054,10 +1058,14 @@ ModelEntityRenderer::ModelEntityRenderer(const EntityItemPointer& entity) : Pare } -void ModelEntityRenderer::setKey(bool didVisualGeometryRequestSucceed) { +void ModelEntityRenderer::setKey(bool didVisualGeometryRequestSucceed, const ModelPointer& model) { auto builder = ItemKey::Builder().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); - if (!_cullWithParent && _model && _model->isGroupCulled()) { + if (!_visible) { + builder.withInvisible(); + } + + if (!_cullWithParent && model && model->isGroupCulled()) { builder.withMetaCullGroup(); } else if (_cullWithParent) { builder.withSubMetaCulled(); @@ -1075,8 +1083,9 @@ ItemKey ModelEntityRenderer::getKey() { } uint32_t ModelEntityRenderer::metaFetchMetaSubItems(ItemIDs& subItems) const { - if (_model) { - auto metaSubItems = _model->fetchRenderItemIDs(); + auto model = resultWithReadLock([&] { return _model; }); + if (model) { + auto metaSubItems = model->fetchRenderItemIDs(); subItems.insert(subItems.end(), metaSubItems.begin(), metaSubItems.end()); return (uint32_t)metaSubItems.size(); } @@ -1089,8 +1098,9 @@ void ModelEntityRenderer::handleBlendedVertices(int blendshapeNumber, const QVec } void ModelEntityRenderer::removeFromScene(const ScenePointer& scene, Transaction& transaction) { - if (_model) { - _model->removeFromScene(scene, transaction); + auto model = resultWithReadLock([&] { return _model; }); + if (model) { + model->removeFromScene(scene, transaction); } Parent::removeFromScene(scene, transaction); } @@ -1099,14 +1109,14 @@ void ModelEntityRenderer::onRemoveFromSceneTyped(const TypedEntityPointer& entit entity->setModel({}); } -void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { +void ModelEntityRenderer::animate(const TypedEntityPointer& entity, const ModelPointer& model) { if (!_animation || !_animation->isLoaded()) { return; } QVector jointsData; - const QVector& frames = _animation->getFramesReference(); // NOTE: getFrames() is too heavy + const QVector& frames = _animation->getFramesReference(); // NOTE: getFrames() is too heavy int frameCount = frames.size(); if (frameCount <= 0) { return; @@ -1124,17 +1134,17 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { _lastKnownCurrentFrame = currentIntegerFrame; } - if (_jointMapping.size() != _model->getJointStateCount()) { + if (_jointMapping.size() != model->getJointStateCount()) { qCWarning(entitiesrenderer) << "RenderableModelEntityItem::getAnimationFrame -- joint count mismatch" - << _jointMapping.size() << _model->getJointStateCount(); + << _jointMapping.size() << model->getJointStateCount(); return; } QStringList animationJointNames = _animation->getHFMModel().getJointNames(); auto& hfmJoints = _animation->getHFMModel().joints; - auto& originalHFMJoints = _model->getHFMModel().joints; - auto& originalHFMIndices = _model->getHFMModel().jointIndices; + auto& originalHFMJoints = model->getHFMModel().joints; + auto& originalHFMIndices = model->getHFMModel().jointIndices; bool allowTranslation = entity->getAnimationAllowTranslation(); @@ -1182,146 +1192,49 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { entity->copyAnimationJointDataToModel(); } -bool ModelEntityRenderer::needsRenderUpdate() const { - if (resultWithReadLock([&] { - if (_moving || _animating) { - return true; - } - - if (!_texturesLoaded) { - return true; - } - - if (!_prevModelLoaded) { - return true; - } - - return false; - })) { +bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { + if (entity->blendshapesChanged()) { return true; } - ModelPointer model; - QUrl parsedModelURL; - withReadLock([&] { - model = _model; - parsedModelURL = _parsedModelURL; - }); - - if (model) { - // When the individual mesh parts of a model finish fading, they will mark their Model as needing updating - // we will watch for that and ask the model to update it's render items - if (parsedModelURL != model->getURL()) { - return true; - } - - if (model->needsReload()) { - return true; - } - - if (model->needsFixupInScene()) { - return true; - } - - if (model->getRenderItemsNeedUpdate()) { - return true; - } - } - return Parent::needsRenderUpdate(); -} - -bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { - if (resultWithReadLock([&] { - if (entity->hasModel() != _hasModel) { - return true; - } - - // No model to render, early exit - if (!_hasModel) { - return false; - } - - if (_animating != entity->isAnimatingSomething()) { - return true; - } - - return false; - })) { return true; } - - ModelPointer model; - withReadLock([&] { - model = _model; - }); - - if (model && model->isLoaded()) { - if (!entity->_dimensionsInitialized || entity->_needsInitialSimulation || !entity->_originalTexturesRead) { - return true; - } - - if (entity->blendshapesChanged()) { - return true; - } - - // Check to see if we need to update the model bounds - if (entity->needsUpdateModelBounds()) { - return true; - } - - // Check to see if we need to update the model bounds - auto transform = entity->getTransform(); - if (model->getTranslation() != transform.getTranslation() || - model->getRotation() != transform.getRotation()) { - return true; - } - - if (model->getScaleToFitDimensions() != entity->getScaledDimensions() || - model->getRegistrationPoint() != entity->getRegistrationPoint()) { - return true; - } + // Check to see if we need to update the model bounds + if (entity->needsUpdateModelBounds()) { + return true; } - return false; + return Parent::needsRenderUpdateFromTypedEntity(entity); } -void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { +void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__); - if (_hasModel != entity->hasModel()) { - withWriteLock([&] { - _hasModel = entity->hasModel(); - }); + + _hasModel = entity->hasModel(); + QUrl modelURL = QUrl(entity->getModelURL()); + if (_parsedModelURL != modelURL) { + _parsedModelURL = modelURL; } - withWriteLock([&] { - _animating = entity->isAnimatingSomething(); - if (_parsedModelURL != entity->getModelURL()) { - _parsedModelURL = QUrl(entity->getModelURL()); - } + ModelPointer model = resultWithReadLock([&] { + return _model; }); - ModelPointer model; - withReadLock([&] { model = _model; }); + bool visuallyReady = model && model->isLoaded() && _didLastVisualGeometryRequestSucceed && _texturesLoaded; + entity->setVisuallyReady(visuallyReady); - withWriteLock([&] { - bool visuallyReady = true; - if (_hasModel) { - if (model && _didLastVisualGeometryRequestSucceed) { - visuallyReady = (_prevModelLoaded && _texturesLoaded); - } - } - entity->setVisuallyReady(visuallyReady); - }); + const render::ScenePointer& scene = AbstractViewStateInterface::instance()->getMain3DScene(); + render::Transaction transaction; // Check for removal if (!_hasModel) { if (model) { model->removeFromScene(scene, transaction); entity->bumpAncestorChainRenderableVersion(); - withWriteLock([&] { _model.reset(); }); emit DependencyManager::get()-> - modelRemovedFromScene(entity->getEntityItemID(), NestableType::Entity, _model); + modelRemovedFromScene(entity->getEntityItemID(), NestableType::Entity, model); + withWriteLock([&] { _model.reset(); }); } - setKey(false); _didLastVisualGeometryRequestSucceed = false; + setKey(_didLastVisualGeometryRequestSucceed, model); return; } @@ -1330,48 +1243,52 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce model = std::make_shared(nullptr, entity.get(), _created); connect(model.get(), &Model::requestRenderUpdate, this, &ModelEntityRenderer::requestRenderUpdate); connect(model.get(), &Model::setURLFinished, this, [&](bool didVisualGeometryRequestSucceed) { - setKey(didVisualGeometryRequestSucceed); - _model->setTagMask(getTagMask()); - _model->setHifiRenderLayer(getHifiRenderLayer()); - _model->setPrimitiveMode(_primitiveMode); - _model->setCullWithParent(_cullWithParent); - _model->setRenderWithZones(_renderWithZones); - emit requestRenderUpdate(); - if (didVisualGeometryRequestSucceed) { - emit DependencyManager::get()-> - modelAddedToScene(entity->getEntityItemID(), NestableType::Entity, _model); - } _didLastVisualGeometryRequestSucceed = didVisualGeometryRequestSucceed; + const render::ScenePointer& scene = AbstractViewStateInterface::instance()->getMain3DScene(); + render::Transaction transaction; + transaction.updateItem(_renderItemID, [&](PayloadProxyInterface& self) { + const render::ScenePointer& scene = AbstractViewStateInterface::instance()->getMain3DScene(); + withWriteLock([&] { + setKey(didVisualGeometryRequestSucceed, _model); + _model->setVisibleInScene(_visible, scene); + _model->setCauterized(_cauterized, scene); + _model->setCanCastShadow(_canCastShadow, scene); + _model->setGroupCulled(entity->getGroupCulled(), scene); + _model->setTagMask(getTagMask(), scene); + _model->setHifiRenderLayer(getHifiRenderLayer(), scene); + _model->setPrimitiveMode(_primitiveMode, scene); + _model->setCullWithParent(_cullWithParent, scene); + _model->setRenderWithZones(_renderWithZones, scene); + }); + if (didVisualGeometryRequestSucceed) { + emit DependencyManager::get()-> + modelAddedToScene(entity->getEntityItemID(), NestableType::Entity, model); + } + entity->_originalTexturesRead = false; + entity->_needsJointSimulation = true; + entity->_needsToRescaleModel = true; + emit requestRenderUpdate(); + }); + scene->enqueueTransaction(transaction); }); - model->setLoadingPriority(EntityTreeRenderer::getEntityLoadingPriority(*entity)); entity->setModel(model); withWriteLock([&] { _model = model; }); } // From here on, we are guaranteed a populated model if (_parsedModelURL != model->getURL()) { - withWriteLock([&] { - _texturesLoaded = false; - _jointMappingCompleted = false; - model->setURL(_parsedModelURL); - }); + _texturesLoaded = false; + _jointMappingCompleted = false; + model->setLoadingPriority(EntityTreeRenderer::getEntityLoadingPriority(*entity)); + model->setURL(_parsedModelURL); } // Nothing else to do unless the model is loaded if (!model->isLoaded()) { - withWriteLock([&] { - _prevModelLoaded = false; - }); - emit requestRenderUpdate(); return; - } else if (!_prevModelLoaded) { - withWriteLock([&] { - _prevModelLoaded = true; - }); } // Check for initializing the model - // FIXME: There are several places below here where we are modifying the entity, which we should not be doing from the renderable if (!entity->_dimensionsInitialized) { EntityItemProperties properties; properties.setLastEdited(usecTimestampNow()); // we must set the edit time since we're editing it @@ -1391,53 +1308,39 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce entity->_originalTexturesRead = true; } - if (_textures != entity->getTextures()) { + auto textures = entity->getTextures(); + if (_textures != textures) { QVariantMap newTextures; - withWriteLock([&] { - _texturesLoaded = false; - _textures = entity->getTextures(); - newTextures = parseTexturesToMap(_textures, entity->_originalTextures); - }); + _texturesLoaded = false; + _textures = textures; + newTextures = parseTexturesToMap(_textures, entity->_originalTextures); model->setTextures(newTextures); } + if (entity->_needsJointSimulation) { entity->copyAnimationJointDataToModel(); } entity->updateModelBounds(); entity->stopModelOverrideIfNoParent(); - if (model->isVisible() != _visible) { + withWriteLock([&] { + setKey(_didLastVisualGeometryRequestSucceed, model); model->setVisibleInScene(_visible, scene); - } - - if (model->isCauterized() != _cauterized) { model->setCauterized(_cauterized, scene); - } - - render::hifi::Tag tagMask = getTagMask(); - if (model->getTagMask() != tagMask) { - model->setTagMask(tagMask, scene); - } + model->setCanCastShadow(_canCastShadow, scene); + model->setGroupCulled(entity->getGroupCulled(), scene); + model->setTagMask(getTagMask(), scene); + model->setHifiRenderLayer(getHifiRenderLayer(), scene); + model->setPrimitiveMode(_primitiveMode, scene); + model->setCullWithParent(_cullWithParent, scene); + model->setRenderWithZones(_renderWithZones, scene); + }); if (entity->blendshapesChanged()) { model->setBlendshapeCoefficients(entity->getBlendshapeCoefficientVector()); model->updateBlendshapes(); } - // TODO? early exit here when not visible? - - if (model->canCastShadow() != _canCastShadow) { - model->setCanCastShadow(_canCastShadow, scene); - } - - { - bool groupCulled = entity->getGroupCulled(); - if (model->isGroupCulled() != groupCulled) { - model->setGroupCulled(groupCulled); - setKey(_didLastVisualGeometryRequestSucceed); - } - } - { DETAILED_PROFILE_RANGE(simulation_physics, "Fixup"); if (model->needsFixupInScene()) { @@ -1451,11 +1354,10 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce } } + bool needsUpdate = false; if (!_texturesLoaded && model->getGeometry() && model->getGeometry()->areTexturesLoaded()) { - withWriteLock([&] { - _texturesLoaded = true; - }); - model->updateRenderItems(); + _texturesLoaded = true; + needsUpdate = true; } else if (!_texturesLoaded) { emit requestRenderUpdate(); } @@ -1481,19 +1383,23 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce emit requestRenderUpdate(); } else { _allProceduralMaterialsLoaded = true; - model->setRenderItemsNeedUpdate(); + needsUpdate = true; } } // When the individual mesh parts of a model finish fading, they will mark their Model as needing updating // we will watch for that and ask the model to update it's render items - if (model->getRenderItemsNeedUpdate()) { + if (needsUpdate || model->getRenderItemsNeedUpdate()) { model->updateRenderItems(); } + scene->enqueueTransaction(transaction); +} + +void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { // The code to deal with the change of properties is now in ModelEntityItem.cpp // That is where _currentFrame and _lastAnimated were updated. - if (_animating) { + if (entity->isAnimatingSomething()) { DETAILED_PROFILE_RANGE(simulation_physics, "Animate"); auto animationURL = entity->getAnimationURL(); @@ -1502,18 +1408,22 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce _animationURL = animationURL; if (_animation) { - //(_animation->getURL().toString() != entity->getAnimationURL())) { // bad check // the joints have been mapped before but we have a new animation to load _animation.reset(); _jointMappingCompleted = false; } } - - if (!_jointMappingCompleted) { - mapJoints(entity, model); - } - if (entity->readyToAnimate()) { - animate(entity); + + ModelPointer model = resultWithReadLock([&] { + return _model; + }); + if (model && model->isLoaded()) { + if (!_jointMappingCompleted) { + mapJoints(entity, model); + } + if (entity->readyToAnimate()) { + animate(entity, model); + } } emit requestRenderUpdate(); } @@ -1521,40 +1431,20 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce void ModelEntityRenderer::setIsVisibleInSecondaryCamera(bool value) { Parent::setIsVisibleInSecondaryCamera(value); - setKey(_didLastVisualGeometryRequestSucceed); - if (_model) { - _model->setTagMask(getTagMask()); - } + // called within a lock so no need to lock for _model + setKey(_didLastVisualGeometryRequestSucceed, _model); } void ModelEntityRenderer::setRenderLayer(RenderLayer value) { Parent::setRenderLayer(value); - setKey(_didLastVisualGeometryRequestSucceed); - if (_model) { - _model->setHifiRenderLayer(getHifiRenderLayer()); - } -} - -void ModelEntityRenderer::setPrimitiveMode(PrimitiveMode value) { - Parent::setPrimitiveMode(value); - if (_model) { - _model->setPrimitiveMode(_primitiveMode); - } + // called within a lock so no need to lock for _model + setKey(_didLastVisualGeometryRequestSucceed, _model); } void ModelEntityRenderer::setCullWithParent(bool value) { Parent::setCullWithParent(value); - setKey(_didLastVisualGeometryRequestSucceed); - if (_model) { - _model->setCullWithParent(_cullWithParent); - } -} - -void ModelEntityRenderer::setRenderWithZones(const QVector& renderWithZones) { - Parent::setRenderWithZones(renderWithZones); - if (_model) { - _model->setRenderWithZones(renderWithZones); - } + // called within a lock so no need to lock for _model + setKey(_didLastVisualGeometryRequestSucceed, _model); } // NOTE: this only renders the "meta" portion of the Model, namely it renders debugging items @@ -1570,9 +1460,8 @@ void ModelEntityRenderer::doRender(RenderArgs* args) { geometryCache->renderWireCubeInstance(args, batch, greenColor, geometryCache->getShapePipelinePointer(false, false, args->_renderMethod == Args::RenderMethod::FORWARD)); #if WANT_EXTRA_DEBUGGING - ModelPointer model; - withReadLock([&] { - model = _model; + ModelPointer model = resultWithReadLock([&] { + return _model; }); if (model) { model->renderDebugMeshBoxes(batch, args->_renderMethod == Args::RenderMethod::FORWARD); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 850617d1af..4501f6d88c 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -41,7 +41,6 @@ protected: ModelEntityWrapper(const EntityItemID& entityItemID) : Parent(entityItemID) {} void setModel(const ModelPointer& model); ModelPointer getModel() const; - bool isModelLoaded() const; bool _needsInitialSimulation{ true }; private: @@ -62,7 +61,6 @@ public: virtual void setUnscaledDimensions(const glm::vec3& value) override; virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override; - void doInitialModelSimulation(); void updateModelBounds(); virtual bool supportsDetailedIntersection() const override; @@ -77,6 +75,7 @@ public: virtual void setShapeType(ShapeType type) override; virtual void setCompoundShapeURL(const QString& url) override; + virtual void setModelURL(const QString& url) override; virtual bool isReadyToComputeShape() const override; virtual void computeShapeInfo(ShapeInfo& shapeInfo) override; @@ -121,6 +120,8 @@ private: bool readyToAnimate() const; void fetchCollisionGeometryResource(); + QString getCollisionShapeURL() const; + GeometryResource::Pointer _collisionGeometryResource; std::vector _jointMap; QVariantMap _originalTextures; @@ -128,6 +129,7 @@ private: bool _originalTexturesRead { false }; bool _dimensionsInitialized { true }; bool _needsJointSimulation { false }; + bool _needsToRescaleModel { false }; }; namespace render { namespace entities { @@ -153,25 +155,23 @@ protected: virtual void removeFromScene(const ScenePointer& scene, Transaction& transaction) override; virtual void onRemoveFromSceneTyped(const TypedEntityPointer& entity) override; - void setKey(bool didVisualGeometryRequestSucceed); + void setKey(bool didVisualGeometryRequestSucceed, const ModelPointer& model); virtual ItemKey getKey() override; virtual uint32_t metaFetchMetaSubItems(ItemIDs& subItems) const override; virtual void handleBlendedVertices(int blendshapeNumber, const QVector& blendshapeOffsets, const QVector& blendedMeshSizes, const render::ItemIDs& subItemIDs) override; virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; - virtual bool needsRenderUpdate() const override; - virtual void doRender(RenderArgs* args) override; virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; + virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; + virtual void doRender(RenderArgs* args) override; void setIsVisibleInSecondaryCamera(bool value) override; void setRenderLayer(RenderLayer value) override; - void setPrimitiveMode(PrimitiveMode value) override; void setCullWithParent(bool value) override; - void setRenderWithZones(const QVector& renderWithZones) override; private: - void animate(const TypedEntityPointer& entity); + void animate(const TypedEntityPointer& entity, const ModelPointer& model); void mapJoints(const TypedEntityPointer& entity, const ModelPointer& model); // Transparency is handled in ModelMeshPartPayload @@ -186,20 +186,16 @@ private: bool _hasTransitioned{ false }; #endif - const void* _collisionMeshKey { nullptr }; - QUrl _parsedModelURL; bool _jointMappingCompleted { false }; QVector _jointMapping; // domain is index into model-joints, range is index into animation-joints AnimationPointer _animation; - bool _animating { false }; QString _animationURL; uint64_t _lastAnimated { 0 }; render::ItemKey _itemKey { render::ItemKey::Builder().withTypeMeta() }; bool _didLastVisualGeometryRequestSucceed { true }; - bool _prevModelLoaded { false }; void processMaterials(); bool _allProceduralMaterialsLoaded { false }; diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 8bca6cbe96..e53e52d105 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -64,84 +64,7 @@ ParticleEffectEntityRenderer::ParticleEffectEntityRenderer(const EntityItemPoint }); } -bool ParticleEffectEntityRenderer::needsRenderUpdate() const { - if (resultWithReadLock([&] { - return !_textureLoaded; - })) { - return true; - } - - return Parent::needsRenderUpdate(); -} - void ParticleEffectEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { - auto newParticleProperties = entity->getParticleProperties(); - if (!newParticleProperties.valid()) { - qCWarning(entitiesrenderer) << "Bad particle properties"; - } - - if (resultWithReadLock([&] { return _particleProperties != newParticleProperties; })) { - _timeUntilNextEmit = 0; - withWriteLock([&] { - _particleProperties = newParticleProperties; - if (!_prevEmitterShouldTrailInitialized) { - _prevEmitterShouldTrailInitialized = true; - _prevEmitterShouldTrail = _particleProperties.emission.shouldTrail; - } - }); - } - - withWriteLock([&] { - _pulseProperties = entity->getPulseProperties(); - _shapeType = entity->getShapeType(); - QString compoundShapeURL = entity->getCompoundShapeURL(); - if (_compoundShapeURL != compoundShapeURL) { - _compoundShapeURL = compoundShapeURL; - _hasComputedTriangles = false; - fetchGeometryResource(); - } - }); - _emitting = entity->getIsEmitting(); - - bool textureEmpty = resultWithReadLock([&] { return _particleProperties.textures.isEmpty(); }); - if (textureEmpty) { - if (_networkTexture) { - withWriteLock([&] { - _networkTexture.reset(); - }); - } - - withWriteLock([&] { - _textureLoaded = true; - entity->setVisuallyReady(true); - }); - } else { - bool textureNeedsUpdate = resultWithReadLock([&] { - return !_networkTexture || _networkTexture->getURL() != QUrl(_particleProperties.textures); - }); - if (textureNeedsUpdate) { - withWriteLock([&] { - _networkTexture = DependencyManager::get()->getTexture(_particleProperties.textures); - _textureLoaded = false; - entity->setVisuallyReady(false); - }); - } - - if (!_textureLoaded) { - emit requestRenderUpdate(); - } - - bool textureLoaded = resultWithReadLock([&] { - return _networkTexture && (_networkTexture->isLoaded() || _networkTexture->isFailed()); - }); - if (textureLoaded) { - withWriteLock([&] { - entity->setVisuallyReady(true); - _textureLoaded = true; - }); - } - } - void* key = (void*)this; AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this] { withWriteLock([&] { @@ -151,20 +74,66 @@ void ParticleEffectEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePoi } void ParticleEffectEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { + auto newParticleProperties = entity->getParticleProperties(); + if (!newParticleProperties.valid()) { + qCWarning(entitiesrenderer) << "Bad particle properties"; + } + + if (_particleProperties != newParticleProperties) { + _timeUntilNextEmit = 0; + _particleProperties = newParticleProperties; + if (!_prevEmitterShouldTrailInitialized) { + _prevEmitterShouldTrailInitialized = true; + _prevEmitterShouldTrail = _particleProperties.emission.shouldTrail; + } + } + + _pulseProperties = entity->getPulseProperties(); + _shapeType = entity->getShapeType(); + QString compoundShapeURL = entity->getCompoundShapeURL(); + if (_compoundShapeURL != compoundShapeURL) { + _compoundShapeURL = compoundShapeURL; + _hasComputedTriangles = false; + fetchGeometryResource(); + } + _emitting = entity->getIsEmitting(); + + if (_particleProperties.textures.isEmpty()) { + if (_networkTexture) { + _networkTexture.reset(); + } + + _textureLoaded = true; + entity->setVisuallyReady(true); + } else { + if (!_networkTexture || _networkTexture->getURL() != QUrl(_particleProperties.textures)) { + _networkTexture = DependencyManager::get()->getTexture(_particleProperties.textures); + _textureLoaded = false; + entity->setVisuallyReady(false); + } + + if (!_textureLoaded) { + emit requestRenderUpdate(); + } + + if (_networkTexture && (_networkTexture->isLoaded() || _networkTexture->isFailed())) { + entity->setVisuallyReady(true); + _textureLoaded = true; + } + } + // Fill in Uniforms structure ParticleUniforms particleUniforms; - withReadLock([&] { - particleUniforms.radius.start = _particleProperties.radius.range.start; - particleUniforms.radius.middle = _particleProperties.radius.gradient.target; - particleUniforms.radius.finish = _particleProperties.radius.range.finish; - particleUniforms.radius.spread = _particleProperties.radius.gradient.spread; - particleUniforms.spin.start = _particleProperties.spin.range.start; - particleUniforms.spin.middle = _particleProperties.spin.gradient.target; - particleUniforms.spin.finish = _particleProperties.spin.range.finish; - particleUniforms.spin.spread = _particleProperties.spin.gradient.spread; - particleUniforms.lifespan = _particleProperties.lifespan; - particleUniforms.rotateWithEntity = _particleProperties.rotateWithEntity ? 1 : 0; - }); + particleUniforms.radius.start = _particleProperties.radius.range.start; + particleUniforms.radius.middle = _particleProperties.radius.gradient.target; + particleUniforms.radius.finish = _particleProperties.radius.range.finish; + particleUniforms.radius.spread = _particleProperties.radius.gradient.spread; + particleUniforms.spin.start = _particleProperties.spin.range.start; + particleUniforms.spin.middle = _particleProperties.spin.gradient.target; + particleUniforms.spin.finish = _particleProperties.spin.range.finish; + particleUniforms.spin.spread = _particleProperties.spin.gradient.spread; + particleUniforms.lifespan = _particleProperties.lifespan; + particleUniforms.rotateWithEntity = _particleProperties.rotateWithEntity ? 1 : 0; // Update particle uniforms _uniformBuffer.edit() = particleUniforms; } @@ -403,27 +372,18 @@ void ParticleEffectEntityRenderer::stepSimulation() { const auto interval = std::min(USECS_PER_SECOND / 60, now - _lastSimulated); _lastSimulated = now; - particle::Properties particleProperties; - ShapeType shapeType; - GeometryResource::Pointer geometryResource; - withReadLock([&] { - particleProperties = _particleProperties; - shapeType = _shapeType; - geometryResource = _geometryResource; - }); - const auto& modelTransform = getModelTransform(); - if (_emitting && particleProperties.emitting() && - (shapeType != SHAPE_TYPE_COMPOUND || (geometryResource && geometryResource->isLoaded()))) { - uint64_t emitInterval = particleProperties.emitIntervalUsecs(); + if (_emitting && _particleProperties.emitting() && + (_shapeType != SHAPE_TYPE_COMPOUND || (_geometryResource && _geometryResource->isLoaded()))) { + uint64_t emitInterval = _particleProperties.emitIntervalUsecs(); if (emitInterval > 0 && interval >= _timeUntilNextEmit) { auto timeRemaining = interval; while (timeRemaining > _timeUntilNextEmit) { if (_shapeType == SHAPE_TYPE_COMPOUND && !_hasComputedTriangles) { - computeTriangles(geometryResource->getHFMModel()); + computeTriangles(_geometryResource->getHFMModel()); } // emit particle - _cpuParticles.push_back(createParticle(modelTransform, particleProperties, shapeType, geometryResource, _triangleInfo)); + _cpuParticles.push_back(createParticle(modelTransform, _particleProperties, _shapeType, _geometryResource, _triangleInfo)); _timeUntilNextEmit = emitInterval; if (emitInterval < timeRemaining) { timeRemaining -= emitInterval; @@ -435,14 +395,14 @@ void ParticleEffectEntityRenderer::stepSimulation() { } // Kill any particles that have expired or are over the max size - while (_cpuParticles.size() > particleProperties.maxParticles || (!_cpuParticles.empty() && _cpuParticles.front().expiration == 0)) { + while (_cpuParticles.size() > _particleProperties.maxParticles || (!_cpuParticles.empty() && _cpuParticles.front().expiration == 0)) { _cpuParticles.pop_front(); } const float deltaTime = (float)interval / (float)USECS_PER_SECOND; // update the particles for (auto& particle : _cpuParticles) { - if (_prevEmitterShouldTrail != particleProperties.emission.shouldTrail) { + if (_prevEmitterShouldTrail != _particleProperties.emission.shouldTrail) { if (_prevEmitterShouldTrail) { particle.relativePosition = particle.relativePosition + particle.basePosition - modelTransform.getTranslation(); } @@ -451,14 +411,14 @@ void ParticleEffectEntityRenderer::stepSimulation() { particle.expiration = particle.expiration >= interval ? particle.expiration - interval : 0; particle.integrate(deltaTime); } - _prevEmitterShouldTrail = particleProperties.emission.shouldTrail; + _prevEmitterShouldTrail = _particleProperties.emission.shouldTrail; // Build particle primitives static GpuParticles gpuParticles; gpuParticles.clear(); gpuParticles.reserve(_cpuParticles.size()); // Reserve space - std::transform(_cpuParticles.begin(), _cpuParticles.end(), std::back_inserter(gpuParticles), [&particleProperties, &modelTransform] (const CpuParticle& particle) { - glm::vec3 position = particle.relativePosition + (particleProperties.emission.shouldTrail ? particle.basePosition : modelTransform.getTranslation()); + std::transform(_cpuParticles.begin(), _cpuParticles.end(), std::back_inserter(gpuParticles), [this, &modelTransform] (const CpuParticle& particle) { + glm::vec3 position = particle.relativePosition + (_particleProperties.emission.shouldTrail ? particle.basePosition : modelTransform.getTranslation()); return GpuParticle(position, glm::vec2(particle.lifetime, particle.seed)); }); @@ -487,13 +447,14 @@ void ParticleEffectEntityRenderer::doRender(RenderArgs* args) { // if the particles are marked rotateWithEntity withReadLock([&] { transform.setRotation(_renderTransform.getRotation()); - auto& color = _uniformBuffer.edit().color; - color.start = EntityRenderer::calculatePulseColor(_particleProperties.getColorStart(), _pulseProperties, _created); - color.middle = EntityRenderer::calculatePulseColor(_particleProperties.getColorMiddle(), _pulseProperties, _created); - color.finish = EntityRenderer::calculatePulseColor(_particleProperties.getColorFinish(), _pulseProperties, _created); - color.spread = EntityRenderer::calculatePulseColor(_particleProperties.getColorSpread(), _pulseProperties, _created); }); + auto& color = _uniformBuffer.edit().color; + color.start = EntityRenderer::calculatePulseColor(_particleProperties.getColorStart(), _pulseProperties, _created); + color.middle = EntityRenderer::calculatePulseColor(_particleProperties.getColorMiddle(), _pulseProperties, _created); + color.finish = EntityRenderer::calculatePulseColor(_particleProperties.getColorFinish(), _pulseProperties, _created); + color.spread = EntityRenderer::calculatePulseColor(_particleProperties.getColorSpread(), _pulseProperties, _created); + batch.setModelTransform(transform); batch.setUniformBuffer(0, _uniformBuffer); batch.setInputFormat(_vertexFormat); diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h index 0811b231d8..ca6bc859fb 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h @@ -25,7 +25,6 @@ public: ParticleEffectEntityRenderer(const EntityItemPointer& entity); protected: - virtual bool needsRenderUpdate() const override; virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index a843083831..f98a54d594 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -121,16 +121,6 @@ ShapeKey PolyLineEntityRenderer::getShapeKey() { return builder.build(); } -bool PolyLineEntityRenderer::needsRenderUpdate() const { - if (resultWithReadLock([&] { - return (!_textureLoaded && _texture && _texture->isLoaded()); - })) { - return true; - } - - return Parent::needsRenderUpdate(); -} - bool PolyLineEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { if (entity->pointsChanged() || entity->widthsChanged() || entity->normalsChanged() || entity->texturesChanged() || entity->colorsChanged()) { return true; @@ -140,6 +130,15 @@ bool PolyLineEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityP } void PolyLineEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { + void* key = (void*)this; + AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this] { + withWriteLock([&] { + _renderTransform = getModelTransform(); + }); + }); +} + +void PolyLineEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { auto pointsChanged = entity->pointsChanged(); auto widthsChanged = entity->widthsChanged(); auto normalsChanged = entity->normalsChanged(); @@ -159,13 +158,15 @@ void PolyLineEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& if (!textures.isEmpty()) { entityTextures = QUrl(textures); } - withWriteLock([&] { - _texture = DependencyManager::get()->getTexture(entityTextures); - }); + _texture = DependencyManager::get()->getTexture(entityTextures); _textureAspectRatio = 1.0f; _textureLoaded = false; } + if (!_textureLoaded) { + emit requestRenderUpdate(); + } + bool textureChanged = false; if (!_textureLoaded && _texture && _texture->isLoaded()) { textureChanged = true; @@ -175,13 +176,11 @@ void PolyLineEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& // Data bool faceCameraChanged = faceCamera != _faceCamera; - withWriteLock([&] { - if (faceCameraChanged || glow != _glow) { - _faceCamera = faceCamera; - _glow = glow; - updateData(); - } - }); + if (faceCameraChanged || glow != _glow) { + _faceCamera = faceCamera; + _glow = glow; + updateData(); + } // Geometry if (pointsChanged) { @@ -200,19 +199,10 @@ void PolyLineEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& bool uvModeStretchChanged = _isUVModeStretch != isUVModeStretch; _isUVModeStretch = isUVModeStretch; - - bool geometryChanged = uvModeStretchChanged || pointsChanged || widthsChanged || normalsChanged || colorsChanged || textureChanged || faceCameraChanged; - void* key = (void*)this; - AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, geometryChanged] { - withWriteLock([&] { - _renderTransform = getModelTransform(); - - if (geometryChanged) { - updateGeometry(); - } - }); - }); + if (uvModeStretchChanged || pointsChanged || widthsChanged || normalsChanged || colorsChanged || textureChanged || faceCameraChanged) { + updateGeometry(); + } } void PolyLineEntityRenderer::updateGeometry() { @@ -318,19 +308,16 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) { Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; - size_t numVertices; Transform transform; - gpu::TexturePointer texture; + gpu::TexturePointer texture = _textureLoaded ? _texture->getGPUTexture() : DependencyManager::get()->getWhiteTexture(); withReadLock([&] { - numVertices = _numVertices; transform = _renderTransform; - texture = _textureLoaded ? _texture->getGPUTexture() : DependencyManager::get()->getWhiteTexture(); - - batch.setResourceBuffer(0, _polylineGeometryBuffer); - batch.setUniformBuffer(0, _polylineDataBuffer); }); - if (numVertices < 2) { + batch.setResourceBuffer(0, _polylineGeometryBuffer); + batch.setUniformBuffer(0, _polylineDataBuffer); + + if (_numVertices < 2) { return; } @@ -341,5 +328,5 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) { batch.setPipeline(_pipelines[{args->_renderMethod, isTransparent()}]); batch.setModelTransform(transform); batch.setResourceTexture(0, texture); - batch.draw(gpu::TRIANGLE_STRIP, (gpu::uint32)(2 * numVertices), 0); + batch.draw(gpu::TRIANGLE_STRIP, (gpu::uint32)(2 * _numVertices), 0); } diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h index 41b66c0e51..c4fbb9a776 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h @@ -30,9 +30,9 @@ public: virtual bool isTransparent() const override; protected: - virtual bool needsRenderUpdate() const override; virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; + virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; virtual ItemKey getKey() override; virtual ShapeKey getShapeKey() override; diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 1555604604..f0a6684654 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -1802,25 +1802,44 @@ ShapeKey PolyVoxEntityRenderer::getShapeKey() { } bool PolyVoxEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { - if (entity->voxelToWorldMatrix() != _lastVoxelToWorldMatrix) { + if (resultWithReadLock([&] { + if (entity->voxelToWorldMatrix() != _lastVoxelToWorldMatrix) { + return true; + } + + if (entity->_mesh != _mesh) { + return true; + } + + return false; + })) { return true; } - if (entity->_mesh != _mesh) { - return true; - } - - return false; + return Parent::needsRenderUpdateFromTypedEntity(entity); } void PolyVoxEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { - #ifdef POLYVOX_ENTITY_USE_FADE_EFFECT if (!_hasTransitioned) { transaction.resetTransitionOnItem(_renderItemID, render::Transition::ELEMENT_ENTER_DOMAIN); _hasTransitioned = true; } #endif +} + +void PolyVoxEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { + _lastVoxelToWorldMatrix = entity->voxelToWorldMatrix(); + _lastVoxelVolumeSize = entity->getVoxelVolumeSize(); + _params->setSubData(0, vec4(_lastVoxelVolumeSize, 0.0)); + graphics::MeshPointer newMesh; + entity->withReadLock([&] { + newMesh = entity->_mesh; + }); + + if (newMesh && newMesh->getIndexBuffer()._buffer) { + _mesh = newMesh; + } std::array xyzTextureURLs{ { entity->getXTextureURL(), @@ -1838,20 +1857,6 @@ void PolyVoxEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& s } } -void PolyVoxEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { - _lastVoxelToWorldMatrix = entity->voxelToWorldMatrix(); - _lastVoxelVolumeSize = entity->getVoxelVolumeSize(); - _params->setSubData(0, vec4(_lastVoxelVolumeSize, 0.0)); - graphics::MeshPointer newMesh; - entity->withReadLock([&] { - newMesh = entity->_mesh; - }); - - if (newMesh && newMesh->getIndexBuffer()._buffer) { - _mesh = newMesh; - } -} - void PolyVoxEntityRenderer::doRender(RenderArgs* args) { if (!_mesh || !_mesh->getIndexBuffer()._buffer) { return; diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 4c6f5adc13..06ccdef753 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -51,24 +51,7 @@ bool ShapeEntityRenderer::needsRenderUpdate() const { return Parent::needsRenderUpdate(); } -bool ShapeEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { - if (_dimensions != entity->getScaledDimensions()) { - return true; - } - - if (_proceduralData != entity->getUserData()) { - return true; - } - - return false; -} - void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { - withWriteLock([&] { - _shape = entity->getShape(); - _pulseProperties = entity->getPulseProperties(); - }); - void* key = (void*)this; AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] { withWriteLock([&] { @@ -86,47 +69,53 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce } void ShapeEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { + _shape = entity->getShape(); + _pulseProperties = entity->getPulseProperties(); + + bool materialChanged = false; + glm::vec3 color = toGlm(entity->getColor()); + if (_color != color) { + _color = color; + _material->setAlbedo(color); + materialChanged = true; + } + + float alpha = entity->getAlpha(); + if (_alpha != alpha) { + _alpha = alpha; + _material->setOpacity(alpha); + materialChanged = true; + } + + auto userData = entity->getUserData(); + if (_proceduralData != userData) { + _proceduralData = userData; + _material->setProceduralData(_proceduralData); + materialChanged = true; + } + withReadLock([&] { - auto mat = _materials.find("0"); - if (mat != _materials.end() && mat->second.top().material && mat->second.top().material->isProcedural() && mat->second.top().material->isReady()) { - auto procedural = std::static_pointer_cast(mat->second.top().material); - if (procedural->isFading()) { - procedural->setIsFading(Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) < 1.0f); - } - } - }); - - withWriteLock([&] { - bool materialChanged = false; - glm::vec3 color = toGlm(entity->getColor()); - if (_color != color) { - _color = color; - _material->setAlbedo(color); - materialChanged = true; - } - - float alpha = entity->getAlpha(); - if (_alpha != alpha) { - _alpha = alpha; - _material->setOpacity(alpha); - materialChanged = true; - } - - auto userData = entity->getUserData(); - if (_proceduralData != userData) { - _proceduralData = userData; - _material->setProceduralData(_proceduralData); - materialChanged = true; - } - auto materials = _materials.find("0"); if (materials != _materials.end()) { if (materialChanged) { materials->second.setNeedsUpdate(true); } + bool requestUpdate = false; + if (materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) { + auto procedural = std::static_pointer_cast(materials->second.top().material); + if (procedural->isFading()) { + procedural->setIsFading(Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) < 1.0f); + requestUpdate = true; + } + } + if (materials->second.shouldUpdate()) { RenderPipelines::updateMultiMaterial(materials->second); + requestUpdate = true; + } + + if (requestUpdate) { emit requestRenderUpdate(); } } @@ -231,13 +220,12 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { graphics::MultiMaterial materials; auto geometryCache = DependencyManager::get(); - GeometryCache::Shape geometryShape; + GeometryCache::Shape geometryShape = geometryCache->getShapeForEntityShape(_shape); PrimitiveMode primitiveMode; RenderLayer renderLayer; glm::vec4 outColor; Pipeline pipelineType; withReadLock([&] { - geometryShape = geometryCache->getShapeForEntityShape(_shape); primitiveMode = _primitiveMode; renderLayer = _renderLayer; batch.setModelTransform(_renderTransform); // use a transform with scale, rotation, registration point and translation @@ -245,9 +233,10 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { pipelineType = getPipelineType(materials); auto& schema = materials.getSchemaBuffer().get(); outColor = glm::vec4(ColorUtils::tosRGBVec3(schema._albedo), schema._opacity); - outColor = EntityRenderer::calculatePulseColor(outColor, _pulseProperties, _created); }); + outColor = EntityRenderer::calculatePulseColor(outColor, _pulseProperties, _created); + if (outColor.a == 0.0f) { return; } @@ -256,7 +245,9 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { auto procedural = std::static_pointer_cast(materials.top().material); outColor = procedural->getColor(outColor); outColor.a *= procedural->isFading() ? Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) : 1.0f; - procedural->prepare(batch, _position, _dimensions, _orientation, _created, ProceduralProgramKey(outColor.a < 1.0f)); + withReadLock([&] { + procedural->prepare(batch, _position, _dimensions, _orientation, _created, ProceduralProgramKey(outColor.a < 1.0f)); + }); if (render::ShapeKey(args->_globalShapeKey).isWireframe() || primitiveMode == PrimitiveMode::LINES) { geometryCache->renderWireShape(batch, geometryShape, outColor); diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.h b/libraries/entities-renderer/src/RenderableShapeEntityItem.h index e4d6d099a6..9fb2fa8f23 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.h +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.h @@ -30,7 +30,6 @@ protected: private: virtual bool needsRenderUpdate() const override; - virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; virtual void doRender(RenderArgs* args) override; diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index a744fc9a62..04ad86c7e1 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -92,14 +92,6 @@ uint32_t TextEntityRenderer::metaFetchMetaSubItems(ItemIDs& subItems) const { return parentSubs; } -bool TextEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { - if (_dimensions != entity->getScaledDimensions()) { - return true; - } - - return false; -} - void TextEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { void* key = (void*)this; AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] { @@ -112,26 +104,24 @@ void TextEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen } void TextEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { - withWriteLock([&] { - _pulseProperties = entity->getPulseProperties(); - _text = entity->getText(); - _lineHeight = entity->getLineHeight(); - _textColor = toGlm(entity->getTextColor()); - _textAlpha = entity->getTextAlpha(); - _backgroundColor = toGlm(entity->getBackgroundColor()); - _backgroundAlpha = entity->getBackgroundAlpha(); - _billboardMode = entity->getBillboardMode(); - _leftMargin = entity->getLeftMargin(); - _rightMargin = entity->getRightMargin(); - _topMargin = entity->getTopMargin(); - _bottomMargin = entity->getBottomMargin(); - _unlit = entity->getUnlit(); - _font = entity->getFont(); - _effect = entity->getTextEffect(); - _effectColor = toGlm(entity->getTextEffectColor()); - _effectThickness = entity->getTextEffectThickness(); - updateTextRenderItem(); - }); + _pulseProperties = entity->getPulseProperties(); + _text = entity->getText(); + _lineHeight = entity->getLineHeight(); + _textColor = toGlm(entity->getTextColor()); + _textAlpha = entity->getTextAlpha(); + _backgroundColor = toGlm(entity->getBackgroundColor()); + _backgroundAlpha = entity->getBackgroundAlpha(); + _billboardMode = entity->getBillboardMode(); + _leftMargin = entity->getLeftMargin(); + _rightMargin = entity->getRightMargin(); + _topMargin = entity->getTopMargin(); + _bottomMargin = entity->getBottomMargin(); + _unlit = entity->getUnlit(); + _font = entity->getFont(); + _effect = entity->getTextEffect(); + _effectColor = toGlm(entity->getTextEffectColor()); + _effectThickness = entity->getTextEffectThickness(); + updateTextRenderItem(); } void TextEntityRenderer::doRender(RenderArgs* args) { @@ -141,25 +131,23 @@ void TextEntityRenderer::doRender(RenderArgs* args) { glm::vec4 backgroundColor; Transform modelTransform; - BillboardMode billboardMode; PrimitiveMode primitiveMode; RenderLayer renderLayer; withReadLock([&] { modelTransform = _renderTransform; - billboardMode = _billboardMode; primitiveMode = _primitiveMode; renderLayer = _renderLayer; float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; backgroundColor = glm::vec4(_backgroundColor, fadeRatio * _backgroundAlpha); - backgroundColor = EntityRenderer::calculatePulseColor(backgroundColor, _pulseProperties, _created); }); + backgroundColor = EntityRenderer::calculatePulseColor(backgroundColor, _pulseProperties, _created); if (backgroundColor.a <= 0.0f) { return; } - modelTransform.setRotation(EntityItem::getBillboardRotation(modelTransform.getTranslation(), modelTransform.getRotation(), billboardMode, args->getViewFrustum().getPosition())); + modelTransform.setRotation(EntityItem::getBillboardRotation(modelTransform.getTranslation(), modelTransform.getRotation(), _billboardMode, args->getViewFrustum().getPosition())); batch.setModelTransform(modelTransform); auto geometryCache = DependencyManager::get(); @@ -323,53 +311,36 @@ void entities::TextPayload::render(RenderArgs* args) { glm::vec3 dimensions; BillboardMode billboardMode; - QString text; glm::vec4 textColor; - QString font; - TextEffect effect; - glm::vec3 effectColor; - float effectThickness; - float lineHeight, leftMargin, rightMargin, topMargin, bottomMargin; bool forward; textRenderable->withReadLock([&] { modelTransform = textRenderable->_renderTransform; dimensions = textRenderable->_dimensions; billboardMode = textRenderable->_billboardMode; - text = textRenderable->_text; - font = textRenderable->_font; - effect = textRenderable->_effect; - effectThickness = textRenderable->_effectThickness; - - lineHeight = textRenderable->_lineHeight; - leftMargin = textRenderable->_leftMargin; - rightMargin = textRenderable->_rightMargin; - topMargin = textRenderable->_topMargin; - bottomMargin = textRenderable->_bottomMargin; - float fadeRatio = textRenderable->_isFading ? Interpolate::calculateFadeRatio(textRenderable->_fadeStartTime) : 1.0f; textColor = glm::vec4(textRenderable->_textColor, fadeRatio * textRenderable->_textAlpha); - textColor = EntityRenderer::calculatePulseColor(textColor, textRenderable->_pulseProperties, textRenderable->_created); - - effectColor = EntityRenderer::calculatePulseColor(textRenderable->_effectColor, textRenderable->_pulseProperties, textRenderable->_created); forward = textRenderable->_renderLayer != RenderLayer::WORLD || args->_renderMethod == render::Args::FORWARD; }); + textColor = EntityRenderer::calculatePulseColor(textColor, textRenderable->_pulseProperties, textRenderable->_created); + glm::vec3 effectColor = EntityRenderer::calculatePulseColor(textRenderable->_effectColor, textRenderable->_pulseProperties, textRenderable->_created); + if (textColor.a <= 0.0f) { return; } modelTransform.setRotation(EntityItem::getBillboardRotation(modelTransform.getTranslation(), modelTransform.getRotation(), billboardMode, args->getViewFrustum().getPosition())); - float scale = lineHeight / textRenderer->getFontSize(); + float scale = textRenderable->_lineHeight / textRenderer->getFontSize(); modelTransform.postTranslate(glm::vec3(-0.5, 0.5, 1.0f + EPSILON / dimensions.z)); modelTransform.setScale(scale); batch.setModelTransform(modelTransform); - glm::vec2 bounds = glm::vec2(dimensions.x - (leftMargin + rightMargin), dimensions.y - (topMargin + bottomMargin)); - textRenderer->draw(batch, leftMargin / scale, -topMargin / scale, bounds / scale, scale, - text, font, textColor, effectColor, effectThickness, effect, + glm::vec2 bounds = glm::vec2(dimensions.x - (textRenderable->_leftMargin + textRenderable->_rightMargin), dimensions.y - (textRenderable->_topMargin + textRenderable->_bottomMargin)); + textRenderer->draw(batch, textRenderable->_leftMargin / scale, -textRenderable->_topMargin / scale, bounds / scale, scale, + textRenderable->_text, textRenderable->_font, textColor, effectColor, textRenderable->_effectThickness, textRenderable->_effect, textRenderable->_unlit, forward); } diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.h b/libraries/entities-renderer/src/RenderableTextEntityItem.h index 87102daa32..51651d98ba 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.h +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.h @@ -42,7 +42,6 @@ protected: void onRemoveFromSceneTyped(const TypedEntityPointer& entity) override; private: - virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; virtual void doRender(RenderArgs* args) override; diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index e88ebcf19a..8b41a85cf8 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -125,16 +125,6 @@ bool WebEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointe return false; } -bool WebEntityRenderer::needsRenderUpdate() const { - if (resultWithReadLock([this] { - return !_webSurface; - })) { - return true; - } - - return Parent::needsRenderUpdate(); -} - void WebEntityRenderer::onTimeout() { uint64_t lastRenderTime; if (!resultWithReadLock([&] { @@ -261,6 +251,8 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene _renderTransform.postScale(entity->getScaledDimensions()); }); }); + } else { + emit requestRenderUpdate(); } }); } @@ -339,8 +331,11 @@ void WebEntityRenderer::buildWebSurface(const EntityItemPointer& entity, const Q return; } - ++_currentWebCount; - WebEntityRenderer::acquireWebSurface(newSourceURL, _contentType == ContentType::HtmlContent, _webSurface, _cachedWebSurface); + bool isHTML = _contentType == ContentType::HtmlContent; + if (isHTML) { + ++_currentWebCount; + } + WebEntityRenderer::acquireWebSurface(newSourceURL, isHTML, _webSurface, _cachedWebSurface); _fadeStartTime = usecTimestampNow(); _webSurface->resume(); @@ -358,12 +353,15 @@ void WebEntityRenderer::destroyWebSurface() { QSharedPointer webSurface; withWriteLock([&] { webSurface.swap(_webSurface); - _contentType = ContentType::NoContent; if (webSurface) { - --_currentWebCount; + if (_contentType == ContentType::HtmlContent) { + --_currentWebCount; + } WebEntityRenderer::releaseWebSurface(webSurface, _cachedWebSurface, _connections); } + + _contentType = ContentType::NoContent; }); } diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.h b/libraries/entities-renderer/src/RenderableWebEntityItem.h index ffd5880c1e..63ec722811 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.h +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.h @@ -55,7 +55,6 @@ public: virtual QObject* getEventHandler() override; protected: - virtual bool needsRenderUpdate() const override; virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; virtual void doRender(RenderArgs* args) override; diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index d3c9225b88..ce2dae8d28 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -189,7 +189,7 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) { CullTest::_containingZones.insert(_entityID); } -void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { +void ZoneEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { auto position = entity->getWorldPosition(); auto rotation = entity->getWorldOrientation(); auto dimensions = entity->getScaledDimensions(); @@ -199,7 +199,11 @@ void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen auto visible = entity->getVisible(); if (transformChanged || visible != _lastVisible) { _lastVisible = visible; - DependencyManager::get()->updateZone(entity->getID()); + void* key = (void*)this; + EntityItemID id = entity->getID(); + AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [id] { + DependencyManager::get()->updateZone(id); + }); } auto proceduralUserData = entity->getUserData(); @@ -267,10 +271,6 @@ ItemKey ZoneEntityRenderer::getKey() { } bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { - if (entity->getVisible() != _lastVisible) { - return true; - } - if (entity->keyLightPropertiesChanged() || entity->ambientLightPropertiesChanged() || entity->hazePropertiesChanged() || @@ -280,29 +280,11 @@ bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoint return true; } - if (_skyboxTextureURL != entity->getSkyboxProperties().getURL()) { - return true; - } - - if (entity->getWorldPosition() != _lastPosition) { - return true; - } - if (entity->getScaledDimensions() != _lastDimensions) { - return true; - } - if (entity->getWorldOrientation() != _lastRotation) { - return true; - } - - if (entity->getUserData() != _proceduralUserData) { - return true; - } - return false; } void ZoneEntityRenderer::updateKeySunFromEntity(const TypedEntityPointer& entity) { - setKeyLightMode((ComponentMode)entity->getKeyLightMode()); + _keyLightMode = (ComponentMode)entity->getKeyLightMode(); const auto& sunLight = editSunLight(); sunLight->setType(graphics::Light::SUN); @@ -319,7 +301,7 @@ void ZoneEntityRenderer::updateKeySunFromEntity(const TypedEntityPointer& entity } void ZoneEntityRenderer::updateAmbientLightFromEntity(const TypedEntityPointer& entity) { - setAmbientLightMode((ComponentMode)entity->getAmbientLightMode()); + _ambientLightMode = (ComponentMode)entity->getAmbientLightMode(); const auto& ambientLight = editAmbientLight(); ambientLight->setType(graphics::Light::AMBIENT); @@ -339,11 +321,12 @@ void ZoneEntityRenderer::updateAmbientLightFromEntity(const TypedEntityPointer& } void ZoneEntityRenderer::updateHazeFromEntity(const TypedEntityPointer& entity) { - setHazeMode((ComponentMode)entity->getHazeMode()); + const uint32_t hazeMode = entity->getHazeMode(); + + _hazeMode = (ComponentMode)hazeMode; const auto& haze = editHaze(); - const uint32_t hazeMode = entity->getHazeMode(); haze->setHazeActive(hazeMode == COMPONENT_MODE_ENABLED); haze->setAltitudeBased(_hazeProperties.getHazeAltitudeEffect()); @@ -367,7 +350,7 @@ void ZoneEntityRenderer::updateHazeFromEntity(const TypedEntityPointer& entity) } void ZoneEntityRenderer::updateBloomFromEntity(const TypedEntityPointer& entity) { - setBloomMode((ComponentMode)entity->getBloomMode()); + _bloomMode = (ComponentMode)entity->getBloomMode(); const auto& bloom = editBloom(); @@ -377,7 +360,7 @@ void ZoneEntityRenderer::updateBloomFromEntity(const TypedEntityPointer& entity) } void ZoneEntityRenderer::updateKeyBackgroundFromEntity(const TypedEntityPointer& entity) { - setSkyboxMode((ComponentMode)entity->getSkyboxMode()); + _skyboxMode = (ComponentMode)entity->getSkyboxMode(); editBackground(); setSkyboxColor(toGlm(_skyboxProperties.getColor())); @@ -478,26 +461,6 @@ void ZoneEntityRenderer::updateSkyboxMap() { } } -void ZoneEntityRenderer::setHazeMode(ComponentMode mode) { - _hazeMode = mode; -} - -void ZoneEntityRenderer::setKeyLightMode(ComponentMode mode) { - _keyLightMode = mode; -} - -void ZoneEntityRenderer::setAmbientLightMode(ComponentMode mode) { - _ambientLightMode = mode; -} - -void ZoneEntityRenderer::setSkyboxMode(ComponentMode mode) { - _skyboxMode = mode; -} - -void ZoneEntityRenderer::setBloomMode(ComponentMode mode) { - _bloomMode = mode; -} - void ZoneEntityRenderer::setSkyboxColor(const glm::vec3& color) { editSkybox()->setColor(color); } diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h index d4e3d16408..d2ee90b1e4 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h @@ -38,7 +38,7 @@ protected: virtual ItemKey getKey() override; virtual void doRender(RenderArgs* args) override; virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; - virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; + virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; private: void updateKeyZoneItemFromEntity(const TypedEntityPointer& entity); @@ -52,12 +52,6 @@ private: void setAmbientURL(const QString& ambientUrl); void setSkyboxURL(const QString& skyboxUrl); - void setHazeMode(ComponentMode mode); - void setKeyLightMode(ComponentMode mode); - void setAmbientLightMode(ComponentMode mode); - void setSkyboxMode(ComponentMode mode); - void setBloomMode(ComponentMode mode); - void setSkyboxColor(const glm::vec3& color); void setProceduralUserData(const QString& userData); diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index ddedf0db18..d7a5e992e1 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1911,13 +1911,11 @@ void EntityItem::setUnscaledDimensions(const glm::vec3& value) { if (glm::length2(getUnscaledDimensions() - newDimensions) > MIN_SCALE_CHANGE_SQUARED) { withWriteLock([&] { _unscaledDimensions = newDimensions; - }); - locationChanged(); - dimensionsChanged(); - withWriteLock([&] { _flags |= (Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); _queryAACubeSet = false; }); + locationChanged(); + dimensionsChanged(); } } diff --git a/libraries/entities/src/LightEntityItem.cpp b/libraries/entities/src/LightEntityItem.cpp index 715b457bde..0dcb5d125a 100644 --- a/libraries/entities/src/LightEntityItem.cpp +++ b/libraries/entities/src/LightEntityItem.cpp @@ -78,7 +78,14 @@ void LightEntityItem::setFalloffRadius(float value) { } void LightEntityItem::setIsSpotlight(bool value) { - if (value == getIsSpotlight()) { + bool needsRenderUpdate; + withWriteLock([&] { + needsRenderUpdate = value != _isSpotlight; + _needsRenderUpdate |= needsRenderUpdate; + _isSpotlight = value; + }); + + if (!needsRenderUpdate) { return; } @@ -92,25 +99,25 @@ void LightEntityItem::setIsSpotlight(bool value) { newDimensions = glm::vec3(glm::compMax(dimensions)); } - withWriteLock([&] { - _needsRenderUpdate = true; - _isSpotlight = value; - }); setScaledDimensions(newDimensions); } void LightEntityItem::setCutoff(float value) { value = glm::clamp(value, MIN_CUTOFF, MAX_CUTOFF); - if (value == getCutoff()) { + bool needsRenderUpdate; + bool spotlight; + withWriteLock([&] { + needsRenderUpdate = value != _cutoff; + _needsRenderUpdate |= needsRenderUpdate; + _cutoff = value; + spotlight = _isSpotlight; + }); + + if (!needsRenderUpdate) { return; } - withWriteLock([&] { - _needsRenderUpdate = true; - _cutoff = value; - }); - - if (getIsSpotlight()) { + if (spotlight) { // If we are a spotlight, adjusting the cutoff will affect the area we encapsulate, // so update the dimensions to reflect this. const float length = getScaledDimensions().z; diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index cd27c1cf36..4716db6a41 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -254,26 +254,30 @@ void ModelEntityItem::debugDump() const { } void ModelEntityItem::setShapeType(ShapeType type) { + bool changed = false; + uint32_t flags = 0; withWriteLock([&] { if (type != _shapeType) { if (type == SHAPE_TYPE_STATIC_MESH && _dynamic) { // dynamic and STATIC_MESH are incompatible // since the shape is being set here we clear the dynamic bit _dynamic = false; - _flags |= Simulation::DIRTY_MOTION_TYPE; + flags = Simulation::DIRTY_MOTION_TYPE; } _shapeType = type; - _flags |= Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS; + flags |= Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS; + changed = true; } }); + + if (changed) { + markDirtyFlags(flags); + locationChanged(); + } } ShapeType ModelEntityItem::getShapeType() const { - return computeTrueShapeType(); -} - -ShapeType ModelEntityItem::computeTrueShapeType() const { - ShapeType type = _shapeType; + ShapeType type = resultWithReadLock([&] { return _shapeType; }); if (type == SHAPE_TYPE_STATIC_MESH && _dynamic) { // dynamic is incompatible with STATIC_MESH // shouldn't fall in here but just in case --> fall back to COMPOUND @@ -290,7 +294,6 @@ void ModelEntityItem::setModelURL(const QString& url) { withWriteLock([&] { if (_modelURL != url) { _modelURL = url; - _flags |= Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS; _needsRenderUpdate = true; } }); @@ -325,18 +328,10 @@ void ModelEntityItem::setCompoundShapeURL(const QString& url) { withWriteLock([&] { if (_compoundShapeURL.get() != url) { _compoundShapeURL.set(url); - _flags |= Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS; } }); } -void ModelEntityItem::setAnimationURL(const QString& url) { - _flags |= Simulation::DIRTY_UPDATEABLE; - withWriteLock([&] { - _animationProperties.setURL(url); - }); -} - void ModelEntityItem::setAnimationSettings(const QString& value) { // NOTE: this method only called for old bitstream format @@ -399,20 +394,6 @@ void ModelEntityItem::setAnimationSettings(const QString& value) { }); } -void ModelEntityItem::setAnimationIsPlaying(bool value) { - _flags |= Simulation::DIRTY_UPDATEABLE; - withWriteLock([&] { - _animationProperties.setRunning(value); - }); -} - -void ModelEntityItem::setAnimationFPS(float value) { - _flags |= Simulation::DIRTY_UPDATEABLE; - withWriteLock([&] { - _animationProperties.setFPS(value); - }); -} - void ModelEntityItem::resizeJointArrays(int newSize) { if (newSize < 0) { return; @@ -588,10 +569,6 @@ QString ModelEntityItem::getCompoundShapeURL() const { return _compoundShapeURL.get(); } -QString ModelEntityItem::getCollisionShapeURL() const { - return getShapeType() == SHAPE_TYPE_COMPOUND ? getCompoundShapeURL() : getModelURL(); -} - void ModelEntityItem::setColor(const glm::u8vec3& value) { withWriteLock([&] { _color = value; @@ -629,61 +606,18 @@ void ModelEntityItem::setAnimationCurrentFrame(float value) { }); } -void ModelEntityItem::setAnimationAllowTranslation(bool value) { - withWriteLock([&] { - _animationProperties.setAllowTranslation(value); - }); -} - bool ModelEntityItem::getAnimationAllowTranslation() const { return resultWithReadLock([&] { return _animationProperties.getAllowTranslation(); }); } -void ModelEntityItem::setAnimationLoop(bool loop) { - withWriteLock([&] { - _animationProperties.setLoop(loop); - }); -} - -bool ModelEntityItem::getAnimationLoop() const { - return resultWithReadLock([&] { - return _animationProperties.getLoop(); - }); -} - - -void ModelEntityItem::setAnimationHold(bool hold) { - withWriteLock([&] { - _animationProperties.setHold(hold); - }); -} - -bool ModelEntityItem::getAnimationHold() const { - return resultWithReadLock([&] { - return _animationProperties.getHold(); - }); -} - -bool ModelEntityItem::getAnimationIsPlaying() const { - return resultWithReadLock([&] { - return _animationProperties.getRunning(); - }); -} - float ModelEntityItem::getAnimationCurrentFrame() const { return resultWithReadLock([&] { return _animationProperties.getCurrentFrame(); }); } -float ModelEntityItem::getAnimationFPS() const { - return resultWithReadLock([&] { - return _animationProperties.getFPS(); - }); -} - bool ModelEntityItem::isAnimatingSomething() const { return resultWithReadLock([&] { return _animationProperties.isValidAndRunning(); @@ -722,6 +656,7 @@ bool ModelEntityItem::applyNewAnimationProperties(AnimationPropertyGroup newProp bool somethingChanged = newProperties != _animationProperties; if (somethingChanged) { _animationProperties = newProperties; + _needsRenderUpdate = true; _flags |= Simulation::DIRTY_UPDATEABLE; } return somethingChanged; diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 795630a72a..b835b48d13 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -76,33 +76,18 @@ public: static const QString DEFAULT_COMPOUND_SHAPE_URL; QString getCompoundShapeURL() const; - // Returns the URL used for the collision shape - QString getCollisionShapeURL() const; - // model related properties virtual void setModelURL(const QString& url); virtual void setCompoundShapeURL(const QString& url); // Animation related items... AnimationPropertyGroup getAnimationProperties() const; - - // TODO: audit and remove unused Animation accessors bool hasAnimation() const; QString getAnimationURL() const; - virtual void setAnimationURL(const QString& url); - void setAnimationCurrentFrame(float value); - void setAnimationIsPlaying(bool value); - void setAnimationFPS(float value); - - void setAnimationAllowTranslation(bool value); + float getAnimationCurrentFrame() const; bool getAnimationAllowTranslation() const; - - void setAnimationLoop(bool loop); - bool getAnimationLoop() const; - - void setAnimationHold(bool hold); - bool getAnimationHold() const; + bool isAnimatingSomething() const; void setRelayParentJoints(bool relayJoints); bool getRelayParentJoints() const; @@ -110,11 +95,6 @@ public: void setGroupCulled(bool value); bool getGroupCulled() const; - bool getAnimationIsPlaying() const; - float getAnimationCurrentFrame() const; - float getAnimationFPS() const; - bool isAnimatingSomething() const; - static const QString DEFAULT_TEXTURES; const QString getTextures() const; void setTextures(const QString& textures); @@ -142,7 +122,6 @@ public: private: void setAnimationSettings(const QString& value); // only called for old bitstream format bool applyNewAnimationProperties(AnimationPropertyGroup newProperties); - ShapeType computeTrueShapeType() const; protected: void resizeJointArrays(int newSize); diff --git a/libraries/entities/src/PolyLineEntityItem.cpp b/libraries/entities/src/PolyLineEntityItem.cpp index 909bc132fb..4aaf0ad521 100644 --- a/libraries/entities/src/PolyLineEntityItem.cpp +++ b/libraries/entities/src/PolyLineEntityItem.cpp @@ -266,21 +266,21 @@ glm::u8vec3 PolyLineEntityItem::getColor() const { void PolyLineEntityItem::setIsUVModeStretch(bool isUVModeStretch) { withWriteLock([&] { - _needsRenderUpdate = _isUVModeStretch != isUVModeStretch; + _needsRenderUpdate |= _isUVModeStretch != isUVModeStretch; _isUVModeStretch = isUVModeStretch; }); } void PolyLineEntityItem::setGlow(bool glow) { withWriteLock([&] { - _needsRenderUpdate = _glow != glow; + _needsRenderUpdate |= _glow != glow; _glow = glow; }); } void PolyLineEntityItem::setFaceCamera(bool faceCamera) { withWriteLock([&] { - _needsRenderUpdate = _faceCamera != faceCamera; + _needsRenderUpdate |= _faceCamera != faceCamera; _faceCamera = faceCamera; }); } diff --git a/libraries/entities/src/ShapeEntityItem.cpp b/libraries/entities/src/ShapeEntityItem.cpp index 5e140665b3..3dbb02775a 100644 --- a/libraries/entities/src/ShapeEntityItem.cpp +++ b/libraries/entities/src/ShapeEntityItem.cpp @@ -442,4 +442,11 @@ PulsePropertyGroup ShapeEntityItem::getPulseProperties() const { return resultWithReadLock([&] { return _pulseProperties; }); +} + +void ShapeEntityItem::setUserData(const QString& value) { + withWriteLock([&] { + _needsRenderUpdate |= _userData != value; + _userData = value; + }); } \ No newline at end of file diff --git a/libraries/entities/src/ShapeEntityItem.h b/libraries/entities/src/ShapeEntityItem.h index 7320867430..c0dc9642fe 100644 --- a/libraries/entities/src/ShapeEntityItem.h +++ b/libraries/entities/src/ShapeEntityItem.h @@ -101,6 +101,8 @@ public: PulsePropertyGroup getPulseProperties() const; + void setUserData(const QString& value) override; + protected: glm::u8vec3 _color; float _alpha { 1.0f }; diff --git a/libraries/entities/src/ZoneEntityItem.cpp b/libraries/entities/src/ZoneEntityItem.cpp index 88466caff0..8b020e92d5 100644 --- a/libraries/entities/src/ZoneEntityItem.cpp +++ b/libraries/entities/src/ZoneEntityItem.cpp @@ -84,12 +84,12 @@ bool ZoneEntityItem::setSubClassProperties(const EntityItemProperties& propertie // Contains a QString property, must be synchronized withWriteLock([&] { - _keyLightPropertiesChanged = _keyLightProperties.setProperties(properties); - _ambientLightPropertiesChanged = _ambientLightProperties.setProperties(properties); - _skyboxPropertiesChanged = _skyboxProperties.setProperties(properties); + _keyLightPropertiesChanged |= _keyLightProperties.setProperties(properties); + _ambientLightPropertiesChanged |= _ambientLightProperties.setProperties(properties); + _skyboxPropertiesChanged |= _skyboxProperties.setProperties(properties); }); - _hazePropertiesChanged = _hazeProperties.setProperties(properties); - _bloomPropertiesChanged = _bloomProperties.setProperties(properties); + _hazePropertiesChanged |= _hazeProperties.setProperties(properties); + _bloomPropertiesChanged |= _bloomProperties.setProperties(properties); SET_ENTITY_PROPERTY_FROM_PROPERTIES(flyingAllowed, setFlyingAllowed); SET_ENTITY_PROPERTY_FROM_PROPERTIES(ghostingAllowed, setGhostingAllowed); @@ -125,7 +125,7 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, bytesFromKeylight = _keyLightProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData, _keyLightPropertiesChanged); }); - somethingChanged = somethingChanged || _keyLightPropertiesChanged; + somethingChanged |= _keyLightPropertiesChanged; bytesRead += bytesFromKeylight; dataAt += bytesFromKeylight; } @@ -136,7 +136,7 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, bytesFromAmbientlight = _ambientLightProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData, _ambientLightPropertiesChanged); }); - somethingChanged = somethingChanged || _ambientLightPropertiesChanged; + somethingChanged |= _ambientLightPropertiesChanged; bytesRead += bytesFromAmbientlight; dataAt += bytesFromAmbientlight; } @@ -147,7 +147,7 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, bytesFromSkybox = _skyboxProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData, _skyboxPropertiesChanged); }); - somethingChanged = somethingChanged || _skyboxPropertiesChanged; + somethingChanged |= _skyboxPropertiesChanged; bytesRead += bytesFromSkybox; dataAt += bytesFromSkybox; } @@ -155,7 +155,7 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, { int bytesFromHaze = _hazeProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData, _hazePropertiesChanged); - somethingChanged = somethingChanged || _hazePropertiesChanged; + somethingChanged |= _hazePropertiesChanged; bytesRead += bytesFromHaze; dataAt += bytesFromHaze; } @@ -163,7 +163,7 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, { int bytesFromBloom = _bloomProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData, _bloomPropertiesChanged); - somethingChanged = somethingChanged || _bloomPropertiesChanged; + somethingChanged |= _bloomPropertiesChanged; bytesRead += bytesFromBloom; dataAt += bytesFromBloom; } @@ -444,6 +444,13 @@ uint32_t ZoneEntityItem::getSkyboxMode() const { return _skyboxMode; } +void ZoneEntityItem::setUserData(const QString& value) { + withWriteLock([&] { + _needsRenderUpdate |= _userData != value; + _userData = value; + }); +} + void ZoneEntityItem::fetchCollisionGeometryResource() { QUrl hullURL(getCompoundShapeURL()); if (hullURL.isEmpty()) { diff --git a/libraries/entities/src/ZoneEntityItem.h b/libraries/entities/src/ZoneEntityItem.h index dda03f9115..9c8e3839b7 100644 --- a/libraries/entities/src/ZoneEntityItem.h +++ b/libraries/entities/src/ZoneEntityItem.h @@ -104,6 +104,8 @@ public: uint32_t getScreenshare() const { return _screenshare; } void setScreenshare(uint32_t value) { _screenshare = value; } + void setUserData(const QString& value) override; + bool keyLightPropertiesChanged() const { return _keyLightPropertiesChanged; } bool ambientLightPropertiesChanged() const { return _ambientLightPropertiesChanged; } bool skyboxPropertiesChanged() const { return _skyboxPropertiesChanged; } diff --git a/libraries/gl/src/gl/GLWidget.cpp b/libraries/gl/src/gl/GLWidget.cpp index 94702a9906..45c8e70659 100644 --- a/libraries/gl/src/gl/GLWidget.cpp +++ b/libraries/gl/src/gl/GLWidget.cpp @@ -35,11 +35,6 @@ class GLPaintEngine : public QPaintEngine { }; GLWidget::GLWidget() { -#ifdef Q_OS_LINUX - // Cause GLWidget::eventFilter to be called. - // It wouldn't hurt to do this on Mac and PC too; but apparently it's only needed on linux. - qApp->installEventFilter(this); -#endif setAttribute(Qt::WA_AcceptTouchEvents); setAttribute(Qt::WA_NativeWindow); setAttribute(Qt::WA_PaintOnScreen); @@ -118,39 +113,6 @@ bool GLWidget::event(QEvent* event) { return QWidget::event(event); } -// Pressing Alt (and Meta) key alone activates the menubar because its style inherits the -// SHMenuBarAltKeyNavigation from QWindowsStyle. This makes it impossible for a scripts to -// receive keyPress events for the Alt (and Meta) key in a reliable manner. -// -// This filter catches events before QMenuBar can steal the keyboard focus. -// The idea was borrowed from -// http://www.archivum.info/qt-interest@trolltech.com/2006-09/00053/Re-(Qt4)-Alt-key-focus-QMenuBar-(solved).html - -bool GLWidget::eventFilter(QObject*, QEvent* event) { - switch (event->type()) { - case QEvent::KeyPress: - case QEvent::KeyRelease: - case QEvent::ShortcutOverride: - { - QKeyEvent* keyEvent = static_cast(event); - if (keyEvent->key() == Qt::Key_Alt || keyEvent->key() == Qt::Key_Meta) { - if (event->type() == QEvent::KeyPress) { - keyPressEvent(keyEvent); - } else if (event->type() == QEvent::KeyRelease) { - keyReleaseEvent(keyEvent); - } else { - QWidget::event(event); - } - return true; - } - } - default: - break; - } - return false; -} - - bool GLWidget::nativeEvent(const QByteArray &eventType, void *message, long *result) { #ifdef Q_OS_WIN32 MSG* win32message = static_cast(message); diff --git a/libraries/gl/src/gl/GLWidget.h b/libraries/gl/src/gl/GLWidget.h index 777d43e8af..9d5c8800bb 100644 --- a/libraries/gl/src/gl/GLWidget.h +++ b/libraries/gl/src/gl/GLWidget.h @@ -42,9 +42,6 @@ protected: virtual bool event(QEvent* event) override; gl::Context* _context { nullptr }; -private slots: - virtual bool eventFilter(QObject*, QEvent* event) override; - private: QPaintEngine* _paintEngine { nullptr }; bool _vsyncSupported { false }; diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp index 38aca093cd..8126988294 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp @@ -153,7 +153,7 @@ void GLBackend::init() { if (vendor.contains("NVIDIA") ) { qCDebug(gpugllogging) << "NVIDIA card detected"; -#if !defined(Q_OS_ANDROID) +#if !defined(Q_OS_ANDROID) && !defined(USE_GLES) GL_GET_INTEGER(GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX); GL_GET_INTEGER(GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX); GL_GET_INTEGER(GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX); @@ -170,7 +170,7 @@ void GLBackend::init() { } else if (vendor.contains("ATI")) { qCDebug(gpugllogging) << "ATI card detected"; -#if !defined(Q_OS_ANDROID) +#if !defined(Q_OS_ANDROID) && !defined(USE_GLES) GL_GET_INTEGER(TEXTURE_FREE_MEMORY_ATI); #endif @@ -225,12 +225,12 @@ size_t GLBackend::getAvailableMemory() { switch( _videoCard ) { case NVIDIA: -#if !defined(Q_OS_ANDROID) +#if !defined(Q_OS_ANDROID) && !defined(USE_GLES) glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &mem[0]); #endif return mem[0] * BYTES_PER_KIB; case ATI: -#if !defined(Q_OS_ANDROID) +#if !defined(Q_OS_ANDROID) && !defined(USE_GLES) glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, &mem[0]); #endif return mem[0] * BYTES_PER_KIB; diff --git a/libraries/networking/src/NetworkingConstants.h b/libraries/networking/src/NetworkingConstants.h index 58cefb35ad..b64a0845ac 100644 --- a/libraries/networking/src/NetworkingConstants.h +++ b/libraries/networking/src/NetworkingConstants.h @@ -72,7 +72,7 @@ namespace NetworkingConstants { const QUrl HELP_FORUM_URL { "https://forums.vircadia.dev" }; const QUrl HELP_SCRIPTING_REFERENCE_URL{ "https://apidocs.vircadia.dev/" }; const QUrl HELP_RELEASE_NOTES_URL{ "https://docs.vircadia.dev/release-notes.html" }; - const QUrl HELP_BUG_REPORT_URL{ "https://github.com/kasenvr/project-athena/issues" }; + const QUrl HELP_BUG_REPORT_URL{ "https://github.com/vircadia/vircadia/issues" }; const QString DEFAULT_VIRCADIA_ADDRESS = "file:///~/serverless/tutorial.json"; const QString DEFAULT_HOME_ADDRESS = "file:///~/serverless/tutorial.json"; diff --git a/libraries/oculusMobile/src/ovr/Helpers.h b/libraries/oculusMobile/src/ovr/Helpers.h index 2bd0b7f603..10058dbac8 100644 --- a/libraries/oculusMobile/src/ovr/Helpers.h +++ b/libraries/oculusMobile/src/ovr/Helpers.h @@ -31,9 +31,9 @@ static inline void for_each_eye(const std::function& f) { f(VRAPI_EYE_RIGHT); } -static inline void for_each_hand(const std::function& f) { - f(VRAPI_HAND_LEFT); - f(VRAPI_HAND_RIGHT); +static inline void for_each_hand(const std::function& f) { + f(VRAPI_TRACKED_DEVICE_HAND_LEFT); + f(VRAPI_TRACKED_DEVICE_HAND_RIGHT); } static inline glm::mat4 toGlm(const ovrMatrix4f& om) { diff --git a/libraries/oculusMobile/src/ovr/VrHandler.cpp b/libraries/oculusMobile/src/ovr/VrHandler.cpp index aff1f256b5..1fe4d19401 100644 --- a/libraries/oculusMobile/src/ovr/VrHandler.cpp +++ b/libraries/oculusMobile/src/ovr/VrHandler.cpp @@ -324,7 +324,7 @@ struct VrSurface : public TaskQueue { vrapi_SetTrackingSpace( session, VRAPI_TRACKING_SPACE_LOCAL); vrapi_SetPerfThread(session, VRAPI_PERF_THREAD_TYPE_RENDERER, gettid()); vrapi_SetClockLevels(session, 2, 4); - vrapi_SetExtraLatencyMode(session, VRAPI_EXTRA_LATENCY_MODE_DYNAMIC); + vrapi_SetExtraLatencyMode(session, VRAPI_EXTRA_LATENCY_MODE_ON); // Generates a warning on the quest: "vrapi_SetDisplayRefreshRate: Dynamic Display Refresh Rate not supported" // vrapi_SetDisplayRefreshRate(session, 72); }); diff --git a/libraries/oculusMobilePlugin/src/OculusMobileControllerManager.cpp b/libraries/oculusMobilePlugin/src/OculusMobileControllerManager.cpp index 705045b517..54a796954e 100644 --- a/libraries/oculusMobilePlugin/src/OculusMobileControllerManager.cpp +++ b/libraries/oculusMobilePlugin/src/OculusMobileControllerManager.cpp @@ -31,7 +31,7 @@ const quint64 LOST_TRACKING_DELAY = 3000000; namespace ovr { - controller::Pose toControllerPose(ovrHandedness hand, const ovrRigidBodyPosef& handPose) { + controller::Pose toControllerPose(ovrTrackedDeviceTypeId hand, const ovrRigidBodyPosef& handPose) { // When the sensor-to-world rotation is identity the coordinate axes look like this: // // user @@ -111,7 +111,7 @@ namespace ovr { return pose; } - controller::Pose toControllerPose(ovrHandedness hand, + controller::Pose toControllerPose(ovrTrackedDeviceTypeId hand, const ovrRigidBodyPosef& handPose, const ovrRigidBodyPosef& lastHandPose) { static const glm::quat yFlip = glm::angleAxis(PI, Vectors::UNIT_Y); @@ -165,9 +165,9 @@ public: private: void handlePose(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, - ovrHandedness hand, const ovrRigidBodyPosef& handPose); + ovrTrackedDeviceTypeId hand, const ovrRigidBodyPosef& handPose); void handleRotationForUntrackedHand(const controller::InputCalibrationData& inputCalibrationData, - ovrHandedness hand, const ovrRigidBodyPosef& handPose); + ovrTrackedDeviceTypeId hand, const ovrRigidBodyPosef& handPose); void handleHeadPose(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, const ovrRigidBodyPosef& headPose); @@ -379,9 +379,9 @@ void OculusMobileInputDevice::update(float deltaTime, const controller::InputCal handleHeadPose(deltaTime, inputCalibrationData, _headTracking.HeadPose); static const auto REQUIRED_HAND_STATUS = VRAPI_TRACKING_STATUS_ORIENTATION_TRACKED | VRAPI_TRACKING_STATUS_POSITION_TRACKED; - ovr::for_each_hand([&](ovrHandedness hand) { - size_t handIndex = (hand == VRAPI_HAND_LEFT) ? 0 : 1; - int controller = (hand == VRAPI_HAND_LEFT) ? controller::LEFT_HAND : controller::RIGHT_HAND; + ovr::for_each_hand([&](ovrTrackedDeviceTypeId hand) { + size_t handIndex = (hand == VRAPI_TRACKED_DEVICE_HAND_LEFT) ? 0 : 1; + int controller = (hand == VRAPI_TRACKED_DEVICE_HAND_LEFT) ? controller::LEFT_HAND : controller::RIGHT_HAND; auto& handData = _hands[handIndex]; const auto& tracking = handData.tracking; ++numTrackedControllers; @@ -476,7 +476,7 @@ void OculusMobileInputDevice::focusOutEvent() { void OculusMobileInputDevice::handlePose(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, - ovrHandedness hand, const ovrRigidBodyPosef& handPose) { + ovrTrackedDeviceTypeId hand, const ovrRigidBodyPosef& handPose) { auto poseId = (hand == VRAPI_HAND_LEFT) ? controller::LEFT_HAND : controller::RIGHT_HAND; auto& pose = _poseStateMap[poseId]; pose = ovr::toControllerPose(hand, handPose); @@ -507,7 +507,7 @@ void OculusMobileInputDevice::handleHeadPose(float deltaTime, } void OculusMobileInputDevice::handleRotationForUntrackedHand(const controller::InputCalibrationData& inputCalibrationData, - ovrHandedness hand, const ovrRigidBodyPosef& handPose) { + ovrTrackedDeviceTypeId hand, const ovrRigidBodyPosef& handPose) { auto poseId = (hand == VRAPI_HAND_LEFT ? controller::LEFT_HAND : controller::RIGHT_HAND); auto& pose = _poseStateMap[poseId]; const auto& lastHandPose = (hand == VRAPI_HAND_LEFT) ? _hands[0].lastPose : _hands[1].lastPose; diff --git a/libraries/physics/src/PhysicalEntitySimulation.cpp b/libraries/physics/src/PhysicalEntitySimulation.cpp index 4a2ee9184f..d0d900e14d 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.cpp +++ b/libraries/physics/src/PhysicalEntitySimulation.cpp @@ -425,12 +425,12 @@ void PhysicalEntitySimulation::buildPhysicsTransaction(PhysicsEngine::Transactio continue; } - bool needsNewShape = object->needsNewShape(); + bool needsNewShape = object->needsNewShape() && object->_entity->isReadyToComputeShape(); if (needsNewShape) { ShapeType shapeType = object->getShapeType(); if (shapeType == SHAPE_TYPE_STATIC_MESH) { ShapeRequest shapeRequest(object->_entity); - ShapeRequests::iterator requestItr = _shapeRequests.find(shapeRequest); + ShapeRequests::iterator requestItr = _shapeRequests.find(shapeRequest); if (requestItr == _shapeRequests.end()) { ShapeInfo shapeInfo; object->_entity->computeShapeInfo(shapeInfo); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 182b83762c..9ad343639d 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -338,7 +338,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g bool intersectedSomething = false; // if we aren't active, we can't pick yet... - if (!isActive()) { + if (!isLoaded()) { return intersectedSomething; } @@ -493,7 +493,7 @@ bool Model::findParabolaIntersectionAgainstSubMeshes(const glm::vec3& origin, co bool intersectedSomething = false; // if we aren't active, we can't pick yet... - if (!isActive()) { + if (!isLoaded()) { return intersectedSomething; } @@ -958,16 +958,42 @@ void Model::setCauterized(bool cauterized, const render::ScenePointer& scene) { } } -void Model::setPrimitiveMode(PrimitiveMode primitiveMode) { +void Model::setPrimitiveMode(PrimitiveMode primitiveMode, const render::ScenePointer& scene) { if (_primitiveMode != primitiveMode) { _primitiveMode = primitiveMode; - updateRenderItemsKey(nullptr); + if (!scene) { + _needsFixupInScene = true; + return; + } + + bool useDualQuaternionSkinning = _useDualQuaternionSkinning; + std::unordered_map shouldInvalidatePayloadShapeKeyMap; + + for (auto& shape : _modelMeshRenderItemShapes) { + shouldInvalidatePayloadShapeKeyMap[shape.meshIndex] = shouldInvalidatePayloadShapeKey(shape.meshIndex); + } + + render::Transaction transaction; + + for (int i = 0; i < (int)_modelMeshRenderItemIDs.size(); i++) { + auto itemID = _modelMeshRenderItemIDs[i]; + auto meshIndex = _modelMeshRenderItemShapes[i].meshIndex; + bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex); + transaction.updateItem(itemID, [invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning] (ModelMeshPartPayload& data) { + data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning); + }); + } + scene->enqueueTransaction(transaction); } } -void Model::setCullWithParent(bool cullWithParent) { +void Model::setCullWithParent(bool cullWithParent, const render::ScenePointer& scene) { if (_cullWithParent != cullWithParent) { _cullWithParent = cullWithParent; + if (!scene) { + _needsFixupInScene = true; + return; + } render::Transaction transaction; auto renderItemsKey = _renderItemKeyGlobalFlags; @@ -977,14 +1003,27 @@ void Model::setCullWithParent(bool cullWithParent) { data.updateKey(renderItemsKey); }); } - AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); + scene->enqueueTransaction(transaction); } } -void Model::setRenderWithZones(const QVector& renderWithZones) { +void Model::setRenderWithZones(const QVector& renderWithZones, const render::ScenePointer& scene) { if (_renderWithZones != renderWithZones) { _renderWithZones = renderWithZones; - setRenderItemsNeedUpdate(); + + if (!scene) { + _needsFixupInScene = true; + return; + } + + render::Transaction transaction; + auto renderItemsKey = _renderItemKeyGlobalFlags; + for (auto item : _modelMeshRenderItemIDs) { + transaction.updateItem(item, [renderWithZones, renderItemsKey](ModelMeshPartPayload& data) { + data.setRenderWithZones(renderWithZones); + }); + } + scene->enqueueTransaction(transaction); } } @@ -1129,7 +1168,7 @@ void Model::renderDebugMeshBoxes(gpu::Batch& batch, bool forward) { } Extents Model::getBindExtents() const { - if (!isActive()) { + if (!isLoaded()) { return Extents(); } const Extents& bindExtents = getHFMModel().bindExtents; @@ -1143,7 +1182,7 @@ glm::vec3 Model::getNaturalDimensions() const { } Extents Model::getMeshExtents() const { - if (!isActive()) { + if (!isLoaded()) { return Extents(); } const Extents& extents = getHFMModel().meshExtents; @@ -1157,7 +1196,7 @@ Extents Model::getMeshExtents() const { } Extents Model::getUnscaledMeshExtents() const { - if (!isActive()) { + if (!isLoaded()) { return Extents(); } @@ -1189,7 +1228,7 @@ void Model::setJointTranslation(int index, bool valid, const glm::vec3& translat } int Model::getParentJointIndex(int jointIndex) const { - return (isActive() && jointIndex != -1) ? getHFMModel().joints.at(jointIndex).parentIndex : -1; + return (isLoaded() && jointIndex != -1) ? getHFMModel().joints.at(jointIndex).parentIndex : -1; } void Model::setTextures(const QVariantMap& textures) { @@ -1290,7 +1329,7 @@ QStringList Model::getJointNames() const { Q_RETURN_ARG(QStringList, result)); return result; } - return isActive() ? getHFMModel().getJointNames() : QStringList(); + return isLoaded() ? getHFMModel().getJointNames() : QStringList(); } void Model::setScaleToFit(bool scaleToFit, const glm::vec3& dimensions, bool forceRescale) { @@ -1306,7 +1345,7 @@ void Model::setScaleToFit(bool scaleToFit, float largestDimension, bool forceRes // mesh, and so we can't do the needed calculations for scaling to fit to a single largest dimension. In this // case we will record that we do want to do this, but we will stick our desired single dimension into the // first element of the vec3 for the non-fixed aspect ration dimensions - if (!isActive()) { + if (!isLoaded()) { _scaleToFit = scaleToFit; if (scaleToFit) { _scaleToFitDimensions = glm::vec3(largestDimension, FAKE_DIMENSION_PLACEHOLDER, FAKE_DIMENSION_PLACEHOLDER); @@ -1387,7 +1426,7 @@ void Model::simulate(float deltaTime, bool fullUpdate) { fullUpdate = updateGeometry() || fullUpdate || (_scaleToFit && !_scaledToFit) || (_snapModelToRegistrationPoint && !_snappedToRegistrationPoint); - if (isActive() && fullUpdate) { + if (isLoaded() && fullUpdate) { onInvalidate(); // check for scale to fit @@ -1454,7 +1493,6 @@ void Model::updateBlendshapes() { } void Model::deleteGeometry() { - _deleteGeometryCounter++; _meshStates.clear(); _rig.destroyAnimGraph(); _blendedBlendshapeCoefficients.clear(); diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 4585ad0009..1e7ab55d5a 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -116,14 +116,14 @@ public: void setHifiRenderLayer(render::hifi::Layer layer, const render::ScenePointer& scene = nullptr); bool isCauterized() const { return _cauterized; } - void setCauterized(bool value, const render::ScenePointer& scene); + void setCauterized(bool value, const render::ScenePointer& scene = nullptr); - void setPrimitiveMode(PrimitiveMode primitiveMode); + void setPrimitiveMode(PrimitiveMode primitiveMode, const render::ScenePointer& scene = nullptr); PrimitiveMode getPrimitiveMode() const { return _primitiveMode; } - void setCullWithParent(bool value); + void setCullWithParent(bool value, const render::ScenePointer& scene = nullptr); - void setRenderWithZones(const QVector& renderWithZones); + void setRenderWithZones(const QVector& renderWithZones, const render::ScenePointer& scene = nullptr); const QVector& getRenderWithZones() const { return _renderWithZones; } // Access the current RenderItemKey Global Flags used by the model and applied to the render items representing the parts of the model. @@ -183,10 +183,7 @@ public: const HFMModel& getHFMModel() const { assert(isLoaded()); return _renderGeometry->getHFMModel(); } const MaterialMapping& getMaterialMapping() const { assert(isLoaded()); return _renderGeometry->getMaterialMapping(); } - bool isActive() const { return isLoaded(); } - bool didVisualGeometryRequestFail() const { return _visualGeometryRequestFailed; } - bool didCollisionGeometryRequestFail() const { return _collisionGeometryRequestFailed; } glm::mat4 getWorldToHFMMatrix() const; @@ -338,7 +335,6 @@ public: const MeshState& getMeshState(int index) { return _meshStates.at(index); } - uint32_t getGeometryCounter() const { return _deleteGeometryCounter; } const QMap& getRenderItems() const { return _modelMeshRenderItemsMap; } BlendShapeOperator getModelBlendshapeOperator() const { return _modelBlendshapeOperator; } @@ -474,10 +470,7 @@ protected: friend class ModelMeshPartPayload; Rig _rig; - uint32_t _deleteGeometryCounter { 0 }; - bool _visualGeometryRequestFailed { false }; - bool _collisionGeometryRequestFailed { false }; bool _renderItemsNeedUpdate { false }; diff --git a/libraries/script-engine/src/Quat.h b/libraries/script-engine/src/Quat.h index 23bfe56309..c1eaa97797 100644 --- a/libraries/script-engine/src/Quat.h +++ b/libraries/script-engine/src/Quat.h @@ -188,7 +188,7 @@ public slots: * @param {number} roll - The roll angle in degrees. * @returns {Quat} A quaternion created using the pitch, yaw, and roll Euler angles. * @example Create a rotation of 180 degrees about the y axis. - * var rotation = Quat.fromPitchYawRollDgrees(0, 180, 0 ); + * var rotation = Quat.fromPitchYawRollDegrees(0, 180, 0 ); */ glm::quat fromPitchYawRollDegrees(float pitch, float yaw, float roll); diff --git a/pkg-scripts/README b/pkg-scripts/README index 92a9bf00d3..6eb74980d0 100644 --- a/pkg-scripts/README +++ b/pkg-scripts/README @@ -1,5 +1,5 @@ Collection of scripts to create server distribution packages. Most of these scripts assume -use of the build script at https://github.com/kasenvr/vircadia-builder, specifically that +use of the build script at https://github.com/vircadia/vircadia-builder, specifically that the following directory structure exists base folder/ diff --git a/pkg-scripts/server-control b/pkg-scripts/server-control index c80b8da724..3ed23b7149 100644 --- a/pkg-scripts/server-control +++ b/pkg-scripts/server-control @@ -5,8 +5,8 @@ Maintainer: Heather Anderson Build-Depends: debhelper (>= 10) Standards-Version: 4.1.2 Homepage: https://vircadia.com -Vcs-Git: https://github.com/kasenvr/project-athena.git -Vcs-Browser: https://github.com/kasenvr/project-athena +Vcs-Git: https://github.com/vircadia/vircadia.git +Vcs-Browser: https://github.com/vircadia/vircadia Package: vircadia-server Architecture: any diff --git a/pkg-scripts/vircadia-server.spec b/pkg-scripts/vircadia-server.spec index 3e0eed896e..575ad9589e 100644 --- a/pkg-scripts/vircadia-server.spec +++ b/pkg-scripts/vircadia-server.spec @@ -9,7 +9,7 @@ Summary: Vircadia metaverse platform, based on the High Fidelity Engine. License: ASL 2.0 URL: https://vircadia.com -Source0: https://github.com/kasenvr/vircadia-builder/blob/master/vircadia-builder +Source0: https://github.com/vircadia/vircadia-builder/blob/master/vircadia-builder #BuildRequires: systemd-rpm-macros BuildRequires: chrpath diff --git a/plugins/JSAPIExample/src/JSAPIExample.cpp b/plugins/JSAPIExample/src/JSAPIExample.cpp index ed637e198b..91aa8bd32a 100644 --- a/plugins/JSAPIExample/src/JSAPIExample.cpp +++ b/plugins/JSAPIExample/src/JSAPIExample.cpp @@ -3,7 +3,7 @@ // plugins/JSAPIExample/src // // Copyright (c) 2019-2020 humbletim (humbletim@gmail.com) -// Copyright (c) 2019 Kalila L. (kasenvr@gmail.com) +// Copyright (c) 2019 Kalila L. (somnilibertas@gmail.com) // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/prebuild.py b/prebuild.py index 21363bb9de..d5bed2d813 100644 --- a/prebuild.py +++ b/prebuild.py @@ -102,7 +102,7 @@ def parse_args(): if True: args = parser.parse_args() else: - args = parser.parse_args(['--android', 'questInterface', '--build-root', 'C:/git/project-athena/android/apps/questInterface/.externalNativeBuild/cmake/debug/arm64-v8a']) + args = parser.parse_args(['--android', 'questInterface', '--build-root', 'C:/git/vircadia/android/apps/questInterface/.externalNativeBuild/cmake/debug/arm64-v8a']) return args def main(): diff --git a/screenshare/package-lock.json b/screenshare/package-lock.json index c7d92d3e17..8195347159 100644 --- a/screenshare/package-lock.json +++ b/screenshare/package-lock.json @@ -655,6 +655,12 @@ "yargs-parser": "^13.0.0" }, "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -680,6 +686,16 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } } } }, @@ -1091,9 +1107,9 @@ "dev": true }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", "dev": true }, "is-arrayish": { @@ -2246,23 +2262,13 @@ "requires": { "ansi-regex": "^4.1.0" } - }, - "yargs-parser": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.0.tgz", - "integrity": "sha512-xLTUnCMc4JhxrPEPUYD5IBR1mWCK/aT6+RJ/K29JY2y1vD+FhtgKK0AXRWvI262q3QSffAQuTouFIKUuHX89wQ==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } } }, "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", - "dev": true, + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", + "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -2271,8 +2277,7 @@ "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" } } }, diff --git a/scripts/system/create/assets/images/icon-material.svg b/scripts/system/create/assets/images/icon-material.svg new file mode 100644 index 0000000000..470fed5dbd --- /dev/null +++ b/scripts/system/create/assets/images/icon-material.svg @@ -0,0 +1,5 @@ + + + + +Layer 1 \ No newline at end of file diff --git a/scripts/system/create/assets/images/icon-particles.svg b/scripts/system/create/assets/images/icon-particles.svg index 5e0105d7cd..2b3f365889 100644 --- a/scripts/system/create/assets/images/icon-particles.svg +++ b/scripts/system/create/assets/images/icon-particles.svg @@ -1,29 +1,14 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + +Layer 1 \ No newline at end of file diff --git a/scripts/system/create/assets/images/icon-point-light.svg b/scripts/system/create/assets/images/icon-point-light.svg index 896c35b63b..0f2e91d55b 100644 --- a/scripts/system/create/assets/images/icon-point-light.svg +++ b/scripts/system/create/assets/images/icon-point-light.svg @@ -1,57 +1,48 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +Layer 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/scripts/system/create/assets/images/icon-spot-light.svg b/scripts/system/create/assets/images/icon-spot-light.svg index ac2f87bb27..d8e196ffd7 100644 --- a/scripts/system/create/assets/images/icon-spot-light.svg +++ b/scripts/system/create/assets/images/icon-spot-light.svg @@ -1,37 +1,26 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +Layer 1 + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/scripts/system/create/assets/images/icon-zone.svg b/scripts/system/create/assets/images/icon-zone.svg index 41aeac4951..bfd8e07160 100644 --- a/scripts/system/create/assets/images/icon-zone.svg +++ b/scripts/system/create/assets/images/icon-zone.svg @@ -1,73 +1,5 @@ - - - -image/svg+xmlLayer 1 \ No newline at end of file diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index bc7afd8dc3..9e94b68ba1 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -41,7 +41,7 @@ Script.include([ var CreateWindow = Script.require('./modules/createWindow.js'); var TITLE_OFFSET = 60; -var CREATE_TOOLS_WIDTH = 490; +var CREATE_TOOLS_WIDTH = 750; var MAX_DEFAULT_ENTITY_LIST_HEIGHT = 942; var ENTIRE_DOMAIN_SCAN_RADIUS = 27713; @@ -87,21 +87,24 @@ var PARTICLE_SYSTEM_URL = Script.resolvePath("assets/images/icon-particles.svg") var POINT_LIGHT_URL = Script.resolvePath("assets/images/icon-point-light.svg"); var SPOT_LIGHT_URL = Script.resolvePath("assets/images/icon-spot-light.svg"); var ZONE_URL = Script.resolvePath("assets/images/icon-zone.svg"); +var MATERIAL_URL = Script.resolvePath("assets/images/icon-material.svg"); -var entityIconOverlayManager = new EntityIconOverlayManager(['Light', 'ParticleEffect', 'Zone'], function(entityID) { - var properties = Entities.getEntityProperties(entityID, ['type', 'isSpotlight']); - if (properties.type === 'Light') { - return { - url: properties.isSpotlight ? SPOT_LIGHT_URL : POINT_LIGHT_URL, - }; - } else if (properties.type === 'Zone') { - return { - url: ZONE_URL, +var entityIconOverlayManager = new EntityIconOverlayManager(["Light", "ParticleEffect", "Zone", "Material"], function(entityID) { + var properties = Entities.getEntityProperties(entityID, ["type", "isSpotlight", "parentID", "name"]); + if (properties.type === "Light") { + return { + imageURL: properties.isSpotlight ? SPOT_LIGHT_URL : POINT_LIGHT_URL }; + } else if (properties.type === "Zone") { + return { imageURL: ZONE_URL }; + } else if (properties.type === "Material") { + if (properties.parentID !== Uuid.NULL && properties.name !== "MATERIAL_" + entityShapeVisualizerSessionName) { + return { imageURL: MATERIAL_URL }; + } else { + return { imageURL: "" }; + } } else { - return { - url: PARTICLE_SYSTEM_URL, - }; + return { imageURL: PARTICLE_SYSTEM_URL }; } }); @@ -148,11 +151,13 @@ var DEFAULT_DIMENSIONS = { var DEFAULT_LIGHT_DIMENSIONS = Vec3.multiply(20, DEFAULT_DIMENSIONS); -var SUBMENU_ENTITY_EDITOR_PREFERENCES = "Edit > Create Application - Preferences"; +var MENU_IMPORT_FROM_FILE = "Import Entities (.json) From a File"; +var MENU_IMPORT_FROM_URL = "Import Entities (.json) From a URL"; +var MENU_CREATE_SEPARATOR = "Create Application"; +var SUBMENU_ENTITY_EDITOR_PREFERENCES = "Edit > Preferences"; var MENU_AUTO_FOCUS_ON_SELECT = "Auto Focus on Select"; var MENU_EASE_ON_FOCUS = "Ease Orientation on Focus"; -var MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE = "Show Lights and Particle Systems in Create Mode"; -var MENU_SHOW_ZONES_IN_EDIT_MODE = "Show Zones in Create Mode"; +var MENU_SHOW_ICONS_IN_CREATE_MODE = "Show Icons in Create Mode"; var MENU_CREATE_ENTITIES_GRABBABLE = "Create Entities As Grabbable (except Zones, Particles, and Lights)"; var MENU_ALLOW_SELECTION_LARGE = "Allow Selecting of Large Models"; var MENU_ALLOW_SELECTION_SMALL = "Allow Selecting of Small Models"; @@ -880,13 +885,11 @@ var toolBar = (function () { }); addButton("importEntitiesButton", function() { - Window.browseChanged.connect(onFileOpenChanged); - Window.browseAsync("Select .json to Import", "", "*.json"); + importEntitiesFromFile(); }); addButton("importEntitiesFromUrlButton", function() { - Window.promptTextChanged.connect(onPromptTextChanged); - Window.promptAsync("URL of a .json to import", ""); + importEntitiesFromUrl(); }); addButton("openAssetBrowserButton", function() { @@ -1040,8 +1043,7 @@ var toolBar = (function () { // everybody else to think that Interface has lost focus overall. fogbugzid:558 // Window.setFocus(); } - entityIconOverlayManager.setVisible(isActive && Menu.isOptionChecked(MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE)); - Entities.setDrawZoneBoundaries(isActive && Menu.isOptionChecked(MENU_SHOW_ZONES_IN_EDIT_MODE)); + entityIconOverlayManager.setVisible(isActive && Menu.isOptionChecked(MENU_SHOW_ICONS_IN_CREATE_MODE)); }; initialize(); @@ -1402,6 +1404,22 @@ function setupModelMenus() { position: 1, }); + Menu.addMenuItem({ + menuName: "Edit", + menuItemName: MENU_CREATE_SEPARATOR, + isSeparator: true + }); + Menu.addMenuItem({ + menuName: "Edit", + menuItemName: MENU_IMPORT_FROM_FILE, + afterItem: MENU_CREATE_SEPARATOR + }); + Menu.addMenuItem({ + menuName: "Edit", + menuItemName: MENU_IMPORT_FROM_URL, + afterItem: MENU_IMPORT_FROM_FILE + }); + Menu.addMenu(SUBMENU_ENTITY_EDITOR_PREFERENCES); Menu.addMenuItem({ @@ -1448,22 +1466,15 @@ function setupModelMenus() { }); Menu.addMenuItem({ menuName: SUBMENU_ENTITY_EDITOR_PREFERENCES, - menuItemName: MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE, + menuItemName: MENU_SHOW_ICONS_IN_CREATE_MODE, afterItem: MENU_EASE_ON_FOCUS, isCheckable: true, isChecked: Settings.getValue(SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE) !== "false" }); - Menu.addMenuItem({ - menuName: SUBMENU_ENTITY_EDITOR_PREFERENCES, - menuItemName: MENU_SHOW_ZONES_IN_EDIT_MODE, - afterItem: MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE, - isCheckable: true, - isChecked: Settings.getValue(SETTING_SHOW_ZONES_IN_EDIT_MODE) !== "false" - }); Menu.addMenuItem({ menuName: SUBMENU_ENTITY_EDITOR_PREFERENCES, menuItemName: MENU_ENTITY_LIST_DEFAULT_RADIUS, - afterItem: MENU_SHOW_ZONES_IN_EDIT_MODE + afterItem: MENU_SHOW_ICONS_IN_CREATE_MODE }); Entities.setLightsArePickable(false); @@ -1480,19 +1491,20 @@ function cleanupModelMenus() { Menu.removeMenuItem(SUBMENU_ENTITY_EDITOR_PREFERENCES, MENU_ALLOW_SELECTION_LIGHTS); Menu.removeMenuItem(SUBMENU_ENTITY_EDITOR_PREFERENCES, MENU_AUTO_FOCUS_ON_SELECT); Menu.removeMenuItem(SUBMENU_ENTITY_EDITOR_PREFERENCES, MENU_EASE_ON_FOCUS); - Menu.removeMenuItem(SUBMENU_ENTITY_EDITOR_PREFERENCES, MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE); - Menu.removeMenuItem(SUBMENU_ENTITY_EDITOR_PREFERENCES, MENU_SHOW_ZONES_IN_EDIT_MODE); + Menu.removeMenuItem(SUBMENU_ENTITY_EDITOR_PREFERENCES, MENU_SHOW_ICONS_IN_CREATE_MODE); Menu.removeMenuItem(SUBMENU_ENTITY_EDITOR_PREFERENCES, MENU_CREATE_ENTITIES_GRABBABLE); Menu.removeMenuItem(SUBMENU_ENTITY_EDITOR_PREFERENCES, MENU_ENTITY_LIST_DEFAULT_RADIUS); - Menu.removeMenu(SUBMENU_ENTITY_EDITOR_PREFERENCES); + Menu.removeMenu(SUBMENU_ENTITY_EDITOR_PREFERENCES); + Menu.removeMenuItem("Edit", MENU_IMPORT_FROM_URL); + Menu.removeMenuItem("Edit", MENU_IMPORT_FROM_FILE); + Menu.removeSeparator("Edit", MENU_CREATE_SEPARATOR); } Script.scriptEnding.connect(function () { toolBar.setActive(false); Settings.setValue(SETTING_AUTO_FOCUS_ON_SELECT, Menu.isOptionChecked(MENU_AUTO_FOCUS_ON_SELECT)); Settings.setValue(SETTING_EASE_ON_FOCUS, Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); - Settings.setValue(SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE, Menu.isOptionChecked(MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE)); - Settings.setValue(SETTING_SHOW_ZONES_IN_EDIT_MODE, Menu.isOptionChecked(MENU_SHOW_ZONES_IN_EDIT_MODE)); + Settings.setValue(SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE, Menu.isOptionChecked(MENU_SHOW_ICONS_IN_CREATE_MODE)); Settings.setValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_LARGE, Menu.isOptionChecked(MENU_ALLOW_SELECTION_LARGE)); Settings.setValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_SMALL, Menu.isOptionChecked(MENU_ALLOW_SELECTION_SMALL)); @@ -1849,15 +1861,17 @@ function handleMenuEvent(menuItem) { undoHistory.undo(); } else if (menuItem === "Redo") { undoHistory.redo(); - } else if (menuItem === MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE) { - entityIconOverlayManager.setVisible(isActive && Menu.isOptionChecked(MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE)); - } else if (menuItem === MENU_SHOW_ZONES_IN_EDIT_MODE) { - Entities.setDrawZoneBoundaries(isActive && Menu.isOptionChecked(MENU_SHOW_ZONES_IN_EDIT_MODE)); + } else if (menuItem === MENU_SHOW_ICONS_IN_CREATE_MODE) { + entityIconOverlayManager.setVisible(isActive && Menu.isOptionChecked(MENU_SHOW_ICONS_IN_CREATE_MODE)); } else if (menuItem === MENU_CREATE_ENTITIES_GRABBABLE) { Settings.setValue(SETTING_EDIT_PREFIX + menuItem, Menu.isOptionChecked(menuItem)); } else if (menuItem === MENU_ENTITY_LIST_DEFAULT_RADIUS) { Window.promptTextChanged.connect(onPromptTextChangedDefaultRadiusUserPref); Window.promptAsync("Entity List Default Radius (in meters)", "" + Settings.getValue(SETTING_ENTITY_LIST_DEFAULT_RADIUS, 100)); + } else if (menuItem === MENU_IMPORT_FROM_FILE) { + importEntitiesFromFile(); + } else if (menuItem === MENU_IMPORT_FROM_URL) { + importEntitiesFromUrl(); } tooltip.show(false); } @@ -2015,18 +2029,27 @@ function toggleKey(value) { } function focusKey(value) { if (value === 0) { // on release - cameraManager.enable(); - if (selectionManager.hasSelection()) { - cameraManager.focus(selectionManager.worldPosition, selectionManager.worldDimensions, - Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); - } + setCameraFocusToSelection(); } } function gridKey(value) { if (value === 0) { // on release - if (selectionManager.hasSelection()) { - grid.moveToSelection(); - } + alignGridToSelection(); + } +} +function viewGridKey(value) { + if (value === 0) { // on release + toggleGridVisibility(); + } +} +function snapKey(value) { + if (value === 0) { // on release + entityListTool.toggleSnapToGrid(); + } +} +function gridToAvatarKey(value) { + if (value === 0) { // on release + alignGridToAvatar(); } } function recursiveAdd(newParentID, parentData) { @@ -2426,7 +2449,6 @@ var PropertiesTool = function (opts) { } } - if (data.onlyUpdateEntities) { blockPropertyUpdates = true; } else { @@ -2435,6 +2457,10 @@ var PropertiesTool = function (opts) { } selectionManager._update(false, this); blockPropertyUpdates = false; + + if (data.snapToGrid !== undefined) { + entityListTool.setListMenuSnapToGrid(data.snapToGrid); + } } else if (data.type === 'saveUserData' || data.type === 'saveMaterialData') { data.ids.forEach(function(entityID) { Entities.editEntity(entityID, data.properties); @@ -2789,7 +2815,10 @@ if (isOnMacPlatform) { } mapping.from([Controller.Hardware.Keyboard.T]).to(toggleKey); mapping.from([Controller.Hardware.Keyboard.F]).to(focusKey); -mapping.from([Controller.Hardware.Keyboard.G]).to(gridKey); +mapping.from([Controller.Hardware.Keyboard.J]).to(gridKey); +mapping.from([Controller.Hardware.Keyboard.G]).to(viewGridKey); +mapping.from([Controller.Hardware.Keyboard.H]).to(snapKey); +mapping.from([Controller.Hardware.Keyboard.K]).to(gridToAvatarKey); mapping.from([Controller.Hardware.Keyboard.X]) .when([Controller.Hardware.Keyboard.Control]) .to(whenReleased(function() { selectionManager.cutSelectedEntities() })); @@ -2830,8 +2859,14 @@ keyUpEventFromUIWindow = function(keyUpEvent) { toggleKey(pressedValue); } else if (keyUpEvent.keyCodeString === "F") { focusKey(pressedValue); - } else if (keyUpEvent.keyCodeString === "G") { + } else if (keyUpEvent.keyCodeString === "J") { gridKey(pressedValue); + } else if (keyUpEvent.keyCodeString === "G") { + viewGridKey(pressedValue); + } else if (keyUpEvent.keyCodeString === "H") { + snapKey(pressedValue); + } else if (keyUpEvent.keyCodeString === "K") { + gridToAvatarKey(pressedValue); } else if (keyUpEvent.controlKey && keyUpEvent.keyCodeString === "X") { selectionManager.cutSelectedEntities(); } else if (keyUpEvent.controlKey && keyUpEvent.keyCodeString === "C") { @@ -2938,4 +2973,46 @@ function getDomainOnlyChildrenIDs(id) { return realChildren; } +function importEntitiesFromFile() { + Window.browseChanged.connect(onFileOpenChanged); + Window.browseAsync("Select .json to Import", "", "*.json"); +} + +function importEntitiesFromUrl() { + Window.promptTextChanged.connect(onPromptTextChanged); + Window.promptAsync("URL of a .json to import", ""); +} + +function setCameraFocusToSelection() { + cameraManager.enable(); + if (selectionManager.hasSelection()) { + cameraManager.focus(selectionManager.worldPosition, selectionManager.worldDimensions, + Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); + } +} + +function alignGridToSelection() { + if (selectionManager.hasSelection()) { + if (!grid.getVisible()) { + grid.setVisible(true, true); + } + grid.moveToSelection(); + } +} + +function alignGridToAvatar() { + if (!grid.getVisible()) { + grid.setVisible(true, true); + } + grid.moveToAvatar(); +} + +function toggleGridVisibility() { + if (!grid.getVisible()) { + grid.setVisible(true, true); + } else { + grid.setVisible(false, true); + } +} + }()); // END LOCAL_SCOPE diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index 58cf4ce892..a4d4decedb 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -146,6 +146,20 @@ EntityListTool = function(shouldUseEditTabletApp) { }); }; + that.setListMenuSnapToGrid = function (isSnapToGrid) { + emitJSONScriptEvent({ "type": "setSnapToGrid", "snap": isSnapToGrid }); + }; + + that.toggleSnapToGrid = function () { + if (!grid.getSnapToGrid()) { + grid.setSnapToGrid(true); + emitJSONScriptEvent({ "type": "setSnapToGrid", "snap": true }); + } else { + grid.setSnapToGrid(false); + emitJSONScriptEvent({ "type": "setSnapToGrid", "snap": false }); + } + }; + function valueIfDefined(value) { return value !== undefined ? value : ""; } @@ -381,7 +395,22 @@ EntityListTool = function(shouldUseEditTabletApp) { }); } else if (data.type === 'saveColumnsConfigSetting') { Settings.setValue(SETTING_EDITOR_COLUMNS_SETUP, data.columnsData); + } else if (data.type === 'importFromFile') { + importEntitiesFromFile(); + } else if (data.type === 'importFromUrl') { + importEntitiesFromUrl(); + } else if (data.type === 'setCameraFocusToSelection') { + setCameraFocusToSelection(); + } else if (data.type === 'alignGridToSelection') { + alignGridToSelection(); + } else if (data.type === 'alignGridToAvatar') { + alignGridToAvatar(); + } else if (data.type === 'toggleGridVisibility') { + toggleGridVisibility(); + } else if (data.type === 'toggleSnapToGrid') { + that.toggleSnapToGrid(); } + }; webView.webEventReceived.connect(onWebEventReceived); diff --git a/scripts/system/create/entityList/html/entityList.html b/scripts/system/create/entityList/html/entityList.html index a5f27bd3a8..9817f9ddf9 100644 --- a/scripts/system/create/entityList/html/entityList.html +++ b/scripts/system/create/entityList/html/entityList.html @@ -32,8 +32,9 @@ - - + + +
@@ -159,7 +160,7 @@
@@ -171,7 +172,7 @@ @@ -219,13 +220,71 @@
- +
+
+ + + + + + + + + + + +
diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index 89eac5fb2f..9ba258b801 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -9,8 +9,8 @@ const ASCENDING_SORT = 1; const DESCENDING_SORT = -1; -const ASCENDING_STRING = '▴'; -const DESCENDING_STRING = '▾'; +const ASCENDING_STRING = "▴"; +const DESCENDING_STRING = "▾"; const BYTES_PER_MEGABYTE = 1024 * 1024; const COLLAPSE_EXTRA_INFO = "E"; const EXPAND_EXTRA_INFO = "D"; @@ -34,7 +34,7 @@ function displayIfNonZero(number) { } function getFilename(url) { - let urlParts = url.split('/'); + let urlParts = url.split("/"); return urlParts[urlParts.length - 1]; } @@ -195,7 +195,7 @@ let lastSelectedEntity; */ let entityListContextMenu = null; -let currentSortColumnID = 'type'; +let currentSortColumnID = "type"; let currentSortOrder = ASCENDING_SORT; let elSortOrders = {}; let typeFilters = []; @@ -226,6 +226,7 @@ let elEntityTable, elToggleVisible, elActionsMenu, elSelectionMenu, + elToolsMenu, elMenuBackgroundOverlay, elHmdMultiSelect, elHmdCopy, @@ -249,6 +250,16 @@ let elEntityTable, elSelectFamily, elSelectTopFamily, elTeleportToEntity, + elSetCameraFocusToSelection, + elToggleLocalWorldMode, + elExportSelectedEntities, + elImportEntitiesFromFile, + elImportEntitiesFromUrl, + elGridActivator, + elSnapToGridActivator, + elSnapToGridActivatorCaption, + elAlignGridToSelection, + elAlignGridToAvatar, elFilterTypeMultiselectBox, elFilterTypeText, elFilterTypeOptions, @@ -268,7 +279,7 @@ let elEntityTable, elRenameInput; const ENABLE_PROFILING = false; -let profileIndent = ''; +let profileIndent = ""; const PROFILE_NOOP = function(_name, fn, args) { fn.apply(this, args); } ; @@ -298,6 +309,7 @@ function loaded() { elHmdMultiSelect = document.getElementById("hmdmultiselect"); elActionsMenu = document.getElementById("actions"); elSelectionMenu = document.getElementById("selection"); + elToolsMenu = document.getElementById("tools"); elMenuBackgroundOverlay = document.getElementById("menuBackgroundOverlay"); elHmdCopy = document.getElementById("hmdcopy"); elHmdCut = document.getElementById("hmdcut"); @@ -320,6 +332,16 @@ function loaded() { elSelectFamily = document.getElementById("selectfamily"); elSelectTopFamily = document.getElementById("selecttopfamily"); elTeleportToEntity = document.getElementById("teleport-to-entity"); + elSetCameraFocusToSelection = document.getElementById("setCameraFocusToSelection"); + elToggleLocalWorldMode = document.getElementById("toggleLocalWorldMode"); + elExportSelectedEntities = document.getElementById("exportSelectedEntities"); + elImportEntitiesFromFile = document.getElementById("importEntitiesFromFile"); + elImportEntitiesFromUrl = document.getElementById("importEntitiesFromUrl"); + elGridActivator = document.getElementById("gridActivator"); + elSnapToGridActivator = document.getElementById("snapToGridActivator"); + elSnapToGridActivatorCaption = document.getElementById("snapToGridActivatorCaption"); + elAlignGridToSelection = document.getElementById("alignGridToSelection"); + elAlignGridToAvatar = document.getElementById("alignGridToAvatar"); elFilterTypeMultiselectBox = document.getElementById("filter-type-multiselect-box"); elFilterTypeText = document.getElementById("filter-type-text"); elFilterTypeOptions = document.getElementById("filter-type-options"); @@ -335,17 +357,17 @@ function loaded() { elNoEntitiesMessage = document.getElementById("no-entities"); elColumnsMultiselectBox = document.getElementById("entity-table-columns-multiselect-box"); elColumnsOptions = document.getElementById("entity-table-columns-options"); - elToggleSpaceMode = document.getElementById('toggle-space-mode'); + elToggleSpaceMode = document.getElementById("toggle-space-mode"); document.body.onclick = onBodyClick; elToggleLocked.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleLocked' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "toggleLocked" })); }; elToggleVisible.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleVisible' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "toggleVisible" })); }; elExport.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'export'})); + EventBridge.emitWebEvent(JSON.stringify({ type: "export"})); }; elHmdMultiSelect.onclick = function() { if (hmdMultiSelectMode) { @@ -355,7 +377,7 @@ function loaded() { elHmdMultiSelect.className = "white vglyph"; hmdMultiSelectMode = true; } - EventBridge.emitWebEvent(JSON.stringify({ type: 'hmdMultiSelectMode', value: hmdMultiSelectMode })); + EventBridge.emitWebEvent(JSON.stringify({ type: "hmdMultiSelectMode", value: hmdMultiSelectMode })); }; elActionsMenu.onclick = function() { document.getElementById("menuBackgroundOverlay").style.display = "block"; @@ -365,47 +387,51 @@ function loaded() { document.getElementById("menuBackgroundOverlay").style.display = "block"; document.getElementById("selection-menu").style.display = "block"; }; + elToolsMenu.onclick = function() { + document.getElementById("menuBackgroundOverlay").style.display = "block"; + document.getElementById("tools-menu").style.display = "block"; + }; elMenuBackgroundOverlay.onclick = function() { closeAllEntityListMenu(); }; elHmdCopy.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'copy' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "copy" })); closeAllEntityListMenu(); }; elHmdCut.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'cut' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "cut" })); closeAllEntityListMenu(); }; elHmdPaste.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'paste' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "paste" })); closeAllEntityListMenu(); }; elHmdDuplicate.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'duplicate' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "duplicate" })); closeAllEntityListMenu(); }; elParent.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'parent' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "parent" })); closeAllEntityListMenu(); }; elUnparent.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'unparent' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "unparent" })); closeAllEntityListMenu(); }; elUndo.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'undo' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "undo" })); closeAllEntityListMenu(); }; elRedo.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'redo' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "redo" })); closeAllEntityListMenu(); }; elDelete.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "delete" })); closeAllEntityListMenu(); }; elMoveEntitySelectionToAvatar.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'moveEntitySelectionToAvatar' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "moveEntitySelectionToAvatar" })); closeAllEntityListMenu(); }; elSelectAll.onclick = function() { @@ -467,39 +493,75 @@ function loaded() { closeAllEntityListMenu(); }; elSelectAllInBox.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'selectAllInBox' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "selectAllInBox" })); closeAllEntityListMenu(); }; elSelectAllTouchingBox.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'selectAllTouchingBox' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "selectAllTouchingBox" })); closeAllEntityListMenu(); }; elSelectParent.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'selectParent' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "selectParent" })); closeAllEntityListMenu(); }; elSelectTopParent.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'selectTopParent' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "selectTopParent" })); closeAllEntityListMenu(); }; elAddChildrenToSelection.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'addChildrenToSelection' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "addChildrenToSelection" })); closeAllEntityListMenu(); }; elSelectFamily.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'selectFamily' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "selectFamily" })); closeAllEntityListMenu(); }; elSelectTopFamily.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'selectTopFamily' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "selectTopFamily" })); closeAllEntityListMenu(); }; elTeleportToEntity.onclick = function () { EventBridge.emitWebEvent(JSON.stringify({ type: "teleportToEntity" })); closeAllEntityListMenu(); }; + elSetCameraFocusToSelection.onclick = function () { + EventBridge.emitWebEvent(JSON.stringify({ type: "setCameraFocusToSelection" })); + closeAllEntityListMenu(); + }; + elToggleLocalWorldMode.onclick = function () { + EventBridge.emitWebEvent(JSON.stringify({ type: "toggleSpaceMode" })); + closeAllEntityListMenu(); + }; + elExportSelectedEntities.onclick = function () { + EventBridge.emitWebEvent(JSON.stringify({ type: "export"})); + closeAllEntityListMenu(); + }; + elImportEntitiesFromFile.onclick = function () { + EventBridge.emitWebEvent(JSON.stringify({ type: "importFromFile"})); + closeAllEntityListMenu(); + }; + elImportEntitiesFromUrl.onclick = function () { + EventBridge.emitWebEvent(JSON.stringify({ type: "importFromUrl"})); + closeAllEntityListMenu(); + }; + elGridActivator.onclick = function () { + EventBridge.emitWebEvent(JSON.stringify({ type: "toggleGridVisibility" })); + closeAllEntityListMenu(); + }; + elSnapToGridActivator.onclick = function () { + EventBridge.emitWebEvent(JSON.stringify({ type: "toggleSnapToGrid" })); + closeAllEntityListMenu(); + }; + elAlignGridToSelection.onclick = function () { + EventBridge.emitWebEvent(JSON.stringify({ type: "alignGridToSelection" })); + closeAllEntityListMenu(); + }; + elAlignGridToAvatar.onclick = function () { + EventBridge.emitWebEvent(JSON.stringify({ type: "alignGridToAvatar" })); + closeAllEntityListMenu(); + }; elToggleSpaceMode.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleSpaceMode' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "toggleSpaceMode" })); }; elRefresh.onclick = refreshEntities; elFilterTypeMultiselectBox.onclick = onToggleTypeDropdown; @@ -517,11 +579,11 @@ function loaded() { let type = FILTER_TYPES[i]; let typeFilterID = "filter-type-" + type; - let elDiv = document.createElement('div'); + let elDiv = document.createElement("div"); elDiv.onclick = onToggleTypeFilter; elFilterTypeOptions.insertBefore(elDiv, elFilterTypeOptionsButtons); - let elInput = document.createElement('input'); + let elInput = document.createElement("input"); elInput.setAttribute("type", "checkbox"); elInput.setAttribute("id", typeFilterID); elInput.setAttribute("filterType", type); @@ -529,12 +591,12 @@ function loaded() { elFilterTypeInputs[type] = elInput; elDiv.appendChild(elInput); - let elLabel = document.createElement('label'); + let elLabel = document.createElement("label"); elLabel.setAttribute("for", typeFilterID); elLabel.innerText = type; elDiv.appendChild(elLabel); - let elSpan = document.createElement('span'); + let elSpan = document.createElement("span"); elSpan.setAttribute("class", "typeIcon"); elSpan.innerHTML = ENTITY_TYPE_ICON[type]; @@ -567,11 +629,11 @@ function loaded() { elTh.innerText = columnData.columnHeader; } elTh.onmousedown = function(event) { - if (event.target.nodeName === 'TH') { + if (event.target.nodeName === "TH") { elTargetTh = event.target; targetColumnIndex = parseInt(elTargetTh.getAttribute("columnIndex")); lastColumnSwapPosition = event.clientX; - } else if (event.target.nodeName === 'SPAN') { + } else if (event.target.nodeName === "SPAN") { elTargetSpan = event.target; } initialThEvent = event; @@ -594,18 +656,18 @@ function loaded() { if (columnData.alwaysShown !== true) { let columnDropdownID = "entity-table-column-" + columnID; - let elDiv = document.createElement('div'); + let elDiv = document.createElement("div"); elDiv.onclick = onToggleColumn; elColumnsOptions.appendChild(elDiv); - let elInput = document.createElement('input'); + let elInput = document.createElement("input"); elInput.setAttribute("type", "checkbox"); elInput.setAttribute("id", columnDropdownID); elInput.setAttribute("columnID", columnID); elInput.checked = columnData.initiallyShown === true; elDiv.appendChild(elInput); - let elLabel = document.createElement('label'); + let elLabel = document.createElement("label"); elLabel.setAttribute("for", columnDropdownID); elLabel.innerText = columnData.dropdownLabel; elDiv.appendChild(elLabel); @@ -640,7 +702,7 @@ function loaded() { let elCell = entity.elRow.childNodes[getColumnIndex("name")]; elRenameInput = document.createElement("input"); - elRenameInput.setAttribute('class', 'rename-entity'); + elRenameInput.setAttribute("class", "rename-entity"); elRenameInput.value = entity.name; let ignoreClicks = function(event) { event.stopPropagation(); @@ -705,22 +767,22 @@ function loaded() { entityListContextMenu.setOnSelectedCallback(function(optionName, selectedEntityID) { switch (optionName) { case "Cut": - EventBridge.emitWebEvent(JSON.stringify({ type: 'cut' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "cut" })); break; case "Copy": - EventBridge.emitWebEvent(JSON.stringify({ type: 'copy' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "copy" })); break; case "Paste": - EventBridge.emitWebEvent(JSON.stringify({ type: 'paste' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "paste" })); break; case "Rename": startRenamingEntity(selectedEntityID); break; case "Duplicate": - EventBridge.emitWebEvent(JSON.stringify({ type: 'duplicate' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "duplicate" })); break; case "Delete": - EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "delete" })); break; } }); @@ -744,11 +806,11 @@ function loaded() { })); } - let enabledContextMenuItems = ['Copy', 'Paste', 'Duplicate']; + let enabledContextMenuItems = ["Copy", "Paste", "Duplicate"]; if (entitiesByID[entityID] && !entitiesByID[entityID].locked) { - enabledContextMenuItems.push('Cut'); - enabledContextMenuItems.push('Rename'); - enabledContextMenuItems.push('Delete'); + enabledContextMenuItems.push("Cut"); + enabledContextMenuItems.push("Rename"); + enabledContextMenuItems.push("Delete"); } entityListContextMenu.open(clickEvent, entityID, enabledContextMenuItems); @@ -947,7 +1009,7 @@ function loaded() { if (id === deletedIDs[i]) { let elRow = entities[j].elRow; if (elRow) { - elRow.className = ''; + elRow.className = ""; elRow.dataset.entityID = EMPTY_ENTITY_ID; } entities.splice(j, 1); @@ -1030,7 +1092,7 @@ function loaded() { } function refreshEntities() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'refresh' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "refresh" })); } function refreshFooter() { @@ -1057,7 +1119,7 @@ function loaded() { if (entity !== undefined) { entity.selected = false; if (entity.elRow) { - entity.elRow.className = ''; + entity.elRow.className = ""; } } }); @@ -1071,9 +1133,9 @@ function loaded() { entity.selected = true; if (entity.elRow) { if (id === lastSelectedEntity) { - entity.elRow.className = 'last-selected'; + entity.elRow.className = "last-selected"; } else { - entity.elRow.className = 'selected'; + entity.elRow.className = "selected"; } } } else { @@ -1144,12 +1206,12 @@ function loaded() { // if this entity was previously selected flag it's row as selected if (itemData.selected) { if (itemData.id === lastSelectedEntity) { - elRow.className = 'last-selected'; + elRow.className = "last-selected"; } else { - elRow.className = 'selected'; + elRow.className = "selected"; } } else { - elRow.className = ''; + elRow.className = ""; } // if this row previously had an associated entity ID that wasn't the new entity ID then clear @@ -1202,9 +1264,9 @@ function loaded() { } function onRadiusChange() { - elFilterRadius.value = elFilterRadius.value.replace(/[^0-9]/g, ''); + elFilterRadius.value = elFilterRadius.value.replace(/[^0-9]/g, ""); elFilterRadius.value = Math.max(elFilterRadius.value, 0); - EventBridge.emitWebEvent(JSON.stringify({ type: 'radius', radius: elFilterRadius.value })); + EventBridge.emitWebEvent(JSON.stringify({ type: "radius", radius: elFilterRadius.value })); refreshEntities(); } @@ -1425,7 +1487,7 @@ function loaded() { } if (isColumnsSettingLoaded) { - EventBridge.emitWebEvent(JSON.stringify({ type: 'saveColumnsConfigSetting', columnsData: columns })); + EventBridge.emitWebEvent(JSON.stringify({ type: "saveColumnsConfigSetting", columnsData: columns })); } entityList.refresh(); @@ -1628,7 +1690,7 @@ function loaded() { } EventBridge.emitWebEvent(JSON.stringify({ - type: 'keyUpEvent', + type: "keyUpEvent", keyUpEvent: { code, key, @@ -1673,6 +1735,12 @@ function loaded() { removeEntities(data.ids); } else if (data.type === "setSpaceMode") { setSpaceMode(data.spaceMode); + } else if (data.type === "setSnapToGrid") { + if (data.snap) { + elSnapToGridActivatorCaption.innerHTML = "✓ Deactivate Snap to Grid"; + } else { + elSnapToGridActivatorCaption.innerHTML = "Activate Snap to Grid"; + } } else if (data.type === "confirmHMDstate") { if (data.isHmd) { document.getElementById("hmdmultiselect").style.display = "inline"; @@ -1722,7 +1790,7 @@ function loaded() { } } } else { - EventBridge.emitWebEvent(JSON.stringify({ type: 'saveColumnsConfigSetting', columnsData: "" })); + EventBridge.emitWebEvent(JSON.stringify({ type: "saveColumnsConfigSetting", columnsData: "" })); } } isColumnsSettingLoaded = true; @@ -1735,7 +1803,7 @@ function loaded() { window.addEventListener("resize", updateColumnWidths); - EventBridge.emitWebEvent(JSON.stringify({ type: 'loadConfigSetting' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "loadConfigSetting" })); }); augmentSpinButtons(); @@ -1758,6 +1826,7 @@ function loaded() { document.getElementById("menuBackgroundOverlay").style.display = "none"; document.getElementById("selection-menu").style.display = "none"; document.getElementById("actions-menu").style.display = "none"; + document.getElementById("tools-menu").style.display = "none"; } } diff --git a/scripts/system/create/modules/entityShapeVisualizer.js b/scripts/system/create/modules/entityShapeVisualizer.js index 45cf68fdb5..7a1cd74d25 100644 --- a/scripts/system/create/modules/entityShapeVisualizer.js +++ b/scripts/system/create/modules/entityShapeVisualizer.js @@ -143,6 +143,7 @@ EntityShape.prototype = { var PROJECTED_MATERIALS = false; this.materialEntity = Entities.addEntity({ type: "Material", + name: "MATERIAL_" + this.entityShapeVisualizerSessionName, localPosition: Vec3.ZERO, localRotation: Quat.IDENTITY, localDimensions: properties.localDimensions, diff --git a/scripts/system/create/qml/EditToolsTabView.qml b/scripts/system/create/qml/EditToolsTabView.qml index 2403604342..39074946bd 100644 --- a/scripts/system/create/qml/EditToolsTabView.qml +++ b/scripts/system/create/qml/EditToolsTabView.qml @@ -210,8 +210,8 @@ TabBar { text: "Import Entities (.json) from a File" color: hifi.buttons.black colorScheme: hifi.colorSchemes.dark - anchors.right: parent.horizontalCenter - anchors.rightMargin: 10 + anchors.right: parent.right + anchors.rightMargin: 55 anchors.left: parent.left anchors.leftMargin: 55 anchors.top: assetServerButton.bottom @@ -231,9 +231,9 @@ TabBar { colorScheme: hifi.colorSchemes.dark anchors.right: parent.right anchors.rightMargin: 55 - anchors.left: parent.horizontalCenter - anchors.leftMargin: 10 - anchors.top: assetServerButton.bottom + anchors.left: parent.left + anchors.leftMargin: 55 + anchors.top: importButton.bottom anchors.topMargin: 20 onClicked: { editRoot.sendToScript({ diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 4f0a833a13..db535327d9 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -404,7 +404,7 @@ input[type=button], button.hifi-edit-button { text-transform: uppercase; vertical-align: top; height: 28px; - min-width: 120px; + min-width: 70px; padding: 0 18px; margin-right: 6px; border-radius: 5px; diff --git a/scripts/system/libraries/entityIconOverlayManager.js b/scripts/system/libraries/entityIconOverlayManager.js index 68104ff4bb..f2ca5625ea 100644 --- a/scripts/system/libraries/entityIconOverlayManager.js +++ b/scripts/system/libraries/entityIconOverlayManager.js @@ -29,7 +29,7 @@ EntityIconOverlayManager = function(entityTypes, getOverlayPropertiesFunc) { overlayProperties[key] = customProperties[key]; } } - Overlays.editOverlay(entityOverlays[entityID], overlayProperties); + Entities.editEntity(entityOverlays[entityID], overlayProperties); } }; @@ -63,7 +63,7 @@ EntityIconOverlayManager = function(entityTypes, getOverlayPropertiesFunc) { if (visible !== isVisible) { visible = isVisible; for (var id in entityOverlays) { - Overlays.editOverlay(entityOverlays[id], { + Entities.editEntity(entityOverlays[id], { visible: visible, ignorePickIntersection: !visible }); @@ -75,7 +75,11 @@ EntityIconOverlayManager = function(entityTypes, getOverlayPropertiesFunc) { function getOverlay() { var overlay; if (unusedOverlays.length === 0) { - overlay = Overlays.addOverlay("image3d", {}); + overlay = Entities.addEntity({ + type: "Image", + billboardMode: "full", + emissive: true + }, "local"); allOverlays.push(overlay); } else { overlay = unusedOverlays.pop(); @@ -85,7 +89,7 @@ EntityIconOverlayManager = function(entityTypes, getOverlayPropertiesFunc) { function releaseOverlay(overlay) { unusedOverlays.push(overlay); - Overlays.editOverlay(overlay, { + Entities.editEntity(overlay, { visible: false, ignorePickIntersection: true }); @@ -103,9 +107,8 @@ EntityIconOverlayManager = function(entityTypes, getOverlayPropertiesFunc) { visible: visible, ignorePickIntersection: !visible, alpha: 0.9, - scale: 0.5, - drawInFront: true, - isFacingAvatar: true, + dimensions: { x: 0.5, y: 0.5, z: 0.01 }, + renderLayer: "front", color: { red: 255, green: 255, @@ -118,7 +121,7 @@ EntityIconOverlayManager = function(entityTypes, getOverlayPropertiesFunc) { overlayProperties[key] = customProperties[key]; } } - Overlays.editOverlay(overlay, overlayProperties); + Entities.editEntity(overlay, overlayProperties); } } @@ -149,7 +152,7 @@ EntityIconOverlayManager = function(entityTypes, getOverlayPropertiesFunc) { Script.scriptEnding.connect(function() { for (var i = 0; i < allOverlays.length; i++) { - Overlays.deleteOverlay(allOverlays[i]); + Entities.deleteEntity(allOverlays[i]); } }); }; diff --git a/scripts/system/libraries/gridTool.js b/scripts/system/libraries/gridTool.js index 233ae3a3e4..1dbe1fea4c 100644 --- a/scripts/system/libraries/gridTool.js +++ b/scripts/system/libraries/gridTool.js @@ -1,10 +1,19 @@ +// gridTool.js +// +// Created by Ryan Huffman on 6 Nov 2014 +// Copyright 2014 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// /* global keyUpEventFromUIWindow */ var GRID_CONTROLS_HTML_URL = Script.resolvePath('../html/gridControls.html'); Grid = function() { var that = {}; - var gridColor = { red: 0, green: 0, blue: 0 }; + var gridColor = { red: 255, green: 255, blue: 255 }; var gridAlpha = 0.6; var origin = { x: 0, y: +MyAvatar.getJointPosition('LeftToeBase').y.toFixed(1) + 0.1, z: 0 }; var scale = 500; @@ -16,18 +25,19 @@ Grid = function() { var snapToGrid = false; - var gridOverlay = Overlays.addOverlay("grid", { + var gridEntityTool = Entities.addEntity({ + type: "Grid", rotation: Quat.fromPitchYawRollDegrees(90, 0, 0), dimensions: { x: scale, y: scale, z: scale }, position: origin, visible: false, - drawInFront: false, + renderLayer: "world", color: gridColor, alpha: gridAlpha, minorGridEvery: minorGridEvery, majorGridEvery: majorGridEvery, ignorePickIntersection: true - }); + }, "local"); that.visible = false; that.enabled = false; @@ -163,6 +173,14 @@ Grid = function() { newPosition = Vec3.subtract(newPosition, { x: 0, y: SelectionManager.worldDimensions.y * 0.5, z: 0 }); that.setPosition(newPosition); }; + + that.moveToAvatar = function() { + var position = MyAvatar.getJointPosition("LeftFoot"); + if (position.x === 0.0 && position.y === 0.0 && position.z === 0.0) { + position = MyAvatar.position; + } + that.setPosition(position); + }; that.emitUpdate = function() { if (that.onUpdate) { @@ -214,7 +232,7 @@ Grid = function() { }; function updateGrid(noUpdate) { - Overlays.editOverlay(gridOverlay, { + Entities.editEntity(gridEntityTool, { position: { x: 0, y: origin.y, z: 0 }, visible: that.visible && that.enabled, minorGridEvery: minorGridEvery, @@ -222,6 +240,7 @@ Grid = function() { color: gridColor, alpha: gridAlpha }); + if (!noUpdate) { that.emitUpdate(); @@ -229,7 +248,7 @@ Grid = function() { } function cleanup() { - Overlays.deleteOverlay(gridOverlay); + Entities.deleteEntity(gridEntityTool); } that.addListener = function(callback) { @@ -283,11 +302,7 @@ GridTool = function(opts) { } else if (data.type === "action") { var action = data.action; if (action === "moveToAvatar") { - var position = MyAvatar.getJointPosition("LeftFoot"); - if (position.x === 0 && position.y === 0 && position.z === 0) { - position = MyAvatar.position; - } - horizontalGrid.setPosition(position); + horizontalGrid.moveToAvatar(); } else if (action === "moveToSelection") { horizontalGrid.moveToSelection(); } diff --git a/scripts/system/more/more.html b/scripts/system/more/more.html index db1f73cc85..a8bdaca913 100644 --- a/scripts/system/more/more.html +++ b/scripts/system/more/more.html @@ -5,8 +5,8 @@ // Created by Keb Helion, February 2020. // Copyright 2020 Vircadia contributors. // -// App maintained in: https://github.com/kasenvr/community-apps -// App copied to: https://github.com/kasenvr/project-athena +// App maintained in: https://github.com/vircadia/community-apps +// App copied to: https://github.com/vircadia/vircadia // // // Distributed under the Apache License, Version 2.0. diff --git a/server-console/package.json b/server-console/package.json index 1ceed08d4d..d5b2a0793d 100644 --- a/server-console/package.json +++ b/server-console/package.json @@ -13,7 +13,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/kasenvr/project-athena.git" + "url": "https://github.com/vircadia/vircadia.git" }, "main": "src/main.js", "scripts": {