From 2af92ca3790809a8c5c2fe2e72ac8362ddbccb92 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 2 Jun 2016 16:56:35 -0700 Subject: [PATCH 01/66] Adding a turntable script --- .../developer/utilities/render/turntable.js | 68 +++++++++++++++++++ .../developer/utilities/render/turntable.qml | 30 ++++++++ 2 files changed, 98 insertions(+) create mode 100644 scripts/developer/utilities/render/turntable.js create mode 100644 scripts/developer/utilities/render/turntable.qml diff --git a/scripts/developer/utilities/render/turntable.js b/scripts/developer/utilities/render/turntable.js new file mode 100644 index 0000000000..dcc6dcd0e0 --- /dev/null +++ b/scripts/developer/utilities/render/turntable.js @@ -0,0 +1,68 @@ +// +// turntable.js +// developer/utilities/render +// +// Sam Gateau, created on 6/2/2016. +// Copyright 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 +// + +// Set up the qml ui +var qml = Script.resolvePath('turntable.qml'); +var window = new OverlayWindow({ + title: 'Turntable', + source: qml, + width: 320, + height: 320 +}); +window.setPosition(500, 500); +window.closed.connect(function() { Script.stop(); }); + + + +function findClickedEntity(event) { + var pickZones = event.isControl; + + if (pickZones) { + Entities.setZonesArePickable(true); + } + + var pickRay = Camera.computePickRay(event.x, event.y); + + var entityResult = Entities.findRayIntersection(pickRay, true); // want precision picking + var lightResult = lightOverlayManager.findRayIntersection(pickRay); + lightResult.accurate = true; + + if (pickZones) { + Entities.setZonesArePickable(false); + } + + var result; + + if (!entityResult.intersects && !lightResult.intersects) { + return null; + } else if (entityResult.intersects && !lightResult.intersects) { + result = entityResult; + } else if (!entityResult.intersects && lightResult.intersects) { + result = lightResult; + } else { + if (entityResult.distance < lightResult.distance) { + result = entityResult; + } else { + result = lightResult; + } + } + + if (!result.accurate) { + return null; + } + + var foundEntity = result.entityID; + return { + pickRay: pickRay, + entityID: foundEntity, + intersection: result.intersection + }; +} diff --git a/scripts/developer/utilities/render/turntable.qml b/scripts/developer/utilities/render/turntable.qml new file mode 100644 index 0000000000..8c2af2593f --- /dev/null +++ b/scripts/developer/utilities/render/turntable.qml @@ -0,0 +1,30 @@ +// +// turntable.qml +// developer/utilities/render +// +// Created by Sam Gateau on 6/2/2016 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html +// +import QtQuick 2.5 +import QtQuick.Controls 1.4 + +Item { + id: statsUI + anchors.fill:parent + + Column { + id: stats + spacing: 8 + anchors.fill:parent + + Label { + text: "Turntable" + } + + } + +} + From bf93483f878814b99aa6a8c70e541081afcaf1fb Mon Sep 17 00:00:00 2001 From: humbletim Date: Wed, 19 Oct 2016 15:47:02 -0400 Subject: [PATCH 02/66] allow assignment client scripts to create ATP assets --- domain-server/src/DomainGatekeeper.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index bf9d7d04a6..abe7ed176a 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -237,6 +237,7 @@ void DomainGatekeeper::updateNodePermissions() { userPerms.permissions |= NodePermissions::Permission::canAdjustLocks; userPerms.permissions |= NodePermissions::Permission::canRezPermanentEntities; userPerms.permissions |= NodePermissions::Permission::canRezTemporaryEntities; + userPerms.permissions |= NodePermissions::Permission::canWriteToAssetServer; } else { // this node is an agent const QHostAddress& addr = node->getLocalSocket().getAddress(); @@ -312,6 +313,7 @@ SharedNodePointer DomainGatekeeper::processAssignmentConnectRequest(const NodeCo userPerms.permissions |= NodePermissions::Permission::canAdjustLocks; userPerms.permissions |= NodePermissions::Permission::canRezPermanentEntities; userPerms.permissions |= NodePermissions::Permission::canRezTemporaryEntities; + userPerms.permissions |= NodePermissions::Permission::canWriteToAssetServer; newNode->setPermissions(userPerms); return newNode; } From 80e38c395ecf100d6948dd5f59beaa2b1eb951e3 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Mon, 31 Oct 2016 10:35:16 -0700 Subject: [PATCH 03/66] Send KillAvatar to AudioMixer too So it can remove the listening agent avatar audio streams. Otherwise they stick around forever, and eventually swamp the audio mixer. --- assignment-client/src/Agent.cpp | 3 ++- assignment-client/src/audio/AudioMixer.cpp | 9 +++++++++ assignment-client/src/audio/AudioMixer.h | 1 + assignment-client/src/audio/AudioMixerClientData.cpp | 9 +++++++++ assignment-client/src/audio/AudioMixerClientData.h | 2 ++ 5 files changed, 23 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 23bee2c91a..7515dda13d 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -439,7 +439,8 @@ void Agent::setIsAvatar(bool isAvatar) { packetList->write(getSessionUUID().toRfc4122()); nodeList->eachMatchingNode( [&](const SharedNodePointer& node)->bool { - return node->getType() == NodeType::AvatarMixer && node->getActiveSocket(); + return (node->getType() == NodeType::AvatarMixer || node->getType() == NodeType::AudioMixer) + && node->getActiveSocket(); }, [&](const SharedNodePointer& node) { nodeList->sendPacketList(std::move(packetList), *node); diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index bc356b8ce1..e5a2c9def5 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -93,6 +93,7 @@ AudioMixer::AudioMixer(ReceivedMessage& message) : packetReceiver.registerListener(PacketType::NegotiateAudioFormat, this, "handleNegotiateAudioFormat"); packetReceiver.registerListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); packetReceiver.registerListener(PacketType::NodeIgnoreRequest, this, "handleNodeIgnoreRequestPacket"); + packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket"); connect(nodeList.data(), &NodeList::nodeKilled, this, &AudioMixer::handleNodeKilled); } @@ -598,6 +599,14 @@ void AudioMixer::handleNodeKilled(SharedNodePointer killedNode) { }); } +void AudioMixer::handleKillAvatarPacket(QSharedPointer packet, SharedNodePointer sendingNode) { + auto clientData = dynamic_cast(sendingNode->getLinkedData()); + if (clientData) { + clientData->removeAgentAvatarAudioStream(); + } +} + + void AudioMixer::handleNodeIgnoreRequestPacket(QSharedPointer packet, SharedNodePointer sendingNode) { sendingNode->parseIgnoreRequestMessage(packet); } diff --git a/assignment-client/src/audio/AudioMixer.h b/assignment-client/src/audio/AudioMixer.h index 764c54c6cb..3c68e4c6af 100644 --- a/assignment-client/src/audio/AudioMixer.h +++ b/assignment-client/src/audio/AudioMixer.h @@ -48,6 +48,7 @@ private slots: void handleNegotiateAudioFormat(QSharedPointer message, SharedNodePointer sendingNode); void handleNodeKilled(SharedNodePointer killedNode); void handleNodeIgnoreRequestPacket(QSharedPointer packet, SharedNodePointer sendingNode); + void handleKillAvatarPacket(QSharedPointer packet, SharedNodePointer sendingNode); void removeHRTFsForFinishedInjector(const QUuid& streamID); diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index 58d89697af..72914da075 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -73,6 +73,15 @@ void AudioMixerClientData::removeHRTFForStream(const QUuid& nodeID, const QUuid& } } +void AudioMixerClientData::removeAgentAvatarAudioStream() { + QWriteLocker writeLocker { &_streamsLock }; + auto it = _audioStreams.find(QUuid()); + if (it != _audioStreams.end()) { + _audioStreams.erase(it); + } + writeLocker.unlock(); +} + int AudioMixerClientData::parseData(ReceivedMessage& message) { PacketType packetType = message.getType(); diff --git a/assignment-client/src/audio/AudioMixerClientData.h b/assignment-client/src/audio/AudioMixerClientData.h index 34263f9cbe..52c659c240 100644 --- a/assignment-client/src/audio/AudioMixerClientData.h +++ b/assignment-client/src/audio/AudioMixerClientData.h @@ -50,6 +50,8 @@ public: // removes an AudioHRTF object for a given stream void removeHRTFForStream(const QUuid& nodeID, const QUuid& streamID = QUuid()); + void removeAgentAvatarAudioStream(); + int parseData(ReceivedMessage& message) override; // attempt to pop a frame from each audio stream, and return the number of streams from this client From e63e9bc0176cdfd5b12b0c974000b0fc0c9110e1 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Mon, 31 Oct 2016 13:25:22 -0700 Subject: [PATCH 04/66] Remove HRTFs for Avatar too Turns out there was already a function for that, if you just call removeHRTFForStream without a 2nd param, it appears to just delete the audio with uuid of QUuid() which is the avatar's mic. That is what we want, so cool. --- assignment-client/src/audio/AudioMixer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index e5a2c9def5..602dd233ad 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -603,6 +603,9 @@ void AudioMixer::handleKillAvatarPacket(QSharedPointer packet, auto clientData = dynamic_cast(sendingNode->getLinkedData()); if (clientData) { clientData->removeAgentAvatarAudioStream(); + // when you don't specify a stream, this removes just the QUuid() + // stream (which is the avatar's mic stream) + clientData->removeHRTFForStream(sendingNode->getUUID()); } } From 91d878666cdc734d37d8e2e2920947fafe8e33cc Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 31 Oct 2016 14:56:28 -0700 Subject: [PATCH 05/66] Remove experimental scripts --- .../developer/utilities/render/turntable.js | 68 ------------------- .../developer/utilities/render/turntable.qml | 30 -------- 2 files changed, 98 deletions(-) delete mode 100644 scripts/developer/utilities/render/turntable.js delete mode 100644 scripts/developer/utilities/render/turntable.qml diff --git a/scripts/developer/utilities/render/turntable.js b/scripts/developer/utilities/render/turntable.js deleted file mode 100644 index dcc6dcd0e0..0000000000 --- a/scripts/developer/utilities/render/turntable.js +++ /dev/null @@ -1,68 +0,0 @@ -// -// turntable.js -// developer/utilities/render -// -// Sam Gateau, created on 6/2/2016. -// Copyright 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 -// - -// Set up the qml ui -var qml = Script.resolvePath('turntable.qml'); -var window = new OverlayWindow({ - title: 'Turntable', - source: qml, - width: 320, - height: 320 -}); -window.setPosition(500, 500); -window.closed.connect(function() { Script.stop(); }); - - - -function findClickedEntity(event) { - var pickZones = event.isControl; - - if (pickZones) { - Entities.setZonesArePickable(true); - } - - var pickRay = Camera.computePickRay(event.x, event.y); - - var entityResult = Entities.findRayIntersection(pickRay, true); // want precision picking - var lightResult = lightOverlayManager.findRayIntersection(pickRay); - lightResult.accurate = true; - - if (pickZones) { - Entities.setZonesArePickable(false); - } - - var result; - - if (!entityResult.intersects && !lightResult.intersects) { - return null; - } else if (entityResult.intersects && !lightResult.intersects) { - result = entityResult; - } else if (!entityResult.intersects && lightResult.intersects) { - result = lightResult; - } else { - if (entityResult.distance < lightResult.distance) { - result = entityResult; - } else { - result = lightResult; - } - } - - if (!result.accurate) { - return null; - } - - var foundEntity = result.entityID; - return { - pickRay: pickRay, - entityID: foundEntity, - intersection: result.intersection - }; -} diff --git a/scripts/developer/utilities/render/turntable.qml b/scripts/developer/utilities/render/turntable.qml deleted file mode 100644 index 8c2af2593f..0000000000 --- a/scripts/developer/utilities/render/turntable.qml +++ /dev/null @@ -1,30 +0,0 @@ -// -// turntable.qml -// developer/utilities/render -// -// Created by Sam Gateau on 6/2/2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html -// -import QtQuick 2.5 -import QtQuick.Controls 1.4 - -Item { - id: statsUI - anchors.fill:parent - - Column { - id: stats - spacing: 8 - anchors.fill:parent - - Label { - text: "Turntable" - } - - } - -} - From 5714063eff61701955e4006cc1ba86fa3a967337 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Mon, 31 Oct 2016 16:38:01 -0700 Subject: [PATCH 06/66] Make more reliable Need to be sure we don't change the _isAvatar or _isListeningToAudioStream from one thread while processing audio in another. Also, fixed issue sending NLPacketList. --- assignment-client/src/Agent.cpp | 35 +++++++++++++++++++++++++++++++-- assignment-client/src/Agent.h | 2 +- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 7515dda13d..02d86b5e56 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -404,8 +404,38 @@ QUuid Agent::getSessionUUID() const { return DependencyManager::get()->getSessionUUID(); } +void Agent::setIsListeningToAudioStream(bool isListeningToAudioStream) { + // this must happen on Agent's main thread + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "setIsListeningToAudioStream", Q_ARG(bool, isListeningToAudioStream)); + return; + } + if (_isListeningToAudioStream) { + // have to tell just the audio mixer to KillAvatar. + + auto nodeList = DependencyManager::get(); + nodeList->eachMatchingNode( + [&](const SharedNodePointer& node)->bool { + return (node->getType() == NodeType::AudioMixer) + && node->getActiveSocket(); + }, + [&](const SharedNodePointer& node) { + qDebug() << "sending KillAvatar message to Avatar and Audio Mixers"; + auto packetList = NLPacketList::create(PacketType::KillAvatar, QByteArray(), true, true); + packetList->write(getSessionUUID().toRfc4122()); + nodeList->sendPacketList(std::move(packetList), *node); + }); + + } + _isListeningToAudioStream = isListeningToAudioStream; +} void Agent::setIsAvatar(bool isAvatar) { + // this must happen on Agent's main thread + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "setIsAvatar", Q_ARG(bool, isAvatar)); + return; + } _isAvatar = isAvatar; if (_isAvatar && !_avatarIdentityTimer) { @@ -435,14 +465,15 @@ void Agent::setIsAvatar(bool isAvatar) { // when we stop sending identity, but then get woken up again by the mixer itself, which sends // identity packets to everyone. Here we explicitly tell the mixer to kill the entry for us. auto nodeList = DependencyManager::get(); - auto packetList = NLPacketList::create(PacketType::KillAvatar, QByteArray(), true, true); - packetList->write(getSessionUUID().toRfc4122()); nodeList->eachMatchingNode( [&](const SharedNodePointer& node)->bool { return (node->getType() == NodeType::AvatarMixer || node->getType() == NodeType::AudioMixer) && node->getActiveSocket(); }, [&](const SharedNodePointer& node) { + qDebug() << "sending KillAvatar message to Avatar and Audio Mixers"; + auto packetList = NLPacketList::create(PacketType::KillAvatar, QByteArray(), true, true); + packetList->write(getSessionUUID().toRfc4122()); nodeList->sendPacketList(std::move(packetList), *node); }); } diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index 939b51625a..c9b1707101 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -49,7 +49,7 @@ public: bool isPlayingAvatarSound() const { return _avatarSound != NULL; } bool isListeningToAudioStream() const { return _isListeningToAudioStream; } - void setIsListeningToAudioStream(bool isListeningToAudioStream) { _isListeningToAudioStream = isListeningToAudioStream; } + void setIsListeningToAudioStream(bool isListeningToAudioStream); float getLastReceivedAudioLoudness() const { return _lastReceivedAudioLoudness; } QUuid getSessionUUID() const; From a23bbd1e4e067714dc7457689f1b25a772d9bffc Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 31 Oct 2016 16:40:15 -0700 Subject: [PATCH 07/66] Trying to extend the memory counter --- libraries/shared/src/GPUIdent.cpp | 3 ++- libraries/shared/src/GPUIdent.h | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/libraries/shared/src/GPUIdent.cpp b/libraries/shared/src/GPUIdent.cpp index 02f92d87e7..a78163b570 100644 --- a/libraries/shared/src/GPUIdent.cpp +++ b/libraries/shared/src/GPUIdent.cpp @@ -10,6 +10,7 @@ #include + #ifdef Q_OS_WIN #include #include @@ -139,7 +140,7 @@ GPUIdent* GPUIdent::ensureQuery(const QString& vendor, const QString& renderer) var.ChangeType(CIM_UINT64); // We're going to receive some integral type, but it might not be uint. // We might be hosed here. The parameter is documented to be UINT32, but that's only 4 GB! const ULONGLONG BYTES_PER_MEGABYTE = 1024 * 1024; - _dedicatedMemoryMB = (uint) (var.ullVal / BYTES_PER_MEGABYTE); + _dedicatedMemoryMB = (uint64_t) (var.ullVal / BYTES_PER_MEGABYTE); } else { qCDebug(shared) << "Unable to get video AdapterRAM"; diff --git a/libraries/shared/src/GPUIdent.h b/libraries/shared/src/GPUIdent.h index 4e844b0e54..8615e61b08 100644 --- a/libraries/shared/src/GPUIdent.h +++ b/libraries/shared/src/GPUIdent.h @@ -14,17 +14,19 @@ #ifndef hifi_GPUIdent_h #define hifi_GPUIdent_h +#include + class GPUIdent { public: - unsigned int getMemory() { return _dedicatedMemoryMB; } + uint64_t getMemory() { return _dedicatedMemoryMB; } QString getName() { return _name; } QString getDriver() { return _driver; } bool isValid() { return _isValid; } // E.g., GPUIdent::getInstance()->getMemory(); static GPUIdent* getInstance(const QString& vendor = "", const QString& renderer = "") { return _instance.ensureQuery(vendor, renderer); } private: - uint _dedicatedMemoryMB { 0 }; + uint64_t _dedicatedMemoryMB { 0 }; QString _name { "" }; QString _driver { "" }; bool _isQueried { false }; From b7f5fc2516393404786e8b17d01e9f00fdaa8575 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 1 Nov 2016 08:58:29 -0700 Subject: [PATCH 08/66] Update 'Sandbox' to 'High Fidelity Sandbox' in task manager --- server-console/packager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-console/packager.js b/server-console/packager.js index bc3b8989d2..89bcd7cb71 100644 --- a/server-console/packager.js +++ b/server-console/packager.js @@ -37,7 +37,7 @@ if (osType == "Darwin") { } else if (osType == "Windows_NT") { options["version-string"] = { CompanyName: "High Fidelity, Inc.", - FileDescription: SHORT_NAME, + FileDescription: FULL_NAME, ProductName: FULL_NAME, OriginalFilename: EXEC_NAME + ".exe" } From ea31a8e3b47d4a6e7c23b387d4671c5c70dd99dd Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 1 Nov 2016 08:59:56 -0700 Subject: [PATCH 09/66] Add VersionInfo.rc.in --- cmake/templates/VersionInfo.rc.in | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 cmake/templates/VersionInfo.rc.in diff --git a/cmake/templates/VersionInfo.rc.in b/cmake/templates/VersionInfo.rc.in new file mode 100644 index 0000000000..1d7b3fa585 --- /dev/null +++ b/cmake/templates/VersionInfo.rc.in @@ -0,0 +1,22 @@ +// Language and character set information as described at +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa381049(v=vs.85).aspx +#define US_ENGLISH_UNICODE "040904B0" + +// More information about the format of this file can be found at +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa381058(v=vs.85).aspx +1 VERSIONINFO +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK US_ENGLISH_UNICODE + BEGIN + VALUE "CompanyName", "@BUILD_ORGANIZATION@" + VALUE "FileDescription", "@APP_FULL_NAME@" + VALUE "FileVersion", "@BUILD_VERSION@" + VALUE "InternalName", "@TARGET_NAME@" + VALUE "OriginalFilename", "@EXE_NAME@" + VALUE "ProductName", "@APP_FULL_NAME@" + VALUE "ProductVersion", "@BUILD_VERSION@" + END + END +END From 0cc98d4501e6d009d071fda0b262d3ecb9a7a28d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 1 Nov 2016 09:00:08 -0700 Subject: [PATCH 10/66] Add VersionInfo.rc to interface --- interface/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index b43376c374..f3d684abf1 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -133,8 +133,13 @@ elseif (WIN32) set(CONFIGURE_ICON_RC_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Icon.rc") configure_file("${HF_CMAKE_DIR}/templates/Icon.rc.in" ${CONFIGURE_ICON_RC_OUTPUT}) + set(APP_FULL_NAME "High Fidelity Interface") + set(EXE_NAME "interface.exe") + set(CONFIGURE_VERSION_INFO_RC_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.rc") + configure_file("${HF_CMAKE_DIR}/templates/VersionInfo.rc.in" ${CONFIGURE_VERSION_INFO_RC_OUTPUT}) + # add an executable that also has the icon itself and the configured rc file as resources - add_executable(${TARGET_NAME} WIN32 ${INTERFACE_SRCS} ${QM} ${CONFIGURE_ICON_RC_OUTPUT}) + add_executable(${TARGET_NAME} WIN32 ${INTERFACE_SRCS} ${QM} ${CONFIGURE_ICON_RC_OUTPUT} ${CONFIGURE_VERSION_INFO_RC_OUTPUT}) if (NOT DEV_BUILD) add_custom_command( From 5f8cee787fa06a9e84d44395c1ef71553c3ca667 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 1 Nov 2016 09:07:56 -0700 Subject: [PATCH 11/66] Update VersionInfo.rc.in to use TARGET_NAME.exe as original filename --- cmake/templates/VersionInfo.rc.in | 2 +- interface/CMakeLists.txt | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cmake/templates/VersionInfo.rc.in b/cmake/templates/VersionInfo.rc.in index 1d7b3fa585..ad192ed87d 100644 --- a/cmake/templates/VersionInfo.rc.in +++ b/cmake/templates/VersionInfo.rc.in @@ -14,7 +14,7 @@ BEGIN VALUE "FileDescription", "@APP_FULL_NAME@" VALUE "FileVersion", "@BUILD_VERSION@" VALUE "InternalName", "@TARGET_NAME@" - VALUE "OriginalFilename", "@EXE_NAME@" + VALUE "OriginalFilename", "@TARGET_NAME@.exe" VALUE "ProductName", "@APP_FULL_NAME@" VALUE "ProductVersion", "@BUILD_VERSION@" END diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index f3d684abf1..131c4ee509 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -134,7 +134,6 @@ elseif (WIN32) configure_file("${HF_CMAKE_DIR}/templates/Icon.rc.in" ${CONFIGURE_ICON_RC_OUTPUT}) set(APP_FULL_NAME "High Fidelity Interface") - set(EXE_NAME "interface.exe") set(CONFIGURE_VERSION_INFO_RC_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.rc") configure_file("${HF_CMAKE_DIR}/templates/VersionInfo.rc.in" ${CONFIGURE_VERSION_INFO_RC_OUTPUT}) From fb2968a4191675610451b185d51fd0c1e362e4c8 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Tue, 1 Nov 2016 09:12:35 -0700 Subject: [PATCH 12/66] Reset bytes sent counter when setting avatar sound It could be past the end of the buffer if you changed sounds, and the new one is shorter. Won't happen with our current tests, but that could change, and in general no reason it couldn't happen. --- assignment-client/src/Agent.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 02d86b5e56..1da33f5bd7 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -88,6 +88,7 @@ void Agent::playAvatarSound(SharedSoundPointer sound) { QMetaObject::invokeMethod(this, "playAvatarSound", Q_ARG(SharedSoundPointer, sound)); return; } else { + _numAvatarSoundSentBytes = 0; setAvatarSound(sound); } } From 404c08b0c73f0edf974126f3d06e0dc807404f2e Mon Sep 17 00:00:00 2001 From: David Kelly Date: Tue, 1 Nov 2016 10:46:22 -0700 Subject: [PATCH 13/66] Un-do of previous commit Seems to add an artifact when using our test scripts. Will work on that as a separate issue, as it would be an existing issue in any case. --- assignment-client/src/Agent.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 1da33f5bd7..0ec9b4a172 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -88,7 +88,10 @@ void Agent::playAvatarSound(SharedSoundPointer sound) { QMetaObject::invokeMethod(this, "playAvatarSound", Q_ARG(SharedSoundPointer, sound)); return; } else { - _numAvatarSoundSentBytes = 0; + // TODO: seems to add occasional artifact in tests. I believe it is + // correct to do this, but need to figure out for sure, so commenting this + // out until I verify. + // _numAvatarSoundSentBytes = 0; setAvatarSound(sound); } } From 861944ba71e718391c69554ac1405ba61a3d19c3 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 1 Nov 2016 11:12:47 -0700 Subject: [PATCH 14/66] Try uing DXGI on windows instead of com --- libraries/shared/src/GPUIdent.cpp | 45 ++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/libraries/shared/src/GPUIdent.cpp b/libraries/shared/src/GPUIdent.cpp index a78163b570..170d57fe4f 100644 --- a/libraries/shared/src/GPUIdent.cpp +++ b/libraries/shared/src/GPUIdent.cpp @@ -15,6 +15,9 @@ #include #include +#include +#pragma comment(lib, "dxgi.lib") + #elif defined(Q_OS_MAC) #include #endif @@ -54,9 +57,44 @@ GPUIdent* GPUIdent::ensureQuery(const QString& vendor, const QString& renderer) CGLDestroyRendererInfo(rendererInfo); #elif defined(Q_OS_WIN) + + + // Create the DXGI factory + // Let s get into DXGI land: + HRESULT hr = S_OK; + + IDXGIFactory1* pFactory = nullptr; + hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)(&pFactory) ); + + // Select our adapter + IDXGIAdapter1* capableAdapter = nullptr; + { + for (UINT adapter = 0; !capableAdapter; ++adapter) { + // get a candidate DXGI adapter + IDXGIAdapter1* pAdapter = nullptr; + hr = pFactory->EnumAdapters1(adapter, &pAdapter); + if (FAILED(hr)) { + break; + } + // query to see if there exists a corresponding compute device + + // if so, mark it as the one against which to create our d3d10 device + capableAdapter = pAdapter; + capableAdapter->AddRef(); + + pAdapter->Release(); + } + } + + DXGI_ADAPTER_DESC1 adapterDesc; + capableAdapter->GetDesc1(&adapterDesc); + + capableAdapter->Release(); + pFactory->Release(); + // COM must be initialized already using CoInitialize. E.g., by the audio subsystem. CComPtr spLoc = NULL; - HRESULT hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_SERVER, IID_IWbemLocator, (LPVOID *)&spLoc); + hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_SERVER, IID_IWbemLocator, (LPVOID *)&spLoc); if (hr != S_OK || spLoc == NULL) { qCDebug(shared) << "Unable to connect to WMI"; return this; @@ -150,6 +188,11 @@ GPUIdent* GPUIdent::ensureQuery(const QString& vendor, const QString& renderer) } hr = spEnumInst->Next(WBEM_INFINITE, 1, &spInstance.p, &uNumOfInstances); } + + const ULONGLONG BYTES_PER_MEGABYTE = 1024 * 1024; + _dedicatedMemoryMB = (uint64_t)(adapterDesc.DedicatedVideoMemory / BYTES_PER_MEGABYTE); + + #endif return this; } From ba0dbeac80659a09da19d0373ce2b86b3ba3ffb1 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 1 Nov 2016 13:36:20 -0700 Subject: [PATCH 15/66] Add InputManager::getSubdeviceNames --- libraries/plugins/src/plugins/InputPlugin.h | 3 +++ plugins/hifiSdl2/src/SDL2Manager.cpp | 8 +++++++- plugins/hifiSdl2/src/SDL2Manager.h | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/libraries/plugins/src/plugins/InputPlugin.h b/libraries/plugins/src/plugins/InputPlugin.h index f68be3edf6..0db0b24420 100644 --- a/libraries/plugins/src/plugins/InputPlugin.h +++ b/libraries/plugins/src/plugins/InputPlugin.h @@ -21,6 +21,9 @@ public: virtual void pluginFocusOutEvent() = 0; virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) = 0; + // Some input plugins are comprised of multiple subdevices (SDL2, for instance). + // If an input plugin is only a single device, it will only return it's primary name. + virtual QStringList getSubdeviceNames() { return { getName() }; }; virtual bool isHandController() const = 0; }; diff --git a/plugins/hifiSdl2/src/SDL2Manager.cpp b/plugins/hifiSdl2/src/SDL2Manager.cpp index b9a19658e2..91a693cc09 100644 --- a/plugins/hifiSdl2/src/SDL2Manager.cpp +++ b/plugins/hifiSdl2/src/SDL2Manager.cpp @@ -65,8 +65,10 @@ void SDL2Manager::init() { _openJoysticks[id] = joystick; auto userInputMapper = DependencyManager::get(); userInputMapper->registerDevice(joystick); + auto name = SDL_GameControllerName(controller); + _subdeviceNames << name; emit joystickAdded(joystick.get()); - emit subdeviceConnected(getName(), SDL_GameControllerName(controller)); + emit subdeviceConnected(getName(), name); } } } @@ -78,6 +80,10 @@ void SDL2Manager::init() { } } +QStringList SDL2Manager::getSubdeviceNames() { + return _subdeviceNames; +} + void SDL2Manager::deinit() { _openJoysticks.clear(); diff --git a/plugins/hifiSdl2/src/SDL2Manager.h b/plugins/hifiSdl2/src/SDL2Manager.h index 44b75abd2f..fc1654bce1 100644 --- a/plugins/hifiSdl2/src/SDL2Manager.h +++ b/plugins/hifiSdl2/src/SDL2Manager.h @@ -26,6 +26,7 @@ public: bool isSupported() const override; const QString& getName() const override { return NAME; } + QStringList getSubdeviceNames() override; bool isHandController() const override { return false; } void init() override; @@ -79,6 +80,7 @@ private: QMap _openJoysticks; bool _isInitialized { false } ; static const QString NAME; + QStringList _subdeviceNames; }; #endif // hifi__SDL2Manager_h From e4341d7a02980aacc849f869dd4495997e0fa106 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 1 Nov 2016 13:42:37 -0700 Subject: [PATCH 16/66] Add vive and xbox controller checking to PluginUtils --- libraries/plugins/src/plugins/PluginUtils.cpp | 21 +++++++++++++++++++ libraries/plugins/src/plugins/PluginUtils.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/libraries/plugins/src/plugins/PluginUtils.cpp b/libraries/plugins/src/plugins/PluginUtils.cpp index bc53e8166a..f1cc85634f 100644 --- a/libraries/plugins/src/plugins/PluginUtils.cpp +++ b/libraries/plugins/src/plugins/PluginUtils.cpp @@ -32,3 +32,24 @@ bool PluginUtils::isHandControllerAvailable() { } return false; }; + +bool isSubdeviceContainingNameAvailable(QString name) { + for (auto& inputPlugin : PluginManager::getInstance()->getInputPlugins()) { + auto subdeviceNames = inputPlugin->getSubdeviceNames(); + for (auto& name : subdeviceNames) { + if (name.contains(name)) { + return true; + } + } + } + return false; +}; + +bool PluginUtils::isViveControllerAvailable() { + return isSubdeviceContainingNameAvailable("Vive"); +}; + +bool PluginUtils::isXboxControllerAvailable() { + return isSubdeviceContainingNameAvailable("X360 Controller"); +}; + diff --git a/libraries/plugins/src/plugins/PluginUtils.h b/libraries/plugins/src/plugins/PluginUtils.h index 727677ccd3..f1449bc3af 100644 --- a/libraries/plugins/src/plugins/PluginUtils.h +++ b/libraries/plugins/src/plugins/PluginUtils.h @@ -16,4 +16,6 @@ class PluginUtils { public: static bool isHMDAvailable(const QString& pluginName = ""); static bool isHandControllerAvailable(); + static bool isViveControllerAvailable(); + static bool isXboxControllerAvailable(); }; From 16d91833e8ba6fd9d14e17c728a240b28c76b407 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 1 Nov 2016 13:43:32 -0700 Subject: [PATCH 17/66] Add optional url query to InfoView --- libraries/ui/src/InfoView.cpp | 4 +++- libraries/ui/src/InfoView.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/ui/src/InfoView.cpp b/libraries/ui/src/InfoView.cpp index 6b6d6645f5..d2c72bf5f2 100644 --- a/libraries/ui/src/InfoView.cpp +++ b/libraries/ui/src/InfoView.cpp @@ -37,7 +37,7 @@ QString fetchVersion(const QUrl& url) { return r.trimmed(); } -void InfoView::show(const QString& path, bool firstOrChangedOnly) { +void InfoView::show(const QString& path, bool firstOrChangedOnly, QString urlQuery) { static bool registered{ false }; if (!registered) { registerType(); @@ -49,6 +49,8 @@ void InfoView::show(const QString& path, bool firstOrChangedOnly) { } else { url = QUrl::fromLocalFile(path); } + url.setQuery(urlQuery); + if (firstOrChangedOnly) { const QString lastVersion = infoVersion.get(); const QString version = fetchVersion(url); diff --git a/libraries/ui/src/InfoView.h b/libraries/ui/src/InfoView.h index 275effbfa5..ea6150a4d8 100644 --- a/libraries/ui/src/InfoView.h +++ b/libraries/ui/src/InfoView.h @@ -22,7 +22,7 @@ class InfoView : public QQuickItem { static const QString NAME; public: static void registerType(); - static void show(const QString& path, bool firstOrChangedOnly = false); + static void show(const QString& path, bool firstOrChangedOnly = false, QString urlQuery = ""); InfoView(QQuickItem* parent = nullptr); QUrl url(); From 3147ea9e33c557d48881b849c1ad70a38956f5f3 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 1 Nov 2016 13:43:55 -0700 Subject: [PATCH 18/66] Update help window to auto select xbox or vive controller tab on availability of device --- interface/resources/html/help.html | 22 +++++++++++++++++----- interface/src/Application.cpp | 12 +++++++++++- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/interface/resources/html/help.html b/interface/resources/html/help.html index 6cc4dab6af..422f5c6b46 100644 --- a/interface/resources/html/help.html +++ b/interface/resources/html/help.html @@ -50,21 +50,33 @@ function showKbm() { document.getElementById("main_image").setAttribute("src", "img/controls-help-keyboard.png"); } - function showHandControllers() { + function showViveControllers() { document.getElementById("main_image").setAttribute("src", "img/controls-help-vive.png"); } - function showGameController() { + function showXboxController() { document.getElementById("main_image").setAttribute("src", "img/controls-help-gamepad.png"); } + function load() { + console.log("In help.html: ", window.location.href); + parts = window.location.href.split("?"); + if (parts.length > 0) { + var defaultTab = parts[1]; + if (defaultTab == "xbox") { + showXboxController(); + } else if (defaultTab == "vive") { + showViveControllers(); + } + } + } - +
- - + +
diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5fe15fa8e5..a18081c664 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2155,7 +2155,17 @@ void Application::aboutApp() { } void Application::showHelp() { - InfoView::show(INFO_HELP_PATH); + static const QString QUERY_STRING_XBOX = "xbox"; + static const QString QUERY_STRING_VIVE = "vive"; + + QString queryString = ""; + if (PluginUtils::isViveControllerAvailable()) { + queryString = QUERY_STRING_VIVE; + } else if (PluginUtils::isXboxControllerAvailable()) { + queryString = QUERY_STRING_XBOX; + } + + InfoView::show(INFO_HELP_PATH, false, queryString); } void Application::resizeEvent(QResizeEvent* event) { From ba7eac5281e01b0457bddb1b337ba7f909088a3f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 1 Nov 2016 13:53:10 -0700 Subject: [PATCH 19/66] Override getSubdeviceNames in OculusControllerManager --- plugins/oculus/src/OculusControllerManager.cpp | 11 +++++++++++ plugins/oculus/src/OculusControllerManager.h | 1 + 2 files changed, 12 insertions(+) diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index 5d493f4c9d..f0edc5a465 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -117,6 +117,17 @@ void OculusControllerManager::stopHapticPulse(bool leftHand) { } } +QStringList OculusControllerManager::getSubdeviceNames() { + QStringList devices; + if (_touch) { + devices << _touch->getName(); + } + if (_remote) { + devices << _remote->getName(); + } + return devices; +} + using namespace controller; static const std::vector> BUTTON_MAP { { diff --git a/plugins/oculus/src/OculusControllerManager.h b/plugins/oculus/src/OculusControllerManager.h index 234acd7db2..1ca9e0f47e 100644 --- a/plugins/oculus/src/OculusControllerManager.h +++ b/plugins/oculus/src/OculusControllerManager.h @@ -27,6 +27,7 @@ public: const QString& getName() const override { return NAME; } bool isHandController() const override { return _touch != nullptr; } + QStringList getSubdeviceNames() override; bool activate() override; void deactivate() override; From 52cc03c5a2111fd2525ea784dfdd4faefae63323 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Tue, 1 Nov 2016 14:44:39 -0700 Subject: [PATCH 20/66] Get snapshot location data from file, which now uses shareable place info. --- interface/src/ui/Snapshot.cpp | 9 ++++++--- interface/src/ui/SnapshotUploader.cpp | 22 +++++++++++++--------- interface/src/ui/SnapshotUploader.h | 8 +++++++- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/interface/src/ui/Snapshot.cpp b/interface/src/ui/Snapshot.cpp index 3334b0301b..1bf5f5de4e 100644 --- a/interface/src/ui/Snapshot.cpp +++ b/interface/src/ui/Snapshot.cpp @@ -89,7 +89,7 @@ QTemporaryFile* Snapshot::saveTempSnapshot(QImage image) { QFile* Snapshot::savedFileForSnapshot(QImage & shot, bool isTemporary) { // adding URL to snapshot - QUrl currentURL = DependencyManager::get()->currentAddress(); + QUrl currentURL = DependencyManager::get()->currentShareableAddress(); shot.setText(URL, currentURL.toString()); QString username = DependencyManager::get()->getAccountInfo().getUsername(); @@ -146,7 +146,10 @@ QFile* Snapshot::savedFileForSnapshot(QImage & shot, bool isTemporary) { void Snapshot::uploadSnapshot(const QString& filename) { const QString SNAPSHOT_UPLOAD_URL = "/api/v1/snapshots"; - static SnapshotUploader uploader; + // Alternatively to parseSnapshotData, we could pass the inWorldLocation through the call chain. This way is less disruptive to existing code. + SnapshotMetaData* snapshotData = Snapshot::parseSnapshotData(filename); + SnapshotUploader* uploader = new SnapshotUploader(snapshotData->getURL(), filename); + delete snapshotData; QFile* file = new QFile(filename); Q_ASSERT(file->exists()); @@ -163,7 +166,7 @@ void Snapshot::uploadSnapshot(const QString& filename) { multiPart->append(imagePart); auto accountManager = DependencyManager::get(); - JSONCallbackParameters callbackParams(&uploader, "uploadSuccess", &uploader, "uploadFailure"); + JSONCallbackParameters callbackParams(uploader, "uploadSuccess", uploader, "uploadFailure"); accountManager->sendRequest(SNAPSHOT_UPLOAD_URL, AccountManagerAuth::Required, diff --git a/interface/src/ui/SnapshotUploader.cpp b/interface/src/ui/SnapshotUploader.cpp index 5bc9bb386c..b531f82348 100644 --- a/interface/src/ui/SnapshotUploader.cpp +++ b/interface/src/ui/SnapshotUploader.cpp @@ -15,9 +15,13 @@ #include "scripting/WindowScriptingInterface.h" #include "SnapshotUploader.h" +SnapshotUploader::SnapshotUploader(QUrl inWorldLocation, QString pathname) : + _inWorldLocation(inWorldLocation), + _pathname(pathname) { +} + void SnapshotUploader::uploadSuccess(QNetworkReply& reply) { const QString STORY_UPLOAD_URL = "/api/v1/user_stories"; - static SnapshotUploader uploader; // parse the reply for the thumbnail_url QByteArray contents = reply.readAll(); @@ -28,11 +32,8 @@ void SnapshotUploader::uploadSuccess(QNetworkReply& reply) { QString thumbnailUrl = dataObject.value("thumbnail_url").toString(); QString imageUrl = dataObject.value("image_url").toString(); auto addressManager = DependencyManager::get(); - QString placeName = addressManager->getPlaceName(); - if (placeName.isEmpty()) { - placeName = addressManager->getHost(); - } - QString currentPath = addressManager->currentPath(true); + QString placeName = _inWorldLocation.authority(); // We currently only upload shareable places, in which case this is just host. + QString currentPath = _inWorldLocation.path(); // create json post data QJsonObject rootObject; @@ -48,7 +49,7 @@ void SnapshotUploader::uploadSuccess(QNetworkReply& reply) { rootObject.insert("user_story", userStoryObject); auto accountManager = DependencyManager::get(); - JSONCallbackParameters callbackParams(&uploader, "createStorySuccess", &uploader, "createStoryFailure"); + JSONCallbackParameters callbackParams(this, "createStorySuccess", this, "createStoryFailure"); accountManager->sendRequest(STORY_UPLOAD_URL, AccountManagerAuth::Required, @@ -63,13 +64,16 @@ void SnapshotUploader::uploadSuccess(QNetworkReply& reply) { } void SnapshotUploader::uploadFailure(QNetworkReply& reply) { - emit DependencyManager::get()->snapshotShared(reply.readAll()); + emit DependencyManager::get()->snapshotShared(reply.readAll()); // maybe someday include _inWorldLocation, _filename? + delete this; } void SnapshotUploader::createStorySuccess(QNetworkReply& reply) { emit DependencyManager::get()->snapshotShared(QString()); + delete this; } void SnapshotUploader::createStoryFailure(QNetworkReply& reply) { - emit DependencyManager::get()->snapshotShared(reply.readAll()); + emit DependencyManager::get()->snapshotShared(reply.readAll()); + delete this; } \ No newline at end of file diff --git a/interface/src/ui/SnapshotUploader.h b/interface/src/ui/SnapshotUploader.h index d4a5f86431..ae6d5d55ca 100644 --- a/interface/src/ui/SnapshotUploader.h +++ b/interface/src/ui/SnapshotUploader.h @@ -14,13 +14,19 @@ #include #include +#include class SnapshotUploader : public QObject { Q_OBJECT - public slots: +public: + SnapshotUploader(QUrl inWorldLocation, QString pathname); +public slots: void uploadSuccess(QNetworkReply& reply); void uploadFailure(QNetworkReply& reply); void createStorySuccess(QNetworkReply& reply); void createStoryFailure(QNetworkReply& reply); +private: + QUrl _inWorldLocation; + QString _pathname; }; #endif // hifi_SnapshotUploader_h \ No newline at end of file From 0b80610e65c352f0cbc0b11d79b751e0aac2430e Mon Sep 17 00:00:00 2001 From: David Kelly Date: Tue, 1 Nov 2016 15:09:14 -0700 Subject: [PATCH 21/66] Needed to properly remove hrtfs for avatar audio --- assignment-client/src/audio/AudioMixer.cpp | 14 ++++++++++---- .../src/audio/AudioMixerClientData.cpp | 10 ++++++++-- assignment-client/src/audio/AudioMixerClientData.h | 2 +- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 602dd233ad..a8b0d61299 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -602,10 +602,16 @@ void AudioMixer::handleNodeKilled(SharedNodePointer killedNode) { void AudioMixer::handleKillAvatarPacket(QSharedPointer packet, SharedNodePointer sendingNode) { auto clientData = dynamic_cast(sendingNode->getLinkedData()); if (clientData) { - clientData->removeAgentAvatarAudioStream(); - // when you don't specify a stream, this removes just the QUuid() - // stream (which is the avatar's mic stream) - clientData->removeHRTFForStream(sendingNode->getUUID()); + QUuid streamID = clientData->removeAgentAvatarAudioStream(); + if (streamID != QUuid()) { + auto nodeList = DependencyManager::get(); + nodeList->eachNode([sendingNode, &streamID](const SharedNodePointer& node){ + auto listenerClientData = dynamic_cast(node->getLinkedData()); + if (listenerClientData) { + listenerClientData->removeHRTFForStream(sendingNode->getUUID(), streamID); + } + }); + } } } diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index 72914da075..4896724f8d 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -73,20 +73,26 @@ void AudioMixerClientData::removeHRTFForStream(const QUuid& nodeID, const QUuid& } } -void AudioMixerClientData::removeAgentAvatarAudioStream() { +QUuid AudioMixerClientData::removeAgentAvatarAudioStream() { QWriteLocker writeLocker { &_streamsLock }; + QUuid streamId; auto it = _audioStreams.find(QUuid()); if (it != _audioStreams.end()) { + AvatarAudioStream* stream = dynamic_cast(it->second.get()); + if (stream) { + streamId = stream->getStreamIdentifier(); + } _audioStreams.erase(it); } writeLocker.unlock(); + + return streamId; } int AudioMixerClientData::parseData(ReceivedMessage& message) { PacketType packetType = message.getType(); if (packetType == PacketType::AudioStreamStats) { - // skip over header, appendFlag, and num stats packed message.seek(sizeof(quint8) + sizeof(quint16)); diff --git a/assignment-client/src/audio/AudioMixerClientData.h b/assignment-client/src/audio/AudioMixerClientData.h index 52c659c240..0c5c49d331 100644 --- a/assignment-client/src/audio/AudioMixerClientData.h +++ b/assignment-client/src/audio/AudioMixerClientData.h @@ -50,7 +50,7 @@ public: // removes an AudioHRTF object for a given stream void removeHRTFForStream(const QUuid& nodeID, const QUuid& streamID = QUuid()); - void removeAgentAvatarAudioStream(); + QUuid removeAgentAvatarAudioStream(); int parseData(ReceivedMessage& message) override; From c1feac971b009e0a0815b9dc7acdbe6de199e1d1 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Tue, 1 Nov 2016 15:17:07 -0700 Subject: [PATCH 22/66] CR feedback --- assignment-client/src/Agent.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 0ec9b4a172..5ca5fc748d 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -420,11 +420,10 @@ void Agent::setIsListeningToAudioStream(bool isListeningToAudioStream) { auto nodeList = DependencyManager::get(); nodeList->eachMatchingNode( [&](const SharedNodePointer& node)->bool { - return (node->getType() == NodeType::AudioMixer) - && node->getActiveSocket(); + return (node->getType() == NodeType::AudioMixer) && node->getActiveSocket(); }, [&](const SharedNodePointer& node) { - qDebug() << "sending KillAvatar message to Avatar and Audio Mixers"; + qDebug() << "sending KillAvatar message to Audio Mixers"; auto packetList = NLPacketList::create(PacketType::KillAvatar, QByteArray(), true, true); packetList->write(getSessionUUID().toRfc4122()); nodeList->sendPacketList(std::move(packetList), *node); From 49f1590e01ee2a1dfeed7b43b706a03cb1b82d02 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 1 Nov 2016 16:51:57 -0700 Subject: [PATCH 23/66] Start detecting all the gpus --- libraries/shared/src/GPUIdent.cpp | 32 ++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/libraries/shared/src/GPUIdent.cpp b/libraries/shared/src/GPUIdent.cpp index 170d57fe4f..02ef4b64ab 100644 --- a/libraries/shared/src/GPUIdent.cpp +++ b/libraries/shared/src/GPUIdent.cpp @@ -65,7 +65,12 @@ GPUIdent* GPUIdent::ensureQuery(const QString& vendor, const QString& renderer) IDXGIFactory1* pFactory = nullptr; hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)(&pFactory) ); + if (hr != S_OK || pFactory == nullptr) { + qCDebug(shared) << "Unable to create DXGI"; + return this; + } + std::vector adapterDescs; // Select our adapter IDXGIAdapter1* capableAdapter = nullptr; { @@ -77,21 +82,21 @@ GPUIdent* GPUIdent::ensureQuery(const QString& vendor, const QString& renderer) break; } // query to see if there exists a corresponding compute device - - // if so, mark it as the one against which to create our d3d10 device - capableAdapter = pAdapter; - capableAdapter->AddRef(); - + DXGI_ADAPTER_DESC1 adapterDesc; + pAdapter->GetDesc1(&adapterDesc); pAdapter->Release(); + + qCDebug(shared) << "Found adapter: " << adapterDesc.Description; + + adapterDescs.push_back(adapterDesc); + } } - - DXGI_ADAPTER_DESC1 adapterDesc; - capableAdapter->GetDesc1(&adapterDesc); - - capableAdapter->Release(); pFactory->Release(); + + + // COM must be initialized already using CoInitialize. E.g., by the audio subsystem. CComPtr spLoc = NULL; hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_SERVER, IID_IWbemLocator, (LPVOID *)&spLoc); @@ -189,9 +194,10 @@ GPUIdent* GPUIdent::ensureQuery(const QString& vendor, const QString& renderer) hr = spEnumInst->Next(WBEM_INFINITE, 1, &spInstance.p, &uNumOfInstances); } - const ULONGLONG BYTES_PER_MEGABYTE = 1024 * 1024; - _dedicatedMemoryMB = (uint64_t)(adapterDesc.DedicatedVideoMemory / BYTES_PER_MEGABYTE); - + if (adapterDescs.size()) { + const ULONGLONG BYTES_PER_MEGABYTE = 1024 * 1024; + _dedicatedMemoryMB = (uint64_t)(adapterDescs[0].DedicatedVideoMemory / BYTES_PER_MEGABYTE); + } #endif return this; From ec0382daf75e3d8be61926b95e42651bd4c45ed5 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Tue, 1 Nov 2016 18:29:31 -0700 Subject: [PATCH 24/66] PR feedback Completely deleting hrtfs incorrectly. This seems to be better, we only want to delete HRTF for the QUuid() stream for the killed node in each node's list of HRTFs. --- assignment-client/src/Agent.cpp | 12 ++++++------ assignment-client/src/audio/AudioMixer.cpp | 18 ++++++++---------- .../src/audio/AudioMixerClientData.cpp | 9 +-------- .../src/audio/AudioMixerClientData.h | 2 +- 4 files changed, 16 insertions(+), 25 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 5ca5fc748d..4472b21e9b 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -424,9 +424,9 @@ void Agent::setIsListeningToAudioStream(bool isListeningToAudioStream) { }, [&](const SharedNodePointer& node) { qDebug() << "sending KillAvatar message to Audio Mixers"; - auto packetList = NLPacketList::create(PacketType::KillAvatar, QByteArray(), true, true); - packetList->write(getSessionUUID().toRfc4122()); - nodeList->sendPacketList(std::move(packetList), *node); + auto packet = NLPacket::create(PacketType::KillAvatar, NUM_BYTES_RFC4122_UUID); + packet->write(getSessionUUID().toRfc4122()); + nodeList->sendPacket(std::move(packet), *node); }); } @@ -475,9 +475,9 @@ void Agent::setIsAvatar(bool isAvatar) { }, [&](const SharedNodePointer& node) { qDebug() << "sending KillAvatar message to Avatar and Audio Mixers"; - auto packetList = NLPacketList::create(PacketType::KillAvatar, QByteArray(), true, true); - packetList->write(getSessionUUID().toRfc4122()); - nodeList->sendPacketList(std::move(packetList), *node); + auto packet = NLPacket::create(PacketType::KillAvatar, NUM_BYTES_RFC4122_UUID); + packet->write(getSessionUUID().toRfc4122()); + nodeList->sendPacket(std::move(packet), *node); }); } emit stopAvatarAudioTimer(); diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index a8b0d61299..6390ebd302 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -602,16 +602,14 @@ void AudioMixer::handleNodeKilled(SharedNodePointer killedNode) { void AudioMixer::handleKillAvatarPacket(QSharedPointer packet, SharedNodePointer sendingNode) { auto clientData = dynamic_cast(sendingNode->getLinkedData()); if (clientData) { - QUuid streamID = clientData->removeAgentAvatarAudioStream(); - if (streamID != QUuid()) { - auto nodeList = DependencyManager::get(); - nodeList->eachNode([sendingNode, &streamID](const SharedNodePointer& node){ - auto listenerClientData = dynamic_cast(node->getLinkedData()); - if (listenerClientData) { - listenerClientData->removeHRTFForStream(sendingNode->getUUID(), streamID); - } - }); - } + clientData->removeAgentAvatarAudioStream(); + auto nodeList = DependencyManager::get(); + nodeList->eachNode([sendingNode](const SharedNodePointer& node){ + auto listenerClientData = dynamic_cast(node->getLinkedData()); + if (listenerClientData) { + listenerClientData->removeHRTFForStream(sendingNode->getUUID(), QUuid()); + } + }); } } diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index 4896724f8d..5b8c4aa105 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -73,20 +73,13 @@ void AudioMixerClientData::removeHRTFForStream(const QUuid& nodeID, const QUuid& } } -QUuid AudioMixerClientData::removeAgentAvatarAudioStream() { +void AudioMixerClientData::removeAgentAvatarAudioStream() { QWriteLocker writeLocker { &_streamsLock }; - QUuid streamId; auto it = _audioStreams.find(QUuid()); if (it != _audioStreams.end()) { - AvatarAudioStream* stream = dynamic_cast(it->second.get()); - if (stream) { - streamId = stream->getStreamIdentifier(); - } _audioStreams.erase(it); } writeLocker.unlock(); - - return streamId; } int AudioMixerClientData::parseData(ReceivedMessage& message) { diff --git a/assignment-client/src/audio/AudioMixerClientData.h b/assignment-client/src/audio/AudioMixerClientData.h index 0c5c49d331..52c659c240 100644 --- a/assignment-client/src/audio/AudioMixerClientData.h +++ b/assignment-client/src/audio/AudioMixerClientData.h @@ -50,7 +50,7 @@ public: // removes an AudioHRTF object for a given stream void removeHRTFForStream(const QUuid& nodeID, const QUuid& streamID = QUuid()); - QUuid removeAgentAvatarAudioStream(); + void removeAgentAvatarAudioStream(); int parseData(ReceivedMessage& message) override; From 3c777bb079fe93df3b3e4762dc75933c89f00845 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 2 Nov 2016 12:29:51 -0700 Subject: [PATCH 25/66] Clenaing up the detection phase to get all the iformation from DXGI --- libraries/shared/src/GPUIdent.cpp | 108 ++++++++++++++++++++++++------ 1 file changed, 86 insertions(+), 22 deletions(-) diff --git a/libraries/shared/src/GPUIdent.cpp b/libraries/shared/src/GPUIdent.cpp index 02ef4b64ab..fb6f291e19 100644 --- a/libraries/shared/src/GPUIdent.cpp +++ b/libraries/shared/src/GPUIdent.cpp @@ -12,8 +12,10 @@ #ifdef Q_OS_WIN -#include -#include +#include + +//#include +//#include #include #pragma comment(lib, "dxgi.lib") @@ -58,6 +60,19 @@ GPUIdent* GPUIdent::ensureQuery(const QString& vendor, const QString& renderer) #elif defined(Q_OS_WIN) + struct ConvertLargeIntegerToQString { + QString convert(const LARGE_INTEGER& version) { + QString value; + value.append(QString::number(uint32_t(((version.HighPart & 0xFFFF0000) >> 16) & 0x0000FFFF))); + value.append("."); + value.append(QString::number(uint32_t((version.HighPart) & 0x0000FFFF))); + value.append("."); + value.append(QString::number(uint32_t(((version.LowPart & 0xFFFF0000) >> 16) & 0x0000FFFF))); + value.append("."); + value.append(QString::number(uint32_t((version.LowPart) & 0x0000FFFF))); + return value; + } + } convertDriverVersionToString; // Create the DXGI factory // Let s get into DXGI land: @@ -70,33 +85,72 @@ GPUIdent* GPUIdent::ensureQuery(const QString& vendor, const QString& renderer) return this; } - std::vector adapterDescs; - // Select our adapter - IDXGIAdapter1* capableAdapter = nullptr; + std::vector validAdapterList; + using AdapterEntry = std::pair, std::vector>; + std::vector adapterToOutputs; + // Enumerate adapters and outputs { - for (UINT adapter = 0; !capableAdapter; ++adapter) { - // get a candidate DXGI adapter - IDXGIAdapter1* pAdapter = nullptr; - hr = pFactory->EnumAdapters1(adapter, &pAdapter); - if (FAILED(hr)) { - break; - } - // query to see if there exists a corresponding compute device + UINT adapterNum = 0; + IDXGIAdapter1* pAdapter = nullptr; + while (pFactory->EnumAdapters1(adapterNum, &pAdapter) != DXGI_ERROR_NOT_FOUND) { + + // Found an adapter, get descriptor DXGI_ADAPTER_DESC1 adapterDesc; pAdapter->GetDesc1(&adapterDesc); + + LARGE_INTEGER version; + hr = pAdapter->CheckInterfaceSupport(__uuidof(IDXGIDevice), &version); + + std::wstring wDescription (adapterDesc.Description); + std::string description(wDescription.begin(), wDescription.end()); + qCDebug(shared) << "Found adapter: " << description.c_str() + << " Driver version: " << convertDriverVersionToString.convert(version); + + AdapterEntry adapterEntry; + adapterEntry.first.first = adapterDesc; + adapterEntry.first.second = version; + + + + UINT outputNum = 0; + IDXGIOutput * pOutput; + bool hasOutputConnectedToDesktop = false; + while (pAdapter->EnumOutputs(outputNum, &pOutput) != DXGI_ERROR_NOT_FOUND) { + + // FOund an output attached to the adapter, get descriptor + DXGI_OUTPUT_DESC outputDesc; + pOutput->GetDesc(&outputDesc); + + adapterEntry.second.push_back(outputDesc); + + std::wstring wDeviceName(outputDesc.DeviceName); + std::string deviceName(wDeviceName.begin(), wDeviceName.end()); + qCDebug(shared) << " Found output: " << deviceName.c_str() << " desktop: " << (outputDesc.AttachedToDesktop ? "true" : "false") + << " Rect [ l=" << outputDesc.DesktopCoordinates.left << " r=" << outputDesc.DesktopCoordinates.right + << " b=" << outputDesc.DesktopCoordinates.bottom << " t=" << outputDesc.DesktopCoordinates.top << " ]"; + + hasOutputConnectedToDesktop |= (bool) outputDesc.AttachedToDesktop; + + pOutput->Release(); + outputNum++; + } + + adapterToOutputs.push_back(adapterEntry); + + // add this adapter to the valid list if has output + if (hasOutputConnectedToDesktop && !adapterEntry.second.empty()) { + validAdapterList.push_back(adapterNum); + } + pAdapter->Release(); - - qCDebug(shared) << "Found adapter: " << adapterDesc.Description; - - adapterDescs.push_back(adapterDesc); - + adapterNum++; } } pFactory->Release(); - - + // THis was the previous technique used to detect the platform we are running on on windows. + /* // COM must be initialized already using CoInitialize. E.g., by the audio subsystem. CComPtr spLoc = NULL; hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_SERVER, IID_IWbemLocator, (LPVOID *)&spLoc); @@ -193,10 +247,20 @@ GPUIdent* GPUIdent::ensureQuery(const QString& vendor, const QString& renderer) } hr = spEnumInst->Next(WBEM_INFINITE, 1, &spInstance.p, &uNumOfInstances); } + */ + + if (!validAdapterList.empty()) { + auto& adapterEntry = adapterToOutputs[validAdapterList.front()]; + + std::wstring wDescription(adapterEntry.first.first.Description); + std::string description(wDescription.begin(), wDescription.end()); + _name = QString(description.c_str()); + + _driver = convertDriverVersionToString.convert(adapterEntry.first.second); - if (adapterDescs.size()) { const ULONGLONG BYTES_PER_MEGABYTE = 1024 * 1024; - _dedicatedMemoryMB = (uint64_t)(adapterDescs[0].DedicatedVideoMemory / BYTES_PER_MEGABYTE); + _dedicatedMemoryMB = (uint64_t)(adapterEntry.first.first.DedicatedVideoMemory / BYTES_PER_MEGABYTE); + _isValid = true; } #endif From 90ebbb79c1b51ccaa6b345781940cdeb0d712889 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Wed, 2 Nov 2016 15:37:53 -0700 Subject: [PATCH 26/66] centered toolbar --- interface/resources/qml/hifi/Desktop.qml | 24 ++++++++++++------- .../resources/qml/hifi/toolbars/Toolbar.qml | 3 +++ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/interface/resources/qml/hifi/Desktop.qml b/interface/resources/qml/hifi/Desktop.qml index 7f1fbcb174..e07c404522 100644 --- a/interface/resources/qml/hifi/Desktop.qml +++ b/interface/resources/qml/hifi/Desktop.qml @@ -51,27 +51,35 @@ OriginalDesktop.Desktop { Toolbar { id: sysToolbar; objectName: "com.highfidelity.interface.toolbar.system"; - // These values will be overridden by sysToolbar.x/y if there is a saved position in Settings - // On exit, the sysToolbar position is saved to settings - x: 30 + // Literal 50 is overwritten by settings from previous session, and sysToolbar.x comes from settings. + x: settings.firstRun ? (desktop.width - sysToolbar.width) / 2 : sysToolbar.x; y: 50 } property var toolbars: (function (map) { // answer dictionary preloaded with sysToolbar map[sysToolbar.objectName] = sysToolbar; return map; })({}); + Settings { + id: settings + property bool firstRun: true + } Component.onCompleted: { WebEngine.settings.javascriptCanOpenWindows = true; WebEngine.settings.javascriptCanAccessClipboard = false; WebEngine.settings.spatialNavigationEnabled = false; WebEngine.settings.localContentCanAccessRemoteUrls = true; - var toggleHudButton = sysToolbar.addButton({ - objectName: "hudToggle", - imageURL: "../../../icons/hud.svg", - visible: true, - pinned: true, + [ // Allocate the standard buttons in the correct order. They will get images, etc., via scripts. + "hmdToggle", "mute", "mod", "help", + "hudToggle", + "com.highfidelity.interface.system.editButton", "marketplace", "snapshot", "goto" + ].forEach(function (name) { + sysToolbar.addButton({objectName: name}); }); + var toggleHudButton = sysToolbar.findButton("hudToggle"); + toggleHudButton.imageURL = "../../../icons/hud.svg"; + toggleHudButton.pinned = true; + sysToolbar.updatePinned(); // automatic when adding buttons only IFF button is pinned at creation. toggleHudButton.buttonState = Qt.binding(function(){ return desktop.pinned ? 1 : 0 diff --git a/interface/resources/qml/hifi/toolbars/Toolbar.qml b/interface/resources/qml/hifi/toolbars/Toolbar.qml index 30989be688..01ce74cf6e 100644 --- a/interface/resources/qml/hifi/toolbars/Toolbar.qml +++ b/interface/resources/qml/hifi/toolbars/Toolbar.qml @@ -114,6 +114,9 @@ Window { // and allow scripts to be idempotent so they don't duplicate buttons if they're reloaded var result = findButton(properties.objectName); if (result) { + for (var property in properties) { + result[property] = properties[property]; + } return result; } properties.toolbar = this; From 8350dc47f4ece46d475321955349747d8d55cdfa Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 2 Nov 2016 15:40:58 -0700 Subject: [PATCH 27/66] Fix Controller.Actions not returning correct values --- libraries/controllers/src/controllers/ScriptingInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/controllers/src/controllers/ScriptingInterface.cpp b/libraries/controllers/src/controllers/ScriptingInterface.cpp index d32acb3d82..a690561813 100644 --- a/libraries/controllers/src/controllers/ScriptingInterface.cpp +++ b/libraries/controllers/src/controllers/ScriptingInterface.cpp @@ -68,7 +68,7 @@ controller::ScriptingInterface::ScriptingInterface() { // Expose the IDs to JS QString cleanActionName = QString(actionName).remove(SANITIZE_NAME_EXPRESSION); - _actions.insert(cleanActionName, actionInput.getID()); + _actions.insert(cleanActionName, actionInput.getChannel()); } updateMaps(); From 68735763df351f14ffe96bcb8d8d24bf628e8f97 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 2 Nov 2016 15:41:35 -0700 Subject: [PATCH 28/66] Add support for smooth turning in tutorial --- tutorial/tutorial.js | 45 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/tutorial/tutorial.js b/tutorial/tutorial.js index 4908465779..95a2fcd771 100644 --- a/tutorial/tutorial.js +++ b/tutorial/tutorial.js @@ -715,7 +715,8 @@ var stepTurnAround = function(name) { this.tempTag = name + "-temporary"; this.onActionBound = this.onAction.bind(this); - this.numTimesTurnPressed = 0; + this.numTimesSnapTurnPressed = 0; + this.numTimesSmoothTurnPressed = 0; } stepTurnAround.prototype = { start: function(onFinish) { @@ -724,19 +725,26 @@ stepTurnAround.prototype = { showEntitiesWithTag(this.tag); - this.numTimesTurnPressed = 0; + this.numTimesSnapTurnPressed = 0; + this.numTimesSmoothTurnPressed = 0; + this.smoothTurnDown = false; Controller.actionEvent.connect(this.onActionBound); this.interval = Script.setInterval(function() { - debug("TurnAround | Checking if finished", this.numTimesTurnPressed); + debug("TurnAround | Checking if finished", + this.numTimesSnapTurnPressed, this.numTimesSmoothTurnPressed); var FORWARD_THRESHOLD = 90; - var REQ_NUM_TIMES_PRESSED = 3; + var REQ_NUM_TIMES_SNAP_TURN_PRESSED = 3; + var REQ_NUM_TIMES_SMOOTH_TURN_PRESSED = 2; var dir = Quat.getFront(MyAvatar.orientation); var angle = Math.atan2(dir.z, dir.x); var angleDegrees = ((angle / Math.PI) * 180); - if (this.numTimesTurnPressed >= REQ_NUM_TIMES_PRESSED && Math.abs(angleDegrees) < FORWARD_THRESHOLD) { + var hasTurnedEnough = this.numTimesSnapTurnPressed >= REQ_NUM_TIMES_SNAP_TURN_PRESSED + || this.numTimesSmoothTurnPressed >= REQ_NUM_TIMES_SMOOTH_TURN_PRESSED; + var facingForward = Math.abs(angleDegrees) < FORWARD_THRESHOLD + if (hasTurnedEnough && facingForward) { Script.clearInterval(this.interval); this.interval = null; playSuccessSound(); @@ -745,10 +753,31 @@ stepTurnAround.prototype = { }.bind(this), 100); }, onAction: function(action, value) { - var STEP_YAW_ACTION = 6; + // NOTE(Huffman, 11/2/16): The checks below are for backward compatibility + // Old versions of High Fidelity returned invalid action ids from + // Controller.Actions.Yaw/StepYaw which were above 10000. If they are + // above 10000 then we can assume we are on an old version and hard-code + // the values. Eventually we should remove these checks. + var STEP_YAW_ACTION = Controller.Actions.StepYaw; + if (STEP_YAW_ACTION > 10000) { + STEP_YAW_ACTION = 6; + } + var SMOOTH_YAW_ACTION = Controller.Actions.Yaw; + if (SMOOTH_YAW_ACTION > 10000) { + SMOOTH_YAW_ACTION = 4; + } + if (action == STEP_YAW_ACTION && value != 0) { - debug("TurnAround | Got yaw action"); - this.numTimesTurnPressed += 1; + debug("TurnAround | Got step yaw action"); + ++this.numTimesSnapTurnPressed; + } else if (action == SMOOTH_YAW_ACTION) { + debug("TurnAround | Got smooth yaw action"); + if (this.smoothTurnDown && value === 0) { + this.smoothTurnDown = false; + ++this.numTimesSmoothTurnPressed; + } else if (!this.smoothTurnDown && value !== 0) { + this.smoothTurnDown = true; + } } }, cleanup: function() { From f6c0a451deccc18da8058c921d5565d37f54b596 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 2 Nov 2016 15:53:29 -0700 Subject: [PATCH 29/66] Revert "Fix Controller.Actions not returning correct values" This reverts commit 8350dc47f4ece46d475321955349747d8d55cdfa. --- libraries/controllers/src/controllers/ScriptingInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/controllers/src/controllers/ScriptingInterface.cpp b/libraries/controllers/src/controllers/ScriptingInterface.cpp index a690561813..d32acb3d82 100644 --- a/libraries/controllers/src/controllers/ScriptingInterface.cpp +++ b/libraries/controllers/src/controllers/ScriptingInterface.cpp @@ -68,7 +68,7 @@ controller::ScriptingInterface::ScriptingInterface() { // Expose the IDs to JS QString cleanActionName = QString(actionName).remove(SANITIZE_NAME_EXPRESSION); - _actions.insert(cleanActionName, actionInput.getChannel()); + _actions.insert(cleanActionName, actionInput.getID()); } updateMaps(); From cf975f966735437ac7547bfcaa9cff5280cea084 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 2 Nov 2016 15:56:19 -0700 Subject: [PATCH 30/66] Update step/smooth yaw action values to be hardcoded --- tutorial/tutorial.js | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/tutorial/tutorial.js b/tutorial/tutorial.js index 95a2fcd771..4de418eb19 100644 --- a/tutorial/tutorial.js +++ b/tutorial/tutorial.js @@ -753,19 +753,8 @@ stepTurnAround.prototype = { }.bind(this), 100); }, onAction: function(action, value) { - // NOTE(Huffman, 11/2/16): The checks below are for backward compatibility - // Old versions of High Fidelity returned invalid action ids from - // Controller.Actions.Yaw/StepYaw which were above 10000. If they are - // above 10000 then we can assume we are on an old version and hard-code - // the values. Eventually we should remove these checks. - var STEP_YAW_ACTION = Controller.Actions.StepYaw; - if (STEP_YAW_ACTION > 10000) { - STEP_YAW_ACTION = 6; - } - var SMOOTH_YAW_ACTION = Controller.Actions.Yaw; - if (SMOOTH_YAW_ACTION > 10000) { - SMOOTH_YAW_ACTION = 4; - } + var STEP_YAW_ACTION = 6; + var SMOOTH_YAW_ACTION = 4; if (action == STEP_YAW_ACTION && value != 0) { debug("TurnAround | Got step yaw action"); From d0c0cdd82f569859f76fb148610d9af3429b8117 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 2 Nov 2016 16:31:34 -0700 Subject: [PATCH 31/66] polyvox corners stitch together reliably. surface-extractor dropdown in edit.js works again --- .../src/RenderablePolyVoxEntityItem.cpp | 128 +++++++++++------- .../src/RenderablePolyVoxEntityItem.h | 7 + scripts/system/html/js/entityProperties.js | 2 +- 3 files changed, 84 insertions(+), 53 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index a2ca2a7cfe..d1dd5cce8e 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -1035,50 +1035,53 @@ void RenderablePolyVoxEntityItem::copyUpperEdgesFromNeighbors() { return; } - EntityItemPointer currentXPNeighbor = _xPNeighbor.lock(); - EntityItemPointer currentYPNeighbor = _yPNeighbor.lock(); - EntityItemPointer currentZPNeighbor = _zPNeighbor.lock(); + auto currentXPNeighbor = getXPNeighbor(); + auto currentYPNeighbor = getYPNeighbor(); + auto currentZPNeighbor = getZPNeighbor(); - if (currentXPNeighbor) { - auto polyVoxXPNeighbor = std::dynamic_pointer_cast(currentXPNeighbor); - if (polyVoxXPNeighbor->getVoxelVolumeSize() == _voxelVolumeSize) { - withWriteLock([&] { + if (currentXPNeighbor && currentXPNeighbor->getVoxelVolumeSize() == _voxelVolumeSize) { + withWriteLock([&] { + for (int y = 0; y < _volData->getHeight(); y++) { + for (int z = 0; z < _volData->getDepth(); z++) { + uint8_t neighborValue = currentXPNeighbor->getVoxel(0, y, z); + if ((y == 0 || z == 0) && _volData->getVoxelAt(_volData->getWidth() - 1, y, z) != neighborValue) { + bonkNeighbors(); + } + _volData->setVoxelAt(_volData->getWidth() - 1, y, z, neighborValue); + } + } + }); + } + + + if (currentYPNeighbor && currentYPNeighbor->getVoxelVolumeSize() == _voxelVolumeSize) { + withWriteLock([&] { + for (int x = 0; x < _volData->getWidth(); x++) { + for (int z = 0; z < _volData->getDepth(); z++) { + uint8_t neighborValue = currentYPNeighbor->getVoxel(x, 0, z); + if ((x == 0 || z == 0) && _volData->getVoxelAt(x, _volData->getHeight() - 1, z) != neighborValue) { + bonkNeighbors(); + } + _volData->setVoxelAt(x, _volData->getHeight() - 1, z, neighborValue); + } + } + }); + } + + + if (currentZPNeighbor && currentZPNeighbor->getVoxelVolumeSize() == _voxelVolumeSize) { + withWriteLock([&] { + for (int x = 0; x < _volData->getWidth(); x++) { for (int y = 0; y < _volData->getHeight(); y++) { - for (int z = 0; z < _volData->getDepth(); z++) { - uint8_t neighborValue = polyVoxXPNeighbor->getVoxel(0, y, z); - _volData->setVoxelAt(_volData->getWidth() - 1, y, z, neighborValue); + uint8_t neighborValue = currentZPNeighbor->getVoxel(x, y, 0); + _volData->setVoxelAt(x, y, _volData->getDepth() - 1, neighborValue); + if ((x == 0 || y == 0) && _volData->getVoxelAt(x, y, _volData->getDepth() - 1) != neighborValue) { + bonkNeighbors(); } + _volData->setVoxelAt(x, y, _volData->getDepth() - 1, neighborValue); } - }); - } - } - - if (currentYPNeighbor) { - auto polyVoxYPNeighbor = std::dynamic_pointer_cast(currentYPNeighbor); - if (polyVoxYPNeighbor->getVoxelVolumeSize() == _voxelVolumeSize) { - withWriteLock([&] { - for (int x = 0; x < _volData->getWidth(); x++) { - for (int z = 0; z < _volData->getDepth(); z++) { - uint8_t neighborValue = polyVoxYPNeighbor->getVoxel(x, 0, z); - _volData->setVoxelAt(x, _volData->getWidth() - 1, z, neighborValue); - } - } - }); - } - } - - if (currentZPNeighbor) { - auto polyVoxZPNeighbor = std::dynamic_pointer_cast(currentZPNeighbor); - if (polyVoxZPNeighbor->getVoxelVolumeSize() == _voxelVolumeSize) { - withWriteLock([&] { - for (int x = 0; x < _volData->getWidth(); x++) { - for (int y = 0; y < _volData->getHeight(); y++) { - uint8_t neighborValue = polyVoxZPNeighbor->getVoxel(x, y, 0); - _volData->setVoxelAt(x, y, _volData->getDepth() - 1, neighborValue); - } - } - }); - } + } + }); } } @@ -1393,25 +1396,46 @@ void RenderablePolyVoxEntityItem::setZPNeighborID(const EntityItemID& zPNeighbor } } +std::shared_ptr RenderablePolyVoxEntityItem::getXNNeighbor() { + return std::dynamic_pointer_cast(_xNNeighbor.lock()); +} + +std::shared_ptr RenderablePolyVoxEntityItem::getYNNeighbor() { + return std::dynamic_pointer_cast(_yNNeighbor.lock()); +} + +std::shared_ptr RenderablePolyVoxEntityItem::getZNNeighbor() { + return std::dynamic_pointer_cast(_zNNeighbor.lock()); +} + +std::shared_ptr RenderablePolyVoxEntityItem::getXPNeighbor() { + return std::dynamic_pointer_cast(_xPNeighbor.lock()); +} + +std::shared_ptr RenderablePolyVoxEntityItem::getYPNeighbor() { + return std::dynamic_pointer_cast(_yPNeighbor.lock()); +} + +std::shared_ptr RenderablePolyVoxEntityItem::getZPNeighbor() { + return std::dynamic_pointer_cast(_zPNeighbor.lock()); +} + void RenderablePolyVoxEntityItem::bonkNeighbors() { // flag neighbors to the negative of this entity as needing to rebake their meshes. cacheNeighbors(); - EntityItemPointer currentXNNeighbor = _xNNeighbor.lock(); - EntityItemPointer currentYNNeighbor = _yNNeighbor.lock(); - EntityItemPointer currentZNNeighbor = _zNNeighbor.lock(); + auto currentXNNeighbor = getXNNeighbor(); + auto currentYNNeighbor = getYNNeighbor(); + auto currentZNNeighbor = getZNNeighbor(); - if (currentXNNeighbor && currentXNNeighbor->getType() == EntityTypes::PolyVox) { - auto polyVoxXNNeighbor = std::dynamic_pointer_cast(currentXNNeighbor); - polyVoxXNNeighbor->setVolDataDirty(); + if (currentXNNeighbor) { + currentXNNeighbor->setVolDataDirty(); } - if (currentYNNeighbor && currentYNNeighbor->getType() == EntityTypes::PolyVox) { - auto polyVoxYNNeighbor = std::dynamic_pointer_cast(currentYNNeighbor); - polyVoxYNNeighbor->setVolDataDirty(); + if (currentYNNeighbor) { + currentYNNeighbor->setVolDataDirty(); } - if (currentZNNeighbor && currentZNNeighbor->getType() == EntityTypes::PolyVox) { - auto polyVoxZNNeighbor = std::dynamic_pointer_cast(currentZNNeighbor); - polyVoxZNNeighbor->setVolDataDirty(); + if (currentZNNeighbor) { + currentZNNeighbor->setVolDataDirty(); } } diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index 44186073b2..f84637ec95 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -116,6 +116,13 @@ public: virtual void setYPNeighborID(const EntityItemID& yPNeighborID) override; virtual void setZPNeighborID(const EntityItemID& zPNeighborID) override; + std::shared_ptr getXNNeighbor(); + std::shared_ptr getYNNeighbor(); + std::shared_ptr getZNNeighbor(); + std::shared_ptr getXPNeighbor(); + std::shared_ptr getYPNeighbor(); + std::shared_ptr getZPNeighbor(); + virtual void updateRegistrationPoint(const glm::vec3& value) override; void setVoxelsFromData(QByteArray uncompressedData, quint16 voxelXSize, quint16 voxelYSize, quint16 voxelZSize); diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index a7dfb048b8..d6d9098e21 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -1492,7 +1492,7 @@ function loaded() { var lis = dropdown.parentNode.getElementsByTagName("li"); var text = ""; for (var i = 0; i < lis.length; i++) { - if (lis[i].getAttribute("value") === dropdown.value) { + if (String(lis[i].getAttribute("value")) === String(dropdown.value)) { text = lis[i].textContent; } } From 8eb6699420414d5f604bb85241c444af145d9737 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Wed, 2 Nov 2016 16:50:37 -0700 Subject: [PATCH 32/66] help script --- scripts/defaultScripts.js | 3 +- scripts/system/assets/images/tools/help.svg | 110 ++++++++++++++++++++ scripts/system/help.js | 41 ++++++++ 3 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 scripts/system/assets/images/tools/help.svg create mode 100644 scripts/system/help.js diff --git a/scripts/defaultScripts.js b/scripts/defaultScripts.js index 718b5f3d3e..4376960ea5 100644 --- a/scripts/defaultScripts.js +++ b/scripts/defaultScripts.js @@ -32,7 +32,8 @@ var DEFAULT_SCRIPTS = [ "system/controllers/toggleAdvancedMovementForHandControllers.js", "system/dialTone.js", "system/firstPersonHMD.js", - "system/snapshot.js" + "system/snapshot.js", + "system/help.js" ]; // add a menu item for debugging diff --git a/scripts/system/assets/images/tools/help.svg b/scripts/system/assets/images/tools/help.svg new file mode 100644 index 0000000000..b7fa8ca5cd --- /dev/null +++ b/scripts/system/assets/images/tools/help.svg @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/system/help.js b/scripts/system/help.js new file mode 100644 index 0000000000..e79ed0444c --- /dev/null +++ b/scripts/system/help.js @@ -0,0 +1,41 @@ +"use strict"; + +// +// help.js +// scripts/system/ +// +// Created by Howard Stearns on 2 Nov 2016 +// Copyright 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 +// + +(function() { // BEGIN LOCAL_SCOPE + + var toolBar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system"); + var buttonName = "help"; // matching location reserved in Desktop.qml + var button = toolBar.addButton({ + objectName: buttonName, + imageURL: Script.resolvePath("assets/images/tools/help.svg"), + visible: true, + hoverState: 2, + defaultState: 1, + buttonState: 1, + alpha: 0.9 + }); + + // TODO: make button state reflect whether the window is opened or closed (independently from us). + + function onClicked(){ + Menu.triggerOption('Help...') + } + + button.clicked.connect(onClicked); + + Script.scriptEnding.connect(function () { + toolBar.removeButton(buttonName); + button.clicked.disconnect(onClicked); + }); + +}()); // END LOCAL_SCOPE From 64cb5d1b1a0d5b0b41b44e99326a1507b685bab5 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 2 Nov 2016 20:02:07 -0700 Subject: [PATCH 33/66] fix QVector packing when number of joints isn't a multiple of 8 --- libraries/octree/src/OctreePacketData.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/octree/src/OctreePacketData.cpp b/libraries/octree/src/OctreePacketData.cpp index 5380aaa6ce..5cd93bb0e1 100644 --- a/libraries/octree/src/OctreePacketData.cpp +++ b/libraries/octree/src/OctreePacketData.cpp @@ -451,6 +451,9 @@ bool OctreePacketData::appendValue(const QVector& value) { bit = 0; } } + if (bit != 0) { + destinationBuffer++; + } int boolsSize = destinationBuffer - start; success = append(start, boolsSize); if (success) { From cfea3cba9b0ba9654b871f712676d6595121cf7d Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 3 Nov 2016 06:54:11 -0700 Subject: [PATCH 34/66] guard against heap-overflow in the event of bogus entity network data --- libraries/octree/src/OctreePacketData.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/libraries/octree/src/OctreePacketData.cpp b/libraries/octree/src/OctreePacketData.cpp index 5cd93bb0e1..5344fad430 100644 --- a/libraries/octree/src/OctreePacketData.cpp +++ b/libraries/octree/src/OctreePacketData.cpp @@ -686,6 +686,10 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char *dataBytes, QVecto uint16_t length; memcpy(&length, dataBytes, sizeof(uint16_t)); dataBytes += sizeof(length); + if (length * sizeof(glm::vec3) > MAX_OCTREE_UNCOMRESSED_PACKET_SIZE) { + result.resize(0); + return sizeof(uint16_t); + } result.resize(length); memcpy(result.data(), dataBytes, length * sizeof(glm::vec3)); return sizeof(uint16_t) + length * sizeof(glm::vec3); @@ -695,6 +699,10 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char *dataBytes, QVecto uint16_t length; memcpy(&length, dataBytes, sizeof(uint16_t)); dataBytes += sizeof(length); + if (length * sizeof(glm::quat) > MAX_OCTREE_UNCOMRESSED_PACKET_SIZE) { + result.resize(0); + return sizeof(uint16_t); + } result.resize(length); const unsigned char *start = dataBytes; @@ -709,6 +717,10 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QVecto uint16_t length; memcpy(&length, dataBytes, sizeof(uint16_t)); dataBytes += sizeof(length); + if (length * sizeof(float) > MAX_OCTREE_UNCOMRESSED_PACKET_SIZE) { + result.resize(0); + return sizeof(uint16_t); + } result.resize(length); memcpy(result.data(), dataBytes, length * sizeof(float)); return sizeof(uint16_t) + length * sizeof(float); @@ -718,6 +730,10 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QVecto uint16_t length; memcpy(&length, dataBytes, sizeof(uint16_t)); dataBytes += sizeof(length); + if (length * sizeof(bool) > MAX_OCTREE_UNCOMRESSED_PACKET_SIZE) { + result.resize(0); + return sizeof(uint16_t); + } result.resize(length); int bit = 0; From cd5826e2ce5cbb67f4328469d82b76455c098d14 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 3 Nov 2016 09:03:04 -0700 Subject: [PATCH 35/66] load model of new entity with unknown dimensions --- .../src/RenderableModelEntityItem.cpp | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 95d28f74f3..332a88e499 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -55,7 +55,10 @@ void RenderableModelEntityItem::setModelURL(const QString& url) { auto& currentURL = getParsedModelURL(); ModelEntityItem::setModelURL(url); - if (currentURL != getParsedModelURL() || !_model) { + if (currentURL != getParsedModelURL()) { + _needsModelReload = true; + } + if (_needsModelReload || !_model) { EntityTreePointer tree = getTree(); if (tree) { QMetaObject::invokeMethod(tree.get(), "callLoader", Qt::QueuedConnection, Q_ARG(EntityItemID, getID())); @@ -523,17 +526,24 @@ bool RenderableModelEntityItem::needsToCallUpdate() const { } void RenderableModelEntityItem::update(const quint64& now) { - if (!_dimensionsInitialized && _model && _model->isActive()) { - if (_model->isLoaded()) { - EntityItemProperties properties; - properties.setLastEdited(usecTimestampNow()); // we must set the edit time since we're editing it - auto extents = _model->getMeshExtents(); - properties.setDimensions(extents.maximum - extents.minimum); - qCDebug(entitiesrenderer) << "Autoresizing:" << (!getName().isEmpty() ? getName() : getModelURL()); - QMetaObject::invokeMethod(DependencyManager::get().data(), "editEntity", - Qt::QueuedConnection, - Q_ARG(QUuid, getEntityItemID()), - Q_ARG(EntityItemProperties, properties)); + if (!_dimensionsInitialized) { + if (_model) { + if (_model->isActive() && _model->isLoaded()) { + EntityItemProperties properties; + properties.setLastEdited(usecTimestampNow()); // we must set the edit time since we're editing it + auto extents = _model->getMeshExtents(); + properties.setDimensions(extents.maximum - extents.minimum); + qCDebug(entitiesrenderer) << "Autoresizing:" << (!getName().isEmpty() ? getName() : getModelURL()); + QMetaObject::invokeMethod(DependencyManager::get().data(), "editEntity", + Qt::QueuedConnection, + Q_ARG(QUuid, getEntityItemID()), + Q_ARG(EntityItemProperties, properties)); + } + } else if (_needsModelReload) { + EntityTreePointer tree = getTree(); + if (tree) { + QMetaObject::invokeMethod(tree.get(), "callLoader", Qt::QueuedConnection, Q_ARG(EntityItemID, getID())); + } } } From b7c692254515cf0a82e5efc7a5ece646f0c6f18e Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 3 Nov 2016 09:17:22 -0700 Subject: [PATCH 36/66] proper corner case check for Quat::lookAtSimple() --- libraries/script-engine/src/Quat.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/libraries/script-engine/src/Quat.cpp b/libraries/script-engine/src/Quat.cpp index c0b87c9a5c..6c2e7a349e 100644 --- a/libraries/script-engine/src/Quat.cpp +++ b/libraries/script-engine/src/Quat.cpp @@ -37,29 +37,30 @@ glm::quat Quat::lookAt(const glm::vec3& eye, const glm::vec3& center, const glm: glm::quat Quat::lookAtSimple(const glm::vec3& eye, const glm::vec3& center) { auto dir = glm::normalize(center - eye); // if the direction is nearly aligned with the Y axis, then use the X axis for 'up' - if (dir.x < 0.001f && dir.z < 0.001f) { + const float MAX_ABS_Y_COMPONENT = 0.9999991f; + if (fabsf(dir.y) > MAX_ABS_Y_COMPONENT) { return lookAt(eye, center, Vectors::UNIT_X); } return lookAt(eye, center, Vectors::UNIT_Y); } -glm::quat Quat::multiply(const glm::quat& q1, const glm::quat& q2) { - return q1 * q2; +glm::quat Quat::multiply(const glm::quat& q1, const glm::quat& q2) { + return q1 * q2; } -glm::quat Quat::fromVec3Degrees(const glm::vec3& eulerAngles) { - return glm::quat(glm::radians(eulerAngles)); +glm::quat Quat::fromVec3Degrees(const glm::vec3& eulerAngles) { + return glm::quat(glm::radians(eulerAngles)); } -glm::quat Quat::fromVec3Radians(const glm::vec3& eulerAngles) { - return glm::quat(eulerAngles); +glm::quat Quat::fromVec3Radians(const glm::vec3& eulerAngles) { + return glm::quat(eulerAngles); } -glm::quat Quat::fromPitchYawRollDegrees(float pitch, float yaw, float roll) { +glm::quat Quat::fromPitchYawRollDegrees(float pitch, float yaw, float roll) { return glm::quat(glm::radians(glm::vec3(pitch, yaw, roll))); } -glm::quat Quat::fromPitchYawRollRadians(float pitch, float yaw, float roll) { +glm::quat Quat::fromPitchYawRollRadians(float pitch, float yaw, float roll) { return glm::quat(glm::vec3(pitch, yaw, roll)); } From 1d0c3d71688d8aa897a8ec93581b815595964186 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 3 Nov 2016 09:47:24 -0700 Subject: [PATCH 37/66] fix checker for unreasonable size of vector of bools --- libraries/octree/src/OctreePacketData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/octree/src/OctreePacketData.cpp b/libraries/octree/src/OctreePacketData.cpp index 5344fad430..5fd7e4dba3 100644 --- a/libraries/octree/src/OctreePacketData.cpp +++ b/libraries/octree/src/OctreePacketData.cpp @@ -730,7 +730,7 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QVecto uint16_t length; memcpy(&length, dataBytes, sizeof(uint16_t)); dataBytes += sizeof(length); - if (length * sizeof(bool) > MAX_OCTREE_UNCOMRESSED_PACKET_SIZE) { + if (length / 8 > MAX_OCTREE_UNCOMRESSED_PACKET_SIZE) { result.resize(0); return sizeof(uint16_t); } From f3d482157906c7268a068f1a3706418d6a4cef90 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Thu, 3 Nov 2016 10:39:53 -0700 Subject: [PATCH 38/66] constrain toolbar based on setting. (ui for settings to come.) --- interface/resources/qml/hifi/Desktop.qml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/Desktop.qml b/interface/resources/qml/hifi/Desktop.qml index e07c404522..fbb3a713ae 100644 --- a/interface/resources/qml/hifi/Desktop.qml +++ b/interface/resources/qml/hifi/Desktop.qml @@ -51,8 +51,9 @@ OriginalDesktop.Desktop { Toolbar { id: sysToolbar; objectName: "com.highfidelity.interface.toolbar.system"; - // Literal 50 is overwritten by settings from previous session, and sysToolbar.x comes from settings. - x: settings.firstRun ? (desktop.width - sysToolbar.width) / 2 : sysToolbar.x; + anchors.horizontalCenter: settings.systemToolbarHorizontalConstraint ? desktop.horizontalCenter : undefined; + // Literal 50 is overwritten by settings from previous session, and sysToolbar.x comes from settings when not constrained. + x: sysToolbar.x y: 50 } property var toolbars: (function (map) { // answer dictionary preloaded with sysToolbar @@ -61,7 +62,7 @@ OriginalDesktop.Desktop { Settings { id: settings - property bool firstRun: true + property bool systemToolbarHorizontalConstraint: true } Component.onCompleted: { WebEngine.settings.javascriptCanOpenWindows = true; From a12e0325bf627e7759b931ebbf0c596f5df005ef Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 3 Nov 2016 10:37:06 -0700 Subject: [PATCH 39/66] Making progress... --- .../qml/hifi/dialogs/GeneralPreferencesDialog.qml | 2 +- interface/resources/qml/hifi/toolbars/Toolbar.qml | 2 ++ interface/src/Application.cpp | 5 +++++ interface/src/Application.h | 4 ++++ interface/src/ui/PreferencesDialog.cpp | 9 ++++++++- 5 files changed, 20 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/dialogs/GeneralPreferencesDialog.qml b/interface/resources/qml/hifi/dialogs/GeneralPreferencesDialog.qml index 95f55f504b..9e46d86ecd 100644 --- a/interface/resources/qml/hifi/dialogs/GeneralPreferencesDialog.qml +++ b/interface/resources/qml/hifi/dialogs/GeneralPreferencesDialog.qml @@ -17,7 +17,7 @@ PreferencesDialog { id: root objectName: "GeneralPreferencesDialog" title: "General Settings" - showCategories: ["Snapshots", "Scripts", "Privacy", "Octree", "HMD", "Sixense Controllers"] + showCategories: ["UI", "Snapshots", "Scripts", "Privacy", "Octree", "HMD", "Sixense Controllers"] property var settings: Settings { category: root.objectName property alias x: root.x diff --git a/interface/resources/qml/hifi/toolbars/Toolbar.qml b/interface/resources/qml/hifi/toolbars/Toolbar.qml index 30989be688..2968d61324 100644 --- a/interface/resources/qml/hifi/toolbars/Toolbar.qml +++ b/interface/resources/qml/hifi/toolbars/Toolbar.qml @@ -25,11 +25,13 @@ Window { property real buttonSize: 50; property var buttons: [] property var container: horizontal ? row : column + property bool constrainToolbarToCenterX: false Settings { category: "toolbar/" + window.objectName property alias x: window.x property alias y: window.y + property alias constrainToolbarToCenterX: window.constrainToolbarToCenterX } onHorizontalChanged: { diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5fe15fa8e5..ecedc33542 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -523,6 +523,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)), _previousScriptLocation("LastScriptLocation", DESKTOP_LOCATION), _fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES), + _constrainToolbarPosition("constrainToolbarToCenterX", false), _scaleMirror(1.0f), _rotateMirror(0.0f), _raiseMirror(0.0f), @@ -2150,6 +2151,10 @@ void Application::setFieldOfView(float fov) { } } +void Application::setSettingConstrainToolbarPosition(bool setting) { + _constrainToolbarPosition.set(setting); +} + void Application::aboutApp() { InfoView::show(INFO_WELCOME_PATH); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 79c9ae735c..4c98be9c2d 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -206,6 +206,9 @@ public: float getFieldOfView() { return _fieldOfView.get(); } void setFieldOfView(float fov); + float getSettingConstrainToolbarPosition() { return _constrainToolbarPosition.get(); } + void setSettingConstrainToolbarPosition(bool setting); + NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; } virtual controller::ScriptingInterface* getControllerScriptingInterface() { return _controllerScriptingInterface; } @@ -506,6 +509,7 @@ private: Setting::Handle _previousScriptLocation; Setting::Handle _fieldOfView; + Setting::Handle _constrainToolbarPosition; float _scaleMirror; float _rotateMirror; diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 8e65b2fb57..37135a9379 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -66,7 +66,14 @@ void setupPreferences() { auto getter = [=]()->bool { return myAvatar->getClearOverlayWhenMoving(); }; auto setter = [=](bool value) { myAvatar->setClearOverlayWhenMoving(value); }; preferences->addPreference(new CheckPreference(AVATAR_BASICS, "Clear overlays when moving", getter, setter)); - } + } + + // UI + { + auto getter = []()->bool { return qApp->getSettingConstrainToolbarPosition(); }; + auto setter = [](bool value) { qApp->setSettingConstrainToolbarPosition(!value); }; + preferences->addPreference(new CheckPreference("UI", "Constrain Toolbar Position to Horizontal Center", getter, setter)); + } // Snapshots static const QString SNAPSHOTS { "Snapshots" }; From b74c1d3476fcac27cf08647f0bd29a9cc3f3fcc1 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 3 Nov 2016 10:42:15 -0700 Subject: [PATCH 40/66] tabs to spaces --- interface/resources/qml/hifi/toolbars/Toolbar.qml | 4 ++-- interface/src/Application.cpp | 2 +- interface/src/ui/PreferencesDialog.cpp | 14 +++++++------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/interface/resources/qml/hifi/toolbars/Toolbar.qml b/interface/resources/qml/hifi/toolbars/Toolbar.qml index 2968d61324..f26f4b8a96 100644 --- a/interface/resources/qml/hifi/toolbars/Toolbar.qml +++ b/interface/resources/qml/hifi/toolbars/Toolbar.qml @@ -25,13 +25,13 @@ Window { property real buttonSize: 50; property var buttons: [] property var container: horizontal ? row : column - property bool constrainToolbarToCenterX: false + property bool constrainToolbarToCenterX: false Settings { category: "toolbar/" + window.objectName property alias x: window.x property alias y: window.y - property alias constrainToolbarToCenterX: window.constrainToolbarToCenterX + property alias constrainToolbarToCenterX: window.constrainToolbarToCenterX } onHorizontalChanged: { diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ecedc33542..85406a1e81 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2152,7 +2152,7 @@ void Application::setFieldOfView(float fov) { } void Application::setSettingConstrainToolbarPosition(bool setting) { - _constrainToolbarPosition.set(setting); + _constrainToolbarPosition.set(setting); } void Application::aboutApp() { diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 37135a9379..70be1f61d5 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -66,14 +66,14 @@ void setupPreferences() { auto getter = [=]()->bool { return myAvatar->getClearOverlayWhenMoving(); }; auto setter = [=](bool value) { myAvatar->setClearOverlayWhenMoving(value); }; preferences->addPreference(new CheckPreference(AVATAR_BASICS, "Clear overlays when moving", getter, setter)); - } + } - // UI - { - auto getter = []()->bool { return qApp->getSettingConstrainToolbarPosition(); }; - auto setter = [](bool value) { qApp->setSettingConstrainToolbarPosition(!value); }; - preferences->addPreference(new CheckPreference("UI", "Constrain Toolbar Position to Horizontal Center", getter, setter)); - } + // UI + { + auto getter = []()->bool { return qApp->getSettingConstrainToolbarPosition(); }; + auto setter = [](bool value) { qApp->setSettingConstrainToolbarPosition(!value); }; + preferences->addPreference(new CheckPreference("UI", "Constrain Toolbar Position to Horizontal Center", getter, setter)); + } // Snapshots static const QString SNAPSHOTS { "Snapshots" }; From e9e1d0cb2fccab5c6b21a5632080260f5ba03605 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 3 Nov 2016 11:10:32 -0700 Subject: [PATCH 41/66] Remove erroneous exclamation mark --- interface/src/ui/PreferencesDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 70be1f61d5..7d3261aa78 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -71,7 +71,7 @@ void setupPreferences() { // UI { auto getter = []()->bool { return qApp->getSettingConstrainToolbarPosition(); }; - auto setter = [](bool value) { qApp->setSettingConstrainToolbarPosition(!value); }; + auto setter = [](bool value) { qApp->setSettingConstrainToolbarPosition(value); }; preferences->addPreference(new CheckPreference("UI", "Constrain Toolbar Position to Horizontal Center", getter, setter)); } From 9a22c29788b5ee9a8f6fe1622a855c7f55454899 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 3 Nov 2016 11:20:08 -0700 Subject: [PATCH 42/66] Get ready for merge --- interface/resources/qml/hifi/toolbars/Toolbar.qml | 2 -- interface/src/Application.cpp | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/toolbars/Toolbar.qml b/interface/resources/qml/hifi/toolbars/Toolbar.qml index f26f4b8a96..30989be688 100644 --- a/interface/resources/qml/hifi/toolbars/Toolbar.qml +++ b/interface/resources/qml/hifi/toolbars/Toolbar.qml @@ -25,13 +25,11 @@ Window { property real buttonSize: 50; property var buttons: [] property var container: horizontal ? row : column - property bool constrainToolbarToCenterX: false Settings { category: "toolbar/" + window.objectName property alias x: window.x property alias y: window.y - property alias constrainToolbarToCenterX: window.constrainToolbarToCenterX } onHorizontalChanged: { diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 85406a1e81..ae07ed1226 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -523,7 +523,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)), _previousScriptLocation("LastScriptLocation", DESKTOP_LOCATION), _fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES), - _constrainToolbarPosition("constrainToolbarToCenterX", false), + _constrainToolbarPosition("toolbar/constrainToolbarToCenterX", true), _scaleMirror(1.0f), _rotateMirror(0.0f), _raiseMirror(0.0f), From 3a072b5bf972ad6af351c6abdddef0c1719268f3 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Thu, 3 Nov 2016 12:17:28 -0700 Subject: [PATCH 43/66] tell desktop about preference changes --- interface/resources/qml/hifi/Desktop.qml | 15 ++++++++++----- interface/src/Application.cpp | 1 + libraries/ui/src/OffscreenUi.cpp | 7 +++++++ libraries/ui/src/OffscreenUi.h | 1 + 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/interface/resources/qml/hifi/Desktop.qml b/interface/resources/qml/hifi/Desktop.qml index fbb3a713ae..db0c1ba724 100644 --- a/interface/resources/qml/hifi/Desktop.qml +++ b/interface/resources/qml/hifi/Desktop.qml @@ -51,19 +51,24 @@ OriginalDesktop.Desktop { Toolbar { id: sysToolbar; objectName: "com.highfidelity.interface.toolbar.system"; - anchors.horizontalCenter: settings.systemToolbarHorizontalConstraint ? desktop.horizontalCenter : undefined; + anchors.horizontalCenter: settings.constrainToolbarToCenterX ? desktop.horizontalCenter : undefined; // Literal 50 is overwritten by settings from previous session, and sysToolbar.x comes from settings when not constrained. x: sysToolbar.x y: 50 } + Settings { + id: settings; + category: "toolbar"; + property bool constrainToolbarToCenterX: true; + } + function setConstrainToolbarToCenterX(constrain) { // Learn about c++ preference change. + settings.constrainToolbarToCenterX = constrain; + } property var toolbars: (function (map) { // answer dictionary preloaded with sysToolbar map[sysToolbar.objectName] = sysToolbar; return map; })({}); - Settings { - id: settings - property bool systemToolbarHorizontalConstraint: true - } + Component.onCompleted: { WebEngine.settings.javascriptCanOpenWindows = true; WebEngine.settings.javascriptCanAccessClipboard = false; diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ae07ed1226..bbf97ad60c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2153,6 +2153,7 @@ void Application::setFieldOfView(float fov) { void Application::setSettingConstrainToolbarPosition(bool setting) { _constrainToolbarPosition.set(setting); + DependencyManager::get()->setConstrainToolbarToCenterX(setting); } void Application::aboutApp() { diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index ca7d3f7c17..d9b15eebe0 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -371,6 +371,13 @@ void OffscreenUi::setPinned(bool pinned) { } } +void OffscreenUi::setConstrainToolbarToCenterX(bool constrained) { + bool invokeResult = QMetaObject::invokeMethod(_desktop, "setConstrainToolbarToCenterX", Q_ARG(QVariant, constrained)); + if (!invokeResult) { + qWarning() << "Failed to set toolbar constraint"; + } +} + void OffscreenUi::addMenuInitializer(std::function f) { if (!_vrMenu) { _queuedMenuInitializers.push_back(f); diff --git a/libraries/ui/src/OffscreenUi.h b/libraries/ui/src/OffscreenUi.h index 2e6e853336..3ab4fa0758 100644 --- a/libraries/ui/src/OffscreenUi.h +++ b/libraries/ui/src/OffscreenUi.h @@ -52,6 +52,7 @@ public: void setPinned(bool pinned = true); void togglePinned(); + void setConstrainToolbarToCenterX(bool constrained); bool eventFilter(QObject* originalDestination, QEvent* event) override; void addMenuInitializer(std::function f); From 6a39ad3b5aa1e1559fa7436cd2e85c3632d6db5f Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 3 Nov 2016 13:01:41 -0700 Subject: [PATCH 44/66] Prevent sparse texture on AMD gpus for now --- libraries/gpu-gl/src/gpu/gl/GLBackend.cpp | 1 + libraries/gpu-gl/src/gpu/gl/GLBackend.h | 9 ++++++++ libraries/gpu-gl/src/gpu/gl45/GL45Backend.h | 4 ++++ .../src/gpu/gl45/GL45BackendTexture.cpp | 22 +++++++++++++++++-- libraries/gpu/src/gpu/Context.h | 4 ++-- libraries/gpu/src/gpu/Texture.h | 1 + 6 files changed, 37 insertions(+), 4 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp index 2e1084e581..3513d7a05b 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp @@ -56,6 +56,7 @@ BackendPointer GLBackend::createBackend() { } result->initInput(); result->initTransform(); + result->initTextureManagementStage(); INSTANCE = result.get(); void* voidInstance = &(*result); diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackend.h b/libraries/gpu-gl/src/gpu/gl/GLBackend.h index f99d34393c..fad433d4a2 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl/src/gpu/gl/GLBackend.h @@ -176,6 +176,9 @@ public: virtual void releaseQuery(GLuint id) const; virtual void queueLambda(const std::function lambda) const; + bool isTextureManagementSparseEnabled() const { return (_textureManagement._sparseCapable && Texture::getEnableSparseTextures()); } + bool isTextureManagementIncrementalTransferEnabled() const { return (_textureManagement._incrementalTransferCapable && Texture::getEnableIncrementalTextureTransfers()); } + protected: void recycle() const override; @@ -364,6 +367,12 @@ protected: void resetStages(); + struct TextureManagementStageState { + bool _sparseCapable { false }; + bool _incrementalTransferCapable { false }; + } _textureManagement; + virtual void initTextureManagementStage() {} + typedef void (GLBackend::*CommandCall)(const Batch&, size_t); static CommandCall _commandCalls[Batch::NUM_COMMANDS]; friend class GLState; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h index 059156b4a3..643d54af6a 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h +++ b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h @@ -32,6 +32,7 @@ public: static GLuint allocate(const Texture& texture); static const uint32_t DEFAULT_PAGE_DIMENSION = 128; static const uint32_t DEFAULT_MAX_SPARSE_LEVEL = 0xFFFF; + public: GL45Texture(const std::weak_ptr& backend, const Texture& texture, GLuint externalId); GL45Texture(const std::weak_ptr& backend, const Texture& texture, bool transferrable); @@ -132,6 +133,9 @@ protected: // Output stage void do_blit(const Batch& batch, size_t paramOffset) override; + + // Texture Management Stage + void initTextureManagementStage() override; }; } } diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index 621c619954..07b4ca084d 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -148,6 +148,22 @@ uint32_t SparseInfo::getPageCount(const uvec3& dimensions) const { return pageCounts.x * pageCounts.y * pageCounts.z; } + + +void GL45Backend::initTextureManagementStage() { + + // enable the Sparse Texture on gl45 + _textureManagement._sparseCapable = true; + _textureManagement._incrementalTransferCapable = true; + + // But now let s refine the behavior based on vendor + std::string vendor { (const char*)glGetString(GL_VENDOR) }; + if ((vendor.compare("AMD") <= 0) || (vendor.compare("INTEL") <= 0)) { + qCDebug(gpugllogging, "GPU is sparse capable but force it off %s\n", vendor); + _textureManagement._sparseCapable = false; + } +} + using TransferState = GL45Backend::GL45Texture::TransferState; TransferState::TransferState(GL45Texture& texture) : texture(texture) { @@ -250,7 +266,8 @@ GL45Texture::GL45Texture(const std::weak_ptr& backend, const Texture& GL45Texture::GL45Texture(const std::weak_ptr& backend, const Texture& texture, bool transferrable) : GLTexture(backend, texture, allocate(texture), transferrable), _sparseInfo(*this), _transferState(*this) { - if (_transferrable && Texture::getEnableSparseTextures()) { + auto theBackend = _backend.lock(); + if (_transferrable && theBackend && theBackend->isTextureManagementSparseEnabled()) { _sparseInfo.maybeMakeSparse(); if (_sparseInfo.sparse) { Backend::incrementTextureGPUSparseCount(); @@ -362,7 +379,8 @@ void GL45Texture::startTransfer() { } bool GL45Texture::continueTransfer() { - if (!Texture::getEnableIncrementalTextureTransfers()) { + auto backend = _backend.lock(); + if (!backend || !backend->isTextureManagementIncrementalTransferEnabled()) { size_t maxFace = GL_TEXTURE_CUBE_MAP == _target ? CUBE_NUM_FACES : 1; for (uint8_t face = 0; face < maxFace; ++face) { for (uint16_t mipLevel = _minMip; mipLevel <= _maxMip; ++mipLevel) { diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index 763e91b3e4..56d1930c94 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -125,6 +125,7 @@ protected: friend class Context; ContextStats _stats; StereoState _stereo; + }; class Context { @@ -214,7 +215,7 @@ public: static Size getTextureGPUFramebufferMemoryUsage(); static Size getTextureGPUSparseMemoryUsage(); static uint32_t getTextureGPUTransferCount(); - + protected: Context(const Context& context); @@ -270,7 +271,6 @@ protected: static std::atomic _textureGPUFramebufferMemoryUsage; static std::atomic _textureGPUTransferCount; - friend class Backend; }; typedef std::shared_ptr ContextPointer; diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 0f1022a0c9..1eacb46d77 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -147,6 +147,7 @@ class Texture : public Resource { static std::atomic _enableSparseTextures; static std::atomic _enableIncrementalTextureTransfers; + public: static uint32_t getTextureCPUCount(); static Size getTextureCPUMemoryUsage(); From 920cd90afae8e8826196e779d54cc681ca9fbe3f Mon Sep 17 00:00:00 2001 From: David Kelly Date: Thu, 3 Nov 2016 13:23:05 -0700 Subject: [PATCH 45/66] CR feedback --- assignment-client/src/Agent.cpp | 4 ++-- assignment-client/src/audio/AudioMixer.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 4472b21e9b..4156619bb2 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -424,7 +424,7 @@ void Agent::setIsListeningToAudioStream(bool isListeningToAudioStream) { }, [&](const SharedNodePointer& node) { qDebug() << "sending KillAvatar message to Audio Mixers"; - auto packet = NLPacket::create(PacketType::KillAvatar, NUM_BYTES_RFC4122_UUID); + auto packet = NLPacket::create(PacketType::KillAvatar, NUM_BYTES_RFC4122_UUID, true); packet->write(getSessionUUID().toRfc4122()); nodeList->sendPacket(std::move(packet), *node); }); @@ -475,7 +475,7 @@ void Agent::setIsAvatar(bool isAvatar) { }, [&](const SharedNodePointer& node) { qDebug() << "sending KillAvatar message to Avatar and Audio Mixers"; - auto packet = NLPacket::create(PacketType::KillAvatar, NUM_BYTES_RFC4122_UUID); + auto packet = NLPacket::create(PacketType::KillAvatar, NUM_BYTES_RFC4122_UUID, true); packet->write(getSessionUUID().toRfc4122()); nodeList->sendPacket(std::move(packet), *node); }); diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 6390ebd302..2ea1c978c8 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -607,7 +607,7 @@ void AudioMixer::handleKillAvatarPacket(QSharedPointer packet, nodeList->eachNode([sendingNode](const SharedNodePointer& node){ auto listenerClientData = dynamic_cast(node->getLinkedData()); if (listenerClientData) { - listenerClientData->removeHRTFForStream(sendingNode->getUUID(), QUuid()); + listenerClientData->removeHRTFForStream(sendingNode->getUUID()); } }); } From b6e440f8919b93bd63e6d5b13ed89cbf0d928d2c Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Thu, 3 Nov 2016 13:26:50 -0700 Subject: [PATCH 46/66] delete this and formatting --- interface/src/ui/SnapshotUploader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/SnapshotUploader.cpp b/interface/src/ui/SnapshotUploader.cpp index b531f82348..c36efddc14 100644 --- a/interface/src/ui/SnapshotUploader.cpp +++ b/interface/src/ui/SnapshotUploader.cpp @@ -57,9 +57,9 @@ void SnapshotUploader::uploadSuccess(QNetworkReply& reply) { callbackParams, QJsonDocument(rootObject).toJson()); - } - else { + } else { emit DependencyManager::get()->snapshotShared(contents); + delete this; } } From 625c98820de9e7cc2e78ffc14b1062fb505a4c03 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 3 Nov 2016 14:01:52 -0700 Subject: [PATCH 47/66] Fix isSubdeviceContainingNameAvailable --- libraries/plugins/src/plugins/PluginUtils.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libraries/plugins/src/plugins/PluginUtils.cpp b/libraries/plugins/src/plugins/PluginUtils.cpp index f1cc85634f..b7e025222a 100644 --- a/libraries/plugins/src/plugins/PluginUtils.cpp +++ b/libraries/plugins/src/plugins/PluginUtils.cpp @@ -35,10 +35,12 @@ bool PluginUtils::isHandControllerAvailable() { bool isSubdeviceContainingNameAvailable(QString name) { for (auto& inputPlugin : PluginManager::getInstance()->getInputPlugins()) { - auto subdeviceNames = inputPlugin->getSubdeviceNames(); - for (auto& name : subdeviceNames) { - if (name.contains(name)) { - return true; + if (inputPlugin->isActive()) { + auto subdeviceNames = inputPlugin->getSubdeviceNames(); + for (auto& subdeviceName : subdeviceNames) { + if (subdeviceName.contains(name)) { + return true; + } } } } From 413199459bc6e2cf8caaa4e138216c3e0addea7e Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 3 Nov 2016 14:02:18 -0700 Subject: [PATCH 48/66] Fix the name searched for in isViveControllerAvailable --- libraries/plugins/src/plugins/PluginUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/plugins/src/plugins/PluginUtils.cpp b/libraries/plugins/src/plugins/PluginUtils.cpp index b7e025222a..48530bfe8c 100644 --- a/libraries/plugins/src/plugins/PluginUtils.cpp +++ b/libraries/plugins/src/plugins/PluginUtils.cpp @@ -48,7 +48,7 @@ bool isSubdeviceContainingNameAvailable(QString name) { }; bool PluginUtils::isViveControllerAvailable() { - return isSubdeviceContainingNameAvailable("Vive"); + return isSubdeviceContainingNameAvailable("OpenVR"); }; bool PluginUtils::isXboxControllerAvailable() { From 687605ad38425eee9825e9581e3f8ec6ae7892b1 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 3 Nov 2016 14:02:53 -0700 Subject: [PATCH 49/66] Add proper adding and removal of subdeviceNames in SDL2Manager after startup --- plugins/hifiSdl2/src/Joystick.h | 2 ++ plugins/hifiSdl2/src/SDL2Manager.cpp | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/hifiSdl2/src/Joystick.h b/plugins/hifiSdl2/src/Joystick.h index 25381d545a..a10e02d325 100644 --- a/plugins/hifiSdl2/src/Joystick.h +++ b/plugins/hifiSdl2/src/Joystick.h @@ -31,6 +31,8 @@ public: const QString& getName() const { return _name; } + SDL_GameController* getGameController() { return _sdlGameController; } + // Device functions virtual controller::Input::NamedVector getAvailableInputs() const override; virtual QString getDefaultMappingConfig() const override; diff --git a/plugins/hifiSdl2/src/SDL2Manager.cpp b/plugins/hifiSdl2/src/SDL2Manager.cpp index 91a693cc09..b6fa567aee 100644 --- a/plugins/hifiSdl2/src/SDL2Manager.cpp +++ b/plugins/hifiSdl2/src/SDL2Manager.cpp @@ -163,15 +163,19 @@ void SDL2Manager::pluginUpdate(float deltaTime, const controller::InputCalibrati Joystick::Pointer joystick = std::make_shared(id, controller); _openJoysticks[id] = joystick; userInputMapper->registerDevice(joystick); + QString name = SDL_GameControllerName(controller); emit joystickAdded(joystick.get()); - emit subdeviceConnected(getName(), SDL_GameControllerName(controller)); + emit subdeviceConnected(getName(), name); + _subdeviceNames << name; } } else if (event.type == SDL_CONTROLLERDEVICEREMOVED) { if (_openJoysticks.contains(event.cdevice.which)) { Joystick::Pointer joystick = _openJoysticks[event.cdevice.which]; _openJoysticks.remove(event.cdevice.which); userInputMapper->removeDevice(joystick->getDeviceID()); + QString name = SDL_GameControllerName(joystick->getGameController()); emit joystickRemoved(joystick.get()); + _subdeviceNames.removeOne(name); } } } From c1841f9addcaea7a53d1ec533b22e8b512549acf Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Thu, 3 Nov 2016 14:10:07 -0700 Subject: [PATCH 50/66] more conservative texture memory budget --- libraries/gpu-gl/src/gpu/gl/GLTexture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp index 61a76c2d0b..3ce1c8e5c4 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp @@ -111,7 +111,7 @@ float GLTexture::getMemoryPressure() { } #else // Hardcode texture limit for sparse textures at 1 GB for now - availableTextureMemory = GPU_MEMORY_RESERVE_BYTES; + availableTextureMemory = TEXTURE_MEMORY_MIN_BYTES; #endif } From 4104aa62864fccdc84d8fc6d8d35bcbba58a02d7 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 3 Nov 2016 14:31:28 -0700 Subject: [PATCH 51/66] avoid warning? --- libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index 07b4ca084d..1075c1407d 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -159,7 +159,7 @@ void GL45Backend::initTextureManagementStage() { // But now let s refine the behavior based on vendor std::string vendor { (const char*)glGetString(GL_VENDOR) }; if ((vendor.compare("AMD") <= 0) || (vendor.compare("INTEL") <= 0)) { - qCDebug(gpugllogging, "GPU is sparse capable but force it off %s\n", vendor); + qCDebug(gpugllogging) << "GPU is sparse capable but force it off, vendor = " << vendor.c_str(); _textureManagement._sparseCapable = false; } } From ce89f811f3db06536229415ffb86aac2064306e9 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 3 Nov 2016 14:35:44 -0700 Subject: [PATCH 52/66] better loggin of the sparse switch --- libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index 1075c1407d..6e2e7ca62b 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -161,6 +161,8 @@ void GL45Backend::initTextureManagementStage() { if ((vendor.compare("AMD") <= 0) || (vendor.compare("INTEL") <= 0)) { qCDebug(gpugllogging) << "GPU is sparse capable but force it off, vendor = " << vendor.c_str(); _textureManagement._sparseCapable = false; + } else { + qCDebug(gpugllogging) << "GPU is sparse capable, vendor = " << vendor.c_str(); } } From 1086585559fe5017ee9664f8e26619bbf860c49b Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 3 Nov 2016 15:15:05 -0700 Subject: [PATCH 53/66] fixing the test to actually capture ati correctly and add the report to the ui --- interface/src/ui/Stats.cpp | 2 +- libraries/gpu-gl/src/gpu/gl/GLBackend.h | 4 ++-- libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp | 2 +- libraries/gpu/src/gpu/Context.h | 5 +++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 11660a332d..05632cb1e6 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -302,7 +302,7 @@ void Stats::updateStats(bool force) { STAT_UPDATE(gpuTextureVirtualMemory, (int)BYTES_TO_MB(gpu::Texture::getTextureGPUVirtualMemoryUsage())); STAT_UPDATE(gpuTextureFramebufferMemory, (int)BYTES_TO_MB(gpu::Texture::getTextureGPUFramebufferMemoryUsage())); STAT_UPDATE(gpuTextureSparseMemory, (int)BYTES_TO_MB(gpu::Texture::getTextureGPUSparseMemoryUsage())); - STAT_UPDATE(gpuSparseTextureEnabled, gpu::Texture::getEnableSparseTextures() ? 1 : 0); + STAT_UPDATE(gpuSparseTextureEnabled, qApp->getGPUContext()->getBackend()->isTextureManagementSparseEnabled() ? 1 : 0); STAT_UPDATE(gpuFreeMemory, (int)BYTES_TO_MB(gpu::Context::getFreeGPUMemory())); STAT_UPDATE(rectifiedTextureCount, (int)RECTIFIED_TEXTURE_COUNT.load()); STAT_UPDATE(decimatedTextureCount, (int)DECIMATED_TEXTURE_COUNT.load()); diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackend.h b/libraries/gpu-gl/src/gpu/gl/GLBackend.h index fad433d4a2..1be279b375 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl/src/gpu/gl/GLBackend.h @@ -176,8 +176,8 @@ public: virtual void releaseQuery(GLuint id) const; virtual void queueLambda(const std::function lambda) const; - bool isTextureManagementSparseEnabled() const { return (_textureManagement._sparseCapable && Texture::getEnableSparseTextures()); } - bool isTextureManagementIncrementalTransferEnabled() const { return (_textureManagement._incrementalTransferCapable && Texture::getEnableIncrementalTextureTransfers()); } + bool isTextureManagementSparseEnabled() const override { return (_textureManagement._sparseCapable && Texture::getEnableSparseTextures()); } + bool isTextureManagementIncrementalTransferEnabled() const override { return (_textureManagement._incrementalTransferCapable && Texture::getEnableIncrementalTextureTransfers()); } protected: diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index 6e2e7ca62b..ac9a84513e 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -158,7 +158,7 @@ void GL45Backend::initTextureManagementStage() { // But now let s refine the behavior based on vendor std::string vendor { (const char*)glGetString(GL_VENDOR) }; - if ((vendor.compare("AMD") <= 0) || (vendor.compare("INTEL") <= 0)) { + if ((vendor.find("AMD") != std::string::npos) || (vendor.find("ATI") != std::string::npos) || (vendor.find("INTEL") != std::string::npos)) { qCDebug(gpugllogging) << "GPU is sparse capable but force it off, vendor = " << vendor.c_str(); _textureManagement._sparseCapable = false; } else { diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index 56d1930c94..e174e9d728 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -85,7 +85,8 @@ public: void getStats(ContextStats& stats) const { stats = _stats; } - + virtual bool isTextureManagementSparseEnabled() const = 0; + virtual bool isTextureManagementIncrementalTransferEnabled() const = 0; // These should only be accessed by Backend implementation to repport the buffer and texture allocations, // they are NOT public calls @@ -215,7 +216,7 @@ public: static Size getTextureGPUFramebufferMemoryUsage(); static Size getTextureGPUSparseMemoryUsage(); static uint32_t getTextureGPUTransferCount(); - + protected: Context(const Context& context); From 757ec5fff4c3f34aab2adbadacfda41b50ac0e5b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 3 Nov 2016 16:02:39 -0700 Subject: [PATCH 54/66] normalize quaternions submitted from scriptland --- libraries/shared/src/RegisteredMetaTypes.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp index 171b58de17..7324932477 100644 --- a/libraries/shared/src/RegisteredMetaTypes.cpp +++ b/libraries/shared/src/RegisteredMetaTypes.cpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include "RegisteredMetaTypes.h" @@ -263,6 +263,14 @@ void quatFromScriptValue(const QScriptValue& object, glm::quat &quat) { quat.y = object.property("y").toVariant().toFloat(); quat.z = object.property("z").toVariant().toFloat(); quat.w = object.property("w").toVariant().toFloat(); + + // enforce normalized quaternion + float length2 = glm::length2(quat); + if (length2 > FLT_EPSILON) { + quat /= sqrtf(length2); + } else { + quat = glm::quat(); + } } glm::quat quatFromVariant(const QVariant &object, bool& isValid) { @@ -273,6 +281,14 @@ glm::quat quatFromVariant(const QVariant &object, bool& isValid) { q.y = qvec3.y(); q.z = qvec3.z(); q.w = qvec3.scalar(); + + // enforce normalized quaternion + float length2 = glm::length2(q); + if (length2 > FLT_EPSILON) { + q /= sqrtf(length2); + } else { + q = glm::quat(); + } isValid = true; } else { auto map = object.toMap(); From c9c0b9ebc48b5a0a8493aa53ede486ff64c4eb90 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 3 Nov 2016 17:01:09 -0700 Subject: [PATCH 55/66] tighten rejection of zero-length quaternions --- libraries/shared/src/RegisteredMetaTypes.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp index 7324932477..8a63d53469 100644 --- a/libraries/shared/src/RegisteredMetaTypes.cpp +++ b/libraries/shared/src/RegisteredMetaTypes.cpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include "RegisteredMetaTypes.h" @@ -265,9 +265,9 @@ void quatFromScriptValue(const QScriptValue& object, glm::quat &quat) { quat.w = object.property("w").toVariant().toFloat(); // enforce normalized quaternion - float length2 = glm::length2(quat); - if (length2 > FLT_EPSILON) { - quat /= sqrtf(length2); + float length = glm::length(quat); + if (length > FLT_EPSILON) { + quat /= sqrtf(length); } else { quat = glm::quat(); } @@ -283,9 +283,9 @@ glm::quat quatFromVariant(const QVariant &object, bool& isValid) { q.w = qvec3.scalar(); // enforce normalized quaternion - float length2 = glm::length2(q); - if (length2 > FLT_EPSILON) { - q /= sqrtf(length2); + float length = glm::length(q); + if (length > FLT_EPSILON) { + q /= sqrtf(length); } else { q = glm::quat(); } From c5ee1941d1c482dd5a2131aee59506d7717853e7 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Thu, 3 Nov 2016 17:02:47 -0700 Subject: [PATCH 56/66] raise desktop when showing it --- interface/resources/qml/desktop/Desktop.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index b207087be0..66b59f0aea 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -312,6 +312,7 @@ FocusScope { onPinnedChanged: { if (pinned) { + d.raiseWindow(desktop); desktop.focus = true; desktop.forceActiveFocus(); From 3ed3a74b7d2af77dc88471f17517871b2f9d1097 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 3 Nov 2016 17:08:42 -0700 Subject: [PATCH 57/66] oops, don't forget to remove the sqrt --- libraries/shared/src/RegisteredMetaTypes.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp index 8a63d53469..984529c4ba 100644 --- a/libraries/shared/src/RegisteredMetaTypes.cpp +++ b/libraries/shared/src/RegisteredMetaTypes.cpp @@ -267,7 +267,7 @@ void quatFromScriptValue(const QScriptValue& object, glm::quat &quat) { // enforce normalized quaternion float length = glm::length(quat); if (length > FLT_EPSILON) { - quat /= sqrtf(length); + quat /= length; } else { quat = glm::quat(); } @@ -285,7 +285,7 @@ glm::quat quatFromVariant(const QVariant &object, bool& isValid) { // enforce normalized quaternion float length = glm::length(q); if (length > FLT_EPSILON) { - q /= sqrtf(length); + q /= length; } else { q = glm::quat(); } From 0d2cec290d3b20add7c35c196982571e8be39929 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 3 Nov 2016 17:56:38 -0700 Subject: [PATCH 58/66] use convexHull for ellipsoidal "spheres" --- libraries/physics/src/ShapeFactory.cpp | 14 ++++++++++++-- libraries/shared/src/ShapeInfo.cpp | 7 +------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/libraries/physics/src/ShapeFactory.cpp b/libraries/physics/src/ShapeFactory.cpp index 9b9ee0e299..100dab0fd1 100644 --- a/libraries/physics/src/ShapeFactory.cpp +++ b/libraries/physics/src/ShapeFactory.cpp @@ -256,8 +256,18 @@ const btCollisionShape* ShapeFactory::createShapeFromInfo(const ShapeInfo& info) } break; case SHAPE_TYPE_SPHERE: { - float radius = info.getHalfExtents().x; - shape = new btSphereShape(radius); + glm::vec3 halfExtents = info.getHalfExtents(); + float radius = halfExtents.x; + if (radius == halfExtents.y && radius == halfExtents.z) { + shape = new btSphereShape(radius); + } else { + ShapeInfo::PointList points; + points.reserve(NUM_UNIT_SPHERE_DIRECTIONS); + for (uint32_t i = 0; i < NUM_UNIT_SPHERE_DIRECTIONS; ++i) { + points.push_back(bulletToGLM(_unitSphereDirections[i]) * halfExtents); + } + shape = createConvexHull(points); + } } break; case SHAPE_TYPE_CAPSULE_Y: { diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index 424c2bfa22..1dc0753b8d 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -33,13 +33,8 @@ void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString _halfExtents = glm::vec3(0.0f); break; case SHAPE_TYPE_BOX: + case SHAPE_TYPE_SPHERE: break; - case SHAPE_TYPE_SPHERE: { - // sphere radius is max of halfExtents - float radius = glm::max(glm::max(halfExtents.x, halfExtents.y), halfExtents.z); - _halfExtents = glm::vec3(radius); - break; - } case SHAPE_TYPE_COMPOUND: case SHAPE_TYPE_STATIC_MESH: _url = QUrl(url); From 4b623f72c3a1f2a950de505b9a0477c6f97d6efd Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 3 Nov 2016 18:05:50 -0700 Subject: [PATCH 59/66] compute correct volume for ellipsoid --- libraries/shared/src/ShapeInfo.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index 1dc0753b8d..b8ea3a4272 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -114,8 +114,7 @@ float ShapeInfo::computeVolume() const { break; } case SHAPE_TYPE_SPHERE: { - float radius = _halfExtents.x; - volume = 4.0f * PI * radius * radius * radius / 3.0f; + volume = 4.0f * PI * _halfExtents.x * _halfExtents.y * _halfExtents.z / 3.0f; break; } case SHAPE_TYPE_CYLINDER_Y: { From 38a2ce67bbeb7af6be716f1d46716fdbcf96e5bc Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 4 Nov 2016 11:23:10 -0700 Subject: [PATCH 60/66] Add tools/atp-extract.py Tool to list and extract files from the atp assets directory. --- tools/atp-extract.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 tools/atp-extract.py diff --git a/tools/atp-extract.py b/tools/atp-extract.py new file mode 100644 index 0000000000..10c31ab0d3 --- /dev/null +++ b/tools/atp-extract.py @@ -0,0 +1,44 @@ +# +# Tool to extract atp files from the asset server cache. +# Usage: python2 atp-extract.py -[lxa] [filename] +# +# cd into the c:\Users\BettySpaghetti\AppData\Roaming\High Fidelity\assignment-client\assets dir +# run 'python2 atp-extract.py -l' to list all files +# run 'python2 atp-extract.py -x file' to extract that particular file to the current directory. +# run 'python2 atp-extract.py -a' to extract all files. +# + +import os, json, sys, shutil + +def loadMapFile(filename): + with open(filename, 'r') as f: + return json.load(f) + +def extractFile(assetMap, filename): + if filename != None: + assetFilename = assetMap.get("/" + filename) + if assetFilename != None: + dir = os.path.dirname(filename) + if dir != "" and not os.path.exists(dir): + os.makedirs(dir) + shutil.copy("files/" + assetFilename, filename) + return True + return False + +option = sys.argv[1] +if option == '-l': + assetMap = loadMapFile("map.json") + for key, value in assetMap.iteritems(): + print key[1:] +elif option == '-x': + assetMap = loadMapFile("map.json") + outputFilename = sys.argv[2] + if not extractFile(assetMap, outputFilename): + print("Error could not extract file: \"" + outputFilename + "\"") +elif option == '-a': + assetMap = loadMapFile("map.json") + for key, value in assetMap.iteritems(): + print("Extracting " + key[1:]) + extractFile(assetMap, key[1:]) +else: + print("unsuported option \"" + option + "\"") From 21d1f40f594442121272f1c797761f13d3e47683 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Fri, 4 Nov 2016 13:15:02 -0700 Subject: [PATCH 61/66] Seems we were not deleting the right hrtfs when a node is killed Simple fix, just make sure we delete the hrtfs associated with the killedNode. The test is to delete some nodes (agents) and make sure nothing bad happens to audio mixer, or the audio itself. --- assignment-client/src/audio/AudioMixer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 2ea1c978c8..d785579c38 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -591,10 +591,10 @@ void AudioMixer::handleNodeKilled(SharedNodePointer killedNode) { // enumerate the connected listeners to remove HRTF objects for the disconnected node auto nodeList = DependencyManager::get(); - nodeList->eachNode([](const SharedNodePointer& node) { + nodeList->eachNode([&killedNode](const SharedNodePointer& node) { auto clientData = dynamic_cast(node->getLinkedData()); if (clientData) { - clientData->removeHRTFsForNode(node->getUUID()); + clientData->removeHRTFsForNode(killedNode->getUUID()); } }); } From 5287ec1eee45fadcfa523fd2b1710f565172c305 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Sat, 5 Nov 2016 10:15:56 -0700 Subject: [PATCH 62/66] Fix includes hitting max retries locking the script up --- libraries/script-engine/src/ScriptCache.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/script-engine/src/ScriptCache.cpp b/libraries/script-engine/src/ScriptCache.cpp index 96e3d7e914..025447a5b8 100644 --- a/libraries/script-engine/src/ScriptCache.cpp +++ b/libraries/script-engine/src/ScriptCache.cpp @@ -222,6 +222,9 @@ void ScriptCache::scriptContentAvailable() { }); } else { // Dubious, but retained here because it matches the behavior before fixing the threading + + allCallbacks = scriptRequest.scriptUsers; + scriptContent = _scriptCache[url]; finished = true; qCWarning(scriptengine) << "Error loading script from URL " << url; From 1a704f8d0a570870bf405bfc1b59ca68c3ffac38 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Sat, 5 Nov 2016 10:16:35 -0700 Subject: [PATCH 63/66] Fix ScriptCacheSignalProxy not being properly cleaned up --- libraries/script-engine/src/BatchLoader.cpp | 3 ++- libraries/script-engine/src/BatchLoader.h | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/script-engine/src/BatchLoader.cpp b/libraries/script-engine/src/BatchLoader.cpp index 964807894e..d191c89f09 100644 --- a/libraries/script-engine/src/BatchLoader.cpp +++ b/libraries/script-engine/src/BatchLoader.cpp @@ -55,7 +55,8 @@ void BatchLoader::start() { // Use a proxy callback to handle the call and emit the signal in a thread-safe way. // If BatchLoader is deleted before the callback is called, the subsequent "emit" call will not do // anything. - ScriptCacheSignalProxy* proxy = new ScriptCacheSignalProxy(scriptCache.data()); + ScriptCacheSignalProxy* proxy = new ScriptCacheSignalProxy(); + connect(scriptCache.data(), &ScriptCache::destroyed, proxy, &ScriptCacheSignalProxy::deleteLater); connect(proxy, &ScriptCacheSignalProxy::contentAvailable, this, [this](const QString& url, const QString& contents, bool isURL, bool success) { if (isURL && success) { diff --git a/libraries/script-engine/src/BatchLoader.h b/libraries/script-engine/src/BatchLoader.h index a03a8d80c6..046e17ff63 100644 --- a/libraries/script-engine/src/BatchLoader.h +++ b/libraries/script-engine/src/BatchLoader.h @@ -24,7 +24,6 @@ class ScriptCacheSignalProxy : public QObject { Q_OBJECT public: - ScriptCacheSignalProxy(QObject* parent) : QObject(parent) { } void receivedContent(const QString& url, const QString& contents, bool isURL, bool success); signals: From 2139e979da34c81b7c05bf90d6f4fe29a7001128 Mon Sep 17 00:00:00 2001 From: humbletim Date: Sun, 6 Nov 2016 09:33:16 -0500 Subject: [PATCH 64/66] map specific HTTP errors to corresponding ResourceRequest enums --- .../networking/src/HTTPResourceRequest.cpp | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/libraries/networking/src/HTTPResourceRequest.cpp b/libraries/networking/src/HTTPResourceRequest.cpp index 392654a419..64396ec62e 100644 --- a/libraries/networking/src/HTTPResourceRequest.cpp +++ b/libraries/networking/src/HTTPResourceRequest.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -78,10 +79,36 @@ void HTTPResourceRequest::onRequestFinished() { _loadedFromCache = _reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool(); _result = Success; break; + case QNetworkReply::TimeoutError: _result = Timeout; break; + + case QNetworkReply::ContentNotFoundError: // Script.include('https://httpbin.org/status/404') + _result = NotFound; + break; + + case QNetworkReply::ProtocolInvalidOperationError: // Script.include('https://httpbin.org/status/400') + _result = InvalidURL; + break; + + case QNetworkReply::UnknownContentError: // Script.include('QUrl("https://httpbin.org/status/402")') + case QNetworkReply::ContentOperationNotPermittedError: //Script.include('https://httpbin.org/status/403') + case QNetworkReply::AuthenticationRequiredError: // Script.include('https://httpbin.org/basic-auth/user/passwd') + _result = AccessDenied; + break; + + case QNetworkReply::RemoteHostClosedError: // Script.include('http://127.0.0.1:22') + case QNetworkReply::ConnectionRefusedError: // Script.include(http://127.0.0.1:1') + case QNetworkReply::HostNotFoundError: // Script.include('http://foo.bar.highfidelity.io') + case QNetworkReply::ServiceUnavailableError: // Script.include('QUrl("https://httpbin.org/status/503")') + _result = ServerUnavailable; + break; + + case QNetworkReply::UnknownServerError: // Script.include('QUrl("https://httpbin.org/status/504")') + case QNetworkReply::InternalServerError: // Script.include('QUrl("https://httpbin.org/status/500")') default: + qDebug() << "HTTPResourceRequest error:" << QMetaEnum::fromType().valueToKey(_reply->error()); _result = Error; break; } From 61452c21a2d877a75be54686e91e15cec6abb9cc Mon Sep 17 00:00:00 2001 From: humbletim Date: Sun, 6 Nov 2016 09:40:28 -0500 Subject: [PATCH 65/66] bail early from irrecoverable retry situations --- libraries/script-engine/src/ScriptCache.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libraries/script-engine/src/ScriptCache.cpp b/libraries/script-engine/src/ScriptCache.cpp index 96e3d7e914..941c0b6175 100644 --- a/libraries/script-engine/src/ScriptCache.cpp +++ b/libraries/script-engine/src/ScriptCache.cpp @@ -202,7 +202,14 @@ void ScriptCache::scriptContentAvailable() { finished = true; qCDebug(scriptengine) << "Done downloading script at:" << url.toString(); } else { - if (scriptRequest.numRetries < MAX_RETRIES) { + auto result = req->getResult(); + bool irrecoverable = + result == ResourceRequest::AccessDenied || + result == ResourceRequest::InvalidURL || + result == ResourceRequest::NotFound || + scriptRequest.numRetries >= MAX_RETRIES; + + if (!irrecoverable) { ++scriptRequest.numRetries; qDebug() << "Script request failed: " << url; From 852218815b63ae154108a77ffae0f272b13296b0 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Mon, 7 Nov 2016 13:40:49 +1300 Subject: [PATCH 66/66] Display "content loading" while there are pending GPU texture transfers --- scripts/system/progress.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/scripts/system/progress.js b/scripts/system/progress.js index 92853c9ada..81da38c8c2 100644 --- a/scripts/system/progress.js +++ b/scripts/system/progress.js @@ -248,7 +248,7 @@ } function update() { - var viewport, diff, x; + var viewport, diff, x, gpuTextures; initialDelayCooldown -= 30; @@ -261,26 +261,28 @@ } } + gpuTextures = Render.getConfig("Stats").textureGPUTransferCount; + // Update state if (!visible) { // Not visible because no recent downloads - if (displayProgress < 100) { // Have started downloading so fade in + if (displayProgress < 100 || gpuTextures > 0) { // Have started downloading so fade in visible = true; alphaDelta = ALPHA_DELTA_IN; fadeTimer = Script.setInterval(fade, FADE_INTERVAL); } } else if (alphaDelta !== 0.0) { // Fading in or out if (alphaDelta > 0) { - if (rawProgress === 100) { // Was downloading but now have finished so fade out + if (rawProgress === 100 && gpuTextures === 0) { // Was downloading but now have finished so fade out alphaDelta = ALPHA_DELTA_OUT; } } else { - if (displayProgress < 100) { // Was finished downloading but have resumed so fade in + if (displayProgress < 100 || gpuTextures > 0) { // Was finished downloading but have resumed so fade in alphaDelta = ALPHA_DELTA_IN; } } } else { // Fully visible because downloading or recently so if (fadeWaitTimer === null) { - if (rawProgress === 100) { // Was downloading but have finished so fade out soon + if (rawProgress === 100 && gpuTextures === 0) { // Was downloading but have finished so fade out soon fadeWaitTimer = Script.setTimeout(function () { alphaDelta = ALPHA_DELTA_OUT; fadeTimer = Script.setInterval(fade, FADE_INTERVAL); @@ -288,7 +290,8 @@ }, FADE_OUT_WAIT); } } else { - if (displayProgress < 100) { // Was finished and waiting to fade out but have resumed so don't fade out + if (displayProgress < 100 || gpuTextures > 0) { // Was finished and waiting to fade out but have resumed so + // don't fade out Script.clearInterval(fadeWaitTimer); fadeWaitTimer = null; }