more voxel scene stats

This commit is contained in:
ZappoMan 2013-07-18 14:13:45 -07:00
parent 65f550e68e
commit 3aa6af21b1
5 changed files with 312 additions and 77 deletions

View file

@ -8,70 +8,179 @@
#include <SharedUtil.h> #include <SharedUtil.h>
#include "VoxelNode.h"
#include "VoxelSceneStats.h" #include "VoxelSceneStats.h"
VoxelSceneStats::VoxelSceneStats() : VoxelSceneStats::VoxelSceneStats() {
start(0), reset();
end(0),
elapsed(0),
total(0),
traversed(0),
internal(0),
internalOutOfView(0),
internalOccluded(0),
internalDirty(0),
leaves(0),
leavesOutOfView(0),
leavesOccluded(0),
leavesDirty(0),
packets(0),
bytes(0),
passes(0),
wasFinished(false),
wasMoving(false),
hadDeltaView(false),
hadOcclusionCulling(false)
{
} }
VoxelSceneStats::~VoxelSceneStats() { VoxelSceneStats::~VoxelSceneStats() {
} }
void VoxelSceneStats::sceneStarted() { void VoxelSceneStats::sceneStarted(bool fullScene, bool moving) {
start = usecTimestampNow(); _start = usecTimestampNow();
reset(); // resets packet and voxel stats
_fullSceneDraw = fullScene;
_moving = moving;
} }
void VoxelSceneStats::sceneCompleted() { void VoxelSceneStats::sceneCompleted() {
end = usecTimestampNow(); _end = usecTimestampNow();
elapsed = end - start; _elapsed = _end - _start;
} }
void VoxelSceneStats::reset() { void VoxelSceneStats::reset() {
start = 0; _packets = 0;
end= 0; _bytes = 0;
elapsed= 0; _passes = 0;
_traversed = 0;
_internal = 0;
_leaves = 0;
_skippedDistance = 0;
_internalSkippedDistance = 0;
_leavesSkippedDistance = 0;
_skippedOutOfView = 0;
_internalSkippedOutOfView = 0;
_leavesSkippedOutOfView = 0;
_skippedWasInView = 0;
_internalSkippedWasInView = 0;
_leavesSkippedWasInView = 0;
_skippedNoChange = 0;
_internalSkippedNoChange = 0;
_leavesSkippedNoChange = 0;
_skippedOccluded = 0;
_internalSkippedOccluded = 0;
_leavesSkippedOccluded = 0;
_colorSent = 0;
_internalColorSent = 0;
_leavesColorSent = 0;
_didntFit = 0;
_internalDidntFit = 0;
_leavesDidntFit = 0;
total = 0;
traversed = 0;
internal = 0;
internalOutOfView = 0;
internalOccluded = 0;
internalDirty = 0;
leaves = 0;
leavesOutOfView = 0;
leavesOccluded = 0;
leavesDirty = 0;
packets = 0;
bytes = 0;
passes = 0;
wasFinished = false;
wasMoving = false;
hadDeltaView = false;
hadOcclusionCulling = false;
} }
void VoxelSceneStats::packetSent(int bytes) {
_packets++;
_bytes += bytes;
}
void VoxelSceneStats::traversed(const VoxelNode* node) {
_traversed++;
if (node->isLeaf()) {
_leaves++;
} else {
_internal++;
}
}
void VoxelSceneStats::skippedDistance(const VoxelNode* node) {
_skippedDistance++;
if (node->isLeaf()) {
_leavesSkippedDistance++;
} else {
_internalSkippedDistance++;
}
}
void VoxelSceneStats::skippedOutOfView(const VoxelNode* node) {
_skippedOutOfView++;
if (node->isLeaf()) {
_leavesSkippedOutOfView++;
} else {
_internalSkippedOutOfView++;
}
}
void VoxelSceneStats::skippedWasInView(const VoxelNode* node) {
_skippedWasInView++;
if (node->isLeaf()) {
_leavesSkippedWasInView++;
} else {
_internalSkippedWasInView++;
}
}
void VoxelSceneStats::skippedNoChange(const VoxelNode* node) {
_skippedNoChange++;
if (node->isLeaf()) {
_leavesSkippedNoChange++;
} else {
_internalSkippedNoChange++;
}
}
void VoxelSceneStats::skippedOccluded(const VoxelNode* node) {
_skippedOccluded++;
if (node->isLeaf()) {
_leavesSkippedOccluded++;
} else {
_internalSkippedOccluded++;
}
}
void VoxelSceneStats::colorSent(const VoxelNode* node) {
_colorSent++;
if (node->isLeaf()) {
_leavesColorSent++;
} else {
_internalColorSent++;
}
}
void VoxelSceneStats::didntFit(const VoxelNode* node) {
_didntFit++;
if (node->isLeaf()) {
_leavesDidntFit++;
} else {
_internalDidntFit++;
}
}
void VoxelSceneStats::printDebugDetails() { void VoxelSceneStats::printDebugDetails() {
qDebug("VoxelSceneStats: start: %llu, end: %llu, elapsed: %llu \n", start, end, elapsed); qDebug("\n------------------------------\n");
qDebug("VoxelSceneStats:\n");
qDebug(" start : %llu \n", _start);
qDebug(" end : %llu \n", _end);
qDebug(" elapsed: %llu \n", _elapsed);
qDebug("\n");
qDebug(" full scene: %s\n", debug::valueOf(_fullSceneDraw));
qDebug(" moving: %s\n", debug::valueOf(_moving));
qDebug("\n");
qDebug(" packets: %d\n", _packets);
qDebug(" bytes : %d\n", _bytes);
qDebug("\n");
qDebug(" traversed : %lu\n", _traversed );
qDebug(" internal : %lu\n", _internal );
qDebug(" leaves : %lu\n", _leaves );
qDebug(" skipped distance : %lu\n", _skippedDistance );
qDebug(" internal : %lu\n", _internalSkippedDistance );
qDebug(" leaves : %lu\n", _leavesSkippedDistance );
qDebug(" skipped out of view : %lu\n", _skippedOutOfView );
qDebug(" internal : %lu\n", _internalSkippedOutOfView );
qDebug(" leaves : %lu\n", _leavesSkippedOutOfView );
qDebug(" skipped was in view : %lu\n", _skippedWasInView );
qDebug(" internal : %lu\n", _internalSkippedWasInView );
qDebug(" leaves : %lu\n", _leavesSkippedWasInView );
qDebug(" skipped no change : %lu\n", _skippedNoChange );
qDebug(" internal : %lu\n", _internalSkippedNoChange );
qDebug(" leaves : %lu\n", _leavesSkippedNoChange );
qDebug(" skipped occluded : %lu\n", _skippedOccluded );
qDebug(" internal : %lu\n", _internalSkippedOccluded );
qDebug(" leaves : %lu\n", _leavesSkippedOccluded );
qDebug(" color sent : %lu\n", _colorSent );
qDebug(" internal : %lu\n", _internalColorSent );
qDebug(" leaves : %lu\n", _leavesColorSent );
qDebug(" Didn't Fit : %lu\n", _didntFit );
qDebug(" internal : %lu\n", _internalDidntFit );
qDebug(" leaves : %lu\n", _leavesDidntFit );
} }

View file

@ -11,43 +11,85 @@
#include <stdint.h> #include <stdint.h>
class VoxelNode;
class VoxelSceneStats { class VoxelSceneStats {
public: public:
VoxelSceneStats(); VoxelSceneStats();
~VoxelSceneStats(); ~VoxelSceneStats();
void reset(); void reset();
void sceneStarted(); void sceneStarted(bool fullScene, bool moving);
void sceneCompleted(); void sceneCompleted();
void printDebugDetails(); void printDebugDetails();
void packetSent(int bytes);
void traversed(const VoxelNode* node);
void skippedDistance(const VoxelNode* node);
void skippedOutOfView(const VoxelNode* node);
void skippedWasInView(const VoxelNode* node);
void skippedNoChange(const VoxelNode* node);
void skippedOccluded(const VoxelNode* node);
void colorSent(const VoxelNode* node);
void didntFit(const VoxelNode* node);
void colorBitsWritten(const VoxelNode* node);
void existsBitsWritten(const VoxelNode* node);
void existsInPacketBitsWritten(const VoxelNode* node);
private:
// scene timing data in usecs // scene timing data in usecs
uint64_t start; uint64_t _start;
uint64_t end; uint64_t _end;
uint64_t elapsed; uint64_t _elapsed;
// scene voxel related data // scene voxel related data
unsigned long _traversed;
unsigned long _internal;
unsigned long _leaves;
unsigned long _skippedDistance;
unsigned long _internalSkippedDistance;
unsigned long _leavesSkippedDistance;
unsigned long _skippedOutOfView;
unsigned long _internalSkippedOutOfView;
unsigned long _leavesSkippedOutOfView;
unsigned long _skippedWasInView;
unsigned long _internalSkippedWasInView;
unsigned long _leavesSkippedWasInView;
unsigned long _skippedNoChange;
unsigned long _internalSkippedNoChange;
unsigned long _leavesSkippedNoChange;
unsigned long _skippedOccluded;
unsigned long _internalSkippedOccluded;
unsigned long _leavesSkippedOccluded;
unsigned long _colorSent;
unsigned long _internalColorSent;
unsigned long _leavesColorSent;
unsigned long _didntFit;
unsigned long _internalDidntFit;
unsigned long _leavesDidntFit;
unsigned long total; unsigned long total;
unsigned long traversed;
unsigned long internal;
unsigned long internalOutOfView; unsigned long internalOutOfView;
unsigned long internalOccluded; unsigned long internalOccluded;
unsigned long internalDirty; unsigned long internalDirty;
unsigned long leaves;
unsigned long leavesOutOfView; unsigned long leavesOutOfView;
unsigned long leavesOccluded; unsigned long leavesOccluded;
unsigned long leavesDirty; unsigned long leavesDirty;
// scene network related data // scene network related data
unsigned int packets; unsigned int _packets;
unsigned int bytes; unsigned int _bytes;
unsigned int passes; unsigned int _passes;
// features related items // features related items
bool wasFinished; bool _moving;
bool wasMoving; bool _fullSceneDraw;
bool hadDeltaView;
bool hadOcclusionCulling;
}; };
#endif /* defined(__hifi__VoxelSceneStats__) */ #endif /* defined(__hifi__VoxelSceneStats__) */

View file

@ -1037,6 +1037,13 @@ int VoxelTree::encodeTreeBitstream(VoxelNode* node, unsigned char* outputBuffer,
availableBytes -= codeLength; // keep track or remaining space availableBytes -= codeLength; // keep track or remaining space
int currentEncodeLevel = 0; int currentEncodeLevel = 0;
// record some stats, this is the one node that we won't record below in the recursion function, so we need to
// track it here
if (params.stats) {
params.stats->traversed(node);
}
int childBytesWritten = encodeTreeBitstreamRecursion(node, outputBuffer, availableBytes, bag, params, currentEncodeLevel); int childBytesWritten = encodeTreeBitstreamRecursion(node, outputBuffer, availableBytes, bag, params, currentEncodeLevel);
// if childBytesWritten == 1 then something went wrong... that's not possible // if childBytesWritten == 1 then something went wrong... that's not possible
@ -1081,6 +1088,9 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
// If we're too far away for our render level, then just return // If we're too far away for our render level, then just return
if (distance >= boundaryDistance) { if (distance >= boundaryDistance) {
if (params.stats) {
params.stats->skippedDistance(node);
}
return bytesAtThisLevel; return bytesAtThisLevel;
} }
@ -1088,6 +1098,9 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
// although technically, we really shouldn't ever be here, because our callers shouldn't be calling us if // although technically, we really shouldn't ever be here, because our callers shouldn't be calling us if
// we're out of view // we're out of view
if (!node->isInView(*params.viewFrustum)) { if (!node->isInView(*params.viewFrustum)) {
if (params.stats) {
params.stats->skippedOutOfView(node);
}
return bytesAtThisLevel; return bytesAtThisLevel;
} }
@ -1110,6 +1123,9 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
// if we're in deltaViewFrustum mode, and this node has changed since it was last sent, then we do // if we're in deltaViewFrustum mode, and this node has changed since it was last sent, then we do
// need to send it. // need to send it.
if (wasInView && !(params.deltaViewFrustum && node->hasChangedSince(params.lastViewFrustumSent - CHANGE_FUDGE))) { if (wasInView && !(params.deltaViewFrustum && node->hasChangedSince(params.lastViewFrustumSent - CHANGE_FUDGE))) {
if (params.stats) {
params.stats->skippedWasInView(node);
}
return bytesAtThisLevel; return bytesAtThisLevel;
} }
@ -1117,6 +1133,9 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
// then we can also bail early and save bits // then we can also bail early and save bits
if (!params.forceSendScene && !params.deltaViewFrustum && if (!params.forceSendScene && !params.deltaViewFrustum &&
!node->hasChangedSince(params.lastViewFrustumSent - CHANGE_FUDGE)) { !node->hasChangedSince(params.lastViewFrustumSent - CHANGE_FUDGE)) {
if (params.stats) {
params.stats->skippedNoChange(node);
}
return bytesAtThisLevel; return bytesAtThisLevel;
} }
@ -1136,6 +1155,9 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
CoverageMapStorageResult result = params.map->checkMap(voxelPolygon, false); CoverageMapStorageResult result = params.map->checkMap(voxelPolygon, false);
delete voxelPolygon; // cleanup delete voxelPolygon; // cleanup
if (result == OCCLUDED) { if (result == OCCLUDED) {
if (params.stats) {
params.stats->skippedOccluded(node);
}
return bytesAtThisLevel; return bytesAtThisLevel;
} }
} else { } else {
@ -1201,6 +1223,12 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
distancesToChildren[i] = 0.0f; distancesToChildren[i] = 0.0f;
currentCount++; currentCount++;
} }
// track stats
if (params.stats && childNode) {
params.stats->traversed(childNode);
}
} }
// for each child node in Distance sorted order..., check to see if they exist, are colored, and in view, and if so // for each child node in Distance sorted order..., check to see if they exist, are colored, and in view, and if so
@ -1211,13 +1239,21 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
bool childIsInView = (childNode && (!params.viewFrustum || childNode->isInView(*params.viewFrustum))); bool childIsInView = (childNode && (!params.viewFrustum || childNode->isInView(*params.viewFrustum)));
if (childIsInView) { if (!childIsInView) {
if (params.stats) {
params.stats->skippedOutOfView(childNode);
}
} else {
// Before we determine consider this further, let's see if it's in our LOD scope... // Before we determine consider this further, let's see if it's in our LOD scope...
float distance = distancesToChildren[i]; // params.viewFrustum ? childNode->distanceToCamera(*params.viewFrustum) : 0; float distance = distancesToChildren[i]; // params.viewFrustum ? childNode->distanceToCamera(*params.viewFrustum) : 0;
float boundaryDistance = !params.viewFrustum ? 1 : float boundaryDistance = !params.viewFrustum ? 1 :
boundaryDistanceForRenderLevel(childNode->getLevel() + params.boundaryLevelAdjust); boundaryDistanceForRenderLevel(childNode->getLevel() + params.boundaryLevelAdjust);
if (distance < boundaryDistance) { if (!(distance < boundaryDistance)) {
if (params.stats) {
params.stats->skippedDistance(childNode);
}
} else {
inViewCount++; inViewCount++;
// track children in view as existing and not a leaf, if they're a leaf, // track children in view as existing and not a leaf, if they're a leaf,
@ -1261,7 +1297,18 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
} // wants occlusion culling & isLeaf() } // wants occlusion culling & isLeaf()
bool shouldRender = !params.viewFrustum ? true : childNode->calculateShouldRender(params.viewFrustum, params.boundaryLevelAdjust); bool shouldRender = !params.viewFrustum ? true :
childNode->calculateShouldRender(params.viewFrustum, params.boundaryLevelAdjust);
// track some stats
if (params.stats) {
if (!shouldRender) {
params.stats->skippedDistance(childNode);
}
if (childIsOccluded) {
params.stats->skippedOccluded(childNode);
}
}
// track children with actual color, only if the child wasn't previously in view! // track children with actual color, only if the child wasn't previously in view!
if (shouldRender && !childIsOccluded) { if (shouldRender && !childIsOccluded) {
@ -1288,7 +1335,14 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
inViewWithColorCount++; inViewWithColorCount++;
} else { } else {
// otherwise just track stats of the items we discarded // otherwise just track stats of the items we discarded
params.childWasInViewDiscarded++; if (params.stats) {
if (childWasInView) {
params.stats->skippedWasInView(childNode);
} else {
params.stats->skippedNoChange(childNode);
}
}
} }
} }
} }
@ -1297,14 +1351,23 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
*writeToThisLevelBuffer = childrenColoredBits; *writeToThisLevelBuffer = childrenColoredBits;
writeToThisLevelBuffer += sizeof(childrenColoredBits); // move the pointer writeToThisLevelBuffer += sizeof(childrenColoredBits); // move the pointer
bytesAtThisLevel += sizeof(childrenColoredBits); // keep track of byte count bytesAtThisLevel += sizeof(childrenColoredBits); // keep track of byte count
if (params.stats) {
params.stats->colorBitsWritten(node);
}
// write the color data... // write the color data...
if (params.includeColor) { if (params.includeColor) {
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
if (oneAtBit(childrenColoredBits, i)) { if (oneAtBit(childrenColoredBits, i)) {
memcpy(writeToThisLevelBuffer, &node->getChildAtIndex(i)->getColor(), BYTES_PER_COLOR); VoxelNode* childNode = node->getChildAtIndex(i);
memcpy(writeToThisLevelBuffer, &childNode->getColor(), BYTES_PER_COLOR);
writeToThisLevelBuffer += BYTES_PER_COLOR; // move the pointer for color writeToThisLevelBuffer += BYTES_PER_COLOR; // move the pointer for color
bytesAtThisLevel += BYTES_PER_COLOR; // keep track of byte count for color bytesAtThisLevel += BYTES_PER_COLOR; // keep track of byte count for color
if (params.stats) {
params.stats->colorSent(childNode);
}
} }
} }
} }
@ -1315,12 +1378,18 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
*writeToThisLevelBuffer = childrenExistInTreeBits; *writeToThisLevelBuffer = childrenExistInTreeBits;
writeToThisLevelBuffer += sizeof(childrenExistInTreeBits); // move the pointer writeToThisLevelBuffer += sizeof(childrenExistInTreeBits); // move the pointer
bytesAtThisLevel += sizeof(childrenExistInTreeBits); // keep track of byte count bytesAtThisLevel += sizeof(childrenExistInTreeBits); // keep track of byte count
if (params.stats) {
params.stats->existsBitsWritten(node);
}
} }
// write the child exist bits // write the child exist bits
*writeToThisLevelBuffer = childrenExistInPacketBits; *writeToThisLevelBuffer = childrenExistInPacketBits;
writeToThisLevelBuffer += sizeof(childrenExistInPacketBits); // move the pointer writeToThisLevelBuffer += sizeof(childrenExistInPacketBits); // move the pointer
bytesAtThisLevel += sizeof(childrenExistInPacketBits); // keep track of byte count bytesAtThisLevel += sizeof(childrenExistInPacketBits); // keep track of byte count
if (params.stats) {
params.stats->existsInPacketBitsWritten(node);
}
// We only need to keep digging, if there is at least one child that is inView, and not a leaf. // We only need to keep digging, if there is at least one child that is inView, and not a leaf.
keepDiggingDeeper = (inViewNotLeafCount > 0); keepDiggingDeeper = (inViewNotLeafCount > 0);
@ -1333,6 +1402,11 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
availableBytes -= bytesAtThisLevel; availableBytes -= bytesAtThisLevel;
} else { } else {
bag.insert(node); bag.insert(node);
if (params.stats) {
params.stats->didntFit(node);
}
return 0; return 0;
} }

View file

@ -9,12 +9,14 @@
#ifndef __hifi__VoxelTree__ #ifndef __hifi__VoxelTree__
#define __hifi__VoxelTree__ #define __hifi__VoxelTree__
#include "SimpleMovingAverage.h" #include <PointerStack.h>
#include <SimpleMovingAverage.h>
#include "CoverageMap.h"
#include "ViewFrustum.h" #include "ViewFrustum.h"
#include "VoxelNode.h" #include "VoxelNode.h"
#include "VoxelNodeBag.h" #include "VoxelNodeBag.h"
#include "CoverageMap.h" #include "VoxelSceneStats.h"
#include "PointerStack.h"
// Callback function, for recuseTreeWithOperation // Callback function, for recuseTreeWithOperation
typedef bool (*RecurseVoxelTreeOperation)(VoxelNode* node, void* extraData); typedef bool (*RecurseVoxelTreeOperation)(VoxelNode* node, void* extraData);
@ -36,6 +38,7 @@ typedef enum {GRADIENT, RANDOM, NATURAL} creationMode;
#define NO_BOUNDARY_ADJUST 0 #define NO_BOUNDARY_ADJUST 0
#define LOW_RES_MOVING_ADJUST 1 #define LOW_RES_MOVING_ADJUST 1
#define IGNORE_LAST_SENT 0 #define IGNORE_LAST_SENT 0
#define IGNORE_SCENE_STATS NULL
class EncodeBitstreamParams { class EncodeBitstreamParams {
public: public:
@ -48,10 +51,10 @@ public:
bool deltaViewFrustum; bool deltaViewFrustum;
const ViewFrustum* lastViewFrustum; const ViewFrustum* lastViewFrustum;
bool wantOcclusionCulling; bool wantOcclusionCulling;
long childWasInViewDiscarded;
int boundaryLevelAdjust; int boundaryLevelAdjust;
uint64_t lastViewFrustumSent; uint64_t lastViewFrustumSent;
bool forceSendScene; bool forceSendScene;
VoxelSceneStats* stats;
CoverageMap* map; CoverageMap* map;
EncodeBitstreamParams( EncodeBitstreamParams(
@ -66,7 +69,8 @@ public:
CoverageMap* map = IGNORE_COVERAGE_MAP, CoverageMap* map = IGNORE_COVERAGE_MAP,
int boundaryLevelAdjust = NO_BOUNDARY_ADJUST, int boundaryLevelAdjust = NO_BOUNDARY_ADJUST,
uint64_t lastViewFrustumSent = IGNORE_LAST_SENT, uint64_t lastViewFrustumSent = IGNORE_LAST_SENT,
bool forceSendScene = true) : bool forceSendScene = true,
VoxelSceneStats* stats = IGNORE_SCENE_STATS) :
maxEncodeLevel (maxEncodeLevel), maxEncodeLevel (maxEncodeLevel),
maxLevelReached (0), maxLevelReached (0),
viewFrustum (viewFrustum), viewFrustum (viewFrustum),
@ -76,10 +80,10 @@ public:
deltaViewFrustum (deltaViewFrustum), deltaViewFrustum (deltaViewFrustum),
lastViewFrustum (lastViewFrustum), lastViewFrustum (lastViewFrustum),
wantOcclusionCulling (wantOcclusionCulling), wantOcclusionCulling (wantOcclusionCulling),
childWasInViewDiscarded (0),
boundaryLevelAdjust (boundaryLevelAdjust), boundaryLevelAdjust (boundaryLevelAdjust),
lastViewFrustumSent (lastViewFrustumSent), lastViewFrustumSent (lastViewFrustumSent),
forceSendScene (forceSendScene), forceSendScene (forceSendScene),
stats (stats),
map (map) map (map)
{} {}
}; };

View file

@ -200,9 +200,6 @@ void deepestLevelVoxelDistributor(NodeList* nodeList,
// only set our last sent time if we weren't resetting due to frustum change // only set our last sent time if we weren't resetting due to frustum change
uint64_t now = usecTimestampNow(); uint64_t now = usecTimestampNow();
nodeData->setLastTimeBagEmpty(now); nodeData->setLastTimeBagEmpty(now);
if (::debugVoxelSending) {
printf("ENTIRE SCENE SENT! nodeData->setLastTimeBagEmpty(now=[%lld])\n", now);
}
} }
nodeData->stats.sceneCompleted(); nodeData->stats.sceneCompleted();
@ -210,7 +207,10 @@ void deepestLevelVoxelDistributor(NodeList* nodeList,
// This is the start of "resending" the scene. // This is the start of "resending" the scene.
nodeData->nodeBag.insert(serverTree.rootNode); nodeData->nodeBag.insert(serverTree.rootNode);
nodeData->stats.sceneStarted();
// start tracking our stats
bool fullScene = (!viewFrustumChanged || !nodeData->getWantDelta()) && nodeData->getViewFrustumJustStoppedChanging();
nodeData->stats.sceneStarted(fullScene, viewFrustumChanged);
} }
// If we have something in our nodeBag, then turn them into packets and send them out... // If we have something in our nodeBag, then turn them into packets and send them out...
@ -243,12 +243,15 @@ void deepestLevelVoxelDistributor(NodeList* nodeList,
CoverageMap* coverageMap = wantOcclusionCulling ? &nodeData->map : IGNORE_COVERAGE_MAP; CoverageMap* coverageMap = wantOcclusionCulling ? &nodeData->map : IGNORE_COVERAGE_MAP;
int boundaryLevelAdjust = viewFrustumChanged && nodeData->getWantLowResMoving() int boundaryLevelAdjust = viewFrustumChanged && nodeData->getWantLowResMoving()
? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST; ? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST;
bool fullScene = (!viewFrustumChanged || !nodeData->getWantDelta()) &&
nodeData->getViewFrustumJustStoppedChanging();
EncodeBitstreamParams params(INT_MAX, &nodeData->getCurrentViewFrustum(), wantColor, EncodeBitstreamParams params(INT_MAX, &nodeData->getCurrentViewFrustum(), wantColor,
WANT_EXISTS_BITS, DONT_CHOP, wantDelta, lastViewFrustum, WANT_EXISTS_BITS, DONT_CHOP, wantDelta, lastViewFrustum,
wantOcclusionCulling, coverageMap, boundaryLevelAdjust, wantOcclusionCulling, coverageMap, boundaryLevelAdjust,
nodeData->getLastTimeBagEmpty(), nodeData->getLastTimeBagEmpty(),
nodeData->getViewFrustumJustStoppedChanging()); fullScene, &nodeData->stats);
bytesWritten = serverTree.encodeTreeBitstream(subTree, &tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, bytesWritten = serverTree.encodeTreeBitstream(subTree, &tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1,
nodeData->nodeBag, params); nodeData->nodeBag, params);
@ -258,6 +261,8 @@ void deepestLevelVoxelDistributor(NodeList* nodeList,
} else { } else {
nodeList->getNodeSocket()->send(node->getActiveSocket(), nodeList->getNodeSocket()->send(node->getActiveSocket(),
nodeData->getPacket(), nodeData->getPacketLength()); nodeData->getPacket(), nodeData->getPacketLength());
nodeData->stats.packetSent(nodeData->getPacketLength());
trueBytesSent += nodeData->getPacketLength(); trueBytesSent += nodeData->getPacketLength();
truePacketsSent++; truePacketsSent++;
packetsSentThisInterval++; packetsSentThisInterval++;
@ -268,6 +273,7 @@ void deepestLevelVoxelDistributor(NodeList* nodeList,
if (nodeData->isPacketWaiting()) { if (nodeData->isPacketWaiting()) {
nodeList->getNodeSocket()->send(node->getActiveSocket(), nodeList->getNodeSocket()->send(node->getActiveSocket(),
nodeData->getPacket(), nodeData->getPacketLength()); nodeData->getPacket(), nodeData->getPacketLength());
nodeData->stats.packetSent(nodeData->getPacketLength());
trueBytesSent += nodeData->getPacketLength(); trueBytesSent += nodeData->getPacketLength();
truePacketsSent++; truePacketsSent++;
nodeData->resetVoxelPacket(); nodeData->resetVoxelPacket();