mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 11:07:07 +02:00
initial changes to OctreeQueryNode for new APIs
This commit is contained in:
parent
474b82e3bf
commit
74924bc5f1
4 changed files with 50 additions and 81 deletions
|
@ -22,11 +22,9 @@
|
||||||
|
|
||||||
OctreeQueryNode::OctreeQueryNode() :
|
OctreeQueryNode::OctreeQueryNode() :
|
||||||
_viewSent(false),
|
_viewSent(false),
|
||||||
_octreePacket(new unsigned char[MAX_PACKET_SIZE]),
|
_octreePacket(),
|
||||||
_octreePacketAt(_octreePacket),
|
|
||||||
_octreePacketAvailableBytes(MAX_PACKET_SIZE),
|
|
||||||
_octreePacketWaiting(false),
|
_octreePacketWaiting(false),
|
||||||
_lastOctreePacket(new unsigned char[MAX_PACKET_SIZE]),
|
_lastOctreePayload(new char[MAX_PACKET_SIZE]),
|
||||||
_lastOctreePacketLength(0),
|
_lastOctreePacketLength(0),
|
||||||
_duplicatePacketCount(0),
|
_duplicatePacketCount(0),
|
||||||
_firstSuppressedPacket(usecTimestampNow()),
|
_firstSuppressedPacket(usecTimestampNow()),
|
||||||
|
@ -55,9 +53,8 @@ OctreeQueryNode::~OctreeQueryNode() {
|
||||||
if (_octreeSendThread) {
|
if (_octreeSendThread) {
|
||||||
forceNodeShutdown();
|
forceNodeShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] _octreePacket;
|
delete[] _lastOctreePayload;
|
||||||
delete[] _lastOctreePacket;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeQueryNode::nodeKilled() {
|
void OctreeQueryNode::nodeKilled() {
|
||||||
|
@ -74,7 +71,7 @@ void OctreeQueryNode::forceNodeShutdown() {
|
||||||
_isShuttingDown = true;
|
_isShuttingDown = true;
|
||||||
elementBag.unhookNotifications(); // if our node is shutting down, then we no longer need octree element notifications
|
elementBag.unhookNotifications(); // if our node is shutting down, then we no longer need octree element notifications
|
||||||
if (_octreeSendThread) {
|
if (_octreeSendThread) {
|
||||||
// we really need to force our thread to shutdown, this is synchronous, we will block while the thread actually
|
// we really need to force our thread to shutdown, this is synchronous, we will block while the thread actually
|
||||||
// shuts down because we really need it to shutdown, and it's ok if we wait for it to complete
|
// shuts down because we really need it to shutdown, and it's ok if we wait for it to complete
|
||||||
OctreeSendThread* sendThread = _octreeSendThread;
|
OctreeSendThread* sendThread = _octreeSendThread;
|
||||||
_octreeSendThread = NULL;
|
_octreeSendThread = NULL;
|
||||||
|
@ -96,8 +93,8 @@ void OctreeQueryNode::sendThreadFinished() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeQueryNode::initializeOctreeSendThread(OctreeServer* myServer, const SharedNodePointer& node) {
|
void OctreeQueryNode::initializeOctreeSendThread(OctreeServer* myServer, const SharedNodePointer& node) {
|
||||||
_octreeSendThread = new OctreeSendThread(myServer, node);
|
_octreeSendThread = new OctreeSendThread(myServer, node);
|
||||||
|
|
||||||
// we want to be notified when the thread finishes
|
// we want to be notified when the thread finishes
|
||||||
connect(_octreeSendThread, &GenericThread::finished, this, &OctreeQueryNode::sendThreadFinished);
|
connect(_octreeSendThread, &GenericThread::finished, this, &OctreeQueryNode::sendThreadFinished);
|
||||||
_octreeSendThread->initialize(true);
|
_octreeSendThread->initialize(true);
|
||||||
|
@ -110,12 +107,11 @@ bool OctreeQueryNode::packetIsDuplicate() const {
|
||||||
}
|
}
|
||||||
// since our packets now include header information, like sequence number, and createTime, we can't just do a memcmp
|
// since our packets now include header information, like sequence number, and createTime, we can't just do a memcmp
|
||||||
// of the entire packet, we need to compare only the packet content...
|
// of the entire packet, we need to compare only the packet content...
|
||||||
int numBytesPacketHeader = numBytesForPacketHeaderGivenPacketType(_myPacketType);
|
|
||||||
|
|
||||||
if (_lastOctreePacketLength == getPacketLength()) {
|
if (_lastOctreePacketLength == getPacketLength()) {
|
||||||
if (memcmp(_lastOctreePacket + (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE),
|
if (memcmp(_lastOctreePayload + OCTREE_PACKET_EXTRA_HEADERS_SIZE,
|
||||||
_octreePacket + (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE),
|
_octreePacket->getPayload() + OCTREE_PACKET_EXTRA_HEADERS_SIZE,
|
||||||
getPacketLength() - (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE)) == 0) {
|
_octreePacket->getSizeUsed() - OCTREE_PACKET_EXTRA_HEADERS_SIZE) == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,6 +159,9 @@ bool OctreeQueryNode::shouldSuppressDuplicatePacket() {
|
||||||
|
|
||||||
void OctreeQueryNode::init() {
|
void OctreeQueryNode::init() {
|
||||||
_myPacketType = getMyPacketType();
|
_myPacketType = getMyPacketType();
|
||||||
|
|
||||||
|
_octreePacket = NLPacket::create(getMyPacketType());
|
||||||
|
|
||||||
resetOctreePacket(); // don't bump sequence
|
resetOctreePacket(); // don't bump sequence
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,8 +176,8 @@ void OctreeQueryNode::resetOctreePacket() {
|
||||||
// changed since we last reset it. Since we know that no two packets can ever be identical without being the same
|
// changed since we last reset it. Since we know that no two packets can ever be identical without being the same
|
||||||
// scene information, (e.g. the root node packet of a static scene), we can use this as a strategy for reducing
|
// scene information, (e.g. the root node packet of a static scene), we can use this as a strategy for reducing
|
||||||
// packet send rate.
|
// packet send rate.
|
||||||
_lastOctreePacketLength = getPacketLength();
|
_lastOctreePacketLength = _octreePacket->getSizeUsed();
|
||||||
memcpy(_lastOctreePacket, _octreePacket, _lastOctreePacketLength);
|
memcpy(_lastOctreePayload, _octreePacket->getPayload(), _lastOctreePacketLength);
|
||||||
|
|
||||||
// If we're moving, and the client asked for low res, then we force monochrome, otherwise, use
|
// If we're moving, and the client asked for low res, then we force monochrome, otherwise, use
|
||||||
// the clients requested color state.
|
// the clients requested color state.
|
||||||
|
@ -192,31 +191,17 @@ void OctreeQueryNode::resetOctreePacket() {
|
||||||
setAtBit(flags, PACKET_IS_COMPRESSED_BIT);
|
setAtBit(flags, PACKET_IS_COMPRESSED_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
_octreePacketAvailableBytes = MAX_PACKET_SIZE;
|
_octreePacket->reset();
|
||||||
int numBytesPacketHeader = DependencyManager::get<NodeList>()->populatePacketHeader(reinterpret_cast<char*>(_octreePacket),
|
|
||||||
_myPacketType);
|
|
||||||
|
|
||||||
_octreePacketAt = _octreePacket + numBytesPacketHeader;
|
|
||||||
_octreePacketAvailableBytes -= numBytesPacketHeader;
|
|
||||||
|
|
||||||
// pack in flags
|
// pack in flags
|
||||||
OCTREE_PACKET_FLAGS* flagsAt = (OCTREE_PACKET_FLAGS*)_octreePacketAt;
|
_octreePacket->write(&flags, sizeof(flags));
|
||||||
*flagsAt = flags;
|
|
||||||
_octreePacketAt += sizeof(OCTREE_PACKET_FLAGS);
|
|
||||||
_octreePacketAvailableBytes -= sizeof(OCTREE_PACKET_FLAGS);
|
|
||||||
|
|
||||||
// pack in sequence number
|
// pack in sequence number
|
||||||
OCTREE_PACKET_SEQUENCE* sequenceAt = (OCTREE_PACKET_SEQUENCE*)_octreePacketAt;
|
_octreePacket->write(&_sequenceNumber, sizeof(_sequenceNumber));
|
||||||
*sequenceAt = _sequenceNumber;
|
|
||||||
_octreePacketAt += sizeof(OCTREE_PACKET_SEQUENCE);
|
|
||||||
_octreePacketAvailableBytes -= sizeof(OCTREE_PACKET_SEQUENCE);
|
|
||||||
|
|
||||||
// pack in timestamp
|
// pack in timestamp
|
||||||
OCTREE_PACKET_SENT_TIME now = usecTimestampNow();
|
OCTREE_PACKET_SENT_TIME now = usecTimestampNow();
|
||||||
OCTREE_PACKET_SENT_TIME* timeAt = (OCTREE_PACKET_SENT_TIME*)_octreePacketAt;
|
_octreePacket->write(&now, sizeof(now));
|
||||||
*timeAt = now;
|
|
||||||
_octreePacketAt += sizeof(OCTREE_PACKET_SENT_TIME);
|
|
||||||
_octreePacketAvailableBytes -= sizeof(OCTREE_PACKET_SENT_TIME);
|
|
||||||
|
|
||||||
_octreePacketWaiting = false;
|
_octreePacketWaiting = false;
|
||||||
}
|
}
|
||||||
|
@ -230,14 +215,11 @@ void OctreeQueryNode::writeToPacket(const unsigned char* buffer, unsigned int by
|
||||||
// compressed packets include lead bytes which contain compressed size, this allows packing of
|
// compressed packets include lead bytes which contain compressed size, this allows packing of
|
||||||
// multiple compressed portions together
|
// multiple compressed portions together
|
||||||
if (_currentPacketIsCompressed) {
|
if (_currentPacketIsCompressed) {
|
||||||
*(OCTREE_PACKET_INTERNAL_SECTION_SIZE*)_octreePacketAt = bytes;
|
OCTREE_PACKET_INTERNAL_SECTION_SIZE sectionSize = bytes;
|
||||||
_octreePacketAt += sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE);
|
_octreePacket->write(§ionSize, sizeof(sectionSize));
|
||||||
_octreePacketAvailableBytes -= sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE);
|
|
||||||
}
|
}
|
||||||
if (bytes <= _octreePacketAvailableBytes) {
|
if (bytes <= _octreePacket->bytesAvailable()) {
|
||||||
memcpy(_octreePacketAt, buffer, bytes);
|
_octreePacket->write(buffer, bytes);
|
||||||
_octreePacketAvailableBytes -= bytes;
|
|
||||||
_octreePacketAt += bytes;
|
|
||||||
_octreePacketWaiting = true;
|
_octreePacketWaiting = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,8 +240,8 @@ bool OctreeQueryNode::updateCurrentViewFrustum() {
|
||||||
float originalFOV = getCameraFov();
|
float originalFOV = getCameraFov();
|
||||||
float wideFOV = originalFOV + VIEW_FRUSTUM_FOV_OVERSEND;
|
float wideFOV = originalFOV + VIEW_FRUSTUM_FOV_OVERSEND;
|
||||||
|
|
||||||
if (0.0f != getCameraAspectRatio() &&
|
if (0.0f != getCameraAspectRatio() &&
|
||||||
0.0f != getCameraNearClip() &&
|
0.0f != getCameraNearClip() &&
|
||||||
0.0f != getCameraFarClip()) {
|
0.0f != getCameraFarClip()) {
|
||||||
newestViewFrustum.setProjection(glm::perspective(
|
newestViewFrustum.setProjection(glm::perspective(
|
||||||
glm::radians(wideFOV), // hack
|
glm::radians(wideFOV), // hack
|
||||||
|
@ -351,7 +333,7 @@ void OctreeQueryNode::dumpOutOfView() {
|
||||||
if (_isShuttingDown) {
|
if (_isShuttingDown) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int stillInView = 0;
|
int stillInView = 0;
|
||||||
int outOfView = 0;
|
int outOfView = 0;
|
||||||
OctreeElementBag tempBag;
|
OctreeElementBag tempBag;
|
||||||
|
@ -374,15 +356,7 @@ void OctreeQueryNode::dumpOutOfView() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeQueryNode::octreePacketSent() {
|
void OctreeQueryNode::packetSent(const NLPacket& packet) {
|
||||||
packetSent(_octreePacket, getPacketLength());
|
|
||||||
}
|
|
||||||
|
|
||||||
void OctreeQueryNode::packetSent(unsigned char* packet, int packetLength) {
|
|
||||||
packetSent(QByteArray((char*)packet, packetLength));
|
|
||||||
}
|
|
||||||
|
|
||||||
void OctreeQueryNode::packetSent(const QByteArray& packet) {
|
|
||||||
_sentPacketHistory.packetSent(_sequenceNumber, packet);
|
_sentPacketHistory.packetSent(_sequenceNumber, packet);
|
||||||
_sequenceNumber++;
|
_sequenceNumber++;
|
||||||
}
|
}
|
||||||
|
@ -391,12 +365,13 @@ bool OctreeQueryNode::hasNextNackedPacket() const {
|
||||||
return !_nackedSequenceNumbers.isEmpty();
|
return !_nackedSequenceNumbers.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QByteArray* OctreeQueryNode::getNextNackedPacket() {
|
NLPacket&& OctreeQueryNode::getNextNackedPacket() {
|
||||||
if (!_nackedSequenceNumbers.isEmpty()) {
|
if (!_nackedSequenceNumbers.isEmpty()) {
|
||||||
// could return null if packet is not in the history
|
// could return null if packet is not in the history
|
||||||
return _sentPacketHistory.getPacket(_nackedSequenceNumbers.dequeue());
|
return std::move(_sentPacketHistory.getPacket(_nackedSequenceNumbers.dequeue()));
|
||||||
}
|
}
|
||||||
return NULL;
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeQueryNode::parseNackPacket(const QByteArray& packet) {
|
void OctreeQueryNode::parseNackPacket(const QByteArray& packet) {
|
||||||
|
|
|
@ -41,8 +41,7 @@ public:
|
||||||
|
|
||||||
void writeToPacket(const unsigned char* buffer, unsigned int bytes); // writes to end of packet
|
void writeToPacket(const unsigned char* buffer, unsigned int bytes); // writes to end of packet
|
||||||
|
|
||||||
const unsigned char* getPacket() const { return _octreePacket; }
|
NLPacket& getPacket() const { return _octreePacket; }
|
||||||
unsigned int getPacketLength() const { return (MAX_PACKET_SIZE - _octreePacketAvailableBytes); }
|
|
||||||
bool isPacketWaiting() const { return _octreePacketWaiting; }
|
bool isPacketWaiting() const { return _octreePacketWaiting; }
|
||||||
|
|
||||||
bool packetIsDuplicate() const;
|
bool packetIsDuplicate() const;
|
||||||
|
@ -62,7 +61,7 @@ public:
|
||||||
|
|
||||||
ViewFrustum& getCurrentViewFrustum() { return _currentViewFrustum; }
|
ViewFrustum& getCurrentViewFrustum() { return _currentViewFrustum; }
|
||||||
ViewFrustum& getLastKnownViewFrustum() { return _lastKnownViewFrustum; }
|
ViewFrustum& getLastKnownViewFrustum() { return _lastKnownViewFrustum; }
|
||||||
|
|
||||||
// These are not classic setters because they are calculating and maintaining state
|
// These are not classic setters because they are calculating and maintaining state
|
||||||
// which is set asynchronously through the network receive
|
// which is set asynchronously through the network receive
|
||||||
bool updateCurrentViewFrustum();
|
bool updateCurrentViewFrustum();
|
||||||
|
@ -86,49 +85,46 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasLodChanged() const { return _lodChanged; }
|
bool hasLodChanged() const { return _lodChanged; }
|
||||||
|
|
||||||
OctreeSceneStats stats;
|
OctreeSceneStats stats;
|
||||||
|
|
||||||
void initializeOctreeSendThread(OctreeServer* myServer, const SharedNodePointer& node);
|
void initializeOctreeSendThread(OctreeServer* myServer, const SharedNodePointer& node);
|
||||||
bool isOctreeSendThreadInitalized() { return _octreeSendThread; }
|
bool isOctreeSendThreadInitalized() { return _octreeSendThread; }
|
||||||
|
|
||||||
void dumpOutOfView();
|
void dumpOutOfView();
|
||||||
|
|
||||||
quint64 getLastRootTimestamp() const { return _lastRootTimestamp; }
|
quint64 getLastRootTimestamp() const { return _lastRootTimestamp; }
|
||||||
void setLastRootTimestamp(quint64 timestamp) { _lastRootTimestamp = timestamp; }
|
void setLastRootTimestamp(quint64 timestamp) { _lastRootTimestamp = timestamp; }
|
||||||
unsigned int getlastOctreePacketLength() const { return _lastOctreePacketLength; }
|
unsigned int getlastOctreePacketLength() const { return _lastOctreePacketLength; }
|
||||||
int getDuplicatePacketCount() const { return _duplicatePacketCount; }
|
int getDuplicatePacketCount() const { return _duplicatePacketCount; }
|
||||||
|
|
||||||
void sceneStart(quint64 sceneSendStartTime) { _sceneSendStartTime = sceneSendStartTime; }
|
void sceneStart(quint64 sceneSendStartTime) { _sceneSendStartTime = sceneSendStartTime; }
|
||||||
|
|
||||||
void nodeKilled();
|
void nodeKilled();
|
||||||
void forceNodeShutdown();
|
void forceNodeShutdown();
|
||||||
bool isShuttingDown() const { return _isShuttingDown; }
|
bool isShuttingDown() const { return _isShuttingDown; }
|
||||||
|
|
||||||
void octreePacketSent();
|
void octreePacketSent() { packetSent(_octreePacket); }
|
||||||
void packetSent(unsigned char* packet, int packetLength);
|
void packetSent(const NLPacket& packet);
|
||||||
void packetSent(const QByteArray& packet);
|
|
||||||
|
|
||||||
OCTREE_PACKET_SEQUENCE getSequenceNumber() const { return _sequenceNumber; }
|
OCTREE_PACKET_SEQUENCE getSequenceNumber() const { return _sequenceNumber; }
|
||||||
|
|
||||||
void parseNackPacket(const QByteArray& packet);
|
void parseNackPacket(const QByteArray& packet);
|
||||||
bool hasNextNackedPacket() const;
|
bool hasNextNackedPacket() const;
|
||||||
const QByteArray* getNextNackedPacket();
|
NLPacket&& getNextNackedPacket();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void sendThreadFinished();
|
void sendThreadFinished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OctreeQueryNode(const OctreeQueryNode &);
|
OctreeQueryNode(const OctreeQueryNode &);
|
||||||
OctreeQueryNode& operator= (const OctreeQueryNode&);
|
OctreeQueryNode& operator= (const OctreeQueryNode&);
|
||||||
|
|
||||||
bool _viewSent;
|
bool _viewSent;
|
||||||
unsigned char* _octreePacket;
|
std::unique_ptr<NLPacket> _octreePacket;
|
||||||
unsigned char* _octreePacketAt;
|
|
||||||
unsigned int _octreePacketAvailableBytes;
|
|
||||||
bool _octreePacketWaiting;
|
bool _octreePacketWaiting;
|
||||||
|
|
||||||
unsigned char* _lastOctreePacket;
|
char* _lastOctreePayload = nullptr;
|
||||||
unsigned int _lastOctreePacketLength;
|
unsigned int _lastOctreePacketLength;
|
||||||
int _duplicatePacketCount;
|
int _duplicatePacketCount;
|
||||||
quint64 _firstSuppressedPacket;
|
quint64 _firstSuppressedPacket;
|
||||||
|
@ -154,7 +150,7 @@ private:
|
||||||
OCTREE_PACKET_SEQUENCE _sequenceNumber;
|
OCTREE_PACKET_SEQUENCE _sequenceNumber;
|
||||||
|
|
||||||
quint64 _lastRootTimestamp;
|
quint64 _lastRootTimestamp;
|
||||||
|
|
||||||
PacketType::Value _myPacketType;
|
PacketType::Value _myPacketType;
|
||||||
bool _isShuttingDown;
|
bool _isShuttingDown;
|
||||||
|
|
||||||
|
|
|
@ -13,13 +13,11 @@
|
||||||
#include "SentPacketHistory.h"
|
#include "SentPacketHistory.h"
|
||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SentPacketHistory::SentPacketHistory(int size)
|
SentPacketHistory::SentPacketHistory(int size)
|
||||||
: _sentPackets(size),
|
: _sentPackets(size),
|
||||||
_newestSequenceNumber(std::numeric_limits<uint16_t>::max())
|
_newestSequenceNumber(std::numeric_limits<uint16_t>::max())
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SentPacketHistory::packetSent(uint16_t sequenceNumber, const QByteArray& packet) {
|
void SentPacketHistory::packetSent(uint16_t sequenceNumber, const QByteArray& packet) {
|
||||||
|
|
|
@ -22,11 +22,11 @@ class SentPacketHistory {
|
||||||
public:
|
public:
|
||||||
SentPacketHistory(int size = MAX_REASONABLE_SEQUENCE_GAP);
|
SentPacketHistory(int size = MAX_REASONABLE_SEQUENCE_GAP);
|
||||||
|
|
||||||
void packetSent(uint16_t sequenceNumber, const QByteArray& packet);
|
void packetSent(uint16_t sequenceNumber, const NLPacket& packet);
|
||||||
const QByteArray* getPacket(uint16_t sequenceNumber) const;
|
const QByteArray* getPacket(uint16_t sequenceNumber) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RingBufferHistory<QByteArray> _sentPackets; // circular buffer
|
RingBufferHistory<NLPacket> _sentPackets; // circular buffer
|
||||||
|
|
||||||
uint16_t _newestSequenceNumber;
|
uint16_t _newestSequenceNumber;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue