mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 09:57:26 +02:00
Merge pull request #1227 from ZappoMan/new_voxel_scene_stats
New voxel scene stats
This commit is contained in:
commit
5c219697bc
10 changed files with 344 additions and 131 deletions
|
@ -3396,20 +3396,91 @@ void Application::displayStats() {
|
||||||
sprintf(avatarStats, "Avatar: pos %.3f, %.3f, %.3f, vel %.1f, yaw = %.2f", avatarPos.x, avatarPos.y, avatarPos.z, glm::length(_myAvatar.getVelocity()), _myAvatar.getBodyYaw());
|
sprintf(avatarStats, "Avatar: pos %.3f, %.3f, %.3f, vel %.1f, yaw = %.2f", avatarPos.x, avatarPos.y, avatarPos.z, glm::length(_myAvatar.getVelocity()), _myAvatar.getBodyYaw());
|
||||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, avatarStats);
|
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, avatarStats);
|
||||||
|
|
||||||
|
Node* avatarMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
||||||
|
char avatarMixerStats[200];
|
||||||
|
if (avatarMixer) {
|
||||||
|
sprintf(avatarMixerStats, "Avatar Mixer: %.f kbps, %.f pps",
|
||||||
|
roundf(avatarMixer->getAverageKilobitsPerSecond()),
|
||||||
|
roundf(avatarMixer->getAveragePacketsPerSecond()));
|
||||||
|
} else {
|
||||||
|
sprintf(avatarMixerStats, "No Avatar Mixer");
|
||||||
|
}
|
||||||
|
statsVerticalOffset += PELS_PER_LINE;
|
||||||
|
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, avatarMixerStats);
|
||||||
|
|
||||||
|
|
||||||
|
// Used for formatting voxel stats details
|
||||||
|
statsVerticalOffset += PELS_PER_LINE; // skip a line for voxels
|
||||||
QLocale locale(QLocale::English);
|
QLocale locale(QLocale::English);
|
||||||
|
|
||||||
std::stringstream voxelStats;
|
std::stringstream voxelStats;
|
||||||
voxelStats.precision(4);
|
|
||||||
voxelStats << "Voxels " <<
|
// iterate all the current voxel stats, and list their sending modes, and total voxel counts
|
||||||
"Max: " << _voxels.getMaxVoxels() / 1000.f << "K " <<
|
std::stringstream sendingMode("");
|
||||||
"Rendered: " << _voxels.getVoxelsRendered() / 1000.f << "K " <<
|
sendingMode << "Voxel Sending Mode: [";
|
||||||
"Written: " << _voxels.getVoxelsWritten() / 1000.f << "K " <<
|
int serverCount = 0;
|
||||||
"Abandoned: " << _voxels.getAbandonedVoxels() / 1000.f << "K " <<
|
int movingServerCount = 0;
|
||||||
"Updated: " << _voxels.getVoxelsUpdated() / 1000.f << "K ";
|
unsigned long totalNodes = 0;
|
||||||
|
unsigned long totalInternal = 0;
|
||||||
|
unsigned long totalLeaves = 0;
|
||||||
|
for(NodeToVoxelSceneStatsIterator i = _voxelServerSceneStats.begin(); i != _voxelServerSceneStats.end(); i++) {
|
||||||
|
//const QUuid& uuid = i->first;
|
||||||
|
VoxelSceneStats& stats = i->second;
|
||||||
|
serverCount++;
|
||||||
|
if (serverCount > 1) {
|
||||||
|
sendingMode << ",";
|
||||||
|
}
|
||||||
|
if (stats.isMoving()) {
|
||||||
|
sendingMode << "M";
|
||||||
|
movingServerCount++;
|
||||||
|
} else {
|
||||||
|
sendingMode << "S";
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate server node totals
|
||||||
|
totalNodes += stats.getTotalVoxels();
|
||||||
|
totalInternal += stats.getTotalInternal();
|
||||||
|
totalLeaves += stats.getTotalLeaves();
|
||||||
|
}
|
||||||
|
if (serverCount == 0) {
|
||||||
|
sendingMode << "---";
|
||||||
|
}
|
||||||
|
sendingMode << "] " << serverCount << " servers";
|
||||||
|
if (movingServerCount > 0) {
|
||||||
|
sendingMode << " <SCENE NOT STABLE>";
|
||||||
|
} else {
|
||||||
|
sendingMode << " <SCENE STABLE>";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString serversTotalString = locale.toString((uint)totalNodes); // consider adding: .rightJustified(10, ' ');
|
||||||
|
QString serversInternalString = locale.toString((uint)totalInternal);
|
||||||
|
QString serversLeavesString = locale.toString((uint)totalLeaves);
|
||||||
|
|
||||||
|
// Server Voxels
|
||||||
|
voxelStats.str("");
|
||||||
|
voxelStats <<
|
||||||
|
"Server Voxels Total: " << serversTotalString.toLocal8Bit().constData() << " / " <<
|
||||||
|
"Internal: " << serversInternalString.toLocal8Bit().constData() << " / " <<
|
||||||
|
"Leaves: " << serversLeavesString.toLocal8Bit().constData() << "";
|
||||||
statsVerticalOffset += PELS_PER_LINE;
|
statsVerticalOffset += PELS_PER_LINE;
|
||||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
||||||
|
|
||||||
|
unsigned long localTotal = VoxelNode::getNodeCount();
|
||||||
|
unsigned long localInternal = VoxelNode::getInternalNodeCount();
|
||||||
|
unsigned long localLeaves = VoxelNode::getLeafNodeCount();
|
||||||
|
QString localTotalString = locale.toString((uint)localTotal); // consider adding: .rightJustified(10, ' ');
|
||||||
|
QString localInternalString = locale.toString((uint)localInternal);
|
||||||
|
QString localLeavesString = locale.toString((uint)localLeaves);
|
||||||
|
|
||||||
|
// Local Voxels
|
||||||
|
voxelStats.str("");
|
||||||
|
voxelStats <<
|
||||||
|
"Local Voxels Total: " << localTotalString.toLocal8Bit().constData() << " / " <<
|
||||||
|
"Internal: " << localInternalString.toLocal8Bit().constData() << " / " <<
|
||||||
|
"Leaves: " << localLeavesString.toLocal8Bit().constData() << "";
|
||||||
|
statsVerticalOffset += PELS_PER_LINE;
|
||||||
|
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
||||||
|
|
||||||
|
// Local Voxel Memory Usage
|
||||||
voxelStats.str("");
|
voxelStats.str("");
|
||||||
voxelStats <<
|
voxelStats <<
|
||||||
"Voxels Memory Nodes: " << VoxelNode::getTotalMemoryUsage() / 1000000.f << "MB "
|
"Voxels Memory Nodes: " << VoxelNode::getTotalMemoryUsage() / 1000000.f << "MB "
|
||||||
|
@ -3421,51 +3492,25 @@ void Application::displayStats() {
|
||||||
statsVerticalOffset += PELS_PER_LINE;
|
statsVerticalOffset += PELS_PER_LINE;
|
||||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
||||||
|
|
||||||
unsigned long localTotal = VoxelNode::getNodeCount();
|
// Voxel Rendering
|
||||||
unsigned long localInternal = VoxelNode::getInternalNodeCount();
|
|
||||||
unsigned long localLeaves = VoxelNode::getLeafNodeCount();
|
|
||||||
QString localTotalString = locale.toString((uint)localTotal); // consider adding: .rightJustified(10, ' ');
|
|
||||||
QString localInternalString = locale.toString((uint)localInternal);
|
|
||||||
QString localLeavesString = locale.toString((uint)localLeaves);
|
|
||||||
|
|
||||||
|
|
||||||
voxelStats.str("");
|
voxelStats.str("");
|
||||||
voxelStats <<
|
voxelStats.precision(4);
|
||||||
"Local Voxels Total: " << localTotalString.toLocal8Bit().constData() << " / " <<
|
voxelStats << "Voxel Rendering Slots" <<
|
||||||
"Internal: " << localInternalString.toLocal8Bit().constData() << " / " <<
|
"Max: " << _voxels.getMaxVoxels() / 1000.f << "K " <<
|
||||||
"Leaves: " << localLeavesString.toLocal8Bit().constData() << "";
|
"Drawn: " << _voxels.getVoxelsWritten() / 1000.f << "K " <<
|
||||||
|
"Abandoned: " << _voxels.getAbandonedVoxels() / 1000.f << "K ";
|
||||||
statsVerticalOffset += PELS_PER_LINE;
|
statsVerticalOffset += PELS_PER_LINE;
|
||||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
||||||
|
|
||||||
voxelStats.str("");
|
// draw Sending mode AFTER server node stats
|
||||||
char* voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_VOXELS);
|
|
||||||
voxelStats << "Voxels Sent from Server: " << voxelDetails;
|
|
||||||
statsVerticalOffset += PELS_PER_LINE;
|
statsVerticalOffset += PELS_PER_LINE;
|
||||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)sendingMode.str().c_str());
|
||||||
|
|
||||||
voxelStats.str("");
|
|
||||||
voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_ELAPSED);
|
|
||||||
voxelStats << "Scene Send Time from Server: " << voxelDetails;
|
|
||||||
statsVerticalOffset += PELS_PER_LINE;
|
|
||||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
|
||||||
|
|
||||||
voxelStats.str("");
|
|
||||||
voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_ENCODE);
|
|
||||||
voxelStats << "Encode Time on Server: " << voxelDetails;
|
|
||||||
statsVerticalOffset += PELS_PER_LINE;
|
|
||||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
|
||||||
|
|
||||||
voxelStats.str("");
|
|
||||||
voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_MODE);
|
|
||||||
voxelStats << "Sending Mode: " << voxelDetails;
|
|
||||||
statsVerticalOffset += PELS_PER_LINE;
|
|
||||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
|
||||||
|
|
||||||
|
// Incoming packets
|
||||||
voxelStats.str("");
|
voxelStats.str("");
|
||||||
int voxelPacketsToProcess = _voxelProcessor.packetsToProcessCount();
|
int voxelPacketsToProcess = _voxelProcessor.packetsToProcessCount();
|
||||||
QString packetsString = locale.toString((int)voxelPacketsToProcess);
|
QString packetsString = locale.toString((int)voxelPacketsToProcess);
|
||||||
QString maxString = locale.toString((int)_recentMaxPackets);
|
QString maxString = locale.toString((int)_recentMaxPackets);
|
||||||
|
|
||||||
voxelStats << "Voxel Packets to Process: " << packetsString.toLocal8Bit().constData()
|
voxelStats << "Voxel Packets to Process: " << packetsString.toLocal8Bit().constData()
|
||||||
<< " [Recent Max: " << maxString.toLocal8Bit().constData() << "]";
|
<< " [Recent Max: " << maxString.toLocal8Bit().constData() << "]";
|
||||||
|
|
||||||
|
@ -3484,18 +3529,7 @@ void Application::displayStats() {
|
||||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
||||||
|
|
||||||
|
|
||||||
Node *avatarMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
// Leap data
|
||||||
char avatarMixerStats[200];
|
|
||||||
|
|
||||||
if (avatarMixer) {
|
|
||||||
sprintf(avatarMixerStats, "Avatar Mixer: %.f kbps, %.f pps",
|
|
||||||
roundf(avatarMixer->getAverageKilobitsPerSecond()),
|
|
||||||
roundf(avatarMixer->getAveragePacketsPerSecond()));
|
|
||||||
} else {
|
|
||||||
sprintf(avatarMixerStats, "No Avatar Mixer");
|
|
||||||
}
|
|
||||||
statsVerticalOffset += PELS_PER_LINE;
|
|
||||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, avatarMixerStats);
|
|
||||||
statsVerticalOffset += PELS_PER_LINE;
|
statsVerticalOffset += PELS_PER_LINE;
|
||||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)LeapManager::statusString().c_str());
|
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)LeapManager::statusString().c_str());
|
||||||
|
|
||||||
|
@ -4075,6 +4109,10 @@ void Application::domainChanged(QString domain) {
|
||||||
|
|
||||||
// reset the environment so that we don't erroneously end up with multiple
|
// reset the environment so that we don't erroneously end up with multiple
|
||||||
_environment.resetToDefault();
|
_environment.resetToDefault();
|
||||||
|
|
||||||
|
// reset our node to stats and node to jurisdiction maps... since these must be changing...
|
||||||
|
_voxelServerJurisdictions.clear();
|
||||||
|
_voxelServerSceneStats.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::nodeAdded(Node* node) {
|
void Application::nodeAdded(Node* node) {
|
||||||
|
@ -4101,6 +4139,14 @@ void Application::nodeKilled(Node* node) {
|
||||||
fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
|
fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
|
||||||
_voxelFades.push_back(fade);
|
_voxelFades.push_back(fade);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the voxel server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server
|
||||||
|
_voxelServerJurisdictions.erase(nodeUUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// also clean up scene stats for that server
|
||||||
|
if (_voxelServerSceneStats.find(nodeUUID) != _voxelServerSceneStats.end()) {
|
||||||
|
_voxelServerSceneStats.erase(nodeUUID);
|
||||||
}
|
}
|
||||||
} else if (node->getLinkedData() == _lookatTargetAvatar) {
|
} else if (node->getLinkedData() == _lookatTargetAvatar) {
|
||||||
_lookatTargetAvatar = NULL;
|
_lookatTargetAvatar = NULL;
|
||||||
|
@ -4109,19 +4155,43 @@ void Application::nodeKilled(Node* node) {
|
||||||
|
|
||||||
int Application::parseVoxelStats(unsigned char* messageData, ssize_t messageLength, sockaddr senderAddress) {
|
int Application::parseVoxelStats(unsigned char* messageData, ssize_t messageLength, sockaddr senderAddress) {
|
||||||
|
|
||||||
// parse the incoming stats data, and stick it into our averaging stats object for now... even though this
|
|
||||||
// means mixing in stats from potentially multiple servers.
|
|
||||||
int statsMessageLength = _voxelSceneStats.unpackFromMessage(messageData, messageLength);
|
|
||||||
|
|
||||||
// But, also identify the sender, and keep track of the contained jurisdiction root for this server
|
// But, also identify the sender, and keep track of the contained jurisdiction root for this server
|
||||||
Node* voxelServer = NodeList::getInstance()->nodeWithAddress(&senderAddress);
|
Node* voxelServer = NodeList::getInstance()->nodeWithAddress(&senderAddress);
|
||||||
|
|
||||||
|
// parse the incoming stats datas stick it in a temporary object for now, while we
|
||||||
|
// determine which server it belongs to
|
||||||
|
VoxelSceneStats temp;
|
||||||
|
int statsMessageLength = temp.unpackFromMessage(messageData, messageLength);
|
||||||
|
|
||||||
// quick fix for crash... why would voxelServer be NULL?
|
// quick fix for crash... why would voxelServer be NULL?
|
||||||
if (voxelServer) {
|
if (voxelServer) {
|
||||||
QUuid nodeUUID = voxelServer->getUUID();
|
QUuid nodeUUID = voxelServer->getUUID();
|
||||||
|
|
||||||
|
// now that we know the node ID, let's add these stats to the stats for that node...
|
||||||
|
if (_voxelServerSceneStats.find(nodeUUID) != _voxelServerSceneStats.end()) {
|
||||||
|
VoxelSceneStats& oldStats = _voxelServerSceneStats[nodeUUID];
|
||||||
|
|
||||||
|
// this if construct is a little strange because we aren't quite using it yet. But
|
||||||
|
// we want to keep this logic in here for now because we plan to use it soon to determine
|
||||||
|
// additional network optimization states and better rate control
|
||||||
|
if (!oldStats.isMoving() && temp.isMoving()) {
|
||||||
|
// we think we are starting to move
|
||||||
|
_voxelServerSceneStats[nodeUUID].unpackFromMessage(messageData, messageLength);
|
||||||
|
} else if (oldStats.isMoving() && !temp.isMoving()) {
|
||||||
|
// we think we are done moving
|
||||||
|
_voxelServerSceneStats[nodeUUID].unpackFromMessage(messageData, messageLength);
|
||||||
|
} else if (!oldStats.isMoving() && !temp.isMoving()) {
|
||||||
|
// we think we are still not moving
|
||||||
|
} else {
|
||||||
|
// we think we are still moving
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_voxelServerSceneStats[nodeUUID] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
VoxelPositionSize rootDetails;
|
VoxelPositionSize rootDetails;
|
||||||
voxelDetailsForCode(_voxelSceneStats.getJurisdictionRoot(), rootDetails);
|
voxelDetailsForCode(temp.getJurisdictionRoot(), rootDetails);
|
||||||
|
|
||||||
// see if this is the first we've heard of this node...
|
// see if this is the first we've heard of this node...
|
||||||
if (_voxelServerJurisdictions.find(nodeUUID) == _voxelServerJurisdictions.end()) {
|
if (_voxelServerJurisdictions.find(nodeUUID) == _voxelServerJurisdictions.end()) {
|
||||||
|
@ -4142,7 +4212,7 @@ int Application::parseVoxelStats(unsigned char* messageData, ssize_t messageLeng
|
||||||
// but VoxelSceneStats thinks it's just returning a reference to it's contents. So we need to make a copy of the
|
// but VoxelSceneStats thinks it's just returning a reference to it's contents. So we need to make a copy of the
|
||||||
// details from the VoxelSceneStats to construct the JurisdictionMap
|
// details from the VoxelSceneStats to construct the JurisdictionMap
|
||||||
JurisdictionMap jurisdictionMap;
|
JurisdictionMap jurisdictionMap;
|
||||||
jurisdictionMap.copyContents(_voxelSceneStats.getJurisdictionRoot(), _voxelSceneStats.getJurisdictionEndNodes());
|
jurisdictionMap.copyContents(temp.getJurisdictionRoot(), temp.getJurisdictionEndNodes());
|
||||||
_voxelServerJurisdictions[nodeUUID] = jurisdictionMap;
|
_voxelServerJurisdictions[nodeUUID] = jurisdictionMap;
|
||||||
}
|
}
|
||||||
return statsMessageLength;
|
return statsMessageLength;
|
||||||
|
|
|
@ -135,7 +135,7 @@ public:
|
||||||
QSettings* getSettings() { return _settings; }
|
QSettings* getSettings() { return _settings; }
|
||||||
Swatch* getSwatch() { return &_swatch; }
|
Swatch* getSwatch() { return &_swatch; }
|
||||||
QMainWindow* getWindow() { return _window; }
|
QMainWindow* getWindow() { return _window; }
|
||||||
VoxelSceneStats* getVoxelSceneStats() { return &_voxelSceneStats; }
|
NodeToVoxelSceneStats* getVoxelSceneStats() { return &_voxelServerSceneStats; }
|
||||||
|
|
||||||
QNetworkAccessManager* getNetworkAccessManager() { return _networkAccessManager; }
|
QNetworkAccessManager* getNetworkAccessManager() { return _networkAccessManager; }
|
||||||
GeometryCache* getGeometryCache() { return &_geometryCache; }
|
GeometryCache* getGeometryCache() { return &_geometryCache; }
|
||||||
|
@ -448,10 +448,10 @@ private:
|
||||||
|
|
||||||
PieMenu _pieMenu;
|
PieMenu _pieMenu;
|
||||||
|
|
||||||
VoxelSceneStats _voxelSceneStats;
|
|
||||||
int parseVoxelStats(unsigned char* messageData, ssize_t messageLength, sockaddr senderAddress);
|
int parseVoxelStats(unsigned char* messageData, ssize_t messageLength, sockaddr senderAddress);
|
||||||
|
|
||||||
NodeToJurisdictionMap _voxelServerJurisdictions;
|
NodeToJurisdictionMap _voxelServerJurisdictions;
|
||||||
|
NodeToVoxelSceneStats _voxelServerSceneStats;
|
||||||
|
|
||||||
std::vector<VoxelFade> _voxelFades;
|
std::vector<VoxelFade> _voxelFades;
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,8 +13,6 @@
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
|
|
||||||
#include <VoxelSceneStats.h>
|
|
||||||
|
|
||||||
class LodToolsDialog : public QDialog {
|
class LodToolsDialog : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -14,46 +14,72 @@
|
||||||
|
|
||||||
#include <VoxelSceneStats.h>
|
#include <VoxelSceneStats.h>
|
||||||
|
|
||||||
|
#include "Application.h"
|
||||||
|
|
||||||
#include "ui/VoxelStatsDialog.h"
|
#include "ui/VoxelStatsDialog.h"
|
||||||
|
|
||||||
|
VoxelStatsDialog::VoxelStatsDialog(QWidget* parent, NodeToVoxelSceneStats* model) :
|
||||||
VoxelStatsDialog::VoxelStatsDialog(QWidget* parent, VoxelSceneStats* model) :
|
|
||||||
QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint),
|
QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint),
|
||||||
_model(model) {
|
_model(model) {
|
||||||
|
|
||||||
char strBuf[64];
|
_statCount = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_STATS; i++) {
|
||||||
|
_labels[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
this->setWindowTitle("Voxel Statistics");
|
this->setWindowTitle("Voxel Statistics");
|
||||||
|
|
||||||
// Create layouter
|
// Create layouter
|
||||||
QFormLayout* form = new QFormLayout();
|
_form = new QFormLayout();
|
||||||
this->QDialog::setLayout(form);
|
this->QDialog::setLayout(_form);
|
||||||
|
|
||||||
// Setup labels
|
// Setup stat items
|
||||||
|
_serverVoxels = AddStatItem("Voxels on Servers", GREENISH);
|
||||||
|
_localVoxels = AddStatItem("Local Voxels", YELLOWISH);
|
||||||
|
_localVoxelsMemory = AddStatItem("Voxels Memory", GREYISH);
|
||||||
|
_voxelsRendered = AddStatItem("Voxels Rendered", GREENISH);
|
||||||
|
_sendingMode = AddStatItem("Sending Mode", YELLOWISH);
|
||||||
|
|
||||||
|
/** NOT YET READY
|
||||||
|
VoxelSceneStats temp;
|
||||||
for (int i = 0; i < VoxelSceneStats::ITEM_COUNT; i++) {
|
for (int i = 0; i < VoxelSceneStats::ITEM_COUNT; i++) {
|
||||||
VoxelSceneStats::Item item = (VoxelSceneStats::Item)(i);
|
VoxelSceneStats::Item item = (VoxelSceneStats::Item)(i);
|
||||||
VoxelSceneStats::ItemInfo& itemInfo = _model->getItemInfo(item);
|
VoxelSceneStats::ItemInfo& itemInfo = temp.getItemInfo(item);
|
||||||
QLabel* label = _labels[item] = new QLabel();
|
AddStatItem(itemInfo.caption, itemInfo.colorRGBA);
|
||||||
|
}
|
||||||
|
**/
|
||||||
|
}
|
||||||
|
|
||||||
|
int VoxelStatsDialog::AddStatItem(const char* caption, unsigned colorRGBA) {
|
||||||
|
char strBuf[64];
|
||||||
|
const int STATS_LABEL_WIDTH = 550;
|
||||||
|
|
||||||
|
_statCount++; // increment our current stat count
|
||||||
|
|
||||||
|
QLabel* label = _labels[_statCount] = new QLabel();
|
||||||
|
|
||||||
// Set foreground color to 62.5% brightness of the meter (otherwise will be hard to read on the bright background)
|
// Set foreground color to 62.5% brightness of the meter (otherwise will be hard to read on the bright background)
|
||||||
QPalette palette = label->palette();
|
QPalette palette = label->palette();
|
||||||
unsigned rgb = itemInfo.colorRGBA >> 8;
|
|
||||||
|
// This goofiness came from the bandwidth meter code, it basically stores a color in an unsigned and extracts it
|
||||||
|
unsigned rgb = colorRGBA >> 8;
|
||||||
const unsigned colorpart1 = 0xfefefeu;
|
const unsigned colorpart1 = 0xfefefeu;
|
||||||
const unsigned colorpart2 = 0xf8f8f8;
|
const unsigned colorpart2 = 0xf8f8f8;
|
||||||
rgb = ((rgb & colorpart1) >> 1) + ((rgb & colorpart2) >> 3);
|
rgb = ((rgb & colorpart1) >> 1) + ((rgb & colorpart2) >> 3);
|
||||||
palette.setColor(QPalette::WindowText, QColor::fromRgb(rgb));
|
palette.setColor(QPalette::WindowText, QColor::fromRgb(rgb));
|
||||||
label->setPalette(palette);
|
label->setPalette(palette);
|
||||||
|
|
||||||
const int STATS_LABEL_WIDTH = 550;
|
|
||||||
label->setFixedWidth(STATS_LABEL_WIDTH);
|
label->setFixedWidth(STATS_LABEL_WIDTH);
|
||||||
|
|
||||||
snprintf(strBuf, sizeof(strBuf), " %s:", itemInfo.caption);
|
snprintf(strBuf, sizeof(strBuf), " %s:", caption);
|
||||||
form->addRow(strBuf, label);
|
_form->addRow(strBuf, label);
|
||||||
}
|
|
||||||
|
return _statCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
VoxelStatsDialog::~VoxelStatsDialog() {
|
VoxelStatsDialog::~VoxelStatsDialog() {
|
||||||
for (int i = 0; i < VoxelSceneStats::ITEM_COUNT; ++i) {
|
for (int i = 0; i < _statCount; i++) {
|
||||||
delete _labels[i];
|
delete _labels[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,16 +87,104 @@ VoxelStatsDialog::~VoxelStatsDialog() {
|
||||||
void VoxelStatsDialog::paintEvent(QPaintEvent* event) {
|
void VoxelStatsDialog::paintEvent(QPaintEvent* event) {
|
||||||
|
|
||||||
// Update labels
|
// Update labels
|
||||||
char strBuf[256];
|
|
||||||
for (int i = 0; i < VoxelSceneStats::ITEM_COUNT; i++) {
|
VoxelSystem* voxels = Application::getInstance()->getVoxels();
|
||||||
VoxelSceneStats::Item item = (VoxelSceneStats::Item)(i);
|
QLabel* label;
|
||||||
QLabel* label = _labels[item];
|
QLocale locale(QLocale::English);
|
||||||
snprintf(strBuf, sizeof(strBuf), "%s", _model->getItemValue(item));
|
std::stringstream statsValue;
|
||||||
label->setText(strBuf);
|
statsValue.precision(4);
|
||||||
|
|
||||||
|
// Voxels Rendered
|
||||||
|
label = _labels[_voxelsRendered];
|
||||||
|
statsValue << "Max: " << voxels->getMaxVoxels() / 1000.f << "K " <<
|
||||||
|
"Drawn: " << voxels->getVoxelsWritten() / 1000.f << "K " <<
|
||||||
|
"Abandoned: " << voxels->getAbandonedVoxels() / 1000.f << "K " <<
|
||||||
|
"ReadBuffer: " << voxels->getVoxelsRendered() / 1000.f << "K " <<
|
||||||
|
"Changed: " << voxels->getVoxelsUpdated() / 1000.f << "K ";
|
||||||
|
label->setText(statsValue.str().c_str());
|
||||||
|
|
||||||
|
// Voxels Memory Usage
|
||||||
|
label = _labels[_localVoxelsMemory];
|
||||||
|
statsValue.str("");
|
||||||
|
statsValue <<
|
||||||
|
"Nodes RAM: " << VoxelNode::getTotalMemoryUsage() / 1000000.f << "MB "
|
||||||
|
"Geometry RAM: " << voxels->getVoxelMemoryUsageRAM() / 1000000.f << "MB " <<
|
||||||
|
"VBO: " << voxels->getVoxelMemoryUsageVBO() / 1000000.f << "MB ";
|
||||||
|
if (voxels->hasVoxelMemoryUsageGPU()) {
|
||||||
|
statsValue << "GPU: " << voxels->getVoxelMemoryUsageGPU() / 1000000.f << "MB ";
|
||||||
|
}
|
||||||
|
label->setText(statsValue.str().c_str());
|
||||||
|
|
||||||
|
// Local Voxels
|
||||||
|
label = _labels[_localVoxels];
|
||||||
|
unsigned long localTotal = VoxelNode::getNodeCount();
|
||||||
|
unsigned long localInternal = VoxelNode::getInternalNodeCount();
|
||||||
|
unsigned long localLeaves = VoxelNode::getLeafNodeCount();
|
||||||
|
QString localTotalString = locale.toString((uint)localTotal); // consider adding: .rightJustified(10, ' ');
|
||||||
|
QString localInternalString = locale.toString((uint)localInternal);
|
||||||
|
QString localLeavesString = locale.toString((uint)localLeaves);
|
||||||
|
|
||||||
|
statsValue.str("");
|
||||||
|
statsValue <<
|
||||||
|
"Total: " << localTotalString.toLocal8Bit().constData() << " / " <<
|
||||||
|
"Internal: " << localInternalString.toLocal8Bit().constData() << " / " <<
|
||||||
|
"Leaves: " << localLeavesString.toLocal8Bit().constData() << "";
|
||||||
|
label->setText(statsValue.str().c_str());
|
||||||
|
|
||||||
|
// iterate all the current voxel stats, and list their sending modes, total their voxels, etc...
|
||||||
|
std::stringstream sendingMode("");
|
||||||
|
|
||||||
|
int serverCount = 0;
|
||||||
|
int movingServerCount = 0;
|
||||||
|
unsigned long totalNodes = 0;
|
||||||
|
unsigned long totalInternal = 0;
|
||||||
|
unsigned long totalLeaves = 0;
|
||||||
|
NodeToVoxelSceneStats* sceneStats = Application::getInstance()->getVoxelSceneStats();
|
||||||
|
for(NodeToVoxelSceneStatsIterator i = sceneStats->begin(); i != sceneStats->end(); i++) {
|
||||||
|
//const QUuid& uuid = i->first;
|
||||||
|
VoxelSceneStats& stats = i->second;
|
||||||
|
serverCount++;
|
||||||
|
|
||||||
|
// calculate server node totals
|
||||||
|
totalNodes += stats.getTotalVoxels();
|
||||||
|
totalInternal += stats.getTotalInternal();
|
||||||
|
totalLeaves += stats.getTotalLeaves();
|
||||||
|
|
||||||
|
// Sending mode
|
||||||
|
if (serverCount > 1) {
|
||||||
|
sendingMode << ",";
|
||||||
|
}
|
||||||
|
if (stats.isMoving()) {
|
||||||
|
sendingMode << "M";
|
||||||
|
movingServerCount++;
|
||||||
|
} else {
|
||||||
|
sendingMode << "S";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sendingMode << " - " << serverCount << " servers";
|
||||||
|
if (movingServerCount > 0) {
|
||||||
|
sendingMode << " <SCENE NOT STABLE>";
|
||||||
|
} else {
|
||||||
|
sendingMode << " <SCENE STABLE>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label = _labels[_sendingMode];
|
||||||
|
label->setText(sendingMode.str().c_str());
|
||||||
|
|
||||||
|
// Server Voxels
|
||||||
|
QString serversTotalString = locale.toString((uint)totalNodes); // consider adding: .rightJustified(10, ' ');
|
||||||
|
QString serversInternalString = locale.toString((uint)totalInternal);
|
||||||
|
QString serversLeavesString = locale.toString((uint)totalLeaves);
|
||||||
|
label = _labels[_serverVoxels];
|
||||||
|
statsValue.str("");
|
||||||
|
statsValue <<
|
||||||
|
"Total: " << serversTotalString.toLocal8Bit().constData() << " / " <<
|
||||||
|
"Internal: " << serversInternalString.toLocal8Bit().constData() << " / " <<
|
||||||
|
"Leaves: " << serversLeavesString.toLocal8Bit().constData() << "";
|
||||||
|
label->setText(statsValue.str().c_str());
|
||||||
|
|
||||||
this->QDialog::paintEvent(event);
|
this->QDialog::paintEvent(event);
|
||||||
this->setFixedSize(this->width(), this->height());
|
//this->setFixedSize(this->width(), this->height());
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStatsDialog::reject() {
|
void VoxelStatsDialog::reject() {
|
||||||
|
|
|
@ -10,15 +10,18 @@
|
||||||
#define __hifi__VoxelStatsDialog__
|
#define __hifi__VoxelStatsDialog__
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
#include <QFormLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
|
||||||
#include <VoxelSceneStats.h>
|
#include <VoxelSceneStats.h>
|
||||||
|
|
||||||
|
#define MAX_STATS 40
|
||||||
|
|
||||||
class VoxelStatsDialog : public QDialog {
|
class VoxelStatsDialog : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
// Sets up the UI
|
// Sets up the UI
|
||||||
VoxelStatsDialog(QWidget* parent, VoxelSceneStats* model);
|
VoxelStatsDialog(QWidget* parent, NodeToVoxelSceneStats* model);
|
||||||
~VoxelStatsDialog();
|
~VoxelStatsDialog();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -34,9 +37,19 @@ protected:
|
||||||
// Emits a 'closed' signal when this dialog is closed.
|
// Emits a 'closed' signal when this dialog is closed.
|
||||||
void closeEvent(QCloseEvent*);
|
void closeEvent(QCloseEvent*);
|
||||||
|
|
||||||
|
int AddStatItem(const char* caption, unsigned colorRGBA);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QLabel* _labels[VoxelSceneStats::ITEM_COUNT];
|
QFormLayout* _form;
|
||||||
VoxelSceneStats* _model;
|
QLabel* _labels[MAX_STATS];
|
||||||
|
NodeToVoxelSceneStats* _model;
|
||||||
|
int _statCount;
|
||||||
|
|
||||||
|
int _sendingMode;
|
||||||
|
int _serverVoxels;
|
||||||
|
int _localVoxels;
|
||||||
|
int _localVoxelsMemory;
|
||||||
|
int _voxelsRendered;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__interface__VoxelStatsDialog__) */
|
#endif /* defined(__interface__VoxelStatsDialog__) */
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
class SimpleMovingAverage {
|
class SimpleMovingAverage {
|
||||||
public:
|
public:
|
||||||
SimpleMovingAverage(int numSamplesToAverage);
|
SimpleMovingAverage(int numSamplesToAverage = 100);
|
||||||
|
|
||||||
int updateAverage(float sample);
|
int updateAverage(float sample);
|
||||||
void reset();
|
void reset();
|
||||||
|
@ -30,8 +30,8 @@ private:
|
||||||
float _average;
|
float _average;
|
||||||
float _eventDeltaAverage;
|
float _eventDeltaAverage;
|
||||||
|
|
||||||
const float WEIGHTING;
|
float WEIGHTING;
|
||||||
const float ONE_MINUS_WEIGHTING;
|
float ONE_MINUS_WEIGHTING;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__Stats__) */
|
#endif /* defined(__hifi__Stats__) */
|
||||||
|
|
|
@ -103,6 +103,7 @@ void VoxelNodeData::resetVoxelPacket() {
|
||||||
// the clients requested color state.
|
// the clients requested color state.
|
||||||
_currentPacketIsColor = (LOW_RES_MONO && getWantLowResMoving() && _viewFrustumChanging) ? false : getWantColor();
|
_currentPacketIsColor = (LOW_RES_MONO && getWantLowResMoving() && _viewFrustumChanging) ? false : getWantColor();
|
||||||
PACKET_TYPE voxelPacketType = _currentPacketIsColor ? PACKET_TYPE_VOXEL_DATA : PACKET_TYPE_VOXEL_DATA_MONOCHROME;
|
PACKET_TYPE voxelPacketType = _currentPacketIsColor ? PACKET_TYPE_VOXEL_DATA : PACKET_TYPE_VOXEL_DATA_MONOCHROME;
|
||||||
|
|
||||||
int numBytesPacketHeader = populateTypeAndVersion(_voxelPacket, voxelPacketType);
|
int numBytesPacketHeader = populateTypeAndVersion(_voxelPacket, voxelPacketType);
|
||||||
_voxelPacketAt = _voxelPacket + numBytesPacketHeader;
|
_voxelPacketAt = _voxelPacket + numBytesPacketHeader;
|
||||||
_voxelPacketAvailableBytes = MAX_VOXEL_PACKET_SIZE - numBytesPacketHeader;
|
_voxelPacketAvailableBytes = MAX_VOXEL_PACKET_SIZE - numBytesPacketHeader;
|
||||||
|
|
|
@ -107,6 +107,7 @@ int VoxelSendThread::handlePacketSend(Node* node, VoxelNodeData* nodeData, int&
|
||||||
NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(),
|
NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(),
|
||||||
nodeData->getPacket(), nodeData->getPacketLength());
|
nodeData->getPacket(), nodeData->getPacketLength());
|
||||||
}
|
}
|
||||||
|
nodeData->stats.markAsSent();
|
||||||
} else {
|
} else {
|
||||||
// just send the voxel packet
|
// just send the voxel packet
|
||||||
NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(),
|
NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(),
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
#include <PacketHeaders.h>
|
#include <PacketHeaders.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
|
|
||||||
|
@ -521,30 +524,26 @@ void VoxelSceneStats::printDebugDetails() {
|
||||||
qDebug(" trees removed : %lu\n", _treesRemoved );
|
qDebug(" trees removed : %lu\n", _treesRemoved );
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned greenish = 0x40ff40d0;
|
|
||||||
const unsigned yellowish = 0xffef40c0;
|
|
||||||
const unsigned greyish = 0xd0d0d0a0;
|
|
||||||
|
|
||||||
VoxelSceneStats::ItemInfo VoxelSceneStats::_ITEMS[] = {
|
VoxelSceneStats::ItemInfo VoxelSceneStats::_ITEMS[] = {
|
||||||
{ "Elapsed" , greenish },
|
{ "Elapsed" , GREENISH , 2 , "Elapsed,fps" },
|
||||||
{ "Encode" , yellowish },
|
{ "Encode" , YELLOWISH , 2 , "Time,fps" },
|
||||||
{ "Network" , greyish },
|
{ "Network" , GREYISH , 3 , "Packets,Bytes,KBPS" },
|
||||||
{ "Voxels on Server" , greenish },
|
{ "Voxels on Server" , GREENISH , 3 , "Total,Internal,Leaves" },
|
||||||
{ "Voxels Sent" , yellowish },
|
{ "Voxels Sent" , YELLOWISH , 5 , "Total,Bits/Voxel,Avg Bits/Voxel,Internal,Leaves" },
|
||||||
{ "Colors Sent" , greyish },
|
{ "Colors Sent" , GREYISH , 3 , "Total,Internal,Leaves" },
|
||||||
{ "Bitmasks Sent" , greenish },
|
{ "Bitmasks Sent" , GREENISH , 3 , "Colors,Exists,In Packets" },
|
||||||
{ "Traversed" , yellowish },
|
{ "Traversed" , YELLOWISH , 3 , "Total,Internal,Leaves" },
|
||||||
{ "Skipped - Total" , greyish },
|
{ "Skipped - Total" , GREYISH , 3 , "Total,Internal,Leaves" },
|
||||||
{ "Skipped - Distance" , greenish },
|
{ "Skipped - Distance" , GREENISH , 3 , "Total,Internal,Leaves" },
|
||||||
{ "Skipped - Out of View", yellowish },
|
{ "Skipped - Out of View", YELLOWISH , 3 , "Total,Internal,Leaves" },
|
||||||
{ "Skipped - Was in View", greyish },
|
{ "Skipped - Was in View", GREYISH , 3 , "Total,Internal,Leaves" },
|
||||||
{ "Skipped - No Change" , greenish },
|
{ "Skipped - No Change" , GREENISH , 3 , "Total,Internal,Leaves" },
|
||||||
{ "Skipped - Occluded" , yellowish },
|
{ "Skipped - Occluded" , YELLOWISH , 3 , "Total,Internal,Leaves" },
|
||||||
{ "Didn't fit in packet" , greyish },
|
{ "Didn't fit in packet" , GREYISH , 4 , "Total,Internal,Leaves,Removed" },
|
||||||
{ "Mode" , greenish },
|
{ "Mode" , GREENISH , 4 , "Moving,Stationary,Partial,Full" },
|
||||||
};
|
};
|
||||||
|
|
||||||
char* VoxelSceneStats::getItemValue(Item item) {
|
const char* VoxelSceneStats::getItemValue(Item item) {
|
||||||
const uint64_t USECS_PER_SECOND = 1000 * 1000;
|
const uint64_t USECS_PER_SECOND = 1000 * 1000;
|
||||||
int calcFPS, calcAverageFPS, calculatedKBPS;
|
int calcFPS, calcAverageFPS, calculatedKBPS;
|
||||||
switch(item) {
|
switch(item) {
|
||||||
|
@ -651,3 +650,4 @@ char* VoxelSceneStats::getItemValue(Item item) {
|
||||||
return _itemValueBuffer;
|
return _itemValueBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
#include "JurisdictionMap.h"
|
#include "JurisdictionMap.h"
|
||||||
|
|
||||||
|
#define GREENISH 0x40ff40d0
|
||||||
|
#define YELLOWISH 0xffef40c0
|
||||||
|
#define GREYISH 0xd0d0d0a0
|
||||||
|
|
||||||
class VoxelNode;
|
class VoxelNode;
|
||||||
|
|
||||||
/// Collects statistics for calculating and sending a scene from a voxel server to an interface client
|
/// Collects statistics for calculating and sending a scene from a voxel server to an interface client
|
||||||
|
@ -116,6 +120,8 @@ public:
|
||||||
struct ItemInfo {
|
struct ItemInfo {
|
||||||
char const* const caption;
|
char const* const caption;
|
||||||
unsigned colorRGBA;
|
unsigned colorRGBA;
|
||||||
|
int detailsCount;
|
||||||
|
const char* detailsLabels;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Returns details about items tracked by VoxelSceneStats
|
/// Returns details about items tracked by VoxelSceneStats
|
||||||
|
@ -124,7 +130,7 @@ public:
|
||||||
|
|
||||||
/// Returns a UI formatted value of an item tracked by VoxelSceneStats
|
/// Returns a UI formatted value of an item tracked by VoxelSceneStats
|
||||||
/// \param Item item The item from the stats you're interested in.
|
/// \param Item item The item from the stats you're interested in.
|
||||||
char* getItemValue(Item item);
|
const char* getItemValue(Item item);
|
||||||
|
|
||||||
/// Returns OctCode for root node of the jurisdiction of this particular voxel server
|
/// Returns OctCode for root node of the jurisdiction of this particular voxel server
|
||||||
unsigned char* getJurisdictionRoot() const { return _jurisdictionRoot; }
|
unsigned char* getJurisdictionRoot() const { return _jurisdictionRoot; }
|
||||||
|
@ -132,6 +138,11 @@ public:
|
||||||
/// Returns list of OctCodes for end nodes of the jurisdiction of this particular voxel server
|
/// Returns list of OctCodes for end nodes of the jurisdiction of this particular voxel server
|
||||||
const std::vector<unsigned char*>& getJurisdictionEndNodes() const { return _jurisdictionEndNodes; }
|
const std::vector<unsigned char*>& getJurisdictionEndNodes() const { return _jurisdictionEndNodes; }
|
||||||
|
|
||||||
|
bool isMoving() const { return _isMoving; };
|
||||||
|
unsigned long getTotalVoxels() const { return _totalVoxels; }
|
||||||
|
unsigned long getTotalInternal() const { return _totalInternal; }
|
||||||
|
unsigned long getTotalLeaves() const { return _totalLeaves; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _isReadyToSend;
|
bool _isReadyToSend;
|
||||||
unsigned char _statsMessage[MAX_PACKET_SIZE];
|
unsigned char _statsMessage[MAX_PACKET_SIZE];
|
||||||
|
@ -224,4 +235,9 @@ private:
|
||||||
std::vector<unsigned char*> _jurisdictionEndNodes;
|
std::vector<unsigned char*> _jurisdictionEndNodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Map between node IDs and their reported VoxelSceneStats. Typically used by classes that need to know which nodes sent
|
||||||
|
/// which voxel stats
|
||||||
|
typedef std::map<QUuid, VoxelSceneStats> NodeToVoxelSceneStats;
|
||||||
|
typedef std::map<QUuid, VoxelSceneStats>::iterator NodeToVoxelSceneStatsIterator;
|
||||||
|
|
||||||
#endif /* defined(__hifi__VoxelSceneStats__) */
|
#endif /* defined(__hifi__VoxelSceneStats__) */
|
||||||
|
|
Loading…
Reference in a new issue