mirror of
https://github.com/overte-org/overte.git
synced 2025-04-23 23:33:26 +02:00
fix issue where we sometimes don't completely fill a packet mid scene
This commit is contained in:
parent
0cd269632e
commit
ed80895eb3
4 changed files with 61 additions and 9 deletions
|
@ -350,6 +350,7 @@ int VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* nod
|
|||
break;
|
||||
}
|
||||
|
||||
bool lastNodeDidntFit = false; // assume each node fits
|
||||
if (!nodeData->nodeBag.isEmpty()) {
|
||||
VoxelNode* subTree = nodeData->nodeBag.extract();
|
||||
bool wantOcclusionCulling = nodeData->getWantOcclusionCulling();
|
||||
|
@ -375,11 +376,9 @@ int VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* nod
|
|||
_myServer->getServerTree().lockForRead();
|
||||
nodeData->stats.encodeStarted();
|
||||
bytesWritten = _myServer->getServerTree().encodeTreeBitstream(subTree, &_tempPacket, nodeData->nodeBag, params);
|
||||
|
||||
if (_tempPacket.hasContent() && bytesWritten == 0 && _tempPacket.getFinalizedSize() < 1450) {
|
||||
printf(">>>>>>>>>>>>>>> got bytesWritten==0 _tempPacket.getFinalizedSize()=%d <<<<<<<<<<<<<<<\n",
|
||||
_tempPacket.getFinalizedSize());
|
||||
|
||||
|
||||
if (_tempPacket.hasContent() && bytesWritten == 0 && params.stopReason == EncodeBitstreamParams::DIDNT_FIT) {
|
||||
lastNodeDidntFit = true;
|
||||
}
|
||||
|
||||
if (bytesWritten > 0) {
|
||||
|
@ -396,7 +395,7 @@ int VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* nod
|
|||
// We only consider sending anything if there is something in the _tempPacket to send... But
|
||||
// if bytesWritten == 0 it means either the subTree couldn't fit or we had an empty bag... Both cases
|
||||
// mean we should send the previous packet contents and reset it.
|
||||
bool sendNow = (bytesWritten == 0);
|
||||
bool sendNow = lastNodeDidntFit;
|
||||
if (_tempPacket.hasContent() && sendNow) {
|
||||
if (_myServer->wantsDebugVoxelSending() && _myServer->wantsVerboseDebug()) {
|
||||
printf("calling writeToPacket() compressedSize=%d uncompressedSize=%d\n",
|
||||
|
|
|
@ -11,7 +11,12 @@
|
|||
// * determine why we sometimes don't fill packets very well (rarely) mid-scene... sometimes it appears as if
|
||||
// the "next node" would encode with more bytes than can fit in the remainder of the packet. this might be
|
||||
// several tens or hundreds of bytes, but theoretically other voxels would have fit. This happens in the 0100
|
||||
// scene a couple times.
|
||||
// scene a couple times.
|
||||
// this is happening because of nodes that are not recursed for good reason like:
|
||||
// - being occluded
|
||||
// - being previously in view
|
||||
// - being out of view, etc.
|
||||
// in these cases, the node is not re-added to the bag... so, we can probably just keep going...
|
||||
//
|
||||
// * further testing of compression to determine optimal configuration for performance and compression
|
||||
// * improve semantics for "reshuffle" - current approach will work for now and with compression
|
||||
|
|
|
@ -1031,6 +1031,7 @@ int VoxelTree::encodeTreeBitstream(VoxelNode* node,
|
|||
// you can't call this without a valid node
|
||||
if (!node) {
|
||||
qDebug("WARNING! encodeTreeBitstream() called with node=NULL\n");
|
||||
params.stopReason = EncodeBitstreamParams::NULL_NODE;
|
||||
return bytesWritten;
|
||||
}
|
||||
|
||||
|
@ -1039,6 +1040,7 @@ int VoxelTree::encodeTreeBitstream(VoxelNode* node,
|
|||
// If we're at a node that is out of view, then we can return, because no nodes below us will be in view!
|
||||
if (params.viewFrustum && !node->isInView(*params.viewFrustum)) {
|
||||
doneEncoding(node);
|
||||
params.stopReason = EncodeBitstreamParams::OUT_OF_VIEW;
|
||||
return bytesWritten;
|
||||
}
|
||||
|
||||
|
@ -1063,6 +1065,7 @@ int VoxelTree::encodeTreeBitstream(VoxelNode* node,
|
|||
if (!roomForOctalCode) {
|
||||
doneEncoding(node);
|
||||
bag.insert(node); // add the node back to the bag so it will eventually get included
|
||||
params.stopReason = EncodeBitstreamParams::DIDNT_FIT;
|
||||
return bytesWritten;
|
||||
}
|
||||
|
||||
|
@ -1085,6 +1088,7 @@ int VoxelTree::encodeTreeBitstream(VoxelNode* node,
|
|||
// couldn't be written... so reset them here... This isn't true for the non-color included case
|
||||
if (params.includeColor && childBytesWritten == 2) {
|
||||
childBytesWritten = 0;
|
||||
//params.stopReason = EncodeBitstreamParams::UNKNOWN; // possibly should be DIDNT_FIT...
|
||||
}
|
||||
|
||||
// if we wrote child bytes, then return our result of all bytes written
|
||||
|
@ -1093,6 +1097,7 @@ int VoxelTree::encodeTreeBitstream(VoxelNode* node,
|
|||
} else {
|
||||
// otherwise... if we didn't write any child bytes, then pretend like we also didn't write our octal code
|
||||
bytesWritten = 0;
|
||||
//params.stopReason = EncodeBitstreamParams::DIDNT_FIT;
|
||||
}
|
||||
|
||||
if (bytesWritten == 0) {
|
||||
|
@ -1115,6 +1120,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node,
|
|||
// you can't call this without a valid node
|
||||
if (!node) {
|
||||
qDebug("WARNING! encodeTreeBitstreamRecursion() called with node=NULL\n");
|
||||
params.stopReason = EncodeBitstreamParams::NULL_NODE;
|
||||
return bytesAtThisLevel;
|
||||
}
|
||||
|
||||
|
@ -1125,6 +1131,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node,
|
|||
|
||||
// If we've reached our max Search Level, then stop searching.
|
||||
if (currentEncodeLevel >= params.maxEncodeLevel) {
|
||||
params.stopReason = EncodeBitstreamParams::TOO_DEEP;
|
||||
return bytesAtThisLevel;
|
||||
}
|
||||
|
||||
|
@ -1133,6 +1140,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node,
|
|||
// here's how it works... if we're currently above our root jurisdiction, then we proceed normally.
|
||||
// but once we're in our own jurisdiction, then we need to make sure we're not below it.
|
||||
if (JurisdictionMap::BELOW == params.jurisdictionMap->isMyJurisdiction(node->getOctalCode(), CHECK_NODE_ONLY)) {
|
||||
params.stopReason = EncodeBitstreamParams::OUT_OF_JURISDICTION;
|
||||
return bytesAtThisLevel;
|
||||
}
|
||||
}
|
||||
|
@ -1148,6 +1156,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node,
|
|||
if (params.stats) {
|
||||
params.stats->skippedDistance(node);
|
||||
}
|
||||
params.stopReason = EncodeBitstreamParams::LOD_SKIP;
|
||||
return bytesAtThisLevel;
|
||||
}
|
||||
|
||||
|
@ -1158,6 +1167,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node,
|
|||
if (params.stats) {
|
||||
params.stats->skippedOutOfView(node);
|
||||
}
|
||||
params.stopReason = EncodeBitstreamParams::OUT_OF_VIEW;
|
||||
return bytesAtThisLevel;
|
||||
}
|
||||
|
||||
|
@ -1197,6 +1207,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node,
|
|||
if (params.stats) {
|
||||
params.stats->skippedWasInView(node);
|
||||
}
|
||||
params.stopReason = EncodeBitstreamParams::WAS_IN_VIEW;
|
||||
return bytesAtThisLevel;
|
||||
}
|
||||
|
||||
|
@ -1207,6 +1218,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node,
|
|||
if (params.stats) {
|
||||
params.stats->skippedNoChange(node);
|
||||
}
|
||||
params.stopReason = EncodeBitstreamParams::NO_CHANGE;
|
||||
return bytesAtThisLevel;
|
||||
}
|
||||
|
||||
|
@ -1226,6 +1238,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node,
|
|||
if (params.stats) {
|
||||
params.stats->skippedOccluded(node);
|
||||
}
|
||||
params.stopReason = EncodeBitstreamParams::OCCLUDED;
|
||||
return bytesAtThisLevel;
|
||||
}
|
||||
} else {
|
||||
|
@ -1616,7 +1629,8 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node,
|
|||
params.stats->didntFit(node);
|
||||
}
|
||||
|
||||
return 0;
|
||||
params.stopReason = EncodeBitstreamParams::DIDNT_FIT;
|
||||
bytesAtThisLevel = 0; // didn't fit
|
||||
}
|
||||
|
||||
return bytesAtThisLevel;
|
||||
|
|
|
@ -66,6 +66,21 @@ public:
|
|||
CoverageMap* map;
|
||||
JurisdictionMap* jurisdictionMap;
|
||||
|
||||
// output hints from the encode process
|
||||
typedef enum {
|
||||
UNKNOWN,
|
||||
DIDNT_FIT,
|
||||
NULL_NODE,
|
||||
TOO_DEEP,
|
||||
OUT_OF_JURISDICTION,
|
||||
LOD_SKIP,
|
||||
OUT_OF_VIEW,
|
||||
WAS_IN_VIEW,
|
||||
NO_CHANGE,
|
||||
OCCLUDED
|
||||
} reason;
|
||||
reason stopReason;
|
||||
|
||||
EncodeBitstreamParams(
|
||||
int maxEncodeLevel = INT_MAX,
|
||||
const ViewFrustum* viewFrustum = IGNORE_VIEW_FRUSTUM,
|
||||
|
@ -97,8 +112,27 @@ public:
|
|||
forceSendScene(forceSendScene),
|
||||
stats(stats),
|
||||
map(map),
|
||||
jurisdictionMap(jurisdictionMap)
|
||||
jurisdictionMap(jurisdictionMap),
|
||||
stopReason(UNKNOWN)
|
||||
{}
|
||||
|
||||
void displayStopReason() {
|
||||
printf("StopReason: ");
|
||||
switch (stopReason) {
|
||||
default:
|
||||
case UNKNOWN: printf("UNKNOWN\n"); break;
|
||||
|
||||
case DIDNT_FIT: printf("DIDNT_FIT\n"); break;
|
||||
case NULL_NODE: printf("NULL_NODE\n"); break;
|
||||
case TOO_DEEP: printf("TOO_DEEP\n"); break;
|
||||
case OUT_OF_JURISDICTION: printf("OUT_OF_JURISDICTION\n"); break;
|
||||
case LOD_SKIP: printf("LOD_SKIP\n"); break;
|
||||
case OUT_OF_VIEW: printf("OUT_OF_VIEW\n"); break;
|
||||
case WAS_IN_VIEW: printf("WAS_IN_VIEW\n"); break;
|
||||
case NO_CHANGE: printf("NO_CHANGE\n"); break;
|
||||
case OCCLUDED: printf("OCCLUDED\n"); break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class ReadBitstreamToTreeParams {
|
||||
|
|
Loading…
Reference in a new issue