mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 14:37:46 +02:00
first-pass sending entities from _sendQueue
This commit is contained in:
parent
1562fb153e
commit
b6818c4369
4 changed files with 99 additions and 15 deletions
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
#include "EntityServer.h"
|
#include "EntityServer.h"
|
||||||
|
|
||||||
|
//#define SEND_SORTED_ENTITIES
|
||||||
|
|
||||||
void EntityTreeSendThread::preDistributionProcessing() {
|
void EntityTreeSendThread::preDistributionProcessing() {
|
||||||
auto node = _node.toStrongRef();
|
auto node = _node.toStrongRef();
|
||||||
auto nodeData = static_cast<EntityNodeData*>(node->getLinkedData());
|
auto nodeData = static_cast<EntityNodeData*>(node->getLinkedData());
|
||||||
|
@ -145,6 +147,7 @@ void EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O
|
||||||
std::cout << "adebug traversal complete " << " Q.size = " << _sendQueue.size() << " dt = " << dt << std::endl; // adebug
|
std::cout << "adebug traversal complete " << " Q.size = " << _sendQueue.size() << " dt = " << dt << std::endl; // adebug
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef SEND_SORTED_ENTITIES
|
||||||
if (!_sendQueue.empty()) {
|
if (!_sendQueue.empty()) {
|
||||||
// print what needs to be sent
|
// print what needs to be sent
|
||||||
while (!_sendQueue.empty()) {
|
while (!_sendQueue.empty()) {
|
||||||
|
@ -157,6 +160,7 @@ void EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O
|
||||||
_entitiesToSend.erase(entity);
|
_entitiesToSend.erase(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // SEND_SORTED_ENTITIES
|
||||||
// END EXPERIMENTAL DIFFERENTIAL TRAVERSAL
|
// END EXPERIMENTAL DIFFERENTIAL TRAVERSAL
|
||||||
|
|
||||||
OctreeSendThread::traverseTreeAndSendContents(node, nodeData, viewFrustumChanged, isFullScene);
|
OctreeSendThread::traverseTreeAndSendContents(node, nodeData, viewFrustumChanged, isFullScene);
|
||||||
|
@ -245,7 +249,7 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree
|
||||||
float renderAccuracy = calculateRenderAccuracy(_traversal.getCurrentView().getPosition(),
|
float renderAccuracy = calculateRenderAccuracy(_traversal.getCurrentView().getPosition(),
|
||||||
cube,
|
cube,
|
||||||
_traversal.getCurrentRootSizeScale(),
|
_traversal.getCurrentRootSizeScale(),
|
||||||
lodLevelOffset);
|
_traversal.getCurrentLODOffset());
|
||||||
|
|
||||||
// Only send entities if they are large enough to see
|
// Only send entities if they are large enough to see
|
||||||
if (renderAccuracy > 0.0f) {
|
if (renderAccuracy > 0.0f) {
|
||||||
|
@ -280,7 +284,7 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree
|
||||||
float renderAccuracy = calculateRenderAccuracy(_traversal.getCurrentView().getPosition(),
|
float renderAccuracy = calculateRenderAccuracy(_traversal.getCurrentView().getPosition(),
|
||||||
cube,
|
cube,
|
||||||
_traversal.getCurrentRootSizeScale(),
|
_traversal.getCurrentRootSizeScale(),
|
||||||
lodLevelOffset);
|
_traversal.getCurrentLODOffset());
|
||||||
|
|
||||||
// Only send entities if they are large enough to see
|
// Only send entities if they are large enough to see
|
||||||
if (renderAccuracy > 0.0f) {
|
if (renderAccuracy > 0.0f) {
|
||||||
|
@ -317,7 +321,7 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree
|
||||||
float renderAccuracy = calculateRenderAccuracy(_traversal.getCurrentView().getPosition(),
|
float renderAccuracy = calculateRenderAccuracy(_traversal.getCurrentView().getPosition(),
|
||||||
cube,
|
cube,
|
||||||
_traversal.getCurrentRootSizeScale(),
|
_traversal.getCurrentRootSizeScale(),
|
||||||
lodLevelOffset);
|
_traversal.getCurrentLODOffset());
|
||||||
|
|
||||||
// Only send entities if they are large enough to see
|
// Only send entities if they are large enough to see
|
||||||
if (renderAccuracy > 0.0f) {
|
if (renderAccuracy > 0.0f) {
|
||||||
|
@ -330,7 +334,7 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree
|
||||||
float lastRenderAccuracy = calculateRenderAccuracy(_traversal.getCompletedView().getPosition(),
|
float lastRenderAccuracy = calculateRenderAccuracy(_traversal.getCompletedView().getPosition(),
|
||||||
cube,
|
cube,
|
||||||
_traversal.getCompletedRootSizeScale(),
|
_traversal.getCompletedRootSizeScale(),
|
||||||
lodLevelOffset);
|
_traversal.getCompletedLODOffset());
|
||||||
|
|
||||||
if (lastRenderAccuracy <= 0.0f) {
|
if (lastRenderAccuracy <= 0.0f) {
|
||||||
float priority = _conicalView.computePriority(cube);
|
float priority = _conicalView.computePriority(cube);
|
||||||
|
@ -352,3 +356,77 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EntityTreeSendThread::traverseTreeAndBuildNextPacketPayload(EncodeBitstreamParams& params) {
|
||||||
|
#ifdef SEND_SORTED_ENTITIES
|
||||||
|
//auto entityTree = std::static_pointer_cast<EntityTree>(_myServer->getOctree());
|
||||||
|
if (_sendQueue.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!_packetData.hasContent()) {
|
||||||
|
// This is the beginning of a new packet.
|
||||||
|
// We pack minimal data for this to be accepted as an OctreeElement payload for the root element.
|
||||||
|
// The Octree header bytes look like this:
|
||||||
|
//
|
||||||
|
// 0x00 octalcode for root
|
||||||
|
// 0x00 colors (1 bit where recipient should call: child->readElementDataFromBuffer())
|
||||||
|
// 0xXX childrenInTreeMask (when params.includeExistsBits is true: 1 bit where child is existant)
|
||||||
|
// 0x00 childrenInBufferMask (1 bit where recipient should call: child->readElementData() recursively)
|
||||||
|
const uint8_t zeroByte = 0;
|
||||||
|
_packetData.appendValue(zeroByte); // octalcode
|
||||||
|
_packetData.appendValue(zeroByte); // colors
|
||||||
|
if (params.includeExistsBits) {
|
||||||
|
uint8_t childrenExistBits = 0;
|
||||||
|
EntityTreeElementPointer root = std::dynamic_pointer_cast<EntityTreeElement>(_myServer->getOctree()->getRoot());
|
||||||
|
for (int32_t i = 0; i < NUMBER_OF_CHILDREN; ++i) {
|
||||||
|
if (root->getChildAtIndex(i)) {
|
||||||
|
childrenExistBits += (1 << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_packetData.appendValue(childrenExistBits); // childrenInTreeMask
|
||||||
|
}
|
||||||
|
_packetData.appendValue(zeroByte); // childrenInBufferMask
|
||||||
|
|
||||||
|
// Pack zero for numEntities.
|
||||||
|
// But before we do: grab current byteOffset so we can come back later
|
||||||
|
// and update this with the real number.
|
||||||
|
_numEntities = 0;
|
||||||
|
_numEntitiesOffset = _packetData.getUncompressedByteOffset();
|
||||||
|
_packetData.appendValue(_numEntities);
|
||||||
|
}
|
||||||
|
|
||||||
|
LevelDetails entitiesLevel = _packetData.startLevel();
|
||||||
|
while(!_sendQueue.empty()) {
|
||||||
|
PrioritizedEntity queuedItem = _sendQueue.top();
|
||||||
|
EntityItemPointer entity = queuedItem.getEntity();
|
||||||
|
if (entity) {
|
||||||
|
OctreeElement::AppendState appendEntityState = entity->appendEntityData(&_packetData, params, _extraEncodeData);
|
||||||
|
|
||||||
|
if (appendEntityState != OctreeElement::COMPLETED) {
|
||||||
|
if (appendEntityState == OctreeElement::PARTIAL) {
|
||||||
|
++_numEntities;
|
||||||
|
}
|
||||||
|
params.stopReason = EncodeBitstreamParams::DIDNT_FIT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++_numEntities;
|
||||||
|
}
|
||||||
|
_sendQueue.pop();
|
||||||
|
}
|
||||||
|
if (_sendQueue.empty()) {
|
||||||
|
params.stopReason = EncodeBitstreamParams::FINISHED;
|
||||||
|
_extraEncodeData->entities.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_numEntities == 0) {
|
||||||
|
_packetData.discardLevel(entitiesLevel);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_packetData.endLevel(entitiesLevel);
|
||||||
|
_packetData.updatePriorBytes(_numEntitiesOffset, (const unsigned char*)&_numEntities, sizeof(_numEntities));
|
||||||
|
return true;
|
||||||
|
|
||||||
|
#else // SEND_SORTED_ENTITIES
|
||||||
|
return OctreeSendThread::traverseTreeAndBuildNextPacketPayload(params);
|
||||||
|
#endif // SEND_SORTED_ENTITIES
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,11 +39,17 @@ private:
|
||||||
bool addDescendantsToExtraFlaggedEntities(const QUuid& filteredEntityID, EntityItem& entityItem, EntityNodeData& nodeData);
|
bool addDescendantsToExtraFlaggedEntities(const QUuid& filteredEntityID, EntityItem& entityItem, EntityNodeData& nodeData);
|
||||||
|
|
||||||
void startNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root, int32_t lodLevelOffset);
|
void startNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root, int32_t lodLevelOffset);
|
||||||
|
bool traverseTreeAndBuildNextPacketPayload(EncodeBitstreamParams& params) override;
|
||||||
|
|
||||||
DiffTraversal _traversal;
|
DiffTraversal _traversal;
|
||||||
EntityPriorityQueue _sendQueue;
|
EntityPriorityQueue _sendQueue;
|
||||||
std::unordered_set<EntityItemPointer> _entitiesToSend;
|
std::unordered_set<EntityItemPointer> _entitiesToSend;
|
||||||
ConicalView _conicalView; // cached optimized view for fast priority calculations
|
ConicalView _conicalView; // cached optimized view for fast priority calculations
|
||||||
|
|
||||||
|
// packet construction stuff
|
||||||
|
EntityTreeElementExtraEncodeDataPointer _extraEncodeData { new EntityTreeElementExtraEncodeData() };
|
||||||
|
int32_t _numEntitiesOffset { 0 };
|
||||||
|
uint16_t _numEntities { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_EntityTreeSendThread_h
|
#endif // hifi_EntityTreeSendThread_h
|
||||||
|
|
|
@ -89,22 +89,15 @@ void DiffTraversal::Waypoint::getNextVisibleElementRepeat(
|
||||||
next.intersection = ViewFrustum::OUTSIDE;
|
next.intersection = ViewFrustum::OUTSIDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
DiffTraversal::DiffTraversal() {
|
|
||||||
const int32_t MIN_PATH_DEPTH = 16;
|
|
||||||
_path.reserve(MIN_PATH_DEPTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DiffTraversal::Waypoint::getNextVisibleElementDifferential(DiffTraversal::VisibleElement& next,
|
void DiffTraversal::Waypoint::getNextVisibleElementDifferential(DiffTraversal::VisibleElement& next,
|
||||||
const DiffTraversal::View& view, const DiffTraversal::View& lastView) {
|
const DiffTraversal::View& view, const DiffTraversal::View& lastView) {
|
||||||
if (_nextIndex == -1) {
|
if (_nextIndex == -1) {
|
||||||
// root case is special
|
// root case is special
|
||||||
++_nextIndex;
|
++_nextIndex;
|
||||||
EntityTreeElementPointer element = _weakElement.lock();
|
EntityTreeElementPointer element = _weakElement.lock();
|
||||||
if (element->getLastChangedContent() > lastView.startTime) {
|
next.element = element;
|
||||||
next.element = element;
|
next.intersection = ViewFrustum::INTERSECT;
|
||||||
next.intersection = ViewFrustum::INTERSECT;
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (_nextIndex < NUMBER_OF_CHILDREN) {
|
if (_nextIndex < NUMBER_OF_CHILDREN) {
|
||||||
EntityTreeElementPointer element = _weakElement.lock();
|
EntityTreeElementPointer element = _weakElement.lock();
|
||||||
|
@ -149,6 +142,11 @@ void DiffTraversal::Waypoint::getNextVisibleElementDifferential(DiffTraversal::V
|
||||||
next.intersection = ViewFrustum::OUTSIDE;
|
next.intersection = ViewFrustum::OUTSIDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DiffTraversal::DiffTraversal() {
|
||||||
|
const int32_t MIN_PATH_DEPTH = 16;
|
||||||
|
_path.reserve(MIN_PATH_DEPTH);
|
||||||
|
}
|
||||||
|
|
||||||
DiffTraversal::Type DiffTraversal::prepareNewTraversal(
|
DiffTraversal::Type DiffTraversal::prepareNewTraversal(
|
||||||
const ViewFrustum& viewFrustum, EntityTreeElementPointer root, int32_t lodLevelOffset) {
|
const ViewFrustum& viewFrustum, EntityTreeElementPointer root, int32_t lodLevelOffset) {
|
||||||
assert(root);
|
assert(root);
|
||||||
|
@ -246,7 +244,7 @@ std::ostream& operator<<(std::ostream& s, const DiffTraversal& traversal) {
|
||||||
for (size_t i = 0; i < traversal._path.size(); ++i) {
|
for (size_t i = 0; i < traversal._path.size(); ++i) {
|
||||||
s << (int32_t)(traversal._path[i].getNextIndex());
|
s << (int32_t)(traversal._path[i].getNextIndex());
|
||||||
if (i < traversal._path.size() - 1) {
|
if (i < traversal._path.size() - 1) {
|
||||||
s << "-->";
|
s << ":";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
|
|
|
@ -66,6 +66,8 @@ public:
|
||||||
|
|
||||||
float getCurrentRootSizeScale() const { return _currentView.rootSizeScale; }
|
float getCurrentRootSizeScale() const { return _currentView.rootSizeScale; }
|
||||||
float getCompletedRootSizeScale() const { return _completedView.rootSizeScale; }
|
float getCompletedRootSizeScale() const { return _completedView.rootSizeScale; }
|
||||||
|
float getCurrentLODOffset() const { return _currentView.lodLevelOffset; }
|
||||||
|
float getCompletedLODOffset() const { return _completedView.lodLevelOffset; }
|
||||||
|
|
||||||
uint64_t getStartOfCompletedTraversal() const { return _completedView.startTime; }
|
uint64_t getStartOfCompletedTraversal() const { return _completedView.startTime; }
|
||||||
bool finished() const { return _path.empty(); }
|
bool finished() const { return _path.empty(); }
|
||||||
|
|
Loading…
Reference in a new issue