From b08a1708f509d60615192294fba1b92b4b81a1b1 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Feb 2014 00:18:15 -0800 Subject: [PATCH 01/20] hide some slots from JS --- .../octree/src/OctreeScriptingInterface.h | 6 +++--- .../src/ParticlesScriptingInterface.h | 21 +++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/libraries/octree/src/OctreeScriptingInterface.h b/libraries/octree/src/OctreeScriptingInterface.h index 3c832cbae8..3003950bbf 100644 --- a/libraries/octree/src/OctreeScriptingInterface.h +++ b/libraries/octree/src/OctreeScriptingInterface.h @@ -32,6 +32,9 @@ public: virtual NodeType_t getServerNodeType() const = 0; virtual OctreeEditPacketSender* createPacketSender() = 0; +private slots: + void cleanupManagedObjects(); + public slots: /// Set the desired max packet size in bytes that should be created void setMaxPacketSize(int maxPacketSize) { return _packetSender->setMaxPacketSize(maxPacketSize); } @@ -84,9 +87,6 @@ public slots: /// returns the total bytes queued by this object over its lifetime long long unsigned int getLifetimeBytesQueued() const { return _packetSender->getLifetimeBytesQueued(); } - // TODO: hmmm... we don't want this called from JS, how to handle that? - void cleanupManagedObjects(); - protected: /// attached OctreeEditPacketSender that handles queuing and sending of packets to VS OctreeEditPacketSender* _packetSender; diff --git a/libraries/particles/src/ParticlesScriptingInterface.h b/libraries/particles/src/ParticlesScriptingInterface.h index 729561571e..3aa19629f0 100644 --- a/libraries/particles/src/ParticlesScriptingInterface.h +++ b/libraries/particles/src/ParticlesScriptingInterface.h @@ -26,7 +26,19 @@ public: void setParticleTree(ParticleTree* particleTree) { _particleTree = particleTree; } ParticleTree* getParticleTree(ParticleTree*) { return _particleTree; } + +private slots: + /// inbound slots for external collision systems + void forwardParticleCollisionWithVoxel(const ParticleID& particleID, const VoxelDetail& voxel) { + qDebug() << "forwardParticleCollisionWithVoxel()"; + emit particleCollisionWithVoxel(particleID, voxel); + } + void forwardParticleCollisionWithParticle(const ParticleID& idA, const ParticleID& idB) { + qDebug() << "forwardParticleCollisionWithParticle()"; + emit particleCollisionWithParticle(idA, idB); + } + public slots: /// adds a particle with the specific properties ParticleID addParticle(const ParticleProperties& properties); @@ -54,15 +66,6 @@ public slots: /// this function will not find any particles in script engine contexts which don't have access to particles QVector findParticles(const glm::vec3& center, float radius) const; - /// inbound slots for external collision systems - void forwardParticleCollisionWithVoxel(const ParticleID& particleID, const VoxelDetail& voxel) { - emit particleCollisionWithVoxel(particleID, voxel); - } - - void forwardParticleCollisionWithParticle(const ParticleID& idA, const ParticleID& idB) { - emit particleCollisionWithParticle(idA, idB); - } - signals: void particleCollisionWithVoxel(const ParticleID& particleID, const VoxelDetail& voxel); void particleCollisionWithParticle(const ParticleID& idA, const ParticleID& idB); From cbca2987179f53435f8624cdaf9d9bcff583676c Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Feb 2014 00:31:05 -0800 Subject: [PATCH 02/20] cruft cleanup --- libraries/octree/src/OctreeQuery.cpp | 13 +------------ libraries/octree/src/OctreeQuery.h | 10 ---------- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/libraries/octree/src/OctreeQuery.cpp b/libraries/octree/src/OctreeQuery.cpp index 5c67715ab9..51e235c4e2 100644 --- a/libraries/octree/src/OctreeQuery.cpp +++ b/libraries/octree/src/OctreeQuery.cpp @@ -6,22 +6,11 @@ // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // -#include -#include -#include - -#include -#include #include -#include + #include "OctreeConstants.h" - #include "OctreeQuery.h" -using namespace std; - -static const float fingerVectorRadix = 4; // bits of precision when converting from float<->fixed - OctreeQuery::OctreeQuery() : NodeData(), _cameraPosition(0,0,0), diff --git a/libraries/octree/src/OctreeQuery.h b/libraries/octree/src/OctreeQuery.h index 800d30b7cd..3b53aaa501 100644 --- a/libraries/octree/src/OctreeQuery.h +++ b/libraries/octree/src/OctreeQuery.h @@ -9,8 +9,6 @@ #ifndef __hifi__OctreeQuery__ #define __hifi__OctreeQuery__ -#include - /* VS2010 defines stdint.h, but not inttypes.h */ #if defined(_MSC_VER) typedef signed char int8_t; @@ -27,17 +25,9 @@ typedef unsigned long long quint64; #endif -#include - #include #include -#include -#include -#include - -#include - #include // First bitset From 5fdfee4cd5703e1ef221154dd85838b4370be342 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Feb 2014 00:48:38 -0800 Subject: [PATCH 03/20] cleaning up some stuff --- libraries/octree/src/OctreeRenderer.cpp | 4 +++- libraries/octree/src/OctreeRenderer.h | 3 --- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/libraries/octree/src/OctreeRenderer.cpp b/libraries/octree/src/OctreeRenderer.cpp index 9a00ce245b..b3d2ea45e3 100644 --- a/libraries/octree/src/OctreeRenderer.cpp +++ b/libraries/octree/src/OctreeRenderer.cpp @@ -37,6 +37,8 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar unsigned char command = *packetData; int numBytesPacketHeader = numBytesForPacketHeader(dataByteArray); + QUuid sourceUUID = uuidFromPacketHeader(dataByteArray); + PacketType expectedType = getExpectedPacketType(); @@ -91,7 +93,7 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar if (sectionLength) { // ask the VoxelTree to read the bitstream into the tree ReadBitstreamToTreeParams args(packetIsColored ? WANT_COLOR : NO_COLOR, WANT_EXISTS_BITS, NULL, - getDataSourceUUID(), sourceNode); + sourceUUID, sourceNode); _tree->lockForWrite(); OctreePacketData packetData(packetIsCompressed); packetData.loadFinalizedContent(dataAt, sectionLength); diff --git a/libraries/octree/src/OctreeRenderer.h b/libraries/octree/src/OctreeRenderer.h index e29cdc4020..4f0f76eb6c 100644 --- a/libraries/octree/src/OctreeRenderer.h +++ b/libraries/octree/src/OctreeRenderer.h @@ -51,8 +51,6 @@ public: /// render the content of the octree virtual void render(); - void setDataSourceUUID(const QUuid& dataSourceUUID) { _dataSourceUUID = dataSourceUUID; } - const QUuid& getDataSourceUUID() const { return _dataSourceUUID; } ViewFrustum* getViewFrustum() const { return _viewFrustum; } void setViewFrustum(ViewFrustum* viewFrustum) { _viewFrustum = viewFrustum; } @@ -62,7 +60,6 @@ public: void clear(); protected: Octree* _tree; - QUuid _dataSourceUUID; ViewFrustum* _viewFrustum; }; From 5b1037cc63b98c3aba4875af2082d4597665ce1c Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Feb 2014 01:22:53 -0800 Subject: [PATCH 04/20] switching to OctreeQuery instead of VoxelQuery --- interface/src/Application.cpp | 54 +++++++++++++++++------------------ interface/src/Application.h | 4 +-- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4393db4d76..3dff980b64 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1931,23 +1931,23 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node bool wantExtraDebugging = getLogger()->extraDebugging(); // These will be the same for all servers, so we can set them up once and then reuse for each server we send to. - _voxelQuery.setWantLowResMoving(!Menu::getInstance()->isOptionChecked(MenuOption::DisableLowRes)); - _voxelQuery.setWantColor(!Menu::getInstance()->isOptionChecked(MenuOption::DisableColorVoxels)); - _voxelQuery.setWantDelta(!Menu::getInstance()->isOptionChecked(MenuOption::DisableDeltaSending)); - _voxelQuery.setWantOcclusionCulling(Menu::getInstance()->isOptionChecked(MenuOption::EnableOcclusionCulling)); - _voxelQuery.setWantCompression(Menu::getInstance()->isOptionChecked(MenuOption::EnableVoxelPacketCompression)); + _octreeQuery.setWantLowResMoving(!Menu::getInstance()->isOptionChecked(MenuOption::DisableLowRes)); + _octreeQuery.setWantColor(!Menu::getInstance()->isOptionChecked(MenuOption::DisableColorVoxels)); + _octreeQuery.setWantDelta(!Menu::getInstance()->isOptionChecked(MenuOption::DisableDeltaSending)); + _octreeQuery.setWantOcclusionCulling(Menu::getInstance()->isOptionChecked(MenuOption::EnableOcclusionCulling)); + _octreeQuery.setWantCompression(Menu::getInstance()->isOptionChecked(MenuOption::EnableVoxelPacketCompression)); - _voxelQuery.setCameraPosition(_viewFrustum.getPosition()); - _voxelQuery.setCameraOrientation(_viewFrustum.getOrientation()); - _voxelQuery.setCameraFov(_viewFrustum.getFieldOfView()); - _voxelQuery.setCameraAspectRatio(_viewFrustum.getAspectRatio()); - _voxelQuery.setCameraNearClip(_viewFrustum.getNearClip()); - _voxelQuery.setCameraFarClip(_viewFrustum.getFarClip()); - _voxelQuery.setCameraEyeOffsetPosition(_viewFrustum.getEyeOffsetPosition()); - _voxelQuery.setOctreeSizeScale(Menu::getInstance()->getVoxelSizeScale()); - _voxelQuery.setBoundaryLevelAdjust(Menu::getInstance()->getBoundaryLevelAdjust()); + _octreeQuery.setCameraPosition(_viewFrustum.getPosition()); + _octreeQuery.setCameraOrientation(_viewFrustum.getOrientation()); + _octreeQuery.setCameraFov(_viewFrustum.getFieldOfView()); + _octreeQuery.setCameraAspectRatio(_viewFrustum.getAspectRatio()); + _octreeQuery.setCameraNearClip(_viewFrustum.getNearClip()); + _octreeQuery.setCameraFarClip(_viewFrustum.getFarClip()); + _octreeQuery.setCameraEyeOffsetPosition(_viewFrustum.getEyeOffsetPosition()); + _octreeQuery.setOctreeSizeScale(Menu::getInstance()->getVoxelSizeScale()); + _octreeQuery.setBoundaryLevelAdjust(Menu::getInstance()->getBoundaryLevelAdjust()); - unsigned char voxelQueryPacket[MAX_PACKET_SIZE]; + unsigned char queryPacket[MAX_PACKET_SIZE]; // Iterate all of the nodes, and get a count of how many voxel servers we have... int totalServers = 0; @@ -2057,7 +2057,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node } if (inView) { - _voxelQuery.setMaxOctreePacketsPerSecond(perServerPPS); + _octreeQuery.setMaxOctreePacketsPerSecond(perServerPPS); } else if (unknownView) { if (wantExtraDebugging) { qDebug() << "no known jurisdiction for node " << *node << ", give it budget of " @@ -2068,11 +2068,11 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node // If there's only one server, then don't do this, and just let the normal voxel query pass through // as expected... this way, we will actually get a valid scene if there is one to be seen if (totalServers > 1) { - _voxelQuery.setCameraPosition(glm::vec3(-0.1,-0.1,-0.1)); + _octreeQuery.setCameraPosition(glm::vec3(-0.1,-0.1,-0.1)); const glm::quat OFF_IN_NEGATIVE_SPACE = glm::quat(-0.5, 0, -0.5, 1.0); - _voxelQuery.setCameraOrientation(OFF_IN_NEGATIVE_SPACE); - _voxelQuery.setCameraNearClip(0.1f); - _voxelQuery.setCameraFarClip(0.1f); + _octreeQuery.setCameraOrientation(OFF_IN_NEGATIVE_SPACE); + _octreeQuery.setCameraNearClip(0.1f); + _octreeQuery.setCameraFarClip(0.1f); if (wantExtraDebugging) { qDebug() << "Using 'minimal' camera position for node" << *node; } @@ -2081,23 +2081,23 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node qDebug() << "Using regular camera position for node" << *node; } } - _voxelQuery.setMaxOctreePacketsPerSecond(perUnknownServer); + _octreeQuery.setMaxOctreePacketsPerSecond(perUnknownServer); } else { - _voxelQuery.setMaxOctreePacketsPerSecond(0); + _octreeQuery.setMaxOctreePacketsPerSecond(0); } // set up the packet for sending... - unsigned char* endOfVoxelQueryPacket = voxelQueryPacket; + unsigned char* endOfQueryPacket = queryPacket; // insert packet type/version and node UUID - endOfVoxelQueryPacket += populatePacketHeader(reinterpret_cast(endOfVoxelQueryPacket), packetType); + endOfQueryPacket += populatePacketHeader(reinterpret_cast(endOfQueryPacket), packetType); // encode the query data... - endOfVoxelQueryPacket += _voxelQuery.getBroadcastData(endOfVoxelQueryPacket); + endOfQueryPacket += _octreeQuery.getBroadcastData(endOfQueryPacket); - int packetLength = endOfVoxelQueryPacket - voxelQueryPacket; + int packetLength = endOfQueryPacket - queryPacket; // make sure we still have an active socket - nodeList->writeDatagram(reinterpret_cast(voxelQueryPacket), packetLength, node); + nodeList->writeDatagram(reinterpret_cast(queryPacket), packetLength, node); // Feed number of bytes to corresponding channel of the bandwidth meter _bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(packetLength); diff --git a/interface/src/Application.h b/interface/src/Application.h index 846d952e5f..51c6734e7a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include "Audio.h" @@ -387,7 +387,7 @@ private: Oscilloscope _audioScope; - VoxelQuery _voxelQuery; // NodeData derived class for querying voxels from voxel server + OctreeQuery _octreeQuery; // NodeData derived class for querying voxels from voxel server AvatarManager _avatarManager; MyAvatar* _myAvatar; // TODO: move this and relevant code to AvatarManager (or MyAvatar as the case may be) From e96206914ece986c76d5f8f84080f67b2de4d5a6 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Feb 2014 01:24:12 -0800 Subject: [PATCH 05/20] early cut at headless viewers --- libraries/octree/src/OctreeHeadlessViewer.cpp | 23 ++++++++++ libraries/octree/src/OctreeHeadlessViewer.h | 34 +++++++++++++++ libraries/octree/src/OctreeRenderer.h | 5 ++- .../src/ParticleTreeHeadlessViewer.cpp | 36 ++++++++++++++++ .../src/ParticleTreeHeadlessViewer.h | 42 +++++++++++++++++++ .../voxels/src/VoxelTreeHeadlessViewer.cpp | 22 ++++++++++ .../voxels/src/VoxelTreeHeadlessViewer.h | 38 +++++++++++++++++ 7 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 libraries/octree/src/OctreeHeadlessViewer.cpp create mode 100644 libraries/octree/src/OctreeHeadlessViewer.h create mode 100644 libraries/particles/src/ParticleTreeHeadlessViewer.cpp create mode 100644 libraries/particles/src/ParticleTreeHeadlessViewer.h create mode 100644 libraries/voxels/src/VoxelTreeHeadlessViewer.cpp create mode 100644 libraries/voxels/src/VoxelTreeHeadlessViewer.h diff --git a/libraries/octree/src/OctreeHeadlessViewer.cpp b/libraries/octree/src/OctreeHeadlessViewer.cpp new file mode 100644 index 0000000000..79f2e3be43 --- /dev/null +++ b/libraries/octree/src/OctreeHeadlessViewer.cpp @@ -0,0 +1,23 @@ +// +// OctreeHeadlessViewer.cpp +// hifi +// +// Created by Brad Hefta-Gaub on 2/26/14 +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// +// + +#include "OctreeHeadlessViewer.h" + +OctreeHeadlessViewer::OctreeHeadlessViewer() : + OctreeRenderer() { +} + +OctreeHeadlessViewer::~OctreeHeadlessViewer() { +} + +void OctreeHeadlessViewer::init() { + OctreeRenderer::init(); + setViewFrustum(&_viewFrustum); +} + diff --git a/libraries/octree/src/OctreeHeadlessViewer.h b/libraries/octree/src/OctreeHeadlessViewer.h new file mode 100644 index 0000000000..54e4a01043 --- /dev/null +++ b/libraries/octree/src/OctreeHeadlessViewer.h @@ -0,0 +1,34 @@ +// +// OctreeHeadlessViewer.h +// hifi +// +// Created by Brad Hefta-Gaub on 2/26/14 +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// +// + +#ifndef __hifi__OctreeHeadlessViewer__ +#define __hifi__OctreeHeadlessViewer__ + +#include +#include +#include "Octree.h" +#include "OctreeRenderer.h" +#include "Octree.h" +#include "ViewFrustum.h" + +// Generic client side Octree renderer class. +class OctreeHeadlessViewer : public OctreeRenderer { + Q_OBJECT +public: + OctreeHeadlessViewer(); + virtual ~OctreeHeadlessViewer(); + virtual void renderElement(OctreeElement* element, RenderArgs* args) { /* swallow these */ }; + + virtual void init(); + virtual void render() { /* swallow these */ }; +private: + ViewFrustum _viewFrustum; +}; + +#endif /* defined(__hifi__OctreeHeadlessViewer__) */ \ No newline at end of file diff --git a/libraries/octree/src/OctreeRenderer.h b/libraries/octree/src/OctreeRenderer.h index 4f0f76eb6c..52b0a3fc2e 100644 --- a/libraries/octree/src/OctreeRenderer.h +++ b/libraries/octree/src/OctreeRenderer.h @@ -13,6 +13,8 @@ #include #include +#include + #include #include @@ -31,7 +33,8 @@ public: // Generic client side Octree renderer class. -class OctreeRenderer { +class OctreeRenderer : public QObject { + Q_OBJECT public: OctreeRenderer(); virtual ~OctreeRenderer(); diff --git a/libraries/particles/src/ParticleTreeHeadlessViewer.cpp b/libraries/particles/src/ParticleTreeHeadlessViewer.cpp new file mode 100644 index 0000000000..f5384c3fec --- /dev/null +++ b/libraries/particles/src/ParticleTreeHeadlessViewer.cpp @@ -0,0 +1,36 @@ +// +// ParticleTreeHeadlessViewer.cpp +// hifi +// +// Created by Brad Hefta-Gaub on 2/26/14 +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// +// + +#include "ParticleTreeHeadlessViewer.h" + +ParticleTreeHeadlessViewer::ParticleTreeHeadlessViewer() : + OctreeHeadlessViewer() { +} + +ParticleTreeHeadlessViewer::~ParticleTreeHeadlessViewer() { +} + +void ParticleTreeHeadlessViewer::init() { + OctreeHeadlessViewer::init(); +} + + +void ParticleTreeHeadlessViewer::update() { + if (_tree) { + ParticleTree* tree = static_cast(_tree); + if (tree->tryLockForWrite()) { + tree->update(); + tree->unlock(); + } + } +} + +void ParticleTreeHeadlessViewer::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) { + static_cast(_tree)->processEraseMessage(dataByteArray, sourceNode); +} diff --git a/libraries/particles/src/ParticleTreeHeadlessViewer.h b/libraries/particles/src/ParticleTreeHeadlessViewer.h new file mode 100644 index 0000000000..08aa12280c --- /dev/null +++ b/libraries/particles/src/ParticleTreeHeadlessViewer.h @@ -0,0 +1,42 @@ +// +// ParticleTreeHeadlessViewer.h +// hifi +// +// Created by Brad Hefta-Gaub on 2/26/14 +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// +// + +#ifndef __hifi__ParticleTreeHeadlessViewer__ +#define __hifi__ParticleTreeHeadlessViewer__ + +#include +#include +#include +#include +#include +#include "ParticleTree.h" +#include + +// Generic client side Octree renderer class. +class ParticleTreeHeadlessViewer : public OctreeHeadlessViewer { + Q_OBJECT +public: + ParticleTreeHeadlessViewer(); + virtual ~ParticleTreeHeadlessViewer(); + + virtual Octree* createTree() { return new ParticleTree(true); } + virtual NodeType_t getMyNodeType() const { return NodeType::ParticleServer; } + virtual PacketType getMyQueryMessageType() const { return PacketTypeParticleQuery; } + virtual PacketType getExpectedPacketType() const { return PacketTypeParticleData; } + + void update(); + + ParticleTree* getTree() { return (ParticleTree*)_tree; } + + void processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode); + + virtual void init(); +}; + +#endif /* defined(__hifi__ParticleTreeHeadlessViewer__) */ \ No newline at end of file diff --git a/libraries/voxels/src/VoxelTreeHeadlessViewer.cpp b/libraries/voxels/src/VoxelTreeHeadlessViewer.cpp new file mode 100644 index 0000000000..999ef4fa36 --- /dev/null +++ b/libraries/voxels/src/VoxelTreeHeadlessViewer.cpp @@ -0,0 +1,22 @@ +// +// VoxelTreeHeadlessViewer.cpp +// hifi +// +// Created by Brad Hefta-Gaub on 2/26/14 +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// +// + +#include "VoxelTreeHeadlessViewer.h" + +VoxelTreeHeadlessViewer::VoxelTreeHeadlessViewer() : + OctreeHeadlessViewer() { +} + +VoxelTreeHeadlessViewer::~VoxelTreeHeadlessViewer() { +} + +void VoxelTreeHeadlessViewer::init() { + OctreeHeadlessViewer::init(); +} + diff --git a/libraries/voxels/src/VoxelTreeHeadlessViewer.h b/libraries/voxels/src/VoxelTreeHeadlessViewer.h new file mode 100644 index 0000000000..9c7481c929 --- /dev/null +++ b/libraries/voxels/src/VoxelTreeHeadlessViewer.h @@ -0,0 +1,38 @@ +// +// VoxelTreeHeadlessViewer.h +// hifi +// +// Created by Brad Hefta-Gaub on 2/26/14 +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// +// + +#ifndef __hifi__VoxelTreeHeadlessViewer__ +#define __hifi__VoxelTreeHeadlessViewer__ + +#include +#include +#include +#include +#include +#include "VoxelTree.h" +#include + +// Generic client side Octree renderer class. +class VoxelTreeHeadlessViewer : public OctreeHeadlessViewer { + Q_OBJECT +public: + VoxelTreeHeadlessViewer(); + virtual ~VoxelTreeHeadlessViewer(); + + virtual Octree* createTree() { return new VoxelTree(true); } + virtual NodeType_t getMyNodeType() const { return NodeType::VoxelServer; } + virtual PacketType getMyQueryMessageType() const { return PacketTypeVoxelQuery; } + virtual PacketType getExpectedPacketType() const { return PacketTypeVoxelData; } + + VoxelTree* getTree() { return (VoxelTree*)_tree; } + + virtual void init(); +}; + +#endif /* defined(__hifi__VoxelTreeHeadlessViewer__) */ \ No newline at end of file From a28f016de06c2a4d7238e1274c4dc82e0df76359 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Feb 2014 01:28:08 -0800 Subject: [PATCH 06/20] removing VoxelQuery --- libraries/voxels/src/VoxelQuery.cpp | 9 --------- libraries/voxels/src/VoxelQuery.h | 25 ------------------------- 2 files changed, 34 deletions(-) delete mode 100644 libraries/voxels/src/VoxelQuery.cpp delete mode 100644 libraries/voxels/src/VoxelQuery.h diff --git a/libraries/voxels/src/VoxelQuery.cpp b/libraries/voxels/src/VoxelQuery.cpp deleted file mode 100644 index 239b352ca1..0000000000 --- a/libraries/voxels/src/VoxelQuery.cpp +++ /dev/null @@ -1,9 +0,0 @@ -// -// VoxelQuery.cpp -// hifi -// -// Created by Brad Hefta-Gaub on 10/24/13. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. -// - -#include "VoxelQuery.h" \ No newline at end of file diff --git a/libraries/voxels/src/VoxelQuery.h b/libraries/voxels/src/VoxelQuery.h deleted file mode 100644 index 6898430d82..0000000000 --- a/libraries/voxels/src/VoxelQuery.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// VoxelQuery.h -// hifi -// -// Created by Stephen Birarda on 4/9/13. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. -// - -#ifndef __hifi__VoxelQuery__ -#define __hifi__VoxelQuery__ - -#include - -class VoxelQuery : public OctreeQuery { - -public: - // currently just an alias - VoxelQuery() : OctreeQuery() {}; -private: - // privatize the copy constructor and assignment operator so they cannot be called - VoxelQuery(const VoxelQuery&); - VoxelQuery& operator= (const VoxelQuery&); -}; - -#endif /* defined(__hifi__VoxelQuery__) */ From 7a2419a5bdca43b82a2e788d6733f1bbaa8f8f19 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Feb 2014 01:54:32 -0800 Subject: [PATCH 07/20] removed old menu items for voxel protocol options --- interface/src/Application.cpp | 10 +++++----- interface/src/Menu.cpp | 6 ------ interface/src/Menu.h | 5 ----- 3 files changed, 5 insertions(+), 16 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3dff980b64..2ebe556016 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1931,11 +1931,11 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node bool wantExtraDebugging = getLogger()->extraDebugging(); // These will be the same for all servers, so we can set them up once and then reuse for each server we send to. - _octreeQuery.setWantLowResMoving(!Menu::getInstance()->isOptionChecked(MenuOption::DisableLowRes)); - _octreeQuery.setWantColor(!Menu::getInstance()->isOptionChecked(MenuOption::DisableColorVoxels)); - _octreeQuery.setWantDelta(!Menu::getInstance()->isOptionChecked(MenuOption::DisableDeltaSending)); - _octreeQuery.setWantOcclusionCulling(Menu::getInstance()->isOptionChecked(MenuOption::EnableOcclusionCulling)); - _octreeQuery.setWantCompression(Menu::getInstance()->isOptionChecked(MenuOption::EnableVoxelPacketCompression)); + _octreeQuery.setWantLowResMoving(true); + _octreeQuery.setWantColor(true); + _octreeQuery.setWantDelta(true); + _octreeQuery.setWantOcclusionCulling(false); + _octreeQuery.setWantCompression(true); _octreeQuery.setCameraPosition(_viewFrustum.getPosition()); _octreeQuery.setCameraOrientation(_viewFrustum.getOrientation()); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 89bebefcdd..37db7b5575 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -254,12 +254,6 @@ Menu::Menu() : addActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools())); QMenu* voxelProtoOptionsMenu = voxelOptionsMenu->addMenu("Voxel Server Protocol Options"); - - addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DisableColorVoxels); - addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DisableLowRes); - addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DisableDeltaSending); - addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::EnableVoxelPacketCompression); - addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::EnableOcclusionCulling); addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DestructiveAddVoxel); QMenu* avatarOptionsMenu = developerMenu->addMenu("Avatar Options"); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 041f1fcd50..2ce250be55 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -218,9 +218,6 @@ namespace MenuOption { const QString DecreaseAvatarSize = "Decrease Avatar Size"; const QString DecreaseVoxelSize = "Decrease Voxel Size"; const QString DestructiveAddVoxel = "Create Voxel is Destructive"; - const QString DisableColorVoxels = "Disable Colored Voxels"; - const QString DisableDeltaSending = "Disable Delta Sending"; - const QString DisableLowRes = "Disable Lower Resolution While Moving"; const QString DisplayFrustum = "Display Frustum"; const QString DisplayHands = "Display Hands"; const QString DisplayHandTargets = "Display Hand Targets"; @@ -228,8 +225,6 @@ namespace MenuOption { const QString DontRenderVoxels = "Don't call _voxels.render()"; const QString DontCallOpenGLForVoxels = "Don't call glDrawRangeElementsEXT() for Voxels"; const QString Enable3DTVMode = "Enable 3DTV Mode"; - const QString EnableOcclusionCulling = "Enable Occlusion Culling"; - const QString EnableVoxelPacketCompression = "Enable Voxel Packet Compression"; const QString AudioNoiseReduction = "Audio Noise Reduction"; const QString EchoServerAudio = "Echo Server Audio"; const QString EchoLocalAudio = "Echo Local Audio"; From dee9d48b5fee7580966198d28fba38f76a1a1172 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Feb 2014 01:55:04 -0800 Subject: [PATCH 08/20] adding OctreeHeadlessViewer::queryOctree() --- libraries/octree/src/OctreeHeadlessViewer.cpp | 180 ++++++++++++++++++ libraries/octree/src/OctreeHeadlessViewer.h | 17 ++ 2 files changed, 197 insertions(+) diff --git a/libraries/octree/src/OctreeHeadlessViewer.cpp b/libraries/octree/src/OctreeHeadlessViewer.cpp index 79f2e3be43..7cf586cbb2 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.cpp +++ b/libraries/octree/src/OctreeHeadlessViewer.cpp @@ -7,6 +7,8 @@ // // +#include + #include "OctreeHeadlessViewer.h" OctreeHeadlessViewer::OctreeHeadlessViewer() : @@ -21,3 +23,181 @@ void OctreeHeadlessViewer::init() { setViewFrustum(&_viewFrustum); } +void OctreeHeadlessViewer::queryOctree() { + NodeType_t serverType = getMyNodeType(); + PacketType packetType = getMyQueryMessageType(); + NodeToJurisdictionMap& jurisdictions = *_jurisdictionListener->getJurisdictions(); + + bool wantExtraDebugging = false; + + // These will be the same for all servers, so we can set them up once and then reuse for each server we send to. + _octreeQuery.setWantLowResMoving(true); + _octreeQuery.setWantColor(true); + _octreeQuery.setWantDelta(true); + _octreeQuery.setWantOcclusionCulling(false); + _octreeQuery.setWantCompression(true); // TODO: should be on by default + + _octreeQuery.setCameraPosition(_viewFrustum.getPosition()); + _octreeQuery.setCameraOrientation(_viewFrustum.getOrientation()); + _octreeQuery.setCameraFov(_viewFrustum.getFieldOfView()); + _octreeQuery.setCameraAspectRatio(_viewFrustum.getAspectRatio()); + _octreeQuery.setCameraNearClip(_viewFrustum.getNearClip()); + _octreeQuery.setCameraFarClip(_viewFrustum.getFarClip()); + _octreeQuery.setCameraEyeOffsetPosition(_viewFrustum.getEyeOffsetPosition()); + _octreeQuery.setOctreeSizeScale(getVoxelSizeScale()); + _octreeQuery.setBoundaryLevelAdjust(getBoundaryLevelAdjust()); + + unsigned char queryPacket[MAX_PACKET_SIZE]; + + // Iterate all of the nodes, and get a count of how many voxel servers we have... + int totalServers = 0; + int inViewServers = 0; + int unknownJurisdictionServers = 0; + + foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + // only send to the NodeTypes that are serverType + if (node->getActiveSocket() != NULL && node->getType() == serverType) { + totalServers++; + + // get the server bounds for this server + QUuid nodeUUID = node->getUUID(); + + // if we haven't heard from this voxel server, go ahead and send it a query, so we + // can get the jurisdiction... + if (jurisdictions.find(nodeUUID) == jurisdictions.end()) { + unknownJurisdictionServers++; + } else { + const JurisdictionMap& map = (jurisdictions)[nodeUUID]; + + unsigned char* rootCode = map.getRootOctalCode(); + + if (rootCode) { + VoxelPositionSize rootDetails; + voxelDetailsForCode(rootCode, rootDetails); + AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s); + serverBounds.scale(TREE_SCALE); + + ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds); + + if (serverFrustumLocation != ViewFrustum::OUTSIDE) { + inViewServers++; + } + } + } + } + } + + if (wantExtraDebugging && unknownJurisdictionServers > 0) { + qDebug("Servers: total %d, in view %d, unknown jurisdiction %d", + totalServers, inViewServers, unknownJurisdictionServers); + } + + int perServerPPS = 0; + const int SMALL_BUDGET = 10; + int perUnknownServer = SMALL_BUDGET; + int totalPPS = getMaxPacketsPerSecond(); + + // determine PPS based on number of servers + if (inViewServers >= 1) { + // set our preferred PPS to be exactly evenly divided among all of the voxel servers... and allocate 1 PPS + // for each unknown jurisdiction server + perServerPPS = (totalPPS / inViewServers) - (unknownJurisdictionServers * perUnknownServer); + } else { + if (unknownJurisdictionServers > 0) { + perUnknownServer = (totalPPS / unknownJurisdictionServers); + } + } + + if (wantExtraDebugging && unknownJurisdictionServers > 0) { + qDebug("perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer); + } + + NodeList* nodeList = NodeList::getInstance(); + + foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { + // only send to the NodeTypes that are serverType + if (node->getActiveSocket() != NULL && node->getType() == serverType) { + + + // get the server bounds for this server + QUuid nodeUUID = node->getUUID(); + + bool inView = false; + bool unknownView = false; + + // if we haven't heard from this voxel server, go ahead and send it a query, so we + // can get the jurisdiction... + if (jurisdictions.find(nodeUUID) == jurisdictions.end()) { + unknownView = true; // assume it's in view + if (wantExtraDebugging) { + qDebug() << "no known jurisdiction for node " << *node << ", assume it's visible."; + } + } else { + const JurisdictionMap& map = (jurisdictions)[nodeUUID]; + + unsigned char* rootCode = map.getRootOctalCode(); + + if (rootCode) { + VoxelPositionSize rootDetails; + voxelDetailsForCode(rootCode, rootDetails); + AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s); + serverBounds.scale(TREE_SCALE); + + ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds); + if (serverFrustumLocation != ViewFrustum::OUTSIDE) { + inView = true; + } else { + inView = false; + } + } else { + if (wantExtraDebugging) { + qDebug() << "Jurisdiction without RootCode for node " << *node << ". That's unusual!"; + } + } + } + + if (inView) { + _octreeQuery.setMaxOctreePacketsPerSecond(perServerPPS); + } else if (unknownView) { + if (wantExtraDebugging) { + qDebug() << "no known jurisdiction for node " << *node << ", give it budget of " + << perUnknownServer << " to send us jurisdiction."; + } + + // set the query's position/orientation to be degenerate in a manner that will get the scene quickly + // If there's only one server, then don't do this, and just let the normal voxel query pass through + // as expected... this way, we will actually get a valid scene if there is one to be seen + if (totalServers > 1) { + _octreeQuery.setCameraPosition(glm::vec3(-0.1,-0.1,-0.1)); + const glm::quat OFF_IN_NEGATIVE_SPACE = glm::quat(-0.5, 0, -0.5, 1.0); + _octreeQuery.setCameraOrientation(OFF_IN_NEGATIVE_SPACE); + _octreeQuery.setCameraNearClip(0.1f); + _octreeQuery.setCameraFarClip(0.1f); + if (wantExtraDebugging) { + qDebug() << "Using 'minimal' camera position for node" << *node; + } + } else { + if (wantExtraDebugging) { + qDebug() << "Using regular camera position for node" << *node; + } + } + _octreeQuery.setMaxOctreePacketsPerSecond(perUnknownServer); + } else { + _octreeQuery.setMaxOctreePacketsPerSecond(0); + } + // set up the packet for sending... + unsigned char* endOfQueryPacket = queryPacket; + + // insert packet type/version and node UUID + endOfQueryPacket += populatePacketHeader(reinterpret_cast(endOfQueryPacket), packetType); + + // encode the query data... + endOfQueryPacket += _octreeQuery.getBroadcastData(endOfQueryPacket); + + int packetLength = endOfQueryPacket - queryPacket; + + // make sure we still have an active socket + nodeList->writeDatagram(reinterpret_cast(queryPacket), packetLength, node); + } + } +} diff --git a/libraries/octree/src/OctreeHeadlessViewer.h b/libraries/octree/src/OctreeHeadlessViewer.h index 54e4a01043..c178c2b7c8 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.h +++ b/libraries/octree/src/OctreeHeadlessViewer.h @@ -12,7 +12,9 @@ #include #include +#include "JurisdictionListener.h" #include "Octree.h" +#include "OctreeQuery.h" #include "OctreeRenderer.h" #include "Octree.h" #include "ViewFrustum.h" @@ -27,8 +29,23 @@ public: virtual void init(); virtual void render() { /* swallow these */ }; + + void setJurisdictionListener(JurisdictionListener* jurisdictionListener) { _jurisdictionListener = jurisdictionListener; } + void queryOctree(); + + void setVoxelSizeScale(float sizeScale); + float getVoxelSizeScale() const { return _voxelSizeScale; } + void setBoundaryLevelAdjust(int boundaryLevelAdjust); + int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; } + int getMaxPacketsPerSecond() const { return _maxTotalPPS; } + private: ViewFrustum _viewFrustum; + JurisdictionListener* _jurisdictionListener; + OctreeQuery _octreeQuery; + float _voxelSizeScale; + int _boundaryLevelAdjust; + int _maxTotalPPS; }; #endif /* defined(__hifi__OctreeHeadlessViewer__) */ \ No newline at end of file From 1e404404c34359da0939ad731376f34e8a92a49e Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Feb 2014 13:35:59 -0800 Subject: [PATCH 09/20] next pass at seeing voxels --- assignment-client/src/Agent.cpp | 70 ++++++++++++-- assignment-client/src/Agent.h | 6 +- interface/src/Application.cpp | 4 +- interface/src/Camera.h | 2 - interface/src/VoxelPacketProcessor.cpp | 3 + libraries/octree/src/JurisdictionListener.cpp | 3 +- libraries/octree/src/JurisdictionMap.h | 3 +- libraries/octree/src/OctreeHeadlessViewer.cpp | 96 ++++++++++++++++++- libraries/octree/src/OctreeHeadlessViewer.h | 28 +++++- libraries/octree/src/OctreeRenderer.cpp | 28 +++--- libraries/octree/src/ViewFrustum.cpp | 4 +- libraries/octree/src/ViewFrustum.h | 5 + 12 files changed, 213 insertions(+), 39 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 104f65d7d9..db7e0dc2a3 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -39,6 +39,7 @@ void Agent::readPendingDatagrams() { while (readAvailableDatagram(receivedPacket, senderSockAddr)) { if (nodeList->packetVersionAndHashMatch(receivedPacket)) { PacketType datagramPacketType = packetTypeForPacket(receivedPacket); + if (datagramPacketType == PacketTypeJurisdiction) { int headerBytes = numBytesForPacketHeader(receivedPacket); @@ -48,12 +49,12 @@ void Agent::readPendingDatagrams() { // PacketType_JURISDICTION, first byte is the node type... switch (receivedPacket[headerBytes]) { case NodeType::VoxelServer: - _scriptEngine.getVoxelsScriptingInterface()->getJurisdictionListener()->queueReceivedPacket(matchedNode, - receivedPacket); + _scriptEngine.getVoxelsScriptingInterface()->getJurisdictionListener()-> + queueReceivedPacket(matchedNode,receivedPacket); break; case NodeType::ParticleServer: - _scriptEngine.getParticlesScriptingInterface()->getJurisdictionListener()->queueReceivedPacket(matchedNode, - receivedPacket); + _scriptEngine.getParticlesScriptingInterface()->getJurisdictionListener()-> + queueReceivedPacket(matchedNode, receivedPacket); break; } } @@ -63,7 +64,46 @@ void Agent::readPendingDatagrams() { Particle::handleAddParticleResponse(receivedPacket); // also give our local particle tree a chance to remap any internal locally created particles - _particleTree.handleAddParticleResponse(receivedPacket); + _particleViewer.getTree()->handleAddParticleResponse(receivedPacket); + + } else if (datagramPacketType == PacketTypeParticleData + || datagramPacketType == PacketTypeParticleErase + || datagramPacketType == PacketTypeOctreeStats + || datagramPacketType == PacketTypeVoxelData + ) { + SharedNodePointer sourceNode = nodeList->sendingNodeForPacket(receivedPacket); + QByteArray mutablePacket = receivedPacket; + ssize_t messageLength = mutablePacket.size(); + + if (datagramPacketType == PacketTypeOctreeStats) { + + int statsMessageLength = OctreeHeadlessViewer::parseOctreeStats(mutablePacket, sourceNode); + if (messageLength > statsMessageLength) { + mutablePacket = mutablePacket.mid(statsMessageLength); + + // 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 + // need to use numBytesArithmeticCodingFromBuffer()... + if (!NodeList::getInstance()->packetVersionAndHashMatch(receivedPacket)) { + return; // bail since piggyback data doesn't match our versioning + } + } 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 + } + + datagramPacketType = packetTypeForPacket(mutablePacket); + + } // fall through to piggyback message + + if (datagramPacketType == PacketTypeParticleData || datagramPacketType == PacketTypeParticleErase) { + _particleViewer.processDatagram(mutablePacket, sourceNode); + } + + if (datagramPacketType == PacketTypeVoxelData) { + _voxelViewer.processDatagram(mutablePacket, sourceNode); + } + } else { NodeList::getInstance()->processNodeData(senderSockAddr, receivedPacket); } @@ -110,9 +150,6 @@ void Agent::run() { connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes())); silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000); - // tell our script engine about our local particle tree - _scriptEngine.getParticlesScriptingInterface()->setParticleTree(&_particleTree); - // setup an Avatar for the script to use AvatarData scriptedAvatar; @@ -126,6 +163,21 @@ void Agent::run() { // register ourselves to the script engine _scriptEngine.registerGlobalObject("Agent", this); + _scriptEngine.init(); // must be done before we set up the viewers + + _scriptEngine.registerGlobalObject("VoxelViewer", &_voxelViewer); + // connect the VoxelViewer and the VoxelScriptingInterface to each other + JurisdictionListener* voxelJL = _scriptEngine.getVoxelsScriptingInterface()->getJurisdictionListener(); + _voxelViewer.setJurisdictionListener(voxelJL); + _voxelViewer.init(); + _scriptEngine.getVoxelsScriptingInterface()->setVoxelTree(_voxelViewer.getTree()); + + _scriptEngine.registerGlobalObject("ParticleViewer", &_particleViewer); + JurisdictionListener* particleJL = _scriptEngine.getParticlesScriptingInterface()->getJurisdictionListener(); + _particleViewer.setJurisdictionListener(particleJL); + _particleViewer.init(); + _scriptEngine.getParticlesScriptingInterface()->setParticleTree(_particleViewer.getTree()); + _scriptEngine.setScriptContents(scriptContents); - _scriptEngine.run(); + _scriptEngine.run(); } diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index 1502093d5b..6d37f66563 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -17,9 +17,11 @@ #include #include +#include #include #include #include +#include class Agent : public ThreadedAssignment { @@ -41,9 +43,11 @@ signals: void willSendVisualDataCallback(); private: ScriptEngine _scriptEngine; - ParticleTree _particleTree; VoxelEditPacketSender _voxelEditSender; ParticleEditPacketSender _particleEditSender; + + ParticleTreeHeadlessViewer _particleViewer; + VoxelTreeHeadlessViewer _voxelViewer; }; #endif /* defined(__hifi__Agent__) */ diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2ebe556016..6d6920c588 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3404,7 +3404,7 @@ void Application::nodeKilled(SharedNodePointer node) { } // If the voxel server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server - _voxelServerJurisdictions.erase(nodeUUID); + _voxelServerJurisdictions.erase(_voxelServerJurisdictions.find(nodeUUID)); } // also clean up scene stats for that server @@ -3435,7 +3435,7 @@ void Application::nodeKilled(SharedNodePointer node) { } // If the voxel server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server - _particleServerJurisdictions.erase(nodeUUID); + _particleServerJurisdictions.erase(_particleServerJurisdictions.find(nodeUUID)); } // also clean up scene stats for that server diff --git a/interface/src/Camera.h b/interface/src/Camera.h index b5bf6ea0b7..81632f4424 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -14,8 +14,6 @@ #include #include -const float DEFAULT_FIELD_OF_VIEW_DEGREES = 90.0f; - enum CameraMode { CAMERA_MODE_NULL = -1, diff --git a/interface/src/VoxelPacketProcessor.cpp b/interface/src/VoxelPacketProcessor.cpp index dce391e587..142285664e 100644 --- a/interface/src/VoxelPacketProcessor.cpp +++ b/interface/src/VoxelPacketProcessor.cpp @@ -48,6 +48,9 @@ void VoxelPacketProcessor::processPacket(const SharedNodePointer& sendingNode, c wasStatsPacket = true; if (messageLength > statsMessageLength) { mutablePacket = mutablePacket.mid(statsMessageLength); + + // 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 (!NodeList::getInstance()->packetVersionAndHashMatch(packet)) { return; // bail since piggyback data doesn't match our versioning } diff --git a/libraries/octree/src/JurisdictionListener.cpp b/libraries/octree/src/JurisdictionListener.cpp index 20e5af012f..1ad6c69912 100644 --- a/libraries/octree/src/JurisdictionListener.cpp +++ b/libraries/octree/src/JurisdictionListener.cpp @@ -62,8 +62,7 @@ bool JurisdictionListener::queueJurisdictionRequest() { } void JurisdictionListener::processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet) { - //qDebug() << "JurisdictionListener::processPacket()"; - if (packetTypeForPacket(packet) == PacketTypeJurisdictionRequest && sendingNode) { + if (packetTypeForPacket(packet) == PacketTypeJurisdiction && sendingNode) { QUuid nodeUUID = sendingNode->getUUID(); JurisdictionMap map; map.unpackFromMessage(reinterpret_cast(packet.data()), packet.size()); diff --git a/libraries/octree/src/JurisdictionMap.h b/libraries/octree/src/JurisdictionMap.h index 219429712e..06305254d1 100644 --- a/libraries/octree/src/JurisdictionMap.h +++ b/libraries/octree/src/JurisdictionMap.h @@ -79,7 +79,8 @@ private: /// Map between node IDs and their reported JurisdictionMap. Typically used by classes that need to know which nodes are /// managing which jurisdictions. -typedef std::map NodeToJurisdictionMap; +typedef QMap NodeToJurisdictionMap; +typedef QMap::iterator NodeToJurisdictionMapIterator; #endif /* defined(__hifi__JurisdictionMap__) */ diff --git a/libraries/octree/src/OctreeHeadlessViewer.cpp b/libraries/octree/src/OctreeHeadlessViewer.cpp index 7cf586cbb2..55a0729742 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.cpp +++ b/libraries/octree/src/OctreeHeadlessViewer.cpp @@ -12,7 +12,15 @@ #include "OctreeHeadlessViewer.h" OctreeHeadlessViewer::OctreeHeadlessViewer() : - OctreeRenderer() { + OctreeRenderer(), + _voxelSizeScale(DEFAULT_OCTREE_SIZE_SCALE), + _boundaryLevelAdjust(0), + _maxPacketsPerSecond(DEFAULT_MAX_OCTREE_PPS) +{ + _viewFrustum.setFieldOfView(DEFAULT_FIELD_OF_VIEW_DEGREES); + _viewFrustum.setAspectRatio(DEFAULT_ASPECT_RATIO); + _viewFrustum.setNearClip(DEFAULT_NEAR_CLIP); + _viewFrustum.setFarClip(TREE_SCALE); } OctreeHeadlessViewer::~OctreeHeadlessViewer() { @@ -30,6 +38,17 @@ void OctreeHeadlessViewer::queryOctree() { bool wantExtraDebugging = false; + if (wantExtraDebugging) { + qDebug() << "OctreeHeadlessViewer::queryOctree() _jurisdictionListener=" << _jurisdictionListener; + qDebug() << "---------------"; + qDebug() << "_jurisdictionListener=" << _jurisdictionListener; + qDebug() << "Jurisdictions..."; + for (NodeToJurisdictionMapIterator i = jurisdictions.begin(); i != jurisdictions.end(); ++i) { + qDebug() << i.key() << ": " << &i.value(); + } + qDebug() << "---------------"; + } + // These will be the same for all servers, so we can set them up once and then reuse for each server we send to. _octreeQuery.setWantLowResMoving(true); _octreeQuery.setWantColor(true); @@ -87,7 +106,7 @@ void OctreeHeadlessViewer::queryOctree() { } } - if (wantExtraDebugging && unknownJurisdictionServers > 0) { + if (wantExtraDebugging) { qDebug("Servers: total %d, in view %d, unknown jurisdiction %d", totalServers, inViewServers, unknownJurisdictionServers); } @@ -108,7 +127,7 @@ void OctreeHeadlessViewer::queryOctree() { } } - if (wantExtraDebugging && unknownJurisdictionServers > 0) { + if (wantExtraDebugging) { qDebug("perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer); } @@ -158,6 +177,9 @@ void OctreeHeadlessViewer::queryOctree() { if (inView) { _octreeQuery.setMaxOctreePacketsPerSecond(perServerPPS); + if (wantExtraDebugging) { + qDebug() << "inView for node " << *node << ", give it budget of " << perServerPPS; + } } else if (unknownView) { if (wantExtraDebugging) { qDebug() << "no known jurisdiction for node " << *node << ", give it budget of " @@ -201,3 +223,71 @@ void OctreeHeadlessViewer::queryOctree() { } } } + + +int OctreeHeadlessViewer::parseOctreeStats(const QByteArray& packet, const SharedNodePointer& sourceNode) { + // 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 + // determine which server it belongs to + OctreeSceneStats temp; + int statsMessageLength = temp.unpackFromMessage(reinterpret_cast(packet.data()), packet.size()); + return statsMessageLength; + +#if 0 // CURRENTLY NOT YET IMPLEMENTED + + // quick fix for crash... why would voxelServer be NULL? + if (sourceNode) { + QUuid nodeUUID = sendingNode->getUUID(); + + // now that we know the node ID, let's add these stats to the stats for that node... + _voxelSceneStatsLock.lockForWrite(); + if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) { + _octreeServerSceneStats[nodeUUID].unpackFromMessage(reinterpret_cast(packet.data()), + packet.size()); + } else { + _octreeServerSceneStats[nodeUUID] = temp; + } + _voxelSceneStatsLock.unlock(); + + VoxelPositionSize rootDetails; + voxelDetailsForCode(temp.getJurisdictionRoot(), rootDetails); + + // see if this is the first we've heard of this node... + NodeToJurisdictionMap* jurisdiction = NULL; + if (sendingNode->getType() == NodeType::VoxelServer) { + jurisdiction = &_voxelServerJurisdictions; + } else { + jurisdiction = &_particleServerJurisdictions; + } + + + if (jurisdiction->find(nodeUUID) == jurisdiction->end()) { + printf("stats from new server... v[%f, %f, %f, %f]\n", + rootDetails.x, rootDetails.y, rootDetails.z, rootDetails.s); + + // Add the jurisditionDetails object to the list of "fade outs" + if (!Menu::getInstance()->isOptionChecked(MenuOption::DontFadeOnVoxelServerChanges)) { + VoxelFade fade(VoxelFade::FADE_OUT, NODE_ADDED_RED, NODE_ADDED_GREEN, NODE_ADDED_BLUE); + fade.voxelDetails = rootDetails; + const float slightly_smaller = 0.99f; + fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller; + _voxelFades.push_back(fade); + } + } + // store jurisdiction details for later use + // This is bit of fiddling is because JurisdictionMap assumes it is the owner of the values used to construct it + // but VoxelSceneStats thinks it's just returning a reference to it's contents. So we need to make a copy of the + // details from the VoxelSceneStats to construct the JurisdictionMap + JurisdictionMap jurisdictionMap; + jurisdictionMap.copyContents(temp.getJurisdictionRoot(), temp.getJurisdictionEndNodes()); + (*jurisdiction)[nodeUUID] = jurisdictionMap; + } + return statsMessageLength; +#endif +} + +void OctreeHeadlessViewer::trackIncomingOctreePacket(const QByteArray& packet, + const SharedNodePointer& sendingNode, bool wasStatsPacket) { + +} diff --git a/libraries/octree/src/OctreeHeadlessViewer.h b/libraries/octree/src/OctreeHeadlessViewer.h index c178c2b7c8..c058809acd 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.h +++ b/libraries/octree/src/OctreeHeadlessViewer.h @@ -12,10 +12,13 @@ #include #include + #include "JurisdictionListener.h" #include "Octree.h" +#include "OctreeConstants.h" #include "OctreeQuery.h" #include "OctreeRenderer.h" +#include "OctreeSceneStats.h" #include "Octree.h" #include "ViewFrustum.h" @@ -31,13 +34,30 @@ public: virtual void render() { /* swallow these */ }; void setJurisdictionListener(JurisdictionListener* jurisdictionListener) { _jurisdictionListener = jurisdictionListener; } + + static int parseOctreeStats(const QByteArray& packet, const SharedNodePointer& sourceNode); + static void trackIncomingOctreePacket(const QByteArray& packet, const SharedNodePointer& sendingNode, bool wasStatsPacket); + +public slots: void queryOctree(); - void setVoxelSizeScale(float sizeScale); + // setters for camera attributes + void setPosition(const glm::vec3& position) { _viewFrustum.setPosition(position); } + void setOrientation(const glm::quat& orientation) { _viewFrustum.setOrientation(orientation); } + + // setters for LOD and PPS + void setVoxelSizeScale(float sizeScale) { _voxelSizeScale = sizeScale; } + void setBoundaryLevelAdjust(int boundaryLevelAdjust) { _boundaryLevelAdjust = boundaryLevelAdjust; } + void setMaxPacketsPerSecond(int maxPacketsPerSecond) { _maxPacketsPerSecond = maxPacketsPerSecond; } + + // getters for camera attributes + const glm::vec3& getPosition() const { return _viewFrustum.getPosition(); } + const glm::quat& getOrientation() const { return _viewFrustum.getOrientation(); } + + // getters for LOD and PPS float getVoxelSizeScale() const { return _voxelSizeScale; } - void setBoundaryLevelAdjust(int boundaryLevelAdjust); int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; } - int getMaxPacketsPerSecond() const { return _maxTotalPPS; } + int getMaxPacketsPerSecond() const { return _maxPacketsPerSecond; } private: ViewFrustum _viewFrustum; @@ -45,7 +65,7 @@ private: OctreeQuery _octreeQuery; float _voxelSizeScale; int _boundaryLevelAdjust; - int _maxTotalPPS; + int _maxPacketsPerSecond; }; #endif /* defined(__hifi__OctreeHeadlessViewer__) */ \ No newline at end of file diff --git a/libraries/octree/src/OctreeRenderer.cpp b/libraries/octree/src/OctreeRenderer.cpp index b3d2ea45e3..06007cb0dc 100644 --- a/libraries/octree/src/OctreeRenderer.cpp +++ b/libraries/octree/src/OctreeRenderer.cpp @@ -27,44 +27,48 @@ OctreeRenderer::~OctreeRenderer() { } void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) { + bool extraDebugging = false; + + if (extraDebugging) { + qDebug() << "OctreeRenderer::processDatagram()"; + } + + if (!_tree) { + qDebug() << "OctreeRenderer::processDatagram() called before init, calling init()..."; + this->init(); + } + bool showTimingDetails = false; // Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - bool extraDebugging = false; // Menu::getInstance()->isOptionChecked(MenuOption::ExtraDebugging) PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram()",showTimingDetails); - const unsigned char* packetData = (const unsigned char*)dataByteArray.constData(); int packetLength = dataByteArray.size(); - - unsigned char command = *packetData; - + PacketType command = packetTypeForPacket(dataByteArray); int numBytesPacketHeader = numBytesForPacketHeader(dataByteArray); QUuid sourceUUID = uuidFromPacketHeader(dataByteArray); - - PacketType expectedType = getExpectedPacketType(); if(command == expectedType) { 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(dataByteArray.data()) + numBytesPacketHeader; 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); - + bool packetIsColored = oneAtBit(flags, PACKET_IS_COLOR_BIT); bool packetIsCompressed = oneAtBit(flags, PACKET_IS_COMPRESSED_BIT); OCTREE_PACKET_SENT_TIME arrivedAt = usecTimestampNow(); int clockSkew = sourceNode ? sourceNode->getClockSkewUsec() : 0; int flightTime = arrivedAt - sentAt + clockSkew; - + OCTREE_PACKET_INTERNAL_SECTION_SIZE sectionLength = 0; int dataBytes = packetLength - (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE); diff --git a/libraries/octree/src/ViewFrustum.cpp b/libraries/octree/src/ViewFrustum.cpp index b6fdcc3e99..e97e05dcb9 100644 --- a/libraries/octree/src/ViewFrustum.cpp +++ b/libraries/octree/src/ViewFrustum.cpp @@ -54,11 +54,9 @@ void ViewFrustum::setOrientation(const glm::quat& orientationAsQuaternion) { _direction = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_FRONT, 0.0f)); } -///////////////////////////////////////////////////////////////////////////////////// // ViewFrustum::calculateViewFrustum() // -// Description: this will calculate the view frustum bounds for a given position -// and direction +// Description: this will calculate the view frustum bounds for a given position and direction // // Notes on how/why this works: // http://www.lighthouse3d.com/tutorials/view-frustum-culling/view-frustums-shape/ diff --git a/libraries/octree/src/ViewFrustum.h b/libraries/octree/src/ViewFrustum.h index bbce7124e0..36d3346cdb 100644 --- a/libraries/octree/src/ViewFrustum.h +++ b/libraries/octree/src/ViewFrustum.h @@ -17,9 +17,14 @@ #include "AABox.h" #include "Plane.h" +#include "OctreeConstants.h" #include "OctreeProjectedPolygon.h" const float DEFAULT_KEYHOLE_RADIUS = 3.0f; +const float DEFAULT_FIELD_OF_VIEW_DEGREES = 90.0f; +const float DEFAULT_ASPECT_RATIO = 16.f/9.f; +const float DEFAULT_NEAR_CLIP = 0.08f; +const float DEFAULT_FAR_CLIP = 50.0f * TREE_SCALE; class ViewFrustum { public: From 08b7b86c3ed2efc28a7c792a67e58490ac59d89f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Feb 2014 13:55:16 -0800 Subject: [PATCH 10/20] next pass at seeing voxels --- examples/seeingVoxelsExample.js | 63 +++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 examples/seeingVoxelsExample.js diff --git a/examples/seeingVoxelsExample.js b/examples/seeingVoxelsExample.js new file mode 100644 index 0000000000..46e06d201d --- /dev/null +++ b/examples/seeingVoxelsExample.js @@ -0,0 +1,63 @@ +// +// seeingVoxelsExample.js +// hifi +// +// Created by Brad Hefta-Gaub on 2/26/14 +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// +// This is an example script +// + +var count = 0; +var yawDirection = -1; +var yaw = 45; +var yawMax = 70; +var yawMin = 20; + +var isLocal = true; + +// set up our VoxelViewer with a position and orientation +var orientation = Quat.fromPitchYawRoll(0, yaw, 0); + +if (isLocal) { + MyAvatar.position = {x: 10, y: 0, z: 10}; + MyAvatar.orientation = orientation; +} else { + VoxelViewer.setPosition({x: 10, y: 0, z: 10}); + VoxelViewer.setOrientation(orientation); + VoxelViewer.queryOctree(); + Agent.isAvatar = true; +} + +function keepLooking() { + //print("count =" + count); + count++; + if (count % 10 == 0) { + yaw += yawDirection; + orientation = Quat.fromPitchYawRoll(0, yaw, 0); + if (yaw > yawMax || yaw < yawMin) { + yawDirection = yawDirection * -1; + } + + print("calling VoxelViewer.queryOctree()... count=" + count + " yaw=" + yaw); + + if (isLocal) { + MyAvatar.orientation = orientation; + } else { + VoxelViewer.setOrientation(orientation); + VoxelViewer.queryOctree(); + } + + } +} + +function scriptEnding() { + print("SCRIPT ENDNG!!!\n"); +} + +// register the call back so it fires before each data send +Script.willSendVisualDataCallback.connect(keepLooking); + +// register our scriptEnding callback +Script.scriptEnding.connect(scriptEnding); + From d361c75b506d6194a004b238219c79bba8364632 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Feb 2014 14:16:22 -0800 Subject: [PATCH 11/20] more work on seeing voxels --- examples/seeingVoxelsExample.js | 29 +++++++--- libraries/octree/src/OctreeHeadlessViewer.cpp | 58 +------------------ libraries/octree/src/OctreeHeadlessViewer.h | 2 + 3 files changed, 25 insertions(+), 64 deletions(-) diff --git a/examples/seeingVoxelsExample.js b/examples/seeingVoxelsExample.js index 46e06d201d..98445990a8 100644 --- a/examples/seeingVoxelsExample.js +++ b/examples/seeingVoxelsExample.js @@ -14,23 +14,29 @@ var yaw = 45; var yawMax = 70; var yawMin = 20; -var isLocal = true; +var isLocal = false; // set up our VoxelViewer with a position and orientation var orientation = Quat.fromPitchYawRoll(0, yaw, 0); -if (isLocal) { - MyAvatar.position = {x: 10, y: 0, z: 10}; - MyAvatar.orientation = orientation; -} else { - VoxelViewer.setPosition({x: 10, y: 0, z: 10}); - VoxelViewer.setOrientation(orientation); - VoxelViewer.queryOctree(); - Agent.isAvatar = true; +function init() { + if (isLocal) { + MyAvatar.position = {x: 10, y: 0, z: 10}; + MyAvatar.orientation = orientation; + } else { + VoxelViewer.setPosition({x: 10, y: 0, z: 10}); + VoxelViewer.setOrientation(orientation); + VoxelViewer.queryOctree(); + Agent.isAvatar = true; + } } function keepLooking() { //print("count =" + count); + + if (count == 0) { + init(); + } count++; if (count % 10 == 0) { yaw += yawDirection; @@ -46,6 +52,7 @@ function keepLooking() { } else { VoxelViewer.setOrientation(orientation); VoxelViewer.queryOctree(); + print("VoxelViewer.getOctreeElementsCount()=" + VoxelViewer.getOctreeElementsCount()); } } @@ -61,3 +68,7 @@ Script.willSendVisualDataCallback.connect(keepLooking); // register our scriptEnding callback Script.scriptEnding.connect(scriptEnding); + +// test for local... +Menu.isOptionChecked("Voxels"); +isLocal = true; // will only get here on local client diff --git a/libraries/octree/src/OctreeHeadlessViewer.cpp b/libraries/octree/src/OctreeHeadlessViewer.cpp index 55a0729742..4ab85e7de8 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.cpp +++ b/libraries/octree/src/OctreeHeadlessViewer.cpp @@ -226,65 +226,13 @@ void OctreeHeadlessViewer::queryOctree() { int OctreeHeadlessViewer::parseOctreeStats(const QByteArray& packet, const SharedNodePointer& sourceNode) { - // 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 - // determine which server it belongs to OctreeSceneStats temp; int statsMessageLength = temp.unpackFromMessage(reinterpret_cast(packet.data()), packet.size()); + + // TODO: actually do something with these stats, like expose them to JS... + return statsMessageLength; - -#if 0 // CURRENTLY NOT YET IMPLEMENTED - - // quick fix for crash... why would voxelServer be NULL? - if (sourceNode) { - QUuid nodeUUID = sendingNode->getUUID(); - - // now that we know the node ID, let's add these stats to the stats for that node... - _voxelSceneStatsLock.lockForWrite(); - if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) { - _octreeServerSceneStats[nodeUUID].unpackFromMessage(reinterpret_cast(packet.data()), - packet.size()); - } else { - _octreeServerSceneStats[nodeUUID] = temp; - } - _voxelSceneStatsLock.unlock(); - - VoxelPositionSize rootDetails; - voxelDetailsForCode(temp.getJurisdictionRoot(), rootDetails); - - // see if this is the first we've heard of this node... - NodeToJurisdictionMap* jurisdiction = NULL; - if (sendingNode->getType() == NodeType::VoxelServer) { - jurisdiction = &_voxelServerJurisdictions; - } else { - jurisdiction = &_particleServerJurisdictions; - } - - - if (jurisdiction->find(nodeUUID) == jurisdiction->end()) { - printf("stats from new server... v[%f, %f, %f, %f]\n", - rootDetails.x, rootDetails.y, rootDetails.z, rootDetails.s); - - // Add the jurisditionDetails object to the list of "fade outs" - if (!Menu::getInstance()->isOptionChecked(MenuOption::DontFadeOnVoxelServerChanges)) { - VoxelFade fade(VoxelFade::FADE_OUT, NODE_ADDED_RED, NODE_ADDED_GREEN, NODE_ADDED_BLUE); - fade.voxelDetails = rootDetails; - const float slightly_smaller = 0.99f; - fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller; - _voxelFades.push_back(fade); - } - } - // store jurisdiction details for later use - // This is bit of fiddling is because JurisdictionMap assumes it is the owner of the values used to construct it - // but VoxelSceneStats thinks it's just returning a reference to it's contents. So we need to make a copy of the - // details from the VoxelSceneStats to construct the JurisdictionMap - JurisdictionMap jurisdictionMap; - jurisdictionMap.copyContents(temp.getJurisdictionRoot(), temp.getJurisdictionEndNodes()); - (*jurisdiction)[nodeUUID] = jurisdictionMap; - } - return statsMessageLength; -#endif } void OctreeHeadlessViewer::trackIncomingOctreePacket(const QByteArray& packet, diff --git a/libraries/octree/src/OctreeHeadlessViewer.h b/libraries/octree/src/OctreeHeadlessViewer.h index c058809acd..fc32dbc682 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.h +++ b/libraries/octree/src/OctreeHeadlessViewer.h @@ -59,6 +59,8 @@ public slots: int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; } int getMaxPacketsPerSecond() const { return _maxPacketsPerSecond; } + unsigned getOctreeElementsCount() const { return _tree->getOctreeElementsCount(); } + private: ViewFrustum _viewFrustum; JurisdictionListener* _jurisdictionListener; From 39ba98f3b132acc89f6f4cf8404a8ab5c5396981 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Feb 2014 14:23:58 -0800 Subject: [PATCH 12/20] fixed a comment --- assignment-client/src/Agent.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index db7e0dc2a3..b61410f22b 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -81,19 +81,17 @@ void Agent::readPendingDatagrams() { if (messageLength > statsMessageLength) { mutablePacket = mutablePacket.mid(statsMessageLength); - // TODO: this does not look correct, the goal is to test the packet version for the piggyback, but + // TODO: this needs to be fixed, the goal is to test the packet version for the piggyback, but // this is testing the version and hash of the original packet // need to use numBytesArithmeticCodingFromBuffer()... if (!NodeList::getInstance()->packetVersionAndHashMatch(receivedPacket)) { return; // bail since piggyback data doesn't match our versioning } } 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 } datagramPacketType = packetTypeForPacket(mutablePacket); - } // fall through to piggyback message if (datagramPacketType == PacketTypeParticleData || datagramPacketType == PacketTypeParticleErase) { From 1603c1f38ce33fa7ff05c8cbf811e5864b09d5fa Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Feb 2014 16:20:33 -0800 Subject: [PATCH 13/20] work on client stats and max total packets per second --- .../src/octree/OctreeQueryNode.cpp | 4 +++ .../src/octree/OctreeSendThread.cpp | 11 +++++++ .../src/octree/OctreeSendThread.h | 1 + assignment-client/src/octree/OctreeServer.cpp | 30 +++++++++++++++---- assignment-client/src/octree/OctreeServer.h | 8 +++++ 5 files changed, 48 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/octree/OctreeQueryNode.cpp b/assignment-client/src/octree/OctreeQueryNode.cpp index 58aea5c792..3f18ccbb34 100644 --- a/assignment-client/src/octree/OctreeQueryNode.cpp +++ b/assignment-client/src/octree/OctreeQueryNode.cpp @@ -41,6 +41,7 @@ void OctreeQueryNode::initializeOctreeSendThread(OctreeServer* octreeServer, con // Create octree sending thread... _octreeSendThread = new OctreeSendThread(nodeUUID, octreeServer); _octreeSendThread->initialize(true); + //connect(_octreeSendThread, SIGNAL(finished()), _octreeSendThread, SLOT(deleteLater())); } bool OctreeQueryNode::packetIsDuplicate() const { @@ -159,8 +160,11 @@ void OctreeQueryNode::writeToPacket(const unsigned char* buffer, int bytes) { } OctreeQueryNode::~OctreeQueryNode() { + //qDebug() << "OctreeQueryNode::~OctreeQueryNode() this=" << this; if (_octreeSendThread) { + //qDebug() << "OctreeQueryNode::~OctreeQueryNode() calling _octreeSendThread->terminate() _octreeSendThread=" << _octreeSendThread; _octreeSendThread->terminate(); + //qDebug() << "OctreeQueryNode::~OctreeQueryNode() calling _octreeSendThread->deleteLater() _octreeSendThread=" << _octreeSendThread; _octreeSendThread->deleteLater(); } diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 121e80b808..5141eaa84b 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -22,9 +22,20 @@ OctreeSendThread::OctreeSendThread(const QUuid& nodeUUID, OctreeServer* myServer _myServer(myServer), _packetData() { + qDebug() << "client connected this=" << this; + _myServer->clientConnected(); } +OctreeSendThread::~OctreeSendThread() { + qDebug() << "OctreeSendThread::~OctreeSendThread()... this=" << this; + qDebug() << "client disconnected this=" << this; + _myServer->clientDisconnected(); +} + + bool OctreeSendThread::process() { + qDebug() << "OctreeSendThread::process() this=" << this; + quint64 start = usecTimestampNow(); bool gotLock = false; diff --git a/assignment-client/src/octree/OctreeSendThread.h b/assignment-client/src/octree/OctreeSendThread.h index ab7a7231ab..3554dcdfef 100644 --- a/assignment-client/src/octree/OctreeSendThread.h +++ b/assignment-client/src/octree/OctreeSendThread.h @@ -20,6 +20,7 @@ class OctreeSendThread : public GenericThread { public: OctreeSendThread(const QUuid& nodeUUID, OctreeServer* myServer); + virtual ~OctreeSendThread(); static quint64 _totalBytes; static quint64 _totalWastedBytes; diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 1fb858c884..743f289dec 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -35,6 +35,7 @@ OctreeServer::OctreeServer(const QByteArray& packet) : _parsedArgV(NULL), _httpManager(NULL), _packetsPerClientPerInterval(10), + _packetsTotalPerInterval(DEFAULT_PACKETS_PER_INTERVAL), _tree(NULL), _wantPersist(true), _debugSending(false), @@ -45,7 +46,8 @@ OctreeServer::OctreeServer(const QByteArray& packet) : _octreeInboundPacketProcessor(NULL), _persistThread(NULL), _started(time(0)), - _startedUSecs(usecTimestampNow()) + _startedUSecs(usecTimestampNow()), + _clientCount(0) { _instance = this; } @@ -234,6 +236,9 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString& quint64 totalBytesOfColor = OctreePacketData::getTotalBytesOfColor(); const int COLUMN_WIDTH = 10; + statsString += QString(" Total Clients Connected: %1 clients\r\n\r\n") + .arg(locale.toString((uint)getCurrentClientCount()).rightJustified(COLUMN_WIDTH, ' ')); + statsString += QString(" Total Outbound Packets: %1 packets\r\n") .arg(locale.toString((uint)totalOutboundPackets).rightJustified(COLUMN_WIDTH, ' ')); statsString += QString(" Total Outbound Bytes: %1 bytes\r\n") @@ -612,15 +617,28 @@ void OctreeServer::run() { } // Check to see if the user passed in a command line option for setting packet send rate - const char* PACKETS_PER_SECOND = "--packetsPerSecond"; - const char* packetsPerSecond = getCmdOption(_argc, _argv, PACKETS_PER_SECOND); - if (packetsPerSecond) { - _packetsPerClientPerInterval = atoi(packetsPerSecond) / INTERVALS_PER_SECOND; + const char* PACKETS_PER_SECOND_PER_CLIENT_MAX = "--packetsPerSecondPerClientMax"; + const char* packetsPerSecondPerClientMax = getCmdOption(_argc, _argv, PACKETS_PER_SECOND_PER_CLIENT_MAX); + if (packetsPerSecondPerClientMax) { + _packetsPerClientPerInterval = atoi(packetsPerSecondPerClientMax) / INTERVALS_PER_SECOND; if (_packetsPerClientPerInterval < 1) { _packetsPerClientPerInterval = 1; } - qDebug("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d", packetsPerSecond, _packetsPerClientPerInterval); } + qDebug("packetsPerSecondPerClientMax=%s _packetsPerClientPerInterval=%d", + packetsPerSecondPerClientMax, _packetsPerClientPerInterval); + + // Check to see if the user passed in a command line option for setting packet send rate + const char* PACKETS_PER_SECOND_TOTAL_MAX = "--packetsPerSecondTotalMax"; + const char* packetsPerSecondTotalMax = getCmdOption(_argc, _argv, PACKETS_PER_SECOND_TOTAL_MAX); + if (packetsPerSecondTotalMax) { + _packetsTotalPerInterval = atoi(packetsPerSecondTotalMax) / INTERVALS_PER_SECOND; + if (_packetsTotalPerInterval < 1) { + _packetsTotalPerInterval = 1; + } + } + qDebug("packetsPerSecondTotalMax=%s _packetsTotalPerInterval=%d", + packetsPerSecondTotalMax, _packetsTotalPerInterval); HifiSockAddr senderSockAddr; diff --git a/assignment-client/src/octree/OctreeServer.h b/assignment-client/src/octree/OctreeServer.h index e221011b76..5c2518fadb 100644 --- a/assignment-client/src/octree/OctreeServer.h +++ b/assignment-client/src/octree/OctreeServer.h @@ -24,6 +24,8 @@ #include "OctreeServerConsts.h" #include "OctreeInboundPacketProcessor.h" +const int DEFAULT_PACKETS_PER_INTERVAL = 2000; // some 120,000 packets per second total + /// Handles assignments of type OctreeServer - sending octrees to various clients. class OctreeServer : public ThreadedAssignment, public HTTPRequestHandler { Q_OBJECT @@ -42,6 +44,9 @@ public: JurisdictionMap* getJurisdiction() { return _jurisdiction; } int getPacketsPerClientPerInterval() const { return _packetsPerClientPerInterval; } + int getCurrentClientCount() const { return _clientCount; } + void clientConnected() { _clientCount++; } + void clientDisconnected() { _clientCount--; } bool isInitialLoadComplete() const { return (_persistThread) ? _persistThread->isInitialLoadComplete() : true; } bool isPersistEnabled() const { return (_persistThread) ? true : false; } @@ -81,6 +86,7 @@ protected: char _persistFilename[MAX_FILENAME_LENGTH]; int _packetsPerClientPerInterval; + int _packetsTotalPerInterval; Octree* _tree; // this IS a reaveraging tree bool _wantPersist; bool _debugSending; @@ -95,6 +101,8 @@ protected: time_t _started; quint64 _startedUSecs; + + int _clientCount; }; #endif // __octree_server__OctreeServer__ From a34aef658d6fb5e1aa82a843c8ec0e746b0d0268 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Feb 2014 19:42:22 -0800 Subject: [PATCH 14/20] cleanup OctreeSendThread correctly --- assignment-client/src/octree/OctreeQueryNode.cpp | 3 ++- assignment-client/src/octree/OctreeSendThread.cpp | 7 ++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/octree/OctreeQueryNode.cpp b/assignment-client/src/octree/OctreeQueryNode.cpp index 3f18ccbb34..30a06e2c85 100644 --- a/assignment-client/src/octree/OctreeQueryNode.cpp +++ b/assignment-client/src/octree/OctreeQueryNode.cpp @@ -165,7 +165,8 @@ OctreeQueryNode::~OctreeQueryNode() { //qDebug() << "OctreeQueryNode::~OctreeQueryNode() calling _octreeSendThread->terminate() _octreeSendThread=" << _octreeSendThread; _octreeSendThread->terminate(); //qDebug() << "OctreeQueryNode::~OctreeQueryNode() calling _octreeSendThread->deleteLater() _octreeSendThread=" << _octreeSendThread; - _octreeSendThread->deleteLater(); + //_octreeSendThread->deleteLater(); + delete _octreeSendThread; } delete[] _octreePacket; diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 5141eaa84b..8e7d9c37c6 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -22,20 +22,17 @@ OctreeSendThread::OctreeSendThread(const QUuid& nodeUUID, OctreeServer* myServer _myServer(myServer), _packetData() { - qDebug() << "client connected this=" << this; + qDebug() << "client connected"; _myServer->clientConnected(); } OctreeSendThread::~OctreeSendThread() { - qDebug() << "OctreeSendThread::~OctreeSendThread()... this=" << this; - qDebug() << "client disconnected this=" << this; + qDebug() << "client disconnected"; _myServer->clientDisconnected(); } bool OctreeSendThread::process() { - qDebug() << "OctreeSendThread::process() this=" << this; - quint64 start = usecTimestampNow(); bool gotLock = false; From 8c4fdbb1c624304cbd79a483d12fdd1b74e0ab1b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Feb 2014 19:44:01 -0800 Subject: [PATCH 15/20] remove dead comments --- assignment-client/src/octree/OctreeQueryNode.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/assignment-client/src/octree/OctreeQueryNode.cpp b/assignment-client/src/octree/OctreeQueryNode.cpp index 30a06e2c85..633ee3ede1 100644 --- a/assignment-client/src/octree/OctreeQueryNode.cpp +++ b/assignment-client/src/octree/OctreeQueryNode.cpp @@ -41,7 +41,6 @@ void OctreeQueryNode::initializeOctreeSendThread(OctreeServer* octreeServer, con // Create octree sending thread... _octreeSendThread = new OctreeSendThread(nodeUUID, octreeServer); _octreeSendThread->initialize(true); - //connect(_octreeSendThread, SIGNAL(finished()), _octreeSendThread, SLOT(deleteLater())); } bool OctreeQueryNode::packetIsDuplicate() const { @@ -160,12 +159,8 @@ void OctreeQueryNode::writeToPacket(const unsigned char* buffer, int bytes) { } OctreeQueryNode::~OctreeQueryNode() { - //qDebug() << "OctreeQueryNode::~OctreeQueryNode() this=" << this; if (_octreeSendThread) { - //qDebug() << "OctreeQueryNode::~OctreeQueryNode() calling _octreeSendThread->terminate() _octreeSendThread=" << _octreeSendThread; _octreeSendThread->terminate(); - //qDebug() << "OctreeQueryNode::~OctreeQueryNode() calling _octreeSendThread->deleteLater() _octreeSendThread=" << _octreeSendThread; - //_octreeSendThread->deleteLater(); delete _octreeSendThread; } From 85a42849a81300c0107bab7f41aaa4da9f3d3170 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Feb 2014 20:36:11 -0800 Subject: [PATCH 16/20] work on current client count --- assignment-client/src/octree/OctreeServer.cpp | 34 ++++++++++++++----- assignment-client/src/octree/OctreeServer.h | 12 ++++--- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 743f289dec..f2ebe4a428 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -19,6 +19,8 @@ #include "OctreeServerConsts.h" OctreeServer* OctreeServer::_instance = NULL; +int OctreeServer::_clientCount = 0; + void OctreeServer::attachQueryNodeToNode(Node* newNode) { if (newNode->getLinkedData() == NULL) { @@ -46,8 +48,7 @@ OctreeServer::OctreeServer(const QByteArray& packet) : _octreeInboundPacketProcessor(NULL), _persistThread(NULL), _started(time(0)), - _startedUSecs(usecTimestampNow()), - _clientCount(0) + _startedUSecs(usecTimestampNow()) { _instance = this; } @@ -77,8 +78,7 @@ OctreeServer::~OctreeServer() { delete _jurisdiction; _jurisdiction = NULL; - - qDebug() << "OctreeServer::run()... DONE"; + qDebug() << "OctreeServer::~OctreeServer()... DONE"; } void OctreeServer::initHTTPManager(int port) { @@ -157,10 +157,16 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString& statsString += "Uptime: "; if (hours > 0) { - statsString += QString("%1 hour%2").arg(hours).arg((hours > 1) ? "s" : ""); + statsString += QString("%1 hour").arg(hours); + if (hours > 1) { + statsString += QString("s"); + } } if (minutes > 0) { - statsString += QString("%1 minute%s").arg(minutes).arg((minutes > 1) ? "s" : ""); + statsString += QString("%1 minute").arg(minutes); + if (minutes > 1) { + statsString += QString("s"); + } } if (seconds > 0) { statsString += QString().sprintf("%.3f seconds", seconds); @@ -182,12 +188,18 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString& int minutes = (msecsElapsed/(MSECS_PER_MIN)) % MIN_PER_HOUR; int hours = (msecsElapsed/(MSECS_PER_MIN * MIN_PER_HOUR)); - statsString += QString("%1 File Load Took").arg(getMyServerName()); + statsString += QString("%1 File Load Took ").arg(getMyServerName()); if (hours > 0) { - statsString += QString("%1 hour%2").arg(hours).arg((hours > 1) ? "s" : ""); + statsString += QString("%1 hour").arg(hours); + if (hours > 1) { + statsString += QString("s"); + } } if (minutes > 0) { - statsString += QString("%1 minute%2").arg(minutes).arg((minutes > 1) ? "s" : ""); + statsString += QString("%1 minute").arg(minutes); + if (minutes > 1) { + statsString += QString("s"); + } } if (seconds >= 0) { statsString += QString().sprintf("%.3f seconds", seconds); @@ -236,6 +248,10 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString& quint64 totalBytesOfColor = OctreePacketData::getTotalBytesOfColor(); const int COLUMN_WIDTH = 10; + statsString += QString(" Configured Max PPS/Client: %1 pps/client\r\n") + .arg(locale.toString((uint)getPacketsPerClientPerSecond()).rightJustified(COLUMN_WIDTH, ' ')); + statsString += QString(" Configured Max PPS/Server: %1 pps/server\r\n\r\n") + .arg(locale.toString((uint)getPacketsTotalPerSecond()).rightJustified(COLUMN_WIDTH, ' ')); statsString += QString(" Total Clients Connected: %1 clients\r\n\r\n") .arg(locale.toString((uint)getCurrentClientCount()).rightJustified(COLUMN_WIDTH, ' ')); diff --git a/assignment-client/src/octree/OctreeServer.h b/assignment-client/src/octree/OctreeServer.h index 5c2518fadb..1dcb3352ff 100644 --- a/assignment-client/src/octree/OctreeServer.h +++ b/assignment-client/src/octree/OctreeServer.h @@ -44,9 +44,13 @@ public: JurisdictionMap* getJurisdiction() { return _jurisdiction; } int getPacketsPerClientPerInterval() const { return _packetsPerClientPerInterval; } - int getCurrentClientCount() const { return _clientCount; } - void clientConnected() { _clientCount++; } - void clientDisconnected() { _clientCount--; } + int getPacketsPerClientPerSecond() const { return getPacketsPerClientPerInterval() * INTERVALS_PER_SECOND; } + int getPacketsTotalPerInterval() const { return _packetsTotalPerInterval; } + int getPacketsTotalPerSecond() const { return getPacketsTotalPerInterval() * INTERVALS_PER_SECOND; } + + static int getCurrentClientCount() { return _clientCount; } + static void clientConnected() { _clientCount++; } + static void clientDisconnected() { _clientCount--; } bool isInitialLoadComplete() const { return (_persistThread) ? _persistThread->isInitialLoadComplete() : true; } bool isPersistEnabled() const { return (_persistThread) ? true : false; } @@ -102,7 +106,7 @@ protected: time_t _started; quint64 _startedUSecs; - int _clientCount; + static int _clientCount; }; #endif // __octree_server__OctreeServer__ From 6f1136c417323f81ffdd432805b874deabebe58e Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Feb 2014 21:21:10 -0800 Subject: [PATCH 17/20] more status page formatting, and include max total packets in packets per client interval --- assignment-client/src/octree/OctreeServer.cpp | 22 +++++++++++++++++++ assignment-client/src/octree/OctreeServer.h | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index f2ebe4a428..7bf5c12a22 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -163,12 +163,18 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString& } } if (minutes > 0) { + if (hours > 0) { + statsString += QString(" "); + } statsString += QString("%1 minute").arg(minutes); if (minutes > 1) { statsString += QString("s"); } } if (seconds > 0) { + if (hours > 0 || minutes > 0) { + statsString += QString(" "); + } statsString += QString().sprintf("%.3f seconds", seconds); } statsString += "\r\n\r\n"; @@ -196,12 +202,18 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString& } } if (minutes > 0) { + if (hours > 0) { + statsString += QString(" "); + } statsString += QString("%1 minute").arg(minutes); if (minutes > 1) { statsString += QString("s"); } } if (seconds >= 0) { + if (hours > 0 || minutes > 0) { + statsString += QString(" "); + } statsString += QString().sprintf("%.3f seconds", seconds); } statsString += "\r\n"; @@ -690,3 +702,13 @@ void OctreeServer::run() { connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes())); silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000); } + + +int OctreeServer::getPacketsPerClientPerInterval() const { + int totalEvenly = getPacketsTotalPerInterval() / getCurrentClientCount(); + if (totalEvenly < 1) { + totalEvenly = 1; + } + int packetsPerClientPerInterval = std::min(_packetsPerClientPerInterval, totalEvenly); + return packetsPerClientPerInterval; +} diff --git a/assignment-client/src/octree/OctreeServer.h b/assignment-client/src/octree/OctreeServer.h index 1dcb3352ff..4a412d19b3 100644 --- a/assignment-client/src/octree/OctreeServer.h +++ b/assignment-client/src/octree/OctreeServer.h @@ -43,7 +43,7 @@ public: Octree* getOctree() { return _tree; } JurisdictionMap* getJurisdiction() { return _jurisdiction; } - int getPacketsPerClientPerInterval() const { return _packetsPerClientPerInterval; } + int getPacketsPerClientPerInterval() const; int getPacketsPerClientPerSecond() const { return getPacketsPerClientPerInterval() * INTERVALS_PER_SECOND; } int getPacketsTotalPerInterval() const { return _packetsTotalPerInterval; } int getPacketsTotalPerSecond() const { return getPacketsTotalPerInterval() * INTERVALS_PER_SECOND; } From 2832c334822a7d6332c8954162344de116fd6015 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Feb 2014 21:38:28 -0800 Subject: [PATCH 18/20] fixed div by zero --- assignment-client/src/octree/OctreeServer.cpp | 9 --------- assignment-client/src/octree/OctreeServer.h | 4 +++- examples/seeingVoxelsExample.js | 4 ++-- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 7bf5c12a22..e823722857 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -703,12 +703,3 @@ void OctreeServer::run() { silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000); } - -int OctreeServer::getPacketsPerClientPerInterval() const { - int totalEvenly = getPacketsTotalPerInterval() / getCurrentClientCount(); - if (totalEvenly < 1) { - totalEvenly = 1; - } - int packetsPerClientPerInterval = std::min(_packetsPerClientPerInterval, totalEvenly); - return packetsPerClientPerInterval; -} diff --git a/assignment-client/src/octree/OctreeServer.h b/assignment-client/src/octree/OctreeServer.h index 4a412d19b3..b5d8f6fb67 100644 --- a/assignment-client/src/octree/OctreeServer.h +++ b/assignment-client/src/octree/OctreeServer.h @@ -43,7 +43,9 @@ public: Octree* getOctree() { return _tree; } JurisdictionMap* getJurisdiction() { return _jurisdiction; } - int getPacketsPerClientPerInterval() const; + int getPacketsPerClientPerInterval() const { return std::min(_packetsPerClientPerInterval, + std::max(1, getPacketsTotalPerInterval() / std::max(1, getCurrentClientCount()))); } + int getPacketsPerClientPerSecond() const { return getPacketsPerClientPerInterval() * INTERVALS_PER_SECOND; } int getPacketsTotalPerInterval() const { return _packetsTotalPerInterval; } int getPacketsTotalPerSecond() const { return getPacketsTotalPerInterval() * INTERVALS_PER_SECOND; } diff --git a/examples/seeingVoxelsExample.js b/examples/seeingVoxelsExample.js index 98445990a8..93f605755f 100644 --- a/examples/seeingVoxelsExample.js +++ b/examples/seeingVoxelsExample.js @@ -21,10 +21,10 @@ var orientation = Quat.fromPitchYawRoll(0, yaw, 0); function init() { if (isLocal) { - MyAvatar.position = {x: 10, y: 0, z: 10}; + MyAvatar.position = {x: 5000, y: 500, z: 5000}; MyAvatar.orientation = orientation; } else { - VoxelViewer.setPosition({x: 10, y: 0, z: 10}); + VoxelViewer.setPosition({x: 5000, y: 500, z: 5000}); VoxelViewer.setOrientation(orientation); VoxelViewer.queryOctree(); Agent.isAvatar = true; From b7f62eabf03b86b4b7ea17927e7649064a18bce4 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 27 Feb 2014 15:22:23 -0800 Subject: [PATCH 19/20] clean up more menu items --- interface/src/Application.cpp | 27 ++++++++++++++------------- interface/src/Menu.cpp | 15 ++------------- interface/src/Menu.h | 7 +------ interface/src/VoxelSystem.cpp | 9 ++------- 4 files changed, 19 insertions(+), 39 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2509654a79..fc9cb9fb2d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1517,8 +1517,8 @@ void Application::init() { // Set up VoxelSystem after loading preferences so we can get the desired max voxel count _voxels.setMaxVoxels(Menu::getInstance()->getMaxVoxels()); - _voxels.setUseVoxelShader(Menu::getInstance()->isOptionChecked(MenuOption::UseVoxelShader)); - _voxels.setVoxelsAsPoints(Menu::getInstance()->isOptionChecked(MenuOption::VoxelsAsPoints)); + _voxels.setUseVoxelShader(false); + _voxels.setVoxelsAsPoints(false); _voxels.setDisableFastVoxelPipeline(false); _voxels.init(); @@ -1914,7 +1914,7 @@ void Application::updateMyAvatar(float deltaTime) { // actually need to calculate the view frustum planes to send these details // to the server. loadViewFrustum(_myCamera, _viewFrustum); - + // Update my voxel servers with my current voxel query... queryOctree(NodeType::VoxelServer, PacketTypeVoxelQuery, _voxelServerJurisdictions); queryOctree(NodeType::ParticleServer, PacketTypeParticleQuery, _particleServerJurisdictions); @@ -1927,6 +1927,8 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node return; } + //qDebug() << ">>> inside... queryOctree()... _viewFrustum.getFieldOfView()=" << _viewFrustum.getFieldOfView(); + bool wantExtraDebugging = getLogger()->extraDebugging(); // These will be the same for all servers, so we can set them up once and then reuse for each server we send to. @@ -1986,7 +1988,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node } } - if (wantExtraDebugging && unknownJurisdictionServers > 0) { + if (wantExtraDebugging) { qDebug("Servers: total %d, in view %d, unknown jurisdiction %d", totalServers, inViewServers, unknownJurisdictionServers); } @@ -2007,7 +2009,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node } } - if (wantExtraDebugging && unknownJurisdictionServers > 0) { + if (wantExtraDebugging) { qDebug("perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer); } @@ -2338,14 +2340,13 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... voxels..."); - if (!Menu::getInstance()->isOptionChecked(MenuOption::DontRenderVoxels)) { - _voxels.render(); - - // double check that our LOD doesn't need to be auto-adjusted - // only adjust if our option is set - if (Menu::getInstance()->isOptionChecked(MenuOption::AutoAdjustLOD)) { - Menu::getInstance()->autoAdjustLOD(_fps); - } + + _voxels.render(); + + // double check that our LOD doesn't need to be auto-adjusted + // adjust it unless we were asked to disable this feature + if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableAutoAdjustLOD)) { + Menu::getInstance()->autoAdjustLOD(_fps); } } diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 4c8a24f3cf..830ac17ebd 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -238,23 +238,12 @@ Menu::Menu() : true, appInstance, SLOT(setRenderVoxels(bool))); - addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontRenderVoxels); - addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontCallOpenGLForVoxels); - - _useVoxelShader = addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseVoxelShader, 0, - false, appInstance->getVoxels(), SLOT(setUseVoxelShader(bool))); - - addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelsAsPoints, 0, - false, appInstance->getVoxels(), SLOT(setVoxelsAsPoints(bool))); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion); - addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontFadeOnVoxelServerChanges); - addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AutoAdjustLOD); addActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools())); - - QMenu* voxelProtoOptionsMenu = voxelOptionsMenu->addMenu("Voxel Server Protocol Options"); - addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DestructiveAddVoxel); + addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontFadeOnVoxelServerChanges); + addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DisableAutoAdjustLOD); QMenu* avatarOptionsMenu = developerMenu->addMenu("Avatar Options"); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 2ce250be55..84a5eef481 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -201,7 +201,7 @@ namespace MenuOption { const QString AmbientOcclusion = "Ambient Occlusion"; const QString Avatars = "Avatars"; const QString Atmosphere = "Atmosphere"; - const QString AutoAdjustLOD = "Automatically Adjust LOD"; + const QString DisableAutoAdjustLOD = "Disable Automatically Adjusting LOD"; const QString AutomaticallyAuditTree = "Automatically Audit Tree Stats"; const QString Bandwidth = "Bandwidth Display"; const QString BandwidthDetails = "Bandwidth Details"; @@ -217,13 +217,10 @@ namespace MenuOption { const QString CullSharedFaces = "Cull Shared Voxel Faces"; const QString DecreaseAvatarSize = "Decrease Avatar Size"; const QString DecreaseVoxelSize = "Decrease Voxel Size"; - const QString DestructiveAddVoxel = "Create Voxel is Destructive"; const QString DisplayFrustum = "Display Frustum"; const QString DisplayHands = "Display Hands"; const QString DisplayHandTargets = "Display Hand Targets"; const QString FilterSixense = "Smooth Sixense Movement"; - const QString DontRenderVoxels = "Don't call _voxels.render()"; - const QString DontCallOpenGLForVoxels = "Don't call glDrawRangeElementsEXT() for Voxels"; const QString Enable3DTVMode = "Enable 3DTV Mode"; const QString AudioNoiseReduction = "Audio Noise Reduction"; const QString EchoServerAudio = "Echo Server Audio"; @@ -296,8 +293,6 @@ namespace MenuOption { const QString TreeStats = "Calculate Tree Stats"; const QString TransmitterDrive = "Transmitter Drive"; const QString Quit = "Quit"; - const QString UseVoxelShader = "Use Voxel Shader"; - const QString VoxelsAsPoints = "Draw Voxels as Points"; const QString Voxels = "Voxels"; const QString VoxelDrumming = "Voxel Drumming"; const QString VoxelMode = "Cycle Voxel Mode"; diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 99f6171b7a..24d1e73ee2 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -867,7 +867,6 @@ void VoxelSystem::checkForCulling() { bool fullRedraw = (_lastKnownVoxelSizeScale != Menu::getInstance()->getVoxelSizeScale() || _lastKnownBoundaryLevelAdjust != Menu::getInstance()->getBoundaryLevelAdjust()); - // track that these values _lastKnownVoxelSizeScale = Menu::getInstance()->getVoxelSizeScale(); _lastKnownBoundaryLevelAdjust = Menu::getInstance()->getBoundaryLevelAdjust(); @@ -1386,7 +1385,6 @@ void VoxelSystem::render() { updateVBOs(); - bool dontCallOpenGLDraw = Menu::getInstance()->isOptionChecked(MenuOption::DontCallOpenGLForVoxels); // if not don't... then do... if (_useVoxelShader) { PerformanceWarning warn(showWarnings,"render().. _useVoxelShader openGL.."); @@ -1432,9 +1430,7 @@ void VoxelSystem::render() { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboVoxelsIndicesID); - if (!dontCallOpenGLDraw) { - glDrawElements(GL_POINTS, _voxelsInReadArrays, GL_UNSIGNED_INT, BUFFER_OFFSET(0)); //The starting point of the IBO - } + glDrawElements(GL_POINTS, _voxelsInReadArrays, GL_UNSIGNED_INT, BUFFER_OFFSET(0)); //The starting point of the IBO // deactivate vertex and color arrays after drawing glDisableClientState(GL_VERTEX_ARRAY); @@ -1477,7 +1473,7 @@ void VoxelSystem::render() { // draw voxels in 6 passes - if (!dontCallOpenGLDraw) { + { PerformanceWarning warn(showWarnings, "render().. glDrawRangeElementsEXT()..."); glNormal3f(0,1.0f,0); @@ -1510,7 +1506,6 @@ void VoxelSystem::render() { glDrawRangeElementsEXT(GL_TRIANGLES, 0, GLOBAL_NORMALS_VERTICES_PER_VOXEL * _voxelsInReadArrays - 1, INDICES_PER_FACE * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); } - { PerformanceWarning warn(showWarnings, "render().. cleanup after glDrawRangeElementsEXT()..."); From 1cc6288899437eb4916607bf2429fb6cd93dc804 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 27 Feb 2014 15:41:36 -0800 Subject: [PATCH 20/20] add back in entry point for import voxels --- interface/src/Application.cpp | 20 ++++++++++++++++++++ interface/src/Application.h | 1 + 2 files changed, 21 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index fc9cb9fb2d..cdc4954794 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1379,6 +1379,26 @@ void Application::exportVoxels(const VoxelDetail& sourceVoxel) { _window->activateWindow(); } +void Application::importVoxels() { + if (!_voxelImporter) { + _voxelImporter = new VoxelImporter(_window); + _voxelImporter->loadSettings(_settings); + } + + if (!_voxelImporter->exec()) { + qDebug() << "[DEBUG] Import succeeded." << endl; + } else { + qDebug() << "[DEBUG] Import failed." << endl; + if (_sharedVoxelSystem.getTree() == _voxelImporter->getVoxelTree()) { + _sharedVoxelSystem.killLocalVoxels(); + _sharedVoxelSystem.changeTree(&_clipboard); + } + } + + // restore the main window's active state + _window->activateWindow(); +} + void Application::cutVoxels(const VoxelDetail& sourceVoxel) { copyVoxels(sourceVoxel); deleteVoxelAt(sourceVoxel); diff --git a/interface/src/Application.h b/interface/src/Application.h index 51c6734e7a..4e91876dfb 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -235,6 +235,7 @@ public slots: void nodeKilled(SharedNodePointer node); void packetSent(quint64 length); + void importVoxels(); // doesn't include source voxel because it goes to clipboard void cutVoxels(const VoxelDetail& sourceVoxel); void copyVoxels(const VoxelDetail& sourceVoxel); void pasteVoxels(const VoxelDetail& sourceVoxel);