Conflicts:
	interface/src/Application.cpp
	interface/src/Application.h
This commit is contained in:
Andrzej Kapolka 2013-05-14 13:51:27 -07:00
commit 4eced82cf4
13 changed files with 172 additions and 46 deletions

View file

@ -1038,6 +1038,11 @@ void Application::setWantsResIn(bool wantsResIn) {
_myAvatar.setWantResIn(wantsResIn); _myAvatar.setWantResIn(wantsResIn);
} }
void Application::setWantsDelta(bool wantsDelta) {
_myAvatar.setWantDelta(wantsDelta);
}
static QIcon createSwatchIcon(const QColor& color) { static QIcon createSwatchIcon(const QColor& color) {
QPixmap map(16, 16); QPixmap map(16, 16);
map.fill(color); map.fill(color);
@ -1051,7 +1056,7 @@ void Application::chooseVoxelPaintColor() {
_voxelPaintColor->setIcon(createSwatchIcon(selected)); _voxelPaintColor->setIcon(createSwatchIcon(selected));
} }
} }
void Application::initMenu() { void Application::initMenu() {
QMenuBar* menuBar = new QMenuBar(); QMenuBar* menuBar = new QMenuBar();
_window->setMenuBar(menuBar); _window->setMenuBar(menuBar);
@ -1114,10 +1119,12 @@ void Application::initMenu() {
debugMenu->addAction("Calculate Tree Stats", this, SLOT(doTreeStats()), Qt::SHIFT | Qt::Key_S); debugMenu->addAction("Calculate Tree Stats", this, SLOT(doTreeStats()), Qt::SHIFT | Qt::Key_S);
debugMenu->addAction("Wants Res-In", this, SLOT(setWantsResIn(bool)))->setCheckable(true); debugMenu->addAction("Wants Res-In", this, SLOT(setWantsResIn(bool)))->setCheckable(true);
debugMenu->addAction("Wants Monochrome", this, SLOT(setWantsMonochrome(bool)))->setCheckable(true); debugMenu->addAction("Wants Monochrome", this, SLOT(setWantsMonochrome(bool)))->setCheckable(true);
debugMenu->addAction("Wants View Delta Sending", this, SLOT(setWantsDelta(bool)))->setCheckable(true);
} }
void Application::updateFrustumRenderModeAction() { void Application::updateFrustumRenderModeAction() {
switch (_frustumDrawingMode) { switch (_frustumDrawingMode) {
default:
case FRUSTUM_DRAW_MODE_ALL: case FRUSTUM_DRAW_MODE_ALL:
_frustumRenderModeAction->setText("Render Mode - All"); _frustumRenderModeAction->setText("Render Mode - All");
break; break;

View file

@ -87,6 +87,7 @@ private slots:
void doTreeStats(); void doTreeStats();
void setWantsMonochrome(bool wantsMonochrome); void setWantsMonochrome(bool wantsMonochrome);
void setWantsResIn(bool wantsResIn); void setWantsResIn(bool wantsResIn);
void setWantsDelta(bool wantsDelta);
void chooseVoxelPaintColor(); void chooseVoxelPaintColor();
private: private:

View file

@ -108,8 +108,12 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
destinationBuffer += _chatMessage.size() * sizeof(char); destinationBuffer += _chatMessage.size() * sizeof(char);
// voxel sending features... // voxel sending features...
*destinationBuffer++ = _wantResIn; // voxel sending features...
*destinationBuffer++ = _wantColor; unsigned char wantItems = 0;
if (_wantResIn) { setAtBit(wantItems,WANT_RESIN_AT_BIT); }
if (_wantColor) { setAtBit(wantItems,WANT_COLOR_AT_BIT); }
if (_wantDelta) { setAtBit(wantItems,WANT_DELTA_AT_BIT); }
*destinationBuffer++ = wantItems;
return destinationBuffer - bufferStart; return destinationBuffer - bufferStart;
} }
@ -117,6 +121,8 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
// called on the other agents - assigns it to my views of the others // called on the other agents - assigns it to my views of the others
int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
//printf("AvatarData::parseData()\n");
// increment to push past the packet header // increment to push past the packet header
sourceBuffer += sizeof(PACKET_HEADER_HEAD_DATA); sourceBuffer += sizeof(PACKET_HEADER_HEAD_DATA);
@ -184,8 +190,12 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
sourceBuffer += chatMessageSize * sizeof(char); sourceBuffer += chatMessageSize * sizeof(char);
// voxel sending features... // voxel sending features...
_wantResIn = (bool)*sourceBuffer++; unsigned char wantItems = 0;
_wantColor = (bool)*sourceBuffer++; wantItems = (unsigned char)*sourceBuffer++;
_wantResIn = oneAtBit(wantItems,WANT_RESIN_AT_BIT);
_wantColor = oneAtBit(wantItems,WANT_COLOR_AT_BIT);
_wantDelta = oneAtBit(wantItems,WANT_DELTA_AT_BIT);
return sourceBuffer - startPosition; return sourceBuffer - startPosition;
} }

View file

@ -15,6 +15,10 @@
#include <AgentData.h> #include <AgentData.h>
const int WANT_RESIN_AT_BIT = 0;
const int WANT_COLOR_AT_BIT = 1;
const int WANT_DELTA_AT_BIT = 2;
enum KeyState enum KeyState
{ {
NO_KEY_DOWN, NO_KEY_DOWN,
@ -124,8 +128,10 @@ public:
// related to Voxel Sending strategies // related to Voxel Sending strategies
bool getWantResIn() const { return _wantResIn; } bool getWantResIn() const { return _wantResIn; }
bool getWantColor() const { return _wantColor; } bool getWantColor() const { return _wantColor; }
bool getWantDelta() const { return _wantDelta; }
void setWantResIn(bool wantResIn) { _wantResIn = wantResIn; } void setWantResIn(bool wantResIn) { _wantResIn = wantResIn; }
void setWantColor(bool wantColor) { _wantColor = wantColor; } void setWantColor(bool wantColor) { _wantColor = wantColor; }
void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; }
protected: protected:
glm::vec3 _position; glm::vec3 _position;
@ -168,8 +174,10 @@ protected:
// chat message // chat message
std::string _chatMessage; std::string _chatMessage;
// voxel server sending items
bool _wantResIn; bool _wantResIn;
bool _wantColor; bool _wantColor;
bool _wantDelta;
}; };
#endif /* defined(__hifi__AvatarData__) */ #endif /* defined(__hifi__AvatarData__) */

View file

@ -94,6 +94,11 @@ bool oneAtBit(unsigned char byte, int bitIndex) {
return (byte >> (7 - bitIndex) & 1); return (byte >> (7 - bitIndex) & 1);
} }
void setAtBit(unsigned char& byte, int bitIndex) {
byte += (1 << (7 - bitIndex));
}
void switchToResourcesParentIfRequired() { void switchToResourcesParentIfRequired() {
#ifdef __APPLE__ #ifdef __APPLE__
CFBundleRef mainBundle = CFBundleGetMainBundle(); CFBundleRef mainBundle = CFBundleGetMainBundle();

View file

@ -49,6 +49,7 @@ void outputBits(unsigned char byte, bool withNewLine = true);
void printVoxelCode(unsigned char* voxelCode); void printVoxelCode(unsigned char* voxelCode);
int numberOfOnes(unsigned char byte); int numberOfOnes(unsigned char byte);
bool oneAtBit(unsigned char byte, int bitIndex); bool oneAtBit(unsigned char byte, int bitIndex);
void setAtBit(unsigned char& byte, int bitIndex);
void switchToResourcesParentIfRequired(); void switchToResourcesParentIfRequired();

View file

@ -276,3 +276,17 @@ void ViewFrustum::computePickRay(float x, float y, glm::vec3& origin, glm::vec3&
origin = _nearTopLeft + x*(_nearTopRight - _nearTopLeft) + y*(_nearBottomLeft - _nearTopLeft); origin = _nearTopLeft + x*(_nearTopRight - _nearTopLeft) + y*(_nearBottomLeft - _nearTopLeft);
direction = glm::normalize(origin - _position); direction = glm::normalize(origin - _position);
} }
void ViewFrustum::printDebugDetails() const {
printLog("ViewFrustum::printDebugDetails()... \n");
printLog("_position=%f,%f,%f\n", _position.x, _position.y, _position.z );
printLog("_direction=%f,%f,%f\n", _direction.x, _direction.y, _direction.z );
printLog("_up=%f,%f,%f\n", _up.x, _up.y, _up.z );
printLog("_right=%f,%f,%f\n", _right.x, _right.y, _right.z );
printLog("_fieldOfView=%f\n", _fieldOfView);
printLog("_aspectRatio=%f\n", _aspectRatio);
printLog("_nearClip=%f\n", _nearClip);
printLog("_farClip=%f\n", _farClip);
}

View file

@ -102,6 +102,8 @@ public:
bool matches(const ViewFrustum& compareTo) const; bool matches(const ViewFrustum& compareTo) const;
bool matches(const ViewFrustum* compareTo) const { return matches(*compareTo); }; bool matches(const ViewFrustum* compareTo) const { return matches(*compareTo); };
void computePickRay(float x, float y, glm::vec3& origin, glm::vec3& direction) const; void computePickRay(float x, float y, glm::vec3& origin, glm::vec3& direction) const;
void printDebugDetails() const;
}; };

View file

@ -617,12 +617,14 @@ void VoxelTree::createSphere(float radius, float xc, float yc, float zc, float v
this->reaverageVoxelColors(this->rootNode); this->reaverageVoxelColors(this->rootNode);
} }
int VoxelTree::searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag) { int VoxelTree::searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag,
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) {
// call the recursive version, this will add all found colored node roots to the bag // call the recursive version, this will add all found colored node roots to the bag
int currentSearchLevel = 0; int currentSearchLevel = 0;
int levelReached = searchForColoredNodesRecursion(maxSearchLevel, currentSearchLevel, rootNode, viewFrustum, bag); int levelReached = searchForColoredNodesRecursion(maxSearchLevel, currentSearchLevel, rootNode,
viewFrustum, bag, deltaViewFrustum, lastViewFrustum);
return levelReached; return levelReached;
} }
@ -667,7 +669,8 @@ bool VoxelTree::findRayIntersection(const glm::vec3& origin, const glm::vec3& di
} }
int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel, int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel,
VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag) { VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag,
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) {
// Keep track of how deep we've searched. // Keep track of how deep we've searched.
currentSearchLevel++; currentSearchLevel++;
@ -702,7 +705,7 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe
bool childIsColored = (childNode && childNode->isColored()); bool childIsColored = (childNode && childNode->isColored());
bool childIsInView = (childNode && childNode->isInView(viewFrustum)); bool childIsInView = (childNode && childNode->isInView(viewFrustum));
bool childIsLeaf = (childNode && childNode->isLeaf()); bool childIsLeaf = (childNode && childNode->isLeaf());
if (childIsInView) { if (childIsInView) {
// track children in view as existing and not a leaf // track children in view as existing and not a leaf
@ -739,7 +742,8 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe
for (int i = 0; i < inViewCount; i++) { for (int i = 0; i < inViewCount; i++) {
VoxelNode* childNode = inViewChildren[i]; VoxelNode* childNode = inViewChildren[i];
thisLevel = currentSearchLevel; // reset this, since the children will munge it up thisLevel = currentSearchLevel; // reset this, since the children will munge it up
int childLevelReached = searchForColoredNodesRecursion(maxSearchLevel, thisLevel, childNode, viewFrustum, bag); int childLevelReached = searchForColoredNodesRecursion(maxSearchLevel, thisLevel, childNode, viewFrustum, bag,
deltaViewFrustum, lastViewFrustum);
maxChildLevel = std::max(maxChildLevel, childLevelReached); maxChildLevel = std::max(maxChildLevel, childLevelReached);
} }
} }
@ -747,7 +751,8 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe
} }
int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes, int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor) const { VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor,
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const {
// How many bytes have we written so far at this level; // How many bytes have we written so far at this level;
int bytesWritten = 0; int bytesWritten = 0;
@ -767,7 +772,8 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
int currentEncodeLevel = 0; int currentEncodeLevel = 0;
int childBytesWritten = encodeTreeBitstreamRecursion(maxEncodeLevel, currentEncodeLevel, int childBytesWritten = encodeTreeBitstreamRecursion(maxEncodeLevel, currentEncodeLevel,
node, outputBuffer, availableBytes, bag, viewFrustum, includeColor); node, outputBuffer, availableBytes, bag, viewFrustum, includeColor,
deltaViewFrustum, lastViewFrustum);
// if childBytesWritten == 1 then something went wrong... that's not possible // if childBytesWritten == 1 then something went wrong... that's not possible
assert(childBytesWritten != 1); assert(childBytesWritten != 1);
@ -790,7 +796,8 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor) const { VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor,
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const {
// How many bytes have we written so far at this level; // How many bytes have we written so far at this level;
int bytesAtThisLevel = 0; int bytesAtThisLevel = 0;
@ -846,6 +853,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
VoxelNode* childNode = node->getChildAtIndex(i); VoxelNode* childNode = node->getChildAtIndex(i);
bool childIsInView = (childNode && (!viewFrustum || childNode->isInView(*viewFrustum))); bool childIsInView = (childNode && (!viewFrustum || childNode->isInView(*viewFrustum)));
if (childIsInView) { if (childIsInView) {
// 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 = viewFrustum ? childNode->distanceToCamera(*viewFrustum) : 0; float distance = viewFrustum ? childNode->distanceToCamera(*viewFrustum) : 0;
@ -861,9 +869,12 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
childrenExistBits += (1 << (7 - i)); childrenExistBits += (1 << (7 - i));
inViewNotLeafCount++; inViewNotLeafCount++;
} }
bool childWasInView = (childNode && deltaViewFrustum &&
(lastViewFrustum && ViewFrustum::INSIDE == childNode->inFrustum(*lastViewFrustum)));
// track children with actual color // track children with actual color, only if the child wasn't previously in view!
if (childNode && childNode->isColored()) { if (childNode && childNode->isColored() && !childWasInView) {
childrenColoredBits += (1 << (7 - i)); childrenColoredBits += (1 << (7 - i));
inViewWithColorCount++; inViewWithColorCount++;
} }
@ -925,7 +936,8 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
int thisLevel = currentEncodeLevel; int thisLevel = currentEncodeLevel;
int childTreeBytesOut = encodeTreeBitstreamRecursion(maxEncodeLevel, thisLevel, childNode, int childTreeBytesOut = encodeTreeBitstreamRecursion(maxEncodeLevel, thisLevel, childNode,
outputBuffer, availableBytes, bag, outputBuffer, availableBytes, bag,
viewFrustum, includeColor); viewFrustum, includeColor,
deltaViewFrustum, lastViewFrustum);
// if the child wrote 0 bytes, it means that nothing below exists or was in view, or we ran out of space, // if the child wrote 0 bytes, it means that nothing below exists or was in view, or we ran out of space,
// basically, the children below don't contain any info. // basically, the children below don't contain any info.

View file

@ -55,9 +55,11 @@ public:
void recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL); void recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL);
int encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes, int encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor = true) const; VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor = true,
bool deltaViewFrustum = false, const ViewFrustum* lastViewFrustum = NULL) const;
int searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag); int searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag,
bool deltaViewFrustum = false, const ViewFrustum* lastViewFrustum = NULL);
bool isDirty() const { return _isDirty; }; bool isDirty() const { return _isDirty; };
void clearDirtyBit() { _isDirty = false; }; void clearDirtyBit() { _isDirty = false; };
@ -79,10 +81,12 @@ public:
private: private:
int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor) const; VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor,
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const;
int searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel, int searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel,
VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag); VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag,
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum);
static bool countVoxelsOperation(VoxelNode* node, void* extraData); static bool countVoxelsOperation(VoxelNode* node, void* extraData);

View file

@ -22,6 +22,7 @@ void VoxelAgentData::init() {
_maxSearchLevel = 1; _maxSearchLevel = 1;
_maxLevelReachedInLastSearch = 1; _maxLevelReachedInLastSearch = 1;
resetVoxelPacket(); resetVoxelPacket();
_viewSent = false;
} }
void VoxelAgentData::resetVoxelPacket() { void VoxelAgentData::resetVoxelPacket() {
@ -50,3 +51,31 @@ VoxelAgentData::VoxelAgentData(const VoxelAgentData &otherAgentData) {
VoxelAgentData* VoxelAgentData::clone() const { VoxelAgentData* VoxelAgentData::clone() const {
return new VoxelAgentData(*this); return new VoxelAgentData(*this);
} }
bool VoxelAgentData::updateCurrentViewFrustum() {
bool currentViewFrustumChanged = false;
ViewFrustum newestViewFrustum;
// get position and orientation details from the camera
newestViewFrustum.setPosition(getCameraPosition());
newestViewFrustum.setOrientation(getCameraDirection(), getCameraUp(), getCameraRight());
// Also make sure it's got the correct lens details from the camera
newestViewFrustum.setFieldOfView(getCameraFov());
newestViewFrustum.setAspectRatio(getCameraAspectRatio());
newestViewFrustum.setNearClip(getCameraNearClip());
newestViewFrustum.setFarClip(getCameraFarClip());
// if there has been a change, then recalculate
if (!newestViewFrustum.matches(_currentViewFrustum)) {
_currentViewFrustum = newestViewFrustum;
_currentViewFrustum.calculate();
currentViewFrustumChanged = true;
}
return currentViewFrustumChanged;
}
void VoxelAgentData::updateLastKnownViewFrustum() {
// save our currentViewFrustum into our lastKnownViewFrustum
_lastKnownViewFrustum = _currentViewFrustum;
}

View file

@ -40,13 +40,29 @@ public:
void setMaxLevelReached(int maxLevelReached) { _maxLevelReachedInLastSearch = maxLevelReached; } void setMaxLevelReached(int maxLevelReached) { _maxLevelReachedInLastSearch = maxLevelReached; }
VoxelNodeBag nodeBag; VoxelNodeBag nodeBag;
ViewFrustum& getCurrentViewFrustum() { return _currentViewFrustum; };
ViewFrustum& getLastKnownViewFrustum() { return _lastKnownViewFrustum; };
// These are not classic setters because they are calculating and maintaining state
// which is set asynchronously through the network receive
bool updateCurrentViewFrustum();
void updateLastKnownViewFrustum();
bool getViewSent() const { return _viewSent; };
void setViewSent(bool viewSent) { _viewSent = viewSent; }
private: private:
bool _viewSent;
unsigned char* _voxelPacket; unsigned char* _voxelPacket;
unsigned char* _voxelPacketAt; unsigned char* _voxelPacketAt;
int _voxelPacketAvailableBytes; int _voxelPacketAvailableBytes;
bool _voxelPacketWaiting; bool _voxelPacketWaiting;
int _maxSearchLevel; int _maxSearchLevel;
int _maxLevelReachedInLastSearch; int _maxLevelReachedInLastSearch;
ViewFrustum _currentViewFrustum;
ViewFrustum _lastKnownViewFrustum;
}; };
#endif /* defined(__hifi__VoxelAgentData__) */ #endif /* defined(__hifi__VoxelAgentData__) */

View file

@ -107,10 +107,8 @@ void eraseVoxelTreeAndCleanupAgentVisitData() {
// Version of voxel distributor that sends each LOD level at a time // Version of voxel distributor that sends each LOD level at a time
void resInVoxelDistributor(AgentList* agentList, void resInVoxelDistributor(AgentList* agentList,
AgentList::iterator& agent, AgentList::iterator& agent,
VoxelAgentData* agentData, VoxelAgentData* agentData) {
ViewFrustum& viewFrustum) { ViewFrustum viewFrustum = agentData->getCurrentViewFrustum();
printf("resInVoxelDistributor()\n");
bool searchReset = false; bool searchReset = false;
int searchLoops = 0; int searchLoops = 0;
int searchLevelWas = agentData->getMaxSearchLevel(); int searchLevelWas = agentData->getMaxSearchLevel();
@ -227,14 +225,32 @@ void resInVoxelDistributor(AgentList* agentList,
void deepestLevelVoxelDistributor(AgentList* agentList, void deepestLevelVoxelDistributor(AgentList* agentList,
AgentList::iterator& agent, AgentList::iterator& agent,
VoxelAgentData* agentData, VoxelAgentData* agentData,
ViewFrustum& viewFrustum) { bool viewFrustumChanged) {
printf("deepestLevelVoxelDistributor()\n");
int maxLevelReached = 0; int maxLevelReached = 0;
double start = usecTimestampNow(); double start = usecTimestampNow();
if (agentData->nodeBag.isEmpty()) {
maxLevelReached = randomTree.searchForColoredNodes(INT_MAX, randomTree.rootNode, viewFrustum, agentData->nodeBag); // FOR NOW... agent tells us if it wants to receive only view frustum deltas
bool wantDelta = agentData->getWantDelta();
const ViewFrustum* lastViewFrustum = wantDelta ? &agentData->getLastKnownViewFrustum() : NULL;
if (::debugVoxelSending) {
printf("deepestLevelVoxelDistributor() viewFrustumChanged=%s, nodeBag.isEmpty=%s, viewSent=%s\n",
viewFrustumChanged ? "yes" : "no",
agentData->nodeBag.isEmpty() ? "yes" : "no",
agentData->getViewSent() ? "yes" : "no"
);
}
// If the current view frustum has changed OR we have nothing to send, then search against
// the current view frustum for things to send.
if (viewFrustumChanged || agentData->nodeBag.isEmpty()) {
// If the bag was empty, then send everything in view, not just the delta
maxLevelReached = randomTree.searchForColoredNodes(INT_MAX, randomTree.rootNode, agentData->getCurrentViewFrustum(),
agentData->nodeBag, wantDelta, lastViewFrustum);
agentData->setViewSent(false);
} }
double end = usecTimestampNow(); double end = usecTimestampNow();
double elapsedmsec = (end - start)/1000.0; double elapsedmsec = (end - start)/1000.0;
@ -266,8 +282,8 @@ void deepestLevelVoxelDistributor(AgentList* agentList,
VoxelNode* subTree = agentData->nodeBag.extract(); VoxelNode* subTree = agentData->nodeBag.extract();
bytesWritten = randomTree.encodeTreeBitstream(INT_MAX, subTree, bytesWritten = randomTree.encodeTreeBitstream(INT_MAX, subTree,
&tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, &tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1,
agentData->nodeBag, &viewFrustum, agentData->nodeBag, &agentData->getCurrentViewFrustum(),
agentData->getWantColor()); agentData->getWantColor(), wantDelta, lastViewFrustum);
if (agentData->getAvailable() >= bytesWritten) { if (agentData->getAvailable() >= bytesWritten) {
agentData->writeToPacket(&tempOutputBuffer[0], bytesWritten); agentData->writeToPacket(&tempOutputBuffer[0], bytesWritten);
@ -313,7 +329,16 @@ void deepestLevelVoxelDistributor(AgentList* agentList,
printf("packetLoop() took %lf milliseconds to generate %d bytes in %d packets, %d nodes still to send\n", printf("packetLoop() took %lf milliseconds to generate %d bytes in %d packets, %d nodes still to send\n",
elapsedmsec, trueBytesSent, truePacketsSent, agentData->nodeBag.count()); elapsedmsec, trueBytesSent, truePacketsSent, agentData->nodeBag.count());
} }
}
// if after sending packets we've emptied our bag, then we want to remember that we've sent all
// the voxels from the current view frustum
if (agentData->nodeBag.isEmpty()) {
agentData->updateLastKnownViewFrustum();
agentData->setViewSent(true);
}
} // end if bag wasn't empty, and so we sent stuff...
} }
void persistVoxelsWhenDirty() { void persistVoxelsWhenDirty() {
@ -340,23 +365,15 @@ void *distributeVoxelsToListeners(void *args) {
// Sometimes the agent data has not yet been linked, in which case we can't really do anything // Sometimes the agent data has not yet been linked, in which case we can't really do anything
if (agentData) { if (agentData) {
ViewFrustum viewFrustum; bool viewFrustumChanged = agentData->updateCurrentViewFrustum();
// get position and orientation details from the camera if (::debugVoxelSending) {
viewFrustum.setPosition(agentData->getCameraPosition()); printf("agentData->updateCurrentViewFrustum() changed=%s\n", (viewFrustumChanged ? "yes" : "no"));
viewFrustum.setOrientation(agentData->getCameraDirection(), agentData->getCameraUp(), agentData->getCameraRight()); }
// Also make sure it's got the correct lens details from the camera
viewFrustum.setFieldOfView(agentData->getCameraFov());
viewFrustum.setAspectRatio(agentData->getCameraAspectRatio());
viewFrustum.setNearClip(agentData->getCameraNearClip());
viewFrustum.setFarClip(agentData->getCameraFarClip());
viewFrustum.calculate();
if (agentData->getWantResIn()) { if (agentData->getWantResIn()) {
resInVoxelDistributor(agentList, agent, agentData, viewFrustum); resInVoxelDistributor(agentList, agent, agentData);
} else { } else {
deepestLevelVoxelDistributor(agentList, agent, agentData, viewFrustum); deepestLevelVoxelDistributor(agentList, agent, agentData, viewFrustumChanged);
} }
} }
} }