From 75b99e71ecbce70218e433efc4d4dcee02b7e919 Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Tue, 11 Aug 2020 15:49:34 -0700 Subject: [PATCH 001/136] playing with gha --- .github/workflows/pr_build.yml | 51 ++++++++++++++++++++++++++++++---- android/build_android.sh | 10 +++---- android/containerized_build.sh | 8 +++--- android/docker/Dockerfile | 28 ++++++++----------- prebuild.py | 2 +- 5 files changed, 66 insertions(+), 33 deletions(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index f28cf1e66b..7bd061e7d2 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -27,14 +27,20 @@ env: jobs: build: + name: "build (${{matrix.os}}, ${{matrix.build_type}})" strategy: matrix: - os: [windows-latest, macOS-latest, ubuntu-18.04] - build_type: [full] include: + - os: windows-latest + build_type: full + - os: macOS-latest + build_type: full - os: ubuntu-18.04 build_type: full apt-dependencies: mesa-common-dev libegl1 libglvnd-dev libdouble-conversion1 libpulse0 + - os: ubuntu-18.04 + build_type: android + apt-dependencies: mesa-common-dev libegl1 libglvnd-dev libdouble-conversion1 libpulse0 fail-fast: false runs-on: ${{matrix.os}} if: github.event.action != 'labeled' || github.event.label.name == 'rebuild' @@ -65,14 +71,25 @@ jobs: echo ::set-env name=INSTALLER_EXT::exe echo ::set-env name=CMAKE_EXTRA::"-A x64" fi + # Android + Quest build variables + if [[ "${{ matrix.build_type }}" == "android" ]]; then + HIFI_ANDROID_PRECOMPILED="${{runner.workspace}}/dependencies" + echo ::set-env name=HIFI_ANDROID_PRECOMPILED::"$HIFI_ANDROID_PRECOMPILED" + mkdir $HIFI_ANDROID_PRECOMPILED + echo ::set-env name=INSTALLER_EXT::apk + fi # Configuration is broken into two steps because you can't set an env var and also reference it in the same step - name: Configure Build Environment 2 shell: bash run: | echo "${{ steps.buildenv1.outputs.symbols_archive }}" - echo ::set-env name=ARTIFACT_PATTERN::Vircadia-Alpha-PR${{ github.event.number }}-*.$INSTALLER_EXT - # Build type variables - echo ::set-env name=INSTALLER::Vircadia-Alpha-$RELEASE_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT + if [[ "${{ matrix.build_type }}" != "android" ]]; then + echo ::set-env name=ARTIFACT_PATTERN::Vircadia-Alpha-PR${{ github.event.number }}-*.$INSTALLER_EXT + # Build type variables + echo ::set-env name=INSTALLER::Vircadia-Alpha-$RELEASE_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT + else + echo ::set-env name=ARTIFACT_PATTERN::*.$INSTALLER_EXT + fi - name: Clear Working Directory if: startsWith(matrix.os, 'windows') shell: bash @@ -98,26 +115,32 @@ jobs: shell: bash run: cmake -E make_directory "${{runner.workspace}}/build" - name: Configure CMake + if: matrix.build_type != 'android' working-directory: ${{runner.workspace}}/build shell: bash run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DVCPKG_BUILD_TYPE=release $CMAKE_EXTRA - name: Build Application + if: matrix.build_type == 'full' || matrix.build_type == 'client' working-directory: ${{runner.workspace}}/build shell: bash run: cmake --build . --config $BUILD_TYPE --target $APP_NAME $CMAKE_BUILD_EXTRA - name: Build Domain Server + if: matrix.build_type == 'full' working-directory: ${{runner.workspace}}/build shell: bash run: cmake --build . --config $BUILD_TYPE --target domain-server $CMAKE_BUILD_EXTRA - name: Build Assignment Client + if: matrix.build_type == 'full' working-directory: ${{runner.workspace}}/build shell: bash run: cmake --build . --config $BUILD_TYPE --target assignment-client $CMAKE_BUILD_EXTRA - name: Build Console + if: matrix.build_type == 'full' working-directory: ${{runner.workspace}}/build shell: bash run: cmake --build . --config $BUILD_TYPE --target packaged-server-console $CMAKE_BUILD_EXTRA - name: Build Installer + if: matrix.build_type != 'android' working-directory: ${{runner.workspace}}/build shell: bash run: | @@ -144,6 +167,18 @@ jobs: done } retry cmake --build . --config $BUILD_TYPE --target package $CMAKE_BUILD_EXTRA + - name: Build for Android + Quest + if: matrix.build_type == 'android' + shell: bash + working-directory: ${{runner.workspace}}/project-athena + run: | + echo "Pre-cache the vcpkg managed dependencies" + $PYTHON_EXEC prebuild.py --build-root ${{runner.workspace}}/build --android interface + cd android + # Pre-cache the gradle dependencies + ./gradlew -m tasks -PHIFI_ANDROID_PRECOMPILED=$HIFI_ANDROID_PRECOMPILED + # Build! + ./build_android.sh - name: Output system stats if: ${{ always() }} working-directory: ${{runner.workspace}}/build @@ -161,4 +196,8 @@ jobs: working-directory: ${{runner.workspace}}/build env: GITHUB_CONTEXT: ${{ toJson(github) }} - run: $PYTHON_EXEC "$GITHUB_WORKSPACE/tools/ci-scripts/upload_to_publish_server.py" + run: | + if [[ "${{ matrix.build_type }}" == "android" ]]; then + cd $GITHUB_WORKSPACE/android + fi + $PYTHON_EXEC "$GITHUB_WORKSPACE/tools/ci-scripts/upload_to_publish_server.py" \ No newline at end of file diff --git a/android/build_android.sh b/android/build_android.sh index e9c69b09de..9cf1b9e2ab 100755 --- a/android/build_android.sh +++ b/android/build_android.sh @@ -5,11 +5,11 @@ ANDROID_BUILD_TYPE=release ANDROID_BUILD_TARGET=assembleRelease if [[ "$RELEASE_TYPE" == "PR" ]]; then -ANDROID_APK_SUFFIX=PR${RELEASE_NUMBER}-${SHA7}.apk ; +ANDROID_APK_SUFFIX=PR${RELEASE_NUMBER}-${GIT_COMMIT_SHORT}.apk ; elif [[ "${STABLE_BUILD}" == "1" ]]; then ANDROID_APK_SUFFIX=${RELEASE_NUMBER}.apk ; else -ANDROID_APK_SUFFIX=${RELEASE_NUMBER}-${SHA7}.apk ; +ANDROID_APK_SUFFIX=${RELEASE_NUMBER}-${GIT_COMMIT_SHORT}.apk ; fi @@ -17,7 +17,7 @@ fi ANDROID_APP=interface ANDROID_OUTPUT_DIR=./apps/${ANDROID_APP}/build/outputs/apk/${ANDROID_BUILD_TYPE} ANDROID_OUTPUT_FILE=${ANDROID_APP}-${ANDROID_BUILD_TYPE}.apk -ANDROID_APK_NAME=HighFidelity-Beta-${ANDROID_APK_SUFFIX} +ANDROID_APK_NAME=Vircadia-Alpha-${ANDROID_APK_SUFFIX} ./gradlew -PHIFI_ANDROID_PRECOMPILED=${HIFI_ANDROID_PRECOMPILED} -PVERSION_CODE=${VERSION_CODE} -PRELEASE_NUMBER=${RELEASE_NUMBER} -PRELEASE_TYPE=${RELEASE_TYPE} ${ANDROID_APP}:${ANDROID_BUILD_TARGET} cp ${ANDROID_OUTPUT_DIR}/${ANDROID_OUTPUT_FILE} ./${ANDROID_APK_NAME} @@ -25,9 +25,9 @@ cp ${ANDROID_OUTPUT_DIR}/${ANDROID_OUTPUT_FILE} ./${ANDROID_APK_NAME} ANDROID_APP=questInterface ANDROID_OUTPUT_DIR=./apps/${ANDROID_APP}/build/outputs/apk/${ANDROID_BUILD_TYPE} ANDROID_OUTPUT_FILE=${ANDROID_APP}-${ANDROID_BUILD_TYPE}.apk -ANDROID_APK_NAME=HighFidelity-Quest-Beta-${ANDROID_APK_SUFFIX} +ANDROID_APK_NAME=Vircadia-Quest-Alpha-${ANDROID_APK_SUFFIX} ./gradlew -PHIFI_ANDROID_PRECOMPILED=${HIFI_ANDROID_PRECOMPILED} -PVERSION_CODE=${VERSION_CODE} -PRELEASE_NUMBER=${RELEASE_NUMBER} -PRELEASE_TYPE=${RELEASE_TYPE} ${ANDROID_APP}:${ANDROID_BUILD_TARGET} || true -cp ${ANDROID_OUTPUT_DIR}/${ANDROID_OUTPUT_FILE} ./${ANDROID_APK_NAME} || true +cp ${ANDROID_OUTPUT_DIR}/${ANDROID_OUTPUT_FILE} ./${ANDROID_APK_NAME} diff --git a/android/containerized_build.sh b/android/containerized_build.sh index 0c21d1df91..94b5b28831 100755 --- a/android/containerized_build.sh +++ b/android/containerized_build.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash set -xeuo pipefail -DOCKER_IMAGE_NAME="hifi_androidbuild" +DOCKER_IMAGE_NAME="vircadia_androidbuild" -docker build --build-arg BUILD_UID=`id -u` -t "${DOCKER_IMAGE_NAME}" -f docker/Dockerfile docker +docker build --build-arg BUILD_UID=`id -u` -t "${DOCKER_IMAGE_NAME}" -f ./android/docker/Dockerfile ./android/docker # The Jenkins PR builds use VERSION_CODE, but the release builds use VERSION # So make sure we use VERSION_CODE consistently @@ -17,7 +17,7 @@ test -z "$STABLE_BUILD" && export STABLE_BUILD=0 docker run \ --rm \ --security-opt seccomp:unconfined \ - -v "${WORKSPACE}":/home/jenkins/hifi \ + -v "${WORKSPACE}":/home/gha/project-athena \ -e RELEASE_NUMBER \ -e RELEASE_TYPE \ -e ANDROID_APP \ @@ -33,7 +33,7 @@ docker run \ -e OAUTH_CLIENT_SECRET \ -e OAUTH_CLIENT_ID \ -e OAUTH_REDIRECT_URI \ - -e SHA7 \ + -e GIT_COMMIT_SHORT \ -e STABLE_BUILD \ -e VERSION_CODE \ "${DOCKER_IMAGE_NAME}" \ diff --git a/android/docker/Dockerfile b/android/docker/Dockerfile index f6c0e7b2e5..144f6caffa 100644 --- a/android/docker/Dockerfile +++ b/android/docker/Dockerfile @@ -57,13 +57,13 @@ RUN apt-get -y install \ # --- Gradle ARG BUILD_UID=1001 -RUN useradd -ms /bin/bash -u $BUILD_UID jenkins -RUN echo "jenkins ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers -USER jenkins -WORKDIR /home/jenkins +RUN useradd -ms /bin/bash -u $BUILD_UID gha +RUN echo "gha ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers +USER gha +WORKDIR /home/gha -# Hifi dependencies -ENV HIFI_BASE="/home/jenkins/hifi_android" +# Vircadia dependencies +ENV HIFI_BASE="/home/gha/vircadia_android" ENV HIFI_ANDROID_PRECOMPILED="$HIFI_BASE/dependencies" ENV HIFI_VCPKG_BASE="$HIFI_BASE/vcpkg" @@ -71,24 +71,18 @@ RUN mkdir "$HIFI_BASE" && \ mkdir "$HIFI_VCPKG_BASE" && \ mkdir "$HIFI_ANDROID_PRECOMPILED" -# Checkout a relatively recent commit from the main repository and use it to cache the -# gradle and vcpkg dependencies -# This commit ID should be updated whenever someone changes the dependency list -# in cmake/ports -RUN git clone https://github.com/highfidelity/hifi.git && \ - cd ~/hifi && \ - git checkout 796bfb5d6715ff14c2e60f3ee8fac1465b7578c6 +# Download the repo +RUN git clone https://github.com/kasenvr/project-athena.git -WORKDIR /home/jenkins/hifi +WORKDIR /home/gha/project-athena RUN mkdir build # Pre-cache the vcpkg managed dependencies -WORKDIR /home/jenkins/hifi/build +WORKDIR /home/gha/project-athena/build RUN python3 ../prebuild.py --build-root `pwd` --android interface # Pre-cache the gradle dependencies -WORKDIR /home/jenkins/hifi/android +WORKDIR /home/gha/project-athena/android RUN ./gradlew -m tasks -PHIFI_ANDROID_PRECOMPILED=$HIFI_ANDROID_PRECOMPILED #RUN ./gradlew extractDependencies -PHIFI_ANDROID_PRECOMPILED=$HIFI_ANDROID_PRECOMPILED - diff --git a/prebuild.py b/prebuild.py index cc315a49a4..21363bb9de 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/hifi/android/apps/questInterface/.externalNativeBuild/cmake/debug/arm64-v8a']) + args = parser.parse_args(['--android', 'questInterface', '--build-root', 'C:/git/project-athena/android/apps/questInterface/.externalNativeBuild/cmake/debug/arm64-v8a']) return args def main(): From 91a35fb4bae944e6eaeac4a4ad2ba5aee0904d5f Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Wed, 19 Aug 2020 16:47:04 -0700 Subject: [PATCH 002/136] change quick goto --- .github/workflows/pr_build.yml | 1 - scripts/system/quickGoto.js | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 7bd061e7d2..3c6b91c65b 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -115,7 +115,6 @@ jobs: shell: bash run: cmake -E make_directory "${{runner.workspace}}/build" - name: Configure CMake - if: matrix.build_type != 'android' working-directory: ${{runner.workspace}}/build shell: bash run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DVCPKG_BUILD_TYPE=release $CMAKE_EXTRA diff --git a/scripts/system/quickGoto.js b/scripts/system/quickGoto.js index c5560cce83..ec278dd1d2 100644 --- a/scripts/system/quickGoto.js +++ b/scripts/system/quickGoto.js @@ -30,7 +30,8 @@ }); } - addGotoButton("dev-mobile"); - addGotoButton("quest-dev"); + addGotoButton("172.104.248.237"); + addGotoButton("167.172.61.134"); + addGotoButton("file:///~/serverless/tutorial.json"); }()); // END LOCAL_SCOPE From 2645547f486c1a55ccba9fa7526fec0d26b8e1ff Mon Sep 17 00:00:00 2001 From: Kalila L <kasenvr@gmail.com> Date: Thu, 27 Aug 2020 05:57:28 -0400 Subject: [PATCH 003/136] Add forceRedownload parameter to Script.require --- libraries/script-engine/src/ScriptEngine.cpp | 5 +++-- libraries/script-engine/src/ScriptEngine.h | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 3b2a122e71..641708e11b 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -4,6 +4,7 @@ // // Created by Brad Hefta-Gaub on 12/14/13. // Copyright 2013 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 @@ -1836,7 +1837,7 @@ QScriptValue ScriptEngine::instantiateModule(const QScriptValue& module, const Q } // CommonJS/Node.js like require/module support -QScriptValue ScriptEngine::require(const QString& moduleId) { +QScriptValue ScriptEngine::require(const QString& moduleId, bool forceRedownload) { qCDebug(scriptengine_module) << "ScriptEngine::require(" << moduleId.left(MAX_DEBUG_VALUE_LENGTH) << ")"; if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) { return unboundNullValue(); @@ -1875,7 +1876,7 @@ QScriptValue ScriptEngine::require(const QString& moduleId) { // `delete Script.require.cache[Script.require.resolve(moduleId)];` // cacheMeta is just used right now to tell deleted keys apart from undefined ones - bool invalidateCache = module.isUndefined() && cacheMeta.property(moduleId).isValid(); + bool invalidateCache = (module.isUndefined() && cacheMeta.property(moduleId).isValid()) || forceRedownload; // reset the cacheMeta record so invalidation won't apply next time, even if the module fails to load cacheMeta.setProperty(modulePath, QScriptValue()); diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 15166d572f..4e855ed125 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -4,6 +4,7 @@ // // Created by Brad Hefta-Gaub on 12/14/13. // Copyright 2013 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 @@ -421,10 +422,11 @@ public: * @function Script.require * @param {string} module - The module to use. May be a JavaScript file, a JSON file, or the name of a system module such * as <code>"appUi"</code> (i.e., the "appUi.js" system module JavaScript file). + * @param {bool} [forceRedownload=false] - Invalidate the cache for this module and redownload it if necessary. * @returns {object|array} The value assigned to <code>module.exports</code> in the JavaScript file, or the value defined * in the JSON file. */ - Q_INVOKABLE QScriptValue require(const QString& moduleId); + Q_INVOKABLE QScriptValue require(const QString& moduleId, bool forceRedownload = false); /**jsdoc * @function Script.resetModuleCache From 2a1857e9ec2a4c7627616cc1d9714a20322ec034 Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Thu, 27 Aug 2020 16:39:21 -0700 Subject: [PATCH 004/136] split entity script engines into two --- .../src/scripts/EntityScriptServer.cpp | 4 +- .../src/EntityTreeRenderer.cpp | 220 +++++++++++------- .../src/EntityTreeRenderer.h | 9 +- .../entities/src/EntityScriptingInterface.cpp | 34 ++- .../entities/src/EntityScriptingInterface.h | 15 +- 5 files changed, 173 insertions(+), 109 deletions(-) diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index 7c3d491470..44c388a42d 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -465,7 +465,9 @@ void EntityScriptServer::resetEntitiesScriptEngine() { scriptEngines->runScriptInitializers(newEngine); newEngine->runInThread(); auto newEngineSP = qSharedPointerCast<EntitiesScriptEngineProvider>(newEngine); - DependencyManager::get<EntityScriptingInterface>()->setEntitiesScriptEngine(newEngineSP); + // On the entity script server, these are the same + DependencyManager::get<EntityScriptingInterface>()->setPersistentEntitiesScriptEngine(newEngineSP); + DependencyManager::get<EntityScriptingInterface>()->setNonPersistentEntitiesScriptEngine(newEngineSP); if (_entitiesScriptEngine) { disconnect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptDetailsUpdated, diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index f070c9c2f7..8e9e9d21e2 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -158,79 +158,86 @@ render::ItemID EntityTreeRenderer::renderableIdForEntityId(const EntityItemID& i int EntityTreeRenderer::_entitiesScriptEngineCount = 0; -void EntityTreeRenderer::resetEntitiesScriptEngine() { - _entitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, - QString("about:Entities %1").arg(++_entitiesScriptEngineCount)); - DependencyManager::get<ScriptEngines>()->runScriptInitializers(_entitiesScriptEngine); - _entitiesScriptEngine->runInThread(); - auto entitiesScriptEngineProvider = qSharedPointerCast<EntitiesScriptEngineProvider>(_entitiesScriptEngine); +void EntityTreeRenderer::setupEntityScriptEngineSignals(const ScriptEnginePointer& scriptEngine) { auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); - entityScriptingInterface->setEntitiesScriptEngine(entitiesScriptEngineProvider); - // Connect mouse events to entity script callbacks - if (!_mouseAndPreloadSignalHandlersConnected) { - - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "mousePressOnEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseDoublePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseDoublePressOnEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveOnEntity", event); - // FIXME: this is a duplicate of mouseMoveOnEntity, but it seems like some scripts might use this naming - _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveEvent", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseReleaseOnEntity", event); - }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "mousePressOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseDoublePressOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "mouseDoublePressOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "mouseMoveOnEntity", event); + // FIXME: this is a duplicate of mouseMoveOnEntity, but it seems like some scripts might use this naming + scriptEngine->callEntityScriptMethod(entityID, "mouseMoveEvent", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "mouseReleaseOnEntity", event); + }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "clickDownOnEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::holdingClickOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "holdingClickOnEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "clickReleaseOnEntity", event); - }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "clickDownOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::holdingClickOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "holdingClickOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickReleaseOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "clickReleaseOnEntity", event); + }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverEnterEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverOverEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverLeaveEntity", event); - }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "hoverEnterEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "hoverOverEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "hoverLeaveEntity", event); + }); - connect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptPreloadFinished, [&](const EntityItemID& entityID) { - EntityItemPointer entity = getTree()->findEntityByID(entityID); - if (entity) { - entity->setScriptHasFinishedPreload(true); - } - }); + connect(scriptEngine.data(), &ScriptEngine::entityScriptPreloadFinished, [&](const EntityItemID& entityID) { + EntityItemPointer entity = getTree()->findEntityByID(entityID); + if (entity) { + entity->setScriptHasFinishedPreload(true); + } + }); +} - _mouseAndPreloadSignalHandlersConnected = true; - } +void EntityTreeRenderer::resetPersistentEntitiesScriptEngine() { + _persistentEntitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, + QString("about:Entities %1").arg(++_entitiesScriptEngineCount)); + DependencyManager::get<ScriptEngines>()->runScriptInitializers(_persistentEntitiesScriptEngine); + _persistentEntitiesScriptEngine->runInThread(); + auto entitiesScriptEngineProvider = qSharedPointerCast<EntitiesScriptEngineProvider>(_persistentEntitiesScriptEngine); + auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); + entityScriptingInterface->setPersistentEntitiesScriptEngine(entitiesScriptEngineProvider); + + setupEntityScriptEngineSignals(_persistentEntitiesScriptEngine); +} + +void EntityTreeRenderer::resetNonPersistentEntitiesScriptEngine() { + _nonPersistentEntitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, + QString("about:Entities %1").arg(++_entitiesScriptEngineCount)); + DependencyManager::get<ScriptEngines>()->runScriptInitializers(_nonPersistentEntitiesScriptEngine); + _nonPersistentEntitiesScriptEngine->runInThread(); + auto entitiesScriptEngineProvider = qSharedPointerCast<EntitiesScriptEngineProvider>(_nonPersistentEntitiesScriptEngine); + DependencyManager::get<EntityScriptingInterface>()->setNonPersistentEntitiesScriptEngine(entitiesScriptEngineProvider); + + setupEntityScriptEngineSignals(_nonPersistentEntitiesScriptEngine); } void EntityTreeRenderer::stopDomainAndNonOwnedEntities() { leaveDomainAndNonOwnedEntities(); // unload and stop the engine - if (_entitiesScriptEngine) { - QList<EntityItemID> entitiesWithEntityScripts = _entitiesScriptEngine->getListOfEntityScriptIDs(); + if (_nonPersistentEntitiesScriptEngine) { + QList<EntityItemID> entitiesWithEntityScripts = _nonPersistentEntitiesScriptEngine->getListOfEntityScriptIDs(); - foreach (const EntityItemID& entityID, entitiesWithEntityScripts) { + foreach (const EntityItemID& entityID, entitiesWithEntityScripts) { EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID); - if (entityItem && !entityItem->getScript().isEmpty()) { if (!(entityItem->isLocalEntity() || entityItem->isMyAvatarEntity())) { - if (_currentEntitiesInside.contains(entityID)) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); - } - _entitiesScriptEngine->unloadEntityScript(entityID, true); + _nonPersistentEntitiesScriptEngine->unloadEntityScript(entityID, true); } } } @@ -240,6 +247,16 @@ void EntityTreeRenderer::stopDomainAndNonOwnedEntities() { void EntityTreeRenderer::clearDomainAndNonOwnedEntities() { stopDomainAndNonOwnedEntities(); + if (_nonPersistentEntitiesScriptEngine) { + // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread + _nonPersistentEntitiesScriptEngine->unloadAllEntityScripts(true); + _nonPersistentEntitiesScriptEngine->stop(); + } + + if (!_shuttingDown && _wantScripts) { + resetNonPersistentEntitiesScriptEngine(); + } + std::unordered_map<EntityItemID, EntityRendererPointer> savedEntities; std::unordered_set<EntityRendererPointer> savedRenderables; // remove all entities from the scene @@ -269,11 +286,17 @@ void EntityTreeRenderer::clearDomainAndNonOwnedEntities() { void EntityTreeRenderer::clear() { leaveAllEntities(); - // unload and stop the engine - if (_entitiesScriptEngine) { + + // unload and stop the engines + if (_nonPersistentEntitiesScriptEngine) { // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread - _entitiesScriptEngine->unloadAllEntityScripts(true); - _entitiesScriptEngine->stop(); + _nonPersistentEntitiesScriptEngine->unloadAllEntityScripts(true); + _nonPersistentEntitiesScriptEngine->stop(); + } + if (_persistentEntitiesScriptEngine) { + // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread + _persistentEntitiesScriptEngine->unloadAllEntityScripts(true); + _persistentEntitiesScriptEngine->stop(); } // reset the engine @@ -289,7 +312,8 @@ void EntityTreeRenderer::clear() { } } else { if (_wantScripts) { - resetEntitiesScriptEngine(); + resetPersistentEntitiesScriptEngine(); + resetNonPersistentEntitiesScriptEngine(); } if (scene) { for (const auto& entry : _entitiesInScene) { @@ -313,13 +337,17 @@ void EntityTreeRenderer::clear() { } void EntityTreeRenderer::reloadEntityScripts() { - _entitiesScriptEngine->unloadAllEntityScripts(); - _entitiesScriptEngine->resetModuleCache(); + _persistentEntitiesScriptEngine->unloadAllEntityScripts(); + _persistentEntitiesScriptEngine->resetModuleCache(); + _nonPersistentEntitiesScriptEngine->unloadAllEntityScripts(); + _nonPersistentEntitiesScriptEngine->resetModuleCache(); + for (const auto& entry : _entitiesInScene) { const auto& renderer = entry.second; const auto& entity = renderer->getEntity(); if (!entity->getScript().isEmpty()) { - _entitiesScriptEngine->loadEntityScript(entity->getEntityItemID(), resolveScriptURL(entity->getScript()), true); + auto scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + scriptEngine->loadEntityScript(entity->getEntityItemID(), resolveScriptURL(entity->getScript()), true); } } } @@ -329,7 +357,8 @@ void EntityTreeRenderer::init() { EntityTreePointer entityTree = std::static_pointer_cast<EntityTree>(_tree); if (_wantScripts) { - resetEntitiesScriptEngine(); + resetPersistentEntitiesScriptEngine(); + resetNonPersistentEntitiesScriptEngine(); } forceRecheckEntities(); // setup our state to force checking our inside/outsideness of entities @@ -341,8 +370,11 @@ void EntityTreeRenderer::init() { } void EntityTreeRenderer::shutdown() { - if (_entitiesScriptEngine) { - _entitiesScriptEngine->disconnectNonEssentialSignals(); // disconnect all slots/signals from the script engine, except essential + if (_persistentEntitiesScriptEngine) { + _persistentEntitiesScriptEngine->disconnectNonEssentialSignals(); // disconnect all slots/signals from the script engine, except essential + } + if (_nonPersistentEntitiesScriptEngine) { + _nonPersistentEntitiesScriptEngine->disconnectNonEssentialSignals(); // disconnect all slots/signals from the script engine, except essential } _shuttingDown = true; @@ -655,12 +687,14 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { // EntityItemIDs from here. The callEntityScriptMethod() method is robust against attempting to call scripts // for entity IDs that no longer exist. - if (_entitiesScriptEngine) { + if (_persistentEntitiesScriptEngine && _nonPersistentEntitiesScriptEngine) { // for all of our previous containing entities, if they are no longer containing then send them a leave event foreach(const EntityItemID& entityID, _currentEntitiesInside) { if (!entitiesContainingAvatar.contains(entityID)) { emit leaveEntity(entityID); - _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + auto& entity = getTree()->findEntityByEntityItemID(entityID); + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); } } @@ -668,7 +702,9 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { foreach(const EntityItemID& entityID, entitiesContainingAvatar) { if (!_currentEntitiesInside.contains(entityID)) { emit enterEntity(entityID); - _entitiesScriptEngine->callEntityScriptMethod(entityID, "enterEntity"); + auto& entity = getTree()->findEntityByEntityItemID(entityID); + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + scriptEngine->callEntityScriptMethod(entityID, "enterEntity"); } } _currentEntitiesInside = entitiesContainingAvatar; @@ -684,8 +720,8 @@ void EntityTreeRenderer::leaveDomainAndNonOwnedEntities() { EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID); if (entityItem && !(entityItem->isLocalEntity() || entityItem->isMyAvatarEntity())) { emit leaveEntity(entityID); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + if (_nonPersistentEntitiesScriptEngine) { + _nonPersistentEntitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); } } else { currentEntitiesInsideToSave.insert(entityID); @@ -703,8 +739,12 @@ void EntityTreeRenderer::leaveAllEntities() { // for all of our previous containing entities, if they are no longer containing then send them a leave event foreach(const EntityItemID& entityID, _currentEntitiesInside) { emit leaveEntity(entityID); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID); + if (entityItem) { + auto& scriptEngine = (entityItem->isLocalEntity() || entityItem->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + if (scriptEngine) { + scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + } } } _currentEntitiesInside.clear(); @@ -1000,11 +1040,12 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) { return; } - if (_tree && !_shuttingDown && _entitiesScriptEngine && !itr->second->getEntity()->getScript().isEmpty()) { + auto& scriptEngine = (itr->second->getEntity()->isLocalEntity() || itr->second->getEntity()->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + if (_tree && !_shuttingDown && scriptEngine && !itr->second->getEntity()->getScript().isEmpty()) { if (_currentEntitiesInside.contains(entityID)) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); } - _entitiesScriptEngine->unloadEntityScript(entityID, true); + scriptEngine->unloadEntityScript(entityID, true); } auto scene = _viewState->getMain3DScene(); @@ -1049,20 +1090,21 @@ void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID, bool if (!entity) { return; } - bool shouldLoad = entity->shouldPreloadScript() && _entitiesScriptEngine; + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + bool shouldLoad = entity->shouldPreloadScript() && scriptEngine; QString scriptUrl = entity->getScript(); if ((shouldLoad && unloadFirst) || scriptUrl.isEmpty()) { - if (_entitiesScriptEngine) { + if (scriptEngine) { if (_currentEntitiesInside.contains(entityID)) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); } - _entitiesScriptEngine->unloadEntityScript(entityID); + scriptEngine->unloadEntityScript(entityID); } entity->scriptHasUnloaded(); } if (shouldLoad) { entity->setScriptHasFinishedPreload(false); - _entitiesScriptEngine->loadEntityScript(entityID, resolveScriptURL(scriptUrl), reload); + scriptEngine->loadEntityScript(entityID, resolveScriptURL(scriptUrl), reload); entity->scriptHasPreloaded(); } } @@ -1169,8 +1211,9 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons if ((myNodeID == entityASimulatorID && entityAIsDynamic) || (myNodeID == entityBSimulatorID && (!entityAIsDynamic || entityASimulatorID.isNull()))) { playEntityCollisionSound(entityA, collision); emit collisionWithEntity(idA, idB, collision); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(idA, "collisionWithEntity", idB, collision); + auto& scriptEngine = (entityA->isLocalEntity() || entityA->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + if (scriptEngine) { + scriptEngine->callEntityScriptMethod(idA, "collisionWithEntity", idB, collision); } } @@ -1180,8 +1223,9 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons Collision invertedCollision(collision); invertedCollision.invert(); emit collisionWithEntity(idB, idA, invertedCollision); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(idB, "collisionWithEntity", idA, invertedCollision); + auto& scriptEngine = (entityB->isLocalEntity() || entityB->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + if (scriptEngine) { + scriptEngine->callEntityScriptMethod(idB, "collisionWithEntity", idA, invertedCollision); } } } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 1deadc254e..8538ec1c13 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -170,7 +170,9 @@ private: EntityRendererPointer renderableForEntity(const EntityItemPointer& entity) const { return renderableForEntityId(entity->getID()); } render::ItemID renderableIdForEntity(const EntityItemPointer& entity) const { return renderableIdForEntityId(entity->getID()); } - void resetEntitiesScriptEngine(); + void resetPersistentEntitiesScriptEngine(); + void resetNonPersistentEntitiesScriptEngine(); + void setupEntityScriptEngineSignals(const ScriptEnginePointer& scriptEngine); void findBestZoneAndMaybeContainingEntities(QSet<EntityItemID>& entitiesContainingAvatar); @@ -193,7 +195,8 @@ private: QSet<EntityItemID> _currentEntitiesInside; bool _wantScripts; - ScriptEnginePointer _entitiesScriptEngine; + ScriptEnginePointer _nonPersistentEntitiesScriptEngine; // used for domain + non-owned avatar entities, cleared on domain switch + ScriptEnginePointer _persistentEntitiesScriptEngine; // used for local + owned avatar entities, persists on domain switch, cleared on reload content void playEntityCollisionSound(const EntityItemPointer& entity, const Collision& collision); @@ -211,8 +214,6 @@ private: std::function<RayToEntityIntersectionResult(unsigned int)> _getPrevRayPickResultOperator; std::function<void(unsigned int, bool)> _setPrecisionPickingOperator; - bool _mouseAndPreloadSignalHandlersConnected { false }; - class LayeredZone { public: LayeredZone(std::shared_ptr<ZoneEntityItem> zone) : zone(zone), id(zone->getID()), volume(zone->getVolumeEstimate()) {} diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index fd83c99ca5..a6f9b824f0 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -1045,18 +1045,26 @@ QSizeF EntityScriptingInterface::textSize(const QUuid& id, const QString& text) return EntityTree::textSize(id, text); } -void EntityScriptingInterface::setEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine) { +void EntityScriptingInterface::setPersistentEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine) { std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); - _entitiesScriptEngine = engine; + _persistentEntitiesScriptEngine = engine; +} + +void EntityScriptingInterface::setNonPersistentEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine) { + std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); + _nonPersistentEntitiesScriptEngine = engine; } void EntityScriptingInterface::callEntityMethod(const QUuid& id, const QString& method, const QStringList& params) { PROFILE_RANGE(script_entities, __FUNCTION__); - - std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); - if (_entitiesScriptEngine) { - EntityItemID entityID{ id }; - _entitiesScriptEngine->callEntityScriptMethod(entityID, method, params); + + auto entity = getEntityTree()->findEntityByEntityItemID(id); + if (entity) { + std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + if (scriptEngine) { + scriptEngine->callEntityScriptMethod(id, method, params); + } } } @@ -1098,9 +1106,13 @@ void EntityScriptingInterface::handleEntityScriptCallMethodPacket(QSharedPointer params << paramString; } - std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, method, params, senderNode->getUUID()); + auto entity = getEntityTree()->findEntityByEntityItemID(entityID); + if (entity) { + std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + if (scriptEngine) { + scriptEngine->callEntityScriptMethod(entityID, method, params, senderNode->getUUID()); + } } } } @@ -1331,7 +1343,7 @@ bool EntityPropertyMetadataRequest::script(EntityItemID entityID, QScriptValue h if (entitiesScriptEngine) { request->setFuture(entitiesScriptEngine->getLocalEntityScriptDetails(entityID)); } - }); + }, entityID); if (!request->isStarted()) { request->deleteLater(); callScopedHandlerObject(handler, _engine->makeError("Entities Scripting Provider unavailable", "InternalError"), QScriptValue()); diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index dae0922f4a..af2ad57ea4 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -178,7 +178,8 @@ public: void setEntityTree(EntityTreePointer modelTree); EntityTreePointer getEntityTree() { return _entityTree; } - void setEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine); + void setPersistentEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine); + void setNonPersistentEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine); void resetActivityTracking(); ActivityTracking getActivityTracking() const { return _activityTracking; } @@ -2497,9 +2498,12 @@ signals: void webEventReceived(const EntityItemID& entityItemID, const QVariant& message); protected: - void withEntitiesScriptEngine(std::function<void(QSharedPointer<EntitiesScriptEngineProvider>)> function) { - std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); - function(_entitiesScriptEngine); + void withEntitiesScriptEngine(std::function<void(QSharedPointer<EntitiesScriptEngineProvider>)> function, const EntityItemID& id) { + auto entity = getEntityTree()->findEntityByEntityItemID(id); + if (entity) { + std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); + function((entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine); + } }; private slots: @@ -2529,7 +2533,8 @@ private: EntityTreePointer _entityTree; std::recursive_mutex _entitiesScriptEngineLock; - QSharedPointer<EntitiesScriptEngineProvider> _entitiesScriptEngine; + QSharedPointer<EntitiesScriptEngineProvider> _persistentEntitiesScriptEngine; + QSharedPointer<EntitiesScriptEngineProvider> _nonPersistentEntitiesScriptEngine; bool _bidOnSimulationOwnership { false }; From 2e4a6ee1b530fae5e69e7033fc15f12dd2e63619 Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Fri, 28 Aug 2020 11:22:08 -0700 Subject: [PATCH 005/136] fix build errors --- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 8e9e9d21e2..b7d9c8cef5 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -346,7 +346,7 @@ void EntityTreeRenderer::reloadEntityScripts() { const auto& renderer = entry.second; const auto& entity = renderer->getEntity(); if (!entity->getScript().isEmpty()) { - auto scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; scriptEngine->loadEntityScript(entity->getEntityItemID(), resolveScriptURL(entity->getScript()), true); } } @@ -692,7 +692,7 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { foreach(const EntityItemID& entityID, _currentEntitiesInside) { if (!entitiesContainingAvatar.contains(entityID)) { emit leaveEntity(entityID); - auto& entity = getTree()->findEntityByEntityItemID(entityID); + auto entity = getTree()->findEntityByEntityItemID(entityID); auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); } @@ -702,7 +702,7 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { foreach(const EntityItemID& entityID, entitiesContainingAvatar) { if (!_currentEntitiesInside.contains(entityID)) { emit enterEntity(entityID); - auto& entity = getTree()->findEntityByEntityItemID(entityID); + auto entity = getTree()->findEntityByEntityItemID(entityID); auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; scriptEngine->callEntityScriptMethod(entityID, "enterEntity"); } From 8a007a4edf5c211d7232c39652012e597f6f1011 Mon Sep 17 00:00:00 2001 From: kasenvr <52365539+kasenvr@users.noreply.github.com> Date: Mon, 7 Sep 2020 01:38:44 -0400 Subject: [PATCH 006/136] Apply suggestions from code review Co-authored-by: HifiExperiments <53453710+HifiExperiments@users.noreply.github.com> Co-authored-by: David Rowe <david@ctrlaltstudio.com> --- libraries/script-engine/src/ScriptEngine.cpp | 2 +- libraries/script-engine/src/ScriptEngine.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 641708e11b..4f2aec0e4c 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -1876,7 +1876,7 @@ QScriptValue ScriptEngine::require(const QString& moduleId, bool forceRedownload // `delete Script.require.cache[Script.require.resolve(moduleId)];` // cacheMeta is just used right now to tell deleted keys apart from undefined ones - bool invalidateCache = (module.isUndefined() && cacheMeta.property(moduleId).isValid()) || forceRedownload; + bool invalidateCache = forceRedownload || (module.isUndefined() && cacheMeta.property(moduleId).isValid()); // reset the cacheMeta record so invalidation won't apply next time, even if the module fails to load cacheMeta.setProperty(modulePath, QScriptValue()); diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 4e855ed125..4aa47834b0 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -422,7 +422,7 @@ public: * @function Script.require * @param {string} module - The module to use. May be a JavaScript file, a JSON file, or the name of a system module such * as <code>"appUi"</code> (i.e., the "appUi.js" system module JavaScript file). - * @param {bool} [forceRedownload=false] - Invalidate the cache for this module and redownload it if necessary. + * @param {boolean} [forceRedownload=false] - Invalidate the cache for this module and redownload it if necessary. * @returns {object|array} The value assigned to <code>module.exports</code> in the JavaScript file, or the value defined * in the JSON file. */ From 8eb12a873bc1217853933e88626b04bae4f9369a Mon Sep 17 00:00:00 2001 From: Kalila L <kasenvr@gmail.com> Date: Thu, 17 Sep 2020 14:14:32 -0400 Subject: [PATCH 007/136] Revert forceRedownload functionality. --- libraries/script-engine/src/ScriptEngine.cpp | 5 ++--- libraries/script-engine/src/ScriptEngine.h | 4 +--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 4f2aec0e4c..3b2a122e71 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -4,7 +4,6 @@ // // Created by Brad Hefta-Gaub on 12/14/13. // Copyright 2013 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 @@ -1837,7 +1836,7 @@ QScriptValue ScriptEngine::instantiateModule(const QScriptValue& module, const Q } // CommonJS/Node.js like require/module support -QScriptValue ScriptEngine::require(const QString& moduleId, bool forceRedownload) { +QScriptValue ScriptEngine::require(const QString& moduleId) { qCDebug(scriptengine_module) << "ScriptEngine::require(" << moduleId.left(MAX_DEBUG_VALUE_LENGTH) << ")"; if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) { return unboundNullValue(); @@ -1876,7 +1875,7 @@ QScriptValue ScriptEngine::require(const QString& moduleId, bool forceRedownload // `delete Script.require.cache[Script.require.resolve(moduleId)];` // cacheMeta is just used right now to tell deleted keys apart from undefined ones - bool invalidateCache = forceRedownload || (module.isUndefined() && cacheMeta.property(moduleId).isValid()); + bool invalidateCache = module.isUndefined() && cacheMeta.property(moduleId).isValid(); // reset the cacheMeta record so invalidation won't apply next time, even if the module fails to load cacheMeta.setProperty(modulePath, QScriptValue()); diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 4aa47834b0..15166d572f 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -4,7 +4,6 @@ // // Created by Brad Hefta-Gaub on 12/14/13. // Copyright 2013 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 @@ -422,11 +421,10 @@ public: * @function Script.require * @param {string} module - The module to use. May be a JavaScript file, a JSON file, or the name of a system module such * as <code>"appUi"</code> (i.e., the "appUi.js" system module JavaScript file). - * @param {boolean} [forceRedownload=false] - Invalidate the cache for this module and redownload it if necessary. * @returns {object|array} The value assigned to <code>module.exports</code> in the JavaScript file, or the value defined * in the JSON file. */ - Q_INVOKABLE QScriptValue require(const QString& moduleId, bool forceRedownload = false); + Q_INVOKABLE QScriptValue require(const QString& moduleId); /**jsdoc * @function Script.resetModuleCache From 9f3978d3d5547dea5a2ec388876712e5aa6d1e49 Mon Sep 17 00:00:00 2001 From: Kalila L <kasenvr@gmail.com> Date: Thu, 17 Sep 2020 18:40:01 -0400 Subject: [PATCH 008/136] Update system to use a checkbox + setting instead. --- interface/src/Application.cpp | 13 +++++++++++++ interface/src/Application.h | 2 ++ interface/src/Menu.cpp | 4 ++++ interface/src/Menu.h | 1 + libraries/script-engine/src/ScriptEngine.cpp | 5 ++++- 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index fe2077f752..26ff27044d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -354,6 +354,7 @@ static const QString DESKTOP_DISPLAY_PLUGIN_NAME = "Desktop"; static const QString ACTIVE_DISPLAY_PLUGIN_SETTING_NAME = "activeDisplayPlugin"; static const QString SYSTEM_TABLET = "com.highfidelity.interface.tablet.system"; static const QString KEEP_ME_LOGGED_IN_SETTING_NAME = "keepMeLoggedIn"; +static const QString CACHEBUST_SCRIPT_REQUIRE_SETTING_NAME = "cachebustScriptRequire"; static const float FOCUS_HIGHLIGHT_EXPANSION_FACTOR = 1.05f; @@ -1958,6 +1959,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo loadSettings(); updateVerboseLogging(); + + setCachebustRequire(); // Make sure we don't time out during slow operations at startup updateHeartbeat(); @@ -2591,6 +2594,16 @@ void Application::updateVerboseLogging() { QLoggingCategory::setFilterRules(rules); } +void Application::setCachebustRequire() { + auto menu = Menu::getInstance(); + if (!menu) { + return; + } + bool enable = menu->isOptionChecked(MenuOption::CachebustRequire); + + Setting::Handle<bool>{ CACHEBUST_SCRIPT_REQUIRE_SETTING_NAME, false }.set(enable); +} + void Application::domainConnectionRefused(const QString& reasonMessage, int reasonCodeInt, const QString& extraInfo) { DomainHandler::ConnectionRefusedReason reasonCode = static_cast<DomainHandler::ConnectionRefusedReason>(reasonCodeInt); diff --git a/interface/src/Application.h b/interface/src/Application.h index f42696cda0..eddf45686d 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -470,6 +470,8 @@ public slots: void setIsInterstitialMode(bool interstitialMode); void updateVerboseLogging(); + + void setCachebustRequire(); void changeViewAsNeeded(float boomLength); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index e460b4b56b..8870d852ba 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -365,6 +365,10 @@ Menu::Menu() { // Developer > Scripting > Verbose Logging addCheckableActionToQMenuAndActionHash(scriptingOptionsMenu, MenuOption::VerboseLogging, 0, false, qApp, SLOT(updateVerboseLogging())); + + // Developer > Scripting > Enable Cachebusting of Script.require + addCheckableActionToQMenuAndActionHash(scriptingOptionsMenu, MenuOption::CachebustRequire, 0, false, + qApp, SLOT(setCachebustRequire())); // Developer > Scripting > Enable Speech Control API #if defined(Q_OS_MAC) || defined(Q_OS_WIN) diff --git a/interface/src/Menu.h b/interface/src/Menu.h index d33b3b0f5e..c7ca64eb5a 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -54,6 +54,7 @@ namespace MenuOption { const QString BookmarkAvatarEntities = "Bookmark Avatar Entities"; const QString BookmarkLocation = "Bookmark Location"; const QString CalibrateCamera = "Calibrate Camera"; + const QString CachebustRequire = "Enable Cachebusting of Script.require"; const QString CenterPlayerInView = "Center Player In View"; const QString Chat = "Chat..."; const QString ClearDiskCaches = "Clear Disk Caches (requires restart)"; diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 3b2a122e71..c2fa5bee04 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -1873,9 +1873,12 @@ QScriptValue ScriptEngine::require(const QString& moduleId) { // modules get cached in `Script.require.cache` and (similar to Node.js) users can access it // to inspect particular entries and invalidate them by deleting the key: // `delete Script.require.cache[Script.require.resolve(moduleId)];` + + // Check to see if + Setting::Handle<bool> getCachebustSetting {"cachebustScriptRequire", false }; // cacheMeta is just used right now to tell deleted keys apart from undefined ones - bool invalidateCache = module.isUndefined() && cacheMeta.property(moduleId).isValid(); + bool invalidateCache = getCachebustSetting.get() || (module.isUndefined() && cacheMeta.property(moduleId).isValid()); // reset the cacheMeta record so invalidation won't apply next time, even if the module fails to load cacheMeta.setProperty(modulePath, QScriptValue()); From 05ad300894b7b2f081934410539456e16695db8f Mon Sep 17 00:00:00 2001 From: Kalila L <kasenvr@gmail.com> Date: Sun, 11 Oct 2020 00:50:41 -0400 Subject: [PATCH 009/136] CR. --- interface/src/Menu.cpp | 8 ++++---- interface/src/Menu.h | 1 + libraries/script-engine/src/ScriptEngine.cpp | 2 +- libraries/script-engine/src/ScriptEngine.h | 1 + 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 1240912767..19cc7eacaa 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -4,14 +4,14 @@ // // Created by Stephen Birarda on 8/12/13. // Copyright 2013 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 // - -// For happ(ier) development of QML, use these two things: -// This forces QML files to be pulled from the source as you edit it: set environment variable HIFI_USE_SOURCE_TREE_RESOURCES=1 -// Use this to live reload: DependencyManager::get<OffscreenUi>()->clearCache(); +// For happ(ier) development of QML, use these two things: +// This forces QML files to be pulled from the source as you edit it: set environment variable HIFI_USE_SOURCE_TREE_RESOURCES=1 +// Use this to live reload: DependencyManager::get<OffscreenUi>()->clearCache(); #include "Menu.h" #include <QDesktopServices> diff --git a/interface/src/Menu.h b/interface/src/Menu.h index c7ca64eb5a..cac8e77f9e 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -4,6 +4,7 @@ // // Created by Stephen Birarda on 8/12/13. // Copyright 2013 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 diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index f97b279fd0..698b495e94 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -1942,7 +1942,7 @@ QScriptValue ScriptEngine::require(const QString& moduleId) { // to inspect particular entries and invalidate them by deleting the key: // `delete Script.require.cache[Script.require.resolve(moduleId)];` - // Check to see if + // Check to see if we should invalidate the cache based on a user setting. Setting::Handle<bool> getCachebustSetting {"cachebustScriptRequire", false }; // cacheMeta is just used right now to tell deleted keys apart from undefined ones diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 219453875e..8cbeed58af 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -4,6 +4,7 @@ // // Created by Brad Hefta-Gaub on 12/14/13. // Copyright 2013 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 From 5a8c1a0374ee713ce6afb1ff84e68cc5521449fb Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Mon, 12 Oct 2020 18:50:46 -0700 Subject: [PATCH 010/136] starting improve entity updates pt 2 --- .../src/RenderableEntityItem.cpp | 4 +- .../src/RenderableEntityItem.h | 11 - .../src/RenderableGizmoEntityItem.cpp | 28 +- .../src/RenderableGridEntityItem.cpp | 25 +- .../src/RenderableGridEntityItem.h | 5 +- .../src/RenderableImageEntityItem.cpp | 111 +++--- .../src/RenderableImageEntityItem.h | 2 +- .../src/RenderableMaterialEntityItem.cpp | 372 +++++++++--------- .../src/RenderableMaterialEntityItem.h | 2 +- .../src/RenderableModelEntityItem.cpp | 330 ++++++---------- .../src/RenderableModelEntityItem.h | 13 +- libraries/entities/src/LightEntityItem.cpp | 31 +- libraries/entities/src/ModelEntityItem.cpp | 65 +-- libraries/entities/src/ModelEntityItem.h | 21 +- libraries/render-utils/src/Model.cpp | 29 +- libraries/render-utils/src/Model.h | 8 +- 16 files changed, 433 insertions(+), 624 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 807a240763..32dd280502 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); }); 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<QUuid>& renderWithZones) { _renderWithZones = renderWithZones; } - - template <typename F, typename T> - T withReadLockResult(const std::function<T()>& 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..3cd8bab822 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; + glm::u8vec3 _color { NAN }; + 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<bool>([&] { - 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<TextureCache>()->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<TextureCache>()->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..8d9ce24992 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -16,199 +16,186 @@ 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<bool>([&] { - if (entity->getTransform() != _transform) { - return true; - } - if (entity->getUnscaledDimensions() != _dimensions) { - return true; - } - if (entity->getParentID() != _parentID) { - return true; - } - - return false; + return entity->getParentID() != _parentID; })) { return true; } return false; } -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 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; - } - } - { - 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); - } - } - - 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; - } - } - } - { - 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; - } - } - { - quint16 priority = entity->getPriority(); - if (priority != _priority) { - _priority = priority; - deleteNeeded = true; - addNeeded = true; - } - } - - if (urlChanged && !usingMaterialData) { - _networkMaterial = DependencyManager::get<MaterialCache>()->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) { - 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); - } - } - - { - auto material = getMaterial(); - bool newTexturesLoaded = material ? !material->isMissingTexture() : false; - if (!_texturesLoaded && newTexturesLoaded) { - material->checkResetOpacityMap(); - } - _texturesLoaded = newTexturesLoaded; - } - - _renderTransform = getModelTransform(); - const float MATERIAL_ENTITY_SCALE = 0.5f; - _renderTransform.postScale(MATERIAL_ENTITY_SCALE); - _renderTransform.postScale(ENTITY_ITEM_DEFAULT_DIMENSIONS); +void MaterialEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { + void* key = (void*)this; + AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] { + withWriteLock([&] { + _renderTransform = getModelTransform(); + const float MATERIAL_ENTITY_SCALE = 0.5f; + _renderTransform.postScale(MATERIAL_ENTITY_SCALE); + _renderTransform.postScale(ENTITY_ITEM_DEFAULT_DIMENSIONS); + }); }); } +void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { + 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; + } + } + { + 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; + } + } + + { + 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 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; + } + } + { + 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; + } + } + + if (urlChanged && !usingMaterialData) { + _networkMaterial = DependencyManager::get<MaterialCache>()->getMaterial(_materialURL); + auto onMaterialRequestFinished = [this, entity, oldParentID, oldParentMaterialName, newCurrentMaterialName](bool success) { + deleteMaterial(oldParentID, oldParentMaterialName); + 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); + }); + } + } + } 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); + } + } + + { + auto material = getMaterial(); + bool newTexturesLoaded = material ? !material->isMissingTexture() : false; + if (!_texturesLoaded && newTexturesLoaded) { + material->checkResetOpacityMap(); + } + _texturesLoaded = newTexturesLoaded; + } + + if (!_texturesLoaded || _retryApply) { + emit requestRenderUpdate(); + } +} + ItemKey MaterialEntityRenderer::getKey() { auto builder = ItemKey::Builder().withTypeShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); @@ -276,25 +263,26 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) { 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..7d455c98de 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h @@ -27,8 +27,8 @@ 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..a508ff7f56 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -53,7 +53,7 @@ ModelPointer ModelEntityWrapper::getModel() const { bool ModelEntityWrapper::isModelLoaded() const { return resultWithReadLock<bool>([&] { - return _model.operator bool() && _model->isLoaded(); + return _model && _model->isLoaded(); }); } @@ -69,8 +69,7 @@ EntityItemPointer RenderableModelEntityItem::factory(const EntityItemID& entityI RenderableModelEntityItem::RenderableModelEntityItem(const EntityItemID& entityItemID, bool dimensionsInitialized) : ModelEntityWrapper(entityItemID), _dimensionsInitialized(dimensionsInitialized) { - - + } RenderableModelEntityItem::~RenderableModelEntityItem() { } @@ -182,20 +181,24 @@ void RenderableModelEntityItem::updateModelBounds() { } bool overridingModelTransform = model->isOverridingModelTransformAndOffset(); + glm::vec3 scaledDimensions = getScaledDimensions(); + glm::vec3 registrationPoint = getRegistrationPoint(); + QString modelURL = getModelURL(); if (!overridingModelTransform && - (model->getScaleToFitDimensions() != getScaledDimensions() || - model->getRegistrationPoint() != getRegistrationPoint() || + (model->getScaleToFitDimensions() != scaledDimensions || + model->getRegistrationPoint() != registrationPoint || + model->getURL() != modelURL || !model->getIsScaledToFit())) { // 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(); } @@ -248,8 +251,6 @@ EntityItemProperties RenderableModelEntityItem::getProperties(const EntityProper } } - - return properties; } @@ -960,13 +961,13 @@ QStringList RenderableModelEntityItem::getJointNames() const { } scriptable::ScriptableModelBase render::entities::ModelEntityRenderer::getScriptableModel() { - auto model = resultWithReadLock<ModelPointer>([this]{ return _model; }); + auto model = resultWithReadLock<ModelPointer>([&] { return _model; }); if (!model || !model->isLoaded()) { return scriptable::ScriptableModelBase(); } - auto result = _model->getScriptableModel(); + auto result = model->getScriptableModel(); result.objectID = getEntity()->getID(); { std::lock_guard<std::mutex> lock(_materialsLock); @@ -1054,10 +1055,10 @@ 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 (!_cullWithParent && model && model->isGroupCulled()) { builder.withMetaCullGroup(); } else if (_cullWithParent) { builder.withSubMetaCulled(); @@ -1075,8 +1076,9 @@ ItemKey ModelEntityRenderer::getKey() { } uint32_t ModelEntityRenderer::metaFetchMetaSubItems(ItemIDs& subItems) const { - if (_model) { - auto metaSubItems = _model->fetchRenderItemIDs(); + auto model = resultWithReadLock<ModelPointer>([&] { return _model; }); + if (model) { + auto metaSubItems = model->fetchRenderItemIDs(); subItems.insert(subItems.end(), metaSubItems.begin(), metaSubItems.end()); return (uint32_t)metaSubItems.size(); } @@ -1089,8 +1091,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<ModelPointer>([&] { return _model; }); + if (model) { + model->removeFromScene(scene, transaction); } Parent::removeFromScene(scene, transaction); } @@ -1099,7 +1102,7 @@ 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; } @@ -1124,17 +1127,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(); @@ -1183,90 +1186,39 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { } bool ModelEntityRenderer::needsRenderUpdate() const { - if (resultWithReadLock<bool>([&] { - if (_moving || _animating) { - return true; - } + //ModelPointer model = resultWithReadLock<ModelPointer>([&] { + // return _model; + //}); - if (!_texturesLoaded) { - return true; - } + //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 (model->needsReload()) { + // return true; + // } - if (!_prevModelLoaded) { - return true; - } - - return false; - })) { - 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; - } - } + // if (model->needsFixupInScene()) { + // return true; + // } + //} return Parent::needsRenderUpdate(); } bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { - if (resultWithReadLock<bool>([&] { - if (entity->hasModel() != _hasModel) { - return true; - } + if (entity->blendshapesChanged()) { + return true; + } - // No model to render, early exit - if (!_hasModel) { - return false; - } + // Check to see if we need to update the model bounds + if (entity->needsUpdateModelBounds()) { + return true; + } - if (_animating != entity->isAnimatingSomething()) { - return true; - } - - return false; - })) { return true; } - - ModelPointer model; - withReadLock([&] { - model = _model; + ModelPointer model = resultWithReadLock<ModelPointer>([&] { + return _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() || @@ -1280,48 +1232,38 @@ bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin } } - 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(); + if (_parsedModelURL != entity->getModelURL()) { + _parsedModelURL = QUrl(entity->getModelURL()); } - withWriteLock([&] { - _animating = entity->isAnimatingSomething(); - if (_parsedModelURL != entity->getModelURL()) { - _parsedModelURL = QUrl(entity->getModelURL()); - } + ModelPointer model = resultWithReadLock<ModelPointer>([&] { + 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<scriptable::ModelProviderFactory>()-> - modelRemovedFromScene(entity->getEntityItemID(), NestableType::Entity, _model); + modelRemovedFromScene(entity->getEntityItemID(), NestableType::Entity, model); + withWriteLock([&] { model.reset(); }); } - setKey(false); _didLastVisualGeometryRequestSucceed = false; + setKey(_didLastVisualGeometryRequestSucceed, model); return; } @@ -1330,18 +1272,28 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce model = std::make_shared<Model>(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(); + 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<scriptable::ModelProviderFactory>()-> - modelAddedToScene(entity->getEntityItemID(), NestableType::Entity, _model); + modelAddedToScene(entity->getEntityItemID(), NestableType::Entity, model); } _didLastVisualGeometryRequestSucceed = didVisualGeometryRequestSucceed; + entity->_dimensionsInitialized = false; + entity->_originalTexturesRead = false; + entity->_needsJointSimulation = true; + emit requestRenderUpdate(); }); model->setLoadingPriority(EntityTreeRenderer::getEntityLoadingPriority(*entity)); entity->setModel(model); @@ -1350,24 +1302,15 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce // 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->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 @@ -1383,6 +1326,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce QMetaObject::invokeMethod(DependencyManager::get<EntityScriptingInterface>().data(), "editEntity", Qt::QueuedConnection, Q_ARG(QUuid, entity->getEntityItemID()), Q_ARG(EntityItemProperties, properties)); + entity->_dimensionsInitialized = true; } if (!entity->_originalTexturesRead) { @@ -1393,51 +1337,34 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce if (_textures != entity->getTextures()) { QVariantMap newTextures; - withWriteLock([&] { - _texturesLoaded = false; - _textures = entity->getTextures(); - newTextures = parseTexturesToMap(_textures, entity->_originalTextures); - }); + _texturesLoaded = false; + _textures = entity->getTextures(); + newTextures = parseTexturesToMap(_textures, entity->_originalTextures); model->setTextures(newTextures); } + if (entity->_needsJointSimulation) { entity->copyAnimationJointDataToModel(); } entity->updateModelBounds(); entity->stopModelOverrideIfNoParent(); - if (model->isVisible() != _visible) { - 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); - } + setKey(_didLastVisualGeometryRequestSucceed, 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 (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()) { @@ -1452,9 +1379,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce } if (!_texturesLoaded && model->getGeometry() && model->getGeometry()->areTexturesLoaded()) { - withWriteLock([&] { - _texturesLoaded = true; - }); + _texturesLoaded = true; model->updateRenderItems(); } else if (!_texturesLoaded) { emit requestRenderUpdate(); @@ -1491,9 +1416,13 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce 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 +1431,20 @@ 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; } } - + + ModelPointer model = resultWithReadLock<ModelPointer>([&] { + return _model; + }); if (!_jointMappingCompleted) { mapJoints(entity, model); } - if (entity->readyToAnimate()) { - animate(entity); + if (entity->readyToAnimate() && model && model->isLoaded()) { + animate(entity, model); } emit requestRenderUpdate(); } @@ -1521,40 +1452,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<QUuid>& 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 +1481,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<ModelPointer>([&] { + 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..4cccc327bc 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -153,25 +153,24 @@ 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<BlendshapeOffset>& blendshapeOffsets, const QVector<int>& 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 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; void setIsVisibleInSecondaryCamera(bool value) override; void setRenderLayer(RenderLayer value) override; - void setPrimitiveMode(PrimitiveMode value) override; void setCullWithParent(bool value) override; - void setRenderWithZones(const QVector<QUuid>& 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 @@ -192,14 +191,12 @@ private: bool _jointMappingCompleted { false }; QVector<int> _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/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..3a4e96d7bd 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -330,13 +330,6 @@ void ModelEntityItem::setCompoundShapeURL(const QString& url) { }); } -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 +392,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; @@ -629,61 +608,18 @@ void ModelEntityItem::setAnimationCurrentFrame(float value) { }); } -void ModelEntityItem::setAnimationAllowTranslation(bool value) { - withWriteLock([&] { - _animationProperties.setAllowTranslation(value); - }); -} - bool ModelEntityItem::getAnimationAllowTranslation() const { return resultWithReadLock<bool>([&] { return _animationProperties.getAllowTranslation(); }); } -void ModelEntityItem::setAnimationLoop(bool loop) { - withWriteLock([&] { - _animationProperties.setLoop(loop); - }); -} - -bool ModelEntityItem::getAnimationLoop() const { - return resultWithReadLock<bool>([&] { - return _animationProperties.getLoop(); - }); -} - - -void ModelEntityItem::setAnimationHold(bool hold) { - withWriteLock([&] { - _animationProperties.setHold(hold); - }); -} - -bool ModelEntityItem::getAnimationHold() const { - return resultWithReadLock<bool>([&] { - return _animationProperties.getHold(); - }); -} - -bool ModelEntityItem::getAnimationIsPlaying() const { - return resultWithReadLock<bool>([&] { - return _animationProperties.getRunning(); - }); -} - float ModelEntityItem::getAnimationCurrentFrame() const { return resultWithReadLock<float>([&] { return _animationProperties.getCurrentFrame(); }); } -float ModelEntityItem::getAnimationFPS() const { - return resultWithReadLock<float>([&] { - return _animationProperties.getFPS(); - }); -} - bool ModelEntityItem::isAnimatingSomething() const { return resultWithReadLock<bool>([&] { return _animationProperties.isValidAndRunning(); @@ -722,6 +658,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..59bb6d67cf 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -85,24 +85,12 @@ public: // 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 +98,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); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 182b83762c..e46bdc03b3 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -958,16 +958,20 @@ 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); + updateRenderItemsKey(scene); } } -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 +981,27 @@ void Model::setCullWithParent(bool cullWithParent) { data.updateKey(renderItemsKey); }); } - AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); + scene->enqueueTransaction(transaction); } } -void Model::setRenderWithZones(const QVector<QUuid>& renderWithZones) { +void Model::setRenderWithZones(const QVector<QUuid>& 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<ModelMeshPartPayload>(item, [renderWithZones, renderItemsKey](ModelMeshPartPayload& data) { + data.setRenderWithZones(renderWithZones); + }); + } + scene->enqueueTransaction(transaction); } } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 4585ad0009..7372baa2dd 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<QUuid>& renderWithZones); + void setRenderWithZones(const QVector<QUuid>& renderWithZones, const render::ScenePointer& scene = nullptr); const QVector<QUuid>& 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. From ae7a46fbca3067963861f306856df915584b6c04 Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Mon, 12 Oct 2020 22:31:39 -0700 Subject: [PATCH 011/136] more updates --- .../src/RenderableModelEntityItem.cpp | 50 +++---------------- .../src/RenderableModelEntityItem.h | 1 - libraries/entities/src/ModelEntityItem.cpp | 1 + 3 files changed, 8 insertions(+), 44 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index a508ff7f56..17c2caffdc 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1185,25 +1185,6 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity, const ModelP entity->copyAnimationJointDataToModel(); } -bool ModelEntityRenderer::needsRenderUpdate() const { - //ModelPointer model = resultWithReadLock<ModelPointer>([&] { - // return _model; - //}); - - //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 (model->needsReload()) { - // return true; - // } - - // if (model->needsFixupInScene()) { - // return true; - // } - //} - return Parent::needsRenderUpdate(); -} - bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { if (entity->blendshapesChanged()) { return true; @@ -1214,24 +1195,6 @@ bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin return true; } - ModelPointer model = resultWithReadLock<ModelPointer>([&] { - return _model; - }); - - if (model && model->isLoaded()) { - // 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; - } - } - return Parent::needsRenderUpdateFromTypedEntity(entity); } @@ -1290,7 +1253,6 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint modelAddedToScene(entity->getEntityItemID(), NestableType::Entity, model); } _didLastVisualGeometryRequestSucceed = didVisualGeometryRequestSucceed; - entity->_dimensionsInitialized = false; entity->_originalTexturesRead = false; entity->_needsJointSimulation = true; emit requestRenderUpdate(); @@ -1440,11 +1402,13 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce ModelPointer model = resultWithReadLock<ModelPointer>([&] { return _model; }); - if (!_jointMappingCompleted) { - mapJoints(entity, model); - } - if (entity->readyToAnimate() && model && model->isLoaded()) { - animate(entity, model); + if (model && model->isLoaded()) { + if (!_jointMappingCompleted) { + mapJoints(entity, model); + } + if (entity->readyToAnimate()) { + animate(entity, model); + } } emit requestRenderUpdate(); } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 4cccc327bc..9606fa679d 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -159,7 +159,6 @@ protected: virtual void handleBlendedVertices(int blendshapeNumber, const QVector<BlendshapeOffset>& blendshapeOffsets, const QVector<int>& blendedMeshSizes, const render::ItemIDs& subItemIDs) override; - 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; diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 3a4e96d7bd..0e5f009065 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -325,6 +325,7 @@ void ModelEntityItem::setCompoundShapeURL(const QString& url) { withWriteLock([&] { if (_compoundShapeURL.get() != url) { _compoundShapeURL.set(url); + _needsRenderUpdate = true; _flags |= Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS; } }); From 9142b7123d8c46973d41fa88bf39d5ef478a8736 Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Tue, 13 Oct 2020 16:27:48 -0700 Subject: [PATCH 012/136] collisions and dimensions seem to be working --- .../src/RenderableModelEntityItem.cpp | 40 ++++++++++--------- .../src/RenderableModelEntityItem.h | 1 + libraries/render-utils/src/Model.h | 2 - 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 17c2caffdc..c8e8b999b8 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -183,12 +183,10 @@ void RenderableModelEntityItem::updateModelBounds() { bool overridingModelTransform = model->isOverridingModelTransformAndOffset(); glm::vec3 scaledDimensions = getScaledDimensions(); glm::vec3 registrationPoint = getRegistrationPoint(); - QString modelURL = getModelURL(); if (!overridingModelTransform && (model->getScaleToFitDimensions() != scaledDimensions || model->getRegistrationPoint() != registrationPoint || - model->getURL() != modelURL || - !model->getIsScaledToFit())) { + !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. @@ -201,6 +199,7 @@ void RenderableModelEntityItem::updateModelBounds() { model->setSnapModelToRegistrationPoint(true, registrationPoint); updateRenderItems = true; model->scaleToFit(); + _needsToRescaleModel = false; } bool success; @@ -718,7 +717,7 @@ void RenderableModelEntityItem::setJointMap(std::vector<int> jointMap) { int RenderableModelEntityItem::avatarJointIndex(int modelJointIndex) { int result = -1; int mapSize = (int) _jointMap.size(); - if (modelJointIndex >=0 && modelJointIndex < mapSize) { + if (modelJointIndex >= 0 && modelJointIndex < mapSize) { result = _jointMap[modelJointIndex]; } @@ -737,18 +736,20 @@ bool RenderableModelEntityItem::contains(const glm::vec3& point) const { } 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_SIMPLE_HULL && 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(); + } else if (shapeType == SHAPE_TYPE_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(_modelURL).isValid(); } int RenderableModelEntityItem::getJointParent(int index) const { @@ -1247,6 +1248,8 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint _model->setPrimitiveMode(_primitiveMode, scene); _model->setCullWithParent(_cullWithParent, scene); _model->setRenderWithZones(_renderWithZones, scene); + entity->locationChanged(); + entity->dimensionsChanged(); }); if (didVisualGeometryRequestSucceed) { emit DependencyManager::get<scriptable::ModelProviderFactory>()-> @@ -1255,6 +1258,7 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint _didLastVisualGeometryRequestSucceed = didVisualGeometryRequestSucceed; entity->_originalTexturesRead = false; entity->_needsJointSimulation = true; + entity->_needsToRescaleModel = true; emit requestRenderUpdate(); }); model->setLoadingPriority(EntityTreeRenderer::getEntityLoadingPriority(*entity)); @@ -1288,7 +1292,6 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint QMetaObject::invokeMethod(DependencyManager::get<EntityScriptingInterface>().data(), "editEntity", Qt::QueuedConnection, Q_ARG(QUuid, entity->getEntityItemID()), Q_ARG(EntityItemProperties, properties)); - entity->_dimensionsInitialized = true; } if (!entity->_originalTexturesRead) { @@ -1340,9 +1343,10 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint } } + bool needsUpdate = false; if (!_texturesLoaded && model->getGeometry() && model->getGeometry()->areTexturesLoaded()) { _texturesLoaded = true; - model->updateRenderItems(); + needsUpdate = true; } else if (!_texturesLoaded) { emit requestRenderUpdate(); } @@ -1368,13 +1372,13 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint 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(); } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 9606fa679d..cef62511bb 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -128,6 +128,7 @@ private: bool _originalTexturesRead { false }; bool _dimensionsInitialized { true }; bool _needsJointSimulation { false }; + bool _needsToRescaleModel { false }; }; namespace render { namespace entities { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 7372baa2dd..74cbfd6e7e 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -186,7 +186,6 @@ public: bool isActive() const { return isLoaded(); } bool didVisualGeometryRequestFail() const { return _visualGeometryRequestFailed; } - bool didCollisionGeometryRequestFail() const { return _collisionGeometryRequestFailed; } glm::mat4 getWorldToHFMMatrix() const; @@ -477,7 +476,6 @@ protected: uint32_t _deleteGeometryCounter { 0 }; bool _visualGeometryRequestFailed { false }; - bool _collisionGeometryRequestFailed { false }; bool _renderItemsNeedUpdate { false }; From 44b34e03416638548f05c7c821582ec22d39e879 Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Wed, 14 Oct 2020 13:21:07 -0700 Subject: [PATCH 013/136] what about...this --- .../src/RenderableModelEntityItem.cpp | 24 +++++++++---------- .../src/RenderableModelEntityItem.h | 1 - libraries/entities/src/EntityItem.cpp | 6 ++--- libraries/entities/src/ModelEntityItem.cpp | 1 - 4 files changed, 13 insertions(+), 19 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index c8e8b999b8..ab057f9d12 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<bool>([&] { - return _model && _model->isLoaded(); - }); -} - EntityItemPointer RenderableModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { EntityItemPointer entity(new RenderableModelEntityItem(entityID, properties.getDimensionsInitialized()), [](EntityItem* ptr) { ptr->deleteLater(); }); @@ -261,7 +255,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 +267,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; } @@ -309,7 +303,8 @@ void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) { auto currentCompoundShapeURL = getCompoundShapeURL(); ModelEntityItem::setCompoundShapeURL(url); if (getCompoundShapeURL() != currentCompoundShapeURL || !getModel()) { - if (getShapeType() == SHAPE_TYPE_COMPOUND) { + auto shapeType = getShapeType(); + if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { fetchCollisionGeometryResource(); } } @@ -350,7 +345,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() const { // the model is still being downloaded. return false; } else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) { - return isModelLoaded(); + return model && model->isLoaded(); } return true; } @@ -1110,7 +1105,7 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity, const ModelP QVector<EntityJointData> jointsData; - const QVector<HFMAnimationFrame>& frames = _animation->getFramesReference(); // NOTE: getFrames() is too heavy + const QVector<HFMAnimationFrame>& frames = _animation->getFramesReference(); // NOTE: getFrames() is too heavy int frameCount = frames.size(); if (frameCount <= 0) { return; @@ -1203,8 +1198,9 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__); _hasModel = entity->hasModel(); - if (_parsedModelURL != entity->getModelURL()) { - _parsedModelURL = QUrl(entity->getModelURL()); + QUrl modelURL = QUrl(entity->getModelURL()); + if (_parsedModelURL != modelURL) { + _parsedModelURL = modelURL; } ModelPointer model = resultWithReadLock<ModelPointer>([&] { @@ -1248,6 +1244,7 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint _model->setPrimitiveMode(_primitiveMode, scene); _model->setCullWithParent(_cullWithParent, scene); _model->setRenderWithZones(_renderWithZones, scene); + entity->markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); entity->locationChanged(); entity->dimensionsChanged(); }); @@ -1259,6 +1256,7 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint entity->_originalTexturesRead = false; entity->_needsJointSimulation = true; entity->_needsToRescaleModel = true; + entity->updateModelBounds(); emit requestRenderUpdate(); }); model->setLoadingPriority(EntityTreeRenderer::getEntityLoadingPriority(*entity)); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index cef62511bb..8d91d6c84b 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: 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/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 0e5f009065..5dea18069f 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -290,7 +290,6 @@ void ModelEntityItem::setModelURL(const QString& url) { withWriteLock([&] { if (_modelURL != url) { _modelURL = url; - _flags |= Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS; _needsRenderUpdate = true; } }); From c664991f6fff8bec130b7d7722524977ec719246 Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Tue, 20 Oct 2020 15:06:21 -0700 Subject: [PATCH 014/136] models seem to be working! --- .../src/RenderableModelEntityItem.cpp | 16 ++++++++++--- libraries/render-utils/src/Model.cpp | 24 ++++++++++++++++++- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index ab057f9d12..b6def4d35d 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -331,7 +331,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() const { const_cast<RenderableModelEntityItem*>(this)->fetchCollisionGeometryResource(); } - if (_collisionGeometryResource && _collisionGeometryResource->isLoaded()) { + if (_collisionGeometryResource && _collisionGeometryResource->isLoaded() && _collisionGeometryResource->isHFMModelLoaded()) { // 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 @@ -362,7 +362,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { } if (type == SHAPE_TYPE_COMPOUND) { - if (!_collisionGeometryResource || !_collisionGeometryResource->isLoaded()) { + if (!_collisionGeometryResource || !_collisionGeometryResource->isLoaded() || !_collisionGeometryResource->isHFMModelLoaded()) { return; } @@ -493,6 +493,9 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { std::vector<std::shared_ptr<const graphics::Mesh>> meshes; if (type == SHAPE_TYPE_SIMPLE_COMPOUND) { + if (!_collisionGeometryResource || !_collisionGeometryResource->isLoaded() || !_collisionGeometryResource->isHFMModelLoaded()) { + return; + } auto& hfmMeshes = _collisionGeometryResource->getHFMModel().meshes; meshes.reserve(hfmMeshes.size()); for (auto& hfmMesh : hfmMeshes) { @@ -721,7 +724,7 @@ int RenderableModelEntityItem::avatarJointIndex(int modelJointIndex) { bool RenderableModelEntityItem::contains(const glm::vec3& point) const { auto model = getModel(); - if (EntityItem::contains(point) && model && _collisionGeometryResource && _collisionGeometryResource->isLoaded()) { + if (model && _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); @@ -738,6 +741,9 @@ bool RenderableModelEntityItem::shouldBePhysical() const { // 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_SIMPLE_COMPOUND) { + physicalModelLoaded &= _collisionGeometryResource && !_collisionGeometryResource->isFailed(); + } } else if (shapeType == SHAPE_TYPE_COMPOUND) { physicalModelLoaded = _collisionGeometryResource && !_collisionGeometryResource->isFailed(); } else if (shapeType != SHAPE_TYPE_NONE) { @@ -1054,6 +1060,10 @@ ModelEntityRenderer::ModelEntityRenderer(const EntityItemPointer& entity) : Pare void ModelEntityRenderer::setKey(bool didVisualGeometryRequestSucceed, const ModelPointer& model) { auto builder = ItemKey::Builder().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); + if (!_visible) { + builder.withInvisible(); + } + if (!_cullWithParent && model && model->isGroupCulled()) { builder.withMetaCullGroup(); } else if (_cullWithParent) { diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index e46bdc03b3..86d6f9ed86 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -961,7 +961,29 @@ void Model::setCauterized(bool cauterized, const render::ScenePointer& scene) { void Model::setPrimitiveMode(PrimitiveMode primitiveMode, const render::ScenePointer& scene) { if (_primitiveMode != primitiveMode) { _primitiveMode = primitiveMode; - updateRenderItemsKey(scene); + if (!scene) { + _needsFixupInScene = true; + return; + } + + bool useDualQuaternionSkinning = _useDualQuaternionSkinning; + std::unordered_map<int, bool> 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<ModelMeshPartPayload>(itemID, [invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning] (ModelMeshPartPayload& data) { + data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning); + }); + } + scene->enqueueTransaction(transaction); } } From 2dd612b926087cf4c9748966f57483908d19404a Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Tue, 20 Oct 2020 17:12:23 -0700 Subject: [PATCH 015/136] more improvements --- .../src/RenderableMaterialEntityItem.cpp | 15 +- .../src/RenderableMaterialEntityItem.h | 1 - .../RenderableParticleEffectEntityItem.cpp | 187 +++++++----------- .../src/RenderableParticleEffectEntityItem.h | 1 - .../src/RenderablePolyLineEntityItem.cpp | 69 +++---- .../src/RenderablePolyLineEntityItem.h | 2 +- .../src/RenderablePolyVoxEntityItem.cpp | 47 +++-- .../src/RenderableShapeEntityItem.cpp | 97 +++++---- .../src/RenderableShapeEntityItem.h | 1 - .../src/RenderableTextEntityItem.cpp | 83 +++----- .../src/RenderableTextEntityItem.h | 1 - .../src/RenderableWebEntityItem.cpp | 26 ++- .../src/RenderableWebEntityItem.h | 1 - .../src/RenderableZoneEntityItem.cpp | 57 +----- .../src/RenderableZoneEntityItem.h | 8 +- libraries/entities/src/ModelEntityItem.cpp | 1 - libraries/entities/src/PolyLineEntityItem.cpp | 6 +- libraries/entities/src/ShapeEntityItem.cpp | 7 + libraries/entities/src/ShapeEntityItem.h | 2 + libraries/entities/src/ZoneEntityItem.cpp | 7 + libraries/entities/src/ZoneEntityItem.h | 2 + 21 files changed, 243 insertions(+), 378 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index 8d9ce24992..6b9ae6b4cf 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -16,15 +16,6 @@ using namespace render; using namespace render::entities; -bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { - if (resultWithReadLock<bool>([&] { - return entity->getParentID() != _parentID; - })) { - 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] { @@ -255,11 +246,7 @@ 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; } diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h index 7d455c98de..340d169f29 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h @@ -27,7 +27,6 @@ public: ~MaterialEntityRenderer() { deleteMaterial(_parentID, _parentMaterialName); } 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/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<bool>([&] { - 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<bool>([&] { 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<bool>([&] { return _particleProperties.textures.isEmpty(); }); - if (textureEmpty) { - if (_networkTexture) { - withWriteLock([&] { - _networkTexture.reset(); - }); - } - - withWriteLock([&] { - _textureLoaded = true; - entity->setVisuallyReady(true); - }); - } else { - bool textureNeedsUpdate = resultWithReadLock<bool>([&] { - return !_networkTexture || _networkTexture->getURL() != QUrl(_particleProperties.textures); - }); - if (textureNeedsUpdate) { - withWriteLock([&] { - _networkTexture = DependencyManager::get<TextureCache>()->getTexture(_particleProperties.textures); - _textureLoaded = false; - entity->setVisuallyReady(false); - }); - } - - if (!_textureLoaded) { - emit requestRenderUpdate(); - } - - bool textureLoaded = resultWithReadLock<bool>([&] { - 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<TextureCache>()->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>() = particleUniforms; } @@ -403,27 +372,18 @@ void ParticleEffectEntityRenderer::stepSimulation() { const auto interval = std::min<uint64_t>(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<ParticleUniforms>().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<ParticleUniforms>().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<bool>([&] { - 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<TextureCache>()->getTexture(entityTextures); - }); + _texture = DependencyManager::get<TextureCache>()->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<TextureCache>()->getWhiteTexture(); withReadLock([&] { - numVertices = _numVertices; transform = _renderTransform; - texture = _textureLoaded ? _texture->getGPUTexture() : DependencyManager::get<TextureCache>()->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<bool>([&] { + 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<QString, 3> 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<graphics::ProceduralMaterial>(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<graphics::ProceduralMaterial>(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>(); - 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<graphics::MultiMaterial::Schema>(); 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<graphics::ProceduralMaterial>(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<GeometryCache>(); @@ -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<bool>([this] { - return !_webSurface; - })) { - return true; - } - - return Parent::needsRenderUpdate(); -} - void WebEntityRenderer::onTimeout() { uint64_t lastRenderTime; if (!resultWithReadLock<bool>([&] { @@ -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<OffscreenQmlSurface> 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..17cb3e87f1 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(); @@ -267,10 +267,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 +276,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 +297,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 +317,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 +346,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 +356,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 +457,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/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 5dea18069f..65f21fd8c9 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -324,7 +324,6 @@ void ModelEntityItem::setCompoundShapeURL(const QString& url) { withWriteLock([&] { if (_compoundShapeURL.get() != url) { _compoundShapeURL.set(url); - _needsRenderUpdate = true; _flags |= Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS; } }); 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<PulsePropertyGroup>([&] { 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..25d3ea6f93 100644 --- a/libraries/entities/src/ZoneEntityItem.cpp +++ b/libraries/entities/src/ZoneEntityItem.cpp @@ -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; } From 081e2b13af277c4c604327e2bbd41da5e6d237c7 Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Tue, 20 Oct 2020 17:49:06 -0700 Subject: [PATCH 016/136] small fixes --- libraries/entities/src/ZoneEntityItem.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libraries/entities/src/ZoneEntityItem.cpp b/libraries/entities/src/ZoneEntityItem.cpp index 25d3ea6f93..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; } From 115229da923438f0146e1096d76e05ce3022de06 Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Tue, 20 Oct 2020 19:31:03 -0700 Subject: [PATCH 017/136] build error --- libraries/entities-renderer/src/RenderableGridEntityItem.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderableGridEntityItem.h b/libraries/entities-renderer/src/RenderableGridEntityItem.h index 3cd8bab822..1958d17136 100644 --- a/libraries/entities-renderer/src/RenderableGridEntityItem.h +++ b/libraries/entities-renderer/src/RenderableGridEntityItem.h @@ -33,7 +33,7 @@ private: virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; virtual void doRender(RenderArgs* args) override; - glm::u8vec3 _color { NAN }; + glm::u8vec3 _color; float _alpha { NAN }; PulsePropertyGroup _pulseProperties; From f413ad331254896f76317721f22a74662cf66bee Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Wed, 21 Oct 2020 16:04:23 -0700 Subject: [PATCH 018/136] small fixes --- .../src/RenderableModelEntityItem.cpp | 15 ++++++++++++++- .../src/RenderableModelEntityItem.h | 1 + .../src/RenderableZoneEntityItem.cpp | 6 +++++- libraries/entities/src/ModelEntityItem.cpp | 1 - 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index b6def4d35d..8640e9e8bf 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -302,10 +302,23 @@ void RenderableModelEntityItem::setShapeType(ShapeType type) { void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) { auto currentCompoundShapeURL = getCompoundShapeURL(); ModelEntityItem::setCompoundShapeURL(url); - if (getCompoundShapeURL() != currentCompoundShapeURL || !getModel()) { + if (getCompoundShapeURL() != currentCompoundShapeURL) { auto shapeType = getShapeType(); if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { fetchCollisionGeometryResource(); + markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); + } + } +} + +void RenderableModelEntityItem::setModelURL(const QString& url) { + auto currentModelURL = getModelURL(); + ModelEntityItem::setModelURL(url); + if (getModelURL() != currentModelURL) { + auto shapeType = getShapeType(); + if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { + fetchCollisionGeometryResource(); + markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); } } } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 8d91d6c84b..b57ebd8056 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -76,6 +76,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; diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 17cb3e87f1..ce2dae8d28 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -199,7 +199,11 @@ void ZoneEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointe auto visible = entity->getVisible(); if (transformChanged || visible != _lastVisible) { _lastVisible = visible; - DependencyManager::get<EntityTreeRenderer>()->updateZone(entity->getID()); + void* key = (void*)this; + EntityItemID id = entity->getID(); + AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [id] { + DependencyManager::get<EntityTreeRenderer>()->updateZone(id); + }); } auto proceduralUserData = entity->getUserData(); diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 65f21fd8c9..e841bf16dd 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -324,7 +324,6 @@ void ModelEntityItem::setCompoundShapeURL(const QString& url) { withWriteLock([&] { if (_compoundShapeURL.get() != url) { _compoundShapeURL.set(url); - _flags |= Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS; } }); } From 436bed3a692dd371329dbbc9f6b7ffd3da293ce5 Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Sat, 24 Oct 2020 16:00:39 +1300 Subject: [PATCH 019/136] Increase HUD overlay radius --- interface/src/ui/OverlayConductor.cpp | 2 ++ .../src/display-plugins/CompositorHelper.cpp | 7 +++---- .../display-plugins/src/display-plugins/CompositorHelper.h | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/OverlayConductor.cpp b/interface/src/ui/OverlayConductor.cpp index 8edd8ee3a5..a359b8d4c9 100644 --- a/interface/src/ui/OverlayConductor.cpp +++ b/interface/src/ui/OverlayConductor.cpp @@ -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)); } diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp index 9b6946bbcc..dc841d6308 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp @@ -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..3149d7fa3f 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.h +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.h @@ -28,6 +28,7 @@ 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 MAGNIFY_WIDTH = 220.0f; const float MAGNIFY_HEIGHT = 100.0f; From 4d70651c699930454d2a55d0b748f410bb3a7eac Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Sat, 24 Oct 2020 16:00:55 +1300 Subject: [PATCH 020/136] Make default reticle depth be HUD overlay radius --- .../display-plugins/src/display-plugins/CompositorHelper.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.h b/libraries/display-plugins/src/display-plugins/CompositorHelper.h index 3149d7fa3f..b44d6ffbd9 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.h +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.h @@ -27,8 +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; @@ -155,7 +155,7 @@ private: std::unique_ptr<QPropertyAnimation> _alphaPropertyAnimation; std::atomic<bool> _reticleVisible { true }; - std::atomic<float> _reticleDepth { 1.0f }; + std::atomic<float> _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 From 01cd4aa22dd8e8e24ed8bfa63b3745e5aa8045ef Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Sat, 24 Oct 2020 16:05:17 +1300 Subject: [PATCH 021/136] Reduce horizontal size of HUD overlay from 270 deg to 180 deg --- .../src/display-plugins/CompositorHelper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp index dc841d6308..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); From d2b15d7cbab0f23c2191338220311b30d7884a4c Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Sat, 24 Oct 2020 16:27:03 +1300 Subject: [PATCH 022/136] Reduce "center UI" trigger distance from 0.99m to 0.33m --- interface/src/ui/OverlayConductor.cpp | 6 +++--- interface/src/ui/OverlayConductor.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/OverlayConductor.cpp b/interface/src/ui/OverlayConductor.cpp index a359b8d4c9..2f0c3c3252 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,7 +32,7 @@ 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_DISTANCE = 0.33f; const float MAX_COMPOSITOR_ANGLE = 180.0f; // rotation check is effectively disabled if (glm::distance(uiPos, hmdPos) > MAX_COMPOSITOR_DISTANCE || glm::dot(uiForward, hmdForward) < cosf(glm::radians(MAX_COMPOSITOR_ANGLE))) { @@ -106,7 +106,7 @@ void OverlayConductor::update(float dt) { shouldRecenter = true; } } else { - if (_hmdMode && headOutsideOverlay()) { + if (_hmdMode && headNotCenteredInOverlay()) { _suppressedByHead = true; } } 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) From 9f95b101fe9266548c5737b12765af3c7532e3dc Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Sat, 24 Oct 2020 16:37:38 +1300 Subject: [PATCH 023/136] Enable "center UI" to be triggered on rotation --- interface/src/ui/OverlayConductor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/OverlayConductor.cpp b/interface/src/ui/OverlayConductor.cpp index 2f0c3c3252..f1aa75eaf9 100644 --- a/interface/src/ui/OverlayConductor.cpp +++ b/interface/src/ui/OverlayConductor.cpp @@ -33,7 +33,7 @@ bool OverlayConductor::headNotCenteredInOverlay() const { glm::vec3 uiForward = uiTransform.getRotation() * glm::vec3(0.0f, 0.0f, -1.0f); const float MAX_COMPOSITOR_DISTANCE = 0.33f; - const float MAX_COMPOSITOR_ANGLE = 180.0f; // rotation check is effectively disabled + 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; From cbef9d2926f5df51bbbc741aa6f0744414d10097 Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Sat, 24 Oct 2020 21:28:49 +1300 Subject: [PATCH 024/136] Fix HUD content displaying only every second HUD recentering --- interface/src/ui/OverlayConductor.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/interface/src/ui/OverlayConductor.cpp b/interface/src/ui/OverlayConductor.cpp index f1aa75eaf9..557b4d09bf 100644 --- a/interface/src/ui/OverlayConductor.cpp +++ b/interface/src/ui/OverlayConductor.cpp @@ -85,7 +85,6 @@ void OverlayConductor::update(float dt) { if (!desktop) { return; } - bool currentVisible = !desktop->property("pinned").toBool(); auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar(); // centerUI when hmd mode is first enabled and mounted @@ -98,24 +97,24 @@ void OverlayConductor::update(float dt) { _hmdMode = false; } - bool shouldRecenter = false; - - if (_suppressedByHead) { - if (updateAvatarIsAtRest()) { - _suppressedByHead = false; - shouldRecenter = true; - } - } else { - if (_hmdMode && headNotCenteredInOverlay()) { - _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 From fa3a886ce22e1259f56fc86a149c9dc65f7100ed Mon Sep 17 00:00:00 2001 From: humbletim <humbletim@gmail.com> Date: Wed, 28 Oct 2020 20:48:59 -0400 Subject: [PATCH 025/136] rename plugin folder --- .../CMakeLists.txt | 0 .../src/JSAPIExample.cpp} | 0 .../src/plugin.json | 0 .../KasenAPIExample/src/ExampleScriptPlugin.h | 58 ------------------- 4 files changed, 58 deletions(-) rename plugins/{KasenAPIExample => JSAPIExample}/CMakeLists.txt (100%) rename plugins/{KasenAPIExample/src/KasenAPIExample.cpp => JSAPIExample/src/JSAPIExample.cpp} (100%) rename plugins/{KasenAPIExample => JSAPIExample}/src/plugin.json (100%) delete mode 100644 plugins/KasenAPIExample/src/ExampleScriptPlugin.h diff --git a/plugins/KasenAPIExample/CMakeLists.txt b/plugins/JSAPIExample/CMakeLists.txt similarity index 100% rename from plugins/KasenAPIExample/CMakeLists.txt rename to plugins/JSAPIExample/CMakeLists.txt diff --git a/plugins/KasenAPIExample/src/KasenAPIExample.cpp b/plugins/JSAPIExample/src/JSAPIExample.cpp similarity index 100% rename from plugins/KasenAPIExample/src/KasenAPIExample.cpp rename to plugins/JSAPIExample/src/JSAPIExample.cpp diff --git a/plugins/KasenAPIExample/src/plugin.json b/plugins/JSAPIExample/src/plugin.json similarity index 100% rename from plugins/KasenAPIExample/src/plugin.json rename to plugins/JSAPIExample/src/plugin.json diff --git a/plugins/KasenAPIExample/src/ExampleScriptPlugin.h b/plugins/KasenAPIExample/src/ExampleScriptPlugin.h deleted file mode 100644 index 76c0a494d7..0000000000 --- a/plugins/KasenAPIExample/src/ExampleScriptPlugin.h +++ /dev/null @@ -1,58 +0,0 @@ -// -// ExampleScriptPlugin.h -// plugins/KasenAPIExample/src -// -// Created by Kasen IO on 2019.07.14 | realities.dev | kasenvr@gmail.com -// Copyright 2019 Kasen IO -// -// Authored by: Humbletim (humbletim@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 -// -// Supporting file containing all QtScript specific integration. - -#ifndef EXAMPLE_SCRIPT_PLUGIN_H -#define EXAMPLE_SCRIPT_PLUGIN_H - -#if DEV_BUILD -#pragma message("QtScript is deprecated see: doc.qt.io/qt-5/topics-scripting.html") -#endif -#include <QtScript/QScriptEngine> - -#include <QtCore/QLoggingCategory> -#include <QCoreApplication> -#include <shared/ScriptInitializerMixin.h> - -namespace example { - -extern const QLoggingCategory& logger; - -inline void setGlobalInstance(QScriptEngine* engine, const QString& name, QObject* object) { - auto value = engine->newQObject(object, QScriptEngine::QtOwnership); - engine->globalObject().setProperty(name, value); - qCDebug(logger) << "setGlobalInstance" << name << engine->property("fileName"); -} - -class ScriptPlugin : public QObject { - Q_OBJECT - QString _version; - Q_PROPERTY(QString version MEMBER _version CONSTANT) -protected: - inline ScriptPlugin(const QString& name, const QString& version) : _version(version) { - setObjectName(name); - if (!DependencyManager::get<ScriptInitializers>()) { - qCWarning(logger) << "COULD NOT INITIALIZE (ScriptInitializers unavailable)" << qApp << this; - return; - } - qCWarning(logger) << "registering w/ScriptInitializerMixin..." << DependencyManager::get<ScriptInitializers>().data(); - DependencyManager::get<ScriptInitializers>()->registerScriptInitializer( - [this](QScriptEngine* engine) { setGlobalInstance(engine, objectName(), this); }); - } -public slots: - inline QString toString() const { return QString("[%1 version=%2]").arg(objectName()).arg(_version); } -}; - -} // namespace example - -#endif \ No newline at end of file From f54b1c5fed48aa87a1ed16bd3d13affb5eb2837d Mon Sep 17 00:00:00 2001 From: humbletim <humbletim@gmail.com> Date: Wed, 28 Oct 2020 21:26:01 -0400 Subject: [PATCH 026/136] revamped modkit plugin example --- .../qml/hifi/dialogs/security/Security.qml | 4 +- plugins/CMakeLists.txt | 2 +- plugins/JSAPIExample/CMakeLists.txt | 4 +- plugins/JSAPIExample/src/JSAPIExample.cpp | 261 ++++++++++++------ plugins/JSAPIExample/src/plugin.json | 21 +- 5 files changed, 176 insertions(+), 116 deletions(-) diff --git a/interface/resources/qml/hifi/dialogs/security/Security.qml b/interface/resources/qml/hifi/dialogs/security/Security.qml index b1f62633e7..cfa420955b 100644 --- a/interface/resources/qml/hifi/dialogs/security/Security.qml +++ b/interface/resources/qml/hifi/dialogs/security/Security.qml @@ -312,9 +312,9 @@ Rectangle { parent.color = hifi.colors.blueHighlight; } onClicked: { - lightboxPopup.titleText = "Script Plugin Infrastructure by Kasen"; + lightboxPopup.titleText = "Script Plugin Infrastructure"; lightboxPopup.bodyText = "Toggles the activation of scripting plugins in the 'plugins/scripting' folder. \n\n" - + "Created by https://kasen.io/"; + + "Created by:\n humbletim@gmail.com\n kasenvr@gmail.com"; lightboxPopup.button1text = "OK"; lightboxPopup.button1method = function() { lightboxPopup.visible = false; diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 1448e14c72..a72371f544 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -53,5 +53,5 @@ set(DIR "opusCodec") add_subdirectory(${DIR}) # example plugins -set(DIR "KasenAPIExample") +set(DIR "JSAPIExample") add_subdirectory(${DIR}) diff --git a/plugins/JSAPIExample/CMakeLists.txt b/plugins/JSAPIExample/CMakeLists.txt index 96ac84e10d..a8fa0a1fd6 100644 --- a/plugins/JSAPIExample/CMakeLists.txt +++ b/plugins/JSAPIExample/CMakeLists.txt @@ -1,3 +1,3 @@ -set(TARGET_NAME KasenAPIExample) +set(TARGET_NAME JSAPIExample) setup_hifi_client_server_plugin(scripting) -link_hifi_libraries(shared plugins avatars networking graphics gpu) +link_hifi_libraries(shared plugins) diff --git a/plugins/JSAPIExample/src/JSAPIExample.cpp b/plugins/JSAPIExample/src/JSAPIExample.cpp index 720c47f6cd..1ac8d56fc5 100644 --- a/plugins/JSAPIExample/src/JSAPIExample.cpp +++ b/plugins/JSAPIExample/src/JSAPIExample.cpp @@ -1,141 +1,218 @@ // -// KasenAPIExample.cpp -// plugins/KasenAPIExample/src +// JSAPIExample.cpp +// plugins/JSAPIExample/src // -// Created by Kasen IO on 2019.07.14 | realities.dev | kasenvr@gmail.com -// Copyright 2019 Kasen IO -// -// Authored by: Humbletim (humbletim@gmail.com) +// Copyright (c) 2019-2020 humbletim (humbletim@gmail.com) +// Copyright (c) 2019 Kalila L. (kasenvr@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 -// + // Example of prototyping new JS APIs by leveraging the existing plugin system. -#include "ExampleScriptPlugin.h" - #include <QCoreApplication> +#include <QtCore/QByteArray> +#include <QtCore/QDir> +#include <QtCore/QFileInfo> #include <QtCore/QJsonObject> #include <QtCore/QLoggingCategory> #include <QtCore/QThread> #include <QtCore/QTimer> +#include <QtScript/QScriptEngine> +#include <QtScript/QScriptable> -#include <SharedUtil.h> -#include <AvatarHashMap.h> +#include <SettingHelpers.h> // for ::settingsFilename() +#include <SharedUtil.h> // for usecTimestampNow() +#include <shared/ScriptInitializerMixin.h> -namespace custom_api_example { +// NOTE: replace this with your own namespace when starting a new plugin (to avoid .so/.dll symbol clashes) +namespace REPLACE_ME_WITH_UNIQUE_NAME { -QLoggingCategory logger{ "custom_api_example" }; +static constexpr auto JSAPI_SEMANTIC_VERSION = "0.0.1"; +static constexpr auto JSAPI_EXPORT_NAME = "JSAPIExample"; -class KasenAPIExample : public example::ScriptPlugin { +QLoggingCategory logger{ "jsapiexample" }; + +inline QVariant raiseScriptingError(QScriptContext* context, const QString& message, const QVariant& returnValue = QVariant()) { + if (context) { + // when a QScriptContext is available throw an actual JS Exception (which can be caught using try/catch on JS side) + context->throwError(message); + } else { + // otherwise just log the error + qCWarning(logger) << "error:" << message; + } + return returnValue; +} + +QObject* createScopedSettings(const QString& scope, QObject* parent, QString& error); + +class JSAPIExample : public QObject, public QScriptable { Q_OBJECT - Q_PLUGIN_METADATA(IID "KasenAPIExample" FILE "plugin.json") + Q_PLUGIN_METADATA(IID "JSAPIExample" FILE "plugin.json") + Q_PROPERTY(QString version MEMBER _version CONSTANT) public: - KasenAPIExample() : example::ScriptPlugin("KasenAPIExample", "0.0.1") { - qCInfo(logger) << "plugin loaded" << qApp << toString() << QThread::currentThread(); + JSAPIExample() { + setObjectName(JSAPI_EXPORT_NAME); + auto scriptInit = DependencyManager::get<ScriptInitializers>(); + if (!scriptInit) { + qCWarning(logger) << "COULD NOT INITIALIZE (ScriptInitializers unavailable)" << qApp << this; + return; + } + qCWarning(logger) << "registering w/ScriptInitializerMixin..." << scriptInit.data(); + scriptInit->registerScriptInitializer([this](QScriptEngine* engine) { + auto value = engine->newQObject(this, QScriptEngine::QtOwnership, QScriptEngine::ExcludeDeleteLater); + engine->globalObject().setProperty(objectName(), value); + // qCDebug(logger) << "setGlobalInstance" << objectName() << engine->property("fileName"); + }); + // qCInfo(logger) << "plugin loaded" << qApp << toString() << QThread::currentThread(); } + // NOTES: everything within the "public slots:" section below will be available from JS via overall plugin QObject + // also, to demonstrate future-proofing JS API code, QVariant's are used throughout most of these examples -- + // which still makes them very Qt-specific, but avoids depending directly on deprecated QtScript/QScriptValue APIs. + // (as such this plugin class and its methods remain forward-compatible with other engines like QML's QJSEngine) + public slots: + // returns a pretty-printed representation for logging eg: print(JSAPIExample) + inline QString toString() const { return QString("[%1 version=%2]").arg(objectName()).arg(_version); } + /**jsdoc * Returns current microseconds (usecs) since Epoch. note: 1000usecs == 1ms * @example <caption>Measure current setTimeout accuracy.</caption> * var expected = 1000; - * var start = KasenAPIExample.now(); + * var start = JSAPIExample.now(); * Script.setTimeout(function () { - * var elapsed = (KasenAPIExample.now() - start)/1000; + * var elapsed = (JSAPIExample.now() - start)/1000; * print("expected (ms):", expected, "actual (ms):", elapsed); * }, expected); */ - QVariant now() const { - return usecTimestampNow(); - } + QVariant now() const { return usecTimestampNow(); } /**jsdoc - * Returns the available blendshape names for an avatar. - * @example <caption>Get blendshape names</caption> - * print(JSON.stringify(KasenAPIExample.getBlendshapeNames(MyAvatar.sessionUUID))); + * Example of returning a JS Object key-value map + * @example <caption>"zip" a list of keys and corresponding values to form key-value map</caption> + * print(JSON.stringify(JSAPIExample.zip(["a","b"], [1,2])); // { "a": 1, "b": 2 } */ - QStringList getBlendshapeNames(const QUuid& avatarID) const { - QVector<QString> out; - if (auto head = getAvatarHead(avatarID)) { - for (const auto& kv : head->getBlendshapeMap().toStdMap()) { - if (kv.second >= out.size()) out.resize(kv.second+1); - out[kv.second] = kv.first; - } - } - return out.toList(); - } - - /**jsdoc - * Returns a key-value object with active (non-zero) blendshapes. - * eg: { JawOpen: 1.0, ... } - * @example <caption>Get active blendshape map</caption> - * print(JSON.stringify(KasenAPIExample.getActiveBlendshapes(MyAvatar.sessionUUID))); - */ - QVariant getActiveBlendshapes(const QUuid& avatarID) const { - if (auto head = getAvatarHead(avatarID)) { - return head->toJson()["blendShapes"].toVariant(); - } - return {}; - } - - QVariant getBlendshapeMapping(const QUuid& avatarID) const { + QVariant zip(const QStringList& keys, const QVariantList& values) const { QVariantMap out; - if (auto head = getAvatarHead(avatarID)) { - for (const auto& kv : head->getBlendshapeMap().toStdMap()) { - out[kv.first] = kv.second; - } + for (int i = 0; i < keys.size(); i++) { + out[keys[i]] = i < values.size() ? values[i] : QVariant(); + } + return out; + } + /**jsdoc + * Example of returning a JS Array result + * @example <caption>emulate Object.values(keyValues)</caption> + * print(JSON.stringify(JSAPIExample.values({ "a": 1, "b": 2 }))); // [1,2] + */ + QVariant values(const QVariantMap& keyValues) const { return keyValues.values(); } + + /**jsdoc + * Another example of returning JS Array data + * @example <caption>generate an integer sequence (inclusive of [from, to])</caption> + * print(JSON.stringify(JSAPIExample.seq(1,5)));// [1,2,3,4,5] + */ + QVariant seq(int from, int to) const { + QVariantList out; + for (int i = from; i <= to; i++) { + out.append(i); } return out; } - QVariant getBlendshapes(const QUuid& avatarID) const { - QVariantMap result; - if (auto head = getAvatarHead(avatarID)) { - QStringList names = getBlendshapeNames(avatarID); - auto states = head->getBlendshapeStates(); - result = { - { "base", zipNonZeroValues(names, states.base) }, - { "summed", zipNonZeroValues(names, states.summed) }, - { "transient", zipNonZeroValues(names, states.transient) }, - }; + /**jsdoc + * Example of returning arbitrary binary data from C++ (resulting in a JS ArrayBuffer) + * see also: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer#Examples + * @example <caption>return compressed/decompressed versions of the input data</caption> + * var data = "testing 1 2 3"; + * var z = JSAPIExample.qCompressString(data); // z will be an ArrayBuffer + * var u = JSAPIExample.qUncompressString(z); // u will be a String value + * print(JSON.stringify({ input: data, compressed: z.byteLength, output: u, uncompressed: u.length })); + */ + QVariant qCompressString(const QString& data, int compress_level = -1) const { + return qCompress(data.toUtf8(), compress_level); + } + QString qUncompressString(const QByteArray& data) const { return QString::fromUtf8(qUncompress(data)); } + + /** + * Example of exposing a custom "managed" C++ QObject to JS + * The lifecycle of the created QObject* instance becomes managed by the invoking QScriptEngine -- + * it will be automatically cleaned up once no longer reachable from any JS variables/closures. + * @example <caption>access persistent settings stored in separate .json files</caption> + * var settings = JSAPIExample.getScopedSettings("example"); + * print("example settings stored in:", settings.fileName()); + * print("(before) example::timestamp", settings.value("timestamp")); + * settings.setValue("timestamp", Date.now()); + * print("(after) example::timestamp", settings.value("timestamp")); + * print("all example::* keys", settings.allKeys()); + * settings = null; // optional best pratice; allows the object to be reclaimed ASAP by the JS garbage collector + */ + QScriptValue getScopedSettings(const QString& scope) { + auto engine = QScriptable::engine(); + if (!engine) return QScriptValue::NullValue; + QString error; + auto cppValue = createScopedSettings(scope, engine, error); + if (!cppValue) { + raiseScriptingError(context(), "error creating scoped settings instance: " + error); + return QScriptValue::NullValue; } - return result; + return engine->newQObject(cppValue, QScriptEngine::ScriptOwnership, QScriptEngine::ExcludeDeleteLater); } private: - static QVariantMap zipNonZeroValues(const QStringList& keys, const QVector<float>& values) { - QVariantMap out; - for (int i=1; i < values.size(); i++) { - if (fabs(values[i]) > 1.0e-6f) { - out[keys.value(i)] = values[i]; - } - } - return out; + const QString _version{ JSAPI_SEMANTIC_VERSION }; +}; + +// Example of how to create a QObject class that can have multiple instances created from the JS side +// JSSettingsHelper emulates a subset of QSetting APIs: +// fileName() -- full path to the scoped settings .json file +// allKeys() -- all previously stored keys available in the scoped settings file +// value(key, defaultValue) -- retrieve a stored value +// setValue(key, newValue) -- set/update a stored value +class JSSettingsHelper : public QObject { + Q_OBJECT + QString _scope; + QString _fileName; + QSharedPointer<QSettings> _settings; + +public: + operator bool() const { return (bool)_settings; } + JSSettingsHelper(const QString& scope, QObject* parent = nullptr) : + QObject(parent), _scope(scope), _fileName(getLocalSettingsPath(scope)), + _settings(_fileName.isEmpty() ? nullptr : new QSettings(_fileName, JSON_FORMAT)) {} + ~JSSettingsHelper() { qCDebug(logger) << "~JSSettingsHelper" << _scope << _fileName << this; } +public slots: + QString fileName() const { return _settings ? _settings->fileName() : ""; } + QString toString() const { return QString("[JSSettingsHelper scope=%1 valid=%2]").arg(_scope).arg((bool)_settings); } + QVariant value(const QString& key, const QVariant& defaultValue = QVariant()) { + return _settings ? _settings->value(key, defaultValue) : defaultValue; } - struct _HeadHelper : public HeadData { - QMap<QString,int> getBlendshapeMap() const { - return BLENDSHAPE_LOOKUP_MAP; + bool setValue(const QString& key, const QVariant& value) { + if (_settings) { + _settings->setValue(key, value); + return true; } - struct States { QVector<float> base, summed, transient; }; - States getBlendshapeStates() const { - return { - _blendshapeCoefficients, - _summedBlendshapeCoefficients, - _transientBlendshapeCoefficients - }; - } - }; - static const _HeadHelper* getAvatarHead(const QUuid& avatarID) { - auto avatars = DependencyManager::get<AvatarHashMap>(); - auto avatar = avatars ? avatars->getAvatarBySessionID(avatarID) : nullptr; - auto head = avatar ? avatar->getHeadData() : nullptr; - return reinterpret_cast<const _HeadHelper*>(head); + return false; + } + QStringList allKeys() const { return _settings ? _settings->allKeys() : QStringList{}; } + +protected: + QString getLocalSettingsPath(const QString& scope) const { + // generate a prefixed filename (relative to the main application's Interface.json file) + const QString fileName = QString("jsapi_%1.json").arg(scope); + return QFileInfo(::settingsFilename()).dir().filePath(fileName); } }; +QObject* createScopedSettings(const QString& scope, QObject* parent, QString& error) { + const QRegExp VALID_SETTINGS_SCOPE{ "[-_A-Za-z0-9]{1,64}" }; + if (!VALID_SETTINGS_SCOPE.exactMatch(scope)) { + error = QString("invalid scope (expected alphanumeric <= 64 chars not '%1')").arg(scope); + return nullptr; + } + return new JSSettingsHelper(scope, parent); } -const QLoggingCategory& example::logger{ custom_api_example::logger }; +} // namespace REPLACE_ME_WITH_UNIQUE_NAME -#include "KasenAPIExample.moc" +#include "JSAPIExample.moc" diff --git a/plugins/JSAPIExample/src/plugin.json b/plugins/JSAPIExample/src/plugin.json index 3e6931deec..f28c7fb988 100644 --- a/plugins/JSAPIExample/src/plugin.json +++ b/plugins/JSAPIExample/src/plugin.json @@ -1,21 +1,4 @@ { - "name":"Kasen JS API Example", - "version": 1, - "package": { - "author": "Revofire", - "homepage": "www.realities.dev", - "version": "0.0.1", - "engines": { - "hifi-interface": ">= 0.83.0", - "hifi-assignment-client": ">= 0.83.0" - }, - "config": { - "client": true, - "entity_client": true, - "entity_server": true, - "edit_filter": true, - "agent": true, - "avatar": true - } - } + "name":"JS API Example", + "version": 1 } From 7fb0173ef7df5b6f00637104742052fc9a1e8f64 Mon Sep 17 00:00:00 2001 From: humbletim <humbletim@gmail.com> Date: Wed, 28 Oct 2020 21:58:32 -0400 Subject: [PATCH 027/136] clarifications per peer review --- plugins/JSAPIExample/src/JSAPIExample.cpp | 30 +++++++++++++++-------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/plugins/JSAPIExample/src/JSAPIExample.cpp b/plugins/JSAPIExample/src/JSAPIExample.cpp index 1ac8d56fc5..f3947b2f4f 100644 --- a/plugins/JSAPIExample/src/JSAPIExample.cpp +++ b/plugins/JSAPIExample/src/JSAPIExample.cpp @@ -73,8 +73,9 @@ public: // (as such this plugin class and its methods remain forward-compatible with other engines like QML's QJSEngine) public slots: - // returns a pretty-printed representation for logging eg: print(JSAPIExample) - inline QString toString() const { return QString("[%1 version=%2]").arg(objectName()).arg(_version); } + // pretty-printed representation for logging eg: print(JSAPIExample) + // (note: Qt script engines automatically look for a ".toString" method on native classes when coercing values to strings) + QString toString() const { return QString("[%1 version=%2]").arg(objectName()).arg(_version); } /**jsdoc * Returns current microseconds (usecs) since Epoch. note: 1000usecs == 1ms @@ -100,12 +101,16 @@ public slots: } return out; } + /**jsdoc * Example of returning a JS Array result * @example <caption>emulate Object.values(keyValues)</caption> * print(JSON.stringify(JSAPIExample.values({ "a": 1, "b": 2 }))); // [1,2] */ - QVariant values(const QVariantMap& keyValues) const { return keyValues.values(); } + QVariant values(const QVariantMap& keyValues) const { + QVariantList values = keyValues.values(); + return values; + } /**jsdoc * Another example of returning JS Array data @@ -129,10 +134,14 @@ public slots: * var u = JSAPIExample.qUncompressString(z); // u will be a String value * print(JSON.stringify({ input: data, compressed: z.byteLength, output: u, uncompressed: u.length })); */ - QVariant qCompressString(const QString& data, int compress_level = -1) const { - return qCompress(data.toUtf8(), compress_level); + QVariant qCompressString(const QString& jsString, int compress_level = -1) const { + QByteArray arrayBuffer = qCompress(jsString.toUtf8(), compress_level); + return arrayBuffer; + } + QVariant qUncompressString(const QByteArray& arrayBuffer) const { + QString jsString = QString::fromUtf8(qUncompress(arrayBuffer)); + return jsString; } - QString qUncompressString(const QByteArray& data) const { return QString::fromUtf8(qUncompress(data)); } /** * Example of exposing a custom "managed" C++ QObject to JS @@ -149,12 +158,13 @@ public slots: */ QScriptValue getScopedSettings(const QString& scope) { auto engine = QScriptable::engine(); - if (!engine) return QScriptValue::NullValue; + if (!engine) + return QScriptValue::NullValue; QString error; auto cppValue = createScopedSettings(scope, engine, error); if (!cppValue) { - raiseScriptingError(context(), "error creating scoped settings instance: " + error); - return QScriptValue::NullValue; + raiseScriptingError(context(), "error creating scoped settings instance: " + error); + return QScriptValue::NullValue; } return engine->newQObject(cppValue, QScriptEngine::ScriptOwnership, QScriptEngine::ExcludeDeleteLater); } @@ -163,7 +173,6 @@ private: const QString _version{ JSAPI_SEMANTIC_VERSION }; }; -// Example of how to create a QObject class that can have multiple instances created from the JS side // JSSettingsHelper emulates a subset of QSetting APIs: // fileName() -- full path to the scoped settings .json file // allKeys() -- all previously stored keys available in the scoped settings file @@ -204,6 +213,7 @@ protected: } }; +// verifies the requested scope is sensible and creates/returns a scoped JSSettingsHelper instance QObject* createScopedSettings(const QString& scope, QObject* parent, QString& error) { const QRegExp VALID_SETTINGS_SCOPE{ "[-_A-Za-z0-9]{1,64}" }; if (!VALID_SETTINGS_SCOPE.exactMatch(scope)) { From dedf6a6975957097bb56d344f8d5fa74f3662ee6 Mon Sep 17 00:00:00 2001 From: humbletim <humbletim@gmail.com> Date: Wed, 28 Oct 2020 22:24:29 -0400 Subject: [PATCH 028/136] further cleanup per peer review (thanks fluffy!) --- plugins/JSAPIExample/src/JSAPIExample.cpp | 94 ++++++++++++++--------- 1 file changed, 58 insertions(+), 36 deletions(-) diff --git a/plugins/JSAPIExample/src/JSAPIExample.cpp b/plugins/JSAPIExample/src/JSAPIExample.cpp index f3947b2f4f..d0e5a27869 100644 --- a/plugins/JSAPIExample/src/JSAPIExample.cpp +++ b/plugins/JSAPIExample/src/JSAPIExample.cpp @@ -22,7 +22,7 @@ #include <QtScript/QScriptable> #include <SettingHelpers.h> // for ::settingsFilename() -#include <SharedUtil.h> // for usecTimestampNow() +#include <SharedUtil.h> // for ::usecTimestampNow() #include <shared/ScriptInitializerMixin.h> // NOTE: replace this with your own namespace when starting a new plugin (to avoid .so/.dll symbol clashes) @@ -150,9 +150,9 @@ public slots: * @example <caption>access persistent settings stored in separate .json files</caption> * var settings = JSAPIExample.getScopedSettings("example"); * print("example settings stored in:", settings.fileName()); - * print("(before) example::timestamp", settings.value("timestamp")); + * print("(before) example::timestamp", settings.getValue("timestamp")); * settings.setValue("timestamp", Date.now()); - * print("(after) example::timestamp", settings.value("timestamp")); + * print("(after) example::timestamp", settings.getValue("timestamp")); * print("all example::* keys", settings.allKeys()); * settings = null; // optional best pratice; allows the object to be reclaimed ASAP by the JS garbage collector */ @@ -173,44 +173,24 @@ private: const QString _version{ JSAPI_SEMANTIC_VERSION }; }; -// JSSettingsHelper emulates a subset of QSetting APIs: -// fileName() -- full path to the scoped settings .json file -// allKeys() -- all previously stored keys available in the scoped settings file -// value(key, defaultValue) -- retrieve a stored value -// setValue(key, newValue) -- set/update a stored value +// JSSettingsHelper wraps a scoped (prefixed/separate) QSettings and exposes a subset of QSetting APIs as slots class JSSettingsHelper : public QObject { Q_OBJECT +public: + JSSettingsHelper(const QString& scope, QObject* parent = nullptr); + ~JSSettingsHelper(); + operator bool() const; +public slots: + QString fileName() const; + QString toString() const; + QVariant getValue(const QString& key, const QVariant& defaultValue = QVariant()); + bool setValue(const QString& key, const QVariant& value); + QStringList allKeys() const; +protected: QString _scope; QString _fileName; QSharedPointer<QSettings> _settings; - -public: - operator bool() const { return (bool)_settings; } - JSSettingsHelper(const QString& scope, QObject* parent = nullptr) : - QObject(parent), _scope(scope), _fileName(getLocalSettingsPath(scope)), - _settings(_fileName.isEmpty() ? nullptr : new QSettings(_fileName, JSON_FORMAT)) {} - ~JSSettingsHelper() { qCDebug(logger) << "~JSSettingsHelper" << _scope << _fileName << this; } -public slots: - QString fileName() const { return _settings ? _settings->fileName() : ""; } - QString toString() const { return QString("[JSSettingsHelper scope=%1 valid=%2]").arg(_scope).arg((bool)_settings); } - QVariant value(const QString& key, const QVariant& defaultValue = QVariant()) { - return _settings ? _settings->value(key, defaultValue) : defaultValue; - } - bool setValue(const QString& key, const QVariant& value) { - if (_settings) { - _settings->setValue(key, value); - return true; - } - return false; - } - QStringList allKeys() const { return _settings ? _settings->allKeys() : QStringList{}; } - -protected: - QString getLocalSettingsPath(const QString& scope) const { - // generate a prefixed filename (relative to the main application's Interface.json file) - const QString fileName = QString("jsapi_%1.json").arg(scope); - return QFileInfo(::settingsFilename()).dir().filePath(fileName); - } + QString getLocalSettingsPath(const QString& scope) const; }; // verifies the requested scope is sensible and creates/returns a scoped JSSettingsHelper instance @@ -223,6 +203,48 @@ QObject* createScopedSettings(const QString& scope, QObject* parent, QString& er return new JSSettingsHelper(scope, parent); } +// -------------------------------------------------- +// ----- inline JSSettingsHelper implementation ----- +JSSettingsHelper::operator bool() const { + return (bool)_settings; +} +JSSettingsHelper::JSSettingsHelper(const QString& scope, QObject* parent) : + QObject(parent), _scope(scope), _fileName(getLocalSettingsPath(scope)), + _settings(_fileName.isEmpty() ? nullptr : new QSettings(_fileName, JSON_FORMAT)) { +} +JSSettingsHelper::~JSSettingsHelper() { + qCDebug(logger) << "~JSSettingsHelper" << _scope << _fileName << this; +} +QString JSSettingsHelper::fileName() const { + return _settings ? _settings->fileName() : ""; +} +QString JSSettingsHelper::toString() const { + return QString("[JSSettingsHelper scope=%1 valid=%2]").arg(_scope).arg((bool)_settings); +} +QVariant JSSettingsHelper::getValue(const QString& key, const QVariant& defaultValue) { + return _settings ? _settings->value(key, defaultValue) : defaultValue; +} +bool JSSettingsHelper::setValue(const QString& key, const QVariant& value) { + if (_settings) { + if (value.isValid()) { + _settings->setValue(key, value); + } else { + _settings->remove(key); + } + return true; + } + return false; +} +QStringList JSSettingsHelper::allKeys() const { + return _settings ? _settings->allKeys() : QStringList{}; +} +QString JSSettingsHelper::getLocalSettingsPath(const QString& scope) const { + // generate a prefixed filename (relative to the main application's Interface.json file) + const QString fileName = QString("jsapi_%1.json").arg(scope); + return QFileInfo(::settingsFilename()).dir().filePath(fileName); +} +// ----- /inline JSSettingsHelper implementation ----- + } // namespace REPLACE_ME_WITH_UNIQUE_NAME #include "JSAPIExample.moc" From cec0b41042581d9c625690a255a4d08a4c13eb40 Mon Sep 17 00:00:00 2001 From: HifiExperiments <53453710+HifiExperiments@users.noreply.github.com> Date: Fri, 30 Oct 2020 16:41:59 -0700 Subject: [PATCH 029/136] Apply suggestions from code review Co-authored-by: kasenvr <52365539+kasenvr@users.noreply.github.com> --- scripts/system/quickGoto.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/quickGoto.js b/scripts/system/quickGoto.js index ec278dd1d2..3211688e6e 100644 --- a/scripts/system/quickGoto.js +++ b/scripts/system/quickGoto.js @@ -30,8 +30,8 @@ }); } - addGotoButton("172.104.248.237"); - addGotoButton("167.172.61.134"); + addGotoButton("hub.daleglass.net"); + addGotoButton("lq-hub.vircadia.com"); addGotoButton("file:///~/serverless/tutorial.json"); }()); // END LOCAL_SCOPE From 5c2a8bd45938bce257af5ed15027d8b11943da35 Mon Sep 17 00:00:00 2001 From: humbletim <humbletim@gmail.com> Date: Sat, 31 Oct 2020 14:11:05 -0400 Subject: [PATCH 030/136] changes per CR --- plugins/JSAPIExample/src/JSAPIExample.cpp | 423 +++++++++++----------- 1 file changed, 212 insertions(+), 211 deletions(-) diff --git a/plugins/JSAPIExample/src/JSAPIExample.cpp b/plugins/JSAPIExample/src/JSAPIExample.cpp index d0e5a27869..ed637e198b 100644 --- a/plugins/JSAPIExample/src/JSAPIExample.cpp +++ b/plugins/JSAPIExample/src/JSAPIExample.cpp @@ -28,222 +28,223 @@ // NOTE: replace this with your own namespace when starting a new plugin (to avoid .so/.dll symbol clashes) namespace REPLACE_ME_WITH_UNIQUE_NAME { -static constexpr auto JSAPI_SEMANTIC_VERSION = "0.0.1"; -static constexpr auto JSAPI_EXPORT_NAME = "JSAPIExample"; + static constexpr auto JSAPI_SEMANTIC_VERSION = "0.0.1"; + static constexpr auto JSAPI_EXPORT_NAME = "JSAPIExample"; -QLoggingCategory logger{ "jsapiexample" }; + QLoggingCategory logger { "jsapiexample" }; -inline QVariant raiseScriptingError(QScriptContext* context, const QString& message, const QVariant& returnValue = QVariant()) { - if (context) { - // when a QScriptContext is available throw an actual JS Exception (which can be caught using try/catch on JS side) - context->throwError(message); - } else { - // otherwise just log the error - qCWarning(logger) << "error:" << message; - } - return returnValue; -} - -QObject* createScopedSettings(const QString& scope, QObject* parent, QString& error); - -class JSAPIExample : public QObject, public QScriptable { - Q_OBJECT - Q_PLUGIN_METADATA(IID "JSAPIExample" FILE "plugin.json") - Q_PROPERTY(QString version MEMBER _version CONSTANT) -public: - JSAPIExample() { - setObjectName(JSAPI_EXPORT_NAME); - auto scriptInit = DependencyManager::get<ScriptInitializers>(); - if (!scriptInit) { - qCWarning(logger) << "COULD NOT INITIALIZE (ScriptInitializers unavailable)" << qApp << this; - return; - } - qCWarning(logger) << "registering w/ScriptInitializerMixin..." << scriptInit.data(); - scriptInit->registerScriptInitializer([this](QScriptEngine* engine) { - auto value = engine->newQObject(this, QScriptEngine::QtOwnership, QScriptEngine::ExcludeDeleteLater); - engine->globalObject().setProperty(objectName(), value); - // qCDebug(logger) << "setGlobalInstance" << objectName() << engine->property("fileName"); - }); - // qCInfo(logger) << "plugin loaded" << qApp << toString() << QThread::currentThread(); - } - - // NOTES: everything within the "public slots:" section below will be available from JS via overall plugin QObject - // also, to demonstrate future-proofing JS API code, QVariant's are used throughout most of these examples -- - // which still makes them very Qt-specific, but avoids depending directly on deprecated QtScript/QScriptValue APIs. - // (as such this plugin class and its methods remain forward-compatible with other engines like QML's QJSEngine) - -public slots: - // pretty-printed representation for logging eg: print(JSAPIExample) - // (note: Qt script engines automatically look for a ".toString" method on native classes when coercing values to strings) - QString toString() const { return QString("[%1 version=%2]").arg(objectName()).arg(_version); } - - /**jsdoc - * Returns current microseconds (usecs) since Epoch. note: 1000usecs == 1ms - * @example <caption>Measure current setTimeout accuracy.</caption> - * var expected = 1000; - * var start = JSAPIExample.now(); - * Script.setTimeout(function () { - * var elapsed = (JSAPIExample.now() - start)/1000; - * print("expected (ms):", expected, "actual (ms):", elapsed); - * }, expected); - */ - QVariant now() const { return usecTimestampNow(); } - - /**jsdoc - * Example of returning a JS Object key-value map - * @example <caption>"zip" a list of keys and corresponding values to form key-value map</caption> - * print(JSON.stringify(JSAPIExample.zip(["a","b"], [1,2])); // { "a": 1, "b": 2 } - */ - QVariant zip(const QStringList& keys, const QVariantList& values) const { - QVariantMap out; - for (int i = 0; i < keys.size(); i++) { - out[keys[i]] = i < values.size() ? values[i] : QVariant(); - } - return out; - } - - /**jsdoc - * Example of returning a JS Array result - * @example <caption>emulate Object.values(keyValues)</caption> - * print(JSON.stringify(JSAPIExample.values({ "a": 1, "b": 2 }))); // [1,2] - */ - QVariant values(const QVariantMap& keyValues) const { - QVariantList values = keyValues.values(); - return values; - } - - /**jsdoc - * Another example of returning JS Array data - * @example <caption>generate an integer sequence (inclusive of [from, to])</caption> - * print(JSON.stringify(JSAPIExample.seq(1,5)));// [1,2,3,4,5] - */ - QVariant seq(int from, int to) const { - QVariantList out; - for (int i = from; i <= to; i++) { - out.append(i); - } - return out; - } - - /**jsdoc - * Example of returning arbitrary binary data from C++ (resulting in a JS ArrayBuffer) - * see also: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer#Examples - * @example <caption>return compressed/decompressed versions of the input data</caption> - * var data = "testing 1 2 3"; - * var z = JSAPIExample.qCompressString(data); // z will be an ArrayBuffer - * var u = JSAPIExample.qUncompressString(z); // u will be a String value - * print(JSON.stringify({ input: data, compressed: z.byteLength, output: u, uncompressed: u.length })); - */ - QVariant qCompressString(const QString& jsString, int compress_level = -1) const { - QByteArray arrayBuffer = qCompress(jsString.toUtf8(), compress_level); - return arrayBuffer; - } - QVariant qUncompressString(const QByteArray& arrayBuffer) const { - QString jsString = QString::fromUtf8(qUncompress(arrayBuffer)); - return jsString; - } - - /** - * Example of exposing a custom "managed" C++ QObject to JS - * The lifecycle of the created QObject* instance becomes managed by the invoking QScriptEngine -- - * it will be automatically cleaned up once no longer reachable from any JS variables/closures. - * @example <caption>access persistent settings stored in separate .json files</caption> - * var settings = JSAPIExample.getScopedSettings("example"); - * print("example settings stored in:", settings.fileName()); - * print("(before) example::timestamp", settings.getValue("timestamp")); - * settings.setValue("timestamp", Date.now()); - * print("(after) example::timestamp", settings.getValue("timestamp")); - * print("all example::* keys", settings.allKeys()); - * settings = null; // optional best pratice; allows the object to be reclaimed ASAP by the JS garbage collector - */ - QScriptValue getScopedSettings(const QString& scope) { - auto engine = QScriptable::engine(); - if (!engine) - return QScriptValue::NullValue; - QString error; - auto cppValue = createScopedSettings(scope, engine, error); - if (!cppValue) { - raiseScriptingError(context(), "error creating scoped settings instance: " + error); - return QScriptValue::NullValue; - } - return engine->newQObject(cppValue, QScriptEngine::ScriptOwnership, QScriptEngine::ExcludeDeleteLater); - } - -private: - const QString _version{ JSAPI_SEMANTIC_VERSION }; -}; - -// JSSettingsHelper wraps a scoped (prefixed/separate) QSettings and exposes a subset of QSetting APIs as slots -class JSSettingsHelper : public QObject { - Q_OBJECT -public: - JSSettingsHelper(const QString& scope, QObject* parent = nullptr); - ~JSSettingsHelper(); - operator bool() const; -public slots: - QString fileName() const; - QString toString() const; - QVariant getValue(const QString& key, const QVariant& defaultValue = QVariant()); - bool setValue(const QString& key, const QVariant& value); - QStringList allKeys() const; -protected: - QString _scope; - QString _fileName; - QSharedPointer<QSettings> _settings; - QString getLocalSettingsPath(const QString& scope) const; -}; - -// verifies the requested scope is sensible and creates/returns a scoped JSSettingsHelper instance -QObject* createScopedSettings(const QString& scope, QObject* parent, QString& error) { - const QRegExp VALID_SETTINGS_SCOPE{ "[-_A-Za-z0-9]{1,64}" }; - if (!VALID_SETTINGS_SCOPE.exactMatch(scope)) { - error = QString("invalid scope (expected alphanumeric <= 64 chars not '%1')").arg(scope); - return nullptr; - } - return new JSSettingsHelper(scope, parent); -} - -// -------------------------------------------------- -// ----- inline JSSettingsHelper implementation ----- -JSSettingsHelper::operator bool() const { - return (bool)_settings; -} -JSSettingsHelper::JSSettingsHelper(const QString& scope, QObject* parent) : - QObject(parent), _scope(scope), _fileName(getLocalSettingsPath(scope)), - _settings(_fileName.isEmpty() ? nullptr : new QSettings(_fileName, JSON_FORMAT)) { -} -JSSettingsHelper::~JSSettingsHelper() { - qCDebug(logger) << "~JSSettingsHelper" << _scope << _fileName << this; -} -QString JSSettingsHelper::fileName() const { - return _settings ? _settings->fileName() : ""; -} -QString JSSettingsHelper::toString() const { - return QString("[JSSettingsHelper scope=%1 valid=%2]").arg(_scope).arg((bool)_settings); -} -QVariant JSSettingsHelper::getValue(const QString& key, const QVariant& defaultValue) { - return _settings ? _settings->value(key, defaultValue) : defaultValue; -} -bool JSSettingsHelper::setValue(const QString& key, const QVariant& value) { - if (_settings) { - if (value.isValid()) { - _settings->setValue(key, value); + inline QVariant raiseScriptingError(QScriptContext* context, const QString& message, const QVariant& returnValue = QVariant()) { + if (context) { + // when a QScriptContext is available throw an actual JS Exception (which can be caught using try/catch on JS side) + context->throwError(message); } else { - _settings->remove(key); + // otherwise just log the error + qCWarning(logger) << "error:" << message; } - return true; + return returnValue; } - return false; -} -QStringList JSSettingsHelper::allKeys() const { - return _settings ? _settings->allKeys() : QStringList{}; -} -QString JSSettingsHelper::getLocalSettingsPath(const QString& scope) const { - // generate a prefixed filename (relative to the main application's Interface.json file) - const QString fileName = QString("jsapi_%1.json").arg(scope); - return QFileInfo(::settingsFilename()).dir().filePath(fileName); -} -// ----- /inline JSSettingsHelper implementation ----- + + QObject* createScopedSettings(const QString& scope, QObject* parent, QString& error); + + class JSAPIExample : public QObject, public QScriptable { + Q_OBJECT + Q_PLUGIN_METADATA(IID "JSAPIExample" FILE "plugin.json") + Q_PROPERTY(QString version MEMBER _version CONSTANT) + public: + JSAPIExample() { + setObjectName(JSAPI_EXPORT_NAME); + auto scriptInit = DependencyManager::get<ScriptInitializers>(); + if (!scriptInit) { + qCWarning(logger) << "COULD NOT INITIALIZE (ScriptInitializers unavailable)" << qApp << this; + return; + } + qCWarning(logger) << "registering w/ScriptInitializerMixin..." << scriptInit.data(); + scriptInit->registerScriptInitializer([this](QScriptEngine* engine) { + auto value = engine->newQObject(this, QScriptEngine::QtOwnership, QScriptEngine::ExcludeDeleteLater); + engine->globalObject().setProperty(objectName(), value); + // qCDebug(logger) << "setGlobalInstance" << objectName() << engine->property("fileName"); + }); + // qCInfo(logger) << "plugin loaded" << qApp << toString() << QThread::currentThread(); + } + + // NOTES: everything within the "public slots:" section below will be available from JS via overall plugin QObject + // also, to demonstrate future-proofing JS API code, QVariant's are used throughout most of these examples -- + // which still makes them very Qt-specific, but avoids depending directly on deprecated QtScript/QScriptValue APIs. + // (as such this plugin class and its methods remain forward-compatible with other engines like QML's QJSEngine) + + public slots: + // pretty-printed representation for logging eg: print(JSAPIExample) + // (note: Qt script engines automatically look for a ".toString" method on native classes when coercing values to strings) + QString toString() const { return QString("[%1 version=%2]").arg(objectName()).arg(_version); } + + /**jsdoc + * Returns current microseconds (usecs) since Epoch. note: 1000usecs == 1ms + * @example <caption>Measure current setTimeout accuracy.</caption> + * var expected = 1000; + * var start = JSAPIExample.now(); + * Script.setTimeout(function () { + * var elapsed = (JSAPIExample.now() - start)/1000; + * print("expected (ms):", expected, "actual (ms):", elapsed); + * }, expected); + */ + QVariant now() const { return usecTimestampNow(); } + + /**jsdoc + * Example of returning a JS Object key-value map + * @example <caption>"zip" a list of keys and corresponding values to form key-value map</caption> + * print(JSON.stringify(JSAPIExample.zip(["a","b"], [1,2])); // { "a": 1, "b": 2 } + */ + QVariant zip(const QStringList& keys, const QVariantList& values) const { + QVariantMap out; + for (int i = 0; i < keys.size(); i++) { + out[keys[i]] = i < values.size() ? values[i] : QVariant(); + } + return out; + } + + /**jsdoc + * Example of returning a JS Array result + * @example <caption>emulate Object.values(keyValues)</caption> + * print(JSON.stringify(JSAPIExample.values({ "a": 1, "b": 2 }))); // [1,2] + */ + QVariant values(const QVariantMap& keyValues) const { + QVariantList values = keyValues.values(); + return values; + } + + /**jsdoc + * Another example of returning JS Array data + * @example <caption>generate an integer sequence (inclusive of [from, to])</caption> + * print(JSON.stringify(JSAPIExample.seq(1,5)));// [1,2,3,4,5] + */ + QVariant seq(int from, int to) const { + QVariantList out; + for (int i = from; i <= to; i++) { + out.append(i); + } + return out; + } + + /**jsdoc + * Example of returning arbitrary binary data from C++ (resulting in a JS ArrayBuffer) + * see also: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer#Examples + * @example <caption>return compressed/decompressed versions of the input data</caption> + * var data = "testing 1 2 3"; + * var z = JSAPIExample.qCompressString(data); // z will be an ArrayBuffer + * var u = JSAPIExample.qUncompressString(z); // u will be a String value + * print(JSON.stringify({ input: data, compressed: z.byteLength, output: u, uncompressed: u.length })); + */ + QVariant qCompressString(const QString& jsString, int compress_level = -1) const { + QByteArray arrayBuffer = qCompress(jsString.toUtf8(), compress_level); + return arrayBuffer; + } + QVariant qUncompressString(const QByteArray& arrayBuffer) const { + QString jsString = QString::fromUtf8(qUncompress(arrayBuffer)); + return jsString; + } + + /** + * Example of exposing a custom "managed" C++ QObject to JS + * The lifecycle of the created QObject* instance becomes managed by the invoking QScriptEngine -- + * it will be automatically cleaned up once no longer reachable from any JS variables/closures. + * @example <caption>access persistent settings stored in separate .json files</caption> + * var settings = JSAPIExample.getScopedSettings("example"); + * print("example settings stored in:", settings.fileName()); + * print("(before) example::timestamp", settings.getValue("timestamp")); + * settings.setValue("timestamp", Date.now()); + * print("(after) example::timestamp", settings.getValue("timestamp")); + * print("all example::* keys", settings.allKeys()); + * settings = null; // optional best pratice; allows the object to be reclaimed ASAP by the JS garbage collector + */ + QScriptValue getScopedSettings(const QString& scope) { + auto engine = QScriptable::engine(); + if (!engine) { + return QScriptValue::NullValue; + } + QString error; + auto cppValue = createScopedSettings(scope, engine, error); + if (!cppValue) { + raiseScriptingError(context(), "error creating scoped settings instance: " + error); + return QScriptValue::NullValue; + } + return engine->newQObject(cppValue, QScriptEngine::ScriptOwnership, QScriptEngine::ExcludeDeleteLater); + } + + private: + const QString _version { JSAPI_SEMANTIC_VERSION }; + }; + + // JSSettingsHelper wraps a scoped (prefixed/separate) QSettings and exposes a subset of QSetting APIs as slots + class JSSettingsHelper : public QObject { + Q_OBJECT + public: + JSSettingsHelper(const QString& scope, QObject* parent = nullptr); + ~JSSettingsHelper(); + operator bool() const; + public slots: + QString fileName() const; + QString toString() const; + QVariant getValue(const QString& key, const QVariant& defaultValue = QVariant()); + bool setValue(const QString& key, const QVariant& value); + QStringList allKeys() const; + protected: + QString _scope; + QString _fileName; + QSharedPointer<QSettings> _settings; + QString getLocalSettingsPath(const QString& scope) const; + }; + + // verifies the requested scope is sensible and creates/returns a scoped JSSettingsHelper instance + QObject* createScopedSettings(const QString& scope, QObject* parent, QString& error) { + const QRegExp VALID_SETTINGS_SCOPE { "[-_A-Za-z0-9]{1,64}" }; + if (!VALID_SETTINGS_SCOPE.exactMatch(scope)) { + error = QString("invalid scope (expected alphanumeric <= 64 chars not '%1')").arg(scope); + return nullptr; + } + return new JSSettingsHelper(scope, parent); + } + + // -------------------------------------------------- + // ----- inline JSSettingsHelper implementation ----- + JSSettingsHelper::operator bool() const { + return (bool)_settings; + } + JSSettingsHelper::JSSettingsHelper(const QString& scope, QObject* parent) : + QObject(parent), _scope(scope), _fileName(getLocalSettingsPath(scope)), + _settings(_fileName.isEmpty() ? nullptr : new QSettings(_fileName, JSON_FORMAT)) { + } + JSSettingsHelper::~JSSettingsHelper() { + qCDebug(logger) << "~JSSettingsHelper" << _scope << _fileName << this; + } + QString JSSettingsHelper::fileName() const { + return _settings ? _settings->fileName() : ""; + } + QString JSSettingsHelper::toString() const { + return QString("[JSSettingsHelper scope=%1 valid=%2]").arg(_scope).arg((bool)_settings); + } + QVariant JSSettingsHelper::getValue(const QString& key, const QVariant& defaultValue) { + return _settings ? _settings->value(key, defaultValue) : defaultValue; + } + bool JSSettingsHelper::setValue(const QString& key, const QVariant& value) { + if (_settings) { + if (value.isValid()) { + _settings->setValue(key, value); + } else { + _settings->remove(key); + } + return true; + } + return false; + } + QStringList JSSettingsHelper::allKeys() const { + return _settings ? _settings->allKeys() : QStringList{}; + } + QString JSSettingsHelper::getLocalSettingsPath(const QString& scope) const { + // generate a prefixed filename (relative to the main application's Interface.json file) + const QString fileName = QString("jsapi_%1.json").arg(scope); + return QFileInfo(::settingsFilename()).dir().filePath(fileName); + } + // ----- /inline JSSettingsHelper implementation ----- } // namespace REPLACE_ME_WITH_UNIQUE_NAME From e28b2025a97747657e8ad11657e706feb395c4d2 Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Tue, 3 Nov 2020 20:47:48 +1300 Subject: [PATCH 031/136] Prompt for username or e-mail for domain login --- interface/resources/qml/LoginDialog/LinkAccountBody.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 694fd6158f..a4d05d9bc4 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -114,7 +114,7 @@ Item { displayNameField.placeholderText = "Display Name (optional)"; var savedDisplayName = Settings.getValue("Avatar/displayName", ""); displayNameField.text = savedDisplayName; - emailField.placeholderText = (!isLoggingInToDomain) ? "Username or Email" : "Username"; + emailField.placeholderText = "Username or Email"; if (!isLoggingInToDomain) { var savedUsername = Settings.getValue("keepMeLoggedIn/savedUsername", ""); emailField.text = keepMeLoggedInCheckbox.checked ? savedUsername === "Unknown user" ? "" : savedUsername : ""; From c6728be4e8c2c52ba62b4b0e54653df67e6549ec Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Wed, 4 Nov 2020 11:23:47 +1300 Subject: [PATCH 032/136] Fix enterEntity event not firing in entithy script after content reload --- .../entities-renderer/src/EntityTreeRenderer.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index b5ed4b767d..3538f07d32 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -167,6 +167,13 @@ void EntityTreeRenderer::resetEntitiesScriptEngine() { auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); entityScriptingInterface->setEntitiesScriptEngine(entitiesScriptEngineProvider); + connect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptPreloadFinished, [&](const EntityItemID& entityID) { + EntityItemPointer entity = getTree()->findEntityByID(entityID); + if (entity) { + entity->setScriptHasFinishedPreload(true); + } + }); + // Connect mouse events to entity script callbacks if (!_mouseAndPreloadSignalHandlersConnected) { @@ -205,13 +212,6 @@ void EntityTreeRenderer::resetEntitiesScriptEngine() { _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverLeaveEntity", event); }); - connect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptPreloadFinished, [&](const EntityItemID& entityID) { - EntityItemPointer entity = getTree()->findEntityByID(entityID); - if (entity) { - entity->setScriptHasFinishedPreload(true); - } - }); - _mouseAndPreloadSignalHandlersConnected = true; } } From a3c85bd438ce5fc3a55f7236b501702e970c9eca Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Wed, 4 Nov 2020 19:41:01 -0800 Subject: [PATCH 033/136] possible fix for collisions again --- .../src/RenderableModelEntityItem.cpp | 227 ++++++++---------- .../src/RenderableModelEntityItem.h | 4 - libraries/entities/src/ModelEntityItem.cpp | 6 +- libraries/entities/src/ModelEntityItem.h | 3 - 4 files changed, 96 insertions(+), 144 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 8640e9e8bf..c9e7362e62 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -76,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) { @@ -217,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(); } } @@ -276,7 +251,18 @@ bool RenderableModelEntityItem::findDetailedParabolaIntersection(const glm::vec3 } void RenderableModelEntityItem::fetchCollisionGeometryResource() { - _collisionGeometryResource = DependencyManager::get<ModelCache>()->getCollisionGeometryResource(getCollisionShapeURL()); + _collisionGeometryResource = DependencyManager::get<ModelCache>()->getCollisionGeometryResource(getCompoundShapeURL()); + 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() { @@ -290,7 +276,7 @@ void RenderableModelEntityItem::setShapeType(ShapeType type) { ModelEntityItem::setShapeType(type); auto shapeType = getShapeType(); if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { - if (!_collisionGeometryResource && !getCollisionShapeURL().isEmpty()) { + if (!_collisionGeometryResource && !getCompoundShapeURL().isEmpty()) { fetchCollisionGeometryResource(); } } else if (_collisionGeometryResource && !getCompoundShapeURL().isEmpty()) { @@ -302,63 +288,32 @@ void RenderableModelEntityItem::setShapeType(ShapeType type) { void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) { auto currentCompoundShapeURL = getCompoundShapeURL(); ModelEntityItem::setCompoundShapeURL(url); - if (getCompoundShapeURL() != currentCompoundShapeURL) { + if (url != currentCompoundShapeURL && !url.isEmpty()) { auto shapeType = getShapeType(); if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { fetchCollisionGeometryResource(); - markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); - } - } -} - -void RenderableModelEntityItem::setModelURL(const QString& url) { - auto currentModelURL = getModelURL(); - ModelEntityItem::setModelURL(url); - if (getModelURL() != currentModelURL) { - auto shapeType = getShapeType(); - if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { - fetchCollisionGeometryResource(); - markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); } } } 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) { + auto shapeURL = getCompoundShapeURL(); + // we need a render geometry with a scale to proceed + if (model && !model->getURL().isEmpty() && !shapeURL.isEmpty() && _dimensionsInitialized && model->isLoaded()) { + if (!_collisionGeometryResource) { const_cast<RenderableModelEntityItem*>(this)->fetchCollisionGeometryResource(); } - if (_collisionGeometryResource && _collisionGeometryResource->isLoaded() && _collisionGeometryResource->isHFMModelLoaded()) { - // 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<RenderableModelEntityItem*>(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 model && model->isLoaded(); + } else if (shapeType >= SHAPE_TYPE_SIMPLE_HULL && shapeType <= SHAPE_TYPE_STATIC_MESH) { + return model && model->isLoaded() && _dimensionsInitialized; } return true; } @@ -370,20 +325,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() || !_collisionGeometryResource->isHFMModelLoaded()) { - 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(); @@ -460,7 +426,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()); @@ -470,12 +437,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 @@ -484,16 +449,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(); } @@ -506,9 +471,6 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { std::vector<std::shared_ptr<const graphics::Mesh>> meshes; if (type == SHAPE_TYPE_SIMPLE_COMPOUND) { - if (!_collisionGeometryResource || !_collisionGeometryResource->isLoaded() || !_collisionGeometryResource->isHFMModelLoaded()) { - return; - } auto& hfmMeshes = _collisionGeometryResource->getHFMModel().meshes; meshes.reserve(hfmMeshes.size()); for (auto& hfmMesh : hfmMeshes) { @@ -708,7 +670,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); @@ -749,21 +711,19 @@ bool RenderableModelEntityItem::contains(const glm::vec3& point) const { bool RenderableModelEntityItem::shouldBePhysical() const { bool physicalModelLoaded = false; ShapeType shapeType = getShapeType(); - if (shapeType >= SHAPE_TYPE_SIMPLE_HULL && shapeType <= SHAPE_TYPE_STATIC_MESH) { + 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_SIMPLE_COMPOUND) { + if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { physicalModelLoaded &= _collisionGeometryResource && !_collisionGeometryResource->isFailed(); } - } else if (shapeType == SHAPE_TYPE_COMPOUND) { - physicalModelLoaded = _collisionGeometryResource && !_collisionGeometryResource->isFailed(); } else if (shapeType != SHAPE_TYPE_NONE) { physicalModelLoaded = true; } - return physicalModelLoaded && !isDead() && !isLocalEntity() && QUrl(_modelURL).isValid(); + return physicalModelLoaded && !isDead() && !isLocalEntity() && QUrl(getModelURL()).isValid(); } int RenderableModelEntityItem::getJointParent(int index) const { @@ -1243,7 +1203,7 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint entity->bumpAncestorChainRenderableVersion(); emit DependencyManager::get<scriptable::ModelProviderFactory>()-> modelRemovedFromScene(entity->getEntityItemID(), NestableType::Entity, model); - withWriteLock([&] { model.reset(); }); + withWriteLock([&] { _model.reset(); }); } _didLastVisualGeometryRequestSucceed = false; setKey(_didLastVisualGeometryRequestSucceed, model); @@ -1256,33 +1216,34 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint connect(model.get(), &Model::requestRenderUpdate, this, &ModelEntityRenderer::requestRenderUpdate); connect(model.get(), &Model::setURLFinished, this, [&](bool didVisualGeometryRequestSucceed) { 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); - entity->markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); - entity->locationChanged(); - entity->dimensionsChanged(); + render::Transaction transaction; + transaction.updateItem<PayloadProxyInterface>(_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<scriptable::ModelProviderFactory>()-> + modelAddedToScene(entity->getEntityItemID(), NestableType::Entity, model); + } + _didLastVisualGeometryRequestSucceed = didVisualGeometryRequestSucceed; + entity->_originalTexturesRead = false; + entity->_needsJointSimulation = true; + entity->_needsToRescaleModel = true; + entity->updateModelBounds(); + emit requestRenderUpdate(); }); - if (didVisualGeometryRequestSucceed) { - emit DependencyManager::get<scriptable::ModelProviderFactory>()-> - modelAddedToScene(entity->getEntityItemID(), NestableType::Entity, model); - } - _didLastVisualGeometryRequestSucceed = didVisualGeometryRequestSucceed; - entity->_originalTexturesRead = false; - entity->_needsJointSimulation = true; - entity->_needsToRescaleModel = true; - entity->updateModelBounds(); - emit requestRenderUpdate(); + scene->enqueueTransaction(transaction); }); - model->setLoadingPriority(EntityTreeRenderer::getEntityLoadingPriority(*entity)); entity->setModel(model); withWriteLock([&] { _model = model; }); } @@ -1291,6 +1252,7 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint if (_parsedModelURL != model->getURL()) { _texturesLoaded = false; _jointMappingCompleted = false; + model->setLoadingPriority(EntityTreeRenderer::getEntityLoadingPriority(*entity)); model->setURL(_parsedModelURL); } @@ -1301,7 +1263,6 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint } // 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 @@ -1335,16 +1296,18 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint entity->updateModelBounds(); entity->stopModelOverrideIfNoParent(); - setKey(_didLastVisualGeometryRequestSucceed, 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); + withWriteLock([&] { + setKey(_didLastVisualGeometryRequestSucceed, 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 (entity->blendshapesChanged()) { model->setBlendshapeCoefficients(entity->getBlendshapeCoefficientVector()); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index b57ebd8056..09c07b3b84 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -61,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; @@ -76,7 +75,6 @@ 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; @@ -185,8 +183,6 @@ private: bool _hasTransitioned{ false }; #endif - const void* _collisionMeshKey { nullptr }; - QUrl _parsedModelURL; bool _jointMappingCompleted { false }; QVector<int> _jointMapping; // domain is index into model-joints, range is index into animation-joints diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index e841bf16dd..8c3a729e41 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -273,7 +273,7 @@ ShapeType ModelEntityItem::getShapeType() const { } ShapeType ModelEntityItem::computeTrueShapeType() const { - ShapeType type = _shapeType; + ShapeType type = resultWithReadLock<ShapeType>([&] { 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 @@ -565,10 +565,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; diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 59bb6d67cf..b6d577dff0 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -76,9 +76,6 @@ 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); From b7933788301995cc58579988e5939f73193fc618 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 4 Nov 2020 23:12:04 -0500 Subject: [PATCH 034/136] Undo-redo for "Move Selected Entities to Avatar" This adds the undo/redo to the action "Move Selected Entities to Avatar". The action is now recorded in the undo history. --- scripts/system/create/entitySelectionTool/entitySelectionTool.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/system/create/entitySelectionTool/entitySelectionTool.js b/scripts/system/create/entitySelectionTool/entitySelectionTool.js index ffa828affe..97e36d818e 100644 --- a/scripts/system/create/entitySelectionTool/entitySelectionTool.js +++ b/scripts/system/create/entitySelectionTool/entitySelectionTool.js @@ -668,6 +668,7 @@ SelectionManager = (function() { var newPosition = Vec3.sum(relativePosition, targetPosition); Entities.editEntity(id, { "position": newPosition }); } + pushCommandForSelections(); that._update(false, this); } else { audioFeedback.rejection(); From 1cf0e2c00a6c75f3a3fa263932e24bdb7922a29f Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 4 Nov 2020 23:23:29 -0500 Subject: [PATCH 035/136] "Teleport to Selected Entities" to Actions menu This moves "Teleport to Selected Entities" from "Selection" to "Actions" menu. --- .../create/entityList/html/entityList.html | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/scripts/system/create/entityList/html/entityList.html b/scripts/system/create/entityList/html/entityList.html index b22cd87a65..b3a354fdda 100644 --- a/scripts/system/create/entityList/html/entityList.html +++ b/scripts/system/create/entityList/html/entityList.html @@ -154,7 +154,13 @@ <div class = "menu-item-caption">Move Selected Entities to Avatar</div> <div class = "menu-item-shortcut"></div> </div> - </button> + </button> + <button class="menu-button" id="teleport-to-entity" > + <div class = "menu-item"> + <div class = "menu-item-caption">Teleport To Selected Entities</div> + <div class = "menu-item-shortcut"></div> + </div> + </button> </div> <div class="entity-list-menu" id="selection-menu" > <button class="menu-button" id="selectall" > @@ -218,14 +224,7 @@ <div class = "menu-item-caption">Select Top Family</div> <div class = "menu-item-shortcut"></div> </div> - </button> - <div class="menu-separator"></div> - <button class="menu-button" id="teleport-to-entity" > - <div class = "menu-item"> - <div class = "menu-item-caption">Teleport To Selected Entities</div> - <div class = "menu-item-shortcut"></div> - </div> - </button> + </button> </div> <div id="menuBackgroundOverlay" ></div> </body> From a7e6332c0e53fa5d463bbaf1653fbea11cf7394e Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Wed, 4 Nov 2020 22:09:11 -0800 Subject: [PATCH 036/136] fix alpha material bug --- libraries/entities-renderer/src/RenderableEntityItem.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 32dd280502..b116423b75 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -469,11 +469,13 @@ void EntityRenderer::onRemoveFromScene(const EntityItemPointer& entity) { void EntityRenderer::addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) { std::lock_guard<std::mutex> lock(_materialsLock); _materials[parentMaterialName].push(material); + emit requestRenderUpdate(); } void EntityRenderer::removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) { std::lock_guard<std::mutex> lock(_materialsLock); _materials[parentMaterialName].remove(material); + emit requestRenderUpdate(); } glm::vec4 EntityRenderer::calculatePulseColor(const glm::vec4& color, const PulsePropertyGroup& pulseProperties, quint64 start) { From c8532a1ac5868b8878cb12f01c5c5ebf8ee1c31f Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Wed, 4 Nov 2020 22:21:24 -0800 Subject: [PATCH 037/136] another unused variable --- libraries/render-utils/src/Model.cpp | 1 - libraries/render-utils/src/Model.h | 3 --- 2 files changed, 4 deletions(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 86d6f9ed86..7262664ddb 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1493,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 74cbfd6e7e..255d2bfc12 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -337,7 +337,6 @@ public: const MeshState& getMeshState(int index) { return _meshStates.at(index); } - uint32_t getGeometryCounter() const { return _deleteGeometryCounter; } const QMap<render::ItemID, render::PayloadPointer>& getRenderItems() const { return _modelMeshRenderItemsMap; } BlendShapeOperator getModelBlendshapeOperator() const { return _modelBlendshapeOperator; } @@ -473,8 +472,6 @@ protected: friend class ModelMeshPartPayload; Rig _rig; - uint32_t _deleteGeometryCounter { 0 }; - bool _visualGeometryRequestFailed { false }; bool _renderItemsNeedUpdate { false }; From dcb1493eaf4e265b552fd1dc21db5b5011230f9e Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Thu, 5 Nov 2020 21:49:22 -0500 Subject: [PATCH 038/136] Rename "Select Family" This renames: "Select Family" for "Select Parent And All Its Children" "Select Top Family" for "Select Top Parent And All Its Children" --- scripts/system/create/entityList/html/entityList.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/entityList/html/entityList.html b/scripts/system/create/entityList/html/entityList.html index b3a354fdda..87f7f535d6 100644 --- a/scripts/system/create/entityList/html/entityList.html +++ b/scripts/system/create/entityList/html/entityList.html @@ -215,13 +215,13 @@ </button> <button class="menu-button" id="selectfamily" > <div class = "menu-item"> - <div class = "menu-item-caption">Select Family</div> + <div class = "menu-item-caption">Select Parent And All Its Children</div> <div class = "menu-item-shortcut"></div> </div> </button> <button class="menu-button" id="selecttopfamily" > <div class = "menu-item"> - <div class = "menu-item-caption">Select Top Family</div> + <div class = "menu-item-caption">Select Top Parent And All Its Children</div> <div class = "menu-item-shortcut"></div> </div> </button> From 1a98e818cc4db2e26310c307b60673477a9995b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 7 Nov 2020 19:44:15 +0000 Subject: [PATCH 039/136] Bump yargs-parser from 13.1.1 to 13.1.2 in /screenshare Bumps [yargs-parser](https://github.com/yargs/yargs-parser) from 13.1.1 to 13.1.2. - [Release notes](https://github.com/yargs/yargs-parser/releases) - [Changelog](https://github.com/yargs/yargs-parser/blob/master/docs/CHANGELOG-full.md) - [Commits](https://github.com/yargs/yargs-parser/commits) Signed-off-by: dependabot[bot] <support@github.com> --- screenshare/package-lock.json | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/screenshare/package-lock.json b/screenshare/package-lock.json index c7d92d3e17..3e799a860a 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" + } } } }, @@ -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==" } } }, From 26405300fefee76bd7de8aebed8dee7453731fc6 Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Sun, 8 Nov 2020 21:35:17 +1300 Subject: [PATCH 040/136] Handle username or email for domain login --- domain-server/src/DomainGatekeeper.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index 18926fc805..7126c525bc 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -1238,7 +1238,7 @@ void DomainGatekeeper::requestDomainUser(const QString& username, const QString& // Get data pertaining to "me", the user who generated the access token. const QString WORDPRESS_USER_ROUTE = "wp/v2/users/me"; - const QString WORDPRESS_USER_QUERY = "_fields=username,roles"; + const QString WORDPRESS_USER_QUERY = "_fields=username,email,roles"; QUrl domainUserURL = apiBase + WORDPRESS_USER_ROUTE + (apiBase.contains("?") ? "&" : "?") + WORDPRESS_USER_QUERY; QNetworkRequest request; @@ -1270,8 +1270,13 @@ void DomainGatekeeper::requestDomainUserFinished() { if (200 <= httpStatus && httpStatus < 300) { QString username = rootObject.value("username").toString().toLower(); - if (_inFlightDomainUserIdentityRequests.contains(username)) { + QString email = rootObject.value("email").toString().toLower(); + + if (_inFlightDomainUserIdentityRequests.contains(username) || _inFlightDomainUserIdentityRequests.contains(email)) { // Success! Verified user. + if (!_inFlightDomainUserIdentityRequests.contains(username)) { + username = email; + } _verifiedDomainUserIdentities.insert(username, _inFlightDomainUserIdentityRequests.value(username)); _inFlightDomainUserIdentityRequests.remove(username); From ac46e9a4929f77e7837a0ef2ceab83f06474116d Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Mon, 9 Nov 2020 00:28:54 -0500 Subject: [PATCH 041/136] Remove uppercase from Create App List header Remove uppercase from Create App List header The columns headers were forced to be displayed in uppercase This was causing the wrong icon to be displayed for some columns like "script". Uppercase wasn't necessary, the header was looking overloaded when many columns are displayed. --- scripts/system/html/css/edit-style.css | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 1f1fb9c86a..14cfe5e431 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -109,7 +109,6 @@ table { thead { font-family: Raleway-Regular; font-size: 12px; - text-transform: uppercase; background-color: #1c1c1c; padding: 1px 0; border-bottom: 1px solid #575757; From c573242043ab3ca921d2d308d7d0fef71cd06c59 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Mon, 9 Nov 2020 00:31:48 -0500 Subject: [PATCH 042/136] Add Setting name to persist the columns setup Add a Setting name to persist the columns' visibility and ordering. --- scripts/system/create/edit.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index 69e2e94818..cd987140d8 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -160,6 +160,7 @@ var SETTING_AUTO_FOCUS_ON_SELECT = "autoFocusOnSelect"; var SETTING_EASE_ON_FOCUS = "cameraEaseOnFocus"; var SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE = "showLightsAndParticlesInEditMode"; var SETTING_SHOW_ZONES_IN_EDIT_MODE = "showZonesInEditMode"; +var SETTING_EDITOR_COLUMNS_SETUP = "editorColumnsSetup"; var SETTING_EDIT_PREFIX = "Edit/"; From f3dea2fbad55082cb1d0176dfde177f7e0e4036f Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Mon, 9 Nov 2020 00:34:07 -0500 Subject: [PATCH 043/136] Add the persistence of the columns setup Add the persistence of the columns' visibility and ordering. --- scripts/system/create/entityList/entityList.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index 252481d44d..d8930ebc2d 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -371,6 +371,14 @@ EntityListTool = function(shouldUseEditTabletApp) { SelectionManager.teleportToEntity(); } else if (data.type === 'moveEntitySelectionToAvatar') { SelectionManager.moveEntitiesSelectionToAvatar(); + } else if (data.type === 'loadColumnsConfigSetting') { + var columnsData = Settings.getValue(SETTING_EDIT_PREFIX + SETTING_EDITOR_COLUMNS_SETUP, "NO_DATA"); + emitJSONScriptEvent({ + "type": "loadedColumnsSetup", + "columnsData": columnsData + }); + } else if (data.type === 'saveColumnsConfigSetting') { + Settings.setValue(SETTING_EDIT_PREFIX + SETTING_EDITOR_COLUMNS_SETUP, data.columnsData); } }; From 233d68952a928f9395a4d02ac907df6a8ea84ca4 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Mon, 9 Nov 2020 00:35:13 -0500 Subject: [PATCH 044/136] Add the persistence of the columns setup Add the persistence of the columns' visibility and ordering. --- .../create/entityList/html/js/entityList.js | 62 +++++++++++++++++-- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index be79593511..3ff8328132 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -20,7 +20,7 @@ const EMPTY_ENTITY_ID = "0"; const MAX_LENGTH_RADIUS = 9; const MINIMUM_COLUMN_WIDTH = 24; const SCROLLBAR_WIDTH = 20; -const RESIZER_WIDTH = 10; +const RESIZER_WIDTH = 13; //Must be the number of COLUMNS - 1. const DELTA_X_MOVE_COLUMNS_THRESHOLD = 2; const DELTA_X_COLUMN_SWAP_POSITION = 5; const CERTIFIED_PLACEHOLDER = "** Certified **"; @@ -283,6 +283,9 @@ const PROFILE = !ENABLE_PROFILING ? PROFILE_NOOP : function(name, fn, args) { function loaded() { openEventBridge(function() { + + var isColumnsSettingLoaded = false; + elEntityTable = document.getElementById("entity-table"); elEntityTableHeader = document.getElementById("entity-table-header"); elEntityTableBody = document.getElementById("entity-table-body"); @@ -331,7 +334,7 @@ function loaded() { elColumnsMultiselectBox = document.getElementById("entity-table-columns-multiselect-box"); elColumnsOptions = document.getElementById("entity-table-columns-options"); elToggleSpaceMode = document.getElementById('toggle-space-mode'); - + document.body.onclick = onBodyClick; elToggleLocked.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleLocked' })); @@ -618,9 +621,9 @@ function loaded() { ++columnIndex; } - + elEntityTableHeaderRow = document.querySelectorAll("#entity-table thead th"); - + entityList = new ListView(elEntityTableBody, elEntityTableScroll, elEntityTableHeaderRow, createRow, updateRow, clearRow, preRefresh, postRefresh, preRefresh, WINDOW_NONVARIABLE_HEIGHT); @@ -1409,6 +1412,10 @@ function loaded() { column.elResizer.style.visibility = columnVisible && visibleColumns > 0 ? "visible" : "hidden"; } + if (isColumnsSettingLoaded) { + EventBridge.emitWebEvent(JSON.stringify({ type: 'saveColumnsConfigSetting', columnsData: columns })); + } + entityList.refresh(); } @@ -1660,14 +1667,59 @@ function loaded() { } else { document.getElementById("hmdmultiselect").style.display = "none"; } + } else if (data.type === "loadedColumnsSetup") { + if (data.columnsData !== "NO_DATA" && typeof(data.columnsData) === "object") { + var isValid = true; + var originalColumnIDs = []; + for (let originalColumnID in COLUMNS) { + originalColumnIDs.push(originalColumnID); + } + for (let columnSetupIndex in data.columnsData) { + var checkPresence = originalColumnIDs.indexOf(data.columnsData[columnSetupIndex].columnID); + if (checkPresence === -1) { + isValid = false; + break; + } + } + if (isValid) { + for (var columnIndex = 0; columnIndex < data.columnsData.length; columnIndex++) { + if (data.columnsData[columnIndex].data.alwaysShown !== true) { + var columnDropdownID = "entity-table-column-" + data.columnsData[columnIndex].columnID; + if (data.columnsData[columnIndex].width !== 0) { + document.getElementById(columnDropdownID).checked = false; + document.getElementById(columnDropdownID).click(); + } else { + document.getElementById(columnDropdownID).checked = true; + document.getElementById(columnDropdownID).click(); + } + } + } + for (columnIndex = 0; columnIndex < data.columnsData.length; columnIndex++) { + let currentColumnIndex = originalColumnIDs.indexOf(data.columnsData[columnIndex].columnID); + if (currentColumnIndex !== -1 && columnIndex !== currentColumnIndex) { + for (var i = currentColumnIndex; i > columnIndex; i--) { + swapColumns(i-1, i); + var swappedContent = originalColumnIDs[i-1]; + originalColumnIDs[i-1] = originalColumnIDs[i]; + originalColumnIDs[i] = swappedContent; + } + } + } + } else { + EventBridge.emitWebEvent(JSON.stringify({ type: 'saveColumnsConfigSetting', columnsData: "" })); + } + } + isColumnsSettingLoaded = true; } }); } - + refreshSortOrder(); refreshEntities(); window.addEventListener("resize", updateColumnWidths); + + EventBridge.emitWebEvent(JSON.stringify({ type: 'loadColumnsConfigSetting' })); }); augmentSpinButtons(); From 44db0bb866b724329e853c686160d2772a274dcf Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Mon, 9 Nov 2020 22:02:42 -0500 Subject: [PATCH 045/136] Add selection color Parent & Child entities Add in-world selection color for entities that are Parent & Child at the same time. When 1 entity is selected (in-world): if the entity is a Top Parent, the selection color of the bounding box is Orange. if the entity is Parent and Child, the selection color of the bounding box is Majenta. if the entity is only a Child, then the selection color of the bounding box is Cyan. If not involved in any parent line, or if the selection is multiple, then the selection color of the bounding box is Light Grey. --- .../create/entitySelectionTool/entitySelectionTool.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/system/create/entitySelectionTool/entitySelectionTool.js b/scripts/system/create/entitySelectionTool/entitySelectionTool.js index 97e36d818e..71edbde765 100644 --- a/scripts/system/create/entitySelectionTool/entitySelectionTool.js +++ b/scripts/system/create/entitySelectionTool/entitySelectionTool.js @@ -798,6 +798,7 @@ SelectionDisplay = (function() { const COLOR_ROTATE_CURRENT_RING = { red: 255, green: 99, blue: 9 }; const COLOR_BOUNDING_EDGE = { red: 160, green: 160, blue: 160 }; const COLOR_BOUNDING_EDGE_PARENT = { red: 194, green: 123, blue: 0 }; + const COLOR_BOUNDING_EDGE_PARENT_AND_CHILDREN = { red: 179, green: 0, blue: 134 }; const COLOR_BOUNDING_EDGE_CHILDREN = { red: 0, green: 168, blue: 214 }; const COLOR_SCALE_CUBE = { red: 192, green: 192, blue: 192 }; const COLOR_DEBUG_PICK_PLANE = { red: 255, green: 255, blue: 255 }; @@ -1934,10 +1935,10 @@ SelectionDisplay = (function() { var parentState = getParentState(SelectionManager.selections[0]); if (parentState === "CHILDREN") { handleBoundingBoxColor = COLOR_BOUNDING_EDGE_CHILDREN; - } else { - if (parentState === "PARENT" || parentState === "PARENT_CHILDREN") { - handleBoundingBoxColor = COLOR_BOUNDING_EDGE_PARENT; - } + } else if (parentState === "PARENT") { + handleBoundingBoxColor = COLOR_BOUNDING_EDGE_PARENT; + } else if (parentState === "PARENT_CHILDREN") { + handleBoundingBoxColor = COLOR_BOUNDING_EDGE_PARENT_AND_CHILDREN; } } From ccd5ef80b3c4b89b5b9cc6ce11b744ba20dd4f89 Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Mon, 9 Nov 2020 19:14:30 -0800 Subject: [PATCH 046/136] remove isActive, fix contains, maybe fix green box issue --- interface/src/Application.cpp | 2 +- .../src/avatars-renderer/Avatar.cpp | 6 ++-- .../src/avatars-renderer/SkeletonModel.cpp | 12 +++---- .../src/avatars-renderer/SkeletonModel.h | 4 +-- .../src/RenderableModelEntityItem.cpp | 31 +++++++++++++------ libraries/render-utils/src/Model.cpp | 18 +++++------ libraries/render-utils/src/Model.h | 2 -- 7 files changed, 43 insertions(+), 32 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4e6ed35d2c..8df5a17e58 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -8663,7 +8663,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/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<void()> 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/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index c9e7362e62..e7eddf70a3 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -90,7 +90,7 @@ bool RenderableModelEntityItem::needsUpdateModelBounds() const { return false; } - if (!_dimensionsInitialized || !model->isActive()) { + if (!_dimensionsInitialized || !model->isLoaded()) { return false; } @@ -699,10 +699,23 @@ int RenderableModelEntityItem::avatarJointIndex(int modelJointIndex) { bool RenderableModelEntityItem::contains(const glm::vec3& point) const { auto model = getModel(); - if (model && _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); + 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; @@ -919,13 +932,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++) { @@ -1012,7 +1025,7 @@ void RenderableModelEntityItem::copyAnimationJointDataToModel() { }); if (changed) { - locationChanged(true, true); + locationChanged(); } } @@ -1215,6 +1228,7 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint model = std::make_shared<Model>(nullptr, entity.get(), _created); connect(model.get(), &Model::requestRenderUpdate, this, &ModelEntityRenderer::requestRenderUpdate); connect(model.get(), &Model::setURLFinished, this, [&](bool didVisualGeometryRequestSucceed) { + _didLastVisualGeometryRequestSucceed = didVisualGeometryRequestSucceed; const render::ScenePointer& scene = AbstractViewStateInterface::instance()->getMain3DScene(); render::Transaction transaction; transaction.updateItem<PayloadProxyInterface>(_renderItemID, [&](PayloadProxyInterface& self) { @@ -1235,7 +1249,6 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint emit DependencyManager::get<scriptable::ModelProviderFactory>()-> modelAddedToScene(entity->getEntityItemID(), NestableType::Entity, model); } - _didLastVisualGeometryRequestSucceed = didVisualGeometryRequestSucceed; entity->_originalTexturesRead = false; entity->_needsJointSimulation = true; entity->_needsToRescaleModel = true; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 7262664ddb..1015c87038 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; } @@ -1168,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; @@ -1182,7 +1182,7 @@ glm::vec3 Model::getNaturalDimensions() const { } Extents Model::getMeshExtents() const { - if (!isActive()) { + if (!isLoaded()) { return Extents(); } const Extents& extents = getHFMModel().meshExtents; @@ -1196,7 +1196,7 @@ Extents Model::getMeshExtents() const { } Extents Model::getUnscaledMeshExtents() const { - if (!isActive()) { + if (!isLoaded()) { return Extents(); } @@ -1228,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) { @@ -1329,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) { @@ -1345,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); @@ -1426,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 diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 255d2bfc12..1e7ab55d5a 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -183,8 +183,6 @@ 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; } glm::mat4 getWorldToHFMMatrix() const; From fc40a401d70416f6cc4329a9daeca506c2d3ddcb Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Mon, 9 Nov 2020 22:37:33 -0500 Subject: [PATCH 047/136] Selection and Actions menu close with the window Bug fixed: The "Selection" and "Actions" menu now close when we close the Entity list window or the Create App. --- scripts/system/create/entityList/html/js/entityList.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index 3ff8328132..aa23784eea 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -1735,6 +1735,7 @@ function loaded() { // close context menu when switching focus to another window $(window).blur(function() { entityListContextMenu.close(); + closeAllEntityListMenu(); }); function closeAllEntityListMenu() { From 9c48acf1d332832234b897a996e05616351c4b9c Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Mon, 9 Nov 2020 23:54:39 -0500 Subject: [PATCH 048/136] Add style for last-selected Add style for last-selected --- scripts/system/html/css/edit-style.css | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 14cfe5e431..4f0a833a13 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -183,6 +183,15 @@ tr.selected + tr.selected { border-top: 1px solid #2e2e2e; } +tr.last-selected { + color: #000000; + background-color: #0064ef; +} + +tr.last-selected + tr.last-selected { + border-top: 1px solid #2e2e2e; +} + th { text-align: center; word-wrap: nowrap; From fb516cf13c0f36cbab2d27ad49e1f6a9403f957f Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 10 Nov 2020 00:01:15 -0500 Subject: [PATCH 049/136] Highlight the last selected entity in the List The last selected entity is now displayed in darker blue in the list (if present per radius search) This makes clear which entity could become the parent. (This enlights some weird behavior with the Selection, making this hazardous to figure which one was the true last selected entity. To be addressed later, it's already better now.) --- .../create/entityList/html/js/entityList.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index aa23784eea..c0b28532cb 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -188,6 +188,8 @@ let selectedEntities = []; let entityList = null; // The ListView let hmdMultiSelectMode = false; + +let lastSelectedEntity; /** * @type EntityListContextMenu */ @@ -1047,6 +1049,8 @@ function loaded() { function updateSelectedEntities(selectedIDs, autoScroll) { let notFound = false; + lastSelectedEntity = selectedIDs[selectedIDs.length - 1]; + // reset all currently selected entities and their rows first selectedEntities.forEach(function(id) { let entity = entitiesByID[id]; @@ -1066,7 +1070,11 @@ function loaded() { if (entity !== undefined) { entity.selected = true; if (entity.elRow) { - entity.elRow.className = 'selected'; + if (id === lastSelectedEntity) { + entity.elRow.className = 'last-selected'; + } else { + entity.elRow.className = 'selected'; + } } } else { notFound = true; @@ -1135,7 +1143,11 @@ function loaded() { // if this entity was previously selected flag it's row as selected if (itemData.selected) { - elRow.className = 'selected'; + if (itemData.id === lastSelectedEntity) { + elRow.className = 'last-selected'; + } else { + elRow.className = 'selected'; + } } else { elRow.className = ''; } From 696239a97b3a92abc99b1823585d1b42259dddb5 Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Mon, 9 Nov 2020 19:22:53 -0800 Subject: [PATCH 050/136] try to fix android build --- libraries/gl/src/gl/Config.cpp | 4 ++-- libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/libraries/gl/src/gl/Config.cpp b/libraries/gl/src/gl/Config.cpp index ab1dfac97c..2d6e3db8d2 100644 --- a/libraries/gl/src/gl/Config.cpp +++ b/libraries/gl/src/gl/Config.cpp @@ -96,7 +96,7 @@ void gl::initModuleGl() { wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)getGlProcessAddress("wglCreateContextAttribsARB"); #endif -#if defined(Q_OS_LINUX) +#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) QueryCurrentRendererIntegerMESA = (PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC)getGlProcessAddress("glXQueryCurrentRendererIntegerMESA"); #endif @@ -134,7 +134,7 @@ void gl::setSwapInterval(int interval) { } bool gl::queryCurrentRendererIntegerMESA(int attr, unsigned int *value) { - #if defined(Q_OS_LINUX) + #if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) if (QueryCurrentRendererIntegerMESA) { return QueryCurrentRendererIntegerMESA(attr, value); } diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp index 602ab1c320..ef247b0835 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp @@ -153,9 +153,11 @@ void GLBackend::init() { if (vendor.contains("NVIDIA") ) { qCDebug(gpugllogging) << "NVIDIA card detected"; +#if !defined(Q_OS_ANDROID) 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); +#endif qCDebug(gpugllogging) << "GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX: " << GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX; qCDebug(gpugllogging) << "GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX: " << GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX; @@ -168,7 +170,9 @@ void GLBackend::init() { } else if (vendor.contains("ATI")) { qCDebug(gpugllogging) << "ATI card detected"; +#if !defined(Q_OS_ANDROID) GL_GET_INTEGER(TEXTURE_FREE_MEMORY_ATI); +#endif _totalMemory = TEXTURE_FREE_MEMORY_ATI * BYTES_PER_KIB; _dedicatedMemory = _totalMemory; @@ -219,10 +223,14 @@ size_t GLBackend::getAvailableMemory() { switch( _videoCard ) { case NVIDIA: +#if !defined(Q_OS_ANDROID) glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &mem); +#endif return mem * BYTES_PER_KIB; case ATI: +#if !defined(Q_OS_ANDROID) glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, &mem); +#endif return mem * BYTES_PER_KIB; case MESA: return 0; // Don't know the current value From 1167ce7a1c9094823ad4045f80da9cdf4bd0b417 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 10 Nov 2020 21:56:44 -0500 Subject: [PATCH 051/136] "Teleport To Selected Entities" back to Selection This returns "Teleport To Selected Entities" back to the "Selection..." menu. After having tried a certain time what was suggested (having it under "Actions..." menu) This is clearly easy to confuse it with "Move Selected Entities to Avatar" "Teleport To Selected Entities" is about position your-self to see what you have "Selected" (which make this a Selection Tools or an assistant to it) while "Move Selected Entities to Avatar" is clearly an action. as it moves the entities to a new position. --- .../system/create/entityList/html/entityList.html | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/scripts/system/create/entityList/html/entityList.html b/scripts/system/create/entityList/html/entityList.html index 87f7f535d6..63e774c787 100644 --- a/scripts/system/create/entityList/html/entityList.html +++ b/scripts/system/create/entityList/html/entityList.html @@ -155,12 +155,6 @@ <div class = "menu-item-shortcut"></div> </div> </button> - <button class="menu-button" id="teleport-to-entity" > - <div class = "menu-item"> - <div class = "menu-item-caption">Teleport To Selected Entities</div> - <div class = "menu-item-shortcut"></div> - </div> - </button> </div> <div class="entity-list-menu" id="selection-menu" > <button class="menu-button" id="selectall" > @@ -225,6 +219,13 @@ <div class = "menu-item-shortcut"></div> </div> </button> + <div class="menu-separator"></div> + <button class="menu-button" id="teleport-to-entity" > + <div class = "menu-item"> + <div class = "menu-item-caption">Teleport To Selected Entities</div> + <div class = "menu-item-shortcut"></div> + </div> + </button> </div> <div id="menuBackgroundOverlay" ></div> </body> From 38e15b62085f8528fd4012aeba4127585379a335 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 10 Nov 2020 22:51:32 -0500 Subject: [PATCH 052/136] Bug fix: CTRL-Click was inverting the selection. Bug fix: EntityList, CTRL-Click was adding the last selected entity as the first selection the selection stack. The first selected item was systematically the last item of the selection. This was causing unpredictable results with "Parent Entities To The Last Selected". (This bug becomes evident by highlighting the "Last Selected" in the entity list. --- scripts/system/create/entityList/html/js/entityList.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index c0b28532cb..bb84f35d6d 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -770,10 +770,10 @@ function loaded() { let selectedIndex = selectedEntities.indexOf(entityID); if (selectedIndex >= 0) { selection = []; - selection = selection.concat(selectedEntities); + selection = selectedEntities.concat(selection); selection.splice(selectedIndex, 1); } else { - selection = selection.concat(selectedEntities); + selection = selectedEntities.concat(selection); } } else if (clickEvent.shiftKey && selectedEntities.length > 0) { let previousItemFound = -1; From 3b2c219e53c6ea6e753a44260bdc54a731bd95d2 Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Tue, 10 Nov 2020 21:39:15 -0800 Subject: [PATCH 053/136] possibly more robust fix? --- .../src/EntityTreeRenderer.cpp | 56 +++++++++++-------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 77c85f0255..2f9c8c4b3a 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -205,6 +205,12 @@ void EntityTreeRenderer::setupEntityScriptEngineSignals(const ScriptEnginePointe } void EntityTreeRenderer::resetPersistentEntitiesScriptEngine() { + if (_persistentEntitiesScriptEngine) { + _persistentEntitiesScriptEngine->unloadAllEntityScripts(true); + _persistentEntitiesScriptEngine->stop(); + _persistentEntitiesScriptEngine->waitTillDoneRunning(); + _persistentEntitiesScriptEngine->disconnectNonEssentialSignals(); + } _persistentEntitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, QString("about:Entities %1").arg(++_entitiesScriptEngineCount)); DependencyManager::get<ScriptEngines>()->runScriptInitializers(_persistentEntitiesScriptEngine); @@ -217,6 +223,12 @@ void EntityTreeRenderer::resetPersistentEntitiesScriptEngine() { } void EntityTreeRenderer::resetNonPersistentEntitiesScriptEngine() { + if (_nonPersistentEntitiesScriptEngine) { + _nonPersistentEntitiesScriptEngine->unloadAllEntityScripts(false); + _nonPersistentEntitiesScriptEngine->stop(); + _nonPersistentEntitiesScriptEngine->waitTillDoneRunning(); + _nonPersistentEntitiesScriptEngine->disconnectNonEssentialSignals(); + } _nonPersistentEntitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, QString("about:Entities %1").arg(++_entitiesScriptEngineCount)); DependencyManager::get<ScriptEngines>()->runScriptInitializers(_nonPersistentEntitiesScriptEngine); @@ -247,12 +259,6 @@ void EntityTreeRenderer::stopDomainAndNonOwnedEntities() { void EntityTreeRenderer::clearDomainAndNonOwnedEntities() { stopDomainAndNonOwnedEntities(); - if (_nonPersistentEntitiesScriptEngine) { - // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread - _nonPersistentEntitiesScriptEngine->unloadAllEntityScripts(true); - _nonPersistentEntitiesScriptEngine->stop(); - } - if (!_shuttingDown && _wantScripts) { resetNonPersistentEntitiesScriptEngine(); } @@ -287,21 +293,21 @@ void EntityTreeRenderer::clearDomainAndNonOwnedEntities() { void EntityTreeRenderer::clear() { leaveAllEntities(); - // unload and stop the engines - if (_nonPersistentEntitiesScriptEngine) { - // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread - _nonPersistentEntitiesScriptEngine->unloadAllEntityScripts(true); - _nonPersistentEntitiesScriptEngine->stop(); - } - if (_persistentEntitiesScriptEngine) { - // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread - _persistentEntitiesScriptEngine->unloadAllEntityScripts(true); - _persistentEntitiesScriptEngine->stop(); - } - // reset the engine auto scene = _viewState->getMain3DScene(); if (_shuttingDown) { + // unload and stop the engines + if (_nonPersistentEntitiesScriptEngine) { + // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread + _nonPersistentEntitiesScriptEngine->unloadAllEntityScripts(true); + _nonPersistentEntitiesScriptEngine->stop(); + } + if (_persistentEntitiesScriptEngine) { + // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread + _persistentEntitiesScriptEngine->unloadAllEntityScripts(true); + _persistentEntitiesScriptEngine->stop(); + } + if (scene) { render::Transaction transaction; for (const auto& entry : _entitiesInScene) { @@ -345,7 +351,7 @@ void EntityTreeRenderer::reloadEntityScripts() { for (const auto& entry : _entitiesInScene) { const auto& renderer = entry.second; const auto& entity = renderer->getEntity(); - if (!entity->getScript().isEmpty()) { + if (entity && !entity->getScript().isEmpty()) { auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; scriptEngine->loadEntityScript(entity->getEntityItemID(), resolveScriptURL(entity->getScript()), true); } @@ -696,8 +702,10 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { if (!entitiesContainingAvatar.contains(entityID)) { emit leaveEntity(entityID); auto entity = getTree()->findEntityByEntityItemID(entityID); - auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; - scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + if (entity) { + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + } } } @@ -706,8 +714,10 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { if (!_currentEntitiesInside.contains(entityID)) { emit enterEntity(entityID); auto entity = getTree()->findEntityByEntityItemID(entityID); - auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; - scriptEngine->callEntityScriptMethod(entityID, "enterEntity"); + if (entity) { + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + scriptEngine->callEntityScriptMethod(entityID, "enterEntity"); + } } } _currentEntitiesInside = entitiesContainingAvatar; From 428db065b548ddff807467b574708702840f87a8 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 11 Nov 2020 23:41:31 -0500 Subject: [PATCH 054/136] User Preference: Entity List Default Radius Add a new User Preference for the Default value of the Entity List Radius. This is available in the Edit menu. If changed, this value will be used as default Radius for the next time the script will be loaded. --- scripts/system/create/entityList/html/js/entityList.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index bb84f35d6d..c8e09e2b37 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -1679,7 +1679,11 @@ function loaded() { } else { document.getElementById("hmdmultiselect").style.display = "none"; } - } else if (data.type === "loadedColumnsSetup") { + } else if (data.type === "loadedConfigSetting") { + if (typeof(data.defaultRadius) === "number") { + elFilterRadius.value = data.defaultRadius; + onRadiusChange(); + } if (data.columnsData !== "NO_DATA" && typeof(data.columnsData) === "object") { var isValid = true; var originalColumnIDs = []; @@ -1731,7 +1735,7 @@ function loaded() { window.addEventListener("resize", updateColumnWidths); - EventBridge.emitWebEvent(JSON.stringify({ type: 'loadColumnsConfigSetting' })); + EventBridge.emitWebEvent(JSON.stringify({ type: 'loadConfigSetting' })); }); augmentSpinButtons(); From f22c7be72e9dba95cb452af5c984b613b1241417 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 11 Nov 2020 23:42:29 -0500 Subject: [PATCH 055/136] User Preference: Entity List Default Radius Add a new User Preference for the Default value of the Entity List Radius. This is available in the Edit menu. If changed, this value will be used as default Radius for the next time the script will be loaded. --- scripts/system/create/entityList/entityList.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index d8930ebc2d..58cf4ce892 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -371,14 +371,16 @@ EntityListTool = function(shouldUseEditTabletApp) { SelectionManager.teleportToEntity(); } else if (data.type === 'moveEntitySelectionToAvatar') { SelectionManager.moveEntitiesSelectionToAvatar(); - } else if (data.type === 'loadColumnsConfigSetting') { - var columnsData = Settings.getValue(SETTING_EDIT_PREFIX + SETTING_EDITOR_COLUMNS_SETUP, "NO_DATA"); + } else if (data.type === 'loadConfigSetting') { + var columnsData = Settings.getValue(SETTING_EDITOR_COLUMNS_SETUP, "NO_DATA"); + var defaultRadius = Settings.getValue(SETTING_ENTITY_LIST_DEFAULT_RADIUS, 100); emitJSONScriptEvent({ - "type": "loadedColumnsSetup", - "columnsData": columnsData + "type": "loadedConfigSetting", + "columnsData": columnsData, + "defaultRadius": defaultRadius }); } else if (data.type === 'saveColumnsConfigSetting') { - Settings.setValue(SETTING_EDIT_PREFIX + SETTING_EDITOR_COLUMNS_SETUP, data.columnsData); + Settings.setValue(SETTING_EDITOR_COLUMNS_SETUP, data.columnsData); } }; From 7bec7cbaa1adceb28a7173fd5429f6a6d99af80e Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 11 Nov 2020 23:43:49 -0500 Subject: [PATCH 056/136] User Preference: Entity List Default Radius Add a new User Preference for the Default value of the Entity List Radius. This is available in the Edit menu. If changed, this value will be used as default Radius for the next time the script will be loaded. --- scripts/system/create/edit.js | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index cd987140d8..a457b62fe6 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -155,12 +155,14 @@ var MENU_CREATE_ENTITIES_GRABBABLE = "Create Entities As Grabbable (except Zones var MENU_ALLOW_SELECTION_LARGE = "Allow Selecting of Large Models"; var MENU_ALLOW_SELECTION_SMALL = "Allow Selecting of Small Models"; var MENU_ALLOW_SELECTION_LIGHTS = "Allow Selecting of Lights"; +var MENU_ENTITY_LIST_DEFAULT_RADIUS = "Entity List Default Radius"; var SETTING_AUTO_FOCUS_ON_SELECT = "autoFocusOnSelect"; var SETTING_EASE_ON_FOCUS = "cameraEaseOnFocus"; var SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE = "showLightsAndParticlesInEditMode"; var SETTING_SHOW_ZONES_IN_EDIT_MODE = "showZonesInEditMode"; var SETTING_EDITOR_COLUMNS_SETUP = "editorColumnsSetup"; +var SETTING_ENTITY_LIST_DEFAULT_RADIUS = "entityListDefaultRadius"; var SETTING_EDIT_PREFIX = "Edit/"; @@ -1509,6 +1511,11 @@ function setupModelMenus() { isCheckable: true, isChecked: Settings.getValue(SETTING_SHOW_ZONES_IN_EDIT_MODE) !== "false" }); + Menu.addMenuItem({ + menuName: "Edit", + menuItemName: MENU_ENTITY_LIST_DEFAULT_RADIUS, + afterItem: MENU_SHOW_ZONES_IN_EDIT_MODE + }); Entities.setLightsArePickable(false); } @@ -1542,6 +1549,7 @@ function cleanupModelMenus() { Menu.removeMenuItem("Edit", MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE); Menu.removeMenuItem("Edit", MENU_SHOW_ZONES_IN_EDIT_MODE); Menu.removeMenuItem("Edit", MENU_CREATE_ENTITIES_GRABBABLE); + Menu.removeMenuItem("Edit", MENU_ENTITY_LIST_DEFAULT_RADIUS); } Script.scriptEnding.connect(function () { @@ -1882,6 +1890,17 @@ function onPromptTextChanged(prompt) { } } +function onPromptTextChangedDefaultRadiusUserPref(prompt) { + Window.promptTextChanged.disconnect(onPromptTextChangedDefaultRadiusUserPref); + if (prompt !== "") { + var radius = parseInt(prompt); + if (radius < 0 || isNaN(radius)){ + radius = 100; + } + Settings.setValue(SETTING_ENTITY_LIST_DEFAULT_RADIUS, radius); + } +} + function handleMenuEvent(menuItem) { if (menuItem === "Allow Selecting of Small Models") { allowSmallModels = Menu.isOptionChecked("Allow Selecting of Small Models"); @@ -1912,7 +1931,7 @@ function handleMenuEvent(menuItem) { Window.browseAsync("Select Model to Import", "", "*.json"); } else { Window.promptTextChanged.connect(onPromptTextChanged); - Window.promptAsync("URL of SVO to import", ""); + Window.promptAsync("URL of a .json to import", ""); } } else if (menuItem === "Select All Entities In Box") { selectAllEntitiesInCurrentSelectionBox(false); @@ -1924,6 +1943,9 @@ function handleMenuEvent(menuItem) { Entities.setDrawZoneBoundaries(isActive && Menu.isOptionChecked(MENU_SHOW_ZONES_IN_EDIT_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)); } tooltip.show(false); } From ce8b9d4b246179c5fcac08df1315fbd06fa3f905 Mon Sep 17 00:00:00 2001 From: Maki <mxmcube@gmail.com> Date: Thu, 3 Sep 2020 18:50:36 +0100 Subject: [PATCH 057/136] Deleted old GLWidget code that breaks alt with current Qt on Linux --- libraries/gl/src/gl/GLWidget.cpp | 38 -------------------------------- libraries/gl/src/gl/GLWidget.h | 3 --- 2 files changed, 41 deletions(-) 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<QKeyEvent*>(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<MSG*>(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 }; From 636d52b306ab5e6de49eb5eca6d700ce997a9bdb Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Thu, 12 Nov 2020 23:48:15 -0500 Subject: [PATCH 058/136] =?UTF-8?q?Add=20=E2=80=9CImport=20Entities=20(.js?= =?UTF-8?q?on)=20from=20a=20URL=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The action “Import Entities (.json) from a URL” has been added to the “Create” Tab. (It was available only in the Edit menu.) --- scripts/system/create/qml/EditTabView.qml | 25 ++++++++++++++++--- .../system/create/qml/EditToolsTabView.qml | 25 ++++++++++++++++--- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/scripts/system/create/qml/EditTabView.qml b/scripts/system/create/qml/EditTabView.qml index 53f6068424..617cdd9e5a 100644 --- a/scripts/system/create/qml/EditTabView.qml +++ b/scripts/system/create/qml/EditTabView.qml @@ -201,11 +201,11 @@ TabBar { HifiControls.Button { id: importButton - text: "Import Entities (.json)" + text: "Import Entities (.json) from a File" color: hifi.buttons.black colorScheme: hifi.colorSchemes.dark - anchors.right: parent.right - anchors.rightMargin: 30 + anchors.right: parent.horizontalCenter + anchors.rightMargin: 10 anchors.left: parent.left anchors.leftMargin: 30 anchors.top: assetServerButton.bottom @@ -217,6 +217,25 @@ TabBar { }); } } + + HifiControls.Button { + id: importButtonFromUrl + text: "Import Entities (.json) from a URL" + color: hifi.buttons.black + colorScheme: hifi.colorSchemes.dark + anchors.right: parent.right + anchors.rightMargin: 30 + anchors.left: parent.horizontalCenter + anchors.leftMargin: 10 + anchors.top: assetServerButton.bottom + anchors.topMargin: 20 + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", + params: { buttonName: "importEntitiesFromUrlButton" } + }); + } + } } } // Flickable } diff --git a/scripts/system/create/qml/EditToolsTabView.qml b/scripts/system/create/qml/EditToolsTabView.qml index 0ce8d8e8d4..8379b47259 100644 --- a/scripts/system/create/qml/EditToolsTabView.qml +++ b/scripts/system/create/qml/EditToolsTabView.qml @@ -207,11 +207,11 @@ TabBar { HifiControls.Button { id: importButton - text: "Import Entities (.json)" + text: "Import Entities (.json) from a File" color: hifi.buttons.black colorScheme: hifi.colorSchemes.dark - anchors.right: parent.right - anchors.rightMargin: 55 + anchors.right: parent.horizontalCenter + anchors.rightMargin: 10 anchors.left: parent.left anchors.leftMargin: 55 anchors.top: assetServerButton.bottom @@ -223,6 +223,25 @@ TabBar { }); } } + + HifiControls.Button { + id: importButtonFromUrl + text: "Import Entities (.json) from a URL" + color: hifi.buttons.black + colorScheme: hifi.colorSchemes.dark + anchors.right: parent.right + anchors.rightMargin: 55 + anchors.left: parent.horizontalCenter + anchors.leftMargin: 10 + anchors.top: assetServerButton.bottom + anchors.topMargin: 20 + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", + params: { buttonName: "importEntitiesFromUrlButton" } + }); + } + } } } // Flickable } From e0cac2b95cac384b1c91e9e7cbbf1fd664412e96 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Thu, 12 Nov 2020 23:52:24 -0500 Subject: [PATCH 059/136] Clean up of the Edit Menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Create App. Menu Items under the “Edit” menu have been cleaned up. All the actions being transferred has been removed. (some was not even decently usable from there) A new sub-menu “Create Application – Preferences” has been implemented to regroup the remaining menu items that are all User Preferences. Eventually in the future, these might be moved to the Create App. UI. For now, it will be OK, it's already cleaner. --- scripts/system/create/edit.js | 160 ++++++++-------------------------- 1 file changed, 35 insertions(+), 125 deletions(-) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index a457b62fe6..099cb94988 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -146,11 +146,11 @@ var DEFAULT_DIMENSIONS = { var DEFAULT_LIGHT_DIMENSIONS = Vec3.multiply(20, DEFAULT_DIMENSIONS); +var SUBMENU_ENTITY_EDITOR_PREFERENCES = "Edit > Create Application - 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_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"; @@ -270,8 +270,6 @@ function adjustPositionPerBoundingBox(position, direction, registration, dimensi return position; } -var GRABBABLE_ENTITIES_MENU_CATEGORY = "Edit"; - // Handles any edit mode updates required when domains have switched function checkEditPermissionsAndUpdate() { if ((createButton === null) || (createButton === undefined)) { @@ -881,7 +879,12 @@ var toolBar = (function () { addButton("importEntitiesButton", function() { Window.browseChanged.connect(onFileOpenChanged); - Window.browseAsync("Select Model to Import", "", "*.json"); + Window.browseAsync("Select .json to Import", "", "*.json"); + }); + + addButton("importEntitiesFromUrlButton", function() { + Window.promptTextChanged.connect(onPromptTextChanged); + Window.promptAsync("URL of a .json to import", ""); }); addButton("openAssetBrowserButton", function() { @@ -1381,11 +1384,9 @@ Controller.mouseReleaseEvent.connect(mouseReleaseEvent); // In order for editVoxels and editModels to play nice together, they each check to see if a "delete" menu item already // exists. If it doesn't they add it. If it does they don't. They also only delete the menu item if they were the one that // added it. -var modelMenuAddedDelete = false; var originalLightsArePickable = Entities.getLightsArePickable(); function setupModelMenus() { - // adj our menuitems Menu.addMenuItem({ menuName: "Edit", menuItemName: "Undo", @@ -1399,120 +1400,66 @@ function setupModelMenus() { position: 1, }); - Menu.addMenuItem({ - menuName: "Edit", - menuItemName: "Entities", - isSeparator: true - }); - if (!Menu.menuItemExists("Edit", "Delete")) { - Menu.addMenuItem({ - menuName: "Edit", - menuItemName: "Delete", - shortcutKeyEvent: { - text: "delete" - }, - afterItem: "Entities", - }); - modelMenuAddedDelete = true; - } + Menu.addMenu(SUBMENU_ENTITY_EDITOR_PREFERENCES); Menu.addMenuItem({ - menuName: "Edit", - menuItemName: "Parent Entity to Last", - afterItem: "Entities" - }); - - Menu.addMenuItem({ - menuName: "Edit", - menuItemName: "Unparent Entity", - afterItem: "Parent Entity to Last" - }); - - Menu.addMenuItem({ - menuName: GRABBABLE_ENTITIES_MENU_CATEGORY, + menuName: SUBMENU_ENTITY_EDITOR_PREFERENCES, menuItemName: MENU_CREATE_ENTITIES_GRABBABLE, - afterItem: "Unparent Entity", + position: 0, isCheckable: true, isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_CREATE_ENTITIES_GRABBABLE, false) }); - Menu.addMenuItem({ - menuName: "Edit", + menuName: SUBMENU_ENTITY_EDITOR_PREFERENCES, menuItemName: MENU_ALLOW_SELECTION_LARGE, afterItem: MENU_CREATE_ENTITIES_GRABBABLE, isCheckable: true, isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_LARGE, true) }); Menu.addMenuItem({ - menuName: "Edit", + menuName: SUBMENU_ENTITY_EDITOR_PREFERENCES, menuItemName: MENU_ALLOW_SELECTION_SMALL, afterItem: MENU_ALLOW_SELECTION_LARGE, isCheckable: true, isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_SMALL, true) }); Menu.addMenuItem({ - menuName: "Edit", + menuName: SUBMENU_ENTITY_EDITOR_PREFERENCES, menuItemName: MENU_ALLOW_SELECTION_LIGHTS, afterItem: MENU_ALLOW_SELECTION_SMALL, isCheckable: true, isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_LIGHTS, false) }); Menu.addMenuItem({ - menuName: "Edit", - menuItemName: "Select All Entities In Box", - afterItem: "Allow Selecting of Lights" - }); - Menu.addMenuItem({ - menuName: "Edit", - menuItemName: "Select All Entities Touching Box", - afterItem: "Select All Entities In Box" - }); - - Menu.addMenuItem({ - menuName: "Edit", - menuItemName: "Export Entities", - afterItem: "Entities" - }); - Menu.addMenuItem({ - menuName: "Edit", - menuItemName: "Import Entities", - afterItem: "Export Entities" - }); - Menu.addMenuItem({ - menuName: "Edit", - menuItemName: "Import Entities from URL", - afterItem: "Import Entities" - }); - - Menu.addMenuItem({ - menuName: "Edit", + menuName: SUBMENU_ENTITY_EDITOR_PREFERENCES, menuItemName: MENU_AUTO_FOCUS_ON_SELECT, + afterItem: MENU_ALLOW_SELECTION_LIGHTS, isCheckable: true, isChecked: Settings.getValue(SETTING_AUTO_FOCUS_ON_SELECT) === "true" }); Menu.addMenuItem({ - menuName: "Edit", + menuName: SUBMENU_ENTITY_EDITOR_PREFERENCES, menuItemName: MENU_EASE_ON_FOCUS, afterItem: MENU_AUTO_FOCUS_ON_SELECT, isCheckable: true, isChecked: Settings.getValue(SETTING_EASE_ON_FOCUS) === "true" }); Menu.addMenuItem({ - menuName: "Edit", + menuName: SUBMENU_ENTITY_EDITOR_PREFERENCES, menuItemName: MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE, afterItem: MENU_EASE_ON_FOCUS, isCheckable: true, isChecked: Settings.getValue(SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE) !== "false" }); Menu.addMenuItem({ - menuName: "Edit", + 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: "Edit", + menuName: SUBMENU_ENTITY_EDITOR_PREFERENCES, menuItemName: MENU_ENTITY_LIST_DEFAULT_RADIUS, afterItem: MENU_SHOW_ZONES_IN_EDIT_MODE }); @@ -1526,30 +1473,16 @@ function cleanupModelMenus() { Menu.removeMenuItem("Edit", "Undo"); Menu.removeMenuItem("Edit", "Redo"); - Menu.removeSeparator("Edit", "Entities"); - if (modelMenuAddedDelete) { - // delete our menuitems - Menu.removeMenuItem("Edit", "Delete"); - } - - Menu.removeMenuItem("Edit", "Parent Entity to Last"); - Menu.removeMenuItem("Edit", "Unparent Entity"); - Menu.removeMenuItem("Edit", "Allow Selecting of Large Models"); - Menu.removeMenuItem("Edit", "Allow Selecting of Small Models"); - Menu.removeMenuItem("Edit", "Allow Selecting of Lights"); - Menu.removeMenuItem("Edit", "Select All Entities In Box"); - Menu.removeMenuItem("Edit", "Select All Entities Touching Box"); - - Menu.removeMenuItem("Edit", "Export Entities"); - Menu.removeMenuItem("Edit", "Import Entities"); - Menu.removeMenuItem("Edit", "Import Entities from URL"); - - Menu.removeMenuItem("Edit", MENU_AUTO_FOCUS_ON_SELECT); - Menu.removeMenuItem("Edit", MENU_EASE_ON_FOCUS); - Menu.removeMenuItem("Edit", MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE); - Menu.removeMenuItem("Edit", MENU_SHOW_ZONES_IN_EDIT_MODE); - Menu.removeMenuItem("Edit", MENU_CREATE_ENTITIES_GRABBABLE); - Menu.removeMenuItem("Edit", MENU_ENTITY_LIST_DEFAULT_RADIUS); + Menu.removeMenuItem(SUBMENU_ENTITY_EDITOR_PREFERENCES, MENU_ALLOW_SELECTION_LARGE); + Menu.removeMenuItem(SUBMENU_ENTITY_EDITOR_PREFERENCES, MENU_ALLOW_SELECTION_SMALL); + 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_CREATE_ENTITIES_GRABBABLE); + Menu.removeMenuItem(SUBMENU_ENTITY_EDITOR_PREFERENCES, MENU_ENTITY_LIST_DEFAULT_RADIUS); + Menu.removeMenu(SUBMENU_ENTITY_EDITOR_PREFERENCES); } Script.scriptEnding.connect(function () { @@ -1902,41 +1835,18 @@ function onPromptTextChangedDefaultRadiusUserPref(prompt) { } function handleMenuEvent(menuItem) { - if (menuItem === "Allow Selecting of Small Models") { - allowSmallModels = Menu.isOptionChecked("Allow Selecting of Small Models"); - } else if (menuItem === "Allow Selecting of Large Models") { - allowLargeModels = Menu.isOptionChecked("Allow Selecting of Large Models"); - } else if (menuItem === "Allow Selecting of Lights") { - Entities.setLightsArePickable(Menu.isOptionChecked("Allow Selecting of Lights")); + if (menuItem === MENU_ALLOW_SELECTION_SMALL) { + allowSmallModels = Menu.isOptionChecked(MENU_ALLOW_SELECTION_SMALL); + } else if (menuItem === MENU_ALLOW_SELECTION_LARGE) { + allowLargeModels = Menu.isOptionChecked(MENU_ALLOW_SELECTION_LARGE); + } else if (menuItem === MENU_ALLOW_SELECTION_LIGHTS) { + Entities.setLightsArePickable(Menu.isOptionChecked(MENU_ALLOW_SELECTION_LIGHTS)); } else if (menuItem === "Delete") { deleteSelectedEntities(); } else if (menuItem === "Undo") { undoHistory.undo(); } else if (menuItem === "Redo") { undoHistory.redo(); - } else if (menuItem === "Parent Entity to Last") { - parentSelectedEntities(); - } else if (menuItem === "Unparent Entity") { - unparentSelectedEntities(); - } else if (menuItem === "Export Entities") { - if (!selectionManager.hasSelection()) { - Window.notifyEditError("No entities have been selected."); - } else { - Window.saveFileChanged.connect(onFileSaveChanged); - Window.saveAsync("Select Where to Save", "", "*.json"); - } - } else if (menuItem === "Import Entities" || menuItem === "Import Entities from URL") { - if (menuItem === "Import Entities") { - Window.browseChanged.connect(onFileOpenChanged); - Window.browseAsync("Select Model to Import", "", "*.json"); - } else { - Window.promptTextChanged.connect(onPromptTextChanged); - Window.promptAsync("URL of a .json to import", ""); - } - } else if (menuItem === "Select All Entities In Box") { - selectAllEntitiesInCurrentSelectionBox(false); - } else if (menuItem === "Select All Entities Touching Box") { - selectAllEntitiesInCurrentSelectionBox(true); } 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) { From 2194a20d347bdb1d7a6b9135a74fa74a25eccb05 Mon Sep 17 00:00:00 2001 From: Dale Glass <dale@daleglass.net> Date: Sat, 14 Nov 2020 18:55:24 +0100 Subject: [PATCH 060/136] Upgrade to latest TBB --- cmake/ports/tbb/portfile.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/ports/tbb/portfile.cmake b/cmake/ports/tbb/portfile.cmake index 4e81df37d1..2e2e78abde 100644 --- a/cmake/ports/tbb/portfile.cmake +++ b/cmake/ports/tbb/portfile.cmake @@ -3,7 +3,7 @@ include(vcpkg_common_functions) vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH REPO oneapi-src/oneTBB - REF 4bdba61bafc6ba2d636f31564f1de5702d365cf7 + REF eca91f16d7490a8abfdee652dadf457ec820cc37 SHA512 f2a8d7e0476f846039390f4a79af3fe13770e23b01bf4741e738136f7ddb401357a0e50f35212e8d0fa5fc4cf1563418337309227d7243fc3676edd406ae652d HEAD_REF tbb_2019 PATCHES fix-static-build.patch From 8e2245c530293b5aaf6fc1ef2583fde1519edc5c Mon Sep 17 00:00:00 2001 From: Dale Glass <dale@daleglass.net> Date: Sat, 14 Nov 2020 19:00:53 +0100 Subject: [PATCH 061/136] Update hash --- cmake/ports/tbb/portfile.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/ports/tbb/portfile.cmake b/cmake/ports/tbb/portfile.cmake index 2e2e78abde..76c881833f 100644 --- a/cmake/ports/tbb/portfile.cmake +++ b/cmake/ports/tbb/portfile.cmake @@ -4,7 +4,7 @@ vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH REPO oneapi-src/oneTBB REF eca91f16d7490a8abfdee652dadf457ec820cc37 - SHA512 f2a8d7e0476f846039390f4a79af3fe13770e23b01bf4741e738136f7ddb401357a0e50f35212e8d0fa5fc4cf1563418337309227d7243fc3676edd406ae652d + SHA512 7144e1dc68304b5358e6ea330431b6f0c61fadb147efa353a5b242777d6fabf7b8cf99b79cffb51b49b911dd17a9f1879619d6eebdf319f23ec3235c89cffc25 HEAD_REF tbb_2019 PATCHES fix-static-build.patch ) From 33eb01a6c7bedb1da6b3041125dcdebe93db4d3a Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sat, 14 Nov 2020 22:33:38 -0500 Subject: [PATCH 062/136] Minor code adjustments Minor code adjustments --- scripts/system/create/entityList/html/entityList.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/create/entityList/html/entityList.html b/scripts/system/create/entityList/html/entityList.html index 63e774c787..a5f27bd3a8 100644 --- a/scripts/system/create/entityList/html/entityList.html +++ b/scripts/system/create/entityList/html/entityList.html @@ -225,7 +225,7 @@ <div class = "menu-item-caption">Teleport To Selected Entities</div> <div class = "menu-item-shortcut"></div> </div> - </button> + </button> </div> <div id="menuBackgroundOverlay" ></div> </body> From 2475deac930db55752f5ac7188dbe6be29c0b9e5 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sat, 14 Nov 2020 22:36:28 -0500 Subject: [PATCH 063/136] Minor code adjustments Minor code adjustments --- scripts/system/create/entityList/html/js/entityList.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index c8e09e2b37..89eac5fb2f 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -1714,9 +1714,9 @@ function loaded() { let currentColumnIndex = originalColumnIDs.indexOf(data.columnsData[columnIndex].columnID); if (currentColumnIndex !== -1 && columnIndex !== currentColumnIndex) { for (var i = currentColumnIndex; i > columnIndex; i--) { - swapColumns(i-1, i); - var swappedContent = originalColumnIDs[i-1]; - originalColumnIDs[i-1] = originalColumnIDs[i]; + swapColumns(i - 1, i); + var swappedContent = originalColumnIDs[i - 1]; + originalColumnIDs[i - 1] = originalColumnIDs[i]; originalColumnIDs[i] = swappedContent; } } From da2737de530d5a91550116d38ea3215f01cd8d15 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sat, 14 Nov 2020 22:39:47 -0500 Subject: [PATCH 064/136] Minor Code Adjustements Minor Code Adjustements --- scripts/system/create/qml/EditToolsTabView.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/qml/EditToolsTabView.qml b/scripts/system/create/qml/EditToolsTabView.qml index 8379b47259..2403604342 100644 --- a/scripts/system/create/qml/EditToolsTabView.qml +++ b/scripts/system/create/qml/EditToolsTabView.qml @@ -211,7 +211,7 @@ TabBar { color: hifi.buttons.black colorScheme: hifi.colorSchemes.dark anchors.right: parent.horizontalCenter - anchors.rightMargin: 10 + anchors.rightMargin: 10 anchors.left: parent.left anchors.leftMargin: 55 anchors.top: assetServerButton.bottom @@ -241,7 +241,7 @@ TabBar { params: { buttonName: "importEntitiesFromUrlButton" } }); } - } + } } } // Flickable } From 06f7624512707d55bec1afc8b375405e7a525131 Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Sat, 14 Nov 2020 22:34:03 -0800 Subject: [PATCH 065/136] some more small improvements --- .../entities-renderer/src/RenderableModelEntityItem.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index e7eddf70a3..392d2a748c 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1252,7 +1252,6 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint entity->_originalTexturesRead = false; entity->_needsJointSimulation = true; entity->_needsToRescaleModel = true; - entity->updateModelBounds(); emit requestRenderUpdate(); }); scene->enqueueTransaction(transaction); @@ -1271,7 +1270,6 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint // Nothing else to do unless the model is loaded if (!model->isLoaded()) { - emit requestRenderUpdate(); return; } @@ -1295,10 +1293,11 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint entity->_originalTexturesRead = true; } - if (_textures != entity->getTextures()) { + auto textures = entity->getTextures(); + if (_textures != textures) { QVariantMap newTextures; _texturesLoaded = false; - _textures = entity->getTextures(); + _textures = textures; newTextures = parseTexturesToMap(_textures, entity->_originalTextures); model->setTextures(newTextures); } From 21f8eac9362ad36e151ab8b24f1b5f59807ebddc Mon Sep 17 00:00:00 2001 From: kasenvr <52365539+kasenvr@users.noreply.github.com> Date: Mon, 16 Nov 2020 22:35:46 -0500 Subject: [PATCH 066/136] Revert "Split Local and owned Avatar Entity scripts into their own ScriptEngine" --- .../src/scripts/EntityScriptServer.cpp | 4 +- .../src/EntityTreeRenderer.cpp | 230 +++++++----------- .../src/EntityTreeRenderer.h | 9 +- .../entities/src/EntityScriptingInterface.cpp | 34 +-- .../entities/src/EntityScriptingInterface.h | 15 +- 5 files changed, 109 insertions(+), 183 deletions(-) diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index 16931e8c26..065ab12abc 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -470,9 +470,7 @@ void EntityScriptServer::resetEntitiesScriptEngine() { scriptEngines->runScriptInitializers(newEngine); newEngine->runInThread(); auto newEngineSP = qSharedPointerCast<EntitiesScriptEngineProvider>(newEngine); - // On the entity script server, these are the same - DependencyManager::get<EntityScriptingInterface>()->setPersistentEntitiesScriptEngine(newEngineSP); - DependencyManager::get<EntityScriptingInterface>()->setNonPersistentEntitiesScriptEngine(newEngineSP); + DependencyManager::get<EntityScriptingInterface>()->setEntitiesScriptEngine(newEngineSP); if (_entitiesScriptEngine) { disconnect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptDetailsUpdated, diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 2f9c8c4b3a..3538f07d32 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -158,98 +158,79 @@ render::ItemID EntityTreeRenderer::renderableIdForEntityId(const EntityItemID& i int EntityTreeRenderer::_entitiesScriptEngineCount = 0; -void EntityTreeRenderer::setupEntityScriptEngineSignals(const ScriptEnginePointer& scriptEngine) { +void EntityTreeRenderer::resetEntitiesScriptEngine() { + _entitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, + QString("about:Entities %1").arg(++_entitiesScriptEngineCount)); + DependencyManager::get<ScriptEngines>()->runScriptInitializers(_entitiesScriptEngine); + _entitiesScriptEngine->runInThread(); + auto entitiesScriptEngineProvider = qSharedPointerCast<EntitiesScriptEngineProvider>(_entitiesScriptEngine); auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); + entityScriptingInterface->setEntitiesScriptEngine(entitiesScriptEngineProvider); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - scriptEngine->callEntityScriptMethod(entityID, "mousePressOnEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseDoublePressOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - scriptEngine->callEntityScriptMethod(entityID, "mouseDoublePressOnEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - scriptEngine->callEntityScriptMethod(entityID, "mouseMoveOnEntity", event); - // FIXME: this is a duplicate of mouseMoveOnEntity, but it seems like some scripts might use this naming - scriptEngine->callEntityScriptMethod(entityID, "mouseMoveEvent", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - scriptEngine->callEntityScriptMethod(entityID, "mouseReleaseOnEntity", event); - }); - - connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - scriptEngine->callEntityScriptMethod(entityID, "clickDownOnEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::holdingClickOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - scriptEngine->callEntityScriptMethod(entityID, "holdingClickOnEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickReleaseOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - scriptEngine->callEntityScriptMethod(entityID, "clickReleaseOnEntity", event); - }); - - connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - scriptEngine->callEntityScriptMethod(entityID, "hoverEnterEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - scriptEngine->callEntityScriptMethod(entityID, "hoverOverEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - scriptEngine->callEntityScriptMethod(entityID, "hoverLeaveEntity", event); - }); - - connect(scriptEngine.data(), &ScriptEngine::entityScriptPreloadFinished, [&](const EntityItemID& entityID) { + connect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptPreloadFinished, [&](const EntityItemID& entityID) { EntityItemPointer entity = getTree()->findEntityByID(entityID); if (entity) { entity->setScriptHasFinishedPreload(true); } }); -} -void EntityTreeRenderer::resetPersistentEntitiesScriptEngine() { - if (_persistentEntitiesScriptEngine) { - _persistentEntitiesScriptEngine->unloadAllEntityScripts(true); - _persistentEntitiesScriptEngine->stop(); - _persistentEntitiesScriptEngine->waitTillDoneRunning(); - _persistentEntitiesScriptEngine->disconnectNonEssentialSignals(); + // Connect mouse events to entity script callbacks + if (!_mouseAndPreloadSignalHandlersConnected) { + + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "mousePressOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseDoublePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseDoublePressOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveOnEntity", event); + // FIXME: this is a duplicate of mouseMoveOnEntity, but it seems like some scripts might use this naming + _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveEvent", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseReleaseOnEntity", event); + }); + + connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "clickDownOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::holdingClickOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "holdingClickOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "clickReleaseOnEntity", event); + }); + + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverEnterEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverOverEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverLeaveEntity", event); + }); + + _mouseAndPreloadSignalHandlersConnected = true; } - _persistentEntitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, - QString("about:Entities %1").arg(++_entitiesScriptEngineCount)); - DependencyManager::get<ScriptEngines>()->runScriptInitializers(_persistentEntitiesScriptEngine); - _persistentEntitiesScriptEngine->runInThread(); - auto entitiesScriptEngineProvider = qSharedPointerCast<EntitiesScriptEngineProvider>(_persistentEntitiesScriptEngine); - auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); - entityScriptingInterface->setPersistentEntitiesScriptEngine(entitiesScriptEngineProvider); - - setupEntityScriptEngineSignals(_persistentEntitiesScriptEngine); -} - -void EntityTreeRenderer::resetNonPersistentEntitiesScriptEngine() { - if (_nonPersistentEntitiesScriptEngine) { - _nonPersistentEntitiesScriptEngine->unloadAllEntityScripts(false); - _nonPersistentEntitiesScriptEngine->stop(); - _nonPersistentEntitiesScriptEngine->waitTillDoneRunning(); - _nonPersistentEntitiesScriptEngine->disconnectNonEssentialSignals(); - } - _nonPersistentEntitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, - QString("about:Entities %1").arg(++_entitiesScriptEngineCount)); - DependencyManager::get<ScriptEngines>()->runScriptInitializers(_nonPersistentEntitiesScriptEngine); - _nonPersistentEntitiesScriptEngine->runInThread(); - auto entitiesScriptEngineProvider = qSharedPointerCast<EntitiesScriptEngineProvider>(_nonPersistentEntitiesScriptEngine); - DependencyManager::get<EntityScriptingInterface>()->setNonPersistentEntitiesScriptEngine(entitiesScriptEngineProvider); - - setupEntityScriptEngineSignals(_nonPersistentEntitiesScriptEngine); } void EntityTreeRenderer::stopDomainAndNonOwnedEntities() { leaveDomainAndNonOwnedEntities(); // unload and stop the engine - if (_nonPersistentEntitiesScriptEngine) { - QList<EntityItemID> entitiesWithEntityScripts = _nonPersistentEntitiesScriptEngine->getListOfEntityScriptIDs(); + if (_entitiesScriptEngine) { + QList<EntityItemID> entitiesWithEntityScripts = _entitiesScriptEngine->getListOfEntityScriptIDs(); - foreach (const EntityItemID& entityID, entitiesWithEntityScripts) { + foreach (const EntityItemID& entityID, entitiesWithEntityScripts) { EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID); + if (entityItem && !entityItem->getScript().isEmpty()) { if (!(entityItem->isLocalEntity() || entityItem->isMyAvatarEntity())) { - _nonPersistentEntitiesScriptEngine->unloadEntityScript(entityID, true); + if (_currentEntitiesInside.contains(entityID)) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + } + _entitiesScriptEngine->unloadEntityScript(entityID, true); } } } @@ -259,10 +240,6 @@ void EntityTreeRenderer::stopDomainAndNonOwnedEntities() { void EntityTreeRenderer::clearDomainAndNonOwnedEntities() { stopDomainAndNonOwnedEntities(); - if (!_shuttingDown && _wantScripts) { - resetNonPersistentEntitiesScriptEngine(); - } - std::unordered_map<EntityItemID, EntityRendererPointer> savedEntities; std::unordered_set<EntityRendererPointer> savedRenderables; // remove all entities from the scene @@ -292,22 +269,16 @@ void EntityTreeRenderer::clearDomainAndNonOwnedEntities() { void EntityTreeRenderer::clear() { leaveAllEntities(); + // unload and stop the engine + if (_entitiesScriptEngine) { + // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread + _entitiesScriptEngine->unloadAllEntityScripts(true); + _entitiesScriptEngine->stop(); + } // reset the engine auto scene = _viewState->getMain3DScene(); if (_shuttingDown) { - // unload and stop the engines - if (_nonPersistentEntitiesScriptEngine) { - // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread - _nonPersistentEntitiesScriptEngine->unloadAllEntityScripts(true); - _nonPersistentEntitiesScriptEngine->stop(); - } - if (_persistentEntitiesScriptEngine) { - // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread - _persistentEntitiesScriptEngine->unloadAllEntityScripts(true); - _persistentEntitiesScriptEngine->stop(); - } - if (scene) { render::Transaction transaction; for (const auto& entry : _entitiesInScene) { @@ -318,8 +289,7 @@ void EntityTreeRenderer::clear() { } } else { if (_wantScripts) { - resetPersistentEntitiesScriptEngine(); - resetNonPersistentEntitiesScriptEngine(); + resetEntitiesScriptEngine(); } if (scene) { for (const auto& entry : _entitiesInScene) { @@ -343,17 +313,13 @@ void EntityTreeRenderer::clear() { } void EntityTreeRenderer::reloadEntityScripts() { - _persistentEntitiesScriptEngine->unloadAllEntityScripts(); - _persistentEntitiesScriptEngine->resetModuleCache(); - _nonPersistentEntitiesScriptEngine->unloadAllEntityScripts(); - _nonPersistentEntitiesScriptEngine->resetModuleCache(); - + _entitiesScriptEngine->unloadAllEntityScripts(); + _entitiesScriptEngine->resetModuleCache(); for (const auto& entry : _entitiesInScene) { const auto& renderer = entry.second; const auto& entity = renderer->getEntity(); - if (entity && !entity->getScript().isEmpty()) { - auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; - scriptEngine->loadEntityScript(entity->getEntityItemID(), resolveScriptURL(entity->getScript()), true); + if (!entity->getScript().isEmpty()) { + _entitiesScriptEngine->loadEntityScript(entity->getEntityItemID(), resolveScriptURL(entity->getScript()), true); } } } @@ -363,8 +329,7 @@ void EntityTreeRenderer::init() { EntityTreePointer entityTree = std::static_pointer_cast<EntityTree>(_tree); if (_wantScripts) { - resetPersistentEntitiesScriptEngine(); - resetNonPersistentEntitiesScriptEngine(); + resetEntitiesScriptEngine(); } forceRecheckEntities(); // setup our state to force checking our inside/outsideness of entities @@ -376,11 +341,8 @@ void EntityTreeRenderer::init() { } void EntityTreeRenderer::shutdown() { - if (_persistentEntitiesScriptEngine) { - _persistentEntitiesScriptEngine->disconnectNonEssentialSignals(); // disconnect all slots/signals from the script engine, except essential - } - if (_nonPersistentEntitiesScriptEngine) { - _nonPersistentEntitiesScriptEngine->disconnectNonEssentialSignals(); // disconnect all slots/signals from the script engine, except essential + if (_entitiesScriptEngine) { + _entitiesScriptEngine->disconnectNonEssentialSignals(); // disconnect all slots/signals from the script engine, except essential } _shuttingDown = true; @@ -696,16 +658,12 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { // EntityItemIDs from here. The callEntityScriptMethod() method is robust against attempting to call scripts // for entity IDs that no longer exist. - if (_persistentEntitiesScriptEngine && _nonPersistentEntitiesScriptEngine) { + if (_entitiesScriptEngine) { // for all of our previous containing entities, if they are no longer containing then send them a leave event foreach(const EntityItemID& entityID, _currentEntitiesInside) { if (!entitiesContainingAvatar.contains(entityID)) { emit leaveEntity(entityID); - auto entity = getTree()->findEntityByEntityItemID(entityID); - if (entity) { - auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; - scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); - } + _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); } } @@ -713,11 +671,7 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { foreach(const EntityItemID& entityID, entitiesContainingAvatar) { if (!_currentEntitiesInside.contains(entityID)) { emit enterEntity(entityID); - auto entity = getTree()->findEntityByEntityItemID(entityID); - if (entity) { - auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; - scriptEngine->callEntityScriptMethod(entityID, "enterEntity"); - } + _entitiesScriptEngine->callEntityScriptMethod(entityID, "enterEntity"); } } _currentEntitiesInside = entitiesContainingAvatar; @@ -733,8 +687,8 @@ void EntityTreeRenderer::leaveDomainAndNonOwnedEntities() { EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID); if (entityItem && !(entityItem->isLocalEntity() || entityItem->isMyAvatarEntity())) { emit leaveEntity(entityID); - if (_nonPersistentEntitiesScriptEngine) { - _nonPersistentEntitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + if (_entitiesScriptEngine) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); } } else { currentEntitiesInsideToSave.insert(entityID); @@ -752,12 +706,8 @@ void EntityTreeRenderer::leaveAllEntities() { // for all of our previous containing entities, if they are no longer containing then send them a leave event foreach(const EntityItemID& entityID, _currentEntitiesInside) { emit leaveEntity(entityID); - EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID); - if (entityItem) { - auto& scriptEngine = (entityItem->isLocalEntity() || entityItem->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; - if (scriptEngine) { - scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); - } + if (_entitiesScriptEngine) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); } } _currentEntitiesInside.clear(); @@ -1053,12 +1003,11 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) { return; } - auto& scriptEngine = (itr->second->getEntity()->isLocalEntity() || itr->second->getEntity()->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; - if (_tree && !_shuttingDown && scriptEngine && !itr->second->getEntity()->getScript().isEmpty()) { + if (_tree && !_shuttingDown && _entitiesScriptEngine && !itr->second->getEntity()->getScript().isEmpty()) { if (_currentEntitiesInside.contains(entityID)) { - scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); } - scriptEngine->unloadEntityScript(entityID, true); + _entitiesScriptEngine->unloadEntityScript(entityID, true); } auto scene = _viewState->getMain3DScene(); @@ -1103,21 +1052,20 @@ void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID, bool if (!entity) { return; } - auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; - bool shouldLoad = entity->shouldPreloadScript() && scriptEngine; + bool shouldLoad = entity->shouldPreloadScript() && _entitiesScriptEngine; QString scriptUrl = entity->getScript(); if ((shouldLoad && unloadFirst) || scriptUrl.isEmpty()) { - if (scriptEngine) { + if (_entitiesScriptEngine) { if (_currentEntitiesInside.contains(entityID)) { - scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); } - scriptEngine->unloadEntityScript(entityID); + _entitiesScriptEngine->unloadEntityScript(entityID); } entity->scriptHasUnloaded(); } if (shouldLoad) { entity->setScriptHasFinishedPreload(false); - scriptEngine->loadEntityScript(entityID, resolveScriptURL(scriptUrl), reload); + _entitiesScriptEngine->loadEntityScript(entityID, resolveScriptURL(scriptUrl), reload); entity->scriptHasPreloaded(); } } @@ -1224,9 +1172,8 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons if ((myNodeID == entityASimulatorID && entityAIsDynamic) || (myNodeID == entityBSimulatorID && (!entityAIsDynamic || entityASimulatorID.isNull()))) { playEntityCollisionSound(entityA, collision); emit collisionWithEntity(idA, idB, collision); - auto& scriptEngine = (entityA->isLocalEntity() || entityA->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; - if (scriptEngine) { - scriptEngine->callEntityScriptMethod(idA, "collisionWithEntity", idB, collision); + if (_entitiesScriptEngine) { + _entitiesScriptEngine->callEntityScriptMethod(idA, "collisionWithEntity", idB, collision); } } @@ -1236,9 +1183,8 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons Collision invertedCollision(collision); invertedCollision.invert(); emit collisionWithEntity(idB, idA, invertedCollision); - auto& scriptEngine = (entityB->isLocalEntity() || entityB->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; - if (scriptEngine) { - scriptEngine->callEntityScriptMethod(idB, "collisionWithEntity", idA, invertedCollision); + if (_entitiesScriptEngine) { + _entitiesScriptEngine->callEntityScriptMethod(idB, "collisionWithEntity", idA, invertedCollision); } } } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index f7623aad10..149b23702f 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -173,9 +173,7 @@ private: EntityRendererPointer renderableForEntity(const EntityItemPointer& entity) const { return renderableForEntityId(entity->getID()); } render::ItemID renderableIdForEntity(const EntityItemPointer& entity) const { return renderableIdForEntityId(entity->getID()); } - void resetPersistentEntitiesScriptEngine(); - void resetNonPersistentEntitiesScriptEngine(); - void setupEntityScriptEngineSignals(const ScriptEnginePointer& scriptEngine); + void resetEntitiesScriptEngine(); void findBestZoneAndMaybeContainingEntities(QSet<EntityItemID>& entitiesContainingAvatar); @@ -198,8 +196,7 @@ private: QSet<EntityItemID> _currentEntitiesInside; bool _wantScripts; - ScriptEnginePointer _nonPersistentEntitiesScriptEngine; // used for domain + non-owned avatar entities, cleared on domain switch - ScriptEnginePointer _persistentEntitiesScriptEngine; // used for local + owned avatar entities, persists on domain switch, cleared on reload content + ScriptEnginePointer _entitiesScriptEngine; void playEntityCollisionSound(const EntityItemPointer& entity, const Collision& collision); @@ -217,6 +214,8 @@ private: std::function<RayToEntityIntersectionResult(unsigned int)> _getPrevRayPickResultOperator; std::function<void(unsigned int, bool)> _setPrecisionPickingOperator; + bool _mouseAndPreloadSignalHandlersConnected { false }; + class LayeredZone { public: LayeredZone(std::shared_ptr<ZoneEntityItem> zone) : zone(zone), id(zone->getID()), volume(zone->getVolumeEstimate()) {} diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 36beb9f0d3..05947551ba 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -1046,26 +1046,18 @@ QSizeF EntityScriptingInterface::textSize(const QUuid& id, const QString& text) return EntityTree::textSize(id, text); } -void EntityScriptingInterface::setPersistentEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine) { +void EntityScriptingInterface::setEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine) { std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); - _persistentEntitiesScriptEngine = engine; -} - -void EntityScriptingInterface::setNonPersistentEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine) { - std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); - _nonPersistentEntitiesScriptEngine = engine; + _entitiesScriptEngine = engine; } void EntityScriptingInterface::callEntityMethod(const QUuid& id, const QString& method, const QStringList& params) { PROFILE_RANGE(script_entities, __FUNCTION__); - - auto entity = getEntityTree()->findEntityByEntityItemID(id); - if (entity) { - std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); - auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; - if (scriptEngine) { - scriptEngine->callEntityScriptMethod(id, method, params); - } + + std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); + if (_entitiesScriptEngine) { + EntityItemID entityID{ id }; + _entitiesScriptEngine->callEntityScriptMethod(entityID, method, params); } } @@ -1107,13 +1099,9 @@ void EntityScriptingInterface::handleEntityScriptCallMethodPacket(QSharedPointer params << paramString; } - auto entity = getEntityTree()->findEntityByEntityItemID(entityID); - if (entity) { - std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); - auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; - if (scriptEngine) { - scriptEngine->callEntityScriptMethod(entityID, method, params, senderNode->getUUID()); - } + std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); + if (_entitiesScriptEngine) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, method, params, senderNode->getUUID()); } } } @@ -1344,7 +1332,7 @@ bool EntityPropertyMetadataRequest::script(EntityItemID entityID, QScriptValue h if (entitiesScriptEngine) { request->setFuture(entitiesScriptEngine->getLocalEntityScriptDetails(entityID)); } - }, entityID); + }); if (!request->isStarted()) { request->deleteLater(); callScopedHandlerObject(handler, _engine->makeError("Entities Scripting Provider unavailable", "InternalError"), QScriptValue()); diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 14d853fbaf..fca0dad871 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -181,8 +181,7 @@ public: void setEntityTree(EntityTreePointer modelTree); EntityTreePointer getEntityTree() { return _entityTree; } - void setPersistentEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine); - void setNonPersistentEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine); + void setEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine); void resetActivityTracking(); ActivityTracking getActivityTracking() const { return _activityTracking; } @@ -2511,12 +2510,9 @@ signals: void webEventReceived(const EntityItemID& entityItemID, const QVariant& message); protected: - void withEntitiesScriptEngine(std::function<void(QSharedPointer<EntitiesScriptEngineProvider>)> function, const EntityItemID& id) { - auto entity = getEntityTree()->findEntityByEntityItemID(id); - if (entity) { - std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); - function((entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine); - } + void withEntitiesScriptEngine(std::function<void(QSharedPointer<EntitiesScriptEngineProvider>)> function) { + std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); + function(_entitiesScriptEngine); }; private slots: @@ -2546,8 +2542,7 @@ private: EntityTreePointer _entityTree; std::recursive_mutex _entitiesScriptEngineLock; - QSharedPointer<EntitiesScriptEngineProvider> _persistentEntitiesScriptEngine; - QSharedPointer<EntitiesScriptEngineProvider> _nonPersistentEntitiesScriptEngine; + QSharedPointer<EntitiesScriptEngineProvider> _entitiesScriptEngine; bool _bidOnSimulationOwnership { false }; From 81940214bb943958611d1789d6cd6fb52dfb523b Mon Sep 17 00:00:00 2001 From: HifiExperiments <53453710+HifiExperiments@users.noreply.github.com> Date: Mon, 16 Nov 2020 21:20:25 -0800 Subject: [PATCH 067/136] Revert "Revert "Split Local and owned Avatar Entity scripts into their own ScriptEngine"" --- .../src/scripts/EntityScriptServer.cpp | 4 +- .../src/EntityTreeRenderer.cpp | 230 +++++++++++------- .../src/EntityTreeRenderer.h | 9 +- .../entities/src/EntityScriptingInterface.cpp | 34 ++- .../entities/src/EntityScriptingInterface.h | 15 +- 5 files changed, 183 insertions(+), 109 deletions(-) diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index 065ab12abc..16931e8c26 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -470,7 +470,9 @@ void EntityScriptServer::resetEntitiesScriptEngine() { scriptEngines->runScriptInitializers(newEngine); newEngine->runInThread(); auto newEngineSP = qSharedPointerCast<EntitiesScriptEngineProvider>(newEngine); - DependencyManager::get<EntityScriptingInterface>()->setEntitiesScriptEngine(newEngineSP); + // On the entity script server, these are the same + DependencyManager::get<EntityScriptingInterface>()->setPersistentEntitiesScriptEngine(newEngineSP); + DependencyManager::get<EntityScriptingInterface>()->setNonPersistentEntitiesScriptEngine(newEngineSP); if (_entitiesScriptEngine) { disconnect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptDetailsUpdated, diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 3538f07d32..2f9c8c4b3a 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -158,79 +158,98 @@ render::ItemID EntityTreeRenderer::renderableIdForEntityId(const EntityItemID& i int EntityTreeRenderer::_entitiesScriptEngineCount = 0; -void EntityTreeRenderer::resetEntitiesScriptEngine() { - _entitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, - QString("about:Entities %1").arg(++_entitiesScriptEngineCount)); - DependencyManager::get<ScriptEngines>()->runScriptInitializers(_entitiesScriptEngine); - _entitiesScriptEngine->runInThread(); - auto entitiesScriptEngineProvider = qSharedPointerCast<EntitiesScriptEngineProvider>(_entitiesScriptEngine); +void EntityTreeRenderer::setupEntityScriptEngineSignals(const ScriptEnginePointer& scriptEngine) { auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); - entityScriptingInterface->setEntitiesScriptEngine(entitiesScriptEngineProvider); - connect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptPreloadFinished, [&](const EntityItemID& entityID) { + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "mousePressOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseDoublePressOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "mouseDoublePressOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "mouseMoveOnEntity", event); + // FIXME: this is a duplicate of mouseMoveOnEntity, but it seems like some scripts might use this naming + scriptEngine->callEntityScriptMethod(entityID, "mouseMoveEvent", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "mouseReleaseOnEntity", event); + }); + + connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "clickDownOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::holdingClickOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "holdingClickOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickReleaseOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "clickReleaseOnEntity", event); + }); + + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "hoverEnterEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "hoverOverEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "hoverLeaveEntity", event); + }); + + connect(scriptEngine.data(), &ScriptEngine::entityScriptPreloadFinished, [&](const EntityItemID& entityID) { EntityItemPointer entity = getTree()->findEntityByID(entityID); if (entity) { entity->setScriptHasFinishedPreload(true); } }); +} - // Connect mouse events to entity script callbacks - if (!_mouseAndPreloadSignalHandlersConnected) { - - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "mousePressOnEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseDoublePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseDoublePressOnEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveOnEntity", event); - // FIXME: this is a duplicate of mouseMoveOnEntity, but it seems like some scripts might use this naming - _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveEvent", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseReleaseOnEntity", event); - }); - - connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "clickDownOnEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::holdingClickOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "holdingClickOnEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "clickReleaseOnEntity", event); - }); - - connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverEnterEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverOverEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverLeaveEntity", event); - }); - - _mouseAndPreloadSignalHandlersConnected = true; +void EntityTreeRenderer::resetPersistentEntitiesScriptEngine() { + if (_persistentEntitiesScriptEngine) { + _persistentEntitiesScriptEngine->unloadAllEntityScripts(true); + _persistentEntitiesScriptEngine->stop(); + _persistentEntitiesScriptEngine->waitTillDoneRunning(); + _persistentEntitiesScriptEngine->disconnectNonEssentialSignals(); } + _persistentEntitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, + QString("about:Entities %1").arg(++_entitiesScriptEngineCount)); + DependencyManager::get<ScriptEngines>()->runScriptInitializers(_persistentEntitiesScriptEngine); + _persistentEntitiesScriptEngine->runInThread(); + auto entitiesScriptEngineProvider = qSharedPointerCast<EntitiesScriptEngineProvider>(_persistentEntitiesScriptEngine); + auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); + entityScriptingInterface->setPersistentEntitiesScriptEngine(entitiesScriptEngineProvider); + + setupEntityScriptEngineSignals(_persistentEntitiesScriptEngine); +} + +void EntityTreeRenderer::resetNonPersistentEntitiesScriptEngine() { + if (_nonPersistentEntitiesScriptEngine) { + _nonPersistentEntitiesScriptEngine->unloadAllEntityScripts(false); + _nonPersistentEntitiesScriptEngine->stop(); + _nonPersistentEntitiesScriptEngine->waitTillDoneRunning(); + _nonPersistentEntitiesScriptEngine->disconnectNonEssentialSignals(); + } + _nonPersistentEntitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, + QString("about:Entities %1").arg(++_entitiesScriptEngineCount)); + DependencyManager::get<ScriptEngines>()->runScriptInitializers(_nonPersistentEntitiesScriptEngine); + _nonPersistentEntitiesScriptEngine->runInThread(); + auto entitiesScriptEngineProvider = qSharedPointerCast<EntitiesScriptEngineProvider>(_nonPersistentEntitiesScriptEngine); + DependencyManager::get<EntityScriptingInterface>()->setNonPersistentEntitiesScriptEngine(entitiesScriptEngineProvider); + + setupEntityScriptEngineSignals(_nonPersistentEntitiesScriptEngine); } void EntityTreeRenderer::stopDomainAndNonOwnedEntities() { leaveDomainAndNonOwnedEntities(); // unload and stop the engine - if (_entitiesScriptEngine) { - QList<EntityItemID> entitiesWithEntityScripts = _entitiesScriptEngine->getListOfEntityScriptIDs(); + if (_nonPersistentEntitiesScriptEngine) { + QList<EntityItemID> entitiesWithEntityScripts = _nonPersistentEntitiesScriptEngine->getListOfEntityScriptIDs(); - foreach (const EntityItemID& entityID, entitiesWithEntityScripts) { + foreach (const EntityItemID& entityID, entitiesWithEntityScripts) { EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID); - if (entityItem && !entityItem->getScript().isEmpty()) { if (!(entityItem->isLocalEntity() || entityItem->isMyAvatarEntity())) { - if (_currentEntitiesInside.contains(entityID)) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); - } - _entitiesScriptEngine->unloadEntityScript(entityID, true); + _nonPersistentEntitiesScriptEngine->unloadEntityScript(entityID, true); } } } @@ -240,6 +259,10 @@ void EntityTreeRenderer::stopDomainAndNonOwnedEntities() { void EntityTreeRenderer::clearDomainAndNonOwnedEntities() { stopDomainAndNonOwnedEntities(); + if (!_shuttingDown && _wantScripts) { + resetNonPersistentEntitiesScriptEngine(); + } + std::unordered_map<EntityItemID, EntityRendererPointer> savedEntities; std::unordered_set<EntityRendererPointer> savedRenderables; // remove all entities from the scene @@ -269,16 +292,22 @@ void EntityTreeRenderer::clearDomainAndNonOwnedEntities() { void EntityTreeRenderer::clear() { leaveAllEntities(); - // unload and stop the engine - if (_entitiesScriptEngine) { - // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread - _entitiesScriptEngine->unloadAllEntityScripts(true); - _entitiesScriptEngine->stop(); - } // reset the engine auto scene = _viewState->getMain3DScene(); if (_shuttingDown) { + // unload and stop the engines + if (_nonPersistentEntitiesScriptEngine) { + // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread + _nonPersistentEntitiesScriptEngine->unloadAllEntityScripts(true); + _nonPersistentEntitiesScriptEngine->stop(); + } + if (_persistentEntitiesScriptEngine) { + // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread + _persistentEntitiesScriptEngine->unloadAllEntityScripts(true); + _persistentEntitiesScriptEngine->stop(); + } + if (scene) { render::Transaction transaction; for (const auto& entry : _entitiesInScene) { @@ -289,7 +318,8 @@ void EntityTreeRenderer::clear() { } } else { if (_wantScripts) { - resetEntitiesScriptEngine(); + resetPersistentEntitiesScriptEngine(); + resetNonPersistentEntitiesScriptEngine(); } if (scene) { for (const auto& entry : _entitiesInScene) { @@ -313,13 +343,17 @@ void EntityTreeRenderer::clear() { } void EntityTreeRenderer::reloadEntityScripts() { - _entitiesScriptEngine->unloadAllEntityScripts(); - _entitiesScriptEngine->resetModuleCache(); + _persistentEntitiesScriptEngine->unloadAllEntityScripts(); + _persistentEntitiesScriptEngine->resetModuleCache(); + _nonPersistentEntitiesScriptEngine->unloadAllEntityScripts(); + _nonPersistentEntitiesScriptEngine->resetModuleCache(); + for (const auto& entry : _entitiesInScene) { const auto& renderer = entry.second; const auto& entity = renderer->getEntity(); - if (!entity->getScript().isEmpty()) { - _entitiesScriptEngine->loadEntityScript(entity->getEntityItemID(), resolveScriptURL(entity->getScript()), true); + if (entity && !entity->getScript().isEmpty()) { + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + scriptEngine->loadEntityScript(entity->getEntityItemID(), resolveScriptURL(entity->getScript()), true); } } } @@ -329,7 +363,8 @@ void EntityTreeRenderer::init() { EntityTreePointer entityTree = std::static_pointer_cast<EntityTree>(_tree); if (_wantScripts) { - resetEntitiesScriptEngine(); + resetPersistentEntitiesScriptEngine(); + resetNonPersistentEntitiesScriptEngine(); } forceRecheckEntities(); // setup our state to force checking our inside/outsideness of entities @@ -341,8 +376,11 @@ void EntityTreeRenderer::init() { } void EntityTreeRenderer::shutdown() { - if (_entitiesScriptEngine) { - _entitiesScriptEngine->disconnectNonEssentialSignals(); // disconnect all slots/signals from the script engine, except essential + if (_persistentEntitiesScriptEngine) { + _persistentEntitiesScriptEngine->disconnectNonEssentialSignals(); // disconnect all slots/signals from the script engine, except essential + } + if (_nonPersistentEntitiesScriptEngine) { + _nonPersistentEntitiesScriptEngine->disconnectNonEssentialSignals(); // disconnect all slots/signals from the script engine, except essential } _shuttingDown = true; @@ -658,12 +696,16 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { // EntityItemIDs from here. The callEntityScriptMethod() method is robust against attempting to call scripts // for entity IDs that no longer exist. - if (_entitiesScriptEngine) { + if (_persistentEntitiesScriptEngine && _nonPersistentEntitiesScriptEngine) { // for all of our previous containing entities, if they are no longer containing then send them a leave event foreach(const EntityItemID& entityID, _currentEntitiesInside) { if (!entitiesContainingAvatar.contains(entityID)) { emit leaveEntity(entityID); - _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + auto entity = getTree()->findEntityByEntityItemID(entityID); + if (entity) { + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + } } } @@ -671,7 +713,11 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { foreach(const EntityItemID& entityID, entitiesContainingAvatar) { if (!_currentEntitiesInside.contains(entityID)) { emit enterEntity(entityID); - _entitiesScriptEngine->callEntityScriptMethod(entityID, "enterEntity"); + auto entity = getTree()->findEntityByEntityItemID(entityID); + if (entity) { + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + scriptEngine->callEntityScriptMethod(entityID, "enterEntity"); + } } } _currentEntitiesInside = entitiesContainingAvatar; @@ -687,8 +733,8 @@ void EntityTreeRenderer::leaveDomainAndNonOwnedEntities() { EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID); if (entityItem && !(entityItem->isLocalEntity() || entityItem->isMyAvatarEntity())) { emit leaveEntity(entityID); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + if (_nonPersistentEntitiesScriptEngine) { + _nonPersistentEntitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); } } else { currentEntitiesInsideToSave.insert(entityID); @@ -706,8 +752,12 @@ void EntityTreeRenderer::leaveAllEntities() { // for all of our previous containing entities, if they are no longer containing then send them a leave event foreach(const EntityItemID& entityID, _currentEntitiesInside) { emit leaveEntity(entityID); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID); + if (entityItem) { + auto& scriptEngine = (entityItem->isLocalEntity() || entityItem->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + if (scriptEngine) { + scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + } } } _currentEntitiesInside.clear(); @@ -1003,11 +1053,12 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) { return; } - if (_tree && !_shuttingDown && _entitiesScriptEngine && !itr->second->getEntity()->getScript().isEmpty()) { + auto& scriptEngine = (itr->second->getEntity()->isLocalEntity() || itr->second->getEntity()->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + if (_tree && !_shuttingDown && scriptEngine && !itr->second->getEntity()->getScript().isEmpty()) { if (_currentEntitiesInside.contains(entityID)) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); } - _entitiesScriptEngine->unloadEntityScript(entityID, true); + scriptEngine->unloadEntityScript(entityID, true); } auto scene = _viewState->getMain3DScene(); @@ -1052,20 +1103,21 @@ void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID, bool if (!entity) { return; } - bool shouldLoad = entity->shouldPreloadScript() && _entitiesScriptEngine; + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + bool shouldLoad = entity->shouldPreloadScript() && scriptEngine; QString scriptUrl = entity->getScript(); if ((shouldLoad && unloadFirst) || scriptUrl.isEmpty()) { - if (_entitiesScriptEngine) { + if (scriptEngine) { if (_currentEntitiesInside.contains(entityID)) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); } - _entitiesScriptEngine->unloadEntityScript(entityID); + scriptEngine->unloadEntityScript(entityID); } entity->scriptHasUnloaded(); } if (shouldLoad) { entity->setScriptHasFinishedPreload(false); - _entitiesScriptEngine->loadEntityScript(entityID, resolveScriptURL(scriptUrl), reload); + scriptEngine->loadEntityScript(entityID, resolveScriptURL(scriptUrl), reload); entity->scriptHasPreloaded(); } } @@ -1172,8 +1224,9 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons if ((myNodeID == entityASimulatorID && entityAIsDynamic) || (myNodeID == entityBSimulatorID && (!entityAIsDynamic || entityASimulatorID.isNull()))) { playEntityCollisionSound(entityA, collision); emit collisionWithEntity(idA, idB, collision); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(idA, "collisionWithEntity", idB, collision); + auto& scriptEngine = (entityA->isLocalEntity() || entityA->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + if (scriptEngine) { + scriptEngine->callEntityScriptMethod(idA, "collisionWithEntity", idB, collision); } } @@ -1183,8 +1236,9 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons Collision invertedCollision(collision); invertedCollision.invert(); emit collisionWithEntity(idB, idA, invertedCollision); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(idB, "collisionWithEntity", idA, invertedCollision); + auto& scriptEngine = (entityB->isLocalEntity() || entityB->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + if (scriptEngine) { + scriptEngine->callEntityScriptMethod(idB, "collisionWithEntity", idA, invertedCollision); } } } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 149b23702f..f7623aad10 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -173,7 +173,9 @@ private: EntityRendererPointer renderableForEntity(const EntityItemPointer& entity) const { return renderableForEntityId(entity->getID()); } render::ItemID renderableIdForEntity(const EntityItemPointer& entity) const { return renderableIdForEntityId(entity->getID()); } - void resetEntitiesScriptEngine(); + void resetPersistentEntitiesScriptEngine(); + void resetNonPersistentEntitiesScriptEngine(); + void setupEntityScriptEngineSignals(const ScriptEnginePointer& scriptEngine); void findBestZoneAndMaybeContainingEntities(QSet<EntityItemID>& entitiesContainingAvatar); @@ -196,7 +198,8 @@ private: QSet<EntityItemID> _currentEntitiesInside; bool _wantScripts; - ScriptEnginePointer _entitiesScriptEngine; + ScriptEnginePointer _nonPersistentEntitiesScriptEngine; // used for domain + non-owned avatar entities, cleared on domain switch + ScriptEnginePointer _persistentEntitiesScriptEngine; // used for local + owned avatar entities, persists on domain switch, cleared on reload content void playEntityCollisionSound(const EntityItemPointer& entity, const Collision& collision); @@ -214,8 +217,6 @@ private: std::function<RayToEntityIntersectionResult(unsigned int)> _getPrevRayPickResultOperator; std::function<void(unsigned int, bool)> _setPrecisionPickingOperator; - bool _mouseAndPreloadSignalHandlersConnected { false }; - class LayeredZone { public: LayeredZone(std::shared_ptr<ZoneEntityItem> zone) : zone(zone), id(zone->getID()), volume(zone->getVolumeEstimate()) {} diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 05947551ba..36beb9f0d3 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -1046,18 +1046,26 @@ QSizeF EntityScriptingInterface::textSize(const QUuid& id, const QString& text) return EntityTree::textSize(id, text); } -void EntityScriptingInterface::setEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine) { +void EntityScriptingInterface::setPersistentEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine) { std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); - _entitiesScriptEngine = engine; + _persistentEntitiesScriptEngine = engine; +} + +void EntityScriptingInterface::setNonPersistentEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine) { + std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); + _nonPersistentEntitiesScriptEngine = engine; } void EntityScriptingInterface::callEntityMethod(const QUuid& id, const QString& method, const QStringList& params) { PROFILE_RANGE(script_entities, __FUNCTION__); - - std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); - if (_entitiesScriptEngine) { - EntityItemID entityID{ id }; - _entitiesScriptEngine->callEntityScriptMethod(entityID, method, params); + + auto entity = getEntityTree()->findEntityByEntityItemID(id); + if (entity) { + std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + if (scriptEngine) { + scriptEngine->callEntityScriptMethod(id, method, params); + } } } @@ -1099,9 +1107,13 @@ void EntityScriptingInterface::handleEntityScriptCallMethodPacket(QSharedPointer params << paramString; } - std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, method, params, senderNode->getUUID()); + auto entity = getEntityTree()->findEntityByEntityItemID(entityID); + if (entity) { + std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + if (scriptEngine) { + scriptEngine->callEntityScriptMethod(entityID, method, params, senderNode->getUUID()); + } } } } @@ -1332,7 +1344,7 @@ bool EntityPropertyMetadataRequest::script(EntityItemID entityID, QScriptValue h if (entitiesScriptEngine) { request->setFuture(entitiesScriptEngine->getLocalEntityScriptDetails(entityID)); } - }); + }, entityID); if (!request->isStarted()) { request->deleteLater(); callScopedHandlerObject(handler, _engine->makeError("Entities Scripting Provider unavailable", "InternalError"), QScriptValue()); diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index fca0dad871..14d853fbaf 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -181,7 +181,8 @@ public: void setEntityTree(EntityTreePointer modelTree); EntityTreePointer getEntityTree() { return _entityTree; } - void setEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine); + void setPersistentEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine); + void setNonPersistentEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine); void resetActivityTracking(); ActivityTracking getActivityTracking() const { return _activityTracking; } @@ -2510,9 +2511,12 @@ signals: void webEventReceived(const EntityItemID& entityItemID, const QVariant& message); protected: - void withEntitiesScriptEngine(std::function<void(QSharedPointer<EntitiesScriptEngineProvider>)> function) { - std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); - function(_entitiesScriptEngine); + void withEntitiesScriptEngine(std::function<void(QSharedPointer<EntitiesScriptEngineProvider>)> function, const EntityItemID& id) { + auto entity = getEntityTree()->findEntityByEntityItemID(id); + if (entity) { + std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock); + function((entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine); + } }; private slots: @@ -2542,7 +2546,8 @@ private: EntityTreePointer _entityTree; std::recursive_mutex _entitiesScriptEngineLock; - QSharedPointer<EntitiesScriptEngineProvider> _entitiesScriptEngine; + QSharedPointer<EntitiesScriptEngineProvider> _persistentEntitiesScriptEngine; + QSharedPointer<EntitiesScriptEngineProvider> _nonPersistentEntitiesScriptEngine; bool _bidOnSimulationOwnership { false }; From b6744588f491869b0f2105fc69ef15244d9b2403 Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Mon, 16 Nov 2020 21:25:25 -0800 Subject: [PATCH 068/136] loading fix --- .../entities-renderer/src/EntityTreeRenderer.cpp | 2 +- libraries/script-engine/src/ScriptEngine.cpp | 16 +++++++++------- libraries/script-engine/src/ScriptEngine.h | 2 +- libraries/script-engine/src/ScriptEngines.cpp | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 2f9c8c4b3a..949ad85945 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -224,7 +224,7 @@ void EntityTreeRenderer::resetPersistentEntitiesScriptEngine() { void EntityTreeRenderer::resetNonPersistentEntitiesScriptEngine() { if (_nonPersistentEntitiesScriptEngine) { - _nonPersistentEntitiesScriptEngine->unloadAllEntityScripts(false); + _nonPersistentEntitiesScriptEngine->unloadAllEntityScripts(true); _nonPersistentEntitiesScriptEngine->stop(); _nonPersistentEntitiesScriptEngine->waitTillDoneRunning(); _nonPersistentEntitiesScriptEngine->disconnectNonEssentialSignals(); diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 9480b498ba..f42178b023 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -451,7 +451,7 @@ void ScriptEngine::executeOnScriptThread(std::function<void()> function, const Q function(); } -void ScriptEngine::waitTillDoneRunning() { +void ScriptEngine::waitTillDoneRunning(bool shutdown) { // Engine should be stopped already, but be defensive stop(); @@ -520,12 +520,14 @@ void ScriptEngine::waitTillDoneRunning() { } } - // NOTE: This will be called on the main application thread (among other threads) from stopAllScripts. - // The thread will need to continue to process events, because - // the scripts will likely need to marshall messages across to the main thread, e.g. - // if they access Settings or Menu in any of their shutdown code. So: - // Process events for this thread, allowing invokeMethod calls to pass between threads. - QCoreApplication::processEvents(); + if (shutdown) { + // NOTE: This will be called on the main application thread (among other threads) from stopAllScripts. + // The thread will need to continue to process events, because + // the scripts will likely need to marshall messages across to the main thread, e.g. + // if they access Settings or Menu in any of their shutdown code. So: + // Process events for this thread, allowing invokeMethod calls to pass between threads. + QCoreApplication::processEvents(); + } // Avoid a pure busy wait QThread::yieldCurrentThread(); diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 8cbeed58af..1d85de4d94 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -197,7 +197,7 @@ public: Q_INVOKABLE void stop(bool marshal = false); // Stop any evaluating scripts and wait for the scripting thread to finish. - void waitTillDoneRunning(); + void waitTillDoneRunning(bool shutdown = false); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // NOTE - these are NOT intended to be public interfaces available to scripts, the are only Q_INVOKABLE so we can diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index 12eaa011a9..381d931620 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -182,7 +182,7 @@ void ScriptEngines::shutdownScripting() { // want any of the scripts final "scriptEnding()" or pending "update()" methods from accessing // any application state after we leave this stopAllScripts() method qCDebug(scriptengine) << "waiting on script:" << scriptName; - scriptEngine->waitTillDoneRunning(); + scriptEngine->waitTillDoneRunning(true); qCDebug(scriptengine) << "done waiting on script:" << scriptName; } // Once the script is stopped, we can remove it from our set From 4c536f43184cb6c1abfdf3d9779a4333a3f2a215 Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Mon, 16 Nov 2020 22:11:14 -0800 Subject: [PATCH 069/136] try to replace set-env --- .github/workflows/master_build.yml | 42 +++++++++++++++--------------- .github/workflows/pr_build.yml | 34 ++++++++++++------------ 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/.github/workflows/master_build.yml b/.github/workflows/master_build.yml index 824c279845..ac718c9bcd 100644 --- a/.github/workflows/master_build.yml +++ b/.github/workflows/master_build.yml @@ -48,36 +48,36 @@ jobs: shell: bash id: buildenv1 run: | - echo ::set-env name=UPLOAD_PREFIX::master - echo ::set-env name=GIT_COMMIT_SHORT::`echo $GIT_COMMIT | cut -c1-7` - echo ::set-env name=JOB_NAME::"build (${{matrix.os}}, ${{matrix.build_type}})" + echo "UPLOAD_PREFIX=master" >> $GITHUB_ENV + echo "GIT_COMMIT_SHORT=`echo $GIT_COMMIT | cut -c1-7`" >> $GITHUB_ENV + echo "JOB_NAME=`build (${{matrix.os}}, ${{matrix.build_type}})` >> $GITHUB_ENV # Linux build variables if [[ "${{ matrix.os }}" = "ubuntu-"* ]]; then - echo ::set-env name=PYTHON_EXEC::python3 - echo ::set-env name=INSTALLER_EXT::tgz - echo ::set-env name=CMAKE_BUILD_EXTRA::"-- -j3" - echo ::set-env name=CMAKE_EXTRA::"-DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)" + echo "PYTHON_EXEC=python3" >> $GITHUB_ENV + echo "INSTALLER_EXT=tgz" >> $GITHUB_ENV + echo "CMAKE_BUILD_EXTRA=`-- -j3`" >> $GITHUB_ENV + echo "CMAKE_EXTRA=`-DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)`" >> $GITHUB_ENV fi # Mac build variables if [ "${{ matrix.os }}" = "macOS-latest" ]; then - echo ::set-env name=PYTHON_EXEC::python3 - echo ::set-env name=ZIP_COMMAND::zip - echo ::set-env name=ZIP_ARGS::-r - echo ::set-env name=INSTALLER_EXT::dmg - echo ::set-env name=CMAKE_EXTRA::"-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode" + echo "PYTHON_EXEC=python3" >> $GITHUB_ENV + echo "ZIP_COMMAND=zip" >> $GITHUB_ENV + echo "ZIP_ARGS=-r" >> $GITHUB_ENV + echo "INSTALLER_EXT=dmg" >> $GITHUB_ENV + echo "CMAKE_EXTRA=`-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode`" >> $GITHUB_ENV echo "::set-output name=symbols_archive::${BUILD_NUMBER}-${{ matrix.build_type }}-mac-symbols.zip" fi # Windows build variables if [ "${{ matrix.os }}" = "windows-latest" ]; then - echo ::set-env name=PYTHON_EXEC::python - echo ::set-env name=ZIP_COMMAND::7z - echo ::set-env name=ZIP_ARGS::a - echo ::set-env name=INSTALLER_EXT::exe - echo ::set-env name=CMAKE_EXTRA::"-A x64" - echo "::set-env name=SYMBOL_REGEX::\(exe\|dll\|pdb\)" - echo "::set-output name=symbols_archive::${BUILD_NUMBER}-${{ matrix.build_type }}-win-symbols.zip" - # echo ::set-env name=HF_PFX_PASSPHRASE::${{secrets.pfx_key}} - # echo "::set-env name=HF_PFX_FILE::${{runner.workspace}}\build\codesign.pfx" + echo "PYTHON_EXEC=python" >> $GITHUB_ENV + echo "ZIP_COMMAND=7z" >> $GITHUB_ENV + echo "ZIP_ARGS=a" >> $GITHUB_ENV + echo "INSTALLER_EXT=exe" >> $GITHUB_ENV + echo "CMAKE_EXTRA=`-A x64`" >> $GITHUB_ENV + echo "SYMBOL_REGEX=\(exe\|dll\|pdb\)" >> $GITHUB_ENV + echo "symbols_archive=${BUILD_NUMBER}-${{ matrix.build_type }}-win-symbols.zip" >> $GITHUB_ENV + # echo "HF_PFX_PASSPHRASE=${{secrets.pfx_key}}" >> $GITHUB_ENV + # echo "HF_PFX_FILE=${{runner.workspace}}\build\codesign.pfx"" >> $GITHUB_ENV fi # Configuration is broken into two steps because you can't set an env var and also reference it in the same step - name: Configure build environment 2 diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 3c6b91c65b..b41304100f 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -49,34 +49,34 @@ jobs: shell: bash id: buildenv1 run: | - echo ::set-env name=GIT_COMMIT_SHORT::`echo $GIT_COMMIT | cut -c1-7` - echo ::set-env name=JOB_NAME::"build (${{matrix.os}}, ${{matrix.build_type}})" + echo "GIT_COMMIT_SHORT=`echo $GIT_COMMIT | cut -c1-7`" >> $GITHUB_ENV + echo "JOB_NAME=`build (${{matrix.os}}, ${{matrix.build_type}})`" >> $GITHUB_ENV # Linux build variables if [[ "${{ matrix.os }}" = "ubuntu-"* ]]; then - echo ::set-env name=PYTHON_EXEC::python3 - echo ::set-env name=INSTALLER_EXT::* - echo ::set-env name=CMAKE_BUILD_EXTRA::"-- -j3" - echo ::set-env name=CMAKE_EXTRA::"-DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)" + echo "PYTHON_EXEC=python3" >> $GITHUB_ENV + echo "INSTALLER_EXT=*" >> $GITHUB_ENV + echo "CMAKE_BUILD_EXTRA=`-- -j3`" >> $GITHUB_ENV + echo "CMAKE_EXTRA=`-DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)`" >> $GITHUB_ENV fi # Mac build variables if [ "${{ matrix.os }}" = "macOS-latest" ]; then - echo ::set-env name=PYTHON_EXEC::python3 - echo ::set-env name=INSTALLER_EXT::dmg - echo ::set-env name=CMAKE_EXTRA::"-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode" + echo "PYTHON_EXEC=python3" >> $GITHUB_ENV + echo "INSTALLER_EXT=dmg" >> $GITHUB_ENV + echo "CMAKE_EXTRA=`-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode`" >> $GITHUB_ENV fi # Windows build variables if [ "${{ matrix.os }}" = "windows-latest" ]; then - echo ::set-env name=PYTHON_EXEC::python - echo ::set-env name=INSTALLER_EXT::exe - echo ::set-env name=CMAKE_EXTRA::"-A x64" + echo "PYTHON_EXEC=python" >> $GITHUB_ENV + echo "INSTALLER_EXT=exe" >> $GITHUB_ENV + echo "CMAKE_EXTRA=`-A x64`" >> $GITHUB_ENV fi # Android + Quest build variables if [[ "${{ matrix.build_type }}" == "android" ]]; then HIFI_ANDROID_PRECOMPILED="${{runner.workspace}}/dependencies" - echo ::set-env name=HIFI_ANDROID_PRECOMPILED::"$HIFI_ANDROID_PRECOMPILED" + echo "HIFI_ANDROID_PRECOMPILED=`$HIFI_ANDROID_PRECOMPILED`" >> $GITHUB_ENV mkdir $HIFI_ANDROID_PRECOMPILED - echo ::set-env name=INSTALLER_EXT::apk + echo "INSTALLER_EXT=apk" >> $GITHUB_ENV fi # Configuration is broken into two steps because you can't set an env var and also reference it in the same step - name: Configure Build Environment 2 @@ -84,11 +84,11 @@ jobs: run: | echo "${{ steps.buildenv1.outputs.symbols_archive }}" if [[ "${{ matrix.build_type }}" != "android" ]]; then - echo ::set-env name=ARTIFACT_PATTERN::Vircadia-Alpha-PR${{ github.event.number }}-*.$INSTALLER_EXT + echo "ARTIFACT_PATTERN=Vircadia-Alpha-PR${{ github.event.number }}-*.$INSTALLER_EXT" >> $GITHUB_ENV # Build type variables - echo ::set-env name=INSTALLER::Vircadia-Alpha-$RELEASE_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT + echo "INSTALLER=Vircadia-Alpha-$RELEASE_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT" >> $GITHUB_ENV else - echo ::set-env name=ARTIFACT_PATTERN::*.$INSTALLER_EXT + echo "ARTIFACT_PATTERN=*.$INSTALLER_EXT" >> $GITHUB_ENV fi - name: Clear Working Directory if: startsWith(matrix.os, 'windows') From 5b8f7fad165d6f4b1f9d1ffb6549c1e1ac679b7f Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Mon, 16 Nov 2020 22:18:43 -0800 Subject: [PATCH 070/136] some more --- .github/workflows/master_build.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/master_build.yml b/.github/workflows/master_build.yml index ac718c9bcd..505efe0171 100644 --- a/.github/workflows/master_build.yml +++ b/.github/workflows/master_build.yml @@ -50,7 +50,7 @@ jobs: run: | echo "UPLOAD_PREFIX=master" >> $GITHUB_ENV echo "GIT_COMMIT_SHORT=`echo $GIT_COMMIT | cut -c1-7`" >> $GITHUB_ENV - echo "JOB_NAME=`build (${{matrix.os}}, ${{matrix.build_type}})` >> $GITHUB_ENV + echo "JOB_NAME=`build (${{matrix.os}}, ${{matrix.build_type}})`" >> $GITHUB_ENV # Linux build variables if [[ "${{ matrix.os }}" = "ubuntu-"* ]]; then echo "PYTHON_EXEC=python3" >> $GITHUB_ENV @@ -77,21 +77,21 @@ jobs: echo "SYMBOL_REGEX=\(exe\|dll\|pdb\)" >> $GITHUB_ENV echo "symbols_archive=${BUILD_NUMBER}-${{ matrix.build_type }}-win-symbols.zip" >> $GITHUB_ENV # echo "HF_PFX_PASSPHRASE=${{secrets.pfx_key}}" >> $GITHUB_ENV - # echo "HF_PFX_FILE=${{runner.workspace}}\build\codesign.pfx"" >> $GITHUB_ENV + # echo "HF_PFX_FILE=${{runner.workspace}}\build\codesign.pfx" >> $GITHUB_ENV fi # Configuration is broken into two steps because you can't set an env var and also reference it in the same step - name: Configure build environment 2 shell: bash run: | echo "${{ steps.buildenv1.outputs.symbols_archive }}" - echo ::set-env name=ARTIFACT_PATTERN::Vircadia-Alpha-*.$INSTALLER_EXT + echo "ARTIFACT_PATTERN=Vircadia-Alpha-*.$INSTALLER_EXT" >> $GITHUB_ENV # Build type variables if [ "${{ matrix.build_type }}" = "full" ]; then - echo ::set-env name=CLIENT_ONLY::FALSE - echo ::set-env name=INSTALLER::Vircadia-Alpha-$BUILD_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT + echo "CLIENT_ONLY=FALSE" >> $GITHUB_ENV + echo "INSTALLER=Vircadia-Alpha-$BUILD_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT" >> $GITHUB_ENV else - echo ::set-env name=CLIENT_ONLY::TRUE - echo ::set-env name=INSTALLER::Vircadia-Alpha-Interface-$BUILD_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT + echo "CLIENT_ONLY=TRUE" >> $GITHUB_ENV + echo "INSTALLER=Vircadia-Alpha-Interface-$BUILD_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT" >> $GITHUB_ENV fi - name: Clear working directory if: startsWith(matrix.os, 'windows') From cfe824c1805bf1bda4cbcc3434161b77ca2e6616 Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Wed, 18 Nov 2020 08:16:25 +1300 Subject: [PATCH 071/136] Replace set-env in PR GHA Code from commit 4c536f4 by HifiExperiments. --- .github/workflows/pr_build.yml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index f28cf1e66b..5eb8e2a647 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -43,36 +43,36 @@ jobs: shell: bash id: buildenv1 run: | - echo ::set-env name=GIT_COMMIT_SHORT::`echo $GIT_COMMIT | cut -c1-7` - echo ::set-env name=JOB_NAME::"build (${{matrix.os}}, ${{matrix.build_type}})" + echo "GIT_COMMIT_SHORT=`echo $GIT_COMMIT | cut -c1-7`" >> $GITHUB_ENV + echo "JOB_NAME=`build (${{matrix.os}}, ${{matrix.build_type}})`" >> $GITHUB_ENV # Linux build variables if [[ "${{ matrix.os }}" = "ubuntu-"* ]]; then - echo ::set-env name=PYTHON_EXEC::python3 - echo ::set-env name=INSTALLER_EXT::* - echo ::set-env name=CMAKE_BUILD_EXTRA::"-- -j3" - echo ::set-env name=CMAKE_EXTRA::"-DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)" + echo "PYTHON_EXEC=python3" >> $GITHUB_ENV + echo "INSTALLER_EXT=*" >> $GITHUB_ENV + echo "CMAKE_BUILD_EXTRA=`-- -j3`" >> $GITHUB_ENV + echo "CMAKE_EXTRA=`-DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)`" >> $GITHUB_ENV fi # Mac build variables if [ "${{ matrix.os }}" = "macOS-latest" ]; then - echo ::set-env name=PYTHON_EXEC::python3 - echo ::set-env name=INSTALLER_EXT::dmg - echo ::set-env name=CMAKE_EXTRA::"-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode" + echo "PYTHON_EXEC=python3" >> $GITHUB_ENV + echo "INSTALLER_EXT=dmg" >> $GITHUB_ENV + echo "CMAKE_EXTRA=`-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode`" >> $GITHUB_ENV fi # Windows build variables if [ "${{ matrix.os }}" = "windows-latest" ]; then - echo ::set-env name=PYTHON_EXEC::python - echo ::set-env name=INSTALLER_EXT::exe - echo ::set-env name=CMAKE_EXTRA::"-A x64" + echo "PYTHON_EXEC=python" >> $GITHUB_ENV + echo "INSTALLER_EXT=exe" >> $GITHUB_ENV + echo "CMAKE_EXTRA=`-A x64`" >> $GITHUB_ENV fi # Configuration is broken into two steps because you can't set an env var and also reference it in the same step - name: Configure Build Environment 2 shell: bash run: | echo "${{ steps.buildenv1.outputs.symbols_archive }}" - echo ::set-env name=ARTIFACT_PATTERN::Vircadia-Alpha-PR${{ github.event.number }}-*.$INSTALLER_EXT + echo "ARTIFACT_PATTERN=Vircadia-Alpha-PR${{ github.event.number }}-*.$INSTALLER_EXT" >> $GITHUB_ENV # Build type variables - echo ::set-env name=INSTALLER::Vircadia-Alpha-$RELEASE_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT + echo "INSTALLER=Vircadia-Alpha-$RELEASE_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT" >> $GITHUB_ENV - name: Clear Working Directory if: startsWith(matrix.os, 'windows') shell: bash From be55993ddac3a7586eb652d54a3a993255f626bb Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Tue, 17 Nov 2020 13:14:23 -0800 Subject: [PATCH 072/136] try removing single quotes --- .github/workflows/master_build.yml | 12 ++++++------ .github/workflows/pr_build.yml | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/master_build.yml b/.github/workflows/master_build.yml index 505efe0171..a09844608f 100644 --- a/.github/workflows/master_build.yml +++ b/.github/workflows/master_build.yml @@ -49,14 +49,14 @@ jobs: id: buildenv1 run: | echo "UPLOAD_PREFIX=master" >> $GITHUB_ENV - echo "GIT_COMMIT_SHORT=`echo $GIT_COMMIT | cut -c1-7`" >> $GITHUB_ENV - echo "JOB_NAME=`build (${{matrix.os}}, ${{matrix.build_type}})`" >> $GITHUB_ENV + echo "GIT_COMMIT_SHORT=echo $GIT_COMMIT | cut -c1-7" >> $GITHUB_ENV + echo "JOB_NAME=build (${{matrix.os}}, ${{matrix.build_type}})" >> $GITHUB_ENV # Linux build variables if [[ "${{ matrix.os }}" = "ubuntu-"* ]]; then echo "PYTHON_EXEC=python3" >> $GITHUB_ENV echo "INSTALLER_EXT=tgz" >> $GITHUB_ENV - echo "CMAKE_BUILD_EXTRA=`-- -j3`" >> $GITHUB_ENV - echo "CMAKE_EXTRA=`-DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)`" >> $GITHUB_ENV + echo "CMAKE_BUILD_EXTRA=-- -j3" >> $GITHUB_ENV + echo "CMAKE_EXTRA=-DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)" >> $GITHUB_ENV fi # Mac build variables if [ "${{ matrix.os }}" = "macOS-latest" ]; then @@ -64,7 +64,7 @@ jobs: echo "ZIP_COMMAND=zip" >> $GITHUB_ENV echo "ZIP_ARGS=-r" >> $GITHUB_ENV echo "INSTALLER_EXT=dmg" >> $GITHUB_ENV - echo "CMAKE_EXTRA=`-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode`" >> $GITHUB_ENV + echo "CMAKE_EXTRA=-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode" >> $GITHUB_ENV echo "::set-output name=symbols_archive::${BUILD_NUMBER}-${{ matrix.build_type }}-mac-symbols.zip" fi # Windows build variables @@ -73,7 +73,7 @@ jobs: echo "ZIP_COMMAND=7z" >> $GITHUB_ENV echo "ZIP_ARGS=a" >> $GITHUB_ENV echo "INSTALLER_EXT=exe" >> $GITHUB_ENV - echo "CMAKE_EXTRA=`-A x64`" >> $GITHUB_ENV + echo "CMAKE_EXTRA=-A x64" >> $GITHUB_ENV echo "SYMBOL_REGEX=\(exe\|dll\|pdb\)" >> $GITHUB_ENV echo "symbols_archive=${BUILD_NUMBER}-${{ matrix.build_type }}-win-symbols.zip" >> $GITHUB_ENV # echo "HF_PFX_PASSPHRASE=${{secrets.pfx_key}}" >> $GITHUB_ENV diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index b41304100f..5cfc566717 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -49,32 +49,32 @@ jobs: shell: bash id: buildenv1 run: | - echo "GIT_COMMIT_SHORT=`echo $GIT_COMMIT | cut -c1-7`" >> $GITHUB_ENV - echo "JOB_NAME=`build (${{matrix.os}}, ${{matrix.build_type}})`" >> $GITHUB_ENV + echo "GIT_COMMIT_SHORT=echo $GIT_COMMIT | cut -c1-7" >> $GITHUB_ENV + echo "JOB_NAME=build (${{matrix.os}}, ${{matrix.build_type}})" >> $GITHUB_ENV # Linux build variables if [[ "${{ matrix.os }}" = "ubuntu-"* ]]; then echo "PYTHON_EXEC=python3" >> $GITHUB_ENV echo "INSTALLER_EXT=*" >> $GITHUB_ENV - echo "CMAKE_BUILD_EXTRA=`-- -j3`" >> $GITHUB_ENV - echo "CMAKE_EXTRA=`-DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)`" >> $GITHUB_ENV + echo "CMAKE_BUILD_EXTRA=-- -j3" >> $GITHUB_ENV + echo "CMAKE_EXTRA=-DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)" >> $GITHUB_ENV fi # Mac build variables if [ "${{ matrix.os }}" = "macOS-latest" ]; then echo "PYTHON_EXEC=python3" >> $GITHUB_ENV echo "INSTALLER_EXT=dmg" >> $GITHUB_ENV - echo "CMAKE_EXTRA=`-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode`" >> $GITHUB_ENV + echo "CMAKE_EXTRA=-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode" >> $GITHUB_ENV fi # Windows build variables if [ "${{ matrix.os }}" = "windows-latest" ]; then echo "PYTHON_EXEC=python" >> $GITHUB_ENV echo "INSTALLER_EXT=exe" >> $GITHUB_ENV - echo "CMAKE_EXTRA=`-A x64`" >> $GITHUB_ENV + echo "CMAKE_EXTRA=-A x64" >> $GITHUB_ENV fi # Android + Quest build variables if [[ "${{ matrix.build_type }}" == "android" ]]; then HIFI_ANDROID_PRECOMPILED="${{runner.workspace}}/dependencies" - echo "HIFI_ANDROID_PRECOMPILED=`$HIFI_ANDROID_PRECOMPILED`" >> $GITHUB_ENV + echo "HIFI_ANDROID_PRECOMPILED=$HIFI_ANDROID_PRECOMPILED" >> $GITHUB_ENV mkdir $HIFI_ANDROID_PRECOMPILED echo "INSTALLER_EXT=apk" >> $GITHUB_ENV fi From 57729e3cef0e142054b0f21c807f550396697028 Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Wed, 18 Nov 2020 11:38:50 +1300 Subject: [PATCH 073/136] Remove single quotes Per commit be55993 by HifiExperiments. --- .github/workflows/pr_build.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 5eb8e2a647..d0fa2b8883 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -43,27 +43,27 @@ jobs: shell: bash id: buildenv1 run: | - echo "GIT_COMMIT_SHORT=`echo $GIT_COMMIT | cut -c1-7`" >> $GITHUB_ENV - echo "JOB_NAME=`build (${{matrix.os}}, ${{matrix.build_type}})`" >> $GITHUB_ENV + echo "GIT_COMMIT_SHORT=echo $GIT_COMMIT | cut -c1-7" >> $GITHUB_ENV + echo "JOB_NAME=build (${{matrix.os}}, ${{matrix.build_type}})" >> $GITHUB_ENV # Linux build variables if [[ "${{ matrix.os }}" = "ubuntu-"* ]]; then echo "PYTHON_EXEC=python3" >> $GITHUB_ENV echo "INSTALLER_EXT=*" >> $GITHUB_ENV - echo "CMAKE_BUILD_EXTRA=`-- -j3`" >> $GITHUB_ENV - echo "CMAKE_EXTRA=`-DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)`" >> $GITHUB_ENV + echo "CMAKE_BUILD_EXTRA=-- -j3" >> $GITHUB_ENV + echo "CMAKE_EXTRA=-DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)" >> $GITHUB_ENV fi # Mac build variables if [ "${{ matrix.os }}" = "macOS-latest" ]; then echo "PYTHON_EXEC=python3" >> $GITHUB_ENV echo "INSTALLER_EXT=dmg" >> $GITHUB_ENV - echo "CMAKE_EXTRA=`-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode`" >> $GITHUB_ENV + echo "CMAKE_EXTRA=-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode" >> $GITHUB_ENV fi # Windows build variables if [ "${{ matrix.os }}" = "windows-latest" ]; then echo "PYTHON_EXEC=python" >> $GITHUB_ENV echo "INSTALLER_EXT=exe" >> $GITHUB_ENV - echo "CMAKE_EXTRA=`-A x64`" >> $GITHUB_ENV + echo "CMAKE_EXTRA=-A x64" >> $GITHUB_ENV fi # Configuration is broken into two steps because you can't set an env var and also reference it in the same step - name: Configure Build Environment 2 From 17f579882a3a1f7a3e93e87440d84e1f4a97cd44 Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Tue, 17 Nov 2020 15:09:50 -0800 Subject: [PATCH 074/136] try fixing commit short --- .github/workflows/master_build.yml | 3 ++- .github/workflows/pr_build.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/master_build.yml b/.github/workflows/master_build.yml index a09844608f..e264ba7937 100644 --- a/.github/workflows/master_build.yml +++ b/.github/workflows/master_build.yml @@ -49,7 +49,8 @@ jobs: id: buildenv1 run: | echo "UPLOAD_PREFIX=master" >> $GITHUB_ENV - echo "GIT_COMMIT_SHORT=echo $GIT_COMMIT | cut -c1-7" >> $GITHUB_ENV + GIT_COMMIT_SHORT=echo $GIT_COMMIT | cut -c1-7 + echo "GIT_COMMIT_SHORT=$GIT_COMMIT_SHORT" >> $GITHUB_ENV echo "JOB_NAME=build (${{matrix.os}}, ${{matrix.build_type}})" >> $GITHUB_ENV # Linux build variables if [[ "${{ matrix.os }}" = "ubuntu-"* ]]; then diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 5cfc566717..9907109e9c 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -49,7 +49,8 @@ jobs: shell: bash id: buildenv1 run: | - echo "GIT_COMMIT_SHORT=echo $GIT_COMMIT | cut -c1-7" >> $GITHUB_ENV + GIT_COMMIT_SHORT=echo $GIT_COMMIT | cut -c1-7 + echo "GIT_COMMIT_SHORT=$GIT_COMMIT_SHORT" >> $GITHUB_ENV echo "JOB_NAME=build (${{matrix.os}}, ${{matrix.build_type}})" >> $GITHUB_ENV # Linux build variables From c2990263783db204cc40e0e8968f8d0e4f143838 Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Wed, 18 Nov 2020 14:52:58 +1300 Subject: [PATCH 075/136] Calculate short SHA --- .github/workflows/pr_build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index d0fa2b8883..2558cb153c 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -43,7 +43,8 @@ jobs: shell: bash id: buildenv1 run: | - echo "GIT_COMMIT_SHORT=echo $GIT_COMMIT | cut -c1-7" >> $GITHUB_ENV + echo ::set-output name=github_sha_short::`echo $GIT_COMMIT | cut -c1-7` + echo "GIT_COMMIT_SHORT={{github_sha_sort}}" >> $GITHUB_ENV echo "JOB_NAME=build (${{matrix.os}}, ${{matrix.build_type}})" >> $GITHUB_ENV # Linux build variables From 6c8b11dddaca9fbc86a934b2ee33d524940634f2 Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Wed, 18 Nov 2020 16:54:21 +1300 Subject: [PATCH 076/136] Typo --- .github/workflows/pr_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 2558cb153c..a8caa1c6bd 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -44,7 +44,7 @@ jobs: id: buildenv1 run: | echo ::set-output name=github_sha_short::`echo $GIT_COMMIT | cut -c1-7` - echo "GIT_COMMIT_SHORT={{github_sha_sort}}" >> $GITHUB_ENV + echo "GIT_COMMIT_SHORT={{github_sha_short}}" >> $GITHUB_ENV echo "JOB_NAME=build (${{matrix.os}}, ${{matrix.build_type}})" >> $GITHUB_ENV # Linux build variables From 066dd2a6cc695713c4ab48c564e952679e04a733 Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Wed, 18 Nov 2020 20:49:47 +1300 Subject: [PATCH 077/136] Typo --- .github/workflows/pr_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index a8caa1c6bd..1e8b7e53ad 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -44,7 +44,7 @@ jobs: id: buildenv1 run: | echo ::set-output name=github_sha_short::`echo $GIT_COMMIT | cut -c1-7` - echo "GIT_COMMIT_SHORT={{github_sha_short}}" >> $GITHUB_ENV + echo "GIT_COMMIT_SHORT=${{github_sha_short}}" >> $GITHUB_ENV echo "JOB_NAME=build (${{matrix.os}}, ${{matrix.build_type}})" >> $GITHUB_ENV # Linux build variables From ea77db85d3734ab18a28b574f0217540303b5996 Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Wed, 18 Nov 2020 21:06:29 +1300 Subject: [PATCH 078/136] Use output var in second step --- .github/workflows/pr_build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 1e8b7e53ad..d975957d55 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -44,7 +44,6 @@ jobs: id: buildenv1 run: | echo ::set-output name=github_sha_short::`echo $GIT_COMMIT | cut -c1-7` - echo "GIT_COMMIT_SHORT=${{github_sha_short}}" >> $GITHUB_ENV echo "JOB_NAME=build (${{matrix.os}}, ${{matrix.build_type}})" >> $GITHUB_ENV # Linux build variables @@ -73,7 +72,8 @@ jobs: echo "${{ steps.buildenv1.outputs.symbols_archive }}" echo "ARTIFACT_PATTERN=Vircadia-Alpha-PR${{ github.event.number }}-*.$INSTALLER_EXT" >> $GITHUB_ENV # Build type variables - echo "INSTALLER=Vircadia-Alpha-$RELEASE_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT" >> $GITHUB_ENV + echo "GIT_COMMIT_SHORT=${{github_sha_short}}" >> $GITHUB_ENV + echo "INSTALLER=Vircadia-Alpha-$RELEASE_NUMBER-${{ github_sha_short }}.$INSTALLER_EXT" >> $GITHUB_ENV - name: Clear Working Directory if: startsWith(matrix.os, 'windows') shell: bash From e8520becd6dce9fad55111713b7315b8c9162e04 Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Wed, 18 Nov 2020 21:11:48 +1300 Subject: [PATCH 079/136] Syntax --- .github/workflows/pr_build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index d975957d55..d1662e5c8e 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -72,8 +72,8 @@ jobs: echo "${{ steps.buildenv1.outputs.symbols_archive }}" echo "ARTIFACT_PATTERN=Vircadia-Alpha-PR${{ github.event.number }}-*.$INSTALLER_EXT" >> $GITHUB_ENV # Build type variables - echo "GIT_COMMIT_SHORT=${{github_sha_short}}" >> $GITHUB_ENV - echo "INSTALLER=Vircadia-Alpha-$RELEASE_NUMBER-${{ github_sha_short }}.$INSTALLER_EXT" >> $GITHUB_ENV + echo "GIT_COMMIT_SHORT=${{ steps.buildenv1.outputs.github_sha_short }}" >> $GITHUB_ENV + echo "INSTALLER=Vircadia-Alpha-$RELEASE_NUMBER-${{ steps.buildenv1.outputs.github_sha_short }}.$INSTALLER_EXT" >> $GITHUB_ENV - name: Clear Working Directory if: startsWith(matrix.os, 'windows') shell: bash From 1e07971d10ae43089b9eea0d9c0044e72109ac86 Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Tue, 17 Nov 2020 18:53:24 -0800 Subject: [PATCH 080/136] how about this --- .github/workflows/master_build.yml | 4 ++-- .github/workflows/pr_build.yml | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/master_build.yml b/.github/workflows/master_build.yml index e264ba7937..6d23257899 100644 --- a/.github/workflows/master_build.yml +++ b/.github/workflows/master_build.yml @@ -49,8 +49,7 @@ jobs: id: buildenv1 run: | echo "UPLOAD_PREFIX=master" >> $GITHUB_ENV - GIT_COMMIT_SHORT=echo $GIT_COMMIT | cut -c1-7 - echo "GIT_COMMIT_SHORT=$GIT_COMMIT_SHORT" >> $GITHUB_ENV + echo ::set-output name=github_sha_short::`echo $GIT_COMMIT | cut -c1-7` echo "JOB_NAME=build (${{matrix.os}}, ${{matrix.build_type}})" >> $GITHUB_ENV # Linux build variables if [[ "${{ matrix.os }}" = "ubuntu-"* ]]; then @@ -87,6 +86,7 @@ jobs: echo "${{ steps.buildenv1.outputs.symbols_archive }}" echo "ARTIFACT_PATTERN=Vircadia-Alpha-*.$INSTALLER_EXT" >> $GITHUB_ENV # Build type variables + echo "GIT_COMMIT_SHORT=${{ steps.buildenv1.outputs.github_sha_short }}" >> $GITHUB_ENV if [ "${{ matrix.build_type }}" = "full" ]; then echo "CLIENT_ONLY=FALSE" >> $GITHUB_ENV echo "INSTALLER=Vircadia-Alpha-$BUILD_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT" >> $GITHUB_ENV diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 9907109e9c..757a6fd7c8 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -22,7 +22,6 @@ env: # WIN32 specific variables PreferredToolArchitecture: X64 - GIT_COMMIT_SHORT: ${{ github.sha }} jobs: @@ -49,8 +48,7 @@ jobs: shell: bash id: buildenv1 run: | - GIT_COMMIT_SHORT=echo $GIT_COMMIT | cut -c1-7 - echo "GIT_COMMIT_SHORT=$GIT_COMMIT_SHORT" >> $GITHUB_ENV + echo ::set-output name=github_sha_short::`echo $GIT_COMMIT | cut -c1-7` echo "JOB_NAME=build (${{matrix.os}}, ${{matrix.build_type}})" >> $GITHUB_ENV # Linux build variables @@ -84,6 +82,7 @@ jobs: shell: bash run: | echo "${{ steps.buildenv1.outputs.symbols_archive }}" + echo "GIT_COMMIT_SHORT=${{ steps.buildenv1.outputs.github_sha_short }}" >> $GITHUB_ENV if [[ "${{ matrix.build_type }}" != "android" ]]; then echo "ARTIFACT_PATTERN=Vircadia-Alpha-PR${{ github.event.number }}-*.$INSTALLER_EXT" >> $GITHUB_ENV # Build type variables From 031b3985b03bf120fff8cb1822d0db34f77a94fa Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 18 Nov 2020 23:14:34 -0500 Subject: [PATCH 081/136] Fix for Issue 869 This excludes the local and avatar entities from what is returns by Entities.getChildrenIDs to avoid the selection tools of the Zone entities to be considered as Children of it. This was necessary for the display of the hierarchy status, but also for the "Add Children to Selection". --- scripts/system/create/edit.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index 099cb94988..a8b829c551 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -2908,7 +2908,7 @@ function zoneSortOrder(a, b) { function getParentState(id) { var state = "NONE"; var properties = Entities.getEntityProperties(id, ["parentID"]); - var children = Entities.getChildrenIDs(id); + var children = getDomainOnlyChildrenIDs(id); if (properties.parentID !== Uuid.NULL) { if (children.length > 0) { state = "PARENT_CHILDREN"; @@ -2923,4 +2923,17 @@ function getParentState(id) { return state; } +function getDomainOnlyChildrenIDs(id) { + var allChildren = Entities.getChildrenIDs(id); + var domainOnlyChildren = []; + var properties; + for (var i = 0; i < allChildren.length; i++) { + properties = Entities.getEntityProperties(allChildren[i], ["entityHostType"]); + if (properties.entityHostType == "domain") { + domainOnlyChildren.push(allChildren[i]); + } + } + return domainOnlyChildren; +} + }()); // END LOCAL_SCOPE From 22abf1c2c47aca06e7637b4a3aea48b9b4e26115 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 18 Nov 2020 23:15:23 -0500 Subject: [PATCH 082/136] Fix for Issue 869 This excludes the local and avatar entities from what is returns by Entities.getChildrenIDs to avoid the selection tools of the Zone entities to be considered as Children of it. This was necessary for the display of the hierarchy status, but also for the "Add Children to Selection". --- .../create/entitySelectionTool/entitySelectionTool.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/system/create/entitySelectionTool/entitySelectionTool.js b/scripts/system/create/entitySelectionTool/entitySelectionTool.js index 71edbde765..f9a30ef6a5 100644 --- a/scripts/system/create/entitySelectionTool/entitySelectionTool.js +++ b/scripts/system/create/entitySelectionTool/entitySelectionTool.js @@ -724,12 +724,12 @@ SelectionManager = (function() { that.addChildrenToSelection = function() { if (that.hasSelection()) { for (var i = 0; i < that.selections.length; i++) { - var childrenIDs = Entities.getChildrenIDs(that.selections[i]); - var collectNewChildren; + var childrenIDs = getDomainOnlyChildrenIDs(that.selections[i]); + var collectNewChildren; var j; var k = 0; do { - collectNewChildren = Entities.getChildrenIDs(childrenIDs[k]); + collectNewChildren = getDomainOnlyChildrenIDs(childrenIDs[k]); if (collectNewChildren.length > 0) { for (j = 0; j < collectNewChildren.length; j++) { childrenIDs.push(collectNewChildren[j]); @@ -746,7 +746,7 @@ SelectionManager = (function() { that._update(true, this); } else { audioFeedback.rejection(); - Window.notifyEditError("You have nothing selected."); + Window.notifyEditError("You have nothing selected."); } }; @@ -832,7 +832,7 @@ SelectionDisplay = (function() { const BOUNDING_EDGE_OFFSET = 0.5; - const DUPLICATOR_OFFSET = { x: 0.6, y: 0, z: 0.6 }; + const DUPLICATOR_OFFSET = { x: 0.6, y: 0, z: 0.6 }; const CTRL_KEY_CODE = 16777249; From d9255eed953517a87c95cb9e3b10445e32e3f13e Mon Sep 17 00:00:00 2001 From: kasenvr <52365539+kasenvr@users.noreply.github.com> Date: Fri, 20 Nov 2020 04:12:07 -0500 Subject: [PATCH 083/136] Update pr_build.yml --- .github/workflows/pr_build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index d1662e5c8e..b427b3dde7 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -14,7 +14,8 @@ env: RELEASE_TYPE: PR RELEASE_NUMBER: ${{ github.event.number }} VERSION_CODE: ${{ github.event.number }} - + CMAKE_BACKTRACE_URL: https://sentry.vircadia.dev/api/2/minidump/?sentry_key=ab9aab2b0d6e46b59d6f06a97048d37e + CMAKE_BACKTRACE_TOKEN: PR_${{ github.event.number }}_${{ github.sha }} # OSX specific variables DEVELOPER_DIR: /Applications/Xcode_11.2.app/Contents/Developer From 84b6736e68922db1bc03a539d2a2e37611a8f2ea Mon Sep 17 00:00:00 2001 From: kasenvr <52365539+kasenvr@users.noreply.github.com> Date: Fri, 20 Nov 2020 04:13:02 -0500 Subject: [PATCH 084/136] Update pr_build.yml --- .github/workflows/pr_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index b427b3dde7..3dfef41db4 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -14,7 +14,7 @@ env: RELEASE_TYPE: PR RELEASE_NUMBER: ${{ github.event.number }} VERSION_CODE: ${{ github.event.number }} - CMAKE_BACKTRACE_URL: https://sentry.vircadia.dev/api/2/minidump/?sentry_key=ab9aab2b0d6e46b59d6f06a97048d37e + CMAKE_BACKTRACE_URL: https://sentry.vircadia.dev/api/2/minidump/?sentry_key=dbf6000201a442e0b5462b63e18ee6b1 CMAKE_BACKTRACE_TOKEN: PR_${{ github.event.number }}_${{ github.sha }} # OSX specific variables From f7b0437bc8cc8419a6eae4d9691384a6ff72fb5a Mon Sep 17 00:00:00 2001 From: Kalila L <somnilibertas@gmail.com> Date: Sat, 21 Nov 2020 00:03:56 -0500 Subject: [PATCH 085/136] Initial add of crash report arg option. --- interface/src/main.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index c14d22bdbb..f63e19f6b0 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>", "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,12 @@ 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 forceCrashReporting = false; + if (parser.isSet(forceCrashReportingOption)) { + forceCrashReporting = true; + } + qDebug() << "Crash handler logger is enabled:" << (forceCrashReporting || ual.isCrashMonitorEnabled()); + if (forceCrashReporting || ual.isCrashMonitorEnabled()) { auto crashHandlerStarted = startCrashHandler(argv[0]); qDebug() << "Crash handler started:" << crashHandlerStarted; } From 8f0684abfd635dbde5e2ce4ed503de347332ba2c Mon Sep 17 00:00:00 2001 From: kasenvr <52365539+kasenvr@users.noreply.github.com> Date: Sat, 21 Nov 2020 14:24:23 -0500 Subject: [PATCH 086/136] Update pr_build.yml --- .github/workflows/pr_build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 3dfef41db4..a554cb5270 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -14,6 +14,7 @@ env: RELEASE_TYPE: PR RELEASE_NUMBER: ${{ github.event.number }} VERSION_CODE: ${{ github.event.number }} + # Sentry Crash Reporting CMAKE_BACKTRACE_URL: https://sentry.vircadia.dev/api/2/minidump/?sentry_key=dbf6000201a442e0b5462b63e18ee6b1 CMAKE_BACKTRACE_TOKEN: PR_${{ github.event.number }}_${{ github.sha }} From 00575ae8f88c40f67679277cbdbe6fc8cc8f5996 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sat, 21 Nov 2020 15:43:12 -0500 Subject: [PATCH 087/136] Excluding EntityShapeVisualizer from Children list Excluding EntityShapeVisualizer from Children list Now a name is given to the EntityShape of the EntityShapeVisualizer (used to display the zone) so we can now exclude them from the children list when it's time to figure if there are children for an entity. (This is a better approach than excluding al the local entities) The name has been used because it gives better results than trying to use the id map that arrive always too late. The name is unique for a session, it includes a UUID. --- scripts/system/create/edit.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index a8b829c551..3c6f43d3a1 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -117,8 +117,10 @@ var gridTool = new GridTool({ }); gridTool.setVisible(false); +var entityShapeVisualizerSessionName = "SHAPE_VISUALIZER_" + Uuid.generate(); + var EntityShapeVisualizer = Script.require('./modules/entityShapeVisualizer.js'); -var entityShapeVisualizer = new EntityShapeVisualizer(["Zone"]); +var entityShapeVisualizer = new EntityShapeVisualizer(["Zone"], entityShapeVisualizerSessionName); var entityListTool = new EntityListTool(shouldUseEditTabletApp); @@ -2925,15 +2927,15 @@ function getParentState(id) { function getDomainOnlyChildrenIDs(id) { var allChildren = Entities.getChildrenIDs(id); - var domainOnlyChildren = []; + var realChildren = []; var properties; for (var i = 0; i < allChildren.length; i++) { - properties = Entities.getEntityProperties(allChildren[i], ["entityHostType"]); - if (properties.entityHostType == "domain") { - domainOnlyChildren.push(allChildren[i]); + properties = Entities.getEntityProperties(allChildren[i], ["name"]); + if (properties.name !== entityShapeVisualizerSessionName && properties.name !== undefined) { + realChildren.push(allChildren[i]); } } - return domainOnlyChildren; + return realChildren; } }()); // END LOCAL_SCOPE From b633bc4a164ecfa44ce7b063b5bf2e676d2b4672 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sat, 21 Nov 2020 15:44:15 -0500 Subject: [PATCH 088/136] Excluding EntityShapeVisualizer from Children list Excluding EntityShapeVisualizer from Children list Now a name is given to the EntityShape of the EntityShapeVisualizer (used to display the zone) so we can now exclude them from the children list when it's time to figure if there are children for an entity. (This is a better approach than excluding al the local entities) The name has been used because it gives better results than trying to use the id map that arrive always too late. The name is unique for a session, it includes a UUID. --- .../system/create/modules/entityShapeVisualizer.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/scripts/system/create/modules/entityShapeVisualizer.js b/scripts/system/create/modules/entityShapeVisualizer.js index dbf09a1cb7..45cf68fdb5 100644 --- a/scripts/system/create/modules/entityShapeVisualizer.js +++ b/scripts/system/create/modules/entityShapeVisualizer.js @@ -116,12 +116,14 @@ function deepCopy(v) { return JSON.parse(JSON.stringify(v)); } -function EntityShape(entityID) { +function EntityShape(entityID, entityShapeVisualizerSessionName) { this.entityID = entityID; + this.entityShapeVisualizerSessionName = entityShapeVisualizerSessionName; + var propertiesForType = getEntityShapePropertiesForType(Entities.getEntityProperties(entityID, REQUESTED_ENTITY_SHAPE_PROPERTIES)); this.previousPropertiesForType = propertiesForType; - + this.initialize(propertiesForType); } @@ -130,6 +132,7 @@ EntityShape.prototype = { // Create new instance of JS object: var overlayProperties = deepCopy(properties); + overlayProperties.name = this.entityShapeVisualizerSessionName; overlayProperties.localPosition = Vec3.ZERO; overlayProperties.localRotation = Quat.IDENTITY; overlayProperties.canCastShadows = false; @@ -172,11 +175,11 @@ EntityShape.prototype = { } }; -function EntityShapeVisualizer(visualizedTypes) { +function EntityShapeVisualizer(visualizedTypes, entityShapeVisualizerSessionName) { this.acceptedEntities = []; this.ignoredEntities = []; this.entityShapes = {}; - + this.entityShapeVisualizerSessionName = entityShapeVisualizerSessionName; this.visualizedTypes = visualizedTypes; } @@ -185,7 +188,7 @@ EntityShapeVisualizer.prototype = { if (this.entityShapes[entityID]) { return; } - this.entityShapes[entityID] = new EntityShape(entityID); + this.entityShapes[entityID] = new EntityShape(entityID, this.entityShapeVisualizerSessionName); }, updateEntity: function(entityID) { From c4092a35e34547edd706de4c8a5b3cd6377b181e Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Sun, 22 Nov 2020 14:08:36 +1300 Subject: [PATCH 089/136] Fix GHA master build target branch --- .github/workflows/master_build.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/master_build.yml b/.github/workflows/master_build.yml index 824c279845..d6e4f648c5 100644 --- a/.github/workflows/master_build.yml +++ b/.github/workflows/master_build.yml @@ -3,8 +3,7 @@ name: Master CI Build on: push: branches: - - gha-master-ci -# FIXME: Change target branch to "master" before merging into "master" branch. + - master env: APP_NAME: interface From 343ded8c6f9cea43e1570e31d50c531ee18307e8 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sat, 21 Nov 2020 22:02:49 -0500 Subject: [PATCH 090/136] Minor code adjustments Minor code adjustments --- scripts/system/create/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index 3c6f43d3a1..bc7afd8dc3 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -2931,7 +2931,7 @@ function getDomainOnlyChildrenIDs(id) { var properties; for (var i = 0; i < allChildren.length; i++) { properties = Entities.getEntityProperties(allChildren[i], ["name"]); - if (properties.name !== entityShapeVisualizerSessionName && properties.name !== undefined) { + if (properties.name !== undefined && properties.name !== entityShapeVisualizerSessionName) { realChildren.push(allChildren[i]); } } From b865e9bc8cde9eefb835a62ae1c372246daedcb7 Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Mon, 23 Nov 2020 16:02:32 +1300 Subject: [PATCH 091/136] Fix laser intersection with HUD overlay dialogs Also fixes dialog resize outline being drawn in the wrong position (desktop and HMD). --- interface/resources/qml/desktop/Desktop.qml | 4 ++-- interface/resources/qml/windows/Frame.qml | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) 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/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 From eb70d15f77a0dbafd8567ad528c0138482527663 Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Mon, 23 Nov 2020 19:13:48 +1300 Subject: [PATCH 092/136] Fix JSDoc typo --- libraries/script-engine/src/Quat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 <code>pitch</code>, <code>yaw</code>, and <code>roll</code> Euler angles. * @example <caption>Create a rotation of 180 degrees about the y axis.</caption> - * var rotation = Quat.fromPitchYawRollDgrees(0, 180, 0 ); + * var rotation = Quat.fromPitchYawRollDegrees(0, 180, 0 ); */ glm::quat fromPitchYawRollDegrees(float pitch, float yaw, float roll); From 2222f8f4f66b8a7d4a138591e6ee9e8c6509e2e7 Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Wed, 25 Nov 2020 11:54:19 +1300 Subject: [PATCH 093/136] Fix collision hull not necessarily being updated when model URL changed --- libraries/physics/src/PhysicalEntitySimulation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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); From 9b253c3a326852990d9e81cd93938ccce43b07ec Mon Sep 17 00:00:00 2001 From: kasenvr <52365539+kasenvr@users.noreply.github.com> Date: Wed, 25 Nov 2020 16:27:46 -0500 Subject: [PATCH 094/136] Update interface/src/main.cpp Co-authored-by: David Rowe <david@ctrlaltstudio.com> --- interface/src/main.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index f63e19f6b0..d190e3f3da 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -220,12 +220,9 @@ int main(int argc, const char* argv[]) { } qDebug() << "UserActivityLogger is enabled:" << ual.isEnabled(); - bool forceCrashReporting = false; - if (parser.isSet(forceCrashReportingOption)) { - forceCrashReporting = true; - } - qDebug() << "Crash handler logger is enabled:" << (forceCrashReporting || ual.isCrashMonitorEnabled()); - if (forceCrashReporting || 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; } From 2ece568f09a479fdedba69c4811ee10254abf78f Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Fri, 27 Nov 2020 15:04:56 -0800 Subject: [PATCH 095/136] fixing up simple-compound logic --- .../src/RenderableModelEntityItem.cpp | 25 +++++++++++++++---- .../src/RenderableModelEntityItem.h | 3 +++ libraries/entities/src/ModelEntityItem.cpp | 16 +++++++----- libraries/entities/src/ModelEntityItem.h | 1 - 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 392d2a748c..d6b7313ae7 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -250,8 +250,12 @@ 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<ModelCache>()->getCollisionGeometryResource(getCompoundShapeURL()); + _collisionGeometryResource = DependencyManager::get<ModelCache>()->getCollisionGeometryResource(getCollisionShapeURL()); if (_collisionGeometryResource) { if (_collisionGeometryResource->isLoaded()) { markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); @@ -276,10 +280,10 @@ void RenderableModelEntityItem::setShapeType(ShapeType type) { ModelEntityItem::setShapeType(type); auto shapeType = getShapeType(); if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { - if (!_collisionGeometryResource && !getCompoundShapeURL().isEmpty()) { + 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(); } @@ -290,7 +294,18 @@ void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) { ModelEntityItem::setCompoundShapeURL(url); if (url != currentCompoundShapeURL && !url.isEmpty()) { auto shapeType = getShapeType(); - if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { + 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(); } } @@ -300,7 +315,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() const { auto model = getModel(); auto shapeType = getShapeType(); if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { - auto shapeURL = getCompoundShapeURL(); + auto shapeURL = getCollisionShapeURL(); // we need a render geometry with a scale to proceed if (model && !model->getURL().isEmpty() && !shapeURL.isEmpty() && _dimensionsInitialized && model->isLoaded()) { if (!_collisionGeometryResource) { diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 09c07b3b84..4501f6d88c 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -75,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; @@ -119,6 +120,8 @@ private: bool readyToAnimate() const; void fetchCollisionGeometryResource(); + QString getCollisionShapeURL() const; + GeometryResource::Pointer _collisionGeometryResource; std::vector<int> _jointMap; QVariantMap _originalTextures; diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 8c3a729e41..4716db6a41 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -254,25 +254,29 @@ 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 = resultWithReadLock<ShapeType>([&] { return _shapeType; }); if (type == SHAPE_TYPE_STATIC_MESH && _dynamic) { // dynamic is incompatible with STATIC_MESH diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index b6d577dff0..b835b48d13 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -122,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); From c510a8fa3e00f786ed85ba1366faf0c0d0635811 Mon Sep 17 00:00:00 2001 From: HifiExperiments <thingsandstuffblog@gmail.com> Date: Fri, 27 Nov 2020 15:10:14 -0800 Subject: [PATCH 096/136] add comment about material sphere scale --- .../entities-renderer/src/RenderableMaterialEntityItem.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index 6b9ae6b4cf..3d2e59518c 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -21,6 +21,8 @@ void MaterialEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& 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); From 9a5b956968ebf6342784ead31709b9b63ac6cb82 Mon Sep 17 00:00:00 2001 From: HifiExperiments <53453710+HifiExperiments@users.noreply.github.com> Date: Fri, 27 Nov 2020 15:11:18 -0800 Subject: [PATCH 097/136] Apply suggestions from code review Co-authored-by: David Rowe <david@ctrlaltstudio.com> --- libraries/entities-renderer/src/RenderableModelEntityItem.cpp | 2 +- libraries/render-utils/src/Model.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index d6b7313ae7..e13ab6f837 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -704,7 +704,7 @@ void RenderableModelEntityItem::setJointMap(std::vector<int> jointMap) { int RenderableModelEntityItem::avatarJointIndex(int modelJointIndex) { int result = -1; - int mapSize = (int) _jointMap.size(); + int mapSize = (int)_jointMap.size(); if (modelJointIndex >= 0 && modelJointIndex < mapSize) { result = _jointMap[modelJointIndex]; } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 1015c87038..9ad343639d 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -975,7 +975,7 @@ void Model::setPrimitiveMode(PrimitiveMode primitiveMode, const render::ScenePoi render::Transaction transaction; - for (int i = 0; i < (int) _modelMeshRenderItemIDs.size(); i++) { + for (int i = 0; i < (int)_modelMeshRenderItemIDs.size(); i++) { auto itemID = _modelMeshRenderItemIDs[i]; auto meshIndex = _modelMeshRenderItemShapes[i].meshIndex; bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex); From 182302c3e75014ead9de65986139d088185b9606 Mon Sep 17 00:00:00 2001 From: Dale Glass <dale@daleglass.net> Date: Sat, 28 Nov 2020 02:07:08 +0100 Subject: [PATCH 098/136] GL_TEXTURE_FREE_MEMORY_ATI returns 4 values, not just 1 This should fix a buffer overflow that happens on ATI cards. --- libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp index ef247b0835..38aca093cd 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp @@ -219,19 +219,21 @@ void GLBackend::init() { } size_t GLBackend::getAvailableMemory() { - GLint mem; + // GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX returns 1 value + // GL_TEXTURE_FREE_MEMORY_ATI returns 4 values, we only need the first + GLint mem[4] = {0,0,0,0}; switch( _videoCard ) { case NVIDIA: #if !defined(Q_OS_ANDROID) - glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &mem); + glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &mem[0]); #endif - return mem * BYTES_PER_KIB; + return mem[0] * BYTES_PER_KIB; case ATI: #if !defined(Q_OS_ANDROID) - glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, &mem); + glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, &mem[0]); #endif - return mem * BYTES_PER_KIB; + return mem[0] * BYTES_PER_KIB; case MESA: return 0; // Don't know the current value case Unknown: @@ -1002,4 +1004,4 @@ void GLBackend::setCameraCorrection(const Mat4& correction, const Mat4& prevRend void GLBackend::syncProgram(const gpu::ShaderPointer& program) { gpu::gl::GLShader::sync(*this, *program); -} \ No newline at end of file +} From dec726b976f5cc9dbf28a25626faa2c79ded669f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20Gro=C3=9F?= <firedefender1@googlemail.com> Date: Sat, 28 Nov 2020 23:30:34 +0100 Subject: [PATCH 099/136] Update hifi_qt.py to recognize ubuntu version over 19.10 as not supported yet. --- hifi_qt.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hifi_qt.py b/hifi_qt.py index 10708e4bc9..d86b2ac6c7 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: From af9367ae29d092610854edc027fd399804282bc2 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Mon, 30 Nov 2020 00:34:09 -0500 Subject: [PATCH 100/136] Create App "tools" menu implementation Create App "tools" menu implementation --- scripts/system/libraries/gridTool.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/scripts/system/libraries/gridTool.js b/scripts/system/libraries/gridTool.js index 233ae3a3e4..90a6745ff4 100644 --- a/scripts/system/libraries/gridTool.js +++ b/scripts/system/libraries/gridTool.js @@ -4,7 +4,7 @@ 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; @@ -163,6 +163,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 && position.y === 0 && position.z === 0) { + position = MyAvatar.position; + } + that.setPosition(position); + }; that.emitUpdate = function() { if (that.onUpdate) { @@ -283,11 +291,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(); } From ab999e529dd891e5c3179deaaacad086157dd7b1 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Mon, 30 Nov 2020 00:35:15 -0500 Subject: [PATCH 101/136] Create App "tools" menu implementation Create App "tools" menu implementation --- scripts/system/html/css/edit-style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; From 21eee3c24e9b377e1812309b29008eebadb1a684 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Mon, 30 Nov 2020 00:36:15 -0500 Subject: [PATCH 102/136] Create App "tools" menu implementation Create App "tools" menu implementation --- scripts/system/create/edit.js | 86 ++++++++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 12 deletions(-) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index bc7afd8dc3..f49b19569a 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -148,7 +148,10 @@ 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"; @@ -880,13 +883,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() { @@ -1402,6 +1403,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({ @@ -1465,7 +1482,7 @@ function setupModelMenus() { menuItemName: MENU_ENTITY_LIST_DEFAULT_RADIUS, afterItem: MENU_SHOW_ZONES_IN_EDIT_MODE }); - + Entities.setLightsArePickable(false); } @@ -1484,7 +1501,10 @@ function cleanupModelMenus() { Menu.removeMenuItem(SUBMENU_ENTITY_EDITOR_PREFERENCES, MENU_SHOW_ZONES_IN_EDIT_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 () { @@ -1858,6 +1878,10 @@ function handleMenuEvent(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,11 +2039,7 @@ 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) { @@ -2938,4 +2958,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 From 7d364add6621f0fa0eca5bd0ce3c17a77b989ba2 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Mon, 30 Nov 2020 00:37:18 -0500 Subject: [PATCH 103/136] Create App "tools" menu implementation Create App "tools" menu implementation --- .../system/create/entityList/entityList.js | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index 58cf4ce892..8ca62e780f 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -381,7 +381,29 @@ 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') { + if (!grid.getSnapToGrid()) { + grid.setSnapToGrid(true); + emitJSONScriptEvent({ "type": "setSnapToGrid", "snap": true }); + } else { + grid.setSnapToGrid(false); + emitJSONScriptEvent({ "type": "setSnapToGrid", "snap": false }); + } } + + }; webView.webEventReceived.connect(onWebEventReceived); From 889b74dd045313b6ad0156dd9b8b49da8d197af4 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Mon, 30 Nov 2020 00:37:48 -0500 Subject: [PATCH 104/136] Create App "tools" menu implementation Create App "tools" menu implementation --- .../create/entityList/html/entityList.html | 69 +++++++++++++++++-- 1 file changed, 64 insertions(+), 5 deletions(-) diff --git a/scripts/system/create/entityList/html/entityList.html b/scripts/system/create/entityList/html/entityList.html index a5f27bd3a8..dc76b1a866 100644 --- a/scripts/system/create/entityList/html/entityList.html +++ b/scripts/system/create/entityList/html/entityList.html @@ -32,8 +32,9 @@ </div> <button id="toggle-space-mode" class="hifi-edit-button space-mode-local">Local</button> <input type="button" class="vglyph" id="hmdmultiselect" value="I" style="display: none;" /> - <input type="button" class="normal" id="selection" value="Selection..." /> - <input type="button" class="normal" id="actions" value="Actions..." /> + <input type="button" class="normal" id="selection" value="Select▾" /> + <input type="button" class="normal" id="actions" value="Edit▾" /> + <input type="button" class="normal" id="tools" value="Tools▾" /> </div> <div id="entity-list"> <div id="filter-area"> @@ -159,7 +160,7 @@ <div class="entity-list-menu" id="selection-menu" > <button class="menu-button" id="selectall" > <div class = "menu-item"> - <div class = "menu-item-caption">Select All</div> + <div class = "menu-item-caption">Select All (in List)</div> <div class = "menu-item-shortcut">Ctrl-A</div> </div> </button> @@ -171,7 +172,7 @@ </button> <button class="menu-button" id="selectinverse" > <div class = "menu-item"> - <div class = "menu-item-caption">Inverse Selection</div> + <div class = "menu-item-caption">Inverse Selection (in List)</div> <div class = "menu-item-shortcut">Ctrl-I</div> </div> </button> @@ -219,13 +220,71 @@ <div class = "menu-item-shortcut"></div> </div> </button> - <div class="menu-separator"></div> + </div> + <div class="entity-list-menu" id="tools-menu" > + <button class="menu-button" id="setCameraFocusToSelection" > + <div class = "menu-item"> + <div class = "menu-item-caption">Set Camera Focus To Selection</div> + <div class = "menu-item-shortcut">F</div> + </div> + </button> <button class="menu-button" id="teleport-to-entity" > <div class = "menu-item"> <div class = "menu-item-caption">Teleport To Selected Entities</div> <div class = "menu-item-shortcut"></div> </div> </button> + <div class="menu-separator"></div> + <button class="menu-button" id="toggleLocalWorldMode" > + <div class = "menu-item"> + <div class = "menu-item-caption">Toggle Local/World Mode</div> + <div class = "menu-item-shortcut">T</div> + </div> + </button> + <div class="menu-separator"></div> + <button class="menu-button" id="exportSelectedEntities" > + <div class = "menu-item"> + <div class = "menu-item-caption">Export Selected Entities</div> + <div class = "menu-item-shortcut"></div> + </div> + </button> + <button class="menu-button" id="importEntitiesFromFile" > + <div class = "menu-item"> + <div class = "menu-item-caption">Import Entities (.json) From a File</div> + <div class = "menu-item-shortcut"></div> + </div> + </button> + <button class="menu-button" id="importEntitiesFromUrl" > + <div class = "menu-item"> + <div class = "menu-item-caption">Import Entities (.json) From a URL</div> + <div class = "menu-item-shortcut"></div> + </div> + </button> + <div class="menu-separator"></div> + <button class="menu-button" id="gridActivator" > + <div class = "menu-item"> + <div class = "menu-item-caption">Toggle Grid</div> + <div class = "menu-item-shortcut"></div> + </div> + </button> + <button class="menu-button" id="snapToGridActivator" > + <div class = "menu-item"> + <div class = "menu-item-caption" id="snapToGridActivatorCaption">Activate Snap to Grid [OFF]</div> + <div class = "menu-item-shortcut"></div> + </div> + </button> + <button class="menu-button" id="alignGridToSelection" > + <div class = "menu-item"> + <div class = "menu-item-caption">Align Grid to Selected Entities</div> + <div class = "menu-item-shortcut">G</div> + </div> + </button> + <button class="menu-button" id="alignGridToAvatar" > + <div class = "menu-item"> + <div class = "menu-item-caption">Align Grid to Avatar</div> + <div class = "menu-item-shortcut"></div> + </div> + </button> </div> <div id="menuBackgroundOverlay" ></div> </body> From 64caa54d08abcb2696d1fb3a993d1550b0889091 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Mon, 30 Nov 2020 00:38:31 -0500 Subject: [PATCH 105/136] Create App "tools" menu implementation Create App "tools" menu implementation --- .../create/entityList/html/js/entityList.js | 71 ++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index 89eac5fb2f..7c882a4199 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -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, @@ -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"); @@ -318,8 +330,18 @@ function loaded() { elSelectTopParent = document.getElementById("selecttopparent"); elAddChildrenToSelection = document.getElementById("addchildrentoselection"); elSelectFamily = document.getElementById("selectfamily"); - elSelectTopFamily = document.getElementById("selecttopfamily"); + 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"); @@ -365,6 +387,10 @@ 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(); }; @@ -498,6 +524,42 @@ function loaded() { 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' })); }; @@ -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 [ON]"; + } else { + elSnapToGridActivatorCaption.innerHTML = "Activate Snap to Grid [OFF]"; + } } else if (data.type === "confirmHMDstate") { if (data.isHmd) { document.getElementById("hmdmultiselect").style.display = "inline"; @@ -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"; } } From 1f205365747e5d65512f00be364596a76df73f10 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 1 Dec 2020 00:12:27 -0500 Subject: [PATCH 106/136] Add Grid Actions Shortkeys Add Grid Actions Shortkeys Toggle Grid G Activate/Deactivate Snap to Grid H Align Grid to Selected Entities J Align Grid to Avatar K --- scripts/system/create/edit.js | 39 ++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index f49b19569a..8e0d3f2536 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -2044,9 +2044,22 @@ function focusKey(value) { } 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) { @@ -2391,7 +2404,7 @@ var PropertiesTool = function (opts) { } var i, properties, dY, diff, newPosition; if (data.type === "update") { - + if (data.properties || data.propertiesMap) { var propertiesMap = data.propertiesMap; if (propertiesMap === undefined) { @@ -2446,7 +2459,6 @@ var PropertiesTool = function (opts) { } } - if (data.onlyUpdateEntities) { blockPropertyUpdates = true; } else { @@ -2455,6 +2467,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); @@ -2809,7 +2825,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() })); @@ -2850,8 +2869,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") { From 6a31c19747c1f8a8d6fc8b4a783f02ca09812dae Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 1 Dec 2020 00:13:26 -0500 Subject: [PATCH 107/136] Add Grid Actions Shortkeys Add Grid Actions Shortkeys Toggle Grid G Activate/Deactivate Snap to Grid H Align Grid to Selected Entities J Align Grid to Avatar K --- .../system/create/entityList/entityList.js | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index 8ca62e780f..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 : ""; } @@ -394,16 +408,9 @@ EntityListTool = function(shouldUseEditTabletApp) { } else if (data.type === 'toggleGridVisibility') { toggleGridVisibility(); } else if (data.type === 'toggleSnapToGrid') { - if (!grid.getSnapToGrid()) { - grid.setSnapToGrid(true); - emitJSONScriptEvent({ "type": "setSnapToGrid", "snap": true }); - } else { - grid.setSnapToGrid(false); - emitJSONScriptEvent({ "type": "setSnapToGrid", "snap": false }); - } + that.toggleSnapToGrid(); } - }; webView.webEventReceived.connect(onWebEventReceived); From 71d0fb52e2c8b96a6458ebecc7987c2ec9076998 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 1 Dec 2020 00:14:15 -0500 Subject: [PATCH 108/136] Add Grid Actions Shortkeys Add Grid Actions Shortkeys Toggle Grid G Activate/Deactivate Snap to Grid H Align Grid to Selected Entities J Align Grid to Avatar K --- scripts/system/create/entityList/html/entityList.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/system/create/entityList/html/entityList.html b/scripts/system/create/entityList/html/entityList.html index dc76b1a866..9817f9ddf9 100644 --- a/scripts/system/create/entityList/html/entityList.html +++ b/scripts/system/create/entityList/html/entityList.html @@ -264,25 +264,25 @@ <button class="menu-button" id="gridActivator" > <div class = "menu-item"> <div class = "menu-item-caption">Toggle Grid</div> - <div class = "menu-item-shortcut"></div> + <div class = "menu-item-shortcut">G</div> </div> </button> <button class="menu-button" id="snapToGridActivator" > <div class = "menu-item"> - <div class = "menu-item-caption" id="snapToGridActivatorCaption">Activate Snap to Grid [OFF]</div> - <div class = "menu-item-shortcut"></div> + <div class = "menu-item-caption" id="snapToGridActivatorCaption">Activate Snap to Grid</div> + <div class = "menu-item-shortcut">H</div> </div> </button> <button class="menu-button" id="alignGridToSelection" > <div class = "menu-item"> <div class = "menu-item-caption">Align Grid to Selected Entities</div> - <div class = "menu-item-shortcut">G</div> + <div class = "menu-item-shortcut">J</div> </div> </button> <button class="menu-button" id="alignGridToAvatar" > <div class = "menu-item"> <div class = "menu-item-caption">Align Grid to Avatar</div> - <div class = "menu-item-shortcut"></div> + <div class = "menu-item-shortcut">K</div> </div> </button> </div> From bbde93f54b9e0398ae3a07cddd7cfb47ee12a229 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 1 Dec 2020 00:15:15 -0500 Subject: [PATCH 109/136] Add Grid Actions Shortkeys Add Grid Actions Shortkeys Toggle Grid G Activate/Deactivate Snap to Grid H Align Grid to Selected Entities J Align Grid to Avatar K --- scripts/system/create/entityList/html/js/entityList.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index 7c882a4199..73914c2851 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -1737,9 +1737,9 @@ function loaded() { setSpaceMode(data.spaceMode); } else if (data.type === "setSnapToGrid") { if (data.snap) { - elSnapToGridActivatorCaption.innerHTML = "Deactivate Snap to Grid [ON]"; + elSnapToGridActivatorCaption.innerHTML = "✓ Deactivate Snap to Grid"; } else { - elSnapToGridActivatorCaption.innerHTML = "Activate Snap to Grid [OFF]"; + elSnapToGridActivatorCaption.innerHTML = "Activate Snap to Grid"; } } else if (data.type === "confirmHMDstate") { if (data.isHmd) { From 0575971d12b59e60aa6ea8da549abff3699ab392 Mon Sep 17 00:00:00 2001 From: Kalila L <somnilibertas@gmail.com> Date: Tue, 1 Dec 2020 05:58:01 -0500 Subject: [PATCH 110/136] Fix references 'kasen/core' -> 'master' --- BUILD_LINUX.md | 6 ++++-- hifi_qt.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index f6287846ed..8d6062f5e6 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/kasenvr/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* @@ -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 diff --git a/hifi_qt.py b/hifi_qt.py index 10708e4bc9..b3b3681049 100644 --- a/hifi_qt.py +++ b/hifi_qt.py @@ -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/kasenvr/project-athena/tree/master/tools/qt-builder") raise Exception('UNKNOWN LINUX VERSION!!!') else: print("System : " + platform.system()) From 510eb08be1ea332daf34fc0d6aea52094da1fdef Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 1 Dec 2020 22:56:17 -0500 Subject: [PATCH 111/136] Replace Overlays by Local Entities 1- Replace Overlays by Local Entities 2- Add the missing header with copyright and license (I have assumed that the author was the same person that make the grid parameter that is referenced there and only used in create App.) 3- Minor requested code change (0.0 instead of 0 in condition using real numbers) --- scripts/system/libraries/gridTool.js | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/scripts/system/libraries/gridTool.js b/scripts/system/libraries/gridTool.js index 90a6745ff4..1dbe1fea4c 100644 --- a/scripts/system/libraries/gridTool.js +++ b/scripts/system/libraries/gridTool.js @@ -1,3 +1,12 @@ +// 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'); @@ -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; @@ -166,7 +176,7 @@ Grid = function() { that.moveToAvatar = function() { var position = MyAvatar.getJointPosition("LeftFoot"); - if (position.x === 0 && position.y === 0 && position.z === 0) { + if (position.x === 0.0 && position.y === 0.0 && position.z === 0.0) { position = MyAvatar.position; } that.setPosition(position); @@ -222,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, @@ -230,6 +240,7 @@ Grid = function() { color: gridColor, alpha: gridAlpha }); + if (!noUpdate) { that.emitUpdate(); @@ -237,7 +248,7 @@ Grid = function() { } function cleanup() { - Overlays.deleteOverlay(gridOverlay); + Entities.deleteEntity(gridEntityTool); } that.addListener = function(callback) { From 5a7188179912ae4ae29a88602ece6d7aacdc0ec6 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 1 Dec 2020 23:04:10 -0500 Subject: [PATCH 112/136] Minor code changes Minor code changes --- scripts/system/create/edit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index 8e0d3f2536..5f69548f6b 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -1482,7 +1482,7 @@ function setupModelMenus() { menuItemName: MENU_ENTITY_LIST_DEFAULT_RADIUS, afterItem: MENU_SHOW_ZONES_IN_EDIT_MODE }); - + Entities.setLightsArePickable(false); } @@ -2404,7 +2404,7 @@ var PropertiesTool = function (opts) { } var i, properties, dY, diff, newPosition; if (data.type === "update") { - + if (data.properties || data.propertiesMap) { var propertiesMap = data.propertiesMap; if (propertiesMap === undefined) { From 670d832c8be42bae74b0025bad329a23425bd55c Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 1 Dec 2020 23:32:52 -0500 Subject: [PATCH 113/136] Minor code change Minor code change --- .../create/entityList/html/js/entityList.js | 132 +++++++++--------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index 73914c2851..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 = []; @@ -279,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); } ; @@ -330,7 +330,7 @@ function loaded() { elSelectTopParent = document.getElementById("selecttopparent"); elAddChildrenToSelection = document.getElementById("addchildrentoselection"); elSelectFamily = document.getElementById("selectfamily"); - elSelectTopFamily = document.getElementById("selecttopfamily"); + elSelectTopFamily = document.getElementById("selecttopfamily"); elTeleportToEntity = document.getElementById("teleport-to-entity"); elSetCameraFocusToSelection = document.getElementById("setCameraFocusToSelection"); elToggleLocalWorldMode = document.getElementById("toggleLocalWorldMode"); @@ -357,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) { @@ -377,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"; @@ -395,43 +395,43 @@ function loaded() { 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() { @@ -493,31 +493,31 @@ 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 () { @@ -529,19 +529,19 @@ function loaded() { closeAllEntityListMenu(); }; elToggleLocalWorldMode.onclick = function () { - EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleSpaceMode' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "toggleSpaceMode" })); closeAllEntityListMenu(); }; elExportSelectedEntities.onclick = function () { - EventBridge.emitWebEvent(JSON.stringify({ type: 'export'})); + EventBridge.emitWebEvent(JSON.stringify({ type: "export"})); closeAllEntityListMenu(); }; elImportEntitiesFromFile.onclick = function () { - EventBridge.emitWebEvent(JSON.stringify({ type: 'importFromFile'})); + EventBridge.emitWebEvent(JSON.stringify({ type: "importFromFile"})); closeAllEntityListMenu(); }; elImportEntitiesFromUrl.onclick = function () { - EventBridge.emitWebEvent(JSON.stringify({ type: 'importFromUrl'})); + EventBridge.emitWebEvent(JSON.stringify({ type: "importFromUrl"})); closeAllEntityListMenu(); }; elGridActivator.onclick = function () { @@ -561,7 +561,7 @@ function loaded() { closeAllEntityListMenu(); }; elToggleSpaceMode.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleSpaceMode' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "toggleSpaceMode" })); }; elRefresh.onclick = refreshEntities; elFilterTypeMultiselectBox.onclick = onToggleTypeDropdown; @@ -579,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); @@ -591,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]; @@ -629,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; @@ -656,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); @@ -702,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(); @@ -767,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; } }); @@ -806,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); @@ -1009,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); @@ -1092,7 +1092,7 @@ function loaded() { } function refreshEntities() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'refresh' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "refresh" })); } function refreshFooter() { @@ -1119,7 +1119,7 @@ function loaded() { if (entity !== undefined) { entity.selected = false; if (entity.elRow) { - entity.elRow.className = ''; + entity.elRow.className = ""; } } }); @@ -1133,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 { @@ -1206,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 @@ -1264,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(); } @@ -1487,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(); @@ -1690,7 +1690,7 @@ function loaded() { } EventBridge.emitWebEvent(JSON.stringify({ - type: 'keyUpEvent', + type: "keyUpEvent", keyUpEvent: { code, key, @@ -1790,7 +1790,7 @@ function loaded() { } } } else { - EventBridge.emitWebEvent(JSON.stringify({ type: 'saveColumnsConfigSetting', columnsData: "" })); + EventBridge.emitWebEvent(JSON.stringify({ type: "saveColumnsConfigSetting", columnsData: "" })); } } isColumnsSettingLoaded = true; @@ -1803,7 +1803,7 @@ function loaded() { window.addEventListener("resize", updateColumnWidths); - EventBridge.emitWebEvent(JSON.stringify({ type: 'loadConfigSetting' })); + EventBridge.emitWebEvent(JSON.stringify({ type: "loadConfigSetting" })); }); augmentSpinButtons(); From 726901b087aa11ac4fb9944a14c7a9d85fb1de0f Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Fri, 4 Dec 2020 23:47:38 -0500 Subject: [PATCH 114/136] Make the Create Tool window larger by default Previously it was 490px wide (in Desktop) Now it will be 750 px wide (in Desktop) The properties tab is now with an acceptable size by default. (which is closer to the landscape display we have in HMD.) No change in HMD or in-Tablet display. --- scripts/system/create/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index 5f69548f6b..fc3d4fc10f 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; From 536bf4ef90240202acbe6b7931accdb50ae05aec Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Fri, 4 Dec 2020 23:50:44 -0500 Subject: [PATCH 115/136] 2 large import button in Desktop In Desktop mode, the 2 import buttons are now one over the other and full width. The text was overlapping with the default Create Tools window size. --- scripts/system/create/qml/EditToolsTabView.qml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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({ From 16cc5304ec2c1f6d9e7f5a8918ebf8f02e10bbad Mon Sep 17 00:00:00 2001 From: Kalila <69767640+digisomni@users.noreply.github.com> Date: Thu, 10 Dec 2020 17:49:41 -0500 Subject: [PATCH 116/136] Update pr_build.yml --- .github/workflows/pr_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index a554cb5270..e5a42f67c7 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -15,7 +15,7 @@ env: RELEASE_NUMBER: ${{ github.event.number }} VERSION_CODE: ${{ github.event.number }} # Sentry Crash Reporting - CMAKE_BACKTRACE_URL: https://sentry.vircadia.dev/api/2/minidump/?sentry_key=dbf6000201a442e0b5462b63e18ee6b1 + CMAKE_BACKTRACE_URL: ${{ secrets.MINIDUMP_TOKEN }} CMAKE_BACKTRACE_TOKEN: PR_${{ github.event.number }}_${{ github.sha }} # OSX specific variables From 15b1c51c4900c415673ed0990c9bee2893b881e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Dec 2020 22:54:46 +0000 Subject: [PATCH 117/136] Bump ini from 1.3.5 to 1.3.7 in /screenshare Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.7. - [Release notes](https://github.com/isaacs/ini/releases) - [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.7) Signed-off-by: dependabot[bot] <support@github.com> --- screenshare/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/screenshare/package-lock.json b/screenshare/package-lock.json index c7d92d3e17..0857ac396b 100644 --- a/screenshare/package-lock.json +++ b/screenshare/package-lock.json @@ -1091,9 +1091,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": { From f5485e858c27c204d1a84ded92ece4de3999c079 Mon Sep 17 00:00:00 2001 From: Kalila L <somnilibertas@gmail.com> Date: Thu, 10 Dec 2020 18:56:04 -0500 Subject: [PATCH 118/136] Licensing headers. --- domain-server/resources/metadata_exporter/index.html | 2 +- .../qml/hifi/dialogs/security/EntityScriptQMLWhitelist.qml | 4 ++-- interface/resources/qml/hifi/dialogs/security/Security.qml | 2 +- plugins/JSAPIExample/src/JSAPIExample.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) 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/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/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 From 5d4612e400f3e5bb41618d6fa9392282cfea72be Mon Sep 17 00:00:00 2001 From: Kalila L <somnilibertas@gmail.com> Date: Thu, 10 Dec 2020 18:56:57 -0500 Subject: [PATCH 119/136] Update 'kasenvr' -> 'vircadia' --- BUILD_ANDROID.md | 2 +- BUILD_LINUX.md | 4 ++-- BUILD_WIN.md | 2 +- CONTRIBUTING.md | 10 +++++----- README.md | 16 ++++++++-------- android/docker/Dockerfile | 2 +- .../resources/web/assignment/placeholder.js | 2 +- hifi_qt.py | 2 +- .../qml/hifi/dialogs/TabletAboutDialog.qml | 4 ++-- libraries/networking/src/NetworkingConstants.h | 2 +- pkg-scripts/README | 2 +- pkg-scripts/server-control | 4 ++-- pkg-scripts/vircadia-server.spec | 2 +- scripts/system/more/more.html | 4 ++-- server-console/package.json | 2 +- 15 files changed, 30 insertions(+), 30 deletions(-) diff --git a/BUILD_ANDROID.md b/BUILD_ANDROID.md index 0bea3e5a90..4998648227 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/project-athena.git` ## Building & Running diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index 8d6062f5e6..fa5d3ef206 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -4,7 +4,7 @@ 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/kasenvr/vircadia-builder) to build on Linux more easily. Alternatively, you can follow the manual steps below. +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 @@ -78,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/project-athena.git ``` To compile a DEV version checkout the branch you need. To get a list of all tags: diff --git a/BUILD_WIN.md b/BUILD_WIN.md index c057d9ca5d..aa94eb30de 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/project-athena) * Restart directions from Step #6 #### CMake gives you the same error message repeatedly after the build fails diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aeb6f49280..70ddd11ad6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,7 +20,7 @@ Contributing 6. Update your branch ``` - git remote add upstream https://github.com/kasenvr/project-athena + git remote add upstream https://github.com/vircadia/project-athena git pull upstream master ``` @@ -38,10 +38,10 @@ Contributing 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/project-athena/issues) to make sure that somebody has not already reported the same bug. +3. [Add](https://github.com/vircadia/project-athena/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/project-athena/issues) to make sure that somebody has not already requested the same feature. +2. [Add](https://github.com/vircadia/project-athena/issues/new) your request to the issues list! diff --git a/README.md b/README.md index baf333d81f..c4de956d1c 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/project-athena/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/project-athena/blob/master/BUILD_WIN.md) -[For Mac](https://github.com/kasenvr/project-athena/blob/master/BUILD_OSX.md) +[For Mac](https://github.com/vircadia/project-athena/blob/master/BUILD_OSX.md) -[For Linux](https://github.com/kasenvr/project-athena/blob/master/BUILD_LINUX.md) +[For Linux](https://github.com/vircadia/project-athena/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/project-athena/blob/master/INSTALL.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/docker/Dockerfile b/android/docker/Dockerfile index 144f6caffa..54f0a544df 100644 --- a/android/docker/Dockerfile +++ b/android/docker/Dockerfile @@ -72,7 +72,7 @@ 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/project-athena.git WORKDIR /home/gha/project-athena diff --git a/domain-server/resources/web/assignment/placeholder.js b/domain-server/resources/web/assignment/placeholder.js index 95c9903e32..b0b2f32c4f 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/project-athena/tree/master/script-archive/acScripts // The directory named acScripts contains assignment-client specific scripts you can try. diff --git a/hifi_qt.py b/hifi_qt.py index c59c7b1202..d08670c805 100644 --- a/hifi_qt.py +++ b/hifi_qt.py @@ -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/master/tools/qt-builder") + print("https://github.com/vircadia/project-athena/tree/master/tools/qt-builder") raise Exception('UNKNOWN LINUX VERSION!!!') else: print("System : " + platform.system()) diff --git a/interface/resources/qml/hifi/dialogs/TabletAboutDialog.qml b/interface/resources/qml/hifi/dialogs/TabletAboutDialog.qml index a943da32a0..09aba7c206 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: "<a href=\"https://github.com/kasenvr/project-athena\">Vircadia Github</a>." + text: "<a href=\"https://github.com/vircadia/project-athena\">Vircadia Github</a>." size: 20 onLinkActivated: { - About.openUrl("https:/github.com/kasenvr/project-athena"); + About.openUrl("https:/github.com/vircadia/project-athena"); } } diff --git a/libraries/networking/src/NetworkingConstants.h b/libraries/networking/src/NetworkingConstants.h index 58cefb35ad..642dd2426e 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/project-athena/issues" }; const QString DEFAULT_VIRCADIA_ADDRESS = "file:///~/serverless/tutorial.json"; const QString DEFAULT_HOME_ADDRESS = "file:///~/serverless/tutorial.json"; 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..c1a43876a3 100644 --- a/pkg-scripts/server-control +++ b/pkg-scripts/server-control @@ -5,8 +5,8 @@ Maintainer: Heather Anderson <heath@odysseus.anderson.name> 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/project-athena.git +Vcs-Browser: https://github.com/vircadia/project-athena 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/scripts/system/more/more.html b/scripts/system/more/more.html index db1f73cc85..9d9a7db257 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/project-athena // // // Distributed under the Apache License, Version 2.0. diff --git a/server-console/package.json b/server-console/package.json index 1ceed08d4d..b36db74670 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/project-athena.git" }, "main": "src/main.js", "scripts": { From e8a2de86bbb85355c0e18a22efec9a177c7150ac Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Sat, 12 Dec 2020 20:32:02 +1300 Subject: [PATCH 120/136] Update GitHub links --- BUILD_ANDROID.md | 2 +- BUILD_LINUX.md | 4 ++-- BUILD_WIN.md | 2 +- CONTRIBUTING.md | 10 +++++----- README.md | 16 ++++++++-------- android/docker/Dockerfile | 2 +- cmake/ports/etc2comp/portfile.cmake | 2 +- cmake/ports/hifi-scribe/portfile.cmake | 2 +- cmake/ports/nvtt/portfile.cmake | 2 +- .../resources/web/assignment/placeholder.js | 2 +- hifi_qt.py | 2 +- .../qml/hifi/dialogs/TabletAboutDialog.qml | 4 ++-- pkg-scripts/README | 2 +- pkg-scripts/server-control | 4 ++-- pkg-scripts/vircadia-server.spec | 2 +- scripts/system/more/more.html | 4 ++-- server-console/package.json | 2 +- 17 files changed, 32 insertions(+), 32 deletions(-) diff --git a/BUILD_ANDROID.md b/BUILD_ANDROID.md index 0bea3e5a90..ccba877bfe 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 diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index 8d6062f5e6..1047e04ef5 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -4,7 +4,7 @@ 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/kasenvr/vircadia-builder) to build on Linux more easily. Alternatively, you can follow the manual steps below. +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 @@ -78,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: 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/CONTRIBUTING.md b/CONTRIBUTING.md index aeb6f49280..88dc39ae51 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,7 +20,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 ``` @@ -38,10 +38,10 @@ Contributing 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/README.md b/README.md index baf333d81f..0368799c73 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/INSTALL.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/docker/Dockerfile b/android/docker/Dockerfile index 144f6caffa..266a8854f1 100644 --- a/android/docker/Dockerfile +++ b/android/docker/Dockerfile @@ -72,7 +72,7 @@ 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 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/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/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_qt.py b/hifi_qt.py index c59c7b1202..48e9b337a6 100644 --- a/hifi_qt.py +++ b/hifi_qt.py @@ -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/master/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/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: "<a href=\"https://github.com/kasenvr/project-athena\">Vircadia Github</a>." + text: "<a href=\"https://github.com/vircadia/vircadia\">Vircadia Github</a>." size: 20 onLinkActivated: { - About.openUrl("https:/github.com/kasenvr/project-athena"); + About.openUrl("https:/github.com/vircadia/vircadia"); } } 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 <heath@odysseus.anderson.name> 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/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": { From fe7380630e882baa722a7621c362c18d2f2447dc Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Sat, 12 Dec 2020 21:17:53 +1300 Subject: [PATCH 121/136] Further updates --- BUILD_LINUX.md | 2 +- CONTRIBUTING.md | 2 +- android/docker/Dockerfile | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index 1047e04ef5..90782e90b4 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -105,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/CONTRIBUTING.md b/CONTRIBUTING.md index 88dc39ae51..35b7589e0c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,7 +6,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 diff --git a/android/docker/Dockerfile b/android/docker/Dockerfile index 266a8854f1..ab5ddb562d 100644 --- a/android/docker/Dockerfile +++ b/android/docker/Dockerfile @@ -74,15 +74,15 @@ RUN mkdir "$HIFI_BASE" && \ # Download the repo 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 From a3dfa6a25bb740fa2751488c1f9302ec0e466474 Mon Sep 17 00:00:00 2001 From: Kalila <69767640+digisomni@users.noreply.github.com> Date: Sun, 13 Dec 2020 03:07:49 -0500 Subject: [PATCH 122/136] Update BUILD_ANDROID.md Co-authored-by: David Rowe <david@ctrlaltstudio.com> --- BUILD_ANDROID.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD_ANDROID.md b/BUILD_ANDROID.md index 4998648227..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/vircadia/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 From 5a4210a04f77f826fb80cafb94f45a0b9d0d8d19 Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Sun, 13 Dec 2020 21:56:03 +1300 Subject: [PATCH 123/136] Further updates --- .github/workflows/pr_build.yml | 2 +- android/containerized_build.sh | 2 +- libraries/networking/src/NetworkingConstants.h | 2 +- prebuild.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 757a6fd7c8..746a5bf3c3 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -169,7 +169,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/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/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/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(): From 16eca5d8558d9d09e1b0de1ef32e8363eef24d9f Mon Sep 17 00:00:00 2001 From: Kalila L <somnilibertas@gmail.com> Date: Sun, 13 Dec 2020 04:42:34 -0500 Subject: [PATCH 124/136] Get most 'project-athena' -> 'vircadia' references. --- .github/workflows/pr_build.yml | 2 +- BUILD_LINUX.md | 2 +- BUILD_WIN.md | 2 +- CONTRIBUTING.md | 10 +++++----- README.md | 10 +++++----- android/docker/Dockerfile | 8 ++++---- domain-server/resources/web/assignment/placeholder.js | 2 +- hifi_qt.py | 2 +- libraries/networking/src/NetworkingConstants.h | 2 +- pkg-scripts/server-control | 4 ++-- prebuild.py | 2 +- scripts/system/more/more.html | 2 +- server-console/package.json | 2 +- 13 files changed, 25 insertions(+), 25 deletions(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 757a6fd7c8..746a5bf3c3 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -169,7 +169,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_LINUX.md b/BUILD_LINUX.md index fa5d3ef206..1047e04ef5 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -78,7 +78,7 @@ sudo apt-get install nodejs Clone this repository: ```bash -git clone https://github.com/vircadia/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: diff --git a/BUILD_WIN.md b/BUILD_WIN.md index aa94eb30de..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/vircadia/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/CONTRIBUTING.md b/CONTRIBUTING.md index 70ddd11ad6..88dc39ae51 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,7 +20,7 @@ Contributing 6. Update your branch ``` - git remote add upstream https://github.com/vircadia/project-athena + git remote add upstream https://github.com/vircadia/vircadia git pull upstream master ``` @@ -38,10 +38,10 @@ Contributing 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/vircadia/project-athena/issues) to make sure that somebody has not already reported the same bug. -3. [Add](https://github.com/vircadia/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/vircadia/project-athena/issues) to make sure that somebody has not already requested the same feature. -2. [Add](https://github.com/vircadia/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/README.md b/README.md index c4de956d1c..0368799c73 100644 --- a/README.md +++ b/README.md @@ -8,15 +8,15 @@ Vircadia is a 3D social software project seeking to incrementally bring about a ### Releases -[View Releases here](https://github.com/vircadia/project-athena/releases/) +[View Releases here](https://github.com/vircadia/vircadia/releases/) ### How to build the Interface -[For Windows](https://github.com/vircadia/project-athena/blob/master/BUILD_WIN.md) +[For Windows](https://github.com/vircadia/vircadia/blob/master/BUILD_WIN.md) -[For Mac](https://github.com/vircadia/project-athena/blob/master/BUILD_OSX.md) +[For Mac](https://github.com/vircadia/vircadia/blob/master/BUILD_OSX.md) -[For Linux](https://github.com/vircadia/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/vircadia/vircadia-builder) @@ -30,7 +30,7 @@ Vircadia is a 3D social software project seeking to incrementally bring about a ### How to generate an Installer -[For Windows](https://github.com/vircadia/project-athena/blob/master/INSTALL.md) +[For Windows](https://github.com/vircadia/vircadia/blob/master/INSTALL.md) [For Linux - AppImage - Vircadia Builder](https://github.com/vircadia/vircadia-builder/blob/master/README.md#building-appimages) diff --git a/android/docker/Dockerfile b/android/docker/Dockerfile index 54f0a544df..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/vircadia/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/domain-server/resources/web/assignment/placeholder.js b/domain-server/resources/web/assignment/placeholder.js index b0b2f32c4f..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/vircadia/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_qt.py b/hifi_qt.py index d08670c805..48e9b337a6 100644 --- a/hifi_qt.py +++ b/hifi_qt.py @@ -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/vircadia/project-athena/tree/master/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/libraries/networking/src/NetworkingConstants.h b/libraries/networking/src/NetworkingConstants.h index 642dd2426e..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/vircadia/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/pkg-scripts/server-control b/pkg-scripts/server-control index c1a43876a3..3ed23b7149 100644 --- a/pkg-scripts/server-control +++ b/pkg-scripts/server-control @@ -5,8 +5,8 @@ Maintainer: Heather Anderson <heath@odysseus.anderson.name> Build-Depends: debhelper (>= 10) Standards-Version: 4.1.2 Homepage: https://vircadia.com -Vcs-Git: https://github.com/vircadia/project-athena.git -Vcs-Browser: https://github.com/vircadia/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/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/scripts/system/more/more.html b/scripts/system/more/more.html index 9d9a7db257..a8bdaca913 100644 --- a/scripts/system/more/more.html +++ b/scripts/system/more/more.html @@ -6,7 +6,7 @@ // Copyright 2020 Vircadia contributors. // // App maintained in: https://github.com/vircadia/community-apps -// App copied to: https://github.com/vircadia/project-athena +// 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 b36db74670..d5b2a0793d 100644 --- a/server-console/package.json +++ b/server-console/package.json @@ -13,7 +13,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/vircadia/project-athena.git" + "url": "https://github.com/vircadia/vircadia.git" }, "main": "src/main.js", "scripts": { From 1634138c6278fa4a79e14bf46a6c75bc7b8068c6 Mon Sep 17 00:00:00 2001 From: Kalila <69767640+digisomni@users.noreply.github.com> Date: Sun, 13 Dec 2020 16:24:42 -0500 Subject: [PATCH 125/136] Apply suggestions from code review Co-authored-by: David Rowe <david@ctrlaltstudio.com> --- interface/resources/qml/hifi/dialogs/TabletAboutDialog.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/dialogs/TabletAboutDialog.qml b/interface/resources/qml/hifi/dialogs/TabletAboutDialog.qml index 09aba7c206..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: "<a href=\"https://github.com/vircadia/project-athena\">Vircadia Github</a>." + text: "<a href=\"https://github.com/vircadia/vircadia\">Vircadia Github</a>." size: 20 onLinkActivated: { - About.openUrl("https:/github.com/vircadia/project-athena"); + About.openUrl("https:/github.com/vircadia/vircadia"); } } From 51ebb12d299adfd78ab92cc6ffa26d4fc095c83d Mon Sep 17 00:00:00 2001 From: Adam Ivie <vegaslon@gmail.com> Date: Sun, 13 Dec 2020 21:18:12 -0500 Subject: [PATCH 126/136] Add Tips for making pull request to CONTRIBUTING.md --- CONTRIBUTING.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a62e4b2825..8cc722554c 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 @@ -21,7 +22,7 @@ Contributing ``` git remote add upstream https://github.com/kasenvr/project-athena - git pull upstream kasen/core + git pull upstream master ``` Resolve any conflicts that arise with this step. @@ -29,12 +30,21 @@ Contributing 7. Push to your fork ``` - git push origin kasen/core + git push origin new_branch_name ``` 8. Submit a pull request *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 added features. +3. If added any new api make sure they come with some documentation included. +4. If accessing any external service make note of how to get a basic setup for these services or what they are based on. + 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! @@ -44,4 +54,4 @@ Reporting Bugs 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! +2. [Add](https://github.com/kasenvr/project-athena/issues/new) your request to the issues list! \ No newline at end of file From 261c2e6cff4f85336556cf67d830095bcda1e386 Mon Sep 17 00:00:00 2001 From: Kalila L <somnilibertas@gmail.com> Date: Sun, 13 Dec 2020 23:57:04 -0500 Subject: [PATCH 127/136] Final stragglers...? --- BUILD_LINUX.md | 2 +- CONTRIBUTING.md | 2 +- android/containerized_build.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index 1047e04ef5..90782e90b4 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -105,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/CONTRIBUTING.md b/CONTRIBUTING.md index 88dc39ae51..35b7589e0c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,7 +6,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 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 \ From e5802a29f1f8af96d5ce54e4ef5677f2c63842c1 Mon Sep 17 00:00:00 2001 From: Adam Ivie <vegaslon@gmail.com> Date: Mon, 14 Dec 2020 18:01:27 -0500 Subject: [PATCH 128/136] Update CONTRIBUTING.md Co-authored-by: Kalila <69767640+digisomni@users.noreply.github.com> --- CONTRIBUTING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8cc722554c..c87ae17ecd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,9 +41,9 @@ 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 added features. -3. If added any new api make sure they come with some documentation included. -4. If accessing any external service make note of how to get a basic setup for these services or what they are based on. +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 === @@ -54,4 +54,4 @@ Reporting Bugs 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! \ No newline at end of file +2. [Add](https://github.com/kasenvr/project-athena/issues/new) your request to the issues list! From 5e17639bed67e2e46da6110c1a0ddd7e72c475c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20Gro=C3=9F?= <firedefender1@googlemail.com> Date: Tue, 15 Dec 2020 02:43:39 +0100 Subject: [PATCH 129/136] Fix building with GLES --- cmake/ports/glad/portfile.cmake | 3 ++- libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/cmake/ports/glad/portfile.cmake b/cmake/ports/glad/portfile.cmake index 54b1d91c89..c13306ed80 100644 --- a/cmake/ports/glad/portfile.cmake +++ b/cmake/ports/glad/portfile.cmake @@ -3,11 +3,12 @@ vcpkg_check_linkage(ONLY_STATIC_LIBRARY) file(READ "${VCPKG_ROOT_DIR}/_env/EXTERNAL_BUILD_ASSETS.txt" EXTERNAL_BUILD_ASSETS) -if (ANDROID) +if (ANDROID OR ${GLES_OPTION} ON) vcpkg_download_distfile( SOURCE_ARCHIVE URLS ${EXTERNAL_BUILD_ASSETS}/dependencies/glad/glad32es.zip SHA512 2e02ac633eed8f2ba2adbf96ea85d08998f48dd2e9ec9a88ec3c25f48eaf1405371d258066327c783772fcb3793bdb82bd7375fdabb2ba5e2ce0835468b17f65 + FILENAME glad32es.zip ) else() # else Linux desktop diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp index 38aca093cd..aa5d3f8ca1 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; From 0cebb700fbb61753cb992ee750cb4dbbcc4f2d77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20Gro=C3=9F?= <firedefender1@googlemail.com> Date: Tue, 15 Dec 2020 04:15:44 +0100 Subject: [PATCH 130/136] Change conditionals according to review --- libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp index aa5d3f8ca1..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) == !defined(USE_GLES) +#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) == !defined(USE_GLES) +#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) == !defined(USE_GLES) +#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) == !defined(USE_GLES) +#if !defined(Q_OS_ANDROID) && !defined(USE_GLES) glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, &mem[0]); #endif return mem[0] * BYTES_PER_KIB; From 3485efd8081c665982ac6104aea86d12fb90503d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20Gro=C3=9F?= <firedefender1@googlemail.com> Date: Tue, 15 Dec 2020 05:00:58 +0100 Subject: [PATCH 131/136] Fix failing builds --- CMakeLists.txt | 12 +++++++++++- cmake/ports/glad/portfile.cmake | 3 ++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 424fbdc940..33efb2f240 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,17 @@ 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 OFF) + +if( DEFINED ENV{USE_GLES} ) + set(USE_GLES "$ENV{USE_GLES}") + set(GLES_OPTION "$ENV{USE_GLES}") +endif() + +# 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 +140,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/cmake/ports/glad/portfile.cmake b/cmake/ports/glad/portfile.cmake index c13306ed80..0c2106e581 100644 --- a/cmake/ports/glad/portfile.cmake +++ b/cmake/ports/glad/portfile.cmake @@ -2,8 +2,9 @@ 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) -if (ANDROID OR ${GLES_OPTION} ON) +if (ANDROID OR USE_GLES) vcpkg_download_distfile( SOURCE_ARCHIVE URLS ${EXTERNAL_BUILD_ASSETS}/dependencies/glad/glad32es.zip From 65fb1320ccf4827e22b1b575527871ca52f9627c Mon Sep 17 00:00:00 2001 From: ArcadeFever <arc8defever@gmail.com> Date: Tue, 15 Dec 2020 00:04:59 -0800 Subject: [PATCH 132/136] Upgraded Oculus SDKs to latest --- cmake/macros/TargetOculusMobile.cmake | 4 ++-- hifi_android.py | 12 ++++++------ libraries/oculusMobile/src/ovr/Helpers.h | 6 +++--- libraries/oculusMobile/src/ovr/VrHandler.cpp | 2 +- .../src/OculusMobileControllerManager.cpp | 18 +++++++++--------- 5 files changed, 21 insertions(+), 21 deletions(-) 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/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/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<void(ovrEye)>& f) { f(VRAPI_EYE_RIGHT); } -static inline void for_each_hand(const std::function<void(ovrHandedness)>& f) { - f(VRAPI_HAND_LEFT); - f(VRAPI_HAND_RIGHT); +static inline void for_each_hand(const std::function<void(ovrTrackedDeviceTypeId)>& 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; From 4e18382089508a89266360a9456dc35479f9d575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20Gro=C3=9F?= <firedefender1@googlemail.com> Date: Tue, 15 Dec 2020 13:53:17 +0100 Subject: [PATCH 133/136] Work around android not building with set glad32es.zip filename --- cmake/ports/glad/portfile.cmake | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cmake/ports/glad/portfile.cmake b/cmake/ports/glad/portfile.cmake index 0c2106e581..bb6a26a40e 100644 --- a/cmake/ports/glad/portfile.cmake +++ b/cmake/ports/glad/portfile.cmake @@ -4,7 +4,13 @@ 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) -if (ANDROID OR USE_GLES) +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 From dcd26c8ad6803e32161061d1aa4883d0fd38bb0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20Gro=C3=9F?= <firedefender1@googlemail.com> Date: Tue, 15 Dec 2020 21:19:49 +0100 Subject: [PATCH 134/136] Add comment about `FILENAME` being missing from ANDROID --- cmake/ports/glad/portfile.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/ports/glad/portfile.cmake b/cmake/ports/glad/portfile.cmake index bb6a26a40e..6e3118b31e 100644 --- a/cmake/ports/glad/portfile.cmake +++ b/cmake/ports/glad/portfile.cmake @@ -4,6 +4,7 @@ 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 From b416ca1e174bc5cd530015b8bcf44cfb7d0cc047 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20Gro=C3=9F?= <firedefender1@googlemail.com> Date: Wed, 16 Dec 2020 16:50:54 +0100 Subject: [PATCH 135/136] Simplify code according to review --- CMakeLists.txt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 33efb2f240..f111f482ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,12 +41,7 @@ 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 OFF) - -if( DEFINED ENV{USE_GLES} ) - set(USE_GLES "$ENV{USE_GLES}") - set(GLES_OPTION "$ENV{USE_GLES}") -endif() +set(GLES_OPTION "$ENV{USE_GLES}") # Will affect VCPKG dependencies file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/_env/USE_GLES.txt" "${GLES_OPTION}") From 3a7195c21ccba763225e38dbc51531d18416947c Mon Sep 17 00:00:00 2001 From: Adam Ivie <vegaslon@gmail.com> Date: Wed, 16 Dec 2020 18:37:19 -0500 Subject: [PATCH 136/136] Remove artifact from resolving conflict Co-authored-by: Kalila <69767640+digisomni@users.noreply.github.com> --- CONTRIBUTING.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b4d6383f7b..72f296e92e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,7 +21,6 @@ Contributing 6. Update your branch ``` - git remote add upstream https://github.com/vircadia/vircadia git pull upstream master ```