Merge branch 'master' of github.com:highfidelity/hifi into migrateEditFiles

This commit is contained in:
RebeccaStankus 2019-06-18 09:10:41 -07:00
commit cd508a5475
28 changed files with 312 additions and 116 deletions

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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -452,16 +452,7 @@ 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;
int outstandingCheckins = _domainHandler.getCheckInPacketsSinceLastReply(); int outstandingCheckins = _domainHandler.getCheckInPacketsSinceLastReply();
/*
static const int WARNING_CHECKIN_COUNT = 2;
if (outstandingCheckins > WARNING_CHECKIN_COUNT) {
// We may be headed for a disconnect, as we've written two DomainListRequests without getting anything back.
// In some cases, we've found that nothing is going out on the wire despite not getting any errors from
// sendPacket => writeDatagram, below. In at least some such cases, we've found that the DomainDisconnectRequest
// does go through, so let's at least try to mix it up with a different safe packet.
// TODO: send ICEPing, and later on tell the other nodes to shut up for a moment.
}*/
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) {
@ -715,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

@ -141,14 +141,19 @@ bool Profiler::isRenderMethodDeferredCapable() {
// Macbook air 2018 are a problem // Macbook air 2018 are a problem
if ((computerModel.find("MacBookAir") != std::string::npos) && (gpuModel.find("Intel HD Graphics 6000") != std::string::npos)) { if ((computerModel.find("MacBookAir7,2") != std::string::npos) && (gpuModel.find("Intel HD Graphics 6000") != std::string::npos)) {
return false; return false;
} }
// We know for fact that one INtel Iris is problematic, not enough info yet for sure // We know for fact that the Mac BOok Pro 13 from Mid 2014 INtel Iris is problematic,
// if ((gpuModel.find("Intel Iris ....") != std::string::npos)) { if ((computerModel.find("MacBookPro11,1") != std::string::npos) && (gpuModel.find("Intel Iris") != std::string::npos)) {
// return false; 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; return true;
#elif defined(Q_OS_ANDROID) #elif defined(Q_OS_ANDROID)

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") {