From 12becb9d19777de3f63c2365bc81de140d853305 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 11 Mar 2014 16:22:35 -0700 Subject: [PATCH 01/14] improve octree stats display --- interface/src/ui/OctreeStatsDialog.cpp | 57 ++++++----- libraries/octree/src/Octree.cpp | 2 - libraries/octree/src/OctreeSceneStats.cpp | 114 +++++++++++++++++++--- libraries/octree/src/OctreeSceneStats.h | 22 ++++- libraries/voxels/src/VoxelTree.cpp | 2 - 5 files changed, 152 insertions(+), 45 deletions(-) diff --git a/interface/src/ui/OctreeStatsDialog.cpp b/interface/src/ui/OctreeStatsDialog.cpp index 974964da04..92578b6b34 100644 --- a/interface/src/ui/OctreeStatsDialog.cpp +++ b/interface/src/ui/OctreeStatsDialog.cpp @@ -157,9 +157,9 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { statsValue.str(""); statsValue << - "Total: " << localTotalString.toLocal8Bit().constData() << " / " << - "Internal: " << localInternalString.toLocal8Bit().constData() << " / " << - "Leaves: " << localLeavesString.toLocal8Bit().constData() << ""; + "Total: " << qPrintable(localTotalString) << " / " << + "Internal: " << qPrintable(localInternalString) << " / " << + "Leaves: " << qPrintable(localLeavesString) << ""; label->setText(statsValue.str().c_str()); // iterate all the current voxel stats, and list their sending modes, total their voxels, etc... @@ -212,9 +212,9 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { label = _labels[_serverVoxels]; statsValue.str(""); statsValue << - "Total: " << serversTotalString.toLocal8Bit().constData() << " / " << - "Internal: " << serversInternalString.toLocal8Bit().constData() << " / " << - "Leaves: " << serversLeavesString.toLocal8Bit().constData() << ""; + "Total: " << qPrintable(serversTotalString) << " / " << + "Internal: " << qPrintable(serversInternalString) << " / " << + "Leaves: " << qPrintable(serversLeavesString) << ""; label->setText(statsValue.str().c_str()); showAllOctreeServers(); @@ -290,7 +290,7 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s); serverBounds.scale(TREE_SCALE); serverDetails << " jurisdiction: " - << rootCodeHex.toLocal8Bit().constData() + << qPrintable(rootCodeHex) << " [" << rootDetails.x << ", " << rootDetails.y << ", " @@ -320,8 +320,8 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser QString lastFullSendString = locale.toString(lastFullSend); extraDetails << "
" << "Last Full Scene... " << - "Encode Time: " << lastFullEncodeString.toLocal8Bit().constData() << " ms " << - "Send Time: " << lastFullSendString.toLocal8Bit().constData() << " ms "; + "Encode Time: " << qPrintable(lastFullEncodeString) << " ms " << + "Send Time: " << qPrintable(lastFullSendString) << " ms "; for (int i = 0; i < OctreeSceneStats::ITEM_COUNT; i++) { OctreeSceneStats::Item item = (OctreeSceneStats::Item)(i); @@ -334,42 +334,51 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser QString internalString = locale.toString((uint)stats.getTotalInternal()); QString leavesString = locale.toString((uint)stats.getTotalLeaves()); - serverDetails << "
" << "Node UUID: " << - nodeUUID.toString().toLocal8Bit().constData() << " "; + serverDetails << "
" << "Node UUID: " << qPrintable(nodeUUID.toString()) << " "; serverDetails << "
" << "Voxels: " << - totalString.toLocal8Bit().constData() << " total " << - internalString.toLocal8Bit().constData() << " internal " << - leavesString.toLocal8Bit().constData() << " leaves "; + qPrintable(totalString) << " total " << + qPrintable(internalString) << " internal " << + qPrintable(leavesString) << " leaves "; QString incomingPacketsString = locale.toString((uint)stats.getIncomingPackets()); QString incomingBytesString = locale.toString((uint)stats.getIncomingBytes()); QString incomingWastedBytesString = locale.toString((uint)stats.getIncomingWastedBytes()); QString incomingOutOfOrderString = locale.toString((uint)stats.getIncomingOutOfOrder()); + QString incomingLateString = locale.toString((uint)stats.getIncomingLate()); + QString incomingReallyLateString = locale.toString((uint)stats.getIncomingReallyLate()); + QString incomingEarlyString = locale.toString((uint)stats.getIncomingEarly()); QString incomingLikelyLostString = locale.toString((uint)stats.getIncomingLikelyLost()); + QString incomingRecovered = locale.toString((uint)stats.getIncomingRecovered()); + QString incomingDuplicateString = locale.toString((uint)stats.getIncomingPossibleDuplicate()); int clockSkewInMS = node->getClockSkewUsec() / (int)USECS_PER_MSEC; QString incomingFlightTimeString = locale.toString((int)stats.getIncomingFlightTimeAverage()); QString incomingPingTimeString = locale.toString(node->getPingMs()); QString incomingClockSkewString = locale.toString(clockSkewInMS); - serverDetails << "
" << "Incoming Packets: " << - incomingPacketsString.toLocal8Bit().constData() << - " Out of Order: " << incomingOutOfOrderString.toLocal8Bit().constData() << - " Likely Lost: " << incomingLikelyLostString.toLocal8Bit().constData(); + serverDetails << "
" << "Incoming Packets: " << qPrintable(incomingPacketsString) << + "/ Lost: " << qPrintable(incomingLikelyLostString) << + "/ Recovered: " << qPrintable(incomingRecovered); + + serverDetails << "
" << " Out of Order: " << qPrintable(incomingOutOfOrderString) << + "/ Early: " << qPrintable(incomingEarlyString) << + "/ Late: " << qPrintable(incomingLateString) << + "/ Really Late: " << qPrintable(incomingReallyLateString) << + "/ Duplicate: " << qPrintable(incomingDuplicateString); serverDetails << "
" << - " Average Flight Time: " << incomingFlightTimeString.toLocal8Bit().constData() << " msecs"; + " Average Flight Time: " << qPrintable(incomingFlightTimeString) << " msecs"; serverDetails << "
" << - " Average Ping Time: " << incomingPingTimeString.toLocal8Bit().constData() << " msecs"; + " Average Ping Time: " << qPrintable(incomingPingTimeString) << " msecs"; serverDetails << "
" << - " Average Clock Skew: " << incomingClockSkewString.toLocal8Bit().constData() << " msecs"; - + " Average Clock Skew: " << qPrintable(incomingClockSkewString) << " msecs"; + serverDetails << "
" << "Incoming" << - " Bytes: " << incomingBytesString.toLocal8Bit().constData() << - " Wasted Bytes: " << incomingWastedBytesString.toLocal8Bit().constData(); + " Bytes: " << qPrintable(incomingBytesString) << + " Wasted Bytes: " << qPrintable(incomingWastedBytesString); serverDetails << extraDetails.str(); if (_extraServerDetails[serverCount-1] == MORE) { diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index f85ed7f487..4c8ed8c9f6 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -15,8 +15,6 @@ #include #include // to load voxels from file -#include - #include #include "CoverageMap.h" diff --git a/libraries/octree/src/OctreeSceneStats.cpp b/libraries/octree/src/OctreeSceneStats.cpp index 794884334f..7d1f3f0cec 100644 --- a/libraries/octree/src/OctreeSceneStats.cpp +++ b/libraries/octree/src/OctreeSceneStats.cpp @@ -30,8 +30,13 @@ OctreeSceneStats::OctreeSceneStats() : _incomingBytes(0), _incomingWastedBytes(0), _incomingLastSequence(0), - _incomingOutOfOrder(0), _incomingLikelyLost(0), + _incomingRecovered(0), + _incomingEarly(0), + _incomingLate(0), + _incomingReallyLate(0), + _incomingPossibleDuplicate(0), + _missingSequenceNumbers(), _incomingFlightTimeAverage(samples), _jurisdictionRoot(NULL) { @@ -134,8 +139,14 @@ void OctreeSceneStats::copyFromOther(const OctreeSceneStats& other) { _incomingBytes = other._incomingBytes; _incomingWastedBytes = other._incomingWastedBytes; _incomingLastSequence = other._incomingLastSequence; - _incomingOutOfOrder = other._incomingOutOfOrder; _incomingLikelyLost = other._incomingLikelyLost; + _incomingRecovered = other._incomingRecovered; + _incomingEarly = other._incomingEarly; + _incomingLate = other._incomingLate; + _incomingReallyLate = other._incomingReallyLate; + _incomingPossibleDuplicate = other._incomingPossibleDuplicate; + + _missingSequenceNumbers = other._missingSequenceNumbers; } @@ -823,18 +834,95 @@ void OctreeSceneStats::trackIncomingOctreePacket(const QByteArray& packet, float flightTimeMsecs = flightTime / USECS_PER_MSEC; _incomingFlightTimeAverage.updateAverage(flightTimeMsecs); + // track out of order and possibly lost packets... + const bool wantExtraDebugging = false; + if (sequence == _incomingLastSequence) { + if (wantExtraDebugging) { + qDebug() << "last packet duplicate got:" << sequence << "_incomingLastSequence:" << _incomingLastSequence; + } + } else { + OCTREE_PACKET_SEQUENCE expected = _incomingLastSequence+1; + if (sequence != expected) { + if (wantExtraDebugging) { + qDebug() << "out of order... got:" << sequence << "expected:" << expected; + } + + // if the sequence is less than our expected, then this might be a packet + // that was delayed and so we should find it in our lostSequence list + if (sequence < expected) { + if (wantExtraDebugging) { + qDebug() << "this packet is later than expected..."; + } + if (sequence < std::max(0, (expected - MAX_MISSING_SEQUENCE_OLD_AGE))) { + _incomingReallyLate++; + } else { + _incomingLate++; + } + + if (_missingSequenceNumbers.contains(sequence)) { + if (wantExtraDebugging) { + qDebug() << "found it in _missingSequenceNumbers"; + } + _missingSequenceNumbers.remove(sequence); + _incomingLikelyLost--; + _incomingRecovered++; + } else { + // if we're still in our pruning window, and we didn't find it in our missing list, + // than this is really unexpected and can probably only happen if the packet was a + // duplicate + if (sequence >= std::max(0, (expected - MAX_MISSING_SEQUENCE_OLD_AGE))) { + if (wantExtraDebugging) { + qDebug() << "sequence:" << sequence << "WAS NOT found in _missingSequenceNumbers, and not that old... (expected - MAX_MISSING_SEQUENCE_OLD_AGE):" << (expected - MAX_MISSING_SEQUENCE_OLD_AGE); + } + _incomingPossibleDuplicate++; + } + } + } + + if (sequence > expected) { + if (wantExtraDebugging) { + qDebug() << "this packet is earlier than expected..."; + } + _incomingEarly++; + + // hmm... so, we either didn't get some packets, or this guy came early... + unsigned int missing = sequence - expected; + if (wantExtraDebugging) { + qDebug() << ">>>>>>>> missing gap=" << missing; + } + _incomingLikelyLost += missing; + for(unsigned int missingSequence = expected; missingSequence < sequence; missingSequence++) { + _missingSequenceNumbers << missingSequence; + } + } + } + } + + // only bump the last sequence if it was greater than our previous last sequence, this will keep us from + // accidentally going backwards when an out of order (recovered) packet comes in + if (sequence > _incomingLastSequence) { + _incomingLastSequence = sequence; + } - // detect out of order packets - if (sequence < _incomingLastSequence) { - _incomingOutOfOrder++; + // do some garbage collecting on our _missingSequenceNumbers + if (_missingSequenceNumbers.size() > MAX_MISSING_SEQUENCE) { + if (wantExtraDebugging) { + qDebug() << "too many _missingSequenceNumbers:" << _missingSequenceNumbers.size(); + } + foreach(unsigned int missingItem, _missingSequenceNumbers) { + if (wantExtraDebugging) { + qDebug() << "checking item:" << missingItem << "is it in need of pruning?"; + qDebug() << "(_incomingLastSequence - MAX_MISSING_SEQUENCE_OLD_AGE):" + << (_incomingLastSequence - MAX_MISSING_SEQUENCE_OLD_AGE); + } + if (missingItem <= std::max(0, (_incomingLastSequence - MAX_MISSING_SEQUENCE_OLD_AGE))) { + if (wantExtraDebugging) { + qDebug() << "pruning really old missing sequence:" << missingItem; + } + _missingSequenceNumbers.remove(missingItem); + } + } } - - // detect likely lost packets - OCTREE_PACKET_SEQUENCE expected = _incomingLastSequence+1; - if (sequence > expected) { - _incomingLikelyLost++; - } - - _incomingLastSequence = sequence; + } diff --git a/libraries/octree/src/OctreeSceneStats.h b/libraries/octree/src/OctreeSceneStats.h index e106f53589..25bc5e2c21 100644 --- a/libraries/octree/src/OctreeSceneStats.h +++ b/libraries/octree/src/OctreeSceneStats.h @@ -159,8 +159,13 @@ public: unsigned int getIncomingPackets() const { return _incomingPacket; } unsigned long getIncomingBytes() const { return _incomingBytes; } unsigned long getIncomingWastedBytes() const { return _incomingWastedBytes; } - unsigned int getIncomingOutOfOrder() const { return _incomingOutOfOrder; } + unsigned int getIncomingOutOfOrder() const { return _incomingLate + _incomingEarly; } unsigned int getIncomingLikelyLost() const { return _incomingLikelyLost; } + unsigned int getIncomingRecovered() const { return _incomingRecovered; } + unsigned int getIncomingEarly() const { return _incomingEarly; } + unsigned int getIncomingLate() const { return _incomingLate; } + unsigned int getIncomingReallyLate() const { return _incomingReallyLate; } + unsigned int getIncomingPossibleDuplicate() const { return _incomingPossibleDuplicate; } float getIncomingFlightTimeAverage() { return _incomingFlightTimeAverage.getAverage(); } private: @@ -251,9 +256,18 @@ private: unsigned int _incomingPacket; unsigned long _incomingBytes; unsigned long _incomingWastedBytes; - unsigned int _incomingLastSequence; - unsigned int _incomingOutOfOrder; - unsigned int _incomingLikelyLost; + + const uint16_t MAX_MISSING_SEQUENCE = 100; /// how many items in our _missingSequenceNumbers before we start to prune them + const uint16_t MAX_MISSING_SEQUENCE_OLD_AGE = 1000; /// age we allow items in _missingSequenceNumbers to be before pruning + + uint16_t _incomingLastSequence; /// last incoming sequence number + unsigned int _incomingLikelyLost; /// count of packets likely lost, may be off by _incomingReallyLate count + unsigned int _incomingRecovered; /// packets that were late, and we had in our missing list, we consider recovered + unsigned int _incomingEarly; /// out of order earlier than expected + unsigned int _incomingLate; /// out of order later than expected + unsigned int _incomingReallyLate; /// out of order and later than MAX_MISSING_SEQUENCE_OLD_AGE late + unsigned int _incomingPossibleDuplicate; /// out of order possibly a duplicate + QSet _missingSequenceNumbers; SimpleMovingAverage _incomingFlightTimeAverage; // features related items diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 4c756c2257..5c48244a39 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -8,8 +8,6 @@ #include -#include - #include #include #include From 029b25ad29c73fea41c0afde61b57ecf3b370be2 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 11 Mar 2014 16:45:15 -0700 Subject: [PATCH 02/14] make domain server less noisy about Agent assignments --- domain-server/src/DomainServer.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index e5979c561f..7e37c9b397 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -544,8 +544,15 @@ void DomainServer::readAvailableDatagrams() { // construct the requested assignment from the packet data Assignment requestAssignment(receivedPacket); - qDebug() << "Received a request for assignment type" << requestAssignment.getType() - << "from" << senderSockAddr; + // Suppress these for Assignment::AgentType to 1 per second... + static quint64 lastMessage = usecTimestampNow(); + quint64 timeNow = usecTimestampNow(); + const quint64 NOISY_TIME_ELAPSED = USECS_PER_SECOND; + if (requestAssignment.getType() != Assignment::AgentType || (timeNow - lastMessage) > NOISY_TIME_ELAPSED) { + qDebug() << "Received a request for assignment type" << requestAssignment.getType() + << "from" << senderSockAddr; + lastMessage = timeNow; + } SharedAssignmentPointer assignmentToDeploy = deployableAssignmentForRequest(requestAssignment); From 00176254424d0f4c75cbe4c6002ba457c821ec8a Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 11 Mar 2014 16:48:49 -0700 Subject: [PATCH 03/14] fix unix compiler issue --- libraries/octree/src/OctreeSceneStats.cpp | 4 ++++ libraries/octree/src/OctreeSceneStats.h | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/octree/src/OctreeSceneStats.cpp b/libraries/octree/src/OctreeSceneStats.cpp index 7d1f3f0cec..ad7f774377 100644 --- a/libraries/octree/src/OctreeSceneStats.cpp +++ b/libraries/octree/src/OctreeSceneStats.cpp @@ -18,6 +18,10 @@ #include "OctreeSceneStats.h" +const uint16_t MAX_MISSING_SEQUENCE = 100; /// how many items in our _missingSequenceNumbers before we start to prune them +const uint16_t MAX_MISSING_SEQUENCE_OLD_AGE = 1000; /// age we allow items in _missingSequenceNumbers to be before pruning + + const int samples = 100; OctreeSceneStats::OctreeSceneStats() : _isReadyToSend(false), diff --git a/libraries/octree/src/OctreeSceneStats.h b/libraries/octree/src/OctreeSceneStats.h index 25bc5e2c21..249ab376c1 100644 --- a/libraries/octree/src/OctreeSceneStats.h +++ b/libraries/octree/src/OctreeSceneStats.h @@ -257,9 +257,6 @@ private: unsigned long _incomingBytes; unsigned long _incomingWastedBytes; - const uint16_t MAX_MISSING_SEQUENCE = 100; /// how many items in our _missingSequenceNumbers before we start to prune them - const uint16_t MAX_MISSING_SEQUENCE_OLD_AGE = 1000; /// age we allow items in _missingSequenceNumbers to be before pruning - uint16_t _incomingLastSequence; /// last incoming sequence number unsigned int _incomingLikelyLost; /// count of packets likely lost, may be off by _incomingReallyLate count unsigned int _incomingRecovered; /// packets that were late, and we had in our missing list, we consider recovered From 3c24121f5c7953ea9d691f0af6dfe039427b700d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 11 Mar 2014 16:54:03 -0700 Subject: [PATCH 04/14] more noise suppression --- domain-server/src/DomainServer.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 7e37c9b397..68601fd007 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -569,8 +569,10 @@ void DomainServer::readAvailableDatagrams() { nodeList->getNodeSocket().writeDatagram(assignmentPacket, senderSockAddr.getAddress(), senderSockAddr.getPort()); } else { - qDebug() << "Unable to fulfill assignment request of type" << requestAssignment.getType() - << "from" << senderSockAddr; + if (requestAssignment.getType() != Assignment::AgentType || (timeNow - lastMessage) > NOISY_TIME_ELAPSED) { + qDebug() << "Unable to fulfill assignment request of type" << requestAssignment.getType() + << "from" << senderSockAddr; + } } } } From 1d17e750439659084c718f259090c5481d045722 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 11 Mar 2014 16:56:41 -0700 Subject: [PATCH 05/14] more noise suppression --- domain-server/src/DomainServer.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 68601fd007..6410737594 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -547,11 +547,12 @@ void DomainServer::readAvailableDatagrams() { // Suppress these for Assignment::AgentType to 1 per second... static quint64 lastMessage = usecTimestampNow(); quint64 timeNow = usecTimestampNow(); - const quint64 NOISY_TIME_ELAPSED = USECS_PER_SECOND; + const quint64 NOISY_TIME_ELAPSED = 10 * USECS_PER_SECOND; + bool noisyMessage = false; if (requestAssignment.getType() != Assignment::AgentType || (timeNow - lastMessage) > NOISY_TIME_ELAPSED) { qDebug() << "Received a request for assignment type" << requestAssignment.getType() << "from" << senderSockAddr; - lastMessage = timeNow; + noisyMessage = true; } SharedAssignmentPointer assignmentToDeploy = deployableAssignmentForRequest(requestAssignment); @@ -572,8 +573,13 @@ void DomainServer::readAvailableDatagrams() { if (requestAssignment.getType() != Assignment::AgentType || (timeNow - lastMessage) > NOISY_TIME_ELAPSED) { qDebug() << "Unable to fulfill assignment request of type" << requestAssignment.getType() << "from" << senderSockAddr; + noisyMessage = true; } } + + if (noisyMessage) { + lastMessage = timeNow; + } } } } From 214866414c6b21eede207a9e87c4d42f81feb062 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 11 Mar 2014 17:09:44 -0700 Subject: [PATCH 06/14] tweak names --- domain-server/src/DomainServer.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 6410737594..8a95a25e23 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -545,11 +545,11 @@ void DomainServer::readAvailableDatagrams() { Assignment requestAssignment(receivedPacket); // Suppress these for Assignment::AgentType to 1 per second... - static quint64 lastMessage = usecTimestampNow(); + static quint64 lastNoisyMessage = usecTimestampNow(); quint64 timeNow = usecTimestampNow(); - const quint64 NOISY_TIME_ELAPSED = 10 * USECS_PER_SECOND; + const quint64 NOISY_TIME_ELAPSED = 5 * USECS_PER_SECOND; bool noisyMessage = false; - if (requestAssignment.getType() != Assignment::AgentType || (timeNow - lastMessage) > NOISY_TIME_ELAPSED) { + if (requestAssignment.getType() != Assignment::AgentType || (timeNow - lastNoisyMessage) > NOISY_TIME_ELAPSED) { qDebug() << "Received a request for assignment type" << requestAssignment.getType() << "from" << senderSockAddr; noisyMessage = true; @@ -570,7 +570,7 @@ void DomainServer::readAvailableDatagrams() { nodeList->getNodeSocket().writeDatagram(assignmentPacket, senderSockAddr.getAddress(), senderSockAddr.getPort()); } else { - if (requestAssignment.getType() != Assignment::AgentType || (timeNow - lastMessage) > NOISY_TIME_ELAPSED) { + if (requestAssignment.getType() != Assignment::AgentType || (timeNow - lastNoisyMessage) > NOISY_TIME_ELAPSED) { qDebug() << "Unable to fulfill assignment request of type" << requestAssignment.getType() << "from" << senderSockAddr; noisyMessage = true; @@ -578,7 +578,7 @@ void DomainServer::readAvailableDatagrams() { } if (noisyMessage) { - lastMessage = timeNow; + lastNoisyMessage = timeNow; } } } From 4d0b762de3fb5f2a0436ee6c73cc71576c4e60bc Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 11 Mar 2014 20:33:53 -0700 Subject: [PATCH 07/14] some hacking on full scene debuggin --- .../src/octree/OctreeSendThread.cpp | 18 ++++++++++++++++-- interface/src/Application.cpp | 18 ++++++++++++++++-- interface/src/Application.h | 2 ++ libraries/octree/src/OctreeSceneStats.cpp | 3 +++ 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 751583960e..7a46fa3722 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -366,8 +366,20 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue } // start tracking our stats - bool isFullScene = ((!viewFrustumChanged || !nodeData->getWantDelta()) - && nodeData->getViewFrustumJustStoppedChanging()) || nodeData->hasLodChanged(); + qDebug() << "----"; + qDebug() << "viewFrustumChanged=" << viewFrustumChanged; + qDebug() << "nodeData->getWantDelta()=" << nodeData->getWantDelta(); + qDebug() << "nodeData->getViewFrustumJustStoppedChanging()=" << nodeData->getViewFrustumJustStoppedChanging(); + qDebug() << "nodeData->hasLodChanged()=" << nodeData->hasLodChanged(); + + + bool isFullScene = ( + (!viewFrustumChanged || !nodeData->getWantDelta()) + && nodeData->getViewFrustumJustStoppedChanging() + ) + || nodeData->hasLodChanged(); + + qDebug() << "isFullScene=" << isFullScene; // If we're starting a full scene, then definitely we want to empty the nodeBag if (isFullScene) { @@ -436,6 +448,8 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue bool isFullScene = ((!viewFrustumChanged || !nodeData->getWantDelta()) && nodeData->getViewFrustumJustStoppedChanging()) || nodeData->hasLodChanged(); + qDebug() << "SECOND CALC.... isFullScene=" << isFullScene; + EncodeBitstreamParams params(INT_MAX, &nodeData->getCurrentViewFrustum(), wantColor, WANT_EXISTS_BITS, DONT_CHOP, wantDelta, lastViewFrustum, wantOcclusionCulling, coverageMap, boundaryLevelAdjust, voxelSizeScale, diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 032e849f0a..f6cdfaa509 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -141,6 +141,9 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _justStarted(true), _voxelImporter(NULL), _wantToKillLocalVoxels(false), + _viewFrustum(), + _lastQueriedViewFrustum(), + _lastQueriedTime(usecTimestampNow()), _audioScope(256, 200, true), _myAvatar(), _mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)), @@ -1917,8 +1920,19 @@ void Application::updateMyAvatar(float deltaTime) { loadViewFrustum(_myCamera, _viewFrustum); // Update my voxel servers with my current voxel query... - queryOctree(NodeType::VoxelServer, PacketTypeVoxelQuery, _voxelServerJurisdictions); - queryOctree(NodeType::ParticleServer, PacketTypeParticleQuery, _particleServerJurisdictions); + quint64 now = usecTimestampNow(); + const quint64 TOO_LONG_SINCE_LAST_QUERY = 1 * USECS_PER_SECOND; + + // if we haven't waited long enough and the frustum is similar enough, then surpress this query... + if ((now - _lastQueriedTime) > TOO_LONG_SINCE_LAST_QUERY || !_lastQueriedViewFrustum.isVerySimilar(_viewFrustum)) { + _lastQueriedTime = now; + queryOctree(NodeType::VoxelServer, PacketTypeVoxelQuery, _voxelServerJurisdictions); + queryOctree(NodeType::ParticleServer, PacketTypeParticleQuery, _particleServerJurisdictions); + _lastQueriedViewFrustum = _viewFrustum; + //qDebug() << ">>>>>>>>>> SENDING query..."; + } else { + //qDebug() << "suppress query..."; + } } void Application::queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 234f264447..f56bb62d9f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -377,6 +377,8 @@ private: MetavoxelSystem _metavoxels; ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc. + ViewFrustum _lastQueriedViewFrustum; /// last view frustum used to query octree servers (voxels, particles) + quint64 _lastQueriedTime; Oscilloscope _audioScope; diff --git a/libraries/octree/src/OctreeSceneStats.cpp b/libraries/octree/src/OctreeSceneStats.cpp index ad7f774377..ec073c6ce5 100644 --- a/libraries/octree/src/OctreeSceneStats.cpp +++ b/libraries/octree/src/OctreeSceneStats.cpp @@ -167,6 +167,9 @@ void OctreeSceneStats::sceneStarted(bool isFullScene, bool isMoving, OctreeEleme _totalInternal = OctreeElement::getInternalNodeCount(); _totalLeaves = OctreeElement::getLeafNodeCount(); + if (isFullScene) { + qDebug() << "OctreeSceneStats::sceneStarted()... IS FULL SCENE"; + } _isFullScene = isFullScene; _isMoving = isMoving; From a95fd55172eb0ca1b1157643b56b81041f78a1a5 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 12 Mar 2014 01:11:21 -0700 Subject: [PATCH 08/14] suppress sending of extra queries when the client's view hasn't changed --- interface/src/Application.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f6cdfaa509..cf1966c585 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1921,17 +1921,17 @@ void Application::updateMyAvatar(float deltaTime) { // Update my voxel servers with my current voxel query... quint64 now = usecTimestampNow(); - const quint64 TOO_LONG_SINCE_LAST_QUERY = 1 * USECS_PER_SECOND; + quint64 sinceLastQuery = now - _lastQueriedTime; + const quint64 TOO_LONG_SINCE_LAST_QUERY = 3 * USECS_PER_SECOND; + bool queryIsDue = sinceLastQuery > TOO_LONG_SINCE_LAST_QUERY; + bool viewIsDifferentEnough = !_lastQueriedViewFrustum.isVerySimilar(_viewFrustum); - // if we haven't waited long enough and the frustum is similar enough, then surpress this query... - if ((now - _lastQueriedTime) > TOO_LONG_SINCE_LAST_QUERY || !_lastQueriedViewFrustum.isVerySimilar(_viewFrustum)) { + // if it's been a while since our last query or the view has significantly changed then send a query, otherwise suppress it + if (queryIsDue || viewIsDifferentEnough) { _lastQueriedTime = now; queryOctree(NodeType::VoxelServer, PacketTypeVoxelQuery, _voxelServerJurisdictions); queryOctree(NodeType::ParticleServer, PacketTypeParticleQuery, _particleServerJurisdictions); _lastQueriedViewFrustum = _viewFrustum; - //qDebug() << ">>>>>>>>>> SENDING query..."; - } else { - //qDebug() << "suppress query..."; } } From 7e6beba4d2ff40759df35f5eebdd1dea7dac49a1 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 12 Mar 2014 01:29:41 -0700 Subject: [PATCH 09/14] removed redundant calc of isFullScene --- .../src/octree/OctreeSendThread.cpp | 23 +++---------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 7a46fa3722..dcef7d59af 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -241,6 +241,7 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue int truePacketsSent = 0; int trueBytesSent = 0; int packetsSentThisInterval = 0; + bool isFullScene = false; bool somethingToSend = true; // assume we have something // FOR NOW... node tells us if it wants to receive only view frustum deltas @@ -366,20 +367,8 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue } // start tracking our stats - qDebug() << "----"; - qDebug() << "viewFrustumChanged=" << viewFrustumChanged; - qDebug() << "nodeData->getWantDelta()=" << nodeData->getWantDelta(); - qDebug() << "nodeData->getViewFrustumJustStoppedChanging()=" << nodeData->getViewFrustumJustStoppedChanging(); - qDebug() << "nodeData->hasLodChanged()=" << nodeData->hasLodChanged(); - - - bool isFullScene = ( - (!viewFrustumChanged || !nodeData->getWantDelta()) - && nodeData->getViewFrustumJustStoppedChanging() - ) - || nodeData->hasLodChanged(); - - qDebug() << "isFullScene=" << isFullScene; + isFullScene = ((!viewFrustumChanged || !nodeData->getWantDelta()) && nodeData->getViewFrustumJustStoppedChanging()) + || nodeData->hasLodChanged(); // If we're starting a full scene, then definitely we want to empty the nodeBag if (isFullScene) { @@ -444,12 +433,6 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue int boundaryLevelAdjust = boundaryLevelAdjustClient + (viewFrustumChanged && nodeData->getWantLowResMoving() ? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST); - - bool isFullScene = ((!viewFrustumChanged || !nodeData->getWantDelta()) && - nodeData->getViewFrustumJustStoppedChanging()) || nodeData->hasLodChanged(); - - qDebug() << "SECOND CALC.... isFullScene=" << isFullScene; - EncodeBitstreamParams params(INT_MAX, &nodeData->getCurrentViewFrustum(), wantColor, WANT_EXISTS_BITS, DONT_CHOP, wantDelta, lastViewFrustum, wantOcclusionCulling, coverageMap, boundaryLevelAdjust, voxelSizeScale, From 86feabee99ec35becd0ab85e9fffce071988aa3c Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 12 Mar 2014 02:22:24 -0700 Subject: [PATCH 10/14] add last scene packets, bytes and pps --- interface/src/ui/OctreeStatsDialog.cpp | 16 +++++++++++++-- libraries/octree/src/OctreeSceneStats.cpp | 25 +++++++++++++---------- libraries/octree/src/OctreeSceneStats.h | 9 ++++++-- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/interface/src/ui/OctreeStatsDialog.cpp b/interface/src/ui/OctreeStatsDialog.cpp index 92578b6b34..daf5a68587 100644 --- a/interface/src/ui/OctreeStatsDialog.cpp +++ b/interface/src/ui/OctreeStatsDialog.cpp @@ -315,13 +315,25 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser const unsigned long USECS_PER_MSEC = 1000; float lastFullEncode = stats.getLastFullTotalEncodeTime() / USECS_PER_MSEC; float lastFullSend = stats.getLastFullElapsedTime() / USECS_PER_MSEC; + float lastFullSendInSeconds = stats.getLastFullElapsedTime() / USECS_PER_SECOND; + float lastFullPackets = stats.getLastFullTotalPackets(); + float lastFullPPS = lastFullPackets; + if (lastFullSendInSeconds > 0) { + lastFullPPS = lastFullPackets / lastFullSendInSeconds; + } QString lastFullEncodeString = locale.toString(lastFullEncode); QString lastFullSendString = locale.toString(lastFullSend); + QString lastFullPacketsString = locale.toString(lastFullPackets); + QString lastFullBytesString = locale.toString((uint)stats.getLastFullTotalBytes()); + QString lastFullPPSString = locale.toString(lastFullPPS); extraDetails << "
" << "Last Full Scene... " << - "Encode Time: " << qPrintable(lastFullEncodeString) << " ms " << - "Send Time: " << qPrintable(lastFullSendString) << " ms "; + "Encode: " << qPrintable(lastFullEncodeString) << " ms " << + "Send: " << qPrintable(lastFullSendString) << " ms " << + "Packets: " << qPrintable(lastFullPacketsString) << " " << + "Bytes: " << qPrintable(lastFullBytesString) << " " << + "Rate: " << qPrintable(lastFullPPSString) << " PPS"; for (int i = 0; i < OctreeSceneStats::ITEM_COUNT; i++) { OctreeSceneStats::Item item = (OctreeSceneStats::Item)(i); diff --git a/libraries/octree/src/OctreeSceneStats.cpp b/libraries/octree/src/OctreeSceneStats.cpp index ec073c6ce5..e42fe17df0 100644 --- a/libraries/octree/src/OctreeSceneStats.cpp +++ b/libraries/octree/src/OctreeSceneStats.cpp @@ -27,9 +27,12 @@ OctreeSceneStats::OctreeSceneStats() : _isReadyToSend(false), _isStarted(false), _lastFullElapsed(0), + _lastFullTotalEncodeTime(0), + _lastFullTotalPackets(0), + _lastFullTotalBytes(0), + _elapsedAverage(samples), _bitsPerOctreeAverage(samples), - _lastFullTotalEncodeTime(0), _incomingPacket(0), _incomingBytes(0), _incomingWastedBytes(0), @@ -62,8 +65,10 @@ OctreeSceneStats& OctreeSceneStats::operator=(const OctreeSceneStats& other) { void OctreeSceneStats::copyFromOther(const OctreeSceneStats& other) { _totalEncodeTime = other._totalEncodeTime; _elapsed = other._elapsed; - _lastFullTotalEncodeTime = other._lastFullTotalEncodeTime; _lastFullElapsed = other._lastFullElapsed; + _lastFullTotalEncodeTime = other._lastFullTotalEncodeTime; + _lastFullTotalPackets = other._lastFullTotalPackets; + _lastFullTotalBytes = other._lastFullTotalBytes; _encodeStart = other._encodeStart; _packets = other._packets; @@ -167,9 +172,6 @@ void OctreeSceneStats::sceneStarted(bool isFullScene, bool isMoving, OctreeEleme _totalInternal = OctreeElement::getInternalNodeCount(); _totalLeaves = OctreeElement::getLeafNodeCount(); - if (isFullScene) { - qDebug() << "OctreeSceneStats::sceneStarted()... IS FULL SCENE"; - } _isFullScene = isFullScene; _isMoving = isMoving; @@ -511,12 +513,6 @@ int OctreeSceneStats::unpackFromMessage(const unsigned char* sourceBuffer, int a memcpy(&_isFullScene, sourceBuffer, sizeof(_isFullScene)); sourceBuffer += sizeof(_isFullScene); - - if (_isFullScene) { - _lastFullElapsed = _elapsed; - _lastFullTotalEncodeTime = _totalEncodeTime; - } - memcpy(&_isMoving, sourceBuffer, sizeof(_isMoving)); sourceBuffer += sizeof(_isMoving); memcpy(&_packets, sourceBuffer, sizeof(_packets)); @@ -524,6 +520,13 @@ int OctreeSceneStats::unpackFromMessage(const unsigned char* sourceBuffer, int a memcpy(&_bytes, sourceBuffer, sizeof(_bytes)); sourceBuffer += sizeof(_bytes); + if (_isFullScene) { + _lastFullElapsed = _elapsed; + _lastFullTotalEncodeTime = _totalEncodeTime; + _lastFullTotalPackets = _packets; + _lastFullTotalBytes = _bytes; + } + memcpy(&_totalInternal, sourceBuffer, sizeof(_totalInternal)); sourceBuffer += sizeof(_totalInternal); memcpy(&_totalLeaves, sourceBuffer, sizeof(_totalLeaves)); diff --git a/libraries/octree/src/OctreeSceneStats.h b/libraries/octree/src/OctreeSceneStats.h index 249ab376c1..2b39b3434c 100644 --- a/libraries/octree/src/OctreeSceneStats.h +++ b/libraries/octree/src/OctreeSceneStats.h @@ -150,8 +150,10 @@ public: unsigned long getTotalEncodeTime() const { return _totalEncodeTime; } unsigned long getElapsedTime() const { return _elapsed; } - unsigned long getLastFullTotalEncodeTime() const { return _lastFullTotalEncodeTime; } unsigned long getLastFullElapsedTime() const { return _lastFullElapsed; } + unsigned long getLastFullTotalEncodeTime() const { return _lastFullTotalEncodeTime; } + unsigned int getLastFullTotalPackets() const { return _lastFullTotalPackets; } + unsigned long getLastFullTotalBytes() const { return _lastFullTotalBytes; } // Used in client implementations to track individual octree packets void trackIncomingOctreePacket(const QByteArray& packet, bool wasStatsPacket, int nodeClockSkewUsec); @@ -181,13 +183,16 @@ private: quint64 _start; quint64 _end; quint64 _elapsed; + quint64 _lastFullElapsed; + quint64 _lastFullTotalEncodeTime; + unsigned int _lastFullTotalPackets; + unsigned long _lastFullTotalBytes; SimpleMovingAverage _elapsedAverage; SimpleMovingAverage _bitsPerOctreeAverage; quint64 _totalEncodeTime; - quint64 _lastFullTotalEncodeTime; quint64 _encodeStart; // scene octree related data From 6173a4d2a79bb1dc969794ab5095cb77261271f5 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 12 Mar 2014 10:19:21 -0700 Subject: [PATCH 11/14] fix isFullScene correctly --- assignment-client/src/octree/OctreeSendThread.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index dcef7d59af..ef69771607 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -241,7 +241,9 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue int truePacketsSent = 0; int trueBytesSent = 0; int packetsSentThisInterval = 0; - bool isFullScene = false; + bool isFullScene = ((!viewFrustumChanged || !nodeData->getWantDelta()) && nodeData->getViewFrustumJustStoppedChanging()) + || nodeData->hasLodChanged(); + bool somethingToSend = true; // assume we have something // FOR NOW... node tells us if it wants to receive only view frustum deltas @@ -366,10 +368,6 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue << " Wasted:" << _totalWastedBytes; } - // start tracking our stats - isFullScene = ((!viewFrustumChanged || !nodeData->getWantDelta()) && nodeData->getViewFrustumJustStoppedChanging()) - || nodeData->hasLodChanged(); - // If we're starting a full scene, then definitely we want to empty the nodeBag if (isFullScene) { nodeData->nodeBag.deleteAll(); @@ -383,6 +381,7 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue } ::startSceneSleepTime = _usleepTime; + // start tracking our stats nodeData->stats.sceneStarted(isFullScene, viewFrustumChanged, _myServer->getOctree()->getRoot(), _myServer->getJurisdiction()); // This is the start of "resending" the scene. From 8622f2d548d5e8c942aeac5c31edda3b6c1882be Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 12 Mar 2014 10:20:33 -0700 Subject: [PATCH 12/14] fix comment --- domain-server/src/DomainServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 8a95a25e23..a425052970 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -544,7 +544,7 @@ void DomainServer::readAvailableDatagrams() { // construct the requested assignment from the packet data Assignment requestAssignment(receivedPacket); - // Suppress these for Assignment::AgentType to 1 per second... + // Suppress these for Assignment::AgentType to once per 5 seconds static quint64 lastNoisyMessage = usecTimestampNow(); quint64 timeNow = usecTimestampNow(); const quint64 NOISY_TIME_ELAPSED = 5 * USECS_PER_SECOND; From 4b60c549e77e021b43344bd7246a3c28279761e1 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 12 Mar 2014 11:10:52 -0700 Subject: [PATCH 13/14] add LOD to overlay display --- interface/src/Application.cpp | 25 +++++++++++------ interface/src/Menu.cpp | 34 +++++++++++++++++++++++ interface/src/Menu.h | 1 + interface/src/ui/LodToolsDialog.cpp | 42 +++-------------------------- interface/src/ui/LodToolsDialog.h | 2 -- 5 files changed, 56 insertions(+), 48 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cf1966c585..2007b7929c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2786,8 +2786,8 @@ void Application::displayStats() { voxelStats.str(""); QString packetsString = locale.toString((int)voxelPacketsToProcess); QString maxString = locale.toString((int)_recentMaxPackets); - voxelStats << "Voxel Packets to Process: " << packetsString.toLocal8Bit().constData() - << " [Recent Max: " << maxString.toLocal8Bit().constData() << "]"; + voxelStats << "Voxel Packets to Process: " << qPrintable(packetsString) + << " [Recent Max: " << qPrintable(maxString) << "]"; verticalOffset += STATS_PELS_PER_LINE; drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT); } @@ -2810,7 +2810,7 @@ void Application::displayStats() { // Server Voxels voxelStats.str(""); - voxelStats << "Server voxels: " << serversTotalString.toLocal8Bit().constData(); + voxelStats << "Server voxels: " << qPrintable(serversTotalString); verticalOffset += STATS_PELS_PER_LINE; drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT); @@ -2820,8 +2820,8 @@ void Application::displayStats() { voxelStats.str(""); voxelStats << - "Internal: " << serversInternalString.toLocal8Bit().constData() << " " << - "Leaves: " << serversLeavesString.toLocal8Bit().constData() << ""; + "Internal: " << qPrintable(serversInternalString) << " " << + "Leaves: " << qPrintable(serversLeavesString) << ""; verticalOffset += STATS_PELS_PER_LINE; drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT); } @@ -2831,7 +2831,7 @@ void Application::displayStats() { // Local Voxels voxelStats.str(""); - voxelStats << "Local voxels: " << localTotalString.toLocal8Bit().constData(); + voxelStats << "Local voxels: " << qPrintable(localTotalString); verticalOffset += STATS_PELS_PER_LINE; drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT); @@ -2843,8 +2843,17 @@ void Application::displayStats() { voxelStats.str(""); voxelStats << - "Internal: " << localInternalString.toLocal8Bit().constData() << " " << - "Leaves: " << localLeavesString.toLocal8Bit().constData() << ""; + "Internal: " << qPrintable(localInternalString) << " " << + "Leaves: " << qPrintable(localLeavesString) << ""; + verticalOffset += STATS_PELS_PER_LINE; + drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT); + } + + // LOD Details + if (_statsExpanded) { + voxelStats.str(""); + QString displayLODDetails = Menu::getInstance()->getLODFeedbackText(); + voxelStats << "LOD: You can see " << qPrintable(displayLODDetails.trimmed()); verticalOffset += STATS_PELS_PER_LINE; drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT); } diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 5f6c541bc5..543694f404 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1087,6 +1087,40 @@ void Menu::octreeStatsDetailsClosed() { } } +QString Menu::getLODFeedbackText() { + // determine granularity feedback + int boundaryLevelAdjust = getBoundaryLevelAdjust(); + QString granularityFeedback; + + switch (boundaryLevelAdjust) { + case 0: { + granularityFeedback = QString("at standard granularity."); + } break; + case 1: { + granularityFeedback = QString("at half of standard granularity."); + } break; + case 2: { + granularityFeedback = QString("at a third of standard granularity."); + } break; + default: { + granularityFeedback = QString("at 1/%1th of standard granularity.").arg(boundaryLevelAdjust + 1); + } break; + } + + // distance feedback + float voxelSizeScale = getVoxelSizeScale(); + float relativeToDefault = voxelSizeScale / DEFAULT_OCTREE_SIZE_SCALE; + QString result; + if (relativeToDefault > 1.01) { + result = QString("%1 further %2").arg(relativeToDefault,8,'f',2).arg(granularityFeedback); + } else if (relativeToDefault > 0.99) { + result = QString("the default distance %1").arg(granularityFeedback); + } else { + result = QString("%1 of default %2").arg(relativeToDefault,8,'f',3).arg(granularityFeedback); + } + return result; +} + void Menu::autoAdjustLOD(float currentFPS) { // NOTE: our first ~100 samples at app startup are completely all over the place, and we don't // really want to count them in our average, so we will ignore the real frame rates and stuff diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 380fe2d3b7..00ef51178a 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -84,6 +84,7 @@ public: void handleViewFrustumOffsetKeyModifier(int key); // User Tweakable LOD Items + QString getLODFeedbackText(); void autoAdjustLOD(float currentFPS); void setVoxelSizeScale(float sizeScale); float getVoxelSizeScale() const { return _voxelSizeScale; } diff --git a/interface/src/ui/LodToolsDialog.cpp b/interface/src/ui/LodToolsDialog.cpp index 4cf4a29bf1..564669757c 100644 --- a/interface/src/ui/LodToolsDialog.cpp +++ b/interface/src/ui/LodToolsDialog.cpp @@ -68,7 +68,7 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) : const unsigned redish = 0xfff00000; palette.setColor(QPalette::WindowText, QColor::fromRgb(redish)); _feedback->setPalette(palette); - _feedback->setText(getFeedbackText()); + _feedback->setText(Menu::getInstance()->getLODFeedbackText()); const int FEEDBACK_WIDTH = 350; _feedback->setFixedWidth(FEEDBACK_WIDTH); form->addRow("You can see... ", _feedback); @@ -81,40 +81,6 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) : this->QDialog::setLayout(form); } -QString LodToolsDialog::getFeedbackText() { - // determine granularity feedback - int boundaryLevelAdjust = Menu::getInstance()->getBoundaryLevelAdjust(); - QString granularityFeedback; - - switch (boundaryLevelAdjust) { - case 0: { - granularityFeedback = QString("at standard granularity."); - } break; - case 1: { - granularityFeedback = QString("at half of standard granularity."); - } break; - case 2: { - granularityFeedback = QString("at a third of standard granularity."); - } break; - default: { - granularityFeedback = QString("at 1/%1th of standard granularity.").arg(boundaryLevelAdjust + 1); - } break; - } - - // distance feedback - float voxelSizeScale = Menu::getInstance()->getVoxelSizeScale(); - float relativeToDefault = voxelSizeScale / DEFAULT_OCTREE_SIZE_SCALE; - QString result; - if (relativeToDefault > 1.01) { - result = QString("%1 further %2").arg(relativeToDefault,8,'f',2).arg(granularityFeedback); - } else if (relativeToDefault > 0.99) { - result = QString("the default distance %1").arg(granularityFeedback); - } else { - result = QString("%1 of default %2").arg(relativeToDefault,8,'f',3).arg(granularityFeedback); - } - return result; -} - LodToolsDialog::~LodToolsDialog() { delete _feedback; delete _lodSize; @@ -124,19 +90,19 @@ LodToolsDialog::~LodToolsDialog() { void LodToolsDialog::reloadSliders() { _lodSize->setValue(Menu::getInstance()->getVoxelSizeScale() / TREE_SCALE); _boundaryLevelAdjust->setValue(Menu::getInstance()->getBoundaryLevelAdjust()); - _feedback->setText(getFeedbackText()); + _feedback->setText(Menu::getInstance()->getLODFeedbackText()); } void LodToolsDialog::sizeScaleValueChanged(int value) { float realValue = value * TREE_SCALE; Menu::getInstance()->setVoxelSizeScale(realValue); - _feedback->setText(getFeedbackText()); + _feedback->setText(Menu::getInstance()->getLODFeedbackText()); } void LodToolsDialog::boundaryLevelValueChanged(int value) { Menu::getInstance()->setBoundaryLevelAdjust(value); - _feedback->setText(getFeedbackText()); + _feedback->setText(Menu::getInstance()->getLODFeedbackText()); } void LodToolsDialog::resetClicked(bool checked) { diff --git a/interface/src/ui/LodToolsDialog.h b/interface/src/ui/LodToolsDialog.h index ee96cffd7e..98a5fce5f8 100644 --- a/interface/src/ui/LodToolsDialog.h +++ b/interface/src/ui/LodToolsDialog.h @@ -36,8 +36,6 @@ protected: void closeEvent(QCloseEvent*); private: - QString getFeedbackText(); - QSlider* _lodSize; QSlider* _boundaryLevelAdjust; QLabel* _feedback; From d67381d85ee890e57a70c4c5c9dd7236f2dec158 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Wed, 12 Mar 2014 23:45:10 +0200 Subject: [PATCH 14/14] Changed the font used in the chat to Helvetica, with Arial as a fallback. --- interface/interface_en.ts | 14 +++++++------- interface/src/ui/ChatWindow.cpp | 5 +---- interface/ui/chatWindow.ui | 5 ++++- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 685c6e3f67..72299befa4 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -4,22 +4,22 @@ Application - + Export Voxels - + Sparse Voxel Octree Files (*.svo) - + Open Script - + JavaScript Files (*.js) @@ -28,19 +28,19 @@ ChatWindow - + Chat - + Connecting to XMPP... - + online now: diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index 2fd3d4f9cb..5fc5d56430 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -184,11 +184,8 @@ void ChatWindow::messageReceived(const QXmppMessage& message) { } QLabel* userLabel = new QLabel(getParticipantName(message.from())); - QFont font = userLabel->font(); - font.setBold(true); - userLabel->setFont(font); userLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - userLabel->setStyleSheet("padding: 2px;"); + userLabel->setStyleSheet("padding: 2px; font-weight: bold"); userLabel->setAlignment(Qt::AlignTop); QLabel* messageLabel = new QLabel(message.body().replace(regexLinks, "\\1")); diff --git a/interface/ui/chatWindow.ui b/interface/ui/chatWindow.ui index 199d9b42e3..18c9b3814a 100644 --- a/interface/ui/chatWindow.ui +++ b/interface/ui/chatWindow.ui @@ -67,7 +67,7 @@ - margin-top: 12px; + margin-top: 12px; font-family: Helvetica, Arial, sans-serif; Qt::ScrollBarAlwaysOff @@ -121,6 +121,9 @@ 0 + + font-family: Helvetica, Arial, sans-serif; + Qt::ScrollBarAlwaysOff