mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 16:14:01 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi
This commit is contained in:
commit
9ad2ea9059
16 changed files with 291 additions and 125 deletions
|
@ -241,6 +241,9 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue
|
|||
int truePacketsSent = 0;
|
||||
int trueBytesSent = 0;
|
||||
int packetsSentThisInterval = 0;
|
||||
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
|
||||
|
@ -365,10 +368,6 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue
|
|||
<< " Wasted:" << _totalWastedBytes;
|
||||
}
|
||||
|
||||
// start tracking our stats
|
||||
bool 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();
|
||||
|
@ -382,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.
|
||||
|
@ -432,10 +432,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();
|
||||
|
||||
EncodeBitstreamParams params(INT_MAX, &nodeData->getCurrentViewFrustum(), wantColor,
|
||||
WANT_EXISTS_BITS, DONT_CHOP, wantDelta, lastViewFrustum,
|
||||
wantOcclusionCulling, coverageMap, boundaryLevelAdjust, voxelSizeScale,
|
||||
|
|
|
@ -544,8 +544,16 @@ 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 once per 5 seconds
|
||||
static quint64 lastNoisyMessage = usecTimestampNow();
|
||||
quint64 timeNow = usecTimestampNow();
|
||||
const quint64 NOISY_TIME_ELAPSED = 5 * USECS_PER_SECOND;
|
||||
bool noisyMessage = false;
|
||||
if (requestAssignment.getType() != Assignment::AgentType || (timeNow - lastNoisyMessage) > NOISY_TIME_ELAPSED) {
|
||||
qDebug() << "Received a request for assignment type" << requestAssignment.getType()
|
||||
<< "from" << senderSockAddr;
|
||||
noisyMessage = true;
|
||||
}
|
||||
|
||||
SharedAssignmentPointer assignmentToDeploy = deployableAssignmentForRequest(requestAssignment);
|
||||
|
||||
|
@ -562,8 +570,15 @@ 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 - lastNoisyMessage) > NOISY_TIME_ELAPSED) {
|
||||
qDebug() << "Unable to fulfill assignment request of type" << requestAssignment.getType()
|
||||
<< "from" << senderSockAddr;
|
||||
noisyMessage = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (noisyMessage) {
|
||||
lastNoisyMessage = timeNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,19 +28,19 @@
|
|||
<name>ChatWindow</name>
|
||||
<message>
|
||||
<location filename="ui/chatWindow.ui" line="14"/>
|
||||
<location filename="../build/interface/ui_chatWindow.h" line="112"/>
|
||||
<location filename="../build/interface/ui_chatWindow.h" line="113"/>
|
||||
<source>Chat</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="ui/chatWindow.ui" line="41"/>
|
||||
<location filename="../build/interface/ui_chatWindow.h" line="113"/>
|
||||
<location filename="../build/interface/ui_chatWindow.h" line="114"/>
|
||||
<source>Connecting to XMPP...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="ui/chatWindow.ui" line="60"/>
|
||||
<location filename="../build/interface/ui_chatWindow.h" line="114"/>
|
||||
<location filename="../build/interface/ui_chatWindow.h" line="115"/>
|
||||
<source> online now:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
|
|
@ -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)),
|
||||
|
@ -1895,8 +1898,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();
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
|
||||
void Application::queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions) {
|
||||
|
@ -2745,8 +2759,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.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||
}
|
||||
|
@ -2769,7 +2783,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.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||
|
||||
|
@ -2779,8 +2793,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.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||
}
|
||||
|
@ -2790,7 +2804,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.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||
|
||||
|
@ -2802,8 +2816,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.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||
}
|
||||
|
|
|
@ -376,6 +376,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;
|
||||
|
||||
|
|
|
@ -1091,6 +1091,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
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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, "<a href=\"\\1\">\\1</a>"));
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -36,8 +36,6 @@ protected:
|
|||
void closeEvent(QCloseEvent*);
|
||||
|
||||
private:
|
||||
QString getFeedbackText();
|
||||
|
||||
QSlider* _lodSize;
|
||||
QSlider* _boundaryLevelAdjust;
|
||||
QLabel* _feedback;
|
||||
|
|
|
@ -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 << ", "
|
||||
|
@ -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 << "<br/>" << "Last Full Scene... " <<
|
||||
"Encode Time: " << lastFullEncodeString.toLocal8Bit().constData() << " ms " <<
|
||||
"Send Time: " << lastFullSendString.toLocal8Bit().constData() << " 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);
|
||||
|
@ -334,42 +346,51 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser
|
|||
QString internalString = locale.toString((uint)stats.getTotalInternal());
|
||||
QString leavesString = locale.toString((uint)stats.getTotalLeaves());
|
||||
|
||||
serverDetails << "<br/>" << "Node UUID: " <<
|
||||
nodeUUID.toString().toLocal8Bit().constData() << " ";
|
||||
serverDetails << "<br/>" << "Node UUID: " << qPrintable(nodeUUID.toString()) << " ";
|
||||
|
||||
serverDetails << "<br/>" << "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 << "<br/>" << "Incoming Packets: " <<
|
||||
incomingPacketsString.toLocal8Bit().constData() <<
|
||||
" Out of Order: " << incomingOutOfOrderString.toLocal8Bit().constData() <<
|
||||
" Likely Lost: " << incomingLikelyLostString.toLocal8Bit().constData();
|
||||
serverDetails << "<br/>" << "Incoming Packets: " << qPrintable(incomingPacketsString) <<
|
||||
"/ Lost: " << qPrintable(incomingLikelyLostString) <<
|
||||
"/ Recovered: " << qPrintable(incomingRecovered);
|
||||
|
||||
serverDetails << "<br/>" << " Out of Order: " << qPrintable(incomingOutOfOrderString) <<
|
||||
"/ Early: " << qPrintable(incomingEarlyString) <<
|
||||
"/ Late: " << qPrintable(incomingLateString) <<
|
||||
"/ Really Late: " << qPrintable(incomingReallyLateString) <<
|
||||
"/ Duplicate: " << qPrintable(incomingDuplicateString);
|
||||
|
||||
serverDetails << "<br/>" <<
|
||||
" Average Flight Time: " << incomingFlightTimeString.toLocal8Bit().constData() << " msecs";
|
||||
" Average Flight Time: " << qPrintable(incomingFlightTimeString) << " msecs";
|
||||
|
||||
serverDetails << "<br/>" <<
|
||||
" Average Ping Time: " << incomingPingTimeString.toLocal8Bit().constData() << " msecs";
|
||||
" Average Ping Time: " << qPrintable(incomingPingTimeString) << " msecs";
|
||||
|
||||
serverDetails << "<br/>" <<
|
||||
" Average Clock Skew: " << incomingClockSkewString.toLocal8Bit().constData() << " msecs";
|
||||
|
||||
" Average Clock Skew: " << qPrintable(incomingClockSkewString) << " msecs";
|
||||
|
||||
serverDetails << "<br/>" << "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) {
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
<item>
|
||||
<widget class="QScrollArea" name="messagesScrollArea">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">margin-top: 12px;</string>
|
||||
<string notr="true">margin-top: 12px; font-family: Helvetica, Arial, sans-serif;</string>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
|
@ -121,6 +121,9 @@
|
|||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font-family: Helvetica, Arial, sans-serif;</string>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
#include <cmath>
|
||||
#include <fstream> // to load voxels from file
|
||||
|
||||
#include <glm/gtc/noise.hpp>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "CoverageMap.h"
|
||||
|
|
|
@ -18,20 +18,32 @@
|
|||
#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),
|
||||
_isStarted(false),
|
||||
_lastFullElapsed(0),
|
||||
_lastFullTotalEncodeTime(0),
|
||||
_lastFullTotalPackets(0),
|
||||
_lastFullTotalBytes(0),
|
||||
|
||||
_elapsedAverage(samples),
|
||||
_bitsPerOctreeAverage(samples),
|
||||
_lastFullTotalEncodeTime(0),
|
||||
_incomingPacket(0),
|
||||
_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)
|
||||
{
|
||||
|
@ -53,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;
|
||||
|
@ -134,8 +148,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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -493,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));
|
||||
|
@ -506,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));
|
||||
|
@ -823,18 +844,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;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
@ -159,8 +161,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:
|
||||
|
@ -176,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
|
||||
|
@ -251,9 +261,15 @@ private:
|
|||
unsigned int _incomingPacket;
|
||||
unsigned long _incomingBytes;
|
||||
unsigned long _incomingWastedBytes;
|
||||
unsigned int _incomingLastSequence;
|
||||
unsigned int _incomingOutOfOrder;
|
||||
unsigned int _incomingLikelyLost;
|
||||
|
||||
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<unsigned int> _missingSequenceNumbers;
|
||||
SimpleMovingAverage _incomingFlightTimeAverage;
|
||||
|
||||
// features related items
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include <glm/gtc/noise.hpp>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QImage>
|
||||
#include <QRgb>
|
||||
|
|
Loading…
Reference in a new issue