diff --git a/cmake/ports/bullet3/portfile.cmake b/cmake/ports/bullet3/portfile.cmake index d4e7aaf787..9318385de0 100644 --- a/cmake/ports/bullet3/portfile.cmake +++ b/cmake/ports/bullet3/portfile.cmake @@ -25,14 +25,13 @@ vcpkg_from_github( HEAD_REF master ) - vcpkg_configure_cmake( SOURCE_PATH ${SOURCE_PATH} OPTIONS -DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=ON -DUSE_MSVC_RUNTIME_LIBRARY_DLL=ON - -DUSE_GLUT=0 - -DUSE_DX11=0 + -DUSE_GLUT=0 + -DUSE_DX11=0 -DBUILD_DEMOS=OFF -DBUILD_OPENGL3_DEMOS=OFF -DBUILD_BULLET3=OFF diff --git a/hifi_vcpkg.py b/hifi_vcpkg.py index 3df714e6f9..cdd44d304e 100644 --- a/hifi_vcpkg.py +++ b/hifi_vcpkg.py @@ -258,18 +258,13 @@ endif() url = 'NOT DEFINED' if platform.system() == 'Windows': - # TODO: figure out how to download with versionId - #url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-windows.tar.gz?versionId=Etx8novAe0.IxQ7AosLFtop7fZur.cx9' - url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-windows.tar.gz' + url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-windows2.tar.gz' elif platform.system() == 'Darwin': - #url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-macos.tar.gz?versionId=QrGxwssB.WwU_z3QCyG7ghP1_VjTkQeK' url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-macos.tar.gz' elif platform.system() == 'Linux': - if platform.linux_distribution()[1] == '16.04': - #url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-16.04.tar.gz?versionId=c9j7PW4uBDPLif7DKmgIhorh9WBMjZRB' + if platform.linux_distribution()[1][:3] == '16.': url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-16.04.tar.gz' - elif platform.linux_distribution()[1] == '18.04': - #url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-18.04.tar.gz?versionId=Z3TojPFdb5pXdahF3oi85jjKocpL0xqw' + elif platform.linux_distribution()[1][:3] == '18.': url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-18.04.tar.gz' else: print('UNKNOWN LINUX VERSION!!!') diff --git a/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml b/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml index 57bec2250f..b426f2d986 100644 --- a/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml +++ b/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml @@ -58,7 +58,8 @@ Rectangle { if (isLoggedIn) { Commerce.getWalletStatus(); } else { - // Show some error to the user + errorText.text = "There was a problem while retrieving your inventory. " + + "Please try closing and re-opening the Avatar app.\n\nLogin status result: " + isLoggedIn; } } @@ -66,11 +67,19 @@ Rectangle { if (walletStatus === 5) { getInventory(); } else { - // Show some error to the user + errorText.text = "There was a problem while retrieving your inventory. " + + "Please try closing and re-opening the Avatar app.\n\nWallet status result: " + walletStatus; } } onInventoryResult: { + if (result.status !== "success") { + errorText.text = "There was a problem while retrieving your inventory. " + + "Please try closing and re-opening the Avatar app.\n\nInventory status: " + result.status + "\nMessage: " + result.message; + } else if (result.data && result.data.assets && result.data.assets.length === 0) { + errorText.text = "You have not created any avatars yet! Create an avatar with the Avatar Creator, then close and re-open the Avatar App." + } + avatarAppInventoryModel.handlePage(result.status !== "success" && result.message, result); root.updatePreviewUrl(); } @@ -172,7 +181,7 @@ Rectangle { anchors.bottom: parent.bottom AnimatedImage { - visible: !inventoryContentsList.visible + visible: !inventoryContentsList.visible && !errorText.visible anchors.centerIn: parent width: 72 height: width @@ -181,7 +190,7 @@ Rectangle { ListView { id: inventoryContentsList - visible: avatarAppInventoryModel.count !== 0 + visible: avatarAppInventoryModel.count !== 0 && !errorText.visible interactive: contentItem.height > height clip: true model: avatarAppInventoryModel @@ -196,6 +205,18 @@ Rectangle { standaloneIncompatible: model.standalone_incompatible } } + + HifiStylesUit.GraphikRegular { + id: errorText + text: "" + visible: text !== "" + anchors.fill: parent + size: 22 + color: simplifiedUI.colors.text.white + wrapMode: Text.Wrap + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + } } diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml index da924615e3..b73c07c78b 100644 --- a/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml @@ -60,7 +60,7 @@ Flickable { HifiStylesUit.GraphikRegular { id: volumeControlsTitle text: "Volume Controls" - Layout.maximumWidth: parent.width + Layout.preferredWidth: parent.width height: paintedHeight size: 22 color: simplifiedUI.colors.text.white @@ -68,57 +68,82 @@ Flickable { SimplifiedControls.Slider { id: peopleVolume - anchors.left: parent.left - anchors.right: parent.right + Layout.preferredWidth: parent.width Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin height: 30 labelText: "People Volume" - from: -60 - to: 10 + from: simplifiedUI.numericConstants.mutedValue + to: 20.0 defaultValue: 0.0 - value: AudioScriptingInterface.getAvatarGain() + stepSize: 5.0 + value: AudioScriptingInterface.avatarGain live: true + function updatePeopleGain(sliderValue) { + if (AudioScriptingInterface.avatarGain !== sliderValue) { + AudioScriptingInterface.avatarGain = sliderValue; + } + } onValueChanged: { - if (AudioScriptingInterface.getAvatarGain() != peopleVolume.value) { - AudioScriptingInterface.setAvatarGain(peopleVolume.value); + updatePeopleGain(value); + } + onPressedChanged: { + if (!pressed) { + updatePeopleGain(value); } } } SimplifiedControls.Slider { id: environmentVolume - anchors.left: parent.left - anchors.right: parent.right + Layout.preferredWidth: parent.width Layout.topMargin: 2 height: 30 labelText: "Environment Volume" - from: -60 - to: 10 + from: simplifiedUI.numericConstants.mutedValue + to: 20.0 defaultValue: 0.0 - value: AudioScriptingInterface.getInjectorGain() + stepSize: 5.0 + value: AudioScriptingInterface.serverInjectorGain live: true + function updateEnvironmentGain(sliderValue) { + if (AudioScriptingInterface.serverInjectorGain !== sliderValue) { + AudioScriptingInterface.serverInjectorGain = sliderValue; + AudioScriptingInterface.localInjectorGain = sliderValue; + } + } onValueChanged: { - if (AudioScriptingInterface.getInjectorGain() != environmentVolume.value) { - AudioScriptingInterface.setInjectorGain(environmentVolume.value); + updateEnvironmentGain(value); + } + onPressedChanged: { + if (!pressed) { + updateEnvironmentGain(value); } } } SimplifiedControls.Slider { id: systemSoundVolume - anchors.left: parent.left - anchors.right: parent.right + Layout.preferredWidth: parent.width Layout.topMargin: 2 height: 30 labelText: "System Sound Volume" - from: -60 - to: 10 + from: simplifiedUI.numericConstants.mutedValue + to: 20.0 defaultValue: 0.0 - value: AudioScriptingInterface.getSystemInjectorGain() + stepSize: 5.0 + value: AudioScriptingInterface.systemInjectorGain live: true + function updateSystemGain(sliderValue) { + if (AudioScriptingInterface.systemInjectorGain !== sliderValue) { + AudioScriptingInterface.systemInjectorGain = sliderValue; + } + } onValueChanged: { - if (AudioScriptingInterface.getSystemInjectorGain() != systemSoundVolume.value) { - AudioScriptingInterface.setSystemInjectorGain(systemSoundVolume.value); + updateSystemGain(value); + } + onPressedChanged: { + if (!pressed) { + updateSystemGain(value); } } } @@ -184,8 +209,7 @@ Flickable { ListView { id: inputDeviceListView - anchors.left: parent.left - anchors.right: parent.right + Layout.preferredWidth: parent.width Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin interactive: false height: contentItem.height @@ -200,7 +224,7 @@ Flickable { id: inputDeviceCheckbox anchors.left: parent.left width: parent.width - inputLevel.width - height: paintedHeight + height: 16 wrapLabel: false checked: selectedDesktop text: model.devicename @@ -223,6 +247,7 @@ Flickable { } SimplifiedControls.Button { + id: audioLoopbackButton property bool audioLoopedBack: AudioScriptingInterface.getLocalEcho() function startAudioLoopback() { @@ -238,29 +263,23 @@ Flickable { } } - Timer { - id: loopbackTimer - interval: 8000 - running: false - repeat: false - onTriggered: { + Component.onDestruction: stopAudioLoopback(); + + onVisibleChanged: { + if (!visible) { stopAudioLoopback(); } } - id: testYourMicButton enabled: !HMD.active - anchors.left: parent.left Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin width: 160 height: 32 text: audioLoopedBack ? "STOP TESTING" : "TEST YOUR MIC" onClicked: { if (audioLoopedBack) { - loopbackTimer.stop(); stopAudioLoopback(); } else { - loopbackTimer.restart(); startAudioLoopback(); } } @@ -285,8 +304,7 @@ Flickable { ListView { id: outputDeviceListView - anchors.left: parent.left - anchors.right: parent.right + Layout.preferredWidth: parent.width Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin interactive: false height: contentItem.height @@ -301,7 +319,7 @@ Flickable { id: outputDeviceCheckbox anchors.left: parent.left width: parent.width - height: paintedHeight + height: 16 checked: selectedDesktop text: model.devicename wrapLabel: false @@ -353,7 +371,6 @@ Flickable { id: testYourSoundButton enabled: !HMD.active - anchors.left: parent.left Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin width: 160 height: 32 diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml index 96dbc5e180..97799921c2 100644 --- a/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml @@ -198,8 +198,7 @@ Flickable { ListView { id: inputDeviceListView - anchors.left: parent.left - anchors.right: parent.right + Layout.preferredWidth: parent.width Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin interactive: false height: contentItem.height @@ -214,8 +213,10 @@ Flickable { id: inputDeviceCheckbox anchors.left: parent.left width: parent.width - inputLevel.width + height: 16 checked: selectedHMD text: model.devicename + wrapLabel: false ButtonGroup.group: inputDeviceButtonGroup onClicked: { AudioScriptingInterface.setStereoInput(false); // the next selected audio device might not support stereo @@ -235,6 +236,7 @@ Flickable { } SimplifiedControls.Button { + id: audioLoopbackButton property bool audioLoopedBack: AudioScriptingInterface.getLocalEcho() function startAudioLoopback() { @@ -250,29 +252,23 @@ Flickable { } } - Timer { - id: loopbackTimer - interval: 8000 - running: false - repeat: false - onTriggered: { + Component.onDestruction: stopAudioLoopback(); + + onVisibleChanged: { + if (!visible) { stopAudioLoopback(); } } - id: testYourMicButton enabled: HMD.active - anchors.left: parent.left Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin width: 160 height: 32 text: audioLoopedBack ? "STOP TESTING" : "TEST YOUR MIC" onClicked: { if (audioLoopedBack) { - loopbackTimer.stop(); stopAudioLoopback(); } else { - loopbackTimer.restart(); startAudioLoopback(); } } @@ -297,8 +293,7 @@ Flickable { ListView { id: outputDeviceListView - anchors.left: parent.left - anchors.right: parent.right + Layout.preferredWidth: parent.width Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin interactive: false height: contentItem.height @@ -313,11 +308,13 @@ Flickable { id: outputDeviceCheckbox anchors.left: parent.left width: parent.width - checked: selectedDesktop + height: 16 + checked: selectedHMD text: model.devicename + wrapLabel: false ButtonGroup.group: outputDeviceButtonGroup onClicked: { - AudioScriptingInterface.setOutputDevice(model.info, true); // `false` argument for Desktop mode setting + AudioScriptingInterface.setOutputDevice(model.info, true); // `true` argument for VR mode setting } } } @@ -363,7 +360,6 @@ Flickable { id: testYourSoundButton enabled: HMD.active - anchors.left: parent.left Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin width: 160 height: 32 diff --git a/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml b/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml index 752c989500..1f628b041d 100644 --- a/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml +++ b/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml @@ -221,4 +221,8 @@ QtObject { } } } + + readonly property QtObject numericConstants: QtObject { + readonly property real mutedValue: -60.0 + } } diff --git a/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Slider.qml b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Slider.qml index 2b1dc68261..38b114e9d2 100644 --- a/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Slider.qml +++ b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Slider.qml @@ -30,6 +30,7 @@ Item { property alias live: sliderControl.live property alias stepSize: sliderControl.stepSize property alias snapMode: sliderControl.snapMode + property alias pressed: sliderControl.pressed property real defaultValue: 0.0 HifiStylesUit.GraphikRegular { diff --git a/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml b/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml index 66270cc325..27a786ece2 100644 --- a/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml +++ b/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml @@ -203,7 +203,10 @@ Rectangle { Image { id: outputDeviceButton - property bool outputMuted: false + property bool outputMuted: AudioScriptingInterface.avatarGain === simplifiedUI.numericConstants.mutedValue && + AudioScriptingInterface.serverInjectorGain === simplifiedUI.numericConstants.mutedValue && + AudioScriptingInterface.localInjectorGain === simplifiedUI.numericConstants.mutedValue && + AudioScriptingInterface.systemInjectorGain === simplifiedUI.numericConstants.mutedValue source: outputDeviceButton.outputMuted ? "./images/outputDeviceMuted.svg" : "./images/outputDeviceLoud.svg" anchors.centerIn: parent width: 20 @@ -228,9 +231,8 @@ Rectangle { } onClicked: { Tablet.playSound(TabletEnums.ButtonClick); - outputDeviceButton.outputMuted = !outputDeviceButton.outputMuted; - if (outputDeviceButton.outputMuted && !AudioScriptingInterface.muted) { + if (!outputDeviceButton.outputMuted && !AudioScriptingInterface.muted) { AudioScriptingInterface.muted = true; } @@ -238,7 +240,7 @@ Rectangle { "source": "SimplifiedTopBar.qml", "method": "setOutputMuted", "data": { - "outputMuted": outputDeviceButton.outputMuted + "outputMuted": !outputDeviceButton.outputMuted } }); } @@ -454,10 +456,6 @@ Rectangle { } break; - case "updateOutputMuted": - outputDeviceButton.outputMuted = message.data.outputMuted; - break; - case "updateStatusButton": statusButton.currentStatus = message.data.currentStatus; break; diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0dba4498d5..a0cb790958 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3800,10 +3800,14 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { // If this is a first run we short-circuit the address passed in if (_firstRun.get()) { - DependencyManager::get()->goToEntry(); - sentTo = SENT_TO_ENTRY; - _firstRun.set(false); - + if (!_overrideEntry) { + DependencyManager::get()->goToEntry(); + sentTo = SENT_TO_ENTRY; + } else { + DependencyManager::get()->loadSettings(addressLookupString); + sentTo = SENT_TO_PREVIOUS_LOCATION; + } + _firstRun.set(false); } else { QString goingTo = ""; if (addressLookupString.isEmpty()) { @@ -3819,7 +3823,7 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { DependencyManager::get()->loadSettings(addressLookupString); sentTo = SENT_TO_PREVIOUS_LOCATION; } - + UserActivityLogger::getInstance().logAction("startup_sent_to", { { "sent_to", sentTo }, { "sandbox_is_running", sandboxIsRunning }, @@ -9354,6 +9358,19 @@ void Application::showUrlHandler(const QUrl& url) { } }); } +void Application::overrideEntry(){ + _overrideEntry = true; +} +void Application::forceDisplayName(const QString& displayName) { + getMyAvatar()->setDisplayName(displayName); +} +void Application::forceLoginWithTokens(const QString& tokens) { + DependencyManager::get()->setAccessTokens(tokens); + Setting::Handle(KEEP_ME_LOGGED_IN_SETTING_NAME, true).set(true); +} +void Application::setConfigFileURL(const QString& fileUrl) { + DependencyManager::get()->setConfigFileURL(fileUrl); +} #if defined(Q_OS_ANDROID) void Application::beforeEnterBackground() { diff --git a/interface/src/Application.h b/interface/src/Application.h index 210039beba..837fb8eae6 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -356,6 +356,11 @@ public: void openDirectory(const QString& path); + void overrideEntry(); + void forceDisplayName(const QString& displayName); + void forceLoginWithTokens(const QString& tokens); + void setConfigFileURL(const QString& fileUrl); + signals: void svoImportRequested(const QString& url); @@ -828,5 +833,6 @@ private: bool _resumeAfterLoginDialogActionTaken_WasPostponed { false }; bool _resumeAfterLoginDialogActionTaken_SafeToRun { false }; bool _startUpFinished { false }; + bool _overrideEntry { false }; }; #endif // hifi_Application_h diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 80b9762213..f153f66799 100755 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -521,6 +521,7 @@ void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transact } } } + _otherAvatarsToChangeInPhysics.clear(); } void AvatarManager::handleProcessedPhysicsTransaction(PhysicsEngine::Transaction& transaction) { @@ -645,7 +646,7 @@ void AvatarManager::clearOtherAvatars() { } void AvatarManager::deleteAllAvatars() { - assert(_otherAvatarsToChangeInPhysics.empty()); + _otherAvatarsToChangeInPhysics.clear(); QReadLocker locker(&_hashLock); AvatarHash::iterator avatarIterator = _avatarHash.begin(); while (avatarIterator != _avatarHash.end()) { diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 9d8b733ba7..7fc4a5b651 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -83,6 +83,8 @@ int main(int argc, const char* argv[]) { QCommandLineOption allowMultipleInstancesOption("allowMultipleInstances", "Allow multiple instances to run"); QCommandLineOption overrideAppLocalDataPathOption("cache", "set test cache ", "dir"); QCommandLineOption overrideScriptsPathOption(SCRIPTS_SWITCH, "set scripts ", "path"); + QCommandLineOption responseTokensOption("tokens", "set response tokens ", "json"); + QCommandLineOption displayNameOption("displayName", "set user display name ", "string"); parser.addOption(urlOption); parser.addOption(noLauncherOption); @@ -93,6 +95,8 @@ int main(int argc, const char* argv[]) { parser.addOption(overrideAppLocalDataPathOption); parser.addOption(overrideScriptsPathOption); parser.addOption(allowMultipleInstancesOption); + parser.addOption(responseTokensOption); + parser.addOption(displayNameOption); if (!parser.parse(arguments)) { std::cout << parser.errorText().toStdString() << std::endl; // Avoid Qt log spam @@ -120,8 +124,10 @@ int main(int argc, const char* argv[]) { static const QString APPLICATION_CONFIG_FILENAME = "config.json"; QDir applicationDir(applicationPath); - QFile configFile(applicationDir.filePath(APPLICATION_CONFIG_FILENAME)); - + QString configFileName = applicationDir.filePath(APPLICATION_CONFIG_FILENAME); + QFile configFile(configFileName); + QString launcherPath; + if (configFile.exists()) { if (!configFile.open(QIODevice::ReadOnly)) { qWarning() << "Found application config, but could not open it"; @@ -134,7 +140,7 @@ int main(int argc, const char* argv[]) { qWarning() << "Found application config, but could not parse it: " << error.errorString(); } else { static const QString LAUNCHER_PATH_KEY = "launcherPath"; - QString launcherPath = doc.object()[LAUNCHER_PATH_KEY].toString(); + launcherPath = doc.object()[LAUNCHER_PATH_KEY].toString(); if (!launcherPath.isEmpty()) { if (!parser.isSet(noLauncherOption)) { qDebug() << "Found a launcherPath in application config. Starting launcher."; @@ -146,6 +152,7 @@ int main(int argc, const char* argv[]) { qDebug() << "Found a launcherPath in application config, but the launcher" " has been suppressed. Continuing normal execution."; } + configFile.close(); } } } @@ -398,6 +405,24 @@ int main(int argc, const char* argv[]) { printSystemInformation(); + auto appPointer = dynamic_cast(&app); + if (appPointer) { + if (parser.isSet(urlOption)) { + appPointer->overrideEntry(); + } + if (parser.isSet(displayNameOption)) { + QString displayName = QString(parser.value(displayNameOption)); + appPointer->forceDisplayName(displayName); + } + if (!launcherPath.isEmpty()) { + appPointer->setConfigFileURL(configFileName); + } + if (parser.isSet(responseTokensOption)) { + QString tokens = QString(parser.value(responseTokensOption)); + appPointer->forceLoginWithTokens(tokens); + } + } + QTranslator translator; translator.load("i18n/interface_en"); app.installTranslator(&translator); diff --git a/interface/src/scripting/Audio.cpp b/interface/src/scripting/Audio.cpp index cb8b211352..6df4729ee0 100644 --- a/interface/src/scripting/Audio.cpp +++ b/interface/src/scripting/Audio.cpp @@ -400,10 +400,19 @@ void Audio::setReverbOptions(const AudioEffectOptions* options) { } void Audio::setAvatarGain(float gain) { + bool changed = false; + if (getAvatarGain() != gain) { + changed = true; + } + withWriteLock([&] { // ask the NodeList to set the master avatar gain DependencyManager::get()->setAvatarGain(QUuid(), gain); }); + + if (changed) { + emit avatarGainChanged(gain); + } } float Audio::getAvatarGain() { @@ -413,10 +422,19 @@ float Audio::getAvatarGain() { } void Audio::setInjectorGain(float gain) { + bool changed = false; + if (getInjectorGain() != gain) { + changed = true; + } + withWriteLock([&] { // ask the NodeList to set the audio injector gain DependencyManager::get()->setInjectorGain(gain); }); + + if (changed) { + emit serverInjectorGainChanged(gain); + } } float Audio::getInjectorGain() { @@ -426,6 +444,11 @@ float Audio::getInjectorGain() { } void Audio::setLocalInjectorGain(float gain) { + bool changed = false; + if (getLocalInjectorGain() != gain) { + changed = true; + } + withWriteLock([&] { if (_localInjectorGain != gain) { _localInjectorGain = gain; @@ -436,6 +459,11 @@ void Audio::setLocalInjectorGain(float gain) { DependencyManager::get()->setLocalInjectorGain(gain); } }); + + + if (changed) { + emit localInjectorGainChanged(gain); + } } float Audio::getLocalInjectorGain() { @@ -445,6 +473,11 @@ float Audio::getLocalInjectorGain() { } void Audio::setSystemInjectorGain(float gain) { + bool changed = false; + if (getSystemInjectorGain() != gain) { + changed = true; + } + withWriteLock([&] { if (_systemInjectorGain != gain) { _systemInjectorGain = gain; @@ -455,6 +488,10 @@ void Audio::setSystemInjectorGain(float gain) { DependencyManager::get()->setSystemInjectorGain(gain); } }); + + if (changed) { + emit systemInjectorGainChanged(gain); + } } float Audio::getSystemInjectorGain() { diff --git a/interface/src/scripting/Audio.h b/interface/src/scripting/Audio.h index ed54dca5c6..c7ac98402c 100644 --- a/interface/src/scripting/Audio.h +++ b/interface/src/scripting/Audio.h @@ -66,6 +66,10 @@ class Audio : public AudioScriptingInterface, protected ReadWriteLockable { * @property {boolean} pushToTalkHMD - true if HMD push-to-talk is enabled, otherwise false. * @property {boolean} pushingToTalk - true if the user is currently pushing-to-talk, otherwise * false. + * @property {float} avatarGain - The gain (relative volume) that avatars' voices are played at. This gain is used at the server. + * @property {float} localInjectorGain - The gain (relative volume) that local injectors (local environment sounds) are played at. + * @property {float} serverInjectorGain - The gain (relative volume) that server injectors (server environment sounds) are played at. This gain is used at the server. + * @property {float} systemInjectorGain - The gain (relative volume) that system sounds are played at. * * @comment The following properties are from AudioScriptingInterface.h. * @property {boolean} isStereoInput - true if the input audio is being used in stereo, otherwise @@ -90,6 +94,10 @@ class Audio : public AudioScriptingInterface, protected ReadWriteLockable { Q_PROPERTY(bool pushToTalkDesktop READ getPTTDesktop WRITE setPTTDesktop NOTIFY pushToTalkDesktopChanged) Q_PROPERTY(bool pushToTalkHMD READ getPTTHMD WRITE setPTTHMD NOTIFY pushToTalkHMDChanged) Q_PROPERTY(bool pushingToTalk READ getPushingToTalk WRITE setPushingToTalk NOTIFY pushingToTalkChanged) + Q_PROPERTY(float avatarGain READ getAvatarGain WRITE setAvatarGain NOTIFY avatarGainChanged) + Q_PROPERTY(float localInjectorGain READ getLocalInjectorGain WRITE setLocalInjectorGain NOTIFY localInjectorGainChanged) + Q_PROPERTY(float serverInjectorGain READ getInjectorGain WRITE setInjectorGain NOTIFY serverInjectorGainChanged) + Q_PROPERTY(float systemInjectorGain READ getSystemInjectorGain WRITE setSystemInjectorGain NOTIFY systemInjectorGainChanged) public: static QString AUDIO; @@ -412,6 +420,38 @@ signals: */ void pushingToTalkChanged(bool talking); + /**jsdoc + * Triggered when the avatar gain changes. + * @function Audio.avatarGainChanged + * @param {float} gain - The new avatar gain value. + * @returns {Signal} + */ + void avatarGainChanged(float gain); + + /**jsdoc + * Triggered when the local injector gain changes. + * @function Audio.localInjectorGainChanged + * @param {float} gain - The new local injector gain value. + * @returns {Signal} + */ + void localInjectorGainChanged(float gain); + + /**jsdoc + * Triggered when the server injector gain changes. + * @function Audio.serverInjectorGainChanged + * @param {float} gain - The new server injector gain value. + * @returns {Signal} + */ + void serverInjectorGainChanged(float gain); + + /**jsdoc + * Triggered when the system injector gain changes. + * @function Audio.systemInjectorGainChanged + * @param {float} gain - The new system injector gain value. + * @returns {Signal} + */ + void systemInjectorGainChanged(float gain); + public slots: /**jsdoc diff --git a/interface/src/scripting/SelectionScriptingInterface.cpp b/interface/src/scripting/SelectionScriptingInterface.cpp index c15b5cde11..5856188868 100644 --- a/interface/src/scripting/SelectionScriptingInterface.cpp +++ b/interface/src/scripting/SelectionScriptingInterface.cpp @@ -44,13 +44,14 @@ SelectionScriptingInterface::SelectionScriptingInterface() { } /**jsdoc + * The type of a specific item in a selection list. * * * * * - * - * + * + * * *
ValueDescription
"avatar"
"entity"
"avatar"The item is an avatar.
"entity"The item is an entity.
* @typedef {string} Selection.ItemType @@ -245,9 +246,10 @@ void SelectionScriptingInterface::printList(const QString& listName) { } /**jsdoc + * A selection list. * @typedef {object} Selection.SelectedItemsList - * @property {Uuid[]} avatars - The IDs of the avatars in the selection. - * @property {Uuid[]} entities - The IDs of the entities in the selection. + * @property {Uuid[]} avatars - The IDs of the avatars in the selection list. + * @property {Uuid[]} entities - The IDs of the entities in the selection list. */ QVariantMap SelectionScriptingInterface::getSelectedItemsList(const QString& listName) const { QReadLocker lock(&_selectionListsLock); @@ -438,18 +440,19 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) { } /**jsdoc + * The highlighting style of a selection list. * @typedef {object} Selection.HighlightStyle - * @property {Color} outlineUnoccludedColor - Color of the specified highlight region. - * @property {Color} outlineOccludedColor - "" - * @property {Color} fillUnoccludedColor- "" - * @property {Color} fillOccludedColor- "" - * @property {number} outlineUnoccludedAlpha - Alpha value ranging from 0.0 (not visible) to 1.0 - * (fully opaque) for the specified highlight region. - * @property {number} outlineOccludedAlpha - "" - * @property {number} fillUnoccludedAlpha - "" - * @property {number} fillOccludedAlpha - "" - * @property {number} outlineWidth - Width of the outline, in pixels. - * @property {boolean} isOutlineSmooth - true to enable outline smooth fall-off. + * @property {Color} outlineUnoccludedColor=255,178,51 - Unoccluded outline color. + * @property {Color} outlineOccludedColor=255,178,51 - Occluded outline color. + * @property {Color} fillUnoccludedColor=51,178,255 - Unoccluded fill color. + * @property {Color} fillOccludedColor=51,178,255 - Occluded fill color. + * @property {number} outlineUnoccludedAlpha=0.9 - Unoccluded outline alpha, range 0.01.0. + * @property {number} outlineOccludedAlpha=0.9 - Occluded outline alpha, range 0.01.0. + * @property {number} fillUnoccludedAlpha=0.0 - Unoccluded fill alpha, range 0.01.0. + * @property {number} fillOccludedAlpha=0.0 - Occluded fill alpha, range 0.01.0. + * @property {number} outlineWidth=2 - Width of the outline, in pixels. + * @property {boolean} isOutlineSmooth=false - true to fade the outside edge of the outline, false + * to have a sharp edge. */ QVariantMap SelectionHighlightStyle::toVariantMap() const { QVariantMap properties; diff --git a/interface/src/scripting/SelectionScriptingInterface.h b/interface/src/scripting/SelectionScriptingInterface.h index fcb4090184..4386ee5ee6 100644 --- a/interface/src/scripting/SelectionScriptingInterface.h +++ b/interface/src/scripting/SelectionScriptingInterface.h @@ -77,47 +77,45 @@ protected: }; /**jsdoc - * The Selection API provides a means of grouping together avatars and entities in named lists. + * The Selection API provides a means of grouping together and highlighting avatars and entities in named lists. + * * @namespace Selection * * @hifi-interface * @hifi-client-entity * @hifi-avatar * - * @example Outline an entity when it is grabbed by a controller. - * // Create a box and copy the following text into the entity's "Script URL" field. + * @example Outline an entity when it is grabbed by the mouse or a controller. + * // Create an entity and copy the following script into the entity's "Script URL" field. + * // Move the entity behind another entity to see the occluded outline. * (function () { - * print("Starting highlight script..............."); - * var _this = this; - * var prevID = 0; - * var listName = "contextOverlayHighlightList"; - * var listType = "entity"; - * - * _this.startNearGrab = function(entityID){ - * if (prevID !== entityID) { - * Selection.addToSelectedItemsList(listName, listType, entityID); - * prevID = entityID; - * } + * var LIST_NAME = "SelectionExample", + * ITEM_TYPE = "entity", + * HIGHLIGHT_STYLE = { + * outlineUnoccludedColor: { red: 0, green: 180, blue: 239 }, + * outlineUnoccludedAlpha: 0.5, + * outlineOccludedColor: { red: 239, green: 180, blue: 0 }, + * outlineOccludedAlpha: 0.5, + * outlineWidth: 4 + * }; + * + * Selection.enableListHighlight(LIST_NAME, HIGHLIGHT_STYLE); + * + * this.startNearGrab = function (entityID) { + * Selection.addToSelectedItemsList(LIST_NAME, ITEM_TYPE, entityID); * }; - * - * _this.releaseGrab = function(entityID){ - * if (prevID !== 0) { - * Selection.removeFromSelectedItemsList("contextOverlayHighlightList", listType, prevID); - * prevID = 0; - * } + * + * this.startDistanceGrab = function (entityID) { + * Selection.addToSelectedItemsList(LIST_NAME, ITEM_TYPE, entityID); * }; - * - * var cleanup = function(){ - * Entities.findEntities(MyAvatar.position, 1000).forEach(function(entity) { - * try { - * Selection.removeListFromMap(listName); - * } catch (e) { - * print("Error cleaning up."); - * } - * }); + * + * this.releaseGrab = function (entityID) { + * Selection.removeFromSelectedItemsList(LIST_NAME, ITEM_TYPE, entityID); * }; - * - * Script.scriptEnding.connect(cleanup); + * + * Script.scriptEnding.connect(function () { + * Selection.removeListFromMap(LIST_NAME); + * }); * }); */ class SelectionScriptingInterface : public QObject, public Dependency { @@ -127,121 +125,119 @@ public: SelectionScriptingInterface(); /**jsdoc - * Get the names of all the selection lists. - * @function Selection.getListNames - * @returns {list[]} An array of names of all the selection lists. - */ + * Gets the names of all current selection lists. + * @function Selection.getListNames + * @returns {string[]} The names of all current selection lists. + * @example List all the current selection lists. + * print("Selection lists: " + Selection.getListNames()); + */ Q_INVOKABLE QStringList getListNames() const; /**jsdoc - * Delete a named selection list. - * @function Selection.removeListFromMap - * @param {string} listName - The name of the selection list. - * @returns {boolean} true if the selection existed and was successfully removed, otherwise false. - */ + * Deletes a selection list. + * @function Selection.removeListFromMap + * @param {string} listName - The name of the selection list to delete. + * @returns {boolean} true if the selection existed and was successfully removed, otherwise false. + */ Q_INVOKABLE bool removeListFromMap(const QString& listName); /**jsdoc - * Add an item to a selection list. - * @function Selection.addToSelectedItemsList - * @param {string} listName - The name of the selection list to add the item to. - * @param {Selection.ItemType} itemType - The type of the item being added. - * @param {Uuid} id - The ID of the item to add to the selection. - * @returns {boolean} true if the item was successfully added, otherwise false. - */ + * Adds an item to a selection list. The list is created if it doesn't exist. + * @function Selection.addToSelectedItemsList + * @param {string} listName - The name of the selection list to add the item to. + * @param {Selection.ItemType} itemType - The type of item being added. + * @param {Uuid} itemID - The ID of the item to add. + * @returns {boolean} true if the item was successfully added or already existed in the list, otherwise + * false. + */ Q_INVOKABLE bool addToSelectedItemsList(const QString& listName, const QString& itemType, const QUuid& id); + /**jsdoc - * Remove an item from a selection list. - * @function Selection.removeFromSelectedItemsList - * @param {string} listName - The name of the selection list to remove the item from. - * @param {Selection.ItemType} itemType - The type of the item being removed. - * @param {Uuid} id - The ID of the item to remove. - * @returns {boolean} true if the item was successfully removed, otherwise false. - * is returned if the list doesn't contain any data. - */ + * Removes an item from a selection list. + * @function Selection.removeFromSelectedItemsList + * @param {string} listName - The name of the selection list to remove the item from. + * @param {Selection.ItemType} itemType - The type of item being removed. + * @param {Uuid} itemID - The ID of the item to remove. + * @returns {boolean} true if the item was successfully removed or was not in the list, otherwise + * false. + */ Q_INVOKABLE bool removeFromSelectedItemsList(const QString& listName, const QString& itemType, const QUuid& id); + /**jsdoc - * Remove all items from a selection. - * @function Selection.clearSelectedItemsList - * @param {string} listName - The name of the selection list. - * @returns {boolean} true if the item was successfully cleared, otherwise false. - */ + * Removes all items from a selection list. + * @function Selection.clearSelectedItemsList + * @param {string} listName - The name of the selection list. + * @returns {boolean} true always. + */ Q_INVOKABLE bool clearSelectedItemsList(const QString& listName); /**jsdoc - * Print out the list of avatars and entities in a selection to the debug log (not the script log). - * @function Selection.printList - * @param {string} listName - The name of the selection list. - */ + * Prints the list of avatars and entities in a selection to the program log (but not the Script Log window). + * @function Selection.printList + * @param {string} listName - The name of the selection list. + */ Q_INVOKABLE void printList(const QString& listName); /**jsdoc - * Get the list of avatars and entities stored in a selection list. - * @function Selection.getSelectedItemsList - * @param {string} listName - The name of the selection list. - * @returns {Selection.SelectedItemsList} The content of a selection list. If the list name doesn't exist, the function - * returns an empty object with no properties. - */ + * Gets the list of avatars and entities in a selection list. + * @function Selection.getSelectedItemsList + * @param {string} listName - The name of the selection list. + * @returns {Selection.SelectedItemsList} The content of the selection list if the list exists, otherwise an empty object. + */ Q_INVOKABLE QVariantMap getSelectedItemsList(const QString& listName) const; /**jsdoc - * Get the names of the highlighted selection lists. - * @function Selection.getHighlightedListNames - * @returns {string[]} An array of names of the selection list currently highlight enabled. - */ + * Gets the names of all current selection lists that have highlighting enabled. + * @function Selection.getHighlightedListNames + * @returns {string[]} The names of the selection lists that currently have highlighting enabled. + */ Q_INVOKABLE QStringList getHighlightedListNames() const; /**jsdoc - * Enable highlighting for a selection list. - * If the selection list doesn't exist, it will be created. - * All objects in the list will be displayed with the highlight effect specified. - * The function can be called several times with different values in the style to modify it.
- * Note: This function implicitly calls {@link Selection.enableListToScene}. - * @function Selection.enableListHighlight - * @param {string} listName - The name of the selection list. - * @param {Selection.HighlightStyle} highlightStyle - The highlight style. - * @returns {boolean} true if the selection was successfully enabled for highlight. - */ + * Enables highlighting for a selection list. All items in or subsequently added to the list are displayed with the + * highlight effect specified. The method can be called multiple times with different values in the style to modify the + * highlighting. + *

Note: This function implicitly calls {@link Selection.enableListToScene|enableListToScene}.

+ * @function Selection.enableListHighlight + * @param {string} listName - The name of the selection list. + * @param {Selection.HighlightStyle} highlightStyle - The highlight style. + * @returns {boolean} true always. + */ Q_INVOKABLE bool enableListHighlight(const QString& listName, const QVariantMap& highlightStyle); /**jsdoc - * Disable highlighting for the selection list. - * If the selection list doesn't exist or wasn't enabled for highlighting then nothing happens and false is - * returned.
- * Note: This function implicitly calls {@link Selection.disableListToScene}. - * @function Selection.disableListHighlight - * @param {string} listName - The name of the selection list. - * @returns {boolean} true if the selection was successfully disabled for highlight, otherwise - * false. - */ + * Disables highlighting for a selection list. + *

Note: This function implicitly calls {@link Selection.disableListToScene|disableListToScene}.

+ * @function Selection.disableListHighlight + * @param {string} listName - The name of the selection list. + * @returns {boolean} true always. + */ Q_INVOKABLE bool disableListHighlight(const QString& listName); + /**jsdoc - * Enable scene selection for the selection list. - * If the Selection doesn't exist, it will be created. - * All objects in the list will be sent to a scene selection. - * @function Selection.enableListToScene - * @param {string} listName - The name of the selection list. - * @returns {boolean} true if the selection was successfully enabled on the scene, otherwise false. - */ + * Enables scene selection for a selection list. All items in or subsequently added to the list are sent to a scene + * selection in the rendering engine for debugging purposes. + * @function Selection.enableListToScene + * @param {string} listName - The name of the selection list. + * @returns {boolean} true always. + */ Q_INVOKABLE bool enableListToScene(const QString& listName); /**jsdoc - * Disable scene selection for the named selection. - * If the selection list doesn't exist or wasn't enabled on the scene then nothing happens and false is - * returned. - * @function Selection.disableListToScene - * @param {string} listName - The name of the selection list. - * @returns {boolean} true if the selection was successfully disabled on the scene, false otherwise. - */ + * Disables scene selection for a selection list. + * @function Selection.disableListToScene + * @param {string} listName - The name of the selection list. + * @returns {boolean} true always. + */ Q_INVOKABLE bool disableListToScene(const QString& listName); /**jsdoc - * Get the highlight style values for the a selection list. - * If the selection doesn't exist or hasn't been highlight enabled yet, an empty object is returned. - * @function Selection.getListHighlightStyle - * @param {string} listName - The name of the selection list. - * @returns {Selection.HighlightStyle} highlight style - */ + * Gets the current highlighting style for a selection list. + * @function Selection.getListHighlightStyle + * @param {string} listName - The name of the selection list. + * @returns {Selection.HighlightStyle} The highlight style of the selection list if the list exists and highlighting is + * enabled, otherwise an empty object. + */ Q_INVOKABLE QVariantMap getListHighlightStyle(const QString& listName) const; @@ -253,7 +249,7 @@ public: signals: /**jsdoc - * Triggered when a list's content changes. + * Triggered when a selection list's content changes or the list is deleted. * @function Selection.selectedItemsListChanged * @param {string} listName - The name of the selection list that changed. * @returns {Signal} @@ -276,7 +272,6 @@ private: void setupHandler(const QString& selectionName); void removeHandler(const QString& selectionName); - }; #endif // hifi_SelectionScriptingInterface_h diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index cef6adcab0..da948f9917 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -2162,6 +2162,8 @@ qint64 AudioClient::AudioOutputIODevice::readData(char * data, qint64 maxSize) { } bytesWritten = framesPopped * AudioConstants::SAMPLE_SIZE * deviceChannelCount; + assert(bytesWritten <= maxSize); + } else { // nothing on network, don't grab anything from injectors, and just return 0s memset(data, 0, maxSize); @@ -2174,7 +2176,6 @@ qint64 AudioClient::AudioOutputIODevice::readData(char * data, qint64 maxSize) { _audio->_audioFileWav.addRawAudioChunk(reinterpret_cast(scratchBuffer), bytesWritten); } - int bytesAudioOutputUnplayed = _audio->_audioOutput->bufferSize() - _audio->_audioOutput->bytesFree(); float msecsAudioOutputUnplayed = bytesAudioOutputUnplayed / (float)_audio->_outputFormat.bytesForDuration(USECS_PER_MSEC); _audio->_stats.updateOutputMsUnplayed(msecsAudioOutputUnplayed); diff --git a/libraries/audio/src/InboundAudioStream.cpp b/libraries/audio/src/InboundAudioStream.cpp index 5ac3996029..7a81b8a67a 100644 --- a/libraries/audio/src/InboundAudioStream.cpp +++ b/libraries/audio/src/InboundAudioStream.cpp @@ -364,10 +364,19 @@ int InboundAudioStream::popSamples(int maxSamples, bool allOrNothing) { // buffer calculations. setToStarved(); _consecutiveNotMixedCount++; - //Kick PLC to generate a filler frame, reducing 'click' - lostAudioData(allOrNothing ? (maxSamples - samplesAvailable) / _ringBuffer.getNumFrameSamples() : 1); - samplesPopped = _ringBuffer.samplesAvailable(); - if (samplesPopped) { + + // use PLC to generate extrapolated audio data, to reduce clicking + if (allOrNothing) { + int samplesNeeded = maxSamples - samplesAvailable; + int packetsNeeded = (samplesNeeded + _ringBuffer.getNumFrameSamples() - 1) / _ringBuffer.getNumFrameSamples(); + lostAudioData(packetsNeeded); + } else { + lostAudioData(1); + } + samplesAvailable = _ringBuffer.samplesAvailable(); + + if (samplesAvailable > 0) { + samplesPopped = std::min(samplesAvailable, maxSamples); popSamplesNoCheck(samplesPopped); } else { // No samples available means a packet is currently being diff --git a/libraries/model-baker/src/model-baker/CalculateBlendshapeTangentsTask.cpp b/libraries/model-baker/src/model-baker/CalculateBlendshapeTangentsTask.cpp index b807aea38f..905de9b5a7 100644 --- a/libraries/model-baker/src/model-baker/CalculateBlendshapeTangentsTask.cpp +++ b/libraries/model-baker/src/model-baker/CalculateBlendshapeTangentsTask.cpp @@ -42,8 +42,8 @@ void CalculateBlendshapeTangentsTask::run(const baker::BakeContextPointer& conte continue; } - // Check if we can and should calculate tangents (we need normals to calculate the tangents) - if (normals.empty()) { + // Check if we can calculate tangents (we need normals and texcoords to calculate the tangents) + if (normals.empty() || normals.size() != (size_t)mesh.texCoords.size()) { continue; } tangentsOut.resize(normals.size()); diff --git a/libraries/model-baker/src/model-baker/CalculateMeshTangentsTask.cpp b/libraries/model-baker/src/model-baker/CalculateMeshTangentsTask.cpp index 58c54c9189..297d8cbde7 100644 --- a/libraries/model-baker/src/model-baker/CalculateMeshTangentsTask.cpp +++ b/libraries/model-baker/src/model-baker/CalculateMeshTangentsTask.cpp @@ -27,10 +27,10 @@ void CalculateMeshTangentsTask::run(const baker::BakeContextPointer& context, co auto& tangentsOut = tangentsPerMeshOut[tangentsPerMeshOut.size()-1]; // Check if we already have tangents and therefore do not need to do any calculation - // Otherwise confirm if we have the normals needed, and need to calculate the tangents + // Otherwise confirm if we have the normals and texcoords needed if (!tangentsIn.empty()) { tangentsOut = tangentsIn.toStdVector(); - } else if (!normals.empty()) { + } else if (!normals.empty() && mesh.vertices.size() == mesh.texCoords.size()) { tangentsOut.resize(normals.size()); baker::calculateTangents(mesh, [&mesh, &normals, &tangentsOut](int firstIndex, int secondIndex, glm::vec3* outVertices, glm::vec2* outTexCoords, glm::vec3& outNormal) { diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index 226433e388..3a7d3e0a67 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -97,6 +97,7 @@ void AccountManager::logout() { // remove this account from the account settings file removeAccountFromFile(); + saveLoginStatus(false); emit logoutComplete(); // the username has changed to blank @@ -650,6 +651,39 @@ void AccountManager::refreshAccessToken() { } } +void AccountManager::setAccessTokens(const QString& response) { + QJsonDocument jsonResponse = QJsonDocument::fromJson(response.toUtf8()); + const QJsonObject& rootObject = jsonResponse.object(); + + if (!rootObject.contains("error")) { + // construct an OAuthAccessToken from the json object + + if (!rootObject.contains("access_token") || !rootObject.contains("expires_in") + || !rootObject.contains("token_type")) { + // TODO: error handling - malformed token response + qCDebug(networking) << "Received a response for password grant that is missing one or more expected values."; + } else { + // clear the path from the response URL so we have the right root URL for this access token + QUrl rootURL = rootObject.contains("url") ? rootObject["url"].toString() : _authURL; + rootURL.setPath(""); + + qCDebug(networking) << "Storing an account with access-token for" << qPrintable(rootURL.toString()); + + _accountInfo = DataServerAccountInfo(); + _accountInfo.setAccessTokenFromJSON(rootObject); + emit loginComplete(rootURL); + + persistAccountToFile(); + saveLoginStatus(true); + requestProfile(); + } + } else { + // TODO: error handling + qCDebug(networking) << "Error in response for password grant -" << rootObject["error_description"].toString(); + emit loginFailed(); + } +} + void AccountManager::requestAccessTokenFinished() { QNetworkReply* requestReply = reinterpret_cast(sender()); @@ -895,3 +929,34 @@ void AccountManager::handleKeypairGenerationError() { void AccountManager::setLimitedCommerce(bool isLimited) { _limitedCommerce = isLimited; } + +void AccountManager::saveLoginStatus(bool isLoggedIn) { + if (!_configFileURL.isEmpty()) { + QFile configFile(_configFileURL); + configFile.open(QIODevice::ReadOnly | QIODevice::Text); + QJsonParseError error; + QJsonDocument jsonDocument = QJsonDocument::fromJson(configFile.readAll(), &error); + configFile.close(); + QString launcherPath; + if (error.error == QJsonParseError::NoError) { + QJsonObject rootObject = jsonDocument.object(); + if (rootObject.contains("launcherPath")) { + launcherPath = rootObject["launcherPath"].toString(); + } + if (rootObject.contains("loggedIn")) { + rootObject["loggedIn"] = isLoggedIn; + } + jsonDocument = QJsonDocument(rootObject); + + } + configFile.open(QFile::WriteOnly | QFile::Text | QFile::Truncate); + configFile.write(jsonDocument.toJson()); + configFile.close(); + if (!isLoggedIn && !launcherPath.isEmpty()) { + QProcess launcher; + launcher.setProgram(launcherPath); + launcher.startDetached(); + qApp->quit(); + } + } +} \ No newline at end of file diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index 8732042e93..c2187f79cb 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -102,6 +102,10 @@ public: bool getLimitedCommerce() { return _limitedCommerce; } void setLimitedCommerce(bool isLimited); + void setAccessTokens(const QString& response); + void setConfigFileURL(const QString& fileURL) { _configFileURL = fileURL; } + void saveLoginStatus(bool isLoggedIn); + public slots: void requestAccessToken(const QString& login, const QString& password); void requestAccessTokenWithSteam(QByteArray authSessionTicket); @@ -162,6 +166,7 @@ private: QUuid _sessionID { QUuid::createUuid() }; bool _limitedCommerce { false }; + QString _configFileURL; }; #endif // hifi_AccountManager_h diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index b3862e4252..4f0e3ca9bd 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -91,10 +91,10 @@ NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort) connect(accountManager.data(), &AccountManager::newKeypair, this, &NodeList::sendDomainServerCheckIn); // clear out NodeList when login is finished and we know our new username - connect(accountManager.data(), SIGNAL(usernameChanged(QString)) , this, SLOT(reset())); + connect(accountManager.data(), &AccountManager::usernameChanged , this, [this]{ reset("Username changed"); }); // clear our NodeList when logout is requested - connect(accountManager.data(), SIGNAL(logoutComplete()) , this, SLOT(reset())); + connect(accountManager.data(), &AccountManager::logoutComplete , this, [this]{ reset("Logged out"); }); // anytime we get a new node we will want to attempt to punch to it connect(this, &LimitedNodeList::nodeAdded, this, &NodeList::startNodeHolePunch); diff --git a/scripts/simplifiedUI/defaultScripts.js b/scripts/simplifiedUI/defaultScripts.js new file mode 100644 index 0000000000..0911c6518a --- /dev/null +++ b/scripts/simplifiedUI/defaultScripts.js @@ -0,0 +1,41 @@ +"use strict"; +/* jslint vars: true, plusplus: true */ + +// +// defaultScripts.js +// +// Authors: Zach Fox +// Created: 2019-05-23 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +var DEFAULT_SCRIPTS_PATH_PREFIX = ScriptDiscoveryService.defaultScriptsPath + "/"; + + +var DEFAULT_SCRIPTS_SEPARATE = [ + DEFAULT_SCRIPTS_PATH_PREFIX + "system/controllers/controllerScripts.js", + Script.resolvePath("simplifiedUI.js") +]; +function loadSeparateDefaults() { + for (var i in DEFAULT_SCRIPTS_SEPARATE) { + Script.load(DEFAULT_SCRIPTS_SEPARATE[i]); + } +} + + +var DEFAULT_SCRIPTS_COMBINED = [ + DEFAULT_SCRIPTS_PATH_PREFIX + "system/request-service.js", + DEFAULT_SCRIPTS_PATH_PREFIX + "system/progress.js", + DEFAULT_SCRIPTS_PATH_PREFIX + "system/away.js" +]; +function runDefaultsTogether() { + for (var i in DEFAULT_SCRIPTS_COMBINED) { + Script.include(DEFAULT_SCRIPTS_COMBINED[i]); + } + loadSeparateDefaults(); +} + + +runDefaultsTogether(); diff --git a/scripts/system/simplifiedUI/images/inputDeviceMuted.svg b/scripts/simplifiedUI/images/inputDeviceMuted.svg similarity index 100% rename from scripts/system/simplifiedUI/images/inputDeviceMuted.svg rename to scripts/simplifiedUI/images/inputDeviceMuted.svg diff --git a/scripts/system/simplifiedUI/images/outputDeviceMuted.svg b/scripts/simplifiedUI/images/outputDeviceMuted.svg similarity index 100% rename from scripts/system/simplifiedUI/images/outputDeviceMuted.svg rename to scripts/simplifiedUI/images/outputDeviceMuted.svg diff --git a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/defaultLocalEntityProps.js b/scripts/simplifiedUI/simplifiedNametag/resources/modules/defaultLocalEntityProps.js similarity index 100% rename from scripts/system/simplifiedUI/simplifiedNametag/resources/modules/defaultLocalEntityProps.js rename to scripts/simplifiedUI/simplifiedNametag/resources/modules/defaultLocalEntityProps.js diff --git a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/entityMaker.js b/scripts/simplifiedUI/simplifiedNametag/resources/modules/entityMaker.js similarity index 100% rename from scripts/system/simplifiedUI/simplifiedNametag/resources/modules/entityMaker.js rename to scripts/simplifiedUI/simplifiedNametag/resources/modules/entityMaker.js diff --git a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/nameTagListManager.js b/scripts/simplifiedUI/simplifiedNametag/resources/modules/nameTagListManager.js similarity index 100% rename from scripts/system/simplifiedUI/simplifiedNametag/resources/modules/nameTagListManager.js rename to scripts/simplifiedUI/simplifiedNametag/resources/modules/nameTagListManager.js diff --git a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/objectAssign.js b/scripts/simplifiedUI/simplifiedNametag/resources/modules/objectAssign.js similarity index 100% rename from scripts/system/simplifiedUI/simplifiedNametag/resources/modules/objectAssign.js rename to scripts/simplifiedUI/simplifiedNametag/resources/modules/objectAssign.js diff --git a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/pickRayController.js b/scripts/simplifiedUI/simplifiedNametag/resources/modules/pickRayController.js similarity index 100% rename from scripts/system/simplifiedUI/simplifiedNametag/resources/modules/pickRayController.js rename to scripts/simplifiedUI/simplifiedNametag/resources/modules/pickRayController.js diff --git a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/textHelper.js b/scripts/simplifiedUI/simplifiedNametag/resources/modules/textHelper.js similarity index 100% rename from scripts/system/simplifiedUI/simplifiedNametag/resources/modules/textHelper.js rename to scripts/simplifiedUI/simplifiedNametag/resources/modules/textHelper.js diff --git a/scripts/system/simplifiedUI/simplifiedNametag/simplifiedNametag.js b/scripts/simplifiedUI/simplifiedNametag/simplifiedNametag.js similarity index 100% rename from scripts/system/simplifiedUI/simplifiedNametag/simplifiedNametag.js rename to scripts/simplifiedUI/simplifiedNametag/simplifiedNametag.js diff --git a/scripts/system/simplifiedUI/simplifiedStatusIndicator/simplifiedStatusIndicator.js b/scripts/simplifiedUI/simplifiedStatusIndicator/simplifiedStatusIndicator.js similarity index 100% rename from scripts/system/simplifiedUI/simplifiedStatusIndicator/simplifiedStatusIndicator.js rename to scripts/simplifiedUI/simplifiedStatusIndicator/simplifiedStatusIndicator.js diff --git a/scripts/system/simplifiedUI/simplifiedUI.js b/scripts/simplifiedUI/simplifiedUI.js similarity index 84% rename from scripts/system/simplifiedUI/simplifiedUI.js rename to scripts/simplifiedUI/simplifiedUI.js index 94eb9f84fd..a6183c5ab9 100644 --- a/scripts/system/simplifiedUI/simplifiedUI.js +++ b/scripts/simplifiedUI/simplifiedUI.js @@ -5,7 +5,7 @@ // simplifiedUI.js // // Authors: Wayne Chen & Zach Fox -// Created on: 5/1/2019 +// Created: 2019-05-01 // Copyright 2019 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -103,6 +103,8 @@ var AVATAR_APP_PRESENTATION_MODE = Desktop.PresentationMode.NATIVE; var AVATAR_APP_WIDTH_PX = 480; var AVATAR_APP_HEIGHT_PX = 615; var avatarAppWindow = false; +var POPOUT_SAFE_MARGIN_X = 30; +var POPOUT_SAFE_MARGIN_Y = 30; function toggleAvatarApp() { if (avatarAppWindow) { avatarAppWindow.close(); @@ -119,6 +121,10 @@ function toggleAvatarApp() { size: { x: AVATAR_APP_WIDTH_PX, y: AVATAR_APP_HEIGHT_PX + }, + position: { + x: Math.max(Window.x + POPOUT_SAFE_MARGIN_X, Window.x + Window.innerWidth / 2 - AVATAR_APP_WIDTH_PX / 2), + y: Math.max(Window.y + POPOUT_SAFE_MARGIN_Y, Window.y + Window.innerHeight / 2 - AVATAR_APP_HEIGHT_PX / 2) } }); @@ -181,6 +187,10 @@ function toggleSettingsApp() { size: { x: SETTINGS_APP_WIDTH_PX, y: SETTINGS_APP_HEIGHT_PX + }, + position: { + x: Math.max(Window.x + POPOUT_SAFE_MARGIN_X, Window.x + Window.innerWidth / 2 - SETTINGS_APP_WIDTH_PX / 2), + y: Math.max(Window.y + POPOUT_SAFE_MARGIN_Y, Window.y + Window.innerHeight / 2 - SETTINGS_APP_HEIGHT_PX / 2) } }); @@ -238,40 +248,39 @@ function updateOutputDeviceMutedOverlay(isMuted) { } -var savedAvatarGain = Audio.getAvatarGain(); -var savedInjectorGain = Audio.getInjectorGain(); -var savedLocalInjectorGain = Audio.getLocalInjectorGain(); -var savedSystemInjectorGain = Audio.getSystemInjectorGain(); +var savedAvatarGain = Audio.avatarGain; +var savedServerInjectorGain = Audio.serverInjectorGain; +var savedLocalInjectorGain = Audio.localInjectorGain; +var savedSystemInjectorGain = Audio.systemInjectorGain; +var MUTED_VALUE_DB = -60; // This should always match `SimplifiedConstants.qml` -> numericConstants -> mutedValue! function setOutputMuted(outputMuted) { - updateOutputDeviceMutedOverlay(outputMuted); - if (outputMuted) { - savedAvatarGain = Audio.getAvatarGain(); - savedInjectorGain = Audio.getInjectorGain(); - savedLocalInjectorGain = Audio.getLocalInjectorGain(); - savedSystemInjectorGain = Audio.getSystemInjectorGain(); + savedAvatarGain = Audio.avatarGain; + savedServerInjectorGain = Audio.serverInjectorGain; + savedLocalInjectorGain = Audio.localInjectorGain; + savedSystemInjectorGain = Audio.systemInjectorGain; - Audio.setAvatarGain(-60); - Audio.setInjectorGain(-60); - Audio.setLocalInjectorGain(-60); - Audio.setSystemInjectorGain(-60); + Audio.avatarGain = MUTED_VALUE_DB; + Audio.serverInjectorGain = MUTED_VALUE_DB; + Audio.localInjectorGain = MUTED_VALUE_DB; + Audio.systemInjectorGain = MUTED_VALUE_DB; } else { - if (savedAvatarGain === -60) { + if (savedAvatarGain === MUTED_VALUE_DB) { savedAvatarGain = 0; } - Audio.setAvatarGain(savedAvatarGain); - if (savedInjectorGain === -60) { - savedInjectorGain = 0; + Audio.avatarGain = savedAvatarGain; + if (savedServerInjectorGain === MUTED_VALUE_DB) { + savedServerInjectorGain = 0; } - Audio.setInjectorGain(savedInjectorGain); - if (savedLocalInjectorGain === -60) { + Audio.serverInjectorGain = savedServerInjectorGain; + if (savedLocalInjectorGain === MUTED_VALUE_DB) { savedLocalInjectorGain = 0; } - Audio.setLocalInjectorGain(savedLocalInjectorGain); - if (savedSystemInjectorGain === -60) { + Audio.localInjectorGain = savedLocalInjectorGain; + if (savedSystemInjectorGain === MUTED_VALUE_DB) { savedSystemInjectorGain = 0; } - Audio.setSystemInjectorGain(savedSystemInjectorGain); + Audio.systemInjectorGain = savedSystemInjectorGain; } } @@ -334,7 +343,10 @@ function onTopBarClosed() { function isOutputMuted() { - return Audio.getAvatarGain() === -60 && Audio.getInjectorGain() === -60 && Audio.getLocalInjectorGain() === -60 && Audio.getSystemInjectorGain() === -60; + return Audio.avatarGain === MUTED_VALUE_DB && + Audio.serverInjectorGain === MUTED_VALUE_DB && + Audio.localInjectorGain === MUTED_VALUE_DB && + Audio.systemInjectorGain === MUTED_VALUE_DB; } @@ -370,15 +382,7 @@ function loadSimplifiedTopBar() { // The eventbridge takes a nonzero time to initialize, so we have to wait a bit // for the QML to load and for that to happen before updating the UI. - Script.setTimeout(function() { - topBarWindow.sendToQml({ - "source": "simplifiedUI.js", - "method": "updateOutputMuted", - "data": { - "outputMuted": isOutputMuted() - } - }); - + Script.setTimeout(function() { sendLocalStatusToQml(); }, WAIT_FOR_TOP_BAR_MS); } @@ -469,6 +473,11 @@ function onStatusChanged() { } +function maybeUpdateOutputDeviceMutedOverlay() { + updateOutputDeviceMutedOverlay(isOutputMuted()); +} + + var simplifiedNametag = Script.require("./simplifiedNametag/simplifiedNametag.js?" + Date.now()); var SimplifiedStatusIndicator = Script.require("./simplifiedStatusIndicator/simplifiedStatusIndicator.js?" + Date.now()); var si; @@ -501,6 +510,10 @@ function startup() { Audio.mutedDesktopChanged.connect(onDesktopInputDeviceMutedChanged); Window.geometryChanged.connect(onGeometryChanged); HMD.displayModeChanged.connect(ensureFirstPersonCameraInHMD); + Audio.avatarGainChanged.connect(maybeUpdateOutputDeviceMutedOverlay); + Audio.localInjectorGainChanged.connect(maybeUpdateOutputDeviceMutedOverlay); + Audio.serverInjectorGainChanged.connect(maybeUpdateOutputDeviceMutedOverlay); + Audio.systemInjectorGainChanged.connect(maybeUpdateOutputDeviceMutedOverlay); oldShowAudioTools = AvatarInputs.showAudioTools; AvatarInputs.showAudioTools = false; @@ -551,6 +564,10 @@ function shutdown() { Audio.mutedDesktopChanged.disconnect(onDesktopInputDeviceMutedChanged); Window.geometryChanged.disconnect(onGeometryChanged); HMD.displayModeChanged.disconnect(ensureFirstPersonCameraInHMD); + Audio.avatarGainChanged.disconnect(maybeUpdateOutputDeviceMutedOverlay); + Audio.localInjectorGainChanged.disconnect(maybeUpdateOutputDeviceMutedOverlay); + Audio.serverInjectorGainChanged.disconnect(maybeUpdateOutputDeviceMutedOverlay); + Audio.systemInjectorGainChanged.disconnect(maybeUpdateOutputDeviceMutedOverlay); AvatarInputs.showAudioTools = oldShowAudioTools; AvatarInputs.showBubbleTools = oldShowBubbleTools; diff --git a/tools/ci-scripts/postbuild.py b/tools/ci-scripts/postbuild.py new file mode 100644 index 0000000000..a1561f6203 --- /dev/null +++ b/tools/ci-scripts/postbuild.py @@ -0,0 +1,20 @@ +# Post build script +import os +import sys + +SOURCE_PATH = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '..', '..')) +BUILD_PATH = os.path.join(SOURCE_PATH, 'build') + +# FIXME move the helper python modules somewher other than the root of the repo +sys.path.append(SOURCE_PATH) + +import hifi_utils + +#for var in sys.argv: +# print("{}".format(var)) + +#for var in os.environ: +# print("{} = {}".format(var, os.environ[var])) + +print("Create ZIP version of installer archive") +hifi_utils.executeSubprocess(['cpack', '-G', 'ZIP'], folder=BUILD_PATH) diff --git a/tools/qt-builder/README.md b/tools/qt-builder/README.md index 4cd49ce865..b7861a5e53 100644 --- a/tools/qt-builder/README.md +++ b/tools/qt-builder/README.md @@ -1,235 +1,235 @@ # General This document describes the process to build Qt 5.12.3. -Note that there are two patches. The first (to qfloat16.h) is needed to compile QT 5.12.3 on Visual Studio 2017 due to a bug in Visual Studio (*bitset* will not compile. Note that there is a change in CMakeLists.txt to support this. +Note that there are two patches. The first (to qfloat16.h) is needed to compile QT 5.12.3 on Visual Studio 2017 due to a bug in Visual Studio (*bitset* will not compile. Note that there is a change in CMakeLists.txt to support this. The second patch is to OpenSL ES audio. ## Requirements ### Windows -1. Visual Studio 2017 - If you don’t have Community or Professional edition of Visual Studio 2017, download [Visual Studio Community 2017](https://www.visualstudio.com/downloads/). +1. Visual Studio 2017 + If you don’t have Community or Professional edition of Visual Studio 2017, download [Visual Studio Community 2017](https://www.visualstudio.com/downloads/). Install with defaults 1. python 2.7.16 -Check if needed running `python --version` - should return python 2.7.x -Install from https://www.python.org/ftp/python/2.7.16/python-2.7.16.amd64.msi +Check if needed running `python --version` - should return python 2.7.x +Install from https://www.python.org/ftp/python/2.7.16/python-2.7.16.amd64.msi Add path to python executable to PATH. NOTE: REMOVE python 3 from PATH. Our regular build uses python 3. This will still work, because HIFI_PYTHON_EXEC points to the python 3 executable. -Verify that python runs python 2.7 (run “python --version”) -1. git >= 1.6 -Check if needed `git --version` -Download from https://git-scm.com/download/win -Verify by entering `git --version` -1. perl >= 5.14 -Install from Strawberry Perl - http://strawberryperl.com/ - 5.28.1.1 64 bit to C:\Strawberry\ -Verify by running `perl --version` -1. flex and bison -Download from https://sourceforge.net/projects/winflexbison/files/latest/download -Uncompress in C:\flex_bison -Rename win-bison.exe to bison.exe and win-flex.exe to flex.exe -Add C:\flex_bison to PATH -Verify by running `flex --version` -Verify by running `bison --version` -1. gperf -Install from http://gnuwin32.sourceforge.net/downlinks/gperf.php -Add C:\Program Files (x86)\GnuWin32\bin to PATH -Verify by running `gperf --version` -1. 7-zip -Download from https://www.7-zip.org/download.html -1. Bash shell -From *Settings* select *Update & Security* -Select *For Developers* -Enable *Developer mode* -Restart PC -Open Control Panel and select *Programs and Features* -Select *Turn Windows features on or off* -Check *Windows Subsystem for Linux* -Click *Restart now* -Download from the Microsoft Store - Search for *bash* and choose the latest Ubuntu version -[First run will take a few minutes] -Enter a user name - all small letters (this is used for *sudo* commands) -Choose a password +Verify that python runs python 2.7 (run “python --version”) +1. git >= 1.6 +Check if needed `git --version` +Download from https://git-scm.com/download/win +Verify by entering `git --version` +1. perl >= 5.14 +Install from Strawberry Perl - http://strawberryperl.com/ - 5.28.1.1 64 bit to C:\Strawberry\ +Verify by running `perl --version` +1. flex and bison +Download from https://sourceforge.net/projects/winflexbison/files/latest/download +Uncompress in C:\flex_bison +Rename win-bison.exe to bison.exe and win-flex.exe to flex.exe +Add C:\flex_bison to PATH +Verify by running `flex --version` +Verify by running `bison --version` +1. gperf +Install from http://gnuwin32.sourceforge.net/downlinks/gperf.php +Add C:\Program Files (x86)\GnuWin32\bin to PATH +Verify by running `gperf --version` +1. 7-zip +Download from https://www.7-zip.org/download.html +1. Bash shell +From *Settings* select *Update & Security* +Select *For Developers* +Enable *Developer mode* +Restart PC +Open Control Panel and select *Programs and Features* +Select *Turn Windows features on or off* +Check *Windows Subsystem for Linux* +Click *Restart now* +Download from the Microsoft Store - Search for *bash* and choose the latest Ubuntu version +[First run will take a few minutes] +Enter a user name - all small letters (this is used for *sudo* commands) +Choose a password ### Linux -Tested on Ubuntu 16.04 and 18.04. +Tested on Ubuntu 16.04 and 18.04. **16.04 NEEDED FOR JENKINS~~ ** -1. qt5 requirements -edit /etc/apt/sources.list (edit as root) -replace all *# deb-src* with *deb-src* (in vi `1,$s/# deb-src/deb-src/`) -`sudo apt-get update -y` -`sudo apt-get upgrade -y` -`sudo apt-get build-dep qt5-default -y` -1. git >= 1.6 -Check if needed `git --version` -`sudo apt-get install git -y` -Verify again -1. python -Check if needed `python --version` - should return python 2.7.x -`sudo apt-get install python -y` (not python 3!) -Verify again -1. gperf -Check if needed `gperf --version` -`sudo apt-get install gperf -y` -Verify again -1. bison and flex -Check if needed `flex --version` and `bison --version` -`sudo apt-get install flex bison -y` -Verify again -1. pkg-config (needed for qtwebengine) -Check if needed `pkg-config --version` -`sudo apt-get install pkg-config -y` -Verify again -1. OpenGL -Verify (first install mesa-utils - `sudo apt install mesa-utils -y`) by `glxinfo | grep "OpenGL version"` -`sudo apt-get install libgl1-mesa-dev -y` -`sudo ln -s /usr/lib/x86_64-linux-gnu/libGL.so.346.35 /usr/lib/x86_64-linux-gnu/libGL.so.1.2.0` -Verify again -1. make -Check if needed `make --version` -`sudo apt-get install make -y` -Verify again -1. g++ -Check if needed - `g++ --version` -`sudo apt-get install g++ -y` -Verify again -1. dbus-1 (needed for qtwebengine) -`sudo apt-get install libdbus-glib-1-dev -y` -1. nss (needed for qtwebengine) -`sudo apt-get install libnss3-dev -y` +1. qt5 requirements +edit /etc/apt/sources.list (edit as root) +replace all *# deb-src* with *deb-src* (in vi `1,$s/# deb-src/deb-src/`) +`sudo apt-get update -y` +`sudo apt-get upgrade -y` +`sudo apt-get build-dep qt5-default -y` +1. git >= 1.6 +Check if needed `git --version` +`sudo apt-get install git -y` +Verify again +1. python +Check if needed `python --version` - should return python 2.7.x +`sudo apt-get install python -y` (not python 3!) +Verify again +1. gperf +Check if needed `gperf --version` +`sudo apt-get install gperf -y` +Verify again +1. bison and flex +Check if needed `flex --version` and `bison --version` +`sudo apt-get install flex bison -y` +Verify again +1. pkg-config (needed for qtwebengine) +Check if needed `pkg-config --version` +`sudo apt-get install pkg-config -y` +Verify again +1. OpenGL +Verify (first install mesa-utils - `sudo apt install mesa-utils -y`) by `glxinfo | grep "OpenGL version"` +`sudo apt-get install libgl1-mesa-dev -y` +`sudo ln -s /usr/lib/x86_64-linux-gnu/libGL.so.346.35 /usr/lib/x86_64-linux-gnu/libGL.so.1.2.0` +Verify again +1. make +Check if needed `make --version` +`sudo apt-get install make -y` +Verify again +1. g++ +Check if needed + `g++ --version` +`sudo apt-get install g++ -y` +Verify again +1. dbus-1 (needed for qtwebengine) +`sudo apt-get install libdbus-glib-1-dev -y` +1. nss (needed for qtwebengine) +`sudo apt-get install libnss3-dev -y` ### Mac -1. git >= 1.6 -Check if needed `git --version` -Install from https://git-scm.com/download/mac -Verify again -1. pkg-config -brew fontconfig dbus-glib stall pkg-config -1. dbus-1 -brew install dbus-glib +1. git >= 1.6 +Check if needed `git --version` +Install from https://git-scm.com/download/mac +Verify again +1. pkg-config +brew fontconfig dbus-glib stall pkg-config +1. dbus-1 +brew install dbus-glib ## Build Process ### General -qt is cloned to the qt5 folder. -The build is performed in the qt5-build folder. -Build products are installed to the qt5-install folder. -Before running configure, make sure that the qt5-build folder is empty. +qt is cloned to the qt5 folder. +The build is performed in the qt5-build folder. +Build products are installed to the qt5-install folder. +Before running configure, make sure that the qt5-build folder is empty. -**Only run the git patches once!!!** +**Only run the git patches once!!!** ### Windows -Before building, verify that **HIFI_VCPKG_BASE_VERSION** points to a *vcpkg* folder containing *packages\openssl-windows_x64-windows*. -If not, follow https://github.com/highfidelity/vcpkg to install *vcpkg* and then *openssl*. +Before building, verify that **HIFI_VCPKG_BASE_VERSION** points to a *vcpkg* folder containing *packages\openssl-windows_x64-windows*. +If not, follow https://github.com/highfidelity/vcpkg to install *vcpkg* and then *openssl*. #### Preparing source files -`git clone --recursive https://code.qt.io/qt/qt5.git -b 5.12.3 --single-branch` - -* Copy the **patches** folder to qt5 -* Copy the **qt5vars.bat** file to qt5 -* Apply the two patches to Qt +`git clone --recursive https://code.qt.io/qt/qt5.git -b 5.12.3 --single-branch` -`cd qt5` -`git apply --ignore-space-change --ignore-whitespace patches/qfloat16.patch` -`git apply --ignore-space-change --ignore-whitespace patches/aec.patch` -`cd ..` -#### Configuring -`mkdir qt5-install` -`mkdir qt5-build` -`cd qt5-build` +* Copy the **patches** folder to qt5 +* Copy the **qt5vars.bat** file to qt5 +* Apply the two patches to Qt -run `..\qt5\qt5vars.bat` -`cd ..\..\qt5-build` - -`..\qt5\configure -force-debug-info -opensource -confirm-license -opengl desktop -platform win32-msvc -openssl-linked OPENSSL_LIBS="-lssleay32 -llibeay32" -I %HIFI_VCPKG_BASE_VERSION%\packages\openssl-windows_x64-windows\include -L %HIFI_VCPKG_BASE_VERSION%\packages\openssl-windows_x64-windows\lib -nomake examples -nomake tests -skip qttranslations -skip qtserialport -skip qt3d -skip qtlocation -skip qtwayland -skip qtsensors -skip qtgamepad -skip qtspeech -skip qtcharts -skip qtx11extras -skip qtmacextras -skip qtvirtualkeyboard -skip qtpurchasing -skip qtdatavis3d -no-warnings-are-errors -no-pch -prefix ..\qt5-install` -#### Make -`nmake` -`nmake install` -#### Fixing -The *.prl* files have an absolute path that needs to be removed (see http://www.linuxfromscratch.org/blfs/view/stable-systemd/x/qtwebengine.html) -1. Open a bash terminal -1. `cd` to the *qt5-install* folder (e.g. `cd /mnt/d/qt5-install/`) -1. Run the following command -`find . -name \*.prl -exec sed -i -e '/^QMAKE_PRL_BUILD_DIR/d' {} \;` -1. Copy *qt.conf* to *qt5-install\bin* -#### Uploading -Create a tar file called qt5-install.tar from the qt5-install folder (e.g. using 7-zip) -Create a gzip file called qt5-install.tar.gz from the qt5-install.tar file just created (e.g. using 7-zip) -Upload qt5-install.tar.gz to https://hifi-qa.s3.amazonaws.com/qt5/Windows/ -### Linux -#### Preparing source files -`git clone --recursive git://code.qt.io/qt/qt5.git -b 5.12.3 --single-branch` - -* Copy the **patches** folder to qt5 -* Apply one patch to Qt -`cd qt5` -`git apply --ignore-space-change --ignore-whitespace patches/aec.patch` +`cd qt5` +`git apply --ignore-space-change --ignore-whitespace patches/qfloat16.patch` +`git apply --ignore-space-change --ignore-whitespace patches/aec.patch` `cd ..` #### Configuring -`mkdir qt5-install` -`mkdir qt5-build` -`cd qt5-build` +`mkdir qt5-install` +`mkdir qt5-build` +`cd qt5-build` -*Ubuntu 16.04* -`../qt5/configure -opensource -confirm-license -platform linux-g++-64 -qt-zlib -qt-libjpeg -qt-libpng -qt-xcb -qt-freetype -qt-pcre -qt-harfbuzz -nomake examples -nomake tests -skip qttranslations -skip qtserialport -skip qt3d -skip qtlocation -skip qtwayland -skip qtsensors -skip qtgamepad -skip qtspeech -skip qtcharts -skip qtmacextras -skip qtvirtualkeyboard -skip qtpurchasing -skip qtdatavis3d -no-warnings-are-errors -no-pch -no-egl -no-icu -prefix ../qt5-install` +run `..\qt5\qt5vars.bat` +`cd ..\..\qt5-build` -*Ubuntu 18.04* -`../qt5/configure -force-debug-info -release -opensource -confirm-license -gdb-index -recheck-all -nomake tests -nomake examples -skip qttranslations -skip qtserialport -skip qt3d -skip qtlocation -skip qtwayland -skip qtsensors -skip qtgamepad -skip qtspeech -skip qtcharts -skip qtx11extras -skip qtmacextras -skip qtvirtualkeyboard -skip qtpurchasing -skip qtdatavis3d -no-warnings-are-errors -no-pch -c++std c++14 -prefix ../qt5-install` - - -???`../qt5/configure -opensource -confirm-license -gdb-index -nomake examples -nomake tests -skip qttranslations -skip qtserialport -skip qt3d -skip qtlocation -skip qtwayland -skip qtsensors -skip qtgamepad -skip qtspeech -skip qtcharts -skip qtmacextras -skip qtvirtualkeyboard -skip qtpurchasing -skip qtdatavis3d -no-warnings-are-errors -no-pch -prefix ../qt5-install` -#### Make -`make` - -????*Ubuntu 18.04 only* -????`make module-qtwebengine` -????`make module-qtscript` - -*Both* -`make install` -#### Fixing -1. The *.prl* files have an absolute path that needs to be removed (see http://www.linuxfromscratch.org/blfs/view/stable-systemd/x/qtwebengine.html) -`cd ../qt5-install` -`find . -name \*.prl -exec sed -i -e '/^QMAKE_PRL_BUILD_DIR/d' {} \;` -1. Copy *qt.conf* to *qt5-install\bin* -#### Uploading -*Ubuntu 16.04* -1. Return to the home folder -`cd ..` -1. Open a python 3 shell -`python3` -1. Run the following snippet: -`import os` -`import tarfile` -`filename=tarfile.open("qt5-install.tar.gz", "w:gz")` -`filename.add("qt5-install", os.path.basename("qt5-install"))` -`exit()` -1. Upload qt5-install.tar.gz to https://hifi-qa.s3.amazonaws.com/qt5/Ubuntu/16.04 - -*Ubuntu 18.04* -``tar -zcvf qt5-install.tar.gz qt5-install` -1. Upload qt5-install.tar.gz to https://hifi-qa.s3.amazonaws.com/qt5/Ubuntu/18.04 - -1. ### Mac -#### Preparing source files -git clone --recursive git://code.qt.io/qt/qt5.git -b 5.12.3 --single-branch - -* Copy the **patches** folder to qt5 -* Apply one patch to Qt -`cd qt5` -`git apply --ignore-space-change --ignore-whitespace patches/aec.patch` -`cd ..` -#### Configuring -`mkdir qt5-install` -`mkdir qt5-build` -`cd ../qt5-build` - -`../qt5/configure -force-debug-info -opensource -confirm-license -qt-zlib -qt-libjpeg -qt-libpng -qt-freetype -qt-pcre -qt-harfbuzz -nomake examples -nomake tests -skip qttranslations -skip qtserialport -skip qt3d -skip qtlocation -skip qtwayland -skip qtsensors -skip qtgamepad -skip qtspeech -skip qtcharts -skip qtx11extras -skip qtmacextras -skip qtvirtualkeyboard -skip qtpurchasing -skip qtdatavis3d -no-warnings-are-errors -no-pch -prefix ../qt5-install` +`..\qt5\configure -force-debug-info -opensource -confirm-license -opengl desktop -platform win32-msvc -openssl-linked OPENSSL_LIBS="-lssleay32 -llibeay32" -I %HIFI_VCPKG_BASE_VERSION%\packages\openssl-windows_x64-windows\include -L %HIFI_VCPKG_BASE_VERSION%\packages\openssl-windows_x64-windows\lib -nomake examples -nomake tests -skip qttranslations -skip qtserialport -skip qt3d -skip qtlocation -skip qtwayland -skip qtsensors -skip qtgamepad -skip qtspeech -skip qtcharts -skip qtx11extras -skip qtmacextras -skip qtvirtualkeyboard -skip qtpurchasing -skip qtdatavis3d -no-warnings-are-errors -no-pch -prefix ..\qt5-install` #### Make -`make` -`make install` +`nmake` +`nmake install` #### Fixing -1. The *.prl* files have an absolute path that needs to be removed (see http://www.linuxfromscratch.org/blfs/view/stable-systemd/x/qtwebengine.html) -`cd ../qt5-install` -`find . -name \*.prl -exec sed -i -e '/^QMAKE_PRL_BUILD_DIR/d' {} \;` -`cd ..` -1. Copy *qt.conf* to *qt5-install\bin* +The *.prl* files have an absolute path that needs to be removed (see http://www.linuxfromscratch.org/blfs/view/stable-systemd/x/qtwebengine.html) +1. Open a bash terminal +1. `cd` to the *qt5-install* folder (e.g. `cd /mnt/d/qt5-install/`) +1. Run the following command +`find . -name \*.prl -exec sed -i -e '/^QMAKE_PRL_BUILD_DIR/d' {} \;` +1. Copy *qt.conf* to *qt5-install\bin* #### Uploading -`tar -zcvf qt5-install.tar.gz qt5-install` -Upload qt5-install.tar.gz to https://hifi-qa.s3.amazonaws.com/qt5/Mac/ +Create a tar file called qt5-install.tar from the qt5-install folder (e.g. using 7-zip) +Create a gzip file called qt5-install.tar.gz from the qt5-install.tar file just created (e.g. using 7-zip) +Upload qt5-install.tar.gz to https://hifi-qa.s3.amazonaws.com/qt5/Windows/ +### Linux +#### Preparing source files +`git clone --recursive git://code.qt.io/qt/qt5.git -b 5.12.3 --single-branch` + +* Copy the **patches** folder to qt5 +* Apply one patch to Qt +`cd qt5` +`git apply --ignore-space-change --ignore-whitespace patches/aec.patch` +`cd ..` +#### Configuring +`mkdir qt5-install` +`mkdir qt5-build` +`cd qt5-build` + +*Ubuntu 16.04* +`../qt5/configure -opensource -confirm-license -platform linux-g++-64 -qt-zlib -qt-libjpeg -qt-libpng -qt-xcb -qt-freetype -qt-pcre -qt-harfbuzz -nomake examples -nomake tests -skip qttranslations -skip qtserialport -skip qt3d -skip qtlocation -skip qtwayland -skip qtsensors -skip qtgamepad -skip qtspeech -skip qtcharts -skip qtmacextras -skip qtvirtualkeyboard -skip qtpurchasing -skip qtdatavis3d -no-warnings-are-errors -no-pch -no-egl -no-icu -prefix ../qt5-install` + +*Ubuntu 18.04* +`../qt5/configure -force-debug-info -release -opensource -confirm-license -gdb-index -recheck-all -nomake tests -nomake examples -skip qttranslations -skip qtserialport -skip qt3d -skip qtlocation -skip qtwayland -skip qtsensors -skip qtgamepad -skip qtspeech -skip qtcharts -skip qtx11extras -skip qtmacextras -skip qtvirtualkeyboard -skip qtpurchasing -skip qtdatavis3d -no-warnings-are-errors -no-pch -c++std c++14 -prefix ../qt5-install` + + +???`../qt5/configure -opensource -confirm-license -gdb-index -nomake examples -nomake tests -skip qttranslations -skip qtserialport -skip qt3d -skip qtlocation -skip qtwayland -skip qtsensors -skip qtgamepad -skip qtspeech -skip qtcharts -skip qtmacextras -skip qtvirtualkeyboard -skip qtpurchasing -skip qtdatavis3d -no-warnings-are-errors -no-pch -prefix ../qt5-install` +#### Make +`make` + +????*Ubuntu 18.04 only* +????`make module-qtwebengine` +????`make module-qtscript` + +*Both* +`make install` +#### Fixing +1. The *.prl* files have an absolute path that needs to be removed (see http://www.linuxfromscratch.org/blfs/view/stable-systemd/x/qtwebengine.html) +`cd ../qt5-install` +`find . -name \*.prl -exec sed -i -e '/^QMAKE_PRL_BUILD_DIR/d' {} \;` +1. Copy *qt.conf* to *qt5-install\bin* +#### Uploading +*Ubuntu 16.04* +1. Return to the home folder +`cd ..` +1. Open a python 3 shell +`python3` +1. Run the following snippet: +`import os` +`import tarfile` +`filename=tarfile.open("qt5-install.tar.gz", "w:gz")` +`filename.add("qt5-install", os.path.basename("qt5-install"))` +`exit()` +1. Upload qt5-install.tar.gz to https://hifi-qa.s3.amazonaws.com/qt5/Ubuntu/16.04 + +*Ubuntu 18.04* +``tar -zcvf qt5-install.tar.gz qt5-install` +1. Upload qt5-install.tar.gz to https://hifi-qa.s3.amazonaws.com/qt5/Ubuntu/18.04 + +1. ### Mac +#### Preparing source files +git clone --recursive git://code.qt.io/qt/qt5.git -b 5.12.3 --single-branch + +* Copy the **patches** folder to qt5 +* Apply one patch to Qt +`cd qt5` +`git apply --ignore-space-change --ignore-whitespace patches/aec.patch` +`cd ..` +#### Configuring +`mkdir qt5-install` +`mkdir qt5-build` +`cd ../qt5-build` + +`../qt5/configure -force-debug-info -opensource -confirm-license -qt-zlib -qt-libjpeg -qt-libpng -qt-freetype -qt-pcre -qt-harfbuzz -nomake examples -nomake tests -skip qttranslations -skip qtserialport -skip qt3d -skip qtlocation -skip qtwayland -skip qtsensors -skip qtgamepad -skip qtspeech -skip qtcharts -skip qtx11extras -skip qtmacextras -skip qtvirtualkeyboard -skip qtpurchasing -skip qtdatavis3d -no-warnings-are-errors -no-pch -prefix ../qt5-install` +#### Make +`make` +`make install` +#### Fixing +1. The *.prl* files have an absolute path that needs to be removed (see http://www.linuxfromscratch.org/blfs/view/stable-systemd/x/qtwebengine.html) +`cd ../qt5-install` +`find . -name \*.prl -exec sed -i -e '/^QMAKE_PRL_BUILD_DIR/d' {} \;` +`cd ..` +1. Copy *qt.conf* to *qt5-install\bin* +#### Uploading +`tar -zcvf qt5-install.tar.gz qt5-install` +Upload qt5-install.tar.gz to https://hifi-qa.s3.amazonaws.com/qt5/Mac/ ## Problems *configure* errors, if any, may be viewed in **config.log** and **config.summary** diff --git a/tools/qt-builder/qt5vars.bat b/tools/qt-builder/qt5vars.bat index 10ad5be4ae..22a976827b 100644 --- a/tools/qt-builder/qt5vars.bat +++ b/tools/qt-builder/qt5vars.bat @@ -1,6 +1,6 @@ @echo off -REM Set up \Microsoft Visual Studio 2015, where is \c amd64, \c x86, etc. +REM Set up \Microsoft Visual Studio 2017, where is \c amd64, \c x86, etc. CALL "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x64 REM Edit this location to point to the source code of Qt