mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-16 07:39:11 +02:00
repairs to octree packet receiving in interface
This commit is contained in:
parent
264f39fa59
commit
d990420565
18 changed files with 179 additions and 218 deletions
|
@ -3910,12 +3910,12 @@ void Application::nodeKilled(SharedNodePointer node) {
|
|||
DependencyManager::get<AvatarManager>()->clearOtherAvatars();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::trackIncomingOctreePacket(const QByteArray& packet, const SharedNodePointer& sendingNode, bool wasStatsPacket) {
|
||||
|
||||
void Application::trackIncomingOctreePacket(NLPacket& packet, SharedNodePointer sendingNode, bool wasStatsPacket) {
|
||||
|
||||
// Attempt to identify the sender from its address.
|
||||
if (sendingNode) {
|
||||
QUuid nodeUUID = sendingNode->getUUID();
|
||||
const QUuid& nodeUUID = sendingNode->getUUID();
|
||||
|
||||
// now that we know the node ID, let's add these stats to the stats for that node...
|
||||
_octreeSceneStatsLock.lockForWrite();
|
||||
|
@ -3927,7 +3927,7 @@ void Application::trackIncomingOctreePacket(const QByteArray& packet, const Shar
|
|||
}
|
||||
}
|
||||
|
||||
int Application::processOctreeStats(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode) {
|
||||
int Application::processOctreeStats(NLPacket& packet, SharedNodePointer sendingNode) {
|
||||
// But, also identify the sender, and keep track of the contained jurisdiction root for this server
|
||||
|
||||
// parse the incoming stats datas stick it in a temporary object for now, while we
|
||||
|
@ -3941,10 +3941,10 @@ int Application::processOctreeStats(QSharedPointer<NLPacket> packet, SharedNodeP
|
|||
_octreeSceneStatsLock.lockForWrite();
|
||||
if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) {
|
||||
octreeStats = &_octreeServerSceneStats[nodeUUID];
|
||||
statsMessageLength = octreeStats->unpackFromPacket(*packet);
|
||||
statsMessageLength = octreeStats->unpackFromPacket(packet);
|
||||
} else {
|
||||
OctreeSceneStats temp;
|
||||
statsMessageLength = temp.unpackFromPacket(*packet);
|
||||
statsMessageLength = temp.unpackFromPacket(packet);
|
||||
octreeStats = &temp;
|
||||
}
|
||||
_octreeSceneStatsLock.unlock();
|
||||
|
|
|
@ -612,8 +612,8 @@ private:
|
|||
StDev _idleLoopStdev;
|
||||
float _idleLoopMeasuredJitter;
|
||||
|
||||
int processOctreeStats(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode);
|
||||
void trackIncomingOctreePacket(const QByteArray& packet, const SharedNodePointer& sendingNode, bool wasStatsPacket);
|
||||
int processOctreeStats(NLPacket& packet, SharedNodePointer sendingNode);
|
||||
void trackIncomingOctreePacket(NLPacket& packet, SharedNodePointer sendingNode, bool wasStatsPacket);
|
||||
|
||||
NodeToJurisdictionMap _entityServerJurisdictions;
|
||||
NodeToOctreeSceneStats _octreeServerSceneStats;
|
||||
|
|
|
@ -28,7 +28,7 @@ OctreePacketProcessor::OctreePacketProcessor() {
|
|||
}
|
||||
|
||||
void OctreePacketProcessor::handleOctreePacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode) {
|
||||
queueReceivedPacket(senderNode, packet);
|
||||
queueReceivedPacket(packet, senderNode);
|
||||
}
|
||||
|
||||
void OctreePacketProcessor::processPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode) {
|
||||
|
@ -41,8 +41,6 @@ void OctreePacketProcessor::processPacket(QSharedPointer<NLPacket> packet, Share
|
|||
qDebug("OctreePacketProcessor::processPacket() packets to process=%d", packetsToProcessCount());
|
||||
}
|
||||
|
||||
int messageLength = packet->getSizeUsed();
|
||||
|
||||
Application* app = Application::getInstance();
|
||||
bool wasStatsPacket = false;
|
||||
|
||||
|
@ -52,60 +50,61 @@ void OctreePacketProcessor::processPacket(QSharedPointer<NLPacket> packet, Share
|
|||
// immediately following them inside the same packet. So, we process the PacketType_OCTREE_STATS first
|
||||
// then process any remaining bytes as if it was another packet
|
||||
if (octreePacketType == PacketType::OctreeStats) {
|
||||
int statsMessageLength = app->processOctreeStats(packet, sendingNode);
|
||||
wasStatsPacket = true;
|
||||
if (messageLength > statsMessageLength) {
|
||||
mutablePacket = mutablePacket.mid(statsMessageLength);
|
||||
int statsMessageLength = app->processOctreeStats(*packet, sendingNode);
|
||||
|
||||
// TODO: this does not look correct, the goal is to test the packet version for the piggyback, but
|
||||
// this is testing the version and hash of the original packet
|
||||
if (!DependencyManager::get<NodeList>()->packetVersionAndHashMatch(packet)) {
|
||||
return; // bail since piggyback data doesn't match our versioning
|
||||
}
|
||||
wasStatsPacket = true;
|
||||
int piggybackBytes = packet->getSizeUsed() - statsMessageLength;
|
||||
|
||||
if (piggybackBytes) {
|
||||
// construct a new packet from the piggybacked one
|
||||
std::unique_ptr<char> buffer = std::unique_ptr<char>(new char[piggybackBytes]);
|
||||
memcpy(buffer.get(), packet->getPayload() + statsMessageLength, piggybackBytes);
|
||||
|
||||
auto newPacket = NLPacket::fromReceivedPacket(std::move(buffer), piggybackBytes, packet->getSenderSockAddr());
|
||||
packet = QSharedPointer<NLPacket>(newPacket.release());
|
||||
} else {
|
||||
// Note... stats packets don't have sequence numbers, so we don't want to send those to trackIncomingVoxelPacket()
|
||||
return; // bail since no piggyback data
|
||||
}
|
||||
} // fall through to piggyback message
|
||||
|
||||
voxelPacketType = packetTypeForPacket(mutablePacket);
|
||||
PacketVersion packetVersion = mutablePacket[1];
|
||||
PacketVersion expectedVersion = versionForPacketType(voxelPacketType);
|
||||
PacketType::Value packetType = packet->getType();
|
||||
|
||||
// check version of piggyback packet against expected version
|
||||
if (packetVersion != expectedVersion) {
|
||||
if (packetType != versionForPacketType(packet->getType())) {
|
||||
static QMultiMap<QUuid, PacketType::Value> versionDebugSuppressMap;
|
||||
|
||||
QUuid senderUUID = uuidFromPacketHeader(packet);
|
||||
if (!versionDebugSuppressMap.contains(senderUUID, voxelPacketType)) {
|
||||
qDebug() << "Packet version mismatch on" << voxelPacketType << "- Sender"
|
||||
<< senderUUID << "sent" << (int)packetVersion << "but"
|
||||
<< (int)expectedVersion << "expected.";
|
||||
const QUuid& senderUUID = packet->getSourceID();
|
||||
if (!versionDebugSuppressMap.contains(senderUUID, packet->getType())) {
|
||||
|
||||
qDebug() << "Packet version mismatch on" << packetType << "- Sender"
|
||||
<< senderUUID << "sent" << (int) packetType << "but"
|
||||
<< (int) versionForPacketType(packetType) << "expected.";
|
||||
|
||||
emit packetVersionMismatch();
|
||||
|
||||
versionDebugSuppressMap.insert(senderUUID, voxelPacketType);
|
||||
versionDebugSuppressMap.insert(senderUUID, packetType);
|
||||
}
|
||||
return; // bail since piggyback version doesn't match
|
||||
}
|
||||
|
||||
app->trackIncomingOctreePacket(mutablePacket, sendingNode, wasStatsPacket);
|
||||
app->trackIncomingOctreePacket(*packet, sendingNode, wasStatsPacket);
|
||||
|
||||
switch(voxelPacketType) {
|
||||
switch(packetType) {
|
||||
case PacketType::EntityErase: {
|
||||
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
|
||||
app->_entities.processEraseMessage(mutablePacket, sendingNode);
|
||||
app->_entities.processEraseMessage(*packet, sendingNode);
|
||||
}
|
||||
} break;
|
||||
|
||||
case PacketType::EntityData: {
|
||||
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
|
||||
app->_entities.processDatagram(mutablePacket, sendingNode);
|
||||
app->_entities.processDatagram(*packet, sendingNode);
|
||||
}
|
||||
} break;
|
||||
|
||||
case PacketType::EnvironmentData: {
|
||||
app->_environment.parseData(*sendingNode->getActiveSocket(), mutablePacket);
|
||||
app->_environment.processPacket(*packet);
|
||||
} break;
|
||||
|
||||
default: {
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#include "EntitiesRendererLogging.h"
|
||||
#include "AddressManager.h"
|
||||
|
||||
EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterface* viewState,
|
||||
EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterface* viewState,
|
||||
AbstractScriptingServicesInterface* scriptingServices) :
|
||||
OctreeRenderer(),
|
||||
_wantScripts(wantScripts),
|
||||
|
@ -75,13 +75,13 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf
|
|||
}
|
||||
|
||||
EntityTreeRenderer::~EntityTreeRenderer() {
|
||||
// NOTE: we don't need to delete _entitiesScriptEngine because it is registered with the application and has a
|
||||
// NOTE: we don't need to delete _entitiesScriptEngine because it is registered with the application and has a
|
||||
// signal tied to call it's deleteLater on doneRunning
|
||||
if (_sandboxScriptEngine) {
|
||||
// TODO: consider reworking how _sandboxScriptEngine is managed. It's treated differently than _entitiesScriptEngine
|
||||
// because we don't call registerScriptEngineWithApplicationServices() for it. This implementation is confusing and
|
||||
// potentially error prone because it's not a full fledged ScriptEngine that has been fully connected to the
|
||||
// application. We did this so that scripts that were ill-formed could be evaluated but not execute against the
|
||||
// because we don't call registerScriptEngineWithApplicationServices() for it. This implementation is confusing and
|
||||
// potentially error prone because it's not a full fledged ScriptEngine that has been fully connected to the
|
||||
// application. We did this so that scripts that were ill-formed could be evaluated but not execute against the
|
||||
// application services. But this means it's shutdown behavior is different from other ScriptEngines
|
||||
delete _sandboxScriptEngine;
|
||||
_sandboxScriptEngine = NULL;
|
||||
|
@ -119,7 +119,7 @@ void EntityTreeRenderer::init() {
|
|||
}
|
||||
|
||||
// make sure our "last avatar position" is something other than our current position, so that on our
|
||||
// first chance, we'll check for enter/leave entity events.
|
||||
// first chance, we'll check for enter/leave entity events.
|
||||
_lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3((float)TREE_SCALE);
|
||||
|
||||
connect(entityTree, &EntityTree::deletingEntity, this, &EntityTreeRenderer::deletingEntity, Qt::QueuedConnection);
|
||||
|
@ -138,7 +138,7 @@ void EntityTreeRenderer::scriptContentsAvailable(const QUrl& url, const QString&
|
|||
_waitingOnPreload.remove(url);
|
||||
foreach(EntityItemID entityID, entityIDs) {
|
||||
checkAndCallPreload(entityID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ QScriptValue EntityTreeRenderer::loadEntityScript(const EntityItemID& entityItem
|
|||
}
|
||||
|
||||
|
||||
QString EntityTreeRenderer::loadScriptContents(const QString& scriptMaybeURLorText, bool& isURL, bool& isPending, QUrl& urlOut,
|
||||
QString EntityTreeRenderer::loadScriptContents(const QString& scriptMaybeURLorText, bool& isURL, bool& isPending, QUrl& urlOut,
|
||||
bool& reload) {
|
||||
isPending = false;
|
||||
QUrl url(scriptMaybeURLorText);
|
||||
|
@ -353,7 +353,7 @@ void EntityTreeRenderer::checkEnterLeaveEntities() {
|
|||
|
||||
// Note: at this point we don't need to worry about the tree being locked, because we only deal with
|
||||
// EntityItemIDs from here. The loadEntityScript() method is robust against attempting to load scripts
|
||||
// for entity IDs that no longer exist.
|
||||
// for entity IDs that no longer exist.
|
||||
|
||||
// for all of our previous containing entities, if they are no longer containing then send them a leave event
|
||||
foreach(const EntityItemID& entityID, _currentEntitiesInside) {
|
||||
|
@ -400,7 +400,7 @@ void EntityTreeRenderer::leaveAllEntities() {
|
|||
_currentEntitiesInside.clear();
|
||||
|
||||
// make sure our "last avatar position" is something other than our current position, so that on our
|
||||
// first chance, we'll check for enter/leave entity events.
|
||||
// first chance, we'll check for enter/leave entity events.
|
||||
_lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3((float)TREE_SCALE);
|
||||
}
|
||||
}
|
||||
|
@ -513,7 +513,7 @@ const FBXGeometry* EntityTreeRenderer::getGeometryForEntity(EntityItemPointer en
|
|||
const FBXGeometry* result = NULL;
|
||||
|
||||
if (entityItem->getType() == EntityTypes::Model) {
|
||||
std::shared_ptr<RenderableModelEntityItem> modelEntityItem =
|
||||
std::shared_ptr<RenderableModelEntityItem> modelEntityItem =
|
||||
std::dynamic_pointer_cast<RenderableModelEntityItem>(entityItem);
|
||||
assert(modelEntityItem); // we need this!!!
|
||||
Model* model = modelEntityItem->getModel(this);
|
||||
|
@ -527,7 +527,7 @@ const FBXGeometry* EntityTreeRenderer::getGeometryForEntity(EntityItemPointer en
|
|||
const Model* EntityTreeRenderer::getModelForEntityItem(EntityItemPointer entityItem) {
|
||||
const Model* result = NULL;
|
||||
if (entityItem->getType() == EntityTypes::Model) {
|
||||
std::shared_ptr<RenderableModelEntityItem> modelEntityItem =
|
||||
std::shared_ptr<RenderableModelEntityItem> modelEntityItem =
|
||||
std::dynamic_pointer_cast<RenderableModelEntityItem>(entityItem);
|
||||
result = modelEntityItem->getModel(this);
|
||||
}
|
||||
|
@ -538,7 +538,7 @@ const FBXGeometry* EntityTreeRenderer::getCollisionGeometryForEntity(EntityItemP
|
|||
const FBXGeometry* result = NULL;
|
||||
|
||||
if (entityItem->getType() == EntityTypes::Model) {
|
||||
std::shared_ptr<RenderableModelEntityItem> modelEntityItem =
|
||||
std::shared_ptr<RenderableModelEntityItem> modelEntityItem =
|
||||
std::dynamic_pointer_cast<RenderableModelEntityItem>(entityItem);
|
||||
if (modelEntityItem->hasCompoundShapeURL()) {
|
||||
Model* model = modelEntityItem->getModel(this);
|
||||
|
@ -678,20 +678,20 @@ float EntityTreeRenderer::getSizeScale() const {
|
|||
return _viewState->getSizeScale();
|
||||
}
|
||||
|
||||
int EntityTreeRenderer::getBoundaryLevelAdjust() const {
|
||||
int EntityTreeRenderer::getBoundaryLevelAdjust() const {
|
||||
return _viewState->getBoundaryLevelAdjust();
|
||||
}
|
||||
|
||||
|
||||
void EntityTreeRenderer::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) {
|
||||
static_cast<EntityTree*>(_tree)->processEraseMessage(dataByteArray, sourceNode);
|
||||
void EntityTreeRenderer::processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode) {
|
||||
static_cast<EntityTree*>(_tree)->processEraseMessage(packet, sourceNode);
|
||||
}
|
||||
|
||||
Model* EntityTreeRenderer::allocateModel(const QString& url, const QString& collisionUrl) {
|
||||
Model* model = NULL;
|
||||
// Make sure we only create and delete models on the thread that owns the EntityTreeRenderer
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "allocateModel", Qt::BlockingQueuedConnection,
|
||||
QMetaObject::invokeMethod(this, "allocateModel", Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(Model*, model),
|
||||
Q_ARG(const QString&, url));
|
||||
|
||||
|
@ -715,7 +715,7 @@ Model* EntityTreeRenderer::updateModel(Model* original, const QString& newUrl, c
|
|||
|
||||
// Before we do any creating or deleting, make sure we're on our renderer thread
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "updateModel", Qt::BlockingQueuedConnection,
|
||||
QMetaObject::invokeMethod(this, "updateModel", Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(Model*, model),
|
||||
Q_ARG(Model*, original),
|
||||
Q_ARG(const QString&, newUrl));
|
||||
|
@ -756,7 +756,7 @@ void EntityTreeRenderer::deleteReleasedModels() {
|
|||
}
|
||||
}
|
||||
|
||||
RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
||||
RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
||||
bool precisionPicking) {
|
||||
RayToEntityIntersectionResult result;
|
||||
if (_tree) {
|
||||
|
@ -764,8 +764,8 @@ RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(cons
|
|||
|
||||
OctreeElement* element;
|
||||
EntityItemPointer intersectedEntity = NULL;
|
||||
result.intersects = entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face,
|
||||
(void**)&intersectedEntity, lockType, &result.accurate,
|
||||
result.intersects = entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face,
|
||||
(void**)&intersectedEntity, lockType, &result.accurate,
|
||||
precisionPicking);
|
||||
if (result.intersects && intersectedEntity) {
|
||||
result.entityID = intersectedEntity->getEntityItemID();
|
||||
|
@ -778,15 +778,15 @@ RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(cons
|
|||
}
|
||||
|
||||
void EntityTreeRenderer::connectSignalsToSlots(EntityScriptingInterface* entityScriptingInterface) {
|
||||
connect(this, &EntityTreeRenderer::mousePressOnEntity, entityScriptingInterface,
|
||||
connect(this, &EntityTreeRenderer::mousePressOnEntity, entityScriptingInterface,
|
||||
[=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId){
|
||||
entityScriptingInterface->mousePressOnEntity(intersection.entityID, MouseEvent(*event, deviceId));
|
||||
});
|
||||
connect(this, &EntityTreeRenderer::mouseMoveOnEntity, entityScriptingInterface,
|
||||
connect(this, &EntityTreeRenderer::mouseMoveOnEntity, entityScriptingInterface,
|
||||
[=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId) {
|
||||
entityScriptingInterface->mouseMoveOnEntity(intersection.entityID, MouseEvent(*event, deviceId));
|
||||
});
|
||||
connect(this, &EntityTreeRenderer::mouseReleaseOnEntity, entityScriptingInterface,
|
||||
connect(this, &EntityTreeRenderer::mouseReleaseOnEntity, entityScriptingInterface,
|
||||
[=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId) {
|
||||
entityScriptingInterface->mouseReleaseOnEntity(intersection.entityID, MouseEvent(*event, deviceId));
|
||||
});
|
||||
|
@ -966,7 +966,7 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event, unsigned int deviceI
|
|||
|
||||
} else {
|
||||
// handle the hover logic...
|
||||
// if we were previously hovering over an entity, and we're no longer hovering over any entity then we need to
|
||||
// if we were previously hovering over an entity, and we're no longer hovering over any entity then we need to
|
||||
// send the hover leave for our previous entity
|
||||
if (!_currentHoverOverEntityID.isInvalidID()) {
|
||||
emit hoverLeaveEntity(_currentHoverOverEntityID, MouseEvent(*event, deviceID));
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
class EntityTreeRenderer : public OctreeRenderer, public EntityItemFBXService, public ScriptUser {
|
||||
Q_OBJECT
|
||||
public:
|
||||
EntityTreeRenderer(bool wantScripts, AbstractViewStateInterface* viewState,
|
||||
EntityTreeRenderer(bool wantScripts, AbstractViewStateInterface* viewState,
|
||||
AbstractScriptingServicesInterface* scriptingServices);
|
||||
virtual ~EntityTreeRenderer();
|
||||
|
||||
|
@ -55,7 +55,7 @@ public:
|
|||
|
||||
EntityTree* getTree() { return static_cast<EntityTree*>(_tree); }
|
||||
|
||||
void processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode);
|
||||
void processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode);
|
||||
|
||||
virtual void init();
|
||||
virtual void render(RenderArgs* renderArgs) override;
|
||||
|
@ -71,7 +71,7 @@ public:
|
|||
Q_INVOKABLE Model* allocateModel(const QString& url, const QString& collisionUrl);
|
||||
|
||||
/// if a renderable entity item needs to update the URL of a model, we will handle that for the entity
|
||||
Q_INVOKABLE Model* updateModel(Model* original, const QString& newUrl, const QString& collisionUrl);
|
||||
Q_INVOKABLE Model* updateModel(Model* original, const QString& newUrl, const QString& collisionUrl);
|
||||
|
||||
/// if a renderable entity item is done with a model, it should return it to us
|
||||
void releaseModel(Model* model);
|
||||
|
@ -136,7 +136,7 @@ private:
|
|||
|
||||
QList<Model*> _releasedModels;
|
||||
void renderProxies(EntityItemPointer entity, RenderArgs* args);
|
||||
RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
||||
RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
||||
bool precisionPicking);
|
||||
|
||||
EntityItemID _currentHoverOverEntityID;
|
||||
|
|
|
@ -128,8 +128,8 @@ void EntityItemProperties::setSittingPoints(const QVector<SittingPoint>& sitting
|
|||
}
|
||||
}
|
||||
|
||||
bool EntityItemProperties::animationSettingsChanged() const {
|
||||
return _animationSettingsChanged;
|
||||
bool EntityItemProperties::animationSettingsChanged() const {
|
||||
return _animationSettingsChanged;
|
||||
}
|
||||
|
||||
void EntityItemProperties::setAnimationSettings(const QString& value) {
|
||||
|
@ -900,11 +900,14 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType::Value command, Ent
|
|||
//
|
||||
// TODO: Implement support for script and visible properties.
|
||||
//
|
||||
bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int bytesToRead, int& processedBytes,
|
||||
bool EntityItemProperties::decodeEntityEditPacket(NLPacket& packet, int& processedBytes,
|
||||
EntityItemID& entityID, EntityItemProperties& properties) {
|
||||
bool valid = false;
|
||||
|
||||
|
||||
const unsigned char* data = reinterpret_cast<const unsigned char*>(packet.getPayload());
|
||||
const unsigned char* dataAt = data;
|
||||
|
||||
int bytesToRead = packet.getSizeUsed();
|
||||
processedBytes = 0;
|
||||
|
||||
// the first part of the data is an octcode, this is a required element of the edit packet format, but we don't
|
||||
|
|
|
@ -179,8 +179,8 @@ public:
|
|||
|
||||
static bool encodeEraseEntityMessage(const EntityItemID& entityItemID, QByteArray& buffer);
|
||||
|
||||
static bool decodeEntityEditPacket(const unsigned char* data, int bytesToRead, int& processedBytes,
|
||||
EntityItemID& entityID, EntityItemProperties& properties);
|
||||
static bool decodeEntityEditPacket(NLPacket& packet, int& processedBytes,
|
||||
EntityItemID& entityID, EntityItemProperties& properties);
|
||||
|
||||
bool glowLevelChanged() const { return _glowLevelChanged; }
|
||||
bool localRenderAlphaChanged() const { return _localRenderAlphaChanged; }
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "LogHandler.h"
|
||||
|
||||
|
||||
EntityTree::EntityTree(bool shouldReaverage) :
|
||||
EntityTree::EntityTree(bool shouldReaverage) :
|
||||
Octree(shouldReaverage),
|
||||
_fbxService(NULL),
|
||||
_simulation(NULL)
|
||||
|
@ -568,8 +568,8 @@ EntityItemPointer EntityTree::findEntityByEntityItemID(const EntityItemID& entit
|
|||
return foundEntity;
|
||||
}
|
||||
|
||||
int EntityTree::processEditPacketData(PacketType::Value packetType, const unsigned char* packetData, int packetLength,
|
||||
const unsigned char* editData, int maxLength, const SharedNodePointer& senderNode) {
|
||||
int EntityTree::processEditPacketData(NLPacket& packet, const unsigned char* editData, int maxLength,
|
||||
const SharedNodePointer& senderNode) {
|
||||
|
||||
if (!getIsServer()) {
|
||||
qCDebug(entities) << "UNEXPECTED!!! processEditPacketData() should only be called on a server tree.";
|
||||
|
@ -578,9 +578,9 @@ int EntityTree::processEditPacketData(PacketType::Value packetType, const unsign
|
|||
|
||||
int processedBytes = 0;
|
||||
// we handle these types of "edit" packets
|
||||
switch (packetType) {
|
||||
switch (packet.getType()) {
|
||||
case PacketType::EntityErase: {
|
||||
QByteArray dataByteArray((const char*)editData, maxLength);
|
||||
QByteArray dataByteArray = QByteArray::fromRawData(reinterpret_cast<const char*>(editData), maxLength);
|
||||
processedBytes = processEraseMessageDetails(dataByteArray, senderNode);
|
||||
break;
|
||||
}
|
||||
|
@ -598,8 +598,8 @@ int EntityTree::processEditPacketData(PacketType::Value packetType, const unsign
|
|||
EntityItemID entityItemID;
|
||||
EntityItemProperties properties;
|
||||
startDecode = usecTimestampNow();
|
||||
bool validEditPacket = EntityItemProperties::decodeEntityEditPacket(editData, maxLength,
|
||||
processedBytes, entityItemID, properties);
|
||||
bool validEditPacket = EntityItemProperties::decodeEntityEditPacket(packet, processedBytes,
|
||||
entityItemID, properties);
|
||||
endDecode = usecTimestampNow();
|
||||
|
||||
// If we got a valid edit packet, then it could be a new entity or it could be an update to
|
||||
|
@ -609,7 +609,7 @@ int EntityTree::processEditPacketData(PacketType::Value packetType, const unsign
|
|||
startLookup = usecTimestampNow();
|
||||
EntityItemPointer existingEntity = findEntityByEntityItemID(entityItemID);
|
||||
endLookup = usecTimestampNow();
|
||||
if (existingEntity && packetType == PacketType::EntityEdit) {
|
||||
if (existingEntity && packet.getType() == PacketType::EntityEdit) {
|
||||
// if the EntityItem exists, then update it
|
||||
startLogging = usecTimestampNow();
|
||||
if (wantEditLogging()) {
|
||||
|
@ -623,7 +623,7 @@ int EntityTree::processEditPacketData(PacketType::Value packetType, const unsign
|
|||
existingEntity->markAsChangedOnServer();
|
||||
endUpdate = usecTimestampNow();
|
||||
_totalUpdates++;
|
||||
} else if (packetType == PacketType::EntityAdd) {
|
||||
} else if (packet.getType() == PacketType::EntityAdd) {
|
||||
if (senderNode->getCanRez()) {
|
||||
// this is a new entity... assign a new entityID
|
||||
properties.setCreated(properties.getLastEdited());
|
||||
|
@ -651,7 +651,7 @@ int EntityTree::processEditPacketData(PacketType::Value packetType, const unsign
|
|||
} else {
|
||||
static QString repeatedMessage =
|
||||
LogHandler::getInstance().addRepeatedMessageRegex("^Add or Edit failed.*");
|
||||
qCDebug(entities) << "Add or Edit failed." << packetType << existingEntity.get();
|
||||
qCDebug(entities) << "Add or Edit failed." << packet.getType() << existingEntity.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -854,45 +854,26 @@ void EntityTree::forgetEntitiesDeletedBefore(quint64 sinceTime) {
|
|||
|
||||
|
||||
// TODO: consider consolidating processEraseMessageDetails() and processEraseMessage()
|
||||
int EntityTree::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) {
|
||||
int EntityTree::processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode) {
|
||||
lockForWrite();
|
||||
const unsigned char* packetData = (const unsigned char*)dataByteArray.constData();
|
||||
const unsigned char* dataAt = packetData;
|
||||
size_t packetLength = dataByteArray.size();
|
||||
|
||||
size_t numBytesPacketHeader = numBytesForPacketHeader(dataByteArray);
|
||||
size_t processedBytes = numBytesPacketHeader;
|
||||
dataAt += numBytesPacketHeader;
|
||||
packet.seek(sizeof(OCTREE_PACKET_FLAGS) + sizeof(OCTREE_PACKET_SEQUENCE) + sizeof(OCTREE_PACKET_SENT_TIME));
|
||||
|
||||
dataAt += sizeof(OCTREE_PACKET_FLAGS);
|
||||
processedBytes += sizeof(OCTREE_PACKET_FLAGS);
|
||||
|
||||
dataAt += sizeof(OCTREE_PACKET_SEQUENCE);
|
||||
processedBytes += sizeof(OCTREE_PACKET_SEQUENCE);
|
||||
|
||||
dataAt += sizeof(OCTREE_PACKET_SENT_TIME);
|
||||
processedBytes += sizeof(OCTREE_PACKET_SENT_TIME);
|
||||
|
||||
uint16_t numberOfIds = 0; // placeholder for now
|
||||
memcpy(&numberOfIds, dataAt, sizeof(numberOfIds));
|
||||
dataAt += sizeof(numberOfIds);
|
||||
processedBytes += sizeof(numberOfIds);
|
||||
|
||||
if (numberOfIds > 0) {
|
||||
uint16_t numberOfIDs = 0; // placeholder for now
|
||||
packet.readPrimitive(&numberOfIDs);
|
||||
|
||||
if (numberOfIDs > 0) {
|
||||
QSet<EntityItemID> entityItemIDsToDelete;
|
||||
|
||||
for (size_t i = 0; i < numberOfIds; i++) {
|
||||
for (size_t i = 0; i < numberOfIDs; i++) {
|
||||
|
||||
if (processedBytes + NUM_BYTES_RFC4122_UUID > packetLength) {
|
||||
if (NUM_BYTES_RFC4122_UUID > packet.bytesAvailable()) {
|
||||
qCDebug(entities) << "EntityTree::processEraseMessage().... bailing because not enough bytes in buffer";
|
||||
break; // bail to prevent buffer overflow
|
||||
}
|
||||
|
||||
QByteArray encodedID = dataByteArray.mid(processedBytes, NUM_BYTES_RFC4122_UUID);
|
||||
QUuid entityID = QUuid::fromRfc4122(encodedID);
|
||||
dataAt += encodedID.size();
|
||||
processedBytes += encodedID.size();
|
||||
|
||||
QUuid entityID = QUuid::fromRfc4122(packet.read(NUM_BYTES_RFC4122_UUID));
|
||||
|
||||
EntityItemID entityItemID(entityID);
|
||||
entityItemIDsToDelete << entityItemID;
|
||||
|
||||
|
@ -904,7 +885,7 @@ int EntityTree::processEraseMessage(const QByteArray& dataByteArray, const Share
|
|||
deleteEntities(entityItemIDsToDelete, true, true);
|
||||
}
|
||||
unlock();
|
||||
return processedBytes;
|
||||
return packet.pos();
|
||||
}
|
||||
|
||||
// This version skips over the header
|
||||
|
|
|
@ -66,8 +66,8 @@ public:
|
|||
virtual bool canProcessVersion(PacketVersion thisVersion) const
|
||||
{ return thisVersion >= VERSION_ENTITIES_USE_METERS_AND_RADIANS; }
|
||||
virtual bool handlesEditPacketType(PacketType::Value packetType) const;
|
||||
virtual int processEditPacketData(PacketType::Value packetType, const unsigned char* packetData, int packetLength,
|
||||
const unsigned char* editData, int maxLength, const SharedNodePointer& senderNode);
|
||||
virtual int processEditPacketData(NLPacket& packet, const unsigned char* editData, int maxLength,
|
||||
const SharedNodePointer& senderNode);
|
||||
|
||||
virtual bool rootElementHasData() const { return true; }
|
||||
|
||||
|
@ -133,8 +133,8 @@ public:
|
|||
bool& hasMore);
|
||||
void forgetEntitiesDeletedBefore(quint64 sinceTime);
|
||||
|
||||
int processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode);
|
||||
int processEraseMessageDetails(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode);
|
||||
int processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode);
|
||||
int processEraseMessageDetails(const QByteArray& buffer, const SharedNodePointer& sourceNode);
|
||||
|
||||
EntityItemFBXService* getFBXService() const { return _fbxService; }
|
||||
void setFBXService(EntityItemFBXService* service) { _fbxService = service; }
|
||||
|
@ -186,9 +186,9 @@ public:
|
|||
virtual quint64 getAverageLoggingTime() const { return _totalEditMessages == 0 ? 0 : _totalLoggingTime / _totalEditMessages; }
|
||||
|
||||
void trackIncomingEntityLastEdited(quint64 lastEditedTime, int bytesRead);
|
||||
quint64 getAverageEditDeltas() const
|
||||
quint64 getAverageEditDeltas() const
|
||||
{ return _totalTrackedEdits == 0 ? 0 : _totalEditDeltas / _totalTrackedEdits; }
|
||||
quint64 getAverageEditBytes() const
|
||||
quint64 getAverageEditBytes() const
|
||||
{ return _totalTrackedEdits == 0 ? 0 : _totalEditBytes / _totalTrackedEdits; }
|
||||
quint64 getMaxEditDelta() const { return _maxEditDelta; }
|
||||
quint64 getTotalTrackedEdits() const { return _totalTrackedEdits; }
|
||||
|
|
|
@ -40,6 +40,6 @@ void EntityTreeHeadlessViewer::update() {
|
|||
}
|
||||
}
|
||||
|
||||
void EntityTreeHeadlessViewer::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) {
|
||||
static_cast<EntityTree*>(_tree)->processEraseMessage(dataByteArray, sourceNode);
|
||||
void EntityTreeHeadlessViewer::processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode) {
|
||||
static_cast<EntityTree*>(_tree)->processEraseMessage(packet, sourceNode);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
|
||||
EntityTree* getTree() { return (EntityTree*)_tree; }
|
||||
|
||||
void processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode);
|
||||
void processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode);
|
||||
|
||||
virtual void init();
|
||||
|
||||
|
|
|
@ -229,12 +229,12 @@ public:
|
|||
// own definition. Implement these to allow your octree based server to support editing
|
||||
virtual bool getWantSVOfileVersions() const { return false; }
|
||||
virtual PacketType::Value expectedDataPacketType() const { return PacketType::Unknown; }
|
||||
virtual bool canProcessVersion(PacketVersion thisVersion) const {
|
||||
virtual bool canProcessVersion(PacketVersion thisVersion) const {
|
||||
return thisVersion == versionForPacketType(expectedDataPacketType()); }
|
||||
virtual PacketVersion expectedVersion() const { return versionForPacketType(expectedDataPacketType()); }
|
||||
virtual bool handlesEditPacketType(PacketType::Value packetType) const { return false; }
|
||||
virtual int processEditPacketData(PacketType::Value packetType, const unsigned char* packetData, int packetLength,
|
||||
const unsigned char* editData, int maxLength, const SharedNodePointer& sourceNode) { return 0; }
|
||||
virtual int processEditPacketData(NLPacket& packet, const unsigned char* editData, int maxLength,
|
||||
const SharedNodePointer& sourceNode) { return 0; }
|
||||
|
||||
virtual bool recurseChildrenWithData() const { return true; }
|
||||
virtual bool rootElementHasData() const { return false; }
|
||||
|
@ -304,16 +304,16 @@ public:
|
|||
} lockType;
|
||||
|
||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
OctreeElement*& node, float& distance, BoxFace& face,
|
||||
OctreeElement*& node, float& distance, BoxFace& face,
|
||||
void** intersectedObject = NULL,
|
||||
Octree::lockType lockType = Octree::TryLock,
|
||||
bool* accurateResult = NULL,
|
||||
Octree::lockType lockType = Octree::TryLock,
|
||||
bool* accurateResult = NULL,
|
||||
bool precisionPicking = false);
|
||||
|
||||
bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration, void** penetratedObject = NULL,
|
||||
bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration, void** penetratedObject = NULL,
|
||||
Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL);
|
||||
|
||||
bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration,
|
||||
bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration,
|
||||
Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL);
|
||||
|
||||
/// \param cube query cube in world-frame (meters)
|
||||
|
@ -323,7 +323,7 @@ public:
|
|||
/// \param point query point in world-frame (meters)
|
||||
/// \param lockType how to lock the tree (Lock, TryLock, NoLock)
|
||||
/// \param[out] accurateResult pointer to output result, will be set "true" or "false" if non-null
|
||||
OctreeElement* getElementEnclosingPoint(const glm::vec3& point,
|
||||
OctreeElement* getElementEnclosingPoint(const glm::vec3& point,
|
||||
Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL);
|
||||
|
||||
// Note: this assumes the fileFormat is the HIO individual voxels code files
|
||||
|
@ -411,7 +411,7 @@ protected:
|
|||
|
||||
QReadWriteLock _lock;
|
||||
|
||||
bool _isViewing;
|
||||
bool _isViewing;
|
||||
bool _isServer;
|
||||
};
|
||||
|
||||
|
|
|
@ -40,15 +40,15 @@ OctreeRenderer::~OctreeRenderer() {
|
|||
}
|
||||
}
|
||||
|
||||
void OctreeRenderer::setTree(Octree* newTree) {
|
||||
void OctreeRenderer::setTree(Octree* newTree) {
|
||||
if (_tree && _managedTree) {
|
||||
delete _tree;
|
||||
_managedTree = false;
|
||||
}
|
||||
_tree = newTree;
|
||||
_tree = newTree;
|
||||
}
|
||||
|
||||
void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) {
|
||||
void OctreeRenderer::processDatagram(NLPacket& packet, SharedNodePointer sourceNode) {
|
||||
bool extraDebugging = false;
|
||||
|
||||
if (extraDebugging) {
|
||||
|
@ -61,30 +61,21 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar
|
|||
}
|
||||
|
||||
bool showTimingDetails = false; // Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram()",showTimingDetails);
|
||||
PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram()", showTimingDetails);
|
||||
|
||||
unsigned int packetLength = dataByteArray.size();
|
||||
PacketType::Value command = packetTypeForPacket(dataByteArray);
|
||||
unsigned int numBytesPacketHeader = numBytesForPacketHeader(dataByteArray);
|
||||
QUuid sourceUUID = uuidFromPacketHeader(dataByteArray);
|
||||
PacketType::Value expectedType = getExpectedPacketType();
|
||||
// packetVersion is the second byte
|
||||
PacketVersion packetVersion = dataByteArray[1];
|
||||
|
||||
if(command == expectedType) {
|
||||
if (packet.getType() == getExpectedPacketType()) {
|
||||
PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram expected PacketType", showTimingDetails);
|
||||
// if we are getting inbound packets, then our tree is also viewing, and we should remember that fact.
|
||||
_tree->setIsViewing(true);
|
||||
|
||||
const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(dataByteArray.data()) + numBytesPacketHeader;
|
||||
OCTREE_PACKET_FLAGS flags;
|
||||
packet.readPrimitive(&flags);
|
||||
|
||||
OCTREE_PACKET_SEQUENCE sequence;
|
||||
packet.readPrimitive(&sequence);
|
||||
|
||||
OCTREE_PACKET_FLAGS flags = (*(OCTREE_PACKET_FLAGS*)(dataAt));
|
||||
dataAt += sizeof(OCTREE_PACKET_FLAGS);
|
||||
OCTREE_PACKET_SEQUENCE sequence = (*(OCTREE_PACKET_SEQUENCE*)dataAt);
|
||||
dataAt += sizeof(OCTREE_PACKET_SEQUENCE);
|
||||
|
||||
OCTREE_PACKET_SENT_TIME sentAt = (*(OCTREE_PACKET_SENT_TIME*)dataAt);
|
||||
dataAt += sizeof(OCTREE_PACKET_SENT_TIME);
|
||||
OCTREE_PACKET_SENT_TIME sentAt;
|
||||
packet.readPrimitive(&sentAt);
|
||||
|
||||
bool packetIsColored = oneAtBit(flags, PACKET_IS_COLOR_BIT);
|
||||
bool packetIsCompressed = oneAtBit(flags, PACKET_IS_COMPRESSED_BIT);
|
||||
|
@ -94,13 +85,12 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar
|
|||
int flightTime = arrivedAt - sentAt + clockSkew;
|
||||
|
||||
OCTREE_PACKET_INTERNAL_SECTION_SIZE sectionLength = 0;
|
||||
unsigned int dataBytes = packetLength - (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE);
|
||||
|
||||
if (extraDebugging) {
|
||||
qCDebug(octree, "OctreeRenderer::processDatagram() ... Got Packet Section"
|
||||
" color:%s compressed:%s sequence: %u flight:%d usec size:%u data:%u",
|
||||
" color:%s compressed:%s sequence: %u flight:%d usec size:%lld data:%lld",
|
||||
debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed),
|
||||
sequence, flightTime, packetLength, dataBytes);
|
||||
sequence, flightTime, packet.getSizeWithHeader(), packet.bytesAvailable());
|
||||
}
|
||||
|
||||
_packetsInLastWindow++;
|
||||
|
@ -111,42 +101,48 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar
|
|||
quint64 totalWaitingForLock = 0;
|
||||
quint64 totalUncompress = 0;
|
||||
quint64 totalReadBitsteam = 0;
|
||||
|
||||
const QUuid& sourceUUID = packet.getSourceID();
|
||||
|
||||
int subsection = 1;
|
||||
while (dataBytes > 0) {
|
||||
|
||||
bool error = false;
|
||||
|
||||
while (packet.bytesAvailable() && !error) {
|
||||
if (packetIsCompressed) {
|
||||
if (dataBytes > sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE)) {
|
||||
sectionLength = (*(OCTREE_PACKET_INTERNAL_SECTION_SIZE*)dataAt);
|
||||
dataAt += sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE);
|
||||
dataBytes -= sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE);
|
||||
if (packet.bytesAvailable() > sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE)) {
|
||||
packet.readPrimitive(§ionLength);
|
||||
} else {
|
||||
sectionLength = 0;
|
||||
dataBytes = 0; // stop looping something is wrong
|
||||
error = true;
|
||||
}
|
||||
} else {
|
||||
sectionLength = dataBytes;
|
||||
sectionLength = packet.bytesAvailable();
|
||||
}
|
||||
|
||||
if (sectionLength) {
|
||||
// ask the VoxelTree to read the bitstream into the tree
|
||||
ReadBitstreamToTreeParams args(packetIsColored ? WANT_COLOR : NO_COLOR, WANT_EXISTS_BITS, NULL,
|
||||
sourceUUID, sourceNode, false, packetVersion);
|
||||
ReadBitstreamToTreeParams args(packetIsColored ? WANT_COLOR : NO_COLOR, WANT_EXISTS_BITS, NULL,
|
||||
sourceUUID, sourceNode, false, packet.getVersion());
|
||||
quint64 startLock = usecTimestampNow();
|
||||
|
||||
// FIXME STUTTER - there may be an opportunity to bump this lock outside of the
|
||||
// loop to reduce the amount of locking/unlocking we're doing
|
||||
_tree->lockForWrite();
|
||||
quint64 startUncompress = usecTimestampNow();
|
||||
|
||||
OctreePacketData packetData(packetIsCompressed);
|
||||
packetData.loadFinalizedContent(dataAt, sectionLength);
|
||||
packetData.loadFinalizedContent(reinterpret_cast<unsigned char*>(packet.getPayload() + packet.pos()),
|
||||
sectionLength);
|
||||
if (extraDebugging) {
|
||||
qCDebug(octree, "OctreeRenderer::processDatagram() ... Got Packet Section"
|
||||
" color:%s compressed:%s sequence: %u flight:%d usec size:%u data:%u"
|
||||
" color:%s compressed:%s sequence: %u flight:%d usec size:%lld data:%lld"
|
||||
" subsection:%d sectionLength:%d uncompressed:%d",
|
||||
debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed),
|
||||
sequence, flightTime, packetLength, dataBytes, subsection, sectionLength,
|
||||
sequence, flightTime, packet.getSizeWithHeader(), packet.bytesAvailable(), subsection, sectionLength,
|
||||
packetData.getUncompressedSize());
|
||||
}
|
||||
|
||||
if (extraDebugging) {
|
||||
qCDebug(octree) << "OctreeRenderer::processDatagram() ******* START _tree->readBitstreamToTree()...";
|
||||
}
|
||||
|
@ -158,8 +154,8 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar
|
|||
}
|
||||
_tree->unlock();
|
||||
|
||||
dataBytes -= sectionLength;
|
||||
dataAt += sectionLength;
|
||||
// seek forwards in packet
|
||||
packet.seek(packet.pos() + sectionLength);
|
||||
|
||||
elementsPerPacket += args.elementsPerPacket;
|
||||
entitiesPerPacket += args.entitiesPerPacket;
|
||||
|
@ -228,10 +224,10 @@ void OctreeRenderer::render(RenderArgs* renderArgs) {
|
|||
}
|
||||
}
|
||||
|
||||
void OctreeRenderer::clear() {
|
||||
void OctreeRenderer::clear() {
|
||||
if (_tree) {
|
||||
_tree->lockForWrite();
|
||||
_tree->eraseAllOctreeElements();
|
||||
_tree->eraseAllOctreeElements();
|
||||
_tree->unlock();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
virtual void setTree(Octree* newTree);
|
||||
|
||||
/// process incoming data
|
||||
virtual void processDatagram(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode);
|
||||
virtual void processDatagram(NLPacket& packet, SharedNodePointer sourceNode);
|
||||
|
||||
/// initialize and GPU/rendering related resources
|
||||
virtual void init();
|
||||
|
|
|
@ -747,20 +747,17 @@ const char* OctreeSceneStats::getItemValue(Item item) {
|
|||
return _itemValueBuffer;
|
||||
}
|
||||
|
||||
void OctreeSceneStats::trackIncomingOctreePacket(const QByteArray& packet,
|
||||
bool wasStatsPacket, int nodeClockSkewUsec) {
|
||||
void OctreeSceneStats::trackIncomingOctreePacket(NLPacket& packet, bool wasStatsPacket, int nodeClockSkewUsec) {
|
||||
const bool wantExtraDebugging = false;
|
||||
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packet);
|
||||
const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(packet.data()) + numBytesPacketHeader;
|
||||
// skip past the flags
|
||||
packet.seek(sizeof(OCTREE_PACKET_FLAGS));
|
||||
|
||||
OCTREE_PACKET_SEQUENCE sequence;
|
||||
packet.readPrimitive(&sequence);
|
||||
|
||||
//VOXEL_PACKET_FLAGS flags = (*(VOXEL_PACKET_FLAGS*)(dataAt));
|
||||
dataAt += sizeof(OCTREE_PACKET_FLAGS);
|
||||
OCTREE_PACKET_SEQUENCE sequence = (*(OCTREE_PACKET_SEQUENCE*)dataAt);
|
||||
dataAt += sizeof(OCTREE_PACKET_SEQUENCE);
|
||||
|
||||
OCTREE_PACKET_SENT_TIME sentAt = (*(OCTREE_PACKET_SENT_TIME*)dataAt);
|
||||
dataAt += sizeof(OCTREE_PACKET_SENT_TIME);
|
||||
OCTREE_PACKET_SENT_TIME sentAt;
|
||||
packet.readPrimitive(&sentAt);
|
||||
|
||||
//bool packetIsColored = oneAtBit(flags, PACKET_IS_COLOR_BIT);
|
||||
//bool packetIsCompressed = oneAtBit(flags, PACKET_IS_COMPRESSED_BIT);
|
||||
|
@ -792,8 +789,8 @@ void OctreeSceneStats::trackIncomingOctreePacket(const QByteArray& packet,
|
|||
|
||||
// track packets here...
|
||||
_incomingPacket++;
|
||||
_incomingBytes += packet.size();
|
||||
_incomingBytes += packet.getSizeWithHeader();
|
||||
if (!wasStatsPacket) {
|
||||
_incomingWastedBytes += (MAX_PACKET_SIZE - packet.size());
|
||||
_incomingWastedBytes += (MAX_PACKET_SIZE - packet.getSizeWithHeader());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -160,7 +160,7 @@ public:
|
|||
quint64 getLastFullTotalBytes() const { return _lastFullTotalBytes; }
|
||||
|
||||
// Used in client implementations to track individual octree packets
|
||||
void trackIncomingOctreePacket(const QByteArray& packet, bool wasStatsPacket, int nodeClockSkewUsec);
|
||||
void trackIncomingOctreePacket(NLPacket& packet, bool wasStatsPacket, int nodeClockSkewUsec);
|
||||
|
||||
quint32 getIncomingPackets() const { return _incomingPacket; }
|
||||
quint64 getIncomingBytes() const { return _incomingBytes; }
|
||||
|
|
|
@ -28,15 +28,6 @@
|
|||
#include "SkyFromAtmosphere_vert.h"
|
||||
#include "SkyFromAtmosphere_frag.h"
|
||||
|
||||
uint qHash(const HifiSockAddr& sockAddr) {
|
||||
if (sockAddr.getAddress().isNull()) {
|
||||
return 0; // shouldn't happen, but if it does, zero is a perfectly valid hash
|
||||
}
|
||||
quint32 address = sockAddr.getAddress().toIPv4Address();
|
||||
return sockAddr.getPort() + qHash(QByteArray::fromRawData((char*) &address,
|
||||
sizeof(address)));
|
||||
}
|
||||
|
||||
Environment::Environment()
|
||||
: _initialized(false) {
|
||||
}
|
||||
|
@ -53,7 +44,7 @@ void Environment::init() {
|
|||
setupAtmosphereProgram(SkyFromAtmosphere_vert, SkyFromAtmosphere_frag, _skyFromAtmosphereProgram, _skyFromAtmosphereUniformLocations);
|
||||
|
||||
// start off with a default-constructed environment data
|
||||
_data[HifiSockAddr()][0];
|
||||
_data[QUuid()][0];
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
|
@ -98,10 +89,10 @@ void Environment::setupAtmosphereProgram(const char* vertSource, const char* fra
|
|||
|
||||
void Environment::resetToDefault() {
|
||||
_data.clear();
|
||||
_data[HifiSockAddr()][0];
|
||||
_data[QUuid()][0];
|
||||
}
|
||||
|
||||
void Environment::renderAtmospheres(gpu::Batch& batch, ViewFrustum& camera) {
|
||||
void Environment::renderAtmospheres(gpu::Batch& batch, ViewFrustum& camera) {
|
||||
// get the lock for the duration of the call
|
||||
QMutexLocker locker(&_mutex);
|
||||
|
||||
|
@ -142,7 +133,7 @@ EnvironmentData Environment::getClosestData(const glm::vec3& position) {
|
|||
|
||||
|
||||
// NOTE: Deprecated - I'm leaving this in for now, but it's not actually used. I made it private
|
||||
// so that if anyone wants to start using this in the future they will consider how to make it
|
||||
// so that if anyone wants to start using this in the future they will consider how to make it
|
||||
// work with new physics systems.
|
||||
glm::vec3 Environment::getGravity (const glm::vec3& position) {
|
||||
//
|
||||
|
@ -169,7 +160,7 @@ glm::vec3 Environment::getGravity (const glm::vec3& position) {
|
|||
// At or inside a planet, gravity is as set for the planet
|
||||
gravity += glm::normalize(vector) * environmentData.getGravity();
|
||||
} else {
|
||||
// Outside a planet, the gravity falls off with distance
|
||||
// Outside a planet, the gravity falls off with distance
|
||||
gravityStrength = 1.0f / powf(glm::length(vector) / surfaceRadius, 2.0f);
|
||||
gravity += glm::normalize(vector) * environmentData.getGravity() * gravityStrength;
|
||||
}
|
||||
|
@ -205,33 +196,28 @@ bool Environment::findCapsulePenetration(const glm::vec3& start, const glm::vec3
|
|||
return found;
|
||||
}
|
||||
|
||||
int Environment::parseData(const HifiSockAddr& senderAddress, const QByteArray& packet) {
|
||||
// push past the packet header
|
||||
int bytesRead = numBytesForPacketHeader(packet);
|
||||
|
||||
int Environment::processPacket(NLPacket& packet) {
|
||||
// push past flags, sequence, timestamp
|
||||
bytesRead += sizeof(OCTREE_PACKET_FLAGS);
|
||||
bytesRead += sizeof(OCTREE_PACKET_SEQUENCE);
|
||||
bytesRead += sizeof(OCTREE_PACKET_SENT_TIME);
|
||||
packet.seek(sizeof(OCTREE_PACKET_FLAGS) + sizeof(OCTREE_PACKET_SEQUENCE) + sizeof(OCTREE_PACKET_SENT_TIME));
|
||||
|
||||
// get the lock for the duration of the call
|
||||
QMutexLocker locker(&_mutex);
|
||||
|
||||
EnvironmentData newData;
|
||||
while (bytesRead < packet.size()) {
|
||||
int dataLength = newData.parseData(reinterpret_cast<const unsigned char*>(packet.data()) + bytesRead,
|
||||
packet.size() - bytesRead);
|
||||
|
||||
while (packet.bytesAvailable() > 0) {
|
||||
int dataLength = newData.parseData(reinterpret_cast<const unsigned char*>(packet.getPayload() + packet.pos()),
|
||||
packet.bytesAvailable());
|
||||
packet.seek(packet.pos() + dataLength);
|
||||
|
||||
// update the mapping by address/ID
|
||||
_data[senderAddress][newData.getID()] = newData;
|
||||
|
||||
bytesRead += dataLength;
|
||||
_data[packet.getSourceID()][newData.getID()] = newData;
|
||||
}
|
||||
|
||||
// remove the default mapping, if any
|
||||
_data.remove(HifiSockAddr());
|
||||
_data.remove(QUuid());
|
||||
|
||||
return bytesRead;
|
||||
return packet.pos();
|
||||
}
|
||||
|
||||
void Environment::renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const EnvironmentData& data) {
|
||||
|
|
|
@ -36,13 +36,12 @@ public:
|
|||
void endOverride() { _environmentIsOverridden = false; }
|
||||
|
||||
EnvironmentData getClosestData(const glm::vec3& position);
|
||||
|
||||
|
||||
int parseData(const HifiSockAddr& senderSockAddr, const QByteArray& packet);
|
||||
|
||||
int processPacket(NLPacket& packet);
|
||||
|
||||
private:
|
||||
glm::vec3 getGravity (const glm::vec3& position); // NOTE: Deprecated
|
||||
bool findCapsulePenetration(const glm::vec3& start,
|
||||
bool findCapsulePenetration(const glm::vec3& start,
|
||||
const glm::vec3& end, float radius, glm::vec3& penetration); // NOTE: Deprecated
|
||||
|
||||
void renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const EnvironmentData& data);
|
||||
|
@ -79,7 +78,7 @@ private:
|
|||
|
||||
typedef QHash<int, EnvironmentData> ServerData;
|
||||
|
||||
QHash<HifiSockAddr, ServerData> _data;
|
||||
QHash<QUuid, ServerData> _data;
|
||||
EnvironmentData _overrideData;
|
||||
bool _environmentIsOverridden = false;
|
||||
|
||||
|
|
Loading…
Reference in a new issue