mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +02:00
Merge pull request #306 from ZappoMan/render_voxels_optimization
Added "Delta" mode
This commit is contained in:
commit
a0179073ae
13 changed files with 170 additions and 45 deletions
|
@ -1035,6 +1035,10 @@ void Application::setWantsMonochrome(bool wantsMonochrome) {
|
|||
void Application::setWantsResIn(bool wantsResIn) {
|
||||
_myAvatar.setWantResIn(wantsResIn);
|
||||
}
|
||||
|
||||
void Application::setWantsDelta(bool wantsDelta) {
|
||||
_myAvatar.setWantDelta(wantsDelta);
|
||||
}
|
||||
|
||||
void Application::initMenu() {
|
||||
QMenuBar* menuBar = new QMenuBar();
|
||||
|
@ -1096,10 +1100,12 @@ void Application::initMenu() {
|
|||
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 Monochrome", this, SLOT(setWantsMonochrome(bool)))->setCheckable(true);
|
||||
debugMenu->addAction("Wants View Delta Sending", this, SLOT(setWantsDelta(bool)))->setCheckable(true);
|
||||
}
|
||||
|
||||
void Application::updateFrustumRenderModeAction() {
|
||||
switch (_frustumDrawingMode) {
|
||||
default:
|
||||
case FRUSTUM_DRAW_MODE_ALL:
|
||||
_frustumRenderModeAction->setText("Render Mode - All");
|
||||
break;
|
||||
|
|
|
@ -87,6 +87,7 @@ private slots:
|
|||
void doTreeStats();
|
||||
void setWantsMonochrome(bool wantsMonochrome);
|
||||
void setWantsResIn(bool wantsResIn);
|
||||
void setWantsDelta(bool wantsDelta);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -108,8 +108,12 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
|||
destinationBuffer += _chatMessage.size() * sizeof(char);
|
||||
|
||||
// voxel sending features...
|
||||
*destinationBuffer++ = _wantResIn;
|
||||
*destinationBuffer++ = _wantColor;
|
||||
// voxel sending features...
|
||||
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;
|
||||
}
|
||||
|
@ -117,6 +121,8 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
|||
// called on the other agents - assigns it to my views of the others
|
||||
int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||
|
||||
//printf("AvatarData::parseData()\n");
|
||||
|
||||
// increment to push past the packet header
|
||||
sourceBuffer += sizeof(PACKET_HEADER_HEAD_DATA);
|
||||
|
||||
|
@ -184,8 +190,12 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
sourceBuffer += chatMessageSize * sizeof(char);
|
||||
|
||||
// voxel sending features...
|
||||
_wantResIn = (bool)*sourceBuffer++;
|
||||
_wantColor = (bool)*sourceBuffer++;
|
||||
unsigned char wantItems = 0;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
|
||||
#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
|
||||
{
|
||||
NO_KEY_DOWN,
|
||||
|
@ -124,8 +128,10 @@ public:
|
|||
// related to Voxel Sending strategies
|
||||
bool getWantResIn() const { return _wantResIn; }
|
||||
bool getWantColor() const { return _wantColor; }
|
||||
bool getWantDelta() const { return _wantDelta; }
|
||||
void setWantResIn(bool wantResIn) { _wantResIn = wantResIn; }
|
||||
void setWantColor(bool wantColor) { _wantColor = wantColor; }
|
||||
void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; }
|
||||
|
||||
protected:
|
||||
glm::vec3 _position;
|
||||
|
@ -168,8 +174,10 @@ protected:
|
|||
// chat message
|
||||
std::string _chatMessage;
|
||||
|
||||
// voxel server sending items
|
||||
bool _wantResIn;
|
||||
bool _wantColor;
|
||||
bool _wantDelta;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__AvatarData__) */
|
||||
|
|
|
@ -94,6 +94,11 @@ bool oneAtBit(unsigned char byte, int bitIndex) {
|
|||
return (byte >> (7 - bitIndex) & 1);
|
||||
}
|
||||
|
||||
void setAtBit(unsigned char& byte, int bitIndex) {
|
||||
byte += (1 << (7 - bitIndex));
|
||||
}
|
||||
|
||||
|
||||
void switchToResourcesParentIfRequired() {
|
||||
#ifdef __APPLE__
|
||||
CFBundleRef mainBundle = CFBundleGetMainBundle();
|
||||
|
|
|
@ -49,6 +49,7 @@ void outputBits(unsigned char byte, bool withNewLine = true);
|
|||
void printVoxelCode(unsigned char* voxelCode);
|
||||
int numberOfOnes(unsigned char byte);
|
||||
bool oneAtBit(unsigned char byte, int bitIndex);
|
||||
void setAtBit(unsigned char& byte, int bitIndex);
|
||||
|
||||
void switchToResourcesParentIfRequired();
|
||||
|
||||
|
|
|
@ -276,3 +276,17 @@ void ViewFrustum::computePickRay(float x, float y, glm::vec3& origin, glm::vec3&
|
|||
origin = _nearTopLeft + x*(_nearTopRight - _nearTopLeft) + y*(_nearBottomLeft - _nearTopLeft);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -102,6 +102,8 @@ public:
|
|||
bool matches(const ViewFrustum& compareTo) const;
|
||||
bool matches(const ViewFrustum* compareTo) const { return matches(*compareTo); };
|
||||
void computePickRay(float x, float y, glm::vec3& origin, glm::vec3& direction) const;
|
||||
|
||||
void printDebugDetails() const;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -617,12 +617,14 @@ void VoxelTree::createSphere(float radius, float xc, float yc, float zc, float v
|
|||
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
|
||||
int currentSearchLevel = 0;
|
||||
|
||||
int levelReached = searchForColoredNodesRecursion(maxSearchLevel, currentSearchLevel, rootNode, viewFrustum, bag);
|
||||
int levelReached = searchForColoredNodesRecursion(maxSearchLevel, currentSearchLevel, rootNode,
|
||||
viewFrustum, bag, deltaViewFrustum, lastViewFrustum);
|
||||
return levelReached;
|
||||
}
|
||||
|
||||
|
@ -667,7 +669,8 @@ bool VoxelTree::findRayIntersection(const glm::vec3& origin, const glm::vec3& di
|
|||
}
|
||||
|
||||
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.
|
||||
currentSearchLevel++;
|
||||
|
@ -702,7 +705,7 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe
|
|||
bool childIsColored = (childNode && childNode->isColored());
|
||||
bool childIsInView = (childNode && childNode->isInView(viewFrustum));
|
||||
bool childIsLeaf = (childNode && childNode->isLeaf());
|
||||
|
||||
|
||||
if (childIsInView) {
|
||||
|
||||
// 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++) {
|
||||
VoxelNode* childNode = inViewChildren[i];
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -747,7 +751,8 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe
|
|||
}
|
||||
|
||||
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;
|
||||
int bytesWritten = 0;
|
||||
|
@ -767,7 +772,8 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
|
|||
|
||||
int currentEncodeLevel = 0;
|
||||
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
|
||||
assert(childBytesWritten != 1);
|
||||
|
@ -790,7 +796,8 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
|
|||
|
||||
int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
|
||||
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;
|
||||
int bytesAtThisLevel = 0;
|
||||
|
||||
|
@ -846,6 +853,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
|||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||
VoxelNode* childNode = node->getChildAtIndex(i);
|
||||
bool childIsInView = (childNode && (!viewFrustum || childNode->isInView(*viewFrustum)));
|
||||
|
||||
if (childIsInView) {
|
||||
// Before we determine consider this further, let's see if it's in our LOD scope...
|
||||
float distance = viewFrustum ? childNode->distanceToCamera(*viewFrustum) : 0;
|
||||
|
@ -861,9 +869,12 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
|||
childrenExistBits += (1 << (7 - i));
|
||||
inViewNotLeafCount++;
|
||||
}
|
||||
|
||||
bool childWasInView = (childNode && deltaViewFrustum &&
|
||||
(lastViewFrustum && ViewFrustum::INSIDE == childNode->inFrustum(*lastViewFrustum)));
|
||||
|
||||
// track children with actual color
|
||||
if (childNode && childNode->isColored()) {
|
||||
// track children with actual color, only if the child wasn't previously in view!
|
||||
if (childNode && childNode->isColored() && !childWasInView) {
|
||||
childrenColoredBits += (1 << (7 - i));
|
||||
inViewWithColorCount++;
|
||||
}
|
||||
|
@ -925,7 +936,8 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
|||
int thisLevel = currentEncodeLevel;
|
||||
int childTreeBytesOut = encodeTreeBitstreamRecursion(maxEncodeLevel, thisLevel, childNode,
|
||||
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,
|
||||
// basically, the children below don't contain any info.
|
||||
|
|
|
@ -55,9 +55,11 @@ public:
|
|||
void recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL);
|
||||
|
||||
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; };
|
||||
void clearDirtyBit() { _isDirty = false; };
|
||||
|
@ -79,10 +81,12 @@ public:
|
|||
private:
|
||||
int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
|
||||
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,
|
||||
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);
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ void VoxelAgentData::init() {
|
|||
_maxSearchLevel = 1;
|
||||
_maxLevelReachedInLastSearch = 1;
|
||||
resetVoxelPacket();
|
||||
_viewSent = false;
|
||||
}
|
||||
|
||||
void VoxelAgentData::resetVoxelPacket() {
|
||||
|
@ -50,3 +51,31 @@ VoxelAgentData::VoxelAgentData(const VoxelAgentData &otherAgentData) {
|
|||
VoxelAgentData* VoxelAgentData::clone() const {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,13 +40,29 @@ public:
|
|||
void setMaxLevelReached(int maxLevelReached) { _maxLevelReachedInLastSearch = maxLevelReached; }
|
||||
|
||||
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:
|
||||
bool _viewSent;
|
||||
unsigned char* _voxelPacket;
|
||||
unsigned char* _voxelPacketAt;
|
||||
int _voxelPacketAvailableBytes;
|
||||
bool _voxelPacketWaiting;
|
||||
int _maxSearchLevel;
|
||||
int _maxLevelReachedInLastSearch;
|
||||
ViewFrustum _currentViewFrustum;
|
||||
ViewFrustum _lastKnownViewFrustum;
|
||||
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__VoxelAgentData__) */
|
||||
|
|
|
@ -107,10 +107,8 @@ void eraseVoxelTreeAndCleanupAgentVisitData() {
|
|||
// Version of voxel distributor that sends each LOD level at a time
|
||||
void resInVoxelDistributor(AgentList* agentList,
|
||||
AgentList::iterator& agent,
|
||||
VoxelAgentData* agentData,
|
||||
ViewFrustum& viewFrustum) {
|
||||
|
||||
printf("resInVoxelDistributor()\n");
|
||||
VoxelAgentData* agentData) {
|
||||
ViewFrustum viewFrustum = agentData->getCurrentViewFrustum();
|
||||
bool searchReset = false;
|
||||
int searchLoops = 0;
|
||||
int searchLevelWas = agentData->getMaxSearchLevel();
|
||||
|
@ -227,14 +225,32 @@ void resInVoxelDistributor(AgentList* agentList,
|
|||
void deepestLevelVoxelDistributor(AgentList* agentList,
|
||||
AgentList::iterator& agent,
|
||||
VoxelAgentData* agentData,
|
||||
ViewFrustum& viewFrustum) {
|
||||
|
||||
printf("deepestLevelVoxelDistributor()\n");
|
||||
bool viewFrustumChanged) {
|
||||
|
||||
int maxLevelReached = 0;
|
||||
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 elapsedmsec = (end - start)/1000.0;
|
||||
|
@ -266,8 +282,8 @@ void deepestLevelVoxelDistributor(AgentList* agentList,
|
|||
VoxelNode* subTree = agentData->nodeBag.extract();
|
||||
bytesWritten = randomTree.encodeTreeBitstream(INT_MAX, subTree,
|
||||
&tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1,
|
||||
agentData->nodeBag, &viewFrustum,
|
||||
agentData->getWantColor());
|
||||
agentData->nodeBag, &agentData->getCurrentViewFrustum(),
|
||||
agentData->getWantColor(), wantDelta, lastViewFrustum);
|
||||
|
||||
if (agentData->getAvailable() >= 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",
|
||||
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() {
|
||||
|
@ -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
|
||||
if (agentData) {
|
||||
ViewFrustum viewFrustum;
|
||||
// get position and orientation details from the camera
|
||||
viewFrustum.setPosition(agentData->getCameraPosition());
|
||||
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();
|
||||
bool viewFrustumChanged = agentData->updateCurrentViewFrustum();
|
||||
if (::debugVoxelSending) {
|
||||
printf("agentData->updateCurrentViewFrustum() changed=%s\n", (viewFrustumChanged ? "yes" : "no"));
|
||||
}
|
||||
|
||||
if (agentData->getWantResIn()) {
|
||||
resInVoxelDistributor(agentList, agent, agentData, viewFrustum);
|
||||
resInVoxelDistributor(agentList, agent, agentData);
|
||||
} else {
|
||||
deepestLevelVoxelDistributor(agentList, agent, agentData, viewFrustum);
|
||||
deepestLevelVoxelDistributor(agentList, agent, agentData, viewFrustumChanged);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue