Merge remote-tracking branch 'origin/master'

This commit is contained in:
SamGondelman 2019-06-18 11:48:38 -07:00
commit c129f84e73
55 changed files with 552 additions and 223 deletions

View file

@ -106,3 +106,4 @@ The following build options can be used when running CMake
#### Devices #### Devices
You can support external input/output devices such as Leap Motion, MIDI, and more by adding each individual SDK in the visible building path. Refer to the readme file available in each device folder in [interface/external/](interface/external) for the detailed explanation of the requirements to use the device. You can support external input/output devices such as Leap Motion, MIDI, and more by adding each individual SDK in the visible building path. Refer to the readme file available in each device folder in [interface/external/](interface/external) for the detailed explanation of the requirements to use the device.

View file

@ -33,7 +33,7 @@ If you do not wish to use the Python installation bundled with Visual Studio, yo
Download and install the latest version of CMake 3.9. Download and install the latest version of CMake 3.9.
Download the file named win64-x64 Installer from the [CMake Website](https://cmake.org/download/). You can access the installer on this [3.9 Version page](https://cmake.org/files/v3.9/). During installation, make sure to check "Add CMake to system PATH for all users" when prompted. Download the file named win64-x64 Installer from the [CMake Website](https://cmake.org/download/). You can access the installer on this [3.14 Version page](https://cmake.org/files/v3.14/). During installation, make sure to check "Add CMake to system PATH for all users" when prompted.
### Step 3. Create VCPKG environment variable ### Step 3. Create VCPKG environment variable
In the next step, you will use CMake to build High Fidelity. By default, the CMake process builds dependency files in Windows' `%TEMP%` directory, which is periodically cleared by the operating system. To prevent you from having to re-build the dependencies in the event that Windows clears that directory, we recommend that you create a `HIFI_VCPKG_BASE` environment variable linked to a directory somewhere on your machine. That directory will contain all dependency files until you manually remove them. In the next step, you will use CMake to build High Fidelity. By default, the CMake process builds dependency files in Windows' `%TEMP%` directory, which is periodically cleared by the operating system. To prevent you from having to re-build the dependencies in the event that Windows clears that directory, we recommend that you create a `HIFI_VCPKG_BASE` environment variable linked to a directory somewhere on your machine. That directory will contain all dependency files until you manually remove them.

View file

@ -1735,7 +1735,12 @@ void DomainServer::nodePingMonitor() {
nodeList->eachNode([now](const SharedNodePointer& node) { nodeList->eachNode([now](const SharedNodePointer& node) {
quint64 lastHeard = now - node->getLastHeardMicrostamp(); quint64 lastHeard = now - node->getLastHeardMicrostamp();
if (lastHeard > 2 * USECS_PER_SECOND) { if (lastHeard > 2 * USECS_PER_SECOND) {
qCDebug(domain_server) << "Haven't heard from " << node->getPublicSocket() << " in " << lastHeard / USECS_PER_MSEC << " msec"; QString username;
DomainServerNodeData* nodeData = static_cast<DomainServerNodeData*>(node->getLinkedData());
if (nodeData) {
username = nodeData->getUsername();
}
qCDebug(domain_server) << "Haven't heard from " << node->getPublicSocket() << username << " in " << lastHeard / USECS_PER_MSEC << " msec";
} }
}); });
} }

View file

@ -58,6 +58,7 @@ Windows.Window {
} }
QmlSurface.load(source, contentHolder, function(newObject) { QmlSurface.load(source, contentHolder, function(newObject) {
dynamicContent = newObject; dynamicContent = newObject;
updateInteractiveWindowSizeForMode();
if (dynamicContent && dynamicContent.anchors) { if (dynamicContent && dynamicContent.anchors) {
dynamicContent.anchors.fill = contentHolder; dynamicContent.anchors.fill = contentHolder;
} }
@ -81,10 +82,12 @@ Windows.Window {
} }
function updateInteractiveWindowSizeForMode() { function updateInteractiveWindowSizeForMode() {
if (presentationMode === Desktop.PresentationMode.VIRTUAL) { root.width = interactiveWindowSize.width;
width = interactiveWindowSize.width; root.height = interactiveWindowSize.height;
height = interactiveWindowSize.height; contentHolder.width = interactiveWindowSize.width;
} else if (presentationMode === Desktop.PresentationMode.NATIVE && nativeWindow) { contentHolder.height = interactiveWindowSize.height;
if (presentationMode === Desktop.PresentationMode.NATIVE && nativeWindow) {
nativeWindow.width = interactiveWindowSize.width; nativeWindow.width = interactiveWindowSize.width;
nativeWindow.height = interactiveWindowSize.height; nativeWindow.height = interactiveWindowSize.height;
} }
@ -134,6 +137,9 @@ Windows.Window {
Window { Window {
id: root; id: root;
width: interactiveWindowSize.width
height: interactiveWindowSize.height
Rectangle { Rectangle {
color: hifi.colors.baseGray color: hifi.colors.baseGray
anchors.fill: parent anchors.fill: parent

View file

@ -13,15 +13,14 @@ import QtQuick 2.4
import controlsUit 1.0 as HifiControlsUit import controlsUit 1.0 as HifiControlsUit
import stylesUit 1.0 as HifiStylesUit import stylesUit 1.0 as HifiStylesUit
import "LoginDialog"
FocusScope { FocusScope {
id: root id: root
HifiStylesUit.HifiConstants { id: hifi }
objectName: "LoginDialog" objectName: "LoginDialog"
property bool shown: true property bool shown: true
visible: shown visible: shown
HifiStylesUit.HifiConstants { id: hifi }
anchors.fill: parent anchors.fill: parent
readonly property bool isTablet: false readonly property bool isTablet: false
@ -33,12 +32,17 @@ FocusScope {
property bool keyboardRaised: false property bool keyboardRaised: false
property bool punctuationMode: false property bool punctuationMode: false
property bool isPassword: false property bool isPassword: false
property string title: ""
property string text: ""
property int titleWidth: 0
property alias bannerWidth: banner.width property alias bannerWidth: banner.width
property alias bannerHeight: banner.height property alias bannerHeight: banner.height
property string title: ""
property string text: ""
property int titleWidth: 0
property bool isHMD: HMD.active
function tryDestroy() { function tryDestroy() {
root.destroy() root.destroy()
} }

View file

@ -23,43 +23,36 @@ FocusScope {
objectName: "LoginDialog" objectName: "LoginDialog"
visible: true visible: true
HifiStylesUit.HifiConstants { id: hifi }
anchors.fill: parent anchors.fill: parent
width: parent.width
height: parent.height
property var tabletProxy: Tablet.getTablet("com.highfidelity.interface.tablet.system"); readonly property bool isTablet: true
readonly property bool isOverlay: false
property bool isHMD: HMD.active
property bool gotoPreviousApp: false;
property string iconText: hifi.glyphs.avatar
property int iconSize: 35
property bool keyboardEnabled: false property bool keyboardEnabled: false
property bool keyboardRaised: false property bool keyboardRaised: false
property bool punctuationMode: false property bool punctuationMode: false
property bool isPassword: false property bool isPassword: false
readonly property bool isTablet: true
readonly property bool isOverlay: false
property alias text: loginKeyboard.mirroredText
property int titleWidth: 0
property alias bannerWidth: banner.width property alias bannerWidth: banner.width
property alias bannerHeight: banner.height property alias bannerHeight: banner.height
property string iconText: hifi.glyphs.avatar
property int iconSize: 35
property var pane: QtObject { property int titleWidth: 0
property real width: root.width
property real height: root.height
}
function tryDestroy() { property bool isHMD: HMD.active
tabletProxy.gotoHomeScreen();
}
MouseArea { // TABLET SPECIFIC PROPERTIES START //
width: root.width property alias text: loginKeyboard.mirroredText
height: root.height
} width: parent.width
height: parent.height
property var tabletProxy: Tablet.getTablet("com.highfidelity.interface.tablet.system")
property bool gotoPreviousApp: false
property bool keyboardOverride: true property bool keyboardOverride: true
@ -70,7 +63,20 @@ FocusScope {
property alias loginDialog: loginDialog property alias loginDialog: loginDialog
property alias hifi: hifi property alias hifi: hifi
HifiStylesUit.HifiConstants { id: hifi } property var pane: QtObject {
property real width: root.width
property real height: root.height
}
MouseArea {
width: root.width
height: root.height
}
// TABLET SPECIFIC PROPERTIES END //
function tryDestroy() {
tabletProxy.gotoHomeScreen();
}
Timer { Timer {
id: keyboardTimer id: keyboardTimer
@ -102,6 +108,15 @@ FocusScope {
anchors.fill: parent anchors.fill: parent
} }
Rectangle {
z: -6
id: opaqueRect
height: parent.height
width: parent.width
opacity: 0.65
color: "black"
}
Item { Item {
z: -5 z: -5
id: bannerContainer id: bannerContainer
@ -119,15 +134,6 @@ FocusScope {
} }
} }
Rectangle {
z: -6
id: opaqueRect
height: parent.height
width: parent.width
opacity: 0.65
color: "black"
}
HifiControlsUit.Keyboard { HifiControlsUit.Keyboard {
id: loginKeyboard id: loginKeyboard
raised: root.keyboardEnabled && root.keyboardRaised raised: root.keyboardEnabled && root.keyboardRaised

View file

@ -75,21 +75,31 @@ ListModel {
// 1: equivalent to paging when reaching end (and not before). // 1: equivalent to paging when reaching end (and not before).
// 0: don't getNextPage on scroll at all here. The application code will do it. // 0: don't getNextPage on scroll at all here. The application code will do it.
property real pageAhead: 2.0; property real pageAhead: 2.0;
function needsEarlyYFetch() { function onContentXChanged() {
return flickable if (flickable &&
&& !flickable.atYBeginning !flickable.atXBeginning &&
&& (flickable.contentY - flickable.originY) >= (flickable.contentHeight - (pageAhead * flickable.height)); (flickable.contentX - flickable.originX) >= (flickable.contentWidth - (pageAhead * flickable.width))) {
getNextPage();
}
} }
function needsEarlyXFetch() { function onContentYChanged() {
return flickable if (flickable &&
&& !flickable.atXBeginning !flickable.atYBeginning &&
&& (flickable.contentX - flickable.originX) >= (flickable.contentWidth - (pageAhead * flickable.width)); (flickable.contentY - flickable.originY) >= (flickable.contentHeight - (pageAhead * flickable.height))) {
getNextPage();
}
} }
function getNextPageIfHorizontalScroll() { function onWidthChanged() {
if (needsEarlyXFetch()) { getNextPage(); } if (flickable &&
(flickable.contentX - flickable.originX) >= (flickable.contentWidth - (pageAhead * flickable.width))) {
getNextPage();
}
} }
function getNextPageIfVerticalScroll() { function onHeightChanged() {
if (needsEarlyYFetch()) { getNextPage(); } if (flickable &&
(flickable.contentY - flickable.originY) >= (flickable.contentHeight - (pageAhead * flickable.height))) {
getNextPage();
}
} }
function needsMoreHorizontalResults() { function needsMoreHorizontalResults() {
return flickable return flickable
@ -118,8 +128,10 @@ ListModel {
initialized = true; initialized = true;
if (flickable && pageAhead > 0.0) { if (flickable && pageAhead > 0.0) {
// Pun: Scrollers are usually one direction or another, such that only one of the following will actually fire. // Pun: Scrollers are usually one direction or another, such that only one of the following will actually fire.
flickable.contentXChanged.connect(getNextPageIfHorizontalScroll); flickable.contentXChanged.connect(onContentXChanged);
flickable.contentYChanged.connect(getNextPageIfVerticalScroll); flickable.contentYChanged.connect(onContentYChanged);
flickable.widthChanged.connect(onWidthChanged);
flickable.heightChanged.connect(onHeightChanged);
flickable.contentWidthChanged.connect(getNextPageIfNotEnoughHorizontalResults); flickable.contentWidthChanged.connect(getNextPageIfNotEnoughHorizontalResults);
flickable.contentHeightChanged.connect(getNextPageIfNotEnoughVerticalResults); flickable.contentHeightChanged.connect(getNextPageIfNotEnoughVerticalResults);
} }

View file

@ -0,0 +1,3 @@
module hifiModels
PSFListModel 1.0 PSFListModel.qml
S3Model 1.0 S3Model.qml

View file

@ -10,6 +10,7 @@
import QtQuick 2.10 import QtQuick 2.10
import "../simplifiedConstants" as SimplifiedConstants import "../simplifiedConstants" as SimplifiedConstants
import "../simplifiedControls" as SimplifiedControls
import "./components" as AvatarAppComponents import "./components" as AvatarAppComponents
import stylesUit 1.0 as HifiStylesUit import stylesUit 1.0 as HifiStylesUit
import TabletScriptingInterface 1.0 import TabletScriptingInterface 1.0
@ -245,6 +246,10 @@ Rectangle {
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
} }
SimplifiedControls.VerticalScrollBar {
parent: inventoryContentsList
}
} }

View file

@ -9,7 +9,9 @@
// //
import QtQuick 2.10 import QtQuick 2.10
import QtQuick.Controls 2.3
import "../simplifiedConstants" as SimplifiedConstants import "../simplifiedConstants" as SimplifiedConstants
import "../simplifiedControls" as SimplifiedControls
import stylesUit 1.0 as HifiStylesUit import stylesUit 1.0 as HifiStylesUit
import "./audio" as AudioSettings import "./audio" as AudioSettings
import "./general" as GeneralSettings import "./general" as GeneralSettings
@ -129,9 +131,7 @@ Rectangle {
id: tabViewContainers id: tabViewContainers
anchors.top: tabContainer.bottom anchors.top: tabContainer.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: 26
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 26
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
@ -162,24 +162,20 @@ Rectangle {
visible: activeTabView === "devTabView" visible: activeTabView === "devTabView"
anchors.fill: parent anchors.fill: parent
} }
}
Image { SimplifiedControls.VerticalScrollBar {
source: { parent: {
if (root.activeTabView === "generalTabView") { if (activeTabView === "generalTabView") {
"images/accent1.svg" generalTabViewContainer
} else if (root.activeTabView === "audioTabView") { } else if (activeTabView === "audioTabView") {
"images/accent2.svg" audioTabViewContainer
} else if (root.activeTabView === "vrTabView") { } else if (activeTabView === "vrTabView") {
"images/accent3.svg" vrTabViewContainer
} else { } else if (activeTabView === "devTabView") {
"images/accent3.svg" devTabViewContainer
}
} }
} }
anchors.right: parent.right
anchors.top: tabContainer.bottom
width: 106
height: 200
} }

View file

@ -19,8 +19,6 @@ Flickable {
id: root id: root
contentWidth: parent.width contentWidth: parent.width
contentHeight: audioColumnLayout.height contentHeight: audioColumnLayout.height
topMargin: 24
bottomMargin: 24
clip: true clip: true
function changePeakValuesEnabled(enabled) { function changePeakValuesEnabled(enabled) {
@ -33,7 +31,7 @@ Flickable {
AudioScriptingInterface.devices.input.peakValuesEnabled = visible; AudioScriptingInterface.devices.input.peakValuesEnabled = visible;
if (visible) { if (visible) {
root.contentX = 0; root.contentX = 0;
root.contentY = -root.topMargin; root.contentY = 0;
AudioScriptingInterface.devices.input.peakValuesEnabledChanged.connect(changePeakValuesEnabled); AudioScriptingInterface.devices.input.peakValuesEnabledChanged.connect(changePeakValuesEnabled);
} else { } else {
AudioScriptingInterface.devices.input.peakValuesEnabledChanged.disconnect(changePeakValuesEnabled); AudioScriptingInterface.devices.input.peakValuesEnabledChanged.disconnect(changePeakValuesEnabled);
@ -45,16 +43,35 @@ Flickable {
id: simplifiedUI id: simplifiedUI
} }
Image {
id: accent
source: "../images/accent2.svg"
anchors.left: parent.left
anchors.top: parent.top
width: 83
height: 156
transform: Scale {
xScale: -1
origin.x: accent.width / 2
origin.y: accent.height / 2
}
}
ColumnLayout { ColumnLayout {
id: audioColumnLayout id: audioColumnLayout
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: 26
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 26
anchors.top: parent.top anchors.top: parent.top
spacing: simplifiedUI.margins.settings.spacingBetweenSettings spacing: simplifiedUI.margins.settings.spacingBetweenSettings
ColumnLayout { ColumnLayout {
id: volumeControlsContainer id: volumeControlsContainer
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
Layout.topMargin: 24
spacing: 0 spacing: 0
HifiStylesUit.GraphikSemiBold { HifiStylesUit.GraphikSemiBold {
@ -289,6 +306,7 @@ Flickable {
ColumnLayout { ColumnLayout {
id: outputDeviceContainer id: outputDeviceContainer
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
Layout.bottomMargin: 24
spacing: 0 spacing: 0
HifiStylesUit.GraphikSemiBold { HifiStylesUit.GraphikSemiBold {

View file

@ -19,14 +19,12 @@ Flickable {
id: root id: root
contentWidth: parent.width contentWidth: parent.width
contentHeight: devColumnLayout.height contentHeight: devColumnLayout.height
topMargin: 24
bottomMargin: 24
clip: true clip: true
onVisibleChanged: { onVisibleChanged: {
if (visible) { if (visible) {
root.contentX = 0; root.contentX = 0;
root.contentY = -root.topMargin; root.contentY = 0;
} }
} }
@ -35,16 +33,36 @@ Flickable {
id: simplifiedUI id: simplifiedUI
} }
Image {
id: accent
source: "../images/accent3.svg"
anchors.left: parent.left
anchors.top: parent.top
width: 83
height: 156
transform: Scale {
xScale: -1
origin.x: accent.width / 2
origin.y: accent.height / 2
}
}
ColumnLayout { ColumnLayout {
id: devColumnLayout id: devColumnLayout
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: 26
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 26
anchors.top: parent.top anchors.top: parent.top
spacing: simplifiedUI.margins.settings.spacingBetweenSettings spacing: simplifiedUI.margins.settings.spacingBetweenSettings
ColumnLayout { ColumnLayout {
id: uiControlsContainer id: uiControlsContainer
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
Layout.topMargin: 24
Layout.bottomMargin: 24
spacing: 0 spacing: 0
HifiStylesUit.GraphikSemiBold { HifiStylesUit.GraphikSemiBold {

View file

@ -9,6 +9,7 @@
// //
import QtQuick 2.10 import QtQuick 2.10
import QtQuick.Controls 2.3
import "../../simplifiedConstants" as SimplifiedConstants import "../../simplifiedConstants" as SimplifiedConstants
import "../../simplifiedControls" as SimplifiedControls import "../../simplifiedControls" as SimplifiedControls
import stylesUit 1.0 as HifiStylesUit import stylesUit 1.0 as HifiStylesUit
@ -20,8 +21,6 @@ Flickable {
id: root id: root
contentWidth: parent.width contentWidth: parent.width
contentHeight: generalColumnLayout.height contentHeight: generalColumnLayout.height
topMargin: 24
bottomMargin: 24
clip: true clip: true
onAvatarNametagModeChanged: { onAvatarNametagModeChanged: {
@ -31,7 +30,7 @@ Flickable {
onVisibleChanged: { onVisibleChanged: {
if (visible) { if (visible) {
root.contentX = 0; root.contentX = 0;
root.contentY = -root.topMargin; root.contentY = 0;
} }
} }
@ -39,16 +38,35 @@ Flickable {
id: simplifiedUI id: simplifiedUI
} }
Image {
id: accent
source: "../images/accent1.svg"
anchors.left: parent.left
anchors.top: parent.top
width: 83
height: 156
transform: Scale {
xScale: -1
origin.x: accent.width / 2
origin.y: accent.height / 2
}
}
ColumnLayout { ColumnLayout {
id: generalColumnLayout id: generalColumnLayout
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: 26
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 26
anchors.top: parent.top anchors.top: parent.top
spacing: simplifiedUI.margins.settings.spacingBetweenSettings spacing: simplifiedUI.margins.settings.spacingBetweenSettings
ColumnLayout { ColumnLayout {
id: avatarNameTagsContainer id: avatarNameTagsContainer
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
Layout.topMargin: 24
spacing: 0 spacing: 0
HifiStylesUit.GraphikSemiBold { HifiStylesUit.GraphikSemiBold {
@ -193,29 +211,36 @@ Flickable {
} }
} }
HifiStylesUit.GraphikRegular { ColumnLayout {
id: logoutText id: logoutContainer
text: (AccountServices.username === "Unknown user" ? "Log In" : "Logout " + AccountServices.username) Layout.preferredWidth: parent.width
wrapMode: Text.Wrap Layout.bottomMargin: 24
width: paintedWidth spacing: 0
height: paintedHeight
size: 14
color: simplifiedUI.colors.text.lightBlue
MouseArea { HifiStylesUit.GraphikRegular {
anchors.fill: parent id: logoutText
hoverEnabled: true text: (AccountServices.username === "Unknown user" ? "Log In" : "Logout " + AccountServices.username)
onEntered: { wrapMode: Text.Wrap
parent.color = simplifiedUI.colors.text.lightBlueHover; width: paintedWidth
} height: paintedHeight
onExited: { size: 14
parent.color = simplifiedUI.colors.text.lightBlue; color: simplifiedUI.colors.text.lightBlue
}
onClicked: { MouseArea {
if (Account.loggedIn) { anchors.fill: parent
AccountServices.logOut(); hoverEnabled: true
} else { onEntered: {
DialogsManager.showLoginDialog(); parent.color = simplifiedUI.colors.text.lightBlueHover;
}
onExited: {
parent.color = simplifiedUI.colors.text.lightBlue;
}
onClicked: {
if (Account.loggedIn) {
AccountServices.logOut();
} else {
DialogsManager.showLoginDialog();
}
} }
} }
} }

View file

@ -19,8 +19,6 @@ Flickable {
id: root id: root
contentWidth: parent.width contentWidth: parent.width
contentHeight: vrColumnLayout.height contentHeight: vrColumnLayout.height
topMargin: 24
bottomMargin: 24
clip: true clip: true
function changePeakValuesEnabled(enabled) { function changePeakValuesEnabled(enabled) {
@ -33,7 +31,7 @@ Flickable {
AudioScriptingInterface.devices.input.peakValuesEnabled = visible; AudioScriptingInterface.devices.input.peakValuesEnabled = visible;
if (visible) { if (visible) {
root.contentX = 0; root.contentX = 0;
root.contentY = -root.topMargin; root.contentY = 0;
AudioScriptingInterface.devices.input.peakValuesEnabledChanged.connect(changePeakValuesEnabled); AudioScriptingInterface.devices.input.peakValuesEnabledChanged.connect(changePeakValuesEnabled);
} else { } else {
AudioScriptingInterface.devices.input.peakValuesEnabledChanged.disconnect(changePeakValuesEnabled); AudioScriptingInterface.devices.input.peakValuesEnabledChanged.disconnect(changePeakValuesEnabled);
@ -45,16 +43,35 @@ Flickable {
id: simplifiedUI id: simplifiedUI
} }
Image {
id: accent
source: "../images/accent3.svg"
anchors.left: parent.left
anchors.top: parent.top
width: 83
height: 156
transform: Scale {
xScale: -1
origin.x: accent.width / 2
origin.y: accent.height / 2
}
}
ColumnLayout { ColumnLayout {
id: vrColumnLayout id: vrColumnLayout
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: 26
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 26
anchors.top: parent.top anchors.top: parent.top
spacing: simplifiedUI.margins.settings.spacingBetweenSettings spacing: simplifiedUI.margins.settings.spacingBetweenSettings
ColumnLayout { ColumnLayout {
id: controlsContainer id: controlsContainer
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
Layout.topMargin: 24
spacing: 0 spacing: 0
HifiStylesUit.GraphikSemiBold { HifiStylesUit.GraphikSemiBold {
@ -278,6 +295,7 @@ Flickable {
ColumnLayout { ColumnLayout {
id: outputDeviceContainer id: outputDeviceContainer
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
Layout.bottomMargin: 24
spacing: 0 spacing: 0
HifiStylesUit.GraphikSemiBold { HifiStylesUit.GraphikSemiBold {

View file

@ -144,6 +144,10 @@ QtObject {
readonly property color hover: "#FFFFFF" readonly property color hover: "#FFFFFF"
readonly property color focus: "#FFFFFF" readonly property color focus: "#FFFFFF"
} }
readonly property QtObject scrollBar: QtObject {
readonly property color background: "#474747"
readonly property color contentItem: "#0198CB"
}
} }
readonly property color darkSeparator: "#595959" readonly property color darkSeparator: "#595959"
@ -219,6 +223,10 @@ QtObject {
readonly property QtObject textField: QtObject { readonly property QtObject textField: QtObject {
readonly property int editPencilPadding: 6 readonly property int editPencilPadding: 6
} }
readonly property QtObject scrollBar: QtObject {
readonly property int backgroundWidth: 9
readonly property int contentItemWidth: 7
}
} }
} }

View file

@ -0,0 +1,51 @@
//
// VerticalScrollBar.qml
//
// Created by Zach Fox on 2019-06-17
// 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
//
import QtQuick 2.10
import QtQuick.Controls 2.3
import "../simplifiedConstants" as SimplifiedConstants
ScrollBar {
SimplifiedConstants.SimplifiedConstants {
id: simplifiedUI
}
orientation: Qt.Vertical
policy: ScrollBar.AlwaysOn
anchors.top: parent.top
anchors.topMargin: 4
anchors.right: parent.right
anchors.rightMargin: 4
anchors.bottom: parent.bottom
anchors.bottomMargin: 4
width: simplifiedUI.sizes.controls.scrollBar.backgroundWidth
visible: parent.contentHeight > parent.parent.height
position: parent.contentY / parent.contentHeight
size: parent.parent.height / parent.contentHeight
minimumSize: 0.1
background: Rectangle {
color: simplifiedUI.colors.controls.scrollBar.background
anchors.fill: parent
}
contentItem: Rectangle {
width: simplifiedUI.sizes.controls.scrollBar.contentItemWidth
color: simplifiedUI.colors.controls.scrollBar.contentItem
anchors {
horizontalCenter: parent.horizontalCenter
topMargin: 1
bottomMargin: 1
}
}
onPositionChanged: {
if (pressed) {
parent.contentY = position * parent.contentHeight;
}
}
}

View file

@ -48,7 +48,8 @@ Rectangle {
onSkeletonModelURLChanged: { onSkeletonModelURLChanged: {
root.updatePreviewUrl(); root.updatePreviewUrl();
if (MyAvatar.skeletonModelURL.indexOf("defaultAvatar" > -1) && topBarInventoryModel.count > 0) { if ((MyAvatar.skeletonModelURL.indexOf("defaultAvatar") > -1 || MyAvatar.skeletonModelURL.indexOf("fst") === -1) &&
topBarInventoryModel.count > 0) {
Settings.setValue("simplifiedUI/alreadyAutoSelectedAvatar", true); Settings.setValue("simplifiedUI/alreadyAutoSelectedAvatar", true);
MyAvatar.skeletonModelURL = topBarInventoryModel.get(0).download_url; MyAvatar.skeletonModelURL = topBarInventoryModel.get(0).download_url;
} }
@ -100,7 +101,8 @@ Rectangle {
inventoryFullyReceived = true; inventoryFullyReceived = true;
// If we have an avatar in our inventory AND we haven't already auto-selected an avatar... // If we have an avatar in our inventory AND we haven't already auto-selected an avatar...
if (!Settings.getValue("simplifiedUI/alreadyAutoSelectedAvatar", false) && topBarInventoryModel.count > 0) { if ((!Settings.getValue("simplifiedUI/alreadyAutoSelectedAvatar", false) ||
MyAvatar.skeletonModelURL.indexOf("defaultAvatar") > -1 || MyAvatar.skeletonModelURL.indexOf("fst") === -1) && topBarInventoryModel.count > 0) {
Settings.setValue("simplifiedUI/alreadyAutoSelectedAvatar", true); Settings.setValue("simplifiedUI/alreadyAutoSelectedAvatar", true);
MyAvatar.skeletonModelURL = topBarInventoryModel.get(0).download_url; MyAvatar.skeletonModelURL = topBarInventoryModel.get(0).download_url;
} }

View file

@ -2708,6 +2708,7 @@ void Application::cleanupBeforeQuit() {
} }
getEntities()->shutdown(); // tell the entities system we're shutting down, so it will stop running scripts getEntities()->shutdown(); // tell the entities system we're shutting down, so it will stop running scripts
getEntities()->clear();
// Clear any queued processing (I/O, FBX/OBJ/Texture parsing) // Clear any queued processing (I/O, FBX/OBJ/Texture parsing)
QThreadPool::globalInstance()->clear(); QThreadPool::globalInstance()->clear();

View file

@ -63,9 +63,15 @@ PerformanceManager::PerformancePreset PerformanceManager::getPerformancePreset()
void PerformanceManager::applyPerformancePreset(PerformanceManager::PerformancePreset preset) { void PerformanceManager::applyPerformancePreset(PerformanceManager::PerformancePreset preset) {
// Ugly case that prevent us to run deferred everywhere...
bool isDeferredCapable = platform::Profiler::isRenderMethodDeferredCapable();
switch (preset) { switch (preset) {
case PerformancePreset::HIGH: case PerformancePreset::HIGH:
RenderScriptingInterface::getInstance()->setRenderMethod(RenderScriptingInterface::RenderMethod::DEFERRED); RenderScriptingInterface::getInstance()->setRenderMethod( ( isDeferredCapable ?
RenderScriptingInterface::RenderMethod::DEFERRED :
RenderScriptingInterface::RenderMethod::FORWARD ) );
RenderScriptingInterface::getInstance()->setShadowsEnabled(true); RenderScriptingInterface::getInstance()->setShadowsEnabled(true);
qApp->getRefreshRateManager().setRefreshRateProfile(RefreshRateManager::RefreshRateProfile::REALTIME); qApp->getRefreshRateManager().setRefreshRateProfile(RefreshRateManager::RefreshRateProfile::REALTIME);
@ -73,7 +79,10 @@ void PerformanceManager::applyPerformancePreset(PerformanceManager::PerformanceP
break; break;
case PerformancePreset::MID: case PerformancePreset::MID:
RenderScriptingInterface::getInstance()->setRenderMethod(RenderScriptingInterface::RenderMethod::DEFERRED); RenderScriptingInterface::getInstance()->setRenderMethod((isDeferredCapable ?
RenderScriptingInterface::RenderMethod::DEFERRED :
RenderScriptingInterface::RenderMethod::FORWARD));
RenderScriptingInterface::getInstance()->setShadowsEnabled(false); RenderScriptingInterface::getInstance()->setShadowsEnabled(false);
qApp->getRefreshRateManager().setRefreshRateProfile(RefreshRateManager::RefreshRateProfile::INTERACTIVE); qApp->getRefreshRateManager().setRefreshRateProfile(RefreshRateManager::RefreshRateProfile::INTERACTIVE);
DependencyManager::get<LODManager>()->setWorldDetailQuality(0.5f); DependencyManager::get<LODManager>()->setWorldDetailQuality(0.5f);

View file

@ -435,7 +435,7 @@ DetailedMotionState* AvatarManager::createDetailedMotionState(OtherAvatarPointer
return nullptr; return nullptr;
} }
void AvatarManager::rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction, OtherAvatarPointer avatar) { void AvatarManager::rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar) {
if (!avatar->_motionState) { if (!avatar->_motionState) {
avatar->_motionState = new AvatarMotionState(avatar, nullptr); avatar->_motionState = new AvatarMotionState(avatar, nullptr);
} }
@ -452,20 +452,24 @@ void AvatarManager::rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction
transaction.objectsToAdd.push_back(motionState); transaction.objectsToAdd.push_back(motionState);
} }
motionState->clearIncomingDirtyFlags(); motionState->clearIncomingDirtyFlags();
}
// Rather than reconcile numbers of joints after change to model or LOD void AvatarManager::removeDetailedAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar) {
// we blow away old detailedMotionStates and create anew all around.
// delete old detailedMotionStates // delete old detailedMotionStates
auto& detailedMotionStates = avatar->getDetailedMotionStates(); auto& detailedMotionStates = avatar->getDetailedMotionStates();
if (detailedMotionStates.size() != 0) { if (detailedMotionStates.size() != 0) {
for (auto& detailedMotionState : detailedMotionStates) { for (auto& detailedMotionState : detailedMotionStates) {
transaction.objectsToRemove.push_back(detailedMotionState); transaction.objectsToRemove.push_back(detailedMotionState);
} }
avatar->resetDetailedMotionStates(); avatar->forgetDetailedMotionStates();
} }
}
// build new detailedMotionStates void AvatarManager::rebuildDetailedAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar) {
// Rather than reconcile numbers of joints after change to model or LOD
// we blow away old detailedMotionStates and create anew all around.
removeDetailedAvatarPhysics(transaction, avatar);
auto& detailedMotionStates = avatar->getDetailedMotionStates();
OtherAvatar::BodyLOD lod = avatar->getBodyLOD(); OtherAvatar::BodyLOD lod = avatar->getBodyLOD();
if (lod == OtherAvatar::BodyLOD::Sphere) { if (lod == OtherAvatar::BodyLOD::Sphere) {
auto dMotionState = createDetailedMotionState(avatar, -1); auto dMotionState = createDetailedMotionState(avatar, -1);
@ -483,24 +487,21 @@ void AvatarManager::rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction
} }
} }
} }
avatar->_needsReinsertion = false; avatar->_needsDetailedRebuild = false;
} }
void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transaction) { void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transaction) {
_myAvatar->getCharacterController()->buildPhysicsTransaction(transaction); _myAvatar->getCharacterController()->buildPhysicsTransaction(transaction);
for (auto avatar : _otherAvatarsToChangeInPhysics) { for (auto avatar : _otherAvatarsToChangeInPhysics) {
bool isInPhysics = avatar->isInPhysicsSimulation(); bool isInPhysics = avatar->isInPhysicsSimulation();
if (isInPhysics != avatar->shouldBeInPhysicsSimulation() || avatar->_needsReinsertion) { if (isInPhysics != avatar->shouldBeInPhysicsSimulation()) {
if (isInPhysics) { if (isInPhysics) {
transaction.objectsToRemove.push_back(avatar->_motionState); transaction.objectsToRemove.push_back(avatar->_motionState);
avatar->_motionState = nullptr; avatar->_motionState = nullptr;
auto& detailedMotionStates = avatar->getDetailedMotionStates(); removeDetailedAvatarPhysics(transaction, avatar);
for (auto& motionState : detailedMotionStates) {
transaction.objectsToRemove.push_back(motionState);
}
avatar->resetDetailedMotionStates();
} else { } else {
rebuildAvatarPhysics(transaction, avatar); rebuildAvatarPhysics(transaction, avatar);
rebuildDetailedAvatarPhysics(transaction, avatar);
} }
} else if (isInPhysics) { } else if (isInPhysics) {
AvatarMotionState* motionState = avatar->_motionState; AvatarMotionState* motionState = avatar->_motionState;
@ -519,6 +520,10 @@ void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transact
} }
motionState->clearIncomingDirtyFlags(); motionState->clearIncomingDirtyFlags();
} }
if (avatar->_needsDetailedRebuild) {
rebuildDetailedAvatarPhysics(transaction, avatar);
}
} }
} }
_otherAvatarsToChangeInPhysics.clear(); _otherAvatarsToChangeInPhysics.clear();

View file

@ -274,7 +274,9 @@ public slots:
protected: protected:
AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) override; AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) override;
DetailedMotionState* createDetailedMotionState(OtherAvatarPointer avatar, int32_t jointIndex); DetailedMotionState* createDetailedMotionState(OtherAvatarPointer avatar, int32_t jointIndex);
void rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction, OtherAvatarPointer avatar); void rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar);
void removeDetailedAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar);
void rebuildDetailedAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar);
private: private:
explicit AvatarManager(QObject* parent = 0); explicit AvatarManager(QObject* parent = 0);

View file

@ -1416,6 +1416,10 @@ void MyAvatar::setEnableDebugDrawAnimPose(bool isEnabled) {
} }
} }
void MyAvatar::setDebugDrawAnimPoseName(QString poseName) {
_debugDrawAnimPoseName.set(poseName);
}
void MyAvatar::setEnableDebugDrawPosition(bool isEnabled) { void MyAvatar::setEnableDebugDrawPosition(bool isEnabled) {
if (isEnabled) { if (isEnabled) {
const glm::vec4 red(1.0f, 0.0f, 0.0f, 1.0f); const glm::vec4 red(1.0f, 0.0f, 0.0f, 1.0f);
@ -3086,15 +3090,26 @@ void MyAvatar::postUpdate(float deltaTime, const render::ScenePointer& scene) {
} }
if (_enableDebugDrawAnimPose && animSkeleton) { if (_enableDebugDrawAnimPose && animSkeleton) {
// build absolute AnimPoseVec from rig
AnimPoseVec absPoses; AnimPoseVec absPoses;
const Rig& rig = _skeletonModel->getRig(); const Rig& rig = _skeletonModel->getRig();
absPoses.reserve(rig.getJointStateCount()); const glm::vec4 CYAN(0.1f, 0.6f, 0.6f, 1.0f);
for (int i = 0; i < rig.getJointStateCount(); i++) {
absPoses.push_back(AnimPose(rig.getJointTransform(i))); QString name = _debugDrawAnimPoseName.get();
if (name.isEmpty()) {
// build absolute AnimPoseVec from rig transforms. i.e. the same that are used for rendering.
absPoses.reserve(rig.getJointStateCount());
for (int i = 0; i < rig.getJointStateCount(); i++) {
absPoses.push_back(AnimPose(rig.getJointTransform(i)));
}
AnimDebugDraw::getInstance().addAbsolutePoses("myAvatarAnimPoses", animSkeleton, absPoses, xform, CYAN);
} else {
AnimNode::ConstPointer node = rig.findAnimNodeByName(name);
if (node) {
rig.buildAbsoluteRigPoses(node->getPoses(), absPoses);
AnimDebugDraw::getInstance().addAbsolutePoses("myAvatarAnimPoses", animSkeleton, absPoses, xform, CYAN);
}
} }
glm::vec4 cyan(0.1f, 0.6f, 0.6f, 1.0f);
AnimDebugDraw::getInstance().addAbsolutePoses("myAvatarAnimPoses", animSkeleton, absPoses, xform, cyan);
} }
} }

View file

@ -2018,12 +2018,20 @@ public slots:
void setEnableDebugDrawDefaultPose(bool isEnabled); void setEnableDebugDrawDefaultPose(bool isEnabled);
/**jsdoc /**jsdoc
* Displays animation debug graphics. * Displays animation debug graphics. By default it shows the animation poses used for rendering.
* However, the property MyAvatar.setDebugDrawAnimPoseName can be used to draw a specific animation node.
* @function MyAvatar.setEnableDebugDrawAnimPose * @function MyAvatar.setEnableDebugDrawAnimPose
* @param {boolean} enabled - <code>true</code> to show the debug graphics, <code>false</code> to hide. * @param {boolean} enabled - <code>true</code> to show the debug graphics, <code>false</code> to hide.
*/ */
void setEnableDebugDrawAnimPose(bool isEnabled); void setEnableDebugDrawAnimPose(bool isEnabled);
/**jsdoc
* If set it determines which animation debug graphics to draw, when MyAvatar.setEnableDebugDrawAnimPose is set to true.
* @function MyAvatar.setDebugDrawAnimPoseName
* @param {boolean} enabled - <code>true</code> to show the debug graphics, <code>false</code> to hide.
*/
void setDebugDrawAnimPoseName(QString poseName);
/**jsdoc /**jsdoc
* Displays position debug graphics. * Displays position debug graphics.
* @function MyAvatar.setEnableDebugDrawPosition * @function MyAvatar.setEnableDebugDrawPosition
@ -2666,6 +2674,8 @@ private:
bool _enableDebugDrawIKChains { false }; bool _enableDebugDrawIKChains { false };
bool _enableDebugDrawDetailedCollision { false }; bool _enableDebugDrawDetailedCollision { false };
ThreadSafeValueCache<QString> _debugDrawAnimPoseName;
mutable bool _cauterizationNeedsUpdate { false }; // do we need to scan children and update their "cauterized" state? mutable bool _cauterizationNeedsUpdate { false }; // do we need to scan children and update their "cauterized" state?
AudioListenerMode _audioListenerMode; AudioListenerMode _audioListenerMode;

View file

@ -398,15 +398,13 @@ DetailedMotionState* MyCharacterController::createDetailedMotionStateForJoint(in
} }
void MyCharacterController::clearDetailedMotionStates() { void MyCharacterController::clearDetailedMotionStates() {
// we don't actually clear the MotionStates here
// instead we twiddle some flags as a signal of what to do later
_pendingFlags |= PENDING_FLAG_REMOVE_DETAILED_FROM_SIMULATION; _pendingFlags |= PENDING_FLAG_REMOVE_DETAILED_FROM_SIMULATION;
// We make sure we don't add them again // We make sure we don't add them again
_pendingFlags &= ~PENDING_FLAG_ADD_DETAILED_TO_SIMULATION; _pendingFlags &= ~PENDING_FLAG_ADD_DETAILED_TO_SIMULATION;
} }
void MyCharacterController::resetDetailedMotionStates() {
_detailedMotionStates.clear();
}
void MyCharacterController::buildPhysicsTransaction(PhysicsEngine::Transaction& transaction) { void MyCharacterController::buildPhysicsTransaction(PhysicsEngine::Transaction& transaction) {
for (size_t i = 0; i < _detailedMotionStates.size(); i++) { for (size_t i = 0; i < _detailedMotionStates.size(); i++) {
_detailedMotionStates[i]->forceActive(); _detailedMotionStates[i]->forceActive();
@ -416,6 +414,8 @@ void MyCharacterController::buildPhysicsTransaction(PhysicsEngine::Transaction&
for (size_t i = 0; i < _detailedMotionStates.size(); i++) { for (size_t i = 0; i < _detailedMotionStates.size(); i++) {
transaction.objectsToRemove.push_back(_detailedMotionStates[i]); transaction.objectsToRemove.push_back(_detailedMotionStates[i]);
} }
// NOTE: the DetailedMotionStates are deleted after being added to PhysicsEngine::Transaction::_objectsToRemove
// See AvatarManager::handleProcessedPhysicsTransaction()
_detailedMotionStates.clear(); _detailedMotionStates.clear();
} }
if (_pendingFlags & PENDING_FLAG_ADD_DETAILED_TO_SIMULATION) { if (_pendingFlags & PENDING_FLAG_ADD_DETAILED_TO_SIMULATION) {

View file

@ -48,7 +48,6 @@ public:
DetailedMotionState* createDetailedMotionStateForJoint(int32_t jointIndex); DetailedMotionState* createDetailedMotionStateForJoint(int32_t jointIndex);
std::vector<DetailedMotionState*>& getDetailedMotionStates() { return _detailedMotionStates; } std::vector<DetailedMotionState*>& getDetailedMotionStates() { return _detailedMotionStates; }
void clearDetailedMotionStates(); void clearDetailedMotionStates();
void resetDetailedMotionStates();
void buildPhysicsTransaction(PhysicsEngine::Transaction& transaction); void buildPhysicsTransaction(PhysicsEngine::Transaction& transaction);

View file

@ -177,7 +177,7 @@ const btCollisionShape* OtherAvatar::createCollisionShape(int32_t jointIndex, bo
return ObjectMotionState::getShapeManager()->getShape(shapeInfo); return ObjectMotionState::getShapeManager()->getShape(shapeInfo);
} }
void OtherAvatar::resetDetailedMotionStates() { void OtherAvatar::forgetDetailedMotionStates() {
// NOTE: the DetailedMotionStates are deleted after being added to PhysicsEngine::Transaction::_objectsToRemove // NOTE: the DetailedMotionStates are deleted after being added to PhysicsEngine::Transaction::_objectsToRemove
// See AvatarManager::handleProcessedPhysicsTransaction() // See AvatarManager::handleProcessedPhysicsTransaction()
_detailedMotionStates.clear(); _detailedMotionStates.clear();
@ -209,7 +209,7 @@ void OtherAvatar::computeShapeLOD() {
if (newLOD != _bodyLOD) { if (newLOD != _bodyLOD) {
_bodyLOD = newLOD; _bodyLOD = newLOD;
if (isInPhysicsSimulation()) { if (isInPhysicsSimulation()) {
_needsReinsertion = true; _needsDetailedRebuild = true;
} }
} }
} }
@ -224,14 +224,14 @@ bool OtherAvatar::shouldBeInPhysicsSimulation() const {
bool OtherAvatar::needsPhysicsUpdate() const { bool OtherAvatar::needsPhysicsUpdate() const {
constexpr uint32_t FLAGS_OF_INTEREST = Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS | Simulation::DIRTY_POSITION | Simulation::DIRTY_COLLISION_GROUP; constexpr uint32_t FLAGS_OF_INTEREST = Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS | Simulation::DIRTY_POSITION | Simulation::DIRTY_COLLISION_GROUP;
return (_needsReinsertion || (_motionState && (bool)(_motionState->getIncomingDirtyFlags() & FLAGS_OF_INTEREST))); return (_needsDetailedRebuild || (_motionState && (bool)(_motionState->getIncomingDirtyFlags() & FLAGS_OF_INTEREST)));
} }
void OtherAvatar::rebuildCollisionShape() { void OtherAvatar::rebuildCollisionShape() {
if (_motionState) { if (_motionState) {
// do not actually rebuild here, instead flag for later // do not actually rebuild here, instead flag for later
_motionState->addDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); _motionState->addDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
_needsReinsertion = true; _needsDetailedRebuild = true;
} }
} }

View file

@ -54,7 +54,7 @@ public:
const btCollisionShape* createCollisionShape(int32_t jointIndex, bool& isBound, std::vector<int32_t>& boundJoints); const btCollisionShape* createCollisionShape(int32_t jointIndex, bool& isBound, std::vector<int32_t>& boundJoints);
std::vector<DetailedMotionState*>& getDetailedMotionStates() { return _detailedMotionStates; } std::vector<DetailedMotionState*>& getDetailedMotionStates() { return _detailedMotionStates; }
void resetDetailedMotionStates(); void forgetDetailedMotionStates();
BodyLOD getBodyLOD() { return _bodyLOD; } BodyLOD getBodyLOD() { return _bodyLOD; }
void computeShapeLOD(); void computeShapeLOD();
@ -90,7 +90,7 @@ protected:
int32_t _spaceIndex { -1 }; int32_t _spaceIndex { -1 };
uint8_t _workloadRegion { workload::Region::INVALID }; uint8_t _workloadRegion { workload::Region::INVALID };
BodyLOD _bodyLOD { BodyLOD::Sphere }; BodyLOD _bodyLOD { BodyLOD::Sphere };
bool _needsReinsertion { false }; bool _needsDetailedRebuild { false };
}; };
using OtherAvatarPointer = std::shared_ptr<OtherAvatar>; using OtherAvatarPointer = std::shared_ptr<OtherAvatar>;

View file

@ -262,7 +262,7 @@ class Stats : public QQuickItem {
STATS_PROPERTY(int, processing, 0) STATS_PROPERTY(int, processing, 0)
STATS_PROPERTY(int, processingPending, 0) STATS_PROPERTY(int, processingPending, 0)
STATS_PROPERTY(int, triangles, 0) STATS_PROPERTY(int, triangles, 0)
STATS_PROPERTY(uint32_t, drawcalls, 0) STATS_PROPERTY(quint32 , drawcalls, 0)
STATS_PROPERTY(int, materialSwitches, 0) STATS_PROPERTY(int, materialSwitches, 0)
STATS_PROPERTY(int, itemConsidered, 0) STATS_PROPERTY(int, itemConsidered, 0)
STATS_PROPERTY(int, itemOutOfView, 0) STATS_PROPERTY(int, itemOutOfView, 0)

View file

@ -64,7 +64,8 @@ function(set_from_env _RESULT_NAME _ENV_VAR_NAME _DEFAULT_VALUE)
endfunction() endfunction()
add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${src_files}) add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${src_files})
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME ${APP_NAME}) set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME ${APP_NAME}
MACOSX_BUNDLE_BUNDLE_NAME ${APP_NAME})
set_from_env(LAUNCHER_HMAC_SECRET LAUNCHER_HMAC_SECRET "") set_from_env(LAUNCHER_HMAC_SECRET LAUNCHER_HMAC_SECRET "")
if (LAUNCHER_HMAC_SECRET STREQUAL "") if (LAUNCHER_HMAC_SECRET STREQUAL "")
message(FATAL_ERROR "LAUNCHER_HMAC_SECRET is not set") message(FATAL_ERROR "LAUNCHER_HMAC_SECRET is not set")

View file

@ -5,7 +5,7 @@
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>English</string> <string>English</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string> <string>${APP_NAME}</string>
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string>${MACOSX_BUNDLE_ICON_FILE}</string> <string>${MACOSX_BUNDLE_ICON_FILE}</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
@ -29,7 +29,9 @@
<string>Window</string> <string>Window</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>
<string>NSApplication</string> <string>NSApplication</string>
<key>CFBundleName</key>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>HQ Launcher</string> <string>CFBundleName</string>
</dict> </dict>
</plist> </plist>

View file

@ -46,6 +46,7 @@ static BOOL const DELETE_ZIP_FILES = TRUE;
} }
-(void)awakeFromNib { -(void)awakeFromNib {
[[NSApplication sharedApplication] activateIgnoringOtherApps:TRUE];
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self
selector:@selector(didTerminateApp:) selector:@selector(didTerminateApp:)
name:NSWorkspaceDidTerminateApplicationNotification name:NSWorkspaceDidTerminateApplicationNotification
@ -114,6 +115,7 @@ static BOOL const DELETE_ZIP_FILES = TRUE;
userInfo:nil userInfo:nil
repeats:NO]; repeats:NO];
} }
[[NSApplication sharedApplication] activateIgnoringOtherApps:TRUE];
} }
- (void) setDownloadContextFilename:(NSString *)aFilename - (void) setDownloadContextFilename:(NSString *)aFilename
@ -277,6 +279,7 @@ static BOOL const DELETE_ZIP_FILES = TRUE;
-(void)onSplashScreenTimerFinished:(NSTimer *)timer -(void)onSplashScreenTimerFinished:(NSTimer *)timer
{ {
[[NSApplication sharedApplication] activateIgnoringOtherApps:TRUE];
[self showLoginScreen]; [self showLoginScreen];
} }
@ -336,6 +339,7 @@ static BOOL const DELETE_ZIP_FILES = TRUE;
NSString* scriptsPath = [[self getAppPath] stringByAppendingString:@"interface.app/Contents/Resources/scripts/simplifiedUI/"]; NSString* scriptsPath = [[self getAppPath] stringByAppendingString:@"interface.app/Contents/Resources/scripts/simplifiedUI/"];
NSString* domainUrl = [[Settings sharedSettings] getDomainUrl]; NSString* domainUrl = [[Settings sharedSettings] getDomainUrl];
NSString* userToken = [[Launcher sharedLauncher] getTokenString]; NSString* userToken = [[Launcher sharedLauncher] getTokenString];
NSString* homeBookmark = [[NSString stringWithFormat:@"hqhome="] stringByAppendingString:domainUrl];
NSArray* arguments; NSArray* arguments;
if (userToken != nil) { if (userToken != nil) {
arguments = [NSArray arrayWithObjects: arguments = [NSArray arrayWithObjects:
@ -344,6 +348,7 @@ static BOOL const DELETE_ZIP_FILES = TRUE;
@"--cache", contentPath, @"--cache", contentPath,
@"--displayName", displayName, @"--displayName", displayName,
@"--scripts", scriptsPath, @"--scripts", scriptsPath,
@"--setBookmark", homeBookmark,
@"--no-updater", @"--no-updater",
@"--no-launcher", nil]; @"--no-launcher", nil];
} else { } else {
@ -351,6 +356,7 @@ static BOOL const DELETE_ZIP_FILES = TRUE;
@"--url" , domainUrl, @"--url" , domainUrl,
@"--cache", contentPath, @"--cache", contentPath,
@"--scripts", scriptsPath, @"--scripts", scriptsPath,
@"--setBookmark", homeBookmark,
@"--no-updater", @"--no-updater",
@"--no-launcher", nil]; @"--no-launcher", nil];
} }

View file

@ -25,7 +25,7 @@
break; break;
case CHECKING_UPDATE: case CHECKING_UPDATE:
[self.boldStatus setStringValue:@"Getting updates..."]; [self.boldStatus setStringValue:@"Getting updates..."];
[self.smallStatus setStringValue:@"We're getting the lastest and greatest for you, one sec."]; [self.smallStatus setStringValue:@"We're getting the latest and greatest for you, one sec."];
break; break;
case RUNNING_INTERFACE_AFTER_UPDATE: case RUNNING_INTERFACE_AFTER_UPDATE:
[self.boldStatus setStringValue:@"You're good to go!"]; [self.boldStatus setStringValue:@"You're good to go!"];

View file

@ -234,9 +234,10 @@ HWND LauncherManager::launchApplication() {
CString parsedTokens = _tokensJSON; CString parsedTokens = _tokensJSON;
parsedTokens.Replace(_T("\""), _T("\\\"")); parsedTokens.Replace(_T("\""), _T("\\\""));
tokensParam = _T("--tokens \""); tokensParam = _T("--tokens \"");
tokensParam += parsedTokens + _T("\""); tokensParam += parsedTokens + _T("\" ");
} }
CString params = urlParam + scriptsParam + cacheParam + nameParam + tokensParam + EXTRA_PARAMETERS; CString bookmarkParam = _T("--setBookmark hqhome=\"") + _domainURL + ("\" ");
CString params = urlParam + scriptsParam + cacheParam + nameParam + tokensParam + bookmarkParam + EXTRA_PARAMETERS;
_shouldLaunch = FALSE; _shouldLaunch = FALSE;
return LauncherUtils::executeOnForeground(interfaceExe, params); return LauncherUtils::executeOnForeground(interfaceExe, params);
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View file

@ -10,10 +10,13 @@
#include "AnimClip.h" #include "AnimClip.h"
#include <assert.h>
#include "GLMHelpers.h" #include "GLMHelpers.h"
#include "AnimationLogging.h" #include "AnimationLogging.h"
#include "AnimUtil.h" #include "AnimUtil.h"
AnimClip::AnimClip(const QString& id, const QString& url, float startFrame, float endFrame, float timeScale, bool loopFlag, bool mirrorFlag) : AnimClip::AnimClip(const QString& id, const QString& url, float startFrame, float endFrame, float timeScale, bool loopFlag, bool mirrorFlag) :
AnimNode(AnimNode::Type::Clip, id), AnimNode(AnimNode::Type::Clip, id),
_startFrame(startFrame), _startFrame(startFrame),
@ -107,6 +110,19 @@ static std::vector<int> buildJointIndexMap(const AnimSkeleton& dstSkeleton, cons
return jointIndexMap; return jointIndexMap;
} }
#ifdef USE_CUSTOM_ASSERT
#undef ASSERT
#define ASSERT(x) \
do { \
if (!(x)) { \
int* bad_ptr = 0; \
*bad_ptr = 0x0badf00d; \
} \
} while (0)
#else
#define ASSERT assert
#endif
void AnimClip::copyFromNetworkAnim() { void AnimClip::copyFromNetworkAnim() {
assert(_networkAnim && _networkAnim->isLoaded() && _skeleton); assert(_networkAnim && _networkAnim->isLoaded() && _skeleton);
_anim.clear(); _anim.clear();
@ -165,11 +181,14 @@ void AnimClip::copyFromNetworkAnim() {
for (int frame = 0; frame < animFrameCount; frame++) { for (int frame = 0; frame < animFrameCount; frame++) {
const HFMAnimationFrame& animFrame = animModel.animationFrames[frame]; const HFMAnimationFrame& animFrame = animModel.animationFrames[frame];
ASSERT(frame >= 0 && frame < (int)animModel.animationFrames.size());
// extract the full rotations from the animFrame (including pre and post rotations from the animModel). // extract the full rotations from the animFrame (including pre and post rotations from the animModel).
std::vector<glm::quat> animRotations; std::vector<glm::quat> animRotations;
animRotations.reserve(animJointCount); animRotations.reserve(animJointCount);
for (int i = 0; i < animJointCount; i++) { for (int i = 0; i < animJointCount; i++) {
ASSERT(i >= 0 && i < (int)animModel.joints.size());
ASSERT(i >= 0 && i < (int)animFrame.rotations.size());
animRotations.push_back(animModel.joints[i].preRotation * animFrame.rotations[i] * animModel.joints[i].postRotation); animRotations.push_back(animModel.joints[i].preRotation * animFrame.rotations[i] * animModel.joints[i].postRotation);
} }
@ -180,10 +199,12 @@ void AnimClip::copyFromNetworkAnim() {
std::vector<glm::quat> avatarRotations; std::vector<glm::quat> avatarRotations;
avatarRotations.reserve(avatarJointCount); avatarRotations.reserve(avatarJointCount);
for (int avatarJointIndex = 0; avatarJointIndex < avatarJointCount; avatarJointIndex++) { for (int avatarJointIndex = 0; avatarJointIndex < avatarJointCount; avatarJointIndex++) {
ASSERT(avatarJointIndex >= 0 && avatarJointIndex < (int)avatarToAnimJointIndexMap.size());
int animJointIndex = avatarToAnimJointIndexMap[avatarJointIndex]; int animJointIndex = avatarToAnimJointIndexMap[avatarJointIndex];
if (animJointIndex >= 0) { if (animJointIndex >= 0) {
// This joint is in both animation and avatar. // This joint is in both animation and avatar.
// Set the absolute rotation directly // Set the absolute rotation directly
ASSERT(animJointIndex >= 0 && animJointIndex < (int)animRotations.size());
avatarRotations.push_back(animRotations[animJointIndex]); avatarRotations.push_back(animRotations[animJointIndex]);
} else { } else {
// This joint is NOT in the animation at all. // This joint is NOT in the animation at all.
@ -192,6 +213,7 @@ void AnimClip::copyFromNetworkAnim() {
glm::quat avatarParentAbsoluteRot; glm::quat avatarParentAbsoluteRot;
int avatarParentJointIndex = avatarSkeleton->getParentIndex(avatarJointIndex); int avatarParentJointIndex = avatarSkeleton->getParentIndex(avatarJointIndex);
if (avatarParentJointIndex >= 0) { if (avatarParentJointIndex >= 0) {
ASSERT(avatarParentJointIndex >= 0 && avatarParentJointIndex < (int)avatarRotations.size());
avatarParentAbsoluteRot = avatarRotations[avatarParentJointIndex]; avatarParentAbsoluteRot = avatarRotations[avatarParentJointIndex];
} }
avatarRotations.push_back(avatarParentAbsoluteRot * avatarRelativeDefaultRot); avatarRotations.push_back(avatarParentAbsoluteRot * avatarRelativeDefaultRot);
@ -201,6 +223,7 @@ void AnimClip::copyFromNetworkAnim() {
// convert avatar rotations into relative frame // convert avatar rotations into relative frame
avatarSkeleton->convertAbsoluteRotationsToRelative(avatarRotations); avatarSkeleton->convertAbsoluteRotationsToRelative(avatarRotations);
ASSERT(frame >= 0 && frame < (int)_anim.size());
_anim[frame].reserve(avatarJointCount); _anim[frame].reserve(avatarJointCount);
for (int avatarJointIndex = 0; avatarJointIndex < avatarJointCount; avatarJointIndex++) { for (int avatarJointIndex = 0; avatarJointIndex < avatarJointCount; avatarJointIndex++) {
const AnimPose& avatarDefaultPose = avatarSkeleton->getRelativeDefaultPose(avatarJointIndex); const AnimPose& avatarDefaultPose = avatarSkeleton->getRelativeDefaultPose(avatarJointIndex);
@ -209,12 +232,15 @@ void AnimClip::copyFromNetworkAnim() {
glm::vec3 relativeScale = avatarDefaultPose.scale(); glm::vec3 relativeScale = avatarDefaultPose.scale();
glm::vec3 relativeTranslation; glm::vec3 relativeTranslation;
ASSERT(avatarJointIndex >= 0 && avatarJointIndex < (int)avatarToAnimJointIndexMap.size());
int animJointIndex = avatarToAnimJointIndexMap[avatarJointIndex]; int animJointIndex = avatarToAnimJointIndexMap[avatarJointIndex];
if (animJointIndex >= 0) { if (animJointIndex >= 0) {
// This joint is in both animation and avatar. // This joint is in both animation and avatar.
ASSERT(animJointIndex >= 0 && animJointIndex < (int)animFrame.translations.size());
const glm::vec3& animTrans = animFrame.translations[animJointIndex]; const glm::vec3& animTrans = animFrame.translations[animJointIndex];
// retarget translation from animation to avatar // retarget translation from animation to avatar
ASSERT(animJointIndex >= 0 && animJointIndex < (int)animModel.animationFrames[0].translations.size());
const glm::vec3& animZeroTrans = animModel.animationFrames[0].translations[animJointIndex]; const glm::vec3& animZeroTrans = animModel.animationFrames[0].translations[animJointIndex];
relativeTranslation = avatarDefaultPose.trans() + boneLengthScale * (animTrans - animZeroTrans); relativeTranslation = avatarDefaultPose.trans() + boneLengthScale * (animTrans - animZeroTrans);
} else { } else {
@ -224,6 +250,7 @@ void AnimClip::copyFromNetworkAnim() {
} }
// build the final pose // build the final pose
ASSERT(avatarJointIndex >= 0 && avatarJointIndex < (int)avatarRotations.size());
_anim[frame].push_back(AnimPose(relativeScale, avatarRotations[avatarJointIndex], relativeTranslation)); _anim[frame].push_back(AnimPose(relativeScale, avatarRotations[avatarJointIndex], relativeTranslation));
} }
} }

View file

@ -98,6 +98,8 @@ public:
return result; return result;
} }
const AnimPoseVec& getPoses() const { return getPosesInternal(); }
protected: protected:
virtual void setCurrentFrameInternal(float frame) {} virtual void setCurrentFrameInternal(float frame) {}

View file

@ -2232,6 +2232,14 @@ void Rig::initAnimGraph(const QUrl& url) {
} }
} }
AnimNode::ConstPointer Rig::findAnimNodeByName(const QString& name) const {
if (_animNode) {
return _animNode->findByName(name);
} else {
return nullptr;
}
}
bool Rig::getModelRegistrationPoint(glm::vec3& modelRegistrationPointOut) const { bool Rig::getModelRegistrationPoint(glm::vec3& modelRegistrationPointOut) const {
if (_animSkeleton && _rootJointIndex >= 0) { if (_animSkeleton && _rootJointIndex >= 0) {
modelRegistrationPointOut = _geometryOffset * -_animSkeleton->getAbsoluteDefaultPose(_rootJointIndex).trans(); modelRegistrationPointOut = _geometryOffset * -_animSkeleton->getAbsoluteDefaultPose(_rootJointIndex).trans();
@ -2258,7 +2266,7 @@ void Rig::applyOverridePoses() {
} }
} }
void Rig::buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut) { void Rig::buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut) const {
DETAILED_PERFORMANCE_TIMER("buildAbsolute"); DETAILED_PERFORMANCE_TIMER("buildAbsolute");
if (!_animSkeleton) { if (!_animSkeleton) {
return; return;

View file

@ -196,6 +196,7 @@ public:
void initAnimGraph(const QUrl& url); void initAnimGraph(const QUrl& url);
AnimNode::ConstPointer getAnimNode() const { return _animNode; } AnimNode::ConstPointer getAnimNode() const { return _animNode; }
AnimNode::ConstPointer findAnimNodeByName(const QString& name) const;
AnimSkeleton::ConstPointer getAnimSkeleton() const { return _animSkeleton; } AnimSkeleton::ConstPointer getAnimSkeleton() const { return _animSkeleton; }
QScriptValue addAnimationStateHandler(QScriptValue handler, QScriptValue propertiesList); QScriptValue addAnimationStateHandler(QScriptValue handler, QScriptValue propertiesList);
void removeAnimationStateHandler(QScriptValue handler); void removeAnimationStateHandler(QScriptValue handler);
@ -243,7 +244,7 @@ public:
Flow& getFlow() { return _internalFlow; } Flow& getFlow() { return _internalFlow; }
float getUnscaledEyeHeight() const; float getUnscaledEyeHeight() const;
void buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut) const;
signals: signals:
void onLoadComplete(); void onLoadComplete();
@ -252,7 +253,6 @@ protected:
bool isIndexValid(int index) const { return _animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints(); } bool isIndexValid(int index) const { return _animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints(); }
void updateAnimationStateHandlers(); void updateAnimationStateHandlers();
void applyOverridePoses(); void applyOverridePoses();
void buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut);
void updateHead(bool headEnabled, bool hipsEnabled, const AnimPose& headMatrix); void updateHead(bool headEnabled, bool hipsEnabled, const AnimPose& headMatrix);
void updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnabled, bool hipsEstimated, void updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnabled, bool hipsEstimated,

View file

@ -368,6 +368,10 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
} }
if (type == SHAPE_TYPE_COMPOUND) { if (type == SHAPE_TYPE_COMPOUND) {
if (!_compoundShapeResource || !_compoundShapeResource->isLoaded()) {
return;
}
updateModelBounds(); updateModelBounds();
// should never fall in here when collision model not fully loaded // should never fall in here when collision model not fully loaded

View file

@ -559,6 +559,8 @@ void DomainHandler::processDomainServerConnectionDeniedPacket(QSharedPointer<Rec
} }
} }
static const int SILENT_DOMAIN_TRAFFIC_DROP_MIN = 2;
bool DomainHandler::checkInPacketTimeout() { bool DomainHandler::checkInPacketTimeout() {
++_checkInPacketsSinceLastReply; ++_checkInPacketsSinceLastReply;
@ -566,9 +568,14 @@ bool DomainHandler::checkInPacketTimeout() {
qCDebug(networking_ice) << "Silent domain checkins:" << _checkInPacketsSinceLastReply; qCDebug(networking_ice) << "Silent domain checkins:" << _checkInPacketsSinceLastReply;
} }
if (_checkInPacketsSinceLastReply > MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { auto nodeList = DependencyManager::get<NodeList>();
auto nodeList = DependencyManager::get<NodeList>(); if (_checkInPacketsSinceLastReply > SILENT_DOMAIN_TRAFFIC_DROP_MIN) {
qCDebug(networking_ice) << _checkInPacketsSinceLastReply << "seconds since last domain list request, squelching traffic";
nodeList->setDropOutgoingNodeTraffic(true);
}
if (_checkInPacketsSinceLastReply > MAX_SILENT_DOMAIN_SERVER_CHECK_INS) {
// we haven't heard back from DS in MAX_SILENT_DOMAIN_SERVER_CHECK_INS // we haven't heard back from DS in MAX_SILENT_DOMAIN_SERVER_CHECK_INS
// so emit our signal that says that // so emit our signal that says that

View file

@ -409,6 +409,16 @@ qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const HifiS
Q_ASSERT_X(!packet.isReliable(), "LimitedNodeList::sendUnreliablePacket", Q_ASSERT_X(!packet.isReliable(), "LimitedNodeList::sendUnreliablePacket",
"Trying to send a reliable packet unreliably."); "Trying to send a reliable packet unreliably.");
if (_dropOutgoingNodeTraffic) {
auto destinationNode = findNodeWithAddr(sockAddr);
// findNodeWithAddr returns null for the address of the domain server
if (!destinationNode.isNull()) {
// This only suppresses individual unreliable packets, not unreliable packet lists
return ERROR_SENDING_PACKET_BYTES;
}
}
fillPacketHeader(packet, hmacAuth); fillPacketHeader(packet, hmacAuth);
return _nodeSocket.writePacket(packet, sockAddr); return _nodeSocket.writePacket(packet, sockAddr);

View file

@ -335,6 +335,8 @@ public:
float getInboundKbps() const { return _inboundKbps; } float getInboundKbps() const { return _inboundKbps; }
float getOutboundKbps() const { return _outboundKbps; } float getOutboundKbps() const { return _outboundKbps; }
void setDropOutgoingNodeTraffic(bool squelchOutgoingNodeTraffic) { _dropOutgoingNodeTraffic = squelchOutgoingNodeTraffic; }
const std::set<NodeType_t> SOLO_NODE_TYPES = { const std::set<NodeType_t> SOLO_NODE_TYPES = {
NodeType::AvatarMixer, NodeType::AvatarMixer,
NodeType::AudioMixer, NodeType::AudioMixer,
@ -493,6 +495,8 @@ private:
int _outboundPPS { 0 }; int _outboundPPS { 0 };
float _inboundKbps { 0.0f }; float _inboundKbps { 0.0f };
float _outboundKbps { 0.0f }; float _outboundKbps { 0.0f };
bool _dropOutgoingNodeTraffic { false };
}; };
#endif // hifi_LimitedNodeList_h #endif // hifi_LimitedNodeList_h

View file

@ -306,7 +306,8 @@ void NodeList::sendDomainServerCheckIn() {
// may be called by multiple threads. // may be called by multiple threads.
if (!_sendDomainServerCheckInEnabled) { if (!_sendDomainServerCheckInEnabled) {
qCDebug(networking_ice) << "Refusing to send a domain-server check in while it is disabled."; static const QString DISABLED_CHECKIN_DEBUG{ "Refusing to send a domain-server check in while it is disabled." };
HIFI_FCDEBUG(networking_ice(), DISABLED_CHECKIN_DEBUG);
return; return;
} }
@ -450,13 +451,8 @@ void NodeList::sendDomainServerCheckIn() {
// Send duplicate check-ins in the exponentially increasing sequence 1, 1, 2, 4, ... // Send duplicate check-ins in the exponentially increasing sequence 1, 1, 2, 4, ...
static const int MAX_CHECKINS_TOGETHER = 20; static const int MAX_CHECKINS_TOGETHER = 20;
static const int REBIND_CHECKIN_COUNT = 2;
int outstandingCheckins = _domainHandler.getCheckInPacketsSinceLastReply(); int outstandingCheckins = _domainHandler.getCheckInPacketsSinceLastReply();
if (outstandingCheckins > REBIND_CHECKIN_COUNT) {
_nodeSocket.rebind();
}
int checkinCount = outstandingCheckins > 1 ? std::pow(2, outstandingCheckins - 2) : 1; int checkinCount = outstandingCheckins > 1 ? std::pow(2, outstandingCheckins - 2) : 1;
checkinCount = std::min(checkinCount, MAX_CHECKINS_TOGETHER); checkinCount = std::min(checkinCount, MAX_CHECKINS_TOGETHER);
for (int i = 1; i < checkinCount; ++i) { for (int i = 1; i < checkinCount; ++i) {
@ -710,6 +706,7 @@ void NodeList::processDomainServerList(QSharedPointer<ReceivedMessage> message)
// this is a packet from the domain server, reset the count of un-replied check-ins // this is a packet from the domain server, reset the count of un-replied check-ins
_domainHandler.clearPendingCheckins(); _domainHandler.clearPendingCheckins();
setDropOutgoingNodeTraffic(false);
// emit our signal so listeners know we just heard from the DS // emit our signal so listeners know we just heard from the DS
emit receivedDomainServerList(); emit receivedDomainServerList();

View file

@ -230,7 +230,7 @@ qint64 Socket::writeDatagram(const QByteArray& datagram, const HifiSockAddr& soc
// _udpSocket.writeDatagram will return an error anyway, but there are // _udpSocket.writeDatagram will return an error anyway, but there are
// potential crashes in Qt when that happens. // potential crashes in Qt when that happens.
if (_udpSocket.state() != QAbstractSocket::BoundState) { if (_udpSocket.state() != QAbstractSocket::BoundState) {
qCDebug(networking) << "Attempt to writeDatagram when in unbound state"; qCDebug(networking) << "Attempt to writeDatagram when in unbound state to" << sockAddr;
return -1; return -1;
} }
qint64 bytesWritten = _udpSocket.writeDatagram(datagram, sockAddr.getAddress(), sockAddr.getPort()); qint64 bytesWritten = _udpSocket.writeDatagram(datagram, sockAddr.getAddress(), sockAddr.getPort());
@ -240,11 +240,11 @@ qint64 Socket::writeDatagram(const QByteArray& datagram, const HifiSockAddr& soc
#ifdef WIN32 #ifdef WIN32
wsaError = WSAGetLastError(); wsaError = WSAGetLastError();
#endif #endif
qCDebug(networking) << "udt::writeDatagram (" << _udpSocket.state() << ") error - " << wsaError << _udpSocket.error() << "(" << _udpSocket.errorString() << ")" qCDebug(networking) << "udt::writeDatagram (" << _udpSocket.state() << sockAddr << ") error - " << wsaError << _udpSocket.error() << "(" << _udpSocket.errorString() << ")"
<< (pending ? "pending bytes:" : "pending:") << pending; << (pending ? "pending bytes:" : "pending:") << pending;
#ifdef DEBUG_EVENT_QUEUE #ifdef DEBUG_EVENT_QUEUE
int nodeListQueueSize = ::hifi::qt::getEventQueueSize(thread()); int nodeListQueueSize = ::hifi::qt::getEventQueueSize(thread());
qCDebug(networking) << "Networking queue size - " << nodeListQueueSize; qCDebug(networking) << "Networking queue size - " << nodeListQueueSize << "writing datagram to" << sockAddr;
#endif // DEBUG_EVENT_QUEUE #endif // DEBUG_EVENT_QUEUE
} }

View file

@ -12,6 +12,7 @@
#include "Platform.h" #include "Platform.h"
#include "PlatformKeys.h" #include "PlatformKeys.h"
#include <qglobal.h>
using namespace platform; using namespace platform;
@ -125,3 +126,39 @@ bool filterOnProcessors(const platform::json& computer, const platform::json& cp
// Not able to profile // Not able to profile
return false; return false;
} }
// Ugly very adhoc capability check to know if a particular hw can REnder with Deferred method or not
// YES for PC windows and linux
// NO for android
// YES on macos EXCEPT for macbookair with gpu intel iris or intel HD 6000
bool Profiler::isRenderMethodDeferredCapable() {
#if defined(Q_OS_MAC)
auto computer = platform::getComputer();
const auto computerModel = (computer.count(keys::computer::model) ? computer[keys::computer::model].get<std::string>() : "");
auto gpuInfo = platform::getGPU(0);
const auto gpuModel = (gpuInfo.count(keys::gpu::model) ? gpuInfo[keys::gpu::model].get<std::string>() : "");
// Macbook air 2018 are a problem
if ((computerModel.find("MacBookAir7,2") != std::string::npos) && (gpuModel.find("Intel HD Graphics 6000") != std::string::npos)) {
return false;
}
// We know for fact that the Mac BOok Pro 13 from Mid 2014 INtel Iris is problematic,
if ((computerModel.find("MacBookPro11,1") != std::string::npos) && (gpuModel.find("Intel Iris") != std::string::npos)) {
return false;
}
// TO avoid issues for the next few days, we are excluding all of intel chipset...
if ((gpuModel.find("Intel ") != std::string::npos)) {
return false;
}
return true;
#elif defined(Q_OS_ANDROID)
return false;
#else
return true;
#endif
}

View file

@ -28,6 +28,9 @@ public:
static const std::array<const char*, Tier::NumTiers> TierNames; static const std::array<const char*, Tier::NumTiers> TierNames;
static Tier profilePlatform(); static Tier profilePlatform();
// Ugly very adhoc capability check to know if a particular hw can REnder with Deferred method or not
static bool isRenderMethodDeferredCapable();
}; };
} }

View file

@ -47,6 +47,7 @@ GPUIdent* GPUIdent::ensureQuery(const QString& vendor, const QString& renderer)
GLint rendererInfoCount; GLint rendererInfoCount;
CGLError err = CGLQueryRendererInfo(cglDisplayMask, &rendererInfo, &rendererInfoCount); CGLError err = CGLQueryRendererInfo(cglDisplayMask, &rendererInfo, &rendererInfoCount);
GLint j, numRenderers = 0, deviceVRAM, bestVRAM = 0; GLint j, numRenderers = 0, deviceVRAM, bestVRAM = 0;
int bestGPUid = 0;
err = CGLQueryRendererInfo(cglDisplayMask, &rendererInfo, &numRenderers); err = CGLQueryRendererInfo(cglDisplayMask, &rendererInfo, &numRenderers);
if (0 == err) { if (0 == err) {
// Iterate over all of them and use the figure for the one with the most VRAM, // Iterate over all of them and use the figure for the one with the most VRAM,
@ -55,6 +56,7 @@ GPUIdent* GPUIdent::ensureQuery(const QString& vendor, const QString& renderer)
for (j = 0; j < numRenderers; j++) { for (j = 0; j < numRenderers; j++) {
CGLDescribeRenderer(rendererInfo, j, kCGLRPVideoMemoryMegabytes, &deviceVRAM); CGLDescribeRenderer(rendererInfo, j, kCGLRPVideoMemoryMegabytes, &deviceVRAM);
if (deviceVRAM > bestVRAM) { if (deviceVRAM > bestVRAM) {
bestGPUid = j;
bestVRAM = deviceVRAM; bestVRAM = deviceVRAM;
_isValid = true; _isValid = true;
} }
@ -78,6 +80,8 @@ GPUIdent* GPUIdent::ensureQuery(const QString& vendor, const QString& renderer)
for (int i = 0; i < parts.size(); ++i) { for (int i = 0; i < parts.size(); ++i) {
if (parts[i].toLower().contains("radeon") || parts[i].toLower().contains("nvidia")) { if (parts[i].toLower().contains("radeon") || parts[i].toLower().contains("nvidia")) {
_name=parts[i]; _name=parts[i];
} else if (i == bestGPUid) {
_name=parts[i];
} }
} }

View file

@ -686,43 +686,52 @@ void OffscreenQmlSurface::setKeyboardRaised(QObject* object, bool raised, bool n
return; return;
} }
#if !defined(Q_OS_ANDROID) bool android = false;
// if HMD is being worn, allow keyboard to open. allow it to close, HMD or not. #if defined(Q_OS_ANDROID)
if (!raised || qApp->property(hifi::properties::HMD).toBool()) { android = true;
QQuickItem* item = dynamic_cast<QQuickItem*>(object); #endif
if (!item) {
return;
}
// for future probably makes sense to consider one of the following: bool hmd = qApp->property(hifi::properties::HMD).toBool();
// 1. make keyboard a singleton, which will be dynamically re-parented before showing
// 2. track currently visible keyboard somewhere, allow to subscribe for this signal
// any of above should also eliminate need in duplicated properties and code below
while (item) { if (!android || hmd) {
// Numeric value may be set in parameter from HTML UI; for QML UI, detect numeric fields here. // if HMD is being worn, allow keyboard to open. allow it to close, HMD or not.
numeric = numeric || QString(item->metaObject()->className()).left(7) == "SpinBox"; if (!raised || hmd) {
QQuickItem* item = dynamic_cast<QQuickItem*>(object);
if (item->property("keyboardRaised").isValid()) { if (!item) {
// FIXME - HMD only: Possibly set value of "keyboardEnabled" per isHMDMode() for use in WebView.qml.
if (item->property("punctuationMode").isValid()) {
item->setProperty("punctuationMode", QVariant(numeric));
}
if (item->property("passwordField").isValid()) {
item->setProperty("passwordField", QVariant(passwordField));
}
if (raised) {
item->setProperty("keyboardRaised", QVariant(!raised));
}
item->setProperty("keyboardRaised", QVariant(raised));
return; return;
} }
item = dynamic_cast<QQuickItem*>(item->parentItem());
// for future probably makes sense to consider one of the following:
// 1. make keyboard a singleton, which will be dynamically re-parented before showing
// 2. track currently visible keyboard somewhere, allow to subscribe for this signal
// any of above should also eliminate need in duplicated properties and code below
while (item) {
// Numeric value may be set in parameter from HTML UI; for QML UI, detect numeric fields here.
numeric = numeric || QString(item->metaObject()->className()).left(7) == "SpinBox";
if (item->property("keyboardRaised").isValid()) {
if (item->property("punctuationMode").isValid()) {
item->setProperty("punctuationMode", QVariant(numeric));
}
if (item->property("passwordField").isValid()) {
item->setProperty("passwordField", QVariant(passwordField));
}
if (hmd && item->property("keyboardEnabled").isValid()) {
item->setProperty("keyboardEnabled", true);
}
item->setProperty("keyboardRaised", QVariant(raised));
return;
}
item = dynamic_cast<QQuickItem*>(item->parentItem());
}
} }
} }
#endif
} }
void OffscreenQmlSurface::emitScriptEvent(const QVariant& message) { void OffscreenQmlSurface::emitScriptEvent(const QVariant& message) {

View file

@ -26,8 +26,9 @@ Rectangle {
color: global.color color: global.color
ScrollView { ScrollView {
id: control id: scrollView
anchors.fill: parent anchors.fill: parent
contentWidth: parent.width
clip: true clip: true
Column { Column {

View file

@ -24,8 +24,11 @@ Rectangle {
color: global.colorBack color: global.colorBack
ScrollView { ScrollView {
id: scrollView
anchors.fill: parent anchors.fill: parent
contentWidth: parent.width
clip: true clip: true
Column { Column {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
@ -35,8 +38,6 @@ Rectangle {
isUnfold: true isUnfold: true
panelFrameData: Component { panelFrameData: Component {
PerformanceSettings { PerformanceSettings {
anchors.left: parent.left
anchors.right: parent.right
} }
} }
} }
@ -45,8 +46,6 @@ Rectangle {
isUnfold: true isUnfold: true
panelFrameData: Component { panelFrameData: Component {
RenderSettings { RenderSettings {
anchors.left: parent.left
anchors.right: parent.right
} }
} }
} }
@ -54,8 +53,6 @@ Rectangle {
label: "Platform" label: "Platform"
panelFrameData: Component { panelFrameData: Component {
Platform { Platform {
anchors.left: parent.left
anchors.right: parent.right
} }
} }
} }

View file

@ -83,9 +83,7 @@
// The initial delay cooldown keeps us from tracking progress before the allotted time // The initial delay cooldown keeps us from tracking progress before the allotted time
// has passed. // has passed.
INITIAL_DELAY_COOLDOWN_TIME = 1000, INITIAL_DELAY_COOLDOWN_TIME = 1000,
initialDelayCooldown = 0, initialDelayCooldown = 0;
isInInterstitialMode = false;
function fade() { function fade() {
@ -267,7 +265,7 @@
// Update state // Update state
if (!visible) { // Not visible because no recent downloads if (!visible) { // Not visible because no recent downloads
if ((displayProgress < 100 || gpuTextures > 0) && !isInInterstitialMode && !isInterstitialOverlaysVisible) { // Have started downloading so fade in if (displayProgress < 100 || gpuTextures > 0) { // Have started downloading so fade in
visible = true; visible = true;
alphaDelta = ALPHA_DELTA_IN; alphaDelta = ALPHA_DELTA_IN;
fadeTimer = Script.setInterval(fade, FADE_INTERVAL); fadeTimer = Script.setInterval(fade, FADE_INTERVAL);
@ -307,9 +305,6 @@
} else { } else {
x = x * BAR_HMD_REPEAT; x = x * BAR_HMD_REPEAT;
} }
if (isInInterstitialMode || isInterstitialOverlaysVisible) {
visible = false;
}
// Update progress bar // Update progress bar
Overlays.editOverlay(barDesktop.overlay, { Overlays.editOverlay(barDesktop.overlay, {
@ -349,10 +344,6 @@
} }
} }
function interstitialModeChanged(inMode) {
isInInterstitialMode = inMode;
}
function setUp() { function setUp() {
var is4k = Window.innerWidth > 3000; var is4k = Window.innerWidth > 3000;
@ -378,7 +369,6 @@
} }
setUp(); setUp();
Window.interstitialModeChanged.connect(interstitialModeChanged);
GlobalServices.downloadInfoChanged.connect(onDownloadInfoChanged); GlobalServices.downloadInfoChanged.connect(onDownloadInfoChanged);
GlobalServices.updateDownloadInfo(); GlobalServices.updateDownloadInfo();
Script.setInterval(update, 1000 / 60); Script.setInterval(update, 1000 / 60);

View file

@ -152,7 +152,7 @@ function simplifiedStatusIndicator(properties) {
// When avatar goes away, set status to busy // When avatar goes away, set status to busy
var previousStatus; var previousStatus = "available";
function onWentAway() { function onWentAway() {
previousStatus = currentStatus; previousStatus = currentStatus;
if (currentStatus !== "busy") { if (currentStatus !== "busy") {

View file

@ -415,7 +415,7 @@ function getInputDeviceMutedOverlayTopY() {
var inputDeviceMutedOverlay = false; var inputDeviceMutedOverlay = false;
var INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_X_PX = 353; var INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_X_PX = 353;
var INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_Y_PX = 95; var INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_Y_PX = 95;
var INPUT_DEVICE_MUTED_MARGIN_BOTTOM_PX = 20; var INPUT_DEVICE_MUTED_MARGIN_BOTTOM_PX = 20 + TOP_BAR_HEIGHT_PX;
function updateInputDeviceMutedOverlay(isMuted) { function updateInputDeviceMutedOverlay(isMuted) {
if (isMuted) { if (isMuted) {
var props = { var props = {