mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 12:53:03 +02:00
commit
11e6982a9d
3 changed files with 49 additions and 25 deletions
|
@ -24,7 +24,7 @@ VoxelSendThread::VoxelSendThread(const QUuid& nodeUUID, VoxelServer* myServer) :
|
|||
}
|
||||
|
||||
bool VoxelSendThread::process() {
|
||||
uint64_t lastSendTime = usecTimestampNow();
|
||||
uint64_t start = usecTimestampNow();
|
||||
|
||||
Node* node = NodeList::getInstance()->nodeWithUUID(_nodeUUID);
|
||||
VoxelNodeData* nodeData = NULL;
|
||||
|
@ -32,6 +32,8 @@ bool VoxelSendThread::process() {
|
|||
if (node) {
|
||||
nodeData = (VoxelNodeData*) node->getLinkedData();
|
||||
}
|
||||
|
||||
int packetsSent = 0;
|
||||
|
||||
// Sometimes the node data has not yet been linked, in which case we can't really do anything
|
||||
if (nodeData) {
|
||||
|
@ -39,11 +41,12 @@ bool VoxelSendThread::process() {
|
|||
if (_myServer->wantsDebugVoxelSending()) {
|
||||
printf("nodeData->updateCurrentViewFrustum() changed=%s\n", debug::valueOf(viewFrustumChanged));
|
||||
}
|
||||
deepestLevelVoxelDistributor(node, nodeData, viewFrustumChanged);
|
||||
packetsSent = deepestLevelVoxelDistributor(node, nodeData, viewFrustumChanged);
|
||||
}
|
||||
|
||||
// dynamically sleep until we need to fire off the next set of voxels
|
||||
int usecToSleep = VOXEL_SEND_INTERVAL_USECS - (usecTimestampNow() - lastSendTime);
|
||||
int elapsed = (usecTimestampNow() - start);
|
||||
int usecToSleep = VOXEL_SEND_INTERVAL_USECS - elapsed;
|
||||
|
||||
if (usecToSleep > 0) {
|
||||
usleep(usecToSleep);
|
||||
|
@ -52,19 +55,19 @@ bool VoxelSendThread::process() {
|
|||
std::cout << "Last send took too much time, not sleeping!\n";
|
||||
}
|
||||
}
|
||||
|
||||
return isStillRunning(); // keep running till they terminate us
|
||||
}
|
||||
|
||||
|
||||
void VoxelSendThread::handlePacketSend(Node* node, VoxelNodeData* nodeData, int& trueBytesSent, int& truePacketsSent) {
|
||||
int VoxelSendThread::handlePacketSend(Node* node, VoxelNodeData* nodeData, int& trueBytesSent, int& truePacketsSent) {
|
||||
|
||||
int packetsSent = 0;
|
||||
// Here's where we check to see if this packet is a duplicate of the last packet. If it is, we will silently
|
||||
// obscure the packet and not send it. This allows the callers and upper level logic to not need to know about
|
||||
// this rate control savings.
|
||||
if (nodeData->shouldSuppressDuplicatePacket()) {
|
||||
nodeData->resetVoxelPacket(); // we still need to reset it though!
|
||||
return; // without sending...
|
||||
return packetsSent; // without sending...
|
||||
}
|
||||
|
||||
// If we've got a stats message ready to send, then see if we can piggyback them together
|
||||
|
@ -85,6 +88,10 @@ void VoxelSendThread::handlePacketSend(Node* node, VoxelNodeData* nodeData, int&
|
|||
} else {
|
||||
// not enough room in the packet, send two packets
|
||||
NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(), statsMessage, statsMessageLength);
|
||||
trueBytesSent += statsMessageLength;
|
||||
truePacketsSent++;
|
||||
packetsSent++;
|
||||
|
||||
NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(),
|
||||
nodeData->getPacket(), nodeData->getPacketLength());
|
||||
}
|
||||
|
@ -97,16 +104,21 @@ void VoxelSendThread::handlePacketSend(Node* node, VoxelNodeData* nodeData, int&
|
|||
nodeData->stats.packetSent(nodeData->getPacketLength());
|
||||
trueBytesSent += nodeData->getPacketLength();
|
||||
truePacketsSent++;
|
||||
packetsSent++;
|
||||
nodeData->resetVoxelPacket();
|
||||
return packetsSent;
|
||||
}
|
||||
|
||||
/// Version of voxel distributor that sends the deepest LOD level at once
|
||||
void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* nodeData, bool viewFrustumChanged) {
|
||||
int VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* nodeData, bool viewFrustumChanged) {
|
||||
|
||||
_myServer->lockTree();
|
||||
|
||||
int truePacketsSent = 0;
|
||||
int trueBytesSent = 0;
|
||||
int packetsSentThisInterval = 0;
|
||||
bool somethingToSend = true; // assume we have something
|
||||
|
||||
|
||||
// FOR NOW... node tells us if it wants to receive only view frustum deltas
|
||||
bool wantDelta = viewFrustumChanged && nodeData->getWantDelta();
|
||||
|
@ -127,8 +139,7 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
|||
debug::valueOf(wantColor), debug::valueOf(nodeData->getCurrentPacketIsColor()));
|
||||
}
|
||||
|
||||
handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
|
||||
|
||||
packetsSentThisInterval += handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
|
||||
} else {
|
||||
if (_myServer->wantsDebugVoxelSending()) {
|
||||
printf("wantColor=%s --- FIXING HEADER! nodeData->getCurrentPacketIsColor()=%s\n",
|
||||
|
@ -217,21 +228,26 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
|||
// If we have something in our nodeBag, then turn them into packets and send them out...
|
||||
if (!nodeData->nodeBag.isEmpty()) {
|
||||
int bytesWritten = 0;
|
||||
int packetsSentThisInterval = 0;
|
||||
uint64_t start = usecTimestampNow();
|
||||
|
||||
bool shouldSendEnvironments = _myServer->wantSendEnvironments() && shouldDo(ENVIRONMENT_SEND_INTERVAL_USECS, VOXEL_SEND_INTERVAL_USECS);
|
||||
|
||||
int clientMaxPacketsPerInterval = nodeData->getMaxVoxelPacketsPerSecond() / INTERVALS_PER_SECOND;
|
||||
int maxPacketsPerInterval = std::max(clientMaxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval());
|
||||
int clientMaxPacketsPerInterval = std::max(1,(nodeData->getMaxVoxelPacketsPerSecond() / INTERVALS_PER_SECOND));
|
||||
int maxPacketsPerInterval = std::min(clientMaxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval());
|
||||
|
||||
if (_myServer->wantsDebugVoxelSending()) {
|
||||
printf("packetsSentThisInterval=%d maxPacketsPerInterval=%d server PPI=%d nodePPS=%d nodePPI=%d\n",
|
||||
packetsSentThisInterval, maxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval(),
|
||||
printf("truePacketsSent=%d packetsSentThisInterval=%d maxPacketsPerInterval=%d server PPI=%d nodePPS=%d nodePPI=%d\n",
|
||||
truePacketsSent, packetsSentThisInterval, maxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval(),
|
||||
nodeData->getMaxVoxelPacketsPerSecond(), clientMaxPacketsPerInterval);
|
||||
}
|
||||
while (somethingToSend && packetsSentThisInterval < maxPacketsPerInterval - (shouldSendEnvironments ? 1 : 0)) {
|
||||
if (_myServer->wantsDebugVoxelSending()) {
|
||||
printf("truePacketsSent=%d packetsSentThisInterval=%d maxPacketsPerInterval=%d server PPI=%d nodePPS=%d nodePPI=%d\n",
|
||||
truePacketsSent, packetsSentThisInterval, maxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval(),
|
||||
nodeData->getMaxVoxelPacketsPerSecond(), clientMaxPacketsPerInterval);
|
||||
}
|
||||
|
||||
|
||||
while (packetsSentThisInterval < maxPacketsPerInterval - (shouldSendEnvironments ? 1 : 0)) {
|
||||
// Check to see if we're taking too long, and if so bail early...
|
||||
uint64_t now = usecTimestampNow();
|
||||
long elapsedUsec = (now - start);
|
||||
|
@ -276,17 +292,18 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
|||
if (nodeData->getAvailable() >= bytesWritten) {
|
||||
nodeData->writeToPacket(_tempOutputBuffer, bytesWritten);
|
||||
} else {
|
||||
handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
|
||||
packetsSentThisInterval++;
|
||||
packetsSentThisInterval += handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
|
||||
nodeData->writeToPacket(_tempOutputBuffer, bytesWritten);
|
||||
}
|
||||
} else {
|
||||
if (nodeData->isPacketWaiting()) {
|
||||
handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
|
||||
packetsSentThisInterval += handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
|
||||
}
|
||||
packetsSentThisInterval = _myServer->getPacketsPerClientPerInterval(); // done for now, no nodes left
|
||||
//packetsSentThisInterval = _myServer->getPacketsPerClientPerInterval(); // done for now, no nodes left
|
||||
somethingToSend = false;
|
||||
}
|
||||
}
|
||||
|
||||
// send the environment packet
|
||||
if (shouldSendEnvironments) {
|
||||
int numBytesPacketHeader = populateTypeAndVersion(_tempOutputBuffer, PACKET_TYPE_ENVIRONMENT_DATA);
|
||||
|
@ -300,6 +317,7 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
|||
NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(), _tempOutputBuffer, envPacketLength);
|
||||
trueBytesSent += envPacketLength;
|
||||
truePacketsSent++;
|
||||
packetsSentThisInterval++;
|
||||
}
|
||||
|
||||
uint64_t end = usecTimestampNow();
|
||||
|
@ -328,9 +346,17 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
|||
}
|
||||
nodeData->map.erase(); // It would be nice if we could save this, and only reset it when the view frustum changes
|
||||
}
|
||||
|
||||
if (_myServer->wantsDebugVoxelSending()) {
|
||||
printf("truePacketsSent=%d packetsSentThisInterval=%d maxPacketsPerInterval=%d server PPI=%d nodePPS=%d nodePPI=%d\n",
|
||||
truePacketsSent, packetsSentThisInterval, maxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval(),
|
||||
nodeData->getMaxVoxelPacketsPerSecond(), clientMaxPacketsPerInterval);
|
||||
}
|
||||
|
||||
} // end if bag wasn't empty, and so we sent stuff...
|
||||
|
||||
_myServer->unlockTree();
|
||||
|
||||
return truePacketsSent;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,8 +30,8 @@ private:
|
|||
QUuid _nodeUUID;
|
||||
VoxelServer* _myServer;
|
||||
|
||||
void handlePacketSend(Node* node, VoxelNodeData* nodeData, int& trueBytesSent, int& truePacketsSent);
|
||||
void deepestLevelVoxelDistributor(Node* node, VoxelNodeData* nodeData, bool viewFrustumChanged);
|
||||
int handlePacketSend(Node* node, VoxelNodeData* nodeData, int& trueBytesSent, int& truePacketsSent);
|
||||
int deepestLevelVoxelDistributor(Node* node, VoxelNodeData* nodeData, bool viewFrustumChanged);
|
||||
|
||||
unsigned char _tempOutputBuffer[MAX_VOXEL_PACKET_SIZE];
|
||||
};
|
||||
|
|
|
@ -18,11 +18,9 @@
|
|||
|
||||
|
||||
const int MAX_FILENAME_LENGTH = 1024;
|
||||
const int VOXEL_SIZE_BYTES = 3 + (3 * sizeof(float));
|
||||
const int VOXELS_PER_PACKET = (MAX_PACKET_SIZE - 1) / VOXEL_SIZE_BYTES;
|
||||
const int VOXEL_SEND_INTERVAL_USECS = 17 * 1000; // approximately 60fps
|
||||
const int INTERVALS_PER_SECOND = 60;
|
||||
const int VOXEL_SEND_INTERVAL_USECS = (1000 * 1000)/INTERVALS_PER_SECOND;
|
||||
const int SENDING_TIME_TO_SPARE = 5 * 1000; // usec of sending interval to spare for calculating voxels
|
||||
const int INTERVALS_PER_SECOND = 1000 * 1000 / VOXEL_SEND_INTERVAL_USECS;
|
||||
const int ENVIRONMENT_SEND_INTERVAL_USECS = 1000000;
|
||||
|
||||
extern const char* LOCAL_VOXELS_PERSIST_FILE;
|
||||
|
|
Loading…
Reference in a new issue