diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index f09caac4b6..f3da74ce5e 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -200,7 +200,7 @@ void AvatarMixer::manageDisplayName(const SharedNodePointer& node) { QString baseName = avatar.getDisplayName().trimmed(); const QRegularExpression curses { "fuck|shit|damn|cock|cunt" }; // POC. We may eventually want something much more elaborate (subscription?). baseName = baseName.replace(curses, "*"); // Replace rather than remove, so that people have a clue that the person's a jerk. - const QRegularExpression trailingDigits { "\\s*_\\d+$" }; // whitespace "_123" + const QRegularExpression trailingDigits { "\\s*(_\\d+\\s*)?(\\s*\\n[^$]*)?$" }; // trailing whitespace "_123" and any subsequent lines baseName = baseName.remove(trailingDigits); if (baseName.isEmpty()) { baseName = "anonymous"; diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 726aa7ef84..ac44be18f2 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -192,7 +192,7 @@ link_hifi_libraries( shared octree ktx gpu gl gpu-gl procedural model render recording fbx networking model-networking entities avatars audio audio-client animation script-engine physics - render-utils entities-renderer ui auto-updater + render-utils entities-renderer avatars-renderer ui auto-updater controllers plugins ui-plugins display-plugins input-plugins ${NON_ANDROID_LIBRARIES} diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml index 17e6578e4d..d6459afd08 100644 --- a/interface/resources/qml/Stats.qml +++ b/interface/resources/qml/Stats.qml @@ -130,7 +130,7 @@ Item { id: pingCol spacing: 4; x: 4; y: 4; StatText { - text: "Audio ping: " + root.audioPing + text: "Audio ping/loss: " + root.audioPing + "/" + root.audioPacketLoss + "%" } StatText { text: "Avatar ping: " + root.avatarPing diff --git a/interface/resources/qml/hifi/NameCard.qml b/interface/resources/qml/hifi/NameCard.qml index 3343cec26f..6be85f2ea6 100644 --- a/interface/resources/qml/hifi/NameCard.qml +++ b/interface/resources/qml/hifi/NameCard.qml @@ -302,7 +302,7 @@ Item { height: usernameTextPixelSize + 4 // Anchors anchors.top: isMyCard ? myDisplayName.bottom : pal.activeTab == "nearbyTab" ? displayNameContainer.bottom : undefined //(parent.height - displayNameTextPixelSize/2)); - anchors.verticalCenter: pal.activeTab == "connectionsTab" ? avatarImage.verticalCenter : undefined + anchors.verticalCenter: pal.activeTab == "connectionsTab" && !isMyCard ? avatarImage.verticalCenter : undefined anchors.left: avatarImage.right; anchors.leftMargin: avatarImage.visible ? 5 : 0; anchors.rightMargin: 5; diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index cedcb923d9..dc612b0129 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -126,7 +126,7 @@ void Stats::updateStats(bool force) { STAT_UPDATE(updatedAvatarCount, avatarManager->getNumAvatarsUpdated()); STAT_UPDATE(notUpdatedAvatarCount, avatarManager->getNumAvatarsNotUpdated()); STAT_UPDATE(serverCount, (int)nodeList->size()); - STAT_UPDATE(framerate, qApp->getFps()); + STAT_UPDATE_FLOAT(framerate, qApp->getFps(), 0.1f); if (qApp->getActiveDisplayPlugin()) { auto displayPlugin = qApp->getActiveDisplayPlugin(); auto stats = displayPlugin->getHardwareStats(); @@ -134,11 +134,11 @@ void Stats::updateStats(bool force) { STAT_UPDATE(longrenders, stats["long_render_count"].toInt()); STAT_UPDATE(longsubmits, stats["long_submit_count"].toInt()); STAT_UPDATE(longframes, stats["long_frame_count"].toInt()); - STAT_UPDATE(renderrate, displayPlugin->renderRate()); - STAT_UPDATE(presentrate, displayPlugin->presentRate()); - STAT_UPDATE(presentnewrate, displayPlugin->newFramePresentRate()); - STAT_UPDATE(presentdroprate, displayPlugin->droppedFrameRate()); - STAT_UPDATE(stutterrate, displayPlugin->stutterRate()); + STAT_UPDATE_FLOAT(renderrate, displayPlugin->renderRate(), 0.1f); + STAT_UPDATE_FLOAT(presentrate, displayPlugin->presentRate(), 0.1f); + STAT_UPDATE_FLOAT(presentnewrate, displayPlugin->newFramePresentRate(), 0.1f); + STAT_UPDATE_FLOAT(presentdroprate, displayPlugin->droppedFrameRate(), 0.1f); + STAT_UPDATE_FLOAT(stutterrate, displayPlugin->stutterRate(), 0.1f); } else { STAT_UPDATE(appdropped, -1); STAT_UPDATE(longrenders, -1); @@ -151,8 +151,8 @@ void Stats::updateStats(bool force) { STAT_UPDATE(avatarSimrate, (int)qApp->getAvatarSimrate()); auto bandwidthRecorder = DependencyManager::get(); - STAT_UPDATE(packetInCount, bandwidthRecorder->getCachedTotalAverageInputPacketsPerSecond()); - STAT_UPDATE(packetOutCount, bandwidthRecorder->getCachedTotalAverageOutputPacketsPerSecond()); + STAT_UPDATE(packetInCount, (int)bandwidthRecorder->getCachedTotalAverageInputPacketsPerSecond()); + STAT_UPDATE(packetOutCount, (int)bandwidthRecorder->getCachedTotalAverageOutputPacketsPerSecond()); STAT_UPDATE_FLOAT(mbpsIn, (float)bandwidthRecorder->getCachedTotalAverageInputKilobitsPerSecond() / 1000.0f, 0.01f); STAT_UPDATE_FLOAT(mbpsOut, (float)bandwidthRecorder->getCachedTotalAverageOutputKilobitsPerSecond() / 1000.0f, 0.01f); @@ -164,7 +164,11 @@ void Stats::updateStats(bool force) { SharedNodePointer avatarMixerNode = nodeList->soloNodeOfType(NodeType::AvatarMixer); SharedNodePointer assetServerNode = nodeList->soloNodeOfType(NodeType::AssetServer); SharedNodePointer messageMixerNode = nodeList->soloNodeOfType(NodeType::MessagesMixer); - STAT_UPDATE(audioPing, audioMixerNode ? audioMixerNode->getPingMs() : -1); + STAT_UPDATE(audioPing, audioMixerNode ? audioMixerNode->getPingMs() : -1); + const int mixerLossRate = (int)roundf(_audioStats->data()->getMixerStream()->lossRateWindow() * 100.0f); + const int clientLossRate = (int)roundf(_audioStats->data()->getClientStream()->lossRateWindow() * 100.0f); + const int largestLossRate = mixerLossRate > clientLossRate ? mixerLossRate : clientLossRate; + STAT_UPDATE(audioPacketLoss, audioMixerNode ? largestLossRate : -1); STAT_UPDATE(avatarPing, avatarMixerNode ? avatarMixerNode->getPingMs() : -1); STAT_UPDATE(assetPing, assetServerNode ? assetServerNode->getPingMs() : -1); STAT_UPDATE(messagePing, messageMixerNode ? messageMixerNode->getPingMs() : -1); @@ -196,36 +200,36 @@ void Stats::updateStats(bool force) { if (_expanded || force) { SharedNodePointer avatarMixer = nodeList->soloNodeOfType(NodeType::AvatarMixer); if (avatarMixer) { - STAT_UPDATE(avatarMixerInKbps, roundf(bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AvatarMixer))); - STAT_UPDATE(avatarMixerInPps, roundf(bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AvatarMixer))); - STAT_UPDATE(avatarMixerOutKbps, roundf(bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AvatarMixer))); - STAT_UPDATE(avatarMixerOutPps, roundf(bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AvatarMixer))); + STAT_UPDATE(avatarMixerInKbps, (int)roundf(bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AvatarMixer))); + STAT_UPDATE(avatarMixerInPps, (int)roundf(bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AvatarMixer))); + STAT_UPDATE(avatarMixerOutKbps, (int)roundf(bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AvatarMixer))); + STAT_UPDATE(avatarMixerOutPps, (int)roundf(bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AvatarMixer))); } else { STAT_UPDATE(avatarMixerInKbps, -1); STAT_UPDATE(avatarMixerInPps, -1); STAT_UPDATE(avatarMixerOutKbps, -1); STAT_UPDATE(avatarMixerOutPps, -1); } - STAT_UPDATE(myAvatarSendRate, avatarManager->getMyAvatarSendRate()); + STAT_UPDATE_FLOAT(myAvatarSendRate, avatarManager->getMyAvatarSendRate(), 0.1f); SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer); auto audioClient = DependencyManager::get(); if (audioMixerNode || force) { - STAT_UPDATE(audioMixerKbps, roundf( + STAT_UPDATE(audioMixerKbps, (int)roundf( bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AudioMixer) + bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AudioMixer))); - STAT_UPDATE(audioMixerPps, roundf( + STAT_UPDATE(audioMixerPps, (int)roundf( bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AudioMixer) + bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AudioMixer))); - STAT_UPDATE(audioMixerInKbps, roundf(bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AudioMixer))); - STAT_UPDATE(audioMixerInPps, roundf(bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AudioMixer))); - STAT_UPDATE(audioMixerOutKbps, roundf(bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AudioMixer))); - STAT_UPDATE(audioMixerOutPps, roundf(bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AudioMixer))); - STAT_UPDATE(audioAudioInboundPPS, audioClient->getAudioInboundPPS()); - STAT_UPDATE(audioSilentInboundPPS, audioClient->getSilentInboundPPS()); - STAT_UPDATE(audioOutboundPPS, audioClient->getAudioOutboundPPS()); - STAT_UPDATE(audioSilentOutboundPPS, audioClient->getSilentOutboundPPS()); + STAT_UPDATE(audioMixerInKbps, (int)roundf(bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AudioMixer))); + STAT_UPDATE(audioMixerInPps, (int)roundf(bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AudioMixer))); + STAT_UPDATE(audioMixerOutKbps, (int)roundf(bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AudioMixer))); + STAT_UPDATE(audioMixerOutPps, (int)roundf(bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AudioMixer))); + STAT_UPDATE(audioAudioInboundPPS, (int)audioClient->getAudioInboundPPS()); + STAT_UPDATE(audioSilentInboundPPS, (int)audioClient->getSilentInboundPPS()); + STAT_UPDATE(audioOutboundPPS, (int)audioClient->getAudioOutboundPPS()); + STAT_UPDATE(audioSilentOutboundPPS, (int)audioClient->getSilentOutboundPPS()); } else { STAT_UPDATE(audioMixerKbps, -1); STAT_UPDATE(audioMixerPps, -1); diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index a93a255a06..85cf2caab9 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -81,6 +81,7 @@ class Stats : public QQuickItem { STATS_PROPERTY(int, audioSilentOutboundPPS, 0) STATS_PROPERTY(int, audioAudioInboundPPS, 0) STATS_PROPERTY(int, audioSilentInboundPPS, 0) + STATS_PROPERTY(int, audioPacketLoss, 0) STATS_PROPERTY(QString, audioCodec, QString()) STATS_PROPERTY(QString, audioNoiseGate, QString()) @@ -204,6 +205,7 @@ signals: void audioSilentOutboundPPSChanged(); void audioAudioInboundPPSChanged(); void audioSilentInboundPPSChanged(); + void audioPacketLossChanged(); void audioCodecChanged(); void audioNoiseGateChanged(); @@ -263,4 +265,3 @@ private: }; #endif // hifi_Stats_h - diff --git a/libraries/avatars-renderer/CMakeLists.txt b/libraries/avatars-renderer/CMakeLists.txt new file mode 100644 index 0000000000..bee2cb31d6 --- /dev/null +++ b/libraries/avatars-renderer/CMakeLists.txt @@ -0,0 +1,6 @@ +set(TARGET_NAME avatars-renderer) +AUTOSCRIBE_SHADER_LIB(gpu model render render-utils) +setup_hifi_library(Widgets Network Script) +link_hifi_libraries(shared gpu model animation physics model-networking script-engine render render-utils) + +target_bullet() diff --git a/libraries/avatars-renderer/src/AvatarsRendererLogging.cpp b/libraries/avatars-renderer/src/AvatarsRendererLogging.cpp new file mode 100644 index 0000000000..2804df1b7a --- /dev/null +++ b/libraries/avatars-renderer/src/AvatarsRendererLogging.cpp @@ -0,0 +1,11 @@ +// +// Created by Bradley Austin Davis on 2016/12/06 +// Copyright 2013-2016 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 +// + +#include "AvatarsRendererLogging.h" + +Q_LOGGING_CATEGORY(avatars_renderer, "hifi.avatars.rendering") diff --git a/libraries/avatars-renderer/src/AvatarsRendererLogging.h b/libraries/avatars-renderer/src/AvatarsRendererLogging.h new file mode 100644 index 0000000000..a1cfd8d9e4 --- /dev/null +++ b/libraries/avatars-renderer/src/AvatarsRendererLogging.h @@ -0,0 +1,16 @@ +// +// Created by Bradley Austin Davis on 2016/12/06 +// Copyright 2013-2016 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 +// + +#ifndef hifi_AvatarsRendererLogging_h +#define hifi_AvatarsRendererLogging_h + +#include + +Q_DECLARE_LOGGING_CATEGORY(avatars_renderer) + +#endif // hifi_AvatarsRendererLogging_h diff --git a/libraries/gl/src/gl/OffscreenGLCanvas.cpp b/libraries/gl/src/gl/OffscreenGLCanvas.cpp index e5c630d97e..3f1d629638 100644 --- a/libraries/gl/src/gl/OffscreenGLCanvas.cpp +++ b/libraries/gl/src/gl/OffscreenGLCanvas.cpp @@ -59,8 +59,6 @@ bool OffscreenGLCanvas::create(QOpenGLContext* sharedContext) { bool OffscreenGLCanvas::makeCurrent() { bool result = _context->makeCurrent(_offscreenSurface); - Q_ASSERT(result); - std::call_once(_reportOnce, [this]{ qCDebug(glLogging) << "GL Version: " << QString((const char*) glGetString(GL_VERSION)); qCDebug(glLogging) << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)); diff --git a/libraries/gl/src/gl/OffscreenQmlSurface.cpp b/libraries/gl/src/gl/OffscreenQmlSurface.cpp index 16e32ab42e..3bbd26e010 100644 --- a/libraries/gl/src/gl/OffscreenQmlSurface.cpp +++ b/libraries/gl/src/gl/OffscreenQmlSurface.cpp @@ -612,11 +612,7 @@ QObject* OffscreenQmlSurface::finishQmlLoad(std::functionmetaObject()->indexOfSignal("sendToScript"); - if (sendToScriptIndex != -1) { - connect(newItem, SIGNAL(sendToScript(QVariant)), this, SIGNAL(fromQml(QVariant))); - } + connect(newItem, SIGNAL(sendToScript(QVariant)), this, SIGNAL(fromQml(QVariant))); // The root item is ready. Associate it with the window. _rootItem = newItem; diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index e1b432d09f..d1c00a9d81 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -1094,7 +1094,6 @@ function MyController(hand) { this.grabbedOverlay = null; this.state = STATE_OFF; this.pointer = null; // entity-id of line object - this.entityActivated = false; this.triggerValue = 0; // rolling average of trigger value this.triggerClicked = false; @@ -2826,12 +2825,6 @@ function MyController(hand) { Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); - if (this.entityActivated) { - var saveGrabbedID = this.grabbedThingID; - this.release(); - this.grabbedThingID = saveGrabbedID; - } - var grabbedProperties; if (this.grabbedIsOverlay) { grabbedProperties = { @@ -3007,22 +3000,25 @@ function MyController(hand) { * is called correctly, as these just freshly created entity may not have completely initialized. */ var grabEquipCheck = function () { - if (_this.state == STATE_NEAR_GRABBING) { - _this.callEntityMethodOnGrabbed("startNearGrab"); + if (_this.state == STATE_NEAR_GRABBING) { + _this.callEntityMethodOnGrabbed("startNearGrab"); } else { // this.state == STATE_HOLD - _this.callEntityMethodOnGrabbed("startEquip"); + _this.callEntityMethodOnGrabbed("startEquip"); } - _this.currentHandControllerTipPosition = - (_this.hand === RIGHT_HAND) ? MyAvatar.rightHandTipPosition : MyAvatar.leftHandTipPosition; - _this.currentObjectTime = Date.now(); + // don't block teleport raypick with equipped entity + Messages.sendMessage('Hifi-Teleport-Ignore-Add', _this.grabbedThingID); - _this.currentObjectPosition = grabbedProperties.position; - _this.currentObjectRotation = grabbedProperties.rotation; - _this.currentVelocity = ZERO_VEC; - _this.currentAngularVelocity = ZERO_VEC; + _this.currentHandControllerTipPosition = + (_this.hand === RIGHT_HAND) ? MyAvatar.rightHandTipPosition : MyAvatar.leftHandTipPosition; + _this.currentObjectTime = Date.now(); - _this.prevDropDetected = false; + _this.currentObjectPosition = grabbedProperties.position; + _this.currentObjectRotation = grabbedProperties.rotation; + _this.currentVelocity = ZERO_VEC; + _this.currentAngularVelocity = ZERO_VEC; + + _this.prevDropDetected = false; } if (isClone) { @@ -3654,6 +3650,9 @@ function MyController(hand) { this.turnOffVisualizations(); if (this.grabbedThingID !== null) { + + Messages.sendMessage('Hifi-Teleport-Ignore-Remove', this.grabbedThingID); + if (this.state === STATE_HOLD) { this.callEntityMethodOnGrabbed("releaseEquip"); }