mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 13:43:49 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into tweak_sit_pose
This commit is contained in:
commit
ec06a02fdf
21 changed files with 241 additions and 436 deletions
|
@ -157,11 +157,6 @@ qint64 AvatarMixerSlave::addChangedTraitsToBulkPacket(AvatarMixerClientData* lis
|
|||
++simpleReceivedIt;
|
||||
}
|
||||
|
||||
if (bytesWritten > 0 && sendingAvatar->isCertifyFailed()) {
|
||||
// Resend identity packet if certification failed:
|
||||
sendingAvatar->setNeedsIdentityUpdate();
|
||||
}
|
||||
|
||||
// enumerate the received instanced trait versions
|
||||
auto instancedReceivedIt = lastReceivedVersions.instancedCBegin();
|
||||
while (instancedReceivedIt != lastReceivedVersions.instancedCEnd()) {
|
||||
|
|
|
@ -4250,6 +4250,19 @@
|
|||
},
|
||||
"id": "LANDRUN",
|
||||
"type": "clip"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
],
|
||||
"data": {
|
||||
"endFrame": 105,
|
||||
"loopFlag": false,
|
||||
"startFrame": 100,
|
||||
"timeScale": 1,
|
||||
"url": "qrc:///avatar/animations/idle.fbx"
|
||||
},
|
||||
"id": "seatedToIdle",
|
||||
"type": "clip"
|
||||
}
|
||||
],
|
||||
"data": {
|
||||
|
@ -4267,60 +4280,8 @@
|
|||
"interpType": "evaluateBoth",
|
||||
"transitions": [
|
||||
{
|
||||
"state": "idle",
|
||||
"var": "isNotMoving"
|
||||
},
|
||||
{
|
||||
"state": "WALKFWD",
|
||||
"var": "isMovingForward"
|
||||
},
|
||||
{
|
||||
"state": "WALKBWD",
|
||||
"var": "isMovingBackward"
|
||||
},
|
||||
{
|
||||
"state": "STRAFERIGHT",
|
||||
"var": "isMovingRight"
|
||||
},
|
||||
{
|
||||
"state": "STRAFELEFT",
|
||||
"var": "isMovingLeft"
|
||||
},
|
||||
{
|
||||
"state": "turnRight",
|
||||
"var": "isTurningRight"
|
||||
},
|
||||
{
|
||||
"state": "turnLeft",
|
||||
"var": "isTurningLeft"
|
||||
},
|
||||
{
|
||||
"state": "fly",
|
||||
"var": "isFlying"
|
||||
},
|
||||
{
|
||||
"state": "takeoffStand",
|
||||
"var": "isTakeoffStand"
|
||||
},
|
||||
{
|
||||
"state": "TAKEOFFRUN",
|
||||
"var": "isTakeoffRun"
|
||||
},
|
||||
{
|
||||
"state": "inAirStand",
|
||||
"var": "isInAirStand"
|
||||
},
|
||||
{
|
||||
"state": "INAIRRUN",
|
||||
"var": "isInAirRun"
|
||||
},
|
||||
{
|
||||
"state": "strafeRightHmd",
|
||||
"var": "isMovingRightHmd"
|
||||
},
|
||||
{
|
||||
"state": "strafeLeftHmd",
|
||||
"var": "isMovingLeftHmd"
|
||||
"state": "seatedToIdle",
|
||||
"var": "isNotSeated"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -5210,6 +5171,18 @@
|
|||
"var": "landRunOnDone"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "seatedToIdle",
|
||||
"interpDuration": 10,
|
||||
"interpTarget": 1,
|
||||
"interpType": "snapshotPrev",
|
||||
"transitions": [
|
||||
{
|
||||
"state": "idle",
|
||||
"var": "seatedToIdleOnDone"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -16,6 +16,7 @@ import stylesUit 1.0 as HifiStylesUit
|
|||
import "./controls" as HelpControls
|
||||
import "./faq" as HelpFAQ
|
||||
import "./about" as HelpAbout
|
||||
import "./support" as HelpSupport
|
||||
|
||||
Rectangle {
|
||||
property string activeTabView: "controlsTabView"
|
||||
|
@ -59,6 +60,10 @@ Rectangle {
|
|||
tabTitle: "Controls"
|
||||
tabViewName: "controlsTabView"
|
||||
}
|
||||
ListElement {
|
||||
tabTitle: "Support"
|
||||
tabViewName: "supportTabView"
|
||||
}
|
||||
ListElement {
|
||||
tabTitle: "FAQ"
|
||||
tabViewName: "faqTabView"
|
||||
|
@ -139,6 +144,12 @@ Rectangle {
|
|||
anchors.fill: parent
|
||||
}
|
||||
|
||||
HelpSupport.HelpSupport {
|
||||
id: supportTabViewContainer
|
||||
visible: activeTabView === "supportTabView"
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
HelpFAQ.HelpFAQ {
|
||||
id: faqTabViewContainer
|
||||
visible: activeTabView === "faqTabView"
|
||||
|
@ -159,6 +170,8 @@ Rectangle {
|
|||
parent: {
|
||||
if (activeTabView === "controlsTabView") {
|
||||
controlsTabViewContainer
|
||||
} else if (activeTabView === "supportTabView") {
|
||||
supportTabViewContainer
|
||||
} else if (activeTabView === "faqTabView") {
|
||||
faqTabViewContainer
|
||||
} else if (activeTabView === "aboutTabView") {
|
||||
|
|
|
@ -88,7 +88,7 @@ Flickable {
|
|||
temporaryText: "Viewing!"
|
||||
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("http://docs.highfidelity.com/explore/get-started/desktop.html");
|
||||
Qt.openUrlExternally("https://www.highfidelity.com/knowledge/get-around");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
//
|
||||
// HelpSupport.qml
|
||||
//
|
||||
// Created by Zach Fox on 2019-08-20
|
||||
// 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
|
||||
import "../../simplifiedControls" as SimplifiedControls
|
||||
import stylesUit 1.0 as HifiStylesUit
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
Item {
|
||||
id: root
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
|
||||
SimplifiedConstants.SimplifiedConstants {
|
||||
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 {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 26
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 26
|
||||
anchors.top: parent.top
|
||||
spacing: 0
|
||||
|
||||
HifiStylesUit.GraphikSemiBold {
|
||||
text: "Support"
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.preferredHeight: paintedHeight
|
||||
Layout.topMargin: 16
|
||||
size: 22
|
||||
color: simplifiedUI.colors.text.white
|
||||
}
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
text: "You can quickly get the support that you need by clicking the button below."
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.preferredHeight: paintedHeight
|
||||
Layout.topMargin: 8
|
||||
size: 18
|
||||
wrapMode: Text.Wrap
|
||||
color: simplifiedUI.colors.text.white
|
||||
}
|
||||
|
||||
SimplifiedControls.Button {
|
||||
Layout.topMargin: 8
|
||||
width: 200
|
||||
height: 32
|
||||
text: "CONTACT SUPPORT"
|
||||
temporaryText: "Opening browser..."
|
||||
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://www.highfidelity.com/knowledge/kb-tickets/new");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signal sendToScript(var message);
|
||||
}
|
|
@ -17,8 +17,6 @@ import "./audio" as AudioSettings
|
|||
import "./general" as GeneralSettings
|
||||
import "./vr" as VrSettings
|
||||
import "./dev" as DevSettings
|
||||
import "./about" as AboutSettings
|
||||
|
||||
Rectangle {
|
||||
property string activeTabView: "generalTabView"
|
||||
id: root
|
||||
|
@ -86,10 +84,6 @@ Rectangle {
|
|||
tabTitle: "VR"
|
||||
tabViewName: "vrTabView"
|
||||
}
|
||||
ListElement {
|
||||
tabTitle: "About"
|
||||
tabViewName: "aboutTabView"
|
||||
}
|
||||
ListElement {
|
||||
tabTitle: "Dev"
|
||||
tabViewName: "devTabView"
|
||||
|
@ -190,12 +184,6 @@ Rectangle {
|
|||
anchors.fill: parent
|
||||
}
|
||||
|
||||
AboutSettings.About {
|
||||
id: aboutTabViewContainer
|
||||
visible: activeTabView === "aboutTabView"
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
SimplifiedControls.VerticalScrollBar {
|
||||
parent: {
|
||||
if (activeTabView === "generalTabView") {
|
||||
|
@ -206,8 +194,6 @@ Rectangle {
|
|||
vrTabViewContainer
|
||||
} else if (activeTabView === "devTabView") {
|
||||
devTabViewContainer
|
||||
} else if (activeTabView === "aboutTabView") {
|
||||
aboutTabViewContainer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,332 +0,0 @@
|
|||
//
|
||||
// About.qml
|
||||
//
|
||||
// Created by Zach Fox on 2019-06-18
|
||||
// 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
|
||||
import "../../simplifiedControls" as SimplifiedControls
|
||||
import stylesUit 1.0 as HifiStylesUit
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
Flickable {
|
||||
id: root
|
||||
contentWidth: parent.width
|
||||
contentHeight: aboutColumnLayout.height
|
||||
clip: true
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
root.contentX = 0;
|
||||
root.contentY = 0;
|
||||
|
||||
// When the user clicks the About tab, refresh the audio I/O model so that
|
||||
// the delegate Component.onCompleted handlers fire, which will update
|
||||
// the text that appears in the About screen.
|
||||
audioOutputDevices.model = undefined;
|
||||
audioOutputDevices.model = AudioScriptingInterface.devices.output;
|
||||
audioInputDevices.model = undefined;
|
||||
audioInputDevices.model = AudioScriptingInterface.devices.input;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SimplifiedConstants.SimplifiedConstants {
|
||||
id: simplifiedUI
|
||||
}
|
||||
|
||||
|
||||
ColumnLayout {
|
||||
id: aboutColumnLayout
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 26
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 26
|
||||
anchors.top: parent.top
|
||||
spacing: 0
|
||||
|
||||
Image {
|
||||
source: "images/logo.png"
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: 16
|
||||
Layout.preferredWidth: 160
|
||||
Layout.preferredHeight: 120
|
||||
fillMode: Image.PreserveAspectFit
|
||||
mipmap: true
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: platformInfoContainer
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.bottomMargin: 24
|
||||
spacing: 0
|
||||
|
||||
HifiStylesUit.GraphikSemiBold {
|
||||
text: "Version " + Window.checkVersion()
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredWidth: parent.width
|
||||
height: paintedHeight
|
||||
size: 16
|
||||
color: simplifiedUI.colors.text.white
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
HifiStylesUit.GraphikSemiBold {
|
||||
text: "Platform Info"
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.topMargin: 8
|
||||
Layout.bottomMargin: 8
|
||||
height: paintedHeight
|
||||
size: 22
|
||||
color: simplifiedUI.colors.text.white
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
text: "<b>Computer Vendor/Model:</b>"
|
||||
Layout.preferredWidth: parent.width
|
||||
height: paintedHeight
|
||||
size: 16
|
||||
color: simplifiedUI.colors.text.white
|
||||
wrapMode: Text.Wrap
|
||||
|
||||
Component.onCompleted: {
|
||||
var computer = JSON.parse(PlatformInfo.getComputer());
|
||||
var computerVendor = computer.vendor;
|
||||
if (computerVendor.length === 0) {
|
||||
computerVendor = "Unknown";
|
||||
}
|
||||
var computerModel = computer.model;
|
||||
if (computerModel.length === 0) {
|
||||
computerModel = "Unknown";
|
||||
}
|
||||
|
||||
text = "<b>Computer Vendor/Model:</b> " + computerVendor + "/" + computerModel;
|
||||
}
|
||||
}
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
text: "<b>Profiled Platform Tier:</b> " + PlatformInfo.getTierProfiled()
|
||||
Layout.preferredWidth: parent.width
|
||||
height: paintedHeight
|
||||
size: 16
|
||||
color: simplifiedUI.colors.text.white
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
text: "<b>OS Type:</b> " + PlatformInfo.getOperatingSystemType()
|
||||
Layout.preferredWidth: parent.width
|
||||
height: paintedHeight
|
||||
size: 16
|
||||
color: simplifiedUI.colors.text.white
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
text: "<b>CPU:</b>"
|
||||
Layout.preferredWidth: parent.width
|
||||
height: paintedHeight
|
||||
size: 16
|
||||
color: simplifiedUI.colors.text.white
|
||||
wrapMode: Text.Wrap
|
||||
|
||||
Component.onCompleted: {
|
||||
var cpu = JSON.parse(PlatformInfo.getCPU(0));
|
||||
var cpuModel = cpu.model;
|
||||
if (cpuModel.length === 0) {
|
||||
cpuModel = "Unknown";
|
||||
}
|
||||
|
||||
text = "<b>CPU:</b> " + cpuModel;
|
||||
}
|
||||
}
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
text: "<b># CPUs:</b> " + PlatformInfo.getNumCPUs()
|
||||
Layout.preferredWidth: parent.width
|
||||
height: paintedHeight
|
||||
size: 16
|
||||
color: simplifiedUI.colors.text.white
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
text: "<b># CPU Cores:</b> " + PlatformInfo.getNumLogicalCores()
|
||||
Layout.preferredWidth: parent.width
|
||||
height: paintedHeight
|
||||
size: 16
|
||||
color: simplifiedUI.colors.text.white
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
text: "<b>RAM:</b> " + PlatformInfo.getTotalSystemMemoryMB() + " MB"
|
||||
Layout.preferredWidth: parent.width
|
||||
height: paintedHeight
|
||||
size: 16
|
||||
color: simplifiedUI.colors.text.white
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
text: "<b>GPU:</b> "
|
||||
Layout.preferredWidth: parent.width
|
||||
height: paintedHeight
|
||||
size: 16
|
||||
color: simplifiedUI.colors.text.white
|
||||
wrapMode: Text.Wrap
|
||||
|
||||
Component.onCompleted: {
|
||||
var gpu = JSON.parse(PlatformInfo.getGPU(PlatformInfo.getMasterGPU()));
|
||||
var gpuModel = gpu.model;
|
||||
if (gpuModel.length === 0) {
|
||||
gpuModel = "Unknown";
|
||||
}
|
||||
|
||||
text = "<b>GPU:</b> " + gpuModel;
|
||||
}
|
||||
}
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
text: "<b>VR Hand Controllers:</b> " + (PlatformInfo.hasRiftControllers() ? "Rift" : (PlatformInfo.hasViveControllers() ? "Vive" : "None"))
|
||||
Layout.preferredWidth: parent.width
|
||||
height: paintedHeight
|
||||
size: 16
|
||||
color: simplifiedUI.colors.text.white
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
// This is a bit of a hack to get the name of the currently-selected audio input device
|
||||
// in the current mode (Desktop or VR). The reason this is necessary is because it seems to me like
|
||||
// the only way one can get a human-readable list of the audio I/O devices is by using a ListView
|
||||
// and grabbing the names from the AudioScriptingInterface; you can't do it using a ListModel.
|
||||
// See `AudioDevices.h`, specifically the comment above the declaration of `QVariant data()`.
|
||||
ListView {
|
||||
id: audioInputDevices
|
||||
visible: false
|
||||
property string selectedInputDeviceName
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.preferredHeight: contentItem.height
|
||||
interactive: false
|
||||
delegate: Item {
|
||||
Component.onCompleted: {
|
||||
if (HMD.active && selectedHMD) {
|
||||
audioInputDevices.selectedInputDeviceName = model.devicename
|
||||
} else if (!HMD.active && selectedDesktop) {
|
||||
audioInputDevices.selectedInputDeviceName = model.devicename
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
text: "<b>Audio Input:</b> " + audioInputDevices.selectedInputDeviceName
|
||||
Layout.preferredWidth: parent.width
|
||||
height: paintedHeight
|
||||
size: 16
|
||||
color: simplifiedUI.colors.text.white
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
|
||||
// This is a bit of a hack to get the name of the currently-selected audio output device
|
||||
// in the current mode (Desktop or VR). The reason this is necessary is because it seems to me like
|
||||
// the only way one can get a human-readable list of the audio I/O devices is by using a ListView
|
||||
// and grabbing the names from the AudioScriptingInterface; you can't do it using a ListModel.
|
||||
// See `AudioDevices.h`, specifically the comment above the declaration of `QVariant data()`.
|
||||
ListView {
|
||||
id: audioOutputDevices
|
||||
visible: false
|
||||
property string selectedOutputDeviceName
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.preferredHeight: contentItem.height
|
||||
interactive: false
|
||||
delegate: Item {
|
||||
Component.onCompleted: {
|
||||
if (HMD.active && selectedHMD) {
|
||||
audioOutputDevices.selectedOutputDeviceName = model.devicename
|
||||
} else if (!HMD.active && selectedDesktop) {
|
||||
audioOutputDevices.selectedOutputDeviceName = model.devicename
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
text: "<b>Audio Output:</b> " + audioOutputDevices.selectedOutputDeviceName
|
||||
Layout.preferredWidth: parent.width
|
||||
height: paintedHeight
|
||||
size: 16
|
||||
color: simplifiedUI.colors.text.white
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
SimplifiedControls.Button {
|
||||
Layout.topMargin: 8
|
||||
width: 200
|
||||
height: 32
|
||||
text: "Copy to Clipboard"
|
||||
temporaryText: "Copied!"
|
||||
|
||||
onClicked: {
|
||||
Window.copyToClipboard(root.buildPlatformInfoTextToCopy());
|
||||
showTemporaryText();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function buildPlatformInfoTextToCopy() {
|
||||
var textToCopy = "**About Interface**\n";
|
||||
textToCopy += "Interface Version: " + Window.checkVersion() + "\n";
|
||||
textToCopy += "\n**Platform Info**\n";
|
||||
|
||||
var computer = JSON.parse(PlatformInfo.getComputer());
|
||||
var computerVendor = computer.vendor;
|
||||
if (computerVendor.length === 0) {
|
||||
computerVendor = "Unknown";
|
||||
}
|
||||
var computerModel = computer.model;
|
||||
if (computerModel.length === 0) {
|
||||
computerModel = "Unknown";
|
||||
}
|
||||
|
||||
textToCopy += "Computer Vendor/Model: " + computerVendor + "/" + computerModel + "\n";
|
||||
textToCopy += "Profiled Platform Tier: " + PlatformInfo.getTierProfiled() + "\n";
|
||||
textToCopy += "OS Type: " + PlatformInfo.getOperatingSystemType() + "\n";
|
||||
|
||||
var cpu = JSON.parse(PlatformInfo.getCPU(0));
|
||||
var cpuModel = cpu.model;
|
||||
if (cpuModel.length === 0) {
|
||||
cpuModel = "Unknown";
|
||||
}
|
||||
|
||||
textToCopy += "CPU: " + cpuModel + "\n";
|
||||
textToCopy += "# CPUs: " + PlatformInfo.getNumCPUs() + "\n";
|
||||
textToCopy += "# CPU Cores: " + PlatformInfo.getNumLogicalCores() + "\n";
|
||||
textToCopy += "RAM: " + PlatformInfo.getTotalSystemMemoryMB() + " MB\n";
|
||||
|
||||
var gpu = JSON.parse(PlatformInfo.getGPU(PlatformInfo.getMasterGPU()));
|
||||
var gpuModel = gpu.model;
|
||||
if (gpuModel.length === 0) {
|
||||
gpuModel = "Unknown";
|
||||
}
|
||||
|
||||
textToCopy += "GPU: " + gpuModel + "\n";
|
||||
textToCopy += "VR Hand Controllers: " + (PlatformInfo.hasRiftControllers() ? "Rift" : (PlatformInfo.hasViveControllers() ? "Vive" : "None")) + "\n";
|
||||
textToCopy += "Audio Input: " + audioInputDevices.selectedInputDeviceName + "\n";
|
||||
textToCopy += "Audio Output: " + audioOutputDevices.selectedOutputDeviceName + "\n";
|
||||
|
||||
textToCopy += "\n**All Platform Info**\n";
|
||||
textToCopy += JSON.stringify(JSON.parse(PlatformInfo.getPlatform()), null, 4);
|
||||
|
||||
return textToCopy;
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 16 KiB |
|
@ -225,10 +225,6 @@ StackView {
|
|||
verticalCenter: addressLineContainer.verticalCenter;
|
||||
}
|
||||
|
||||
onFocusChanged: {
|
||||
addressBarDialog.raised = focus;
|
||||
}
|
||||
|
||||
onTextChanged: {
|
||||
updateLocationText(text.length > 0);
|
||||
}
|
||||
|
|
|
@ -4235,12 +4235,43 @@ bool Application::event(QEvent* event) {
|
|||
}
|
||||
|
||||
bool Application::eventFilter(QObject* object, QEvent* event) {
|
||||
auto eventType = event->type();
|
||||
|
||||
if (_aboutToQuit && event->type() != QEvent::DeferredDelete && event->type() != QEvent::Destroy) {
|
||||
if (_aboutToQuit && eventType != QEvent::DeferredDelete && eventType != QEvent::Destroy) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto eventType = event->type();
|
||||
#if defined(Q_OS_MAC)
|
||||
// On Mac OS, Cmd+LeftClick is treated as a RightClick (more specifically, it seems to
|
||||
// be Cmd+RightClick without the modifier being dropped). Starting in Qt 5.12, only
|
||||
// on Mac, the MouseButtonRelease event for these mouse presses is sent to the top
|
||||
// level QWidgetWindow, but are not propagated further. This means that the Application
|
||||
// will see a MouseButtonPress, but no MouseButtonRelease, causing the client to get
|
||||
// stuck in "mouse-look." The cause of the problem is in the way QWidgetWindow processes
|
||||
// events where QMouseEvent::button() is not equal to QMouseEvent::buttons(). In this case
|
||||
// QMouseEvent::button() is Qt::RightButton, while QMouseEvent::buttons() is (correctly?)
|
||||
// Qt::LeftButton.
|
||||
//
|
||||
// The change here gets around this problem by capturing these
|
||||
// pseudo-RightClicks, and re-emitting them as "pure" RightClicks, where
|
||||
// QMouseEvent::button() == QMouseEvent::buttons() == Qt::RightButton.
|
||||
//
|
||||
if (eventType == QEvent::MouseButtonPress) {
|
||||
auto mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
if (mouseEvent->button() == Qt::RightButton
|
||||
&& mouseEvent->buttons() == Qt::LeftButton
|
||||
&& mouseEvent->modifiers() == Qt::MetaModifier) {
|
||||
|
||||
QMouseEvent* newEvent = new QMouseEvent(
|
||||
QEvent::MouseButtonPress, mouseEvent->localPos(), mouseEvent->windowPos(),
|
||||
mouseEvent->screenPos(), Qt::RightButton, Qt::MouseButtons(Qt::RightButton),
|
||||
mouseEvent->modifiers());
|
||||
QApplication::postEvent(object, newEvent);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (eventType == QEvent::KeyPress || eventType == QEvent::KeyRelease || eventType == QEvent::MouseMove) {
|
||||
getRefreshRateManager().resetInactiveTimer();
|
||||
}
|
||||
|
|
|
@ -6245,31 +6245,43 @@ void MyAvatar::setSitDriveKeysStatus(bool enabled) {
|
|||
}
|
||||
|
||||
void MyAvatar::beginSit(const glm::vec3& position, const glm::quat& rotation) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "beginSit", Q_ARG(glm::vec3, position), Q_ARG(glm::quat, rotation));
|
||||
return;
|
||||
}
|
||||
|
||||
_characterController.setSeated(true);
|
||||
setCollisionsEnabled(false);
|
||||
setCollisionsEnabled(false);
|
||||
setHMDLeanRecenterEnabled(false);
|
||||
// Disable movement
|
||||
setSitDriveKeysStatus(false);
|
||||
centerBody();
|
||||
int hipIndex = getJointIndex("Hips");
|
||||
clearPinOnJoint(hipIndex);
|
||||
goToLocation(position, true, rotation, false, false);
|
||||
pinJoint(hipIndex, position, rotation);
|
||||
}
|
||||
|
||||
void MyAvatar::endSit(const glm::vec3& position, const glm::quat& rotation) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "endSit", Q_ARG(glm::vec3, position), Q_ARG(glm::quat, rotation));
|
||||
return;
|
||||
}
|
||||
|
||||
if (_characterController.getSeated()) {
|
||||
clearPinOnJoint(getJointIndex("Hips"));
|
||||
_characterController.setSeated(false);
|
||||
setCollisionsEnabled(true);
|
||||
setHMDLeanRecenterEnabled(true);
|
||||
centerBody();
|
||||
goToLocation(position, true, rotation, false, false);
|
||||
slamPosition(position);
|
||||
setWorldOrientation(rotation);
|
||||
|
||||
// the jump key is used to exit the chair. We add a delay here to prevent
|
||||
// the avatar from jumping right as they exit the chair.
|
||||
float TIME_BEFORE_DRIVE_ENABLED_MS = 150.0f;
|
||||
QTimer::singleShot(TIME_BEFORE_DRIVE_ENABLED_MS, [this]() {
|
||||
// Enable movement again
|
||||
setSitDriveKeysStatus(true);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1866,6 +1866,9 @@ public:
|
|||
// also clears internal reaction triggers
|
||||
void updateRigControllerParameters(Rig::ControllerParameters& params);
|
||||
|
||||
// Don't substitute verify-fail:
|
||||
virtual const QUrl& getSkeletonModelURL() const override { return _skeletonModelURL; }
|
||||
|
||||
public slots:
|
||||
|
||||
/**jsdoc
|
||||
|
|
|
@ -830,9 +830,14 @@ void Wallet::handleChallengeOwnershipPacket(QSharedPointer<ReceivedMessage> pack
|
|||
}
|
||||
|
||||
void Wallet::sendChallengeOwnershipResponses() {
|
||||
if (_pendingChallenges.size() == 0 || getSalt().length() == 0) {
|
||||
if (_pendingChallenges.size() == 0) {
|
||||
return;
|
||||
}
|
||||
if (getSalt().length() == 0) {
|
||||
qCDebug(commerce) << "Not responding to ownership challenge due to missing Wallet salt";
|
||||
return;
|
||||
}
|
||||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
EC_KEY* ec = readKeys(keyFilePath());
|
||||
|
|
|
@ -1144,6 +1144,11 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
|||
_desiredStateAge = STATE_CHANGE_HYSTERESIS_TIMER;
|
||||
}
|
||||
|
||||
// Skip hysterisis timer for sit transitions.
|
||||
if (_desiredState == RigRole::Seated || _state == RigRole::Seated) {
|
||||
_desiredStateAge = STATE_CHANGE_HYSTERESIS_TIMER;
|
||||
}
|
||||
|
||||
if ((_desiredStateAge >= STATE_CHANGE_HYSTERESIS_TIMER) && _desiredState != _state) {
|
||||
_state = _desiredState;
|
||||
_desiredStateAge = 0.0f;
|
||||
|
@ -1223,6 +1228,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
|||
_animVars.set("isInAirRun", false);
|
||||
_animVars.set("isNotInAir", true);
|
||||
_animVars.set("isSeated", false);
|
||||
_animVars.set("isNotSeated", true);
|
||||
|
||||
} else if (_state == RigRole::Turn) {
|
||||
if (turningSpeed > 0.0f) {
|
||||
|
@ -1252,6 +1258,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
|||
_animVars.set("isInAirRun", false);
|
||||
_animVars.set("isNotInAir", true);
|
||||
_animVars.set("isSeated", false);
|
||||
_animVars.set("isNotSeated", true);
|
||||
|
||||
} else if (_state == RigRole::Idle) {
|
||||
// default anim vars to notMoving and notTurning
|
||||
|
@ -1274,6 +1281,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
|||
_animVars.set("isInAirRun", false);
|
||||
_animVars.set("isNotInAir", true);
|
||||
_animVars.set("isSeated", false);
|
||||
_animVars.set("isNotSeated", true);
|
||||
|
||||
} else if (_state == RigRole::Hover) {
|
||||
// flying.
|
||||
|
@ -1296,6 +1304,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
|||
_animVars.set("isInAirRun", false);
|
||||
_animVars.set("isNotInAir", true);
|
||||
_animVars.set("isSeated", false);
|
||||
_animVars.set("isNotSeated", true);
|
||||
|
||||
} else if (_state == RigRole::Takeoff) {
|
||||
// jumping in-air
|
||||
|
@ -1326,6 +1335,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
|||
_animVars.set("isInAirRun", false);
|
||||
_animVars.set("isNotInAir", false);
|
||||
_animVars.set("isSeated", false);
|
||||
_animVars.set("isNotSeated", true);
|
||||
|
||||
} else if (_state == RigRole::InAir) {
|
||||
// jumping in-air
|
||||
|
@ -1345,6 +1355,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
|||
_animVars.set("isTakeoffRun", false);
|
||||
_animVars.set("isNotTakeoff", true);
|
||||
_animVars.set("isSeated", false);
|
||||
_animVars.set("isNotSeated", true);
|
||||
|
||||
bool inAirRun = forwardSpeed > 0.1f;
|
||||
if (inAirRun) {
|
||||
|
@ -1386,6 +1397,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
|||
_animVars.set("isInAirRun", false);
|
||||
_animVars.set("isNotInAir", true);
|
||||
_animVars.set("isSeated", true);
|
||||
_animVars.set("isNotSeated", false);
|
||||
}
|
||||
|
||||
t += deltaTime;
|
||||
|
@ -1821,8 +1833,10 @@ void Rig::updateFeet(bool leftFootEnabled, bool rightFootEnabled, bool headEnabl
|
|||
int hipsIndex = indexOfJoint("Hips");
|
||||
const float KNEE_POLE_VECTOR_BLEND_FACTOR = 0.85f;
|
||||
|
||||
if (headEnabled) {
|
||||
// always do IK if head is enabled
|
||||
bool isSeated = _state == RigRole::Seated;
|
||||
|
||||
if (headEnabled && !isSeated) {
|
||||
// enable leg IK if head is enabled and we arent sitting down.
|
||||
_animVars.set("leftFootIKEnabled", true);
|
||||
_animVars.set("rightFootIKEnabled", true);
|
||||
} else {
|
||||
|
|
|
@ -131,7 +131,7 @@ AvatarTransit::Status AvatarTransit::update(float deltaTime, const glm::vec3& av
|
|||
} else {
|
||||
_lastPosition = avatarPosition;
|
||||
_status = Status::ABORT_TRANSIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
_lastPosition = avatarPosition;
|
||||
_status = updatePosition(deltaTime);
|
||||
|
@ -143,11 +143,18 @@ AvatarTransit::Status AvatarTransit::update(float deltaTime, const glm::vec3& av
|
|||
return _status;
|
||||
}
|
||||
|
||||
void AvatarTransit::slamPosition(const glm::vec3& avatarPosition) {
|
||||
// used to instantly teleport between two points without triggering a change in status.
|
||||
_lastPosition = avatarPosition;
|
||||
_endPosition = avatarPosition;
|
||||
}
|
||||
|
||||
void AvatarTransit::reset() {
|
||||
_lastPosition = _endPosition;
|
||||
_currentPosition = _endPosition;
|
||||
_isActive = false;
|
||||
}
|
||||
|
||||
void AvatarTransit::start(float deltaTime, const glm::vec3& startPosition, const glm::vec3& endPosition, const AvatarTransit::TransitConfig& config) {
|
||||
_startPosition = startPosition;
|
||||
_endPosition = endPosition;
|
||||
|
@ -192,8 +199,8 @@ AvatarTransit::Status AvatarTransit::updatePosition(float deltaTime) {
|
|||
status = Status::PRE_TRANSIT;
|
||||
if (_currentTime == 0) {
|
||||
status = Status::STARTED;
|
||||
}
|
||||
} else if (nextTime < _totalTime - _postTransitTime){
|
||||
}
|
||||
} else if (nextTime < _totalTime - _postTransitTime) {
|
||||
status = Status::TRANSITING;
|
||||
if (_currentTime <= _preTransitTime) {
|
||||
status = Status::START_TRANSIT;
|
||||
|
@ -519,10 +526,10 @@ void Avatar::relayJointDataToChildren() {
|
|||
* <tbody>
|
||||
* <tr><td><code>"avatar" or ""</code></td><td>The rate at which the avatar is updated even if not in view.</td></tr>
|
||||
* <tr><td><code>"avatarInView"</code></td><td>The rate at which the avatar is updated if in view.</td></tr>
|
||||
* <tr><td><code>"skeletonModel"</code></td><td>The rate at which the skeleton model is being updated, even if there are no
|
||||
* <tr><td><code>"skeletonModel"</code></td><td>The rate at which the skeleton model is being updated, even if there are no
|
||||
* joint data available.</td></tr>
|
||||
* <tr><td><code>"jointData"</code></td><td>The rate at which joint data are being updated.</td></tr>
|
||||
* <tr><td><code>""</code></td><td>When no rate name is specified, the <code>"avatar"</code> update rate is
|
||||
* <tr><td><code>""</code></td><td>When no rate name is specified, the <code>"avatar"</code> update rate is
|
||||
* provided.</td></tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
|
@ -557,6 +564,7 @@ void Avatar::slamPosition(const glm::vec3& newPosition) {
|
|||
_positionDeltaAccumulator = glm::vec3(0.0f);
|
||||
setWorldVelocity(glm::vec3(0.0f));
|
||||
_lastVelocity = glm::vec3(0.0f);
|
||||
_transit.slamPosition(newPosition);
|
||||
}
|
||||
|
||||
void Avatar::updateAttitude(const glm::quat& orientation) {
|
||||
|
@ -1511,7 +1519,7 @@ void Avatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
|
|||
}
|
||||
indicateLoadingStatus(LoadingStatus::LoadModel);
|
||||
|
||||
_skeletonModel->setURL(_skeletonModelURL);
|
||||
_skeletonModel->setURL(getSkeletonModelURL());
|
||||
}
|
||||
|
||||
void Avatar::setModelURLFinished(bool success) {
|
||||
|
@ -1533,7 +1541,7 @@ void Avatar::setModelURLFinished(bool success) {
|
|||
QMetaObject::invokeMethod(_skeletonModel.get(), "setURL",
|
||||
Qt::QueuedConnection, Q_ARG(QUrl, AvatarData::defaultFullAvatarModelUrl()));
|
||||
} else {
|
||||
qCWarning(avatars_renderer) << "Avatar model failed to load... attempts:"
|
||||
qCWarning(avatars_renderer) << "Avatar model failed to load... attempts:"
|
||||
<< _skeletonModel->getResourceDownloadAttempts() << "out of:" << MAX_SKELETON_DOWNLOAD_ATTEMPTS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,6 +93,7 @@ public:
|
|||
|
||||
AvatarTransit() {};
|
||||
Status update(float deltaTime, const glm::vec3& avatarPosition, const TransitConfig& config);
|
||||
void slamPosition(const glm::vec3& avatarPosition);
|
||||
Status getStatus() { return _status; }
|
||||
bool isActive() { return _isActive; }
|
||||
glm::vec3 getCurrentPosition() { return _currentPosition; }
|
||||
|
|
|
@ -1988,7 +1988,11 @@ void AvatarData::processAvatarIdentity(QDataStream& packetStream, bool& identity
|
|||
if (flagValue != _verificationFailed) {
|
||||
_verificationFailed = flagValue;
|
||||
identityChanged = true;
|
||||
}
|
||||
setSkeletonModelURL(_skeletonModelURL);
|
||||
if (_verificationFailed) {
|
||||
qCDebug(avatars) << "Avatar" << getSessionDisplayName() << "marked as VERIFY-FAILED";
|
||||
}
|
||||
};
|
||||
|
||||
if (identity.attachmentData != _attachmentData) {
|
||||
setAttachmentData(identity.attachmentData);
|
||||
|
@ -2016,6 +2020,18 @@ QUrl AvatarData::getWireSafeSkeletonModelURL() const {
|
|||
return QUrl();
|
||||
}
|
||||
}
|
||||
|
||||
static const QString VERIFY_FAIL_MODEL { "/meshes/verifyFailed.fst" };
|
||||
|
||||
const QUrl& AvatarData::getSkeletonModelURL() const {
|
||||
if (_verificationFailed) {
|
||||
static QUrl VERIFY_FAIL_MODEL_URL = PathUtils::resourcesUrl(VERIFY_FAIL_MODEL);
|
||||
return VERIFY_FAIL_MODEL_URL;
|
||||
} else {
|
||||
return _skeletonModelURL;
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray AvatarData::packSkeletonData() const {
|
||||
// Send an avatar trait packet with the skeleton data before the mesh is loaded
|
||||
int avatarDataSize = 0;
|
||||
|
|
|
@ -1205,7 +1205,7 @@ public:
|
|||
QByteArray identityByteArray(bool setIsReplicated = false) const;
|
||||
|
||||
QUrl getWireSafeSkeletonModelURL() const;
|
||||
const QUrl& getSkeletonModelURL() const { return _skeletonModelURL; }
|
||||
virtual const QUrl& getSkeletonModelURL() const;
|
||||
|
||||
const QString& getDisplayName() const { return _displayName; }
|
||||
const QString& getSessionDisplayName() const { return _sessionDisplayName; }
|
||||
|
|
|
@ -330,10 +330,6 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer<ReceivedMessage>
|
|||
bool displayNameChanged = false;
|
||||
// In this case, the "sendingNode" is the Avatar Mixer.
|
||||
avatar->processAvatarIdentity(avatarIdentityStream, identityChanged, displayNameChanged);
|
||||
if (avatar->isCertifyFailed() && identityUUID != EMPTY) {
|
||||
qCDebug(avatars) << "Avatar" << avatar->getSessionDisplayName() << "marked as VERIFY-FAILED";
|
||||
avatar->setSkeletonModelURL(PathUtils::resourcesUrl(VERIFY_FAIL_MODEL));
|
||||
}
|
||||
_replicas.processAvatarIdentity(identityUUID, message->getMessage(), identityChanged, displayNameChanged);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -239,7 +239,7 @@
|
|||
<?js typedefs.forEach(function(e) {
|
||||
if (e.signature) {
|
||||
?>
|
||||
<?js= self.partial('members.tmpl', e) ?>
|
||||
<?js= self.partial('method.tmpl', e) ?>
|
||||
<?js
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -13,7 +13,10 @@ var self = this;
|
|||
<?js returns.forEach(function(r) { ?>
|
||||
<?js= self.partial('returns.tmpl', r) ?>
|
||||
<?js });
|
||||
} ?></span>
|
||||
} ?></span>
|
||||
<?js if (data.kind === 'typedef' && data.type && data.type.names) { ?>
|
||||
<br />Type: <?js= self.partial('type.tmpl', data.type.names) ?>
|
||||
<?js } ?>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -63,7 +66,7 @@ var self = this;
|
|||
<?js= self.partial('augments.tmpl', data) ?>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (kind === 'event' && data.type && data.type.names) {?>
|
||||
<?js if (data.kind === 'event' && data.type && data.type.names) {?>
|
||||
<h5>Type:</h5>
|
||||
<ul>
|
||||
<li>
|
||||
|
|
Loading…
Reference in a new issue