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

This commit is contained in:
dooglife@gmail.com 2019-08-21 08:46:59 -07:00
commit ec06a02fdf
21 changed files with 241 additions and 436 deletions

View file

@ -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()) {

View file

@ -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"
}
]
}
]
},

View file

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

View file

@ -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");
}
}
}

View file

@ -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);
}

View file

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

View file

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

View file

@ -225,10 +225,6 @@ StackView {
verticalCenter: addressLineContainer.verticalCenter;
}
onFocusChanged: {
addressBarDialog.raised = focus;
}
onTextChanged: {
updateLocationText(text.length > 0);
}

View file

@ -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();
}

View file

@ -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);
});
}
}
}

View file

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

View file

@ -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());

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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);
}
}

View file

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

View file

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