From 2c362e62880fb7a25b5e2cdcbfcc51919064dc1f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 21 Aug 2013 12:09:00 -0700 Subject: [PATCH 1/9] adding support for better multithreading in VoxelTree --- libraries/voxels/src/VoxelTree.cpp | 78 ++++++++++++++++++++++++++++-- libraries/voxels/src/VoxelTree.h | 38 ++++++++++++++- 2 files changed, 109 insertions(+), 7 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index c0fcee02dd..2531d267d7 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -50,6 +50,10 @@ VoxelTree::VoxelTree(bool shouldReaverage) : _isDirty(true), _shouldReaverage(shouldReaverage) { rootNode = new VoxelNode(); + + pthread_mutex_init(&_encodeSetLock, NULL); + pthread_mutex_init(&_deleteSetLock, NULL); + pthread_mutex_init(&_deletePendingSetLock, NULL); } VoxelTree::~VoxelTree() { @@ -58,6 +62,10 @@ VoxelTree::~VoxelTree() { for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { delete rootNode->getChildAtIndex(i); } + + pthread_mutex_destroy(&_encodeSetLock); + pthread_mutex_destroy(&_deleteSetLock); + pthread_mutex_destroy(&_deletePendingSetLock); } @@ -393,7 +401,16 @@ void VoxelTree::deleteVoxelCodeFromTree(unsigned char* codeBuffer, bool collapse args.pathChanged = false; VoxelNode* node = rootNode; - deleteVoxelCodeFromTreeRecursion(node, &args); + + // We can't encode and delete nodes at the same time, so we guard against deleting any node that is actively + // being encoded. And we stick that code on our pendingDelete list. + if (isEncoding(codeBuffer)) { + queueForLaterDelete(codeBuffer); + } else { + startDeleting(codeBuffer); + deleteVoxelCodeFromTreeRecursion(node, &args); + doneDeleting(codeBuffer); + } } void VoxelTree::deleteVoxelCodeFromTreeRecursion(VoxelNode* node, void* extraData) { @@ -998,15 +1015,16 @@ bool VoxelTree::findCapsulePenetration(const glm::vec3& start, const glm::vec3& return args.found; } - int VoxelTree::encodeTreeBitstream(VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag, - EncodeBitstreamParams& params) const { + EncodeBitstreamParams& params) { + startEncoding(node); // How many bytes have we written so far at this level; int bytesWritten = 0; // If we're at a node that is out of view, then we can return, because no nodes below us will be in view! if (params.viewFrustum && !node->isInView(*params.viewFrustum)) { + doneEncoding(node); return bytesWritten; } @@ -1057,6 +1075,8 @@ int VoxelTree::encodeTreeBitstream(VoxelNode* node, unsigned char* outputBuffer, // otherwise... if we didn't write any child bytes, then pretend like we also didn't write our octal code bytesWritten = 0; } + + doneEncoding(node); return bytesWritten; } @@ -1661,7 +1681,7 @@ bool VoxelTree::readFromSchematicFile(const char *fileName) { return true; } -void VoxelTree::writeToSVOFile(const char* fileName, VoxelNode* node) const { +void VoxelTree::writeToSVOFile(const char* fileName, VoxelNode* node) { std::ofstream file(fileName, std::ios::out|std::ios::binary); @@ -1898,4 +1918,52 @@ void VoxelTree::computeBlockColor(int id, int data, int& red, int& green, int& b create = 0; break; } -} \ No newline at end of file +} + +void dumpSetContents(const char* name, std::set set) { + printf("set %s has %ld elements\n", name, set.size()); + /* + for (std::set::iterator i = set.begin(); i != set.end(); ++i) { + printOctalCode(*i); + } + */ +} + +void VoxelTree::startEncoding(VoxelNode* node) { + pthread_mutex_lock(&_encodeSetLock); + _codesBeingEncoded.insert(node->getOctalCode()); + pthread_mutex_unlock(&_encodeSetLock); +} + +void VoxelTree::doneEncoding(VoxelNode* node) { + pthread_mutex_lock(&_encodeSetLock); + _codesBeingEncoded.erase(node->getOctalCode()); + pthread_mutex_unlock(&_encodeSetLock); +} + +void VoxelTree::startDeleting(unsigned char* code) { + pthread_mutex_lock(&_deleteSetLock); + _codesBeingDeleted.insert(code); + pthread_mutex_unlock(&_deleteSetLock); +} + +void VoxelTree::doneDeleting(unsigned char* code) { + pthread_mutex_lock(&_deleteSetLock); + _codesBeingDeleted.erase(code); + pthread_mutex_unlock(&_deleteSetLock); +} + +bool VoxelTree::isEncoding(unsigned char* codeBuffer) { + pthread_mutex_lock(&_encodeSetLock); + bool isEncoding = (_codesBeingEncoded.find(codeBuffer) != _codesBeingEncoded.end()); + pthread_mutex_unlock(&_encodeSetLock); + return isEncoding; +} + +void VoxelTree::queueForLaterDelete(unsigned char* codeBuffer) { + pthread_mutex_lock(&_deletePendingSetLock); + _codesPendingDelete.insert(codeBuffer); + pthread_mutex_unlock(&_deletePendingSetLock); +} + + diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index f27543caa8..e44b524376 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -9,6 +9,7 @@ #ifndef __hifi__VoxelTree__ #define __hifi__VoxelTree__ +#include #include #include @@ -152,7 +153,7 @@ public: const glm::vec3& point, void* extraData=NULL); int encodeTreeBitstream(VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag, - EncodeBitstreamParams& params) const; + EncodeBitstreamParams& params) ; bool isDirty() const { return _isDirty; }; void clearDirtyBit() { _isDirty = false; }; @@ -169,7 +170,7 @@ public: void loadVoxelsFile(const char* fileName, bool wantColorRandomizer); // these will read/write files that match the wireformat, excluding the 'V' leading - void writeToSVOFile(const char* filename, VoxelNode* node = NULL) const; + void writeToSVOFile(const char* filename, VoxelNode* node = NULL); bool readFromSVOFile(const char* filename); // reads voxels from square image with alpha as a Y-axis bool readFromSquareARGB32Pixels(const uint32_t* pixels, int dimension); @@ -209,6 +210,39 @@ private: bool _isDirty; unsigned long int _nodesChangedFromBitstream; bool _shouldReaverage; + + /// Octal Codes of any subtrees currently being encoded. While any of these codes is being encoded, ancestors and + /// descendants of them can not be deleted. + std::set _codesBeingEncoded; + /// mutex lock to protect the encoding set + pthread_mutex_t _encodeSetLock; + + /// Called to indicate that a VoxelNode is in the process of being encoded. + void startEncoding(VoxelNode* node); + /// Called to indicate that a VoxelNode is done being encoded. + void doneEncoding(VoxelNode* node); + /// Is the Octal Code currently being deleted? + bool isEncoding(unsigned char* codeBuffer); + + /// Octal Codes of any subtrees currently being deleted. While any of these codes is being deleted, ancestors and + /// descendants of them can not be encoded. + std::set _codesBeingDeleted; + /// mutex lock to protect the deleting set + pthread_mutex_t _deleteSetLock; + + /// Called to indicate that an octal code is in the process of being deleted. + void startDeleting(unsigned char* code); + /// Called to indicate that an octal code is done being deleted. + void doneDeleting(unsigned char* code); + /// Octal Codes that were attempted to be deleted but couldn't be because they were actively being encoded, and were + /// instead queued for later delete + std::set _codesPendingDelete; + /// mutex lock to protect the deleting set + pthread_mutex_t _deletePendingSetLock; + + /// Adds an Octal Code to the set of codes that needs to be deleted + void queueForLaterDelete(unsigned char* codeBuffer); + }; float boundaryDistanceForRenderLevel(unsigned int renderLevel); From bb9a81939c731cd98b2c2b8200982374ff76f9c1 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 21 Aug 2013 15:17:32 -0700 Subject: [PATCH 2/9] threads for persist and packet processing --- voxel-server/src/VoxelPersistThread.cpp | 37 +++ voxel-server/src/VoxelPersistThread.h | 33 ++ voxel-server/src/VoxelServer.h | 58 ++++ .../src/VoxelServerPacketProcessor.cpp | 136 +++++++++ voxel-server/src/VoxelServerPacketProcessor.h | 22 ++ voxel-server/src/main.cpp | 289 +++--------------- 6 files changed, 332 insertions(+), 243 deletions(-) create mode 100644 voxel-server/src/VoxelPersistThread.cpp create mode 100644 voxel-server/src/VoxelPersistThread.h create mode 100644 voxel-server/src/VoxelServer.h create mode 100644 voxel-server/src/VoxelServerPacketProcessor.cpp create mode 100644 voxel-server/src/VoxelServerPacketProcessor.h diff --git a/voxel-server/src/VoxelPersistThread.cpp b/voxel-server/src/VoxelPersistThread.cpp new file mode 100644 index 0000000000..00272b57a4 --- /dev/null +++ b/voxel-server/src/VoxelPersistThread.cpp @@ -0,0 +1,37 @@ +// +// VoxelPersistThread.cpp +// voxel-server +// +// Created by Brad Hefta-Gaub on 8/12/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// +// Threaded or non-threaded voxel persistance +// + +#include +#include + +#include "VoxelPersistThread.h" +#include "VoxelServer.h" + +VoxelPersistThread::VoxelPersistThread(VoxelTree* tree, const char* filename, int persistInterval) : + _tree(tree), + _filename(filename), + _persistInterval(persistInterval) { +} + +bool VoxelPersistThread::process() { + uint64_t MSECS_TO_USECS = 1000; + usleep(_persistInterval * MSECS_TO_USECS); + + + // check the dirty bit and persist here... + if (_tree->isDirty()) { + printf("saving voxels to file %s...\n",_filename); + _tree->writeToSVOFile(_filename); + _tree->clearDirtyBit(); // tree is clean after saving + printf("DONE saving voxels to file...\n"); + } + + return isStillRunning(); // keep running till they terminate us +} diff --git a/voxel-server/src/VoxelPersistThread.h b/voxel-server/src/VoxelPersistThread.h new file mode 100644 index 0000000000..0b5bd2dc16 --- /dev/null +++ b/voxel-server/src/VoxelPersistThread.h @@ -0,0 +1,33 @@ +// +// VoxelPersistThread.h +// shared +// +// Created by Brad Hefta-Gaub on 8/12/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// +// Threaded or non-threaded received packet processor. +// + +#ifndef __shared__VoxelPersistThread__ +#define __shared__VoxelPersistThread__ + +#include +#include +#include + +/// Generalized threaded processor for handling received inbound packets. +class VoxelPersistThread : public virtual GenericThread { +public: + static const int DEFAULT_PERSIST_INTERVAL = 1000 * 30; // every 30 seconds + + VoxelPersistThread(VoxelTree* tree, const char* filename, int persistInterval = DEFAULT_PERSIST_INTERVAL); +protected: + /// Implements generic processing behavior for this thread. + virtual bool process(); +private: + VoxelTree* _tree; + const char* _filename; + int _persistInterval; +}; + +#endif // __shared__PacketReceiver__ diff --git a/voxel-server/src/VoxelServer.h b/voxel-server/src/VoxelServer.h new file mode 100644 index 0000000000..b258ee9406 --- /dev/null +++ b/voxel-server/src/VoxelServer.h @@ -0,0 +1,58 @@ +// VoxelServer.h +// voxel-server +// +// Created by Stephen Birarda on 3/13/13. +// +// + +#ifndef __voxel_server__VoxelServer__ +#define __voxel_server__VoxelServer__ + +#include +#include // for MAX_PACKET_SIZE +#include +#include +#include + +#include "VoxelServerPacketProcessor.h" + + +const int MAX_FILENAME_LENGTH = 1024; +const int VOXEL_LISTEN_PORT = 40106; +const int VOXEL_SIZE_BYTES = 3 + (3 * sizeof(float)); +const int VOXELS_PER_PACKET = (MAX_PACKET_SIZE - 1) / VOXEL_SIZE_BYTES; +const int MIN_BRIGHTNESS = 64; +const float DEATH_STAR_RADIUS = 4.0; +const float MAX_CUBE = 0.05f; +const int VOXEL_SEND_INTERVAL_USECS = 17 * 1000; // approximately 60fps +const int SENDING_TIME_TO_SPARE = 5 * 1000; // usec of sending interval to spare for calculating voxels +const int INTERVALS_PER_SECOND = 1000 * 1000 / VOXEL_SEND_INTERVAL_USECS; +const int MAX_VOXEL_TREE_DEPTH_LEVELS = 4; +const int ENVIRONMENT_SEND_INTERVAL_USECS = 1000000; + +extern const char* LOCAL_VOXELS_PERSIST_FILE; +extern const char* VOXELS_PERSIST_FILE; +extern char voxelPersistFilename[MAX_FILENAME_LENGTH]; +extern int PACKETS_PER_CLIENT_PER_INTERVAL; + +extern VoxelTree serverTree; // this IS a reaveraging tree +extern bool wantVoxelPersist; +extern bool wantLocalDomain; +extern bool wantColorRandomizer; +extern bool debugVoxelSending; +extern bool shouldShowAnimationDebug; +extern bool displayVoxelStats; +extern bool debugVoxelReceiving; +extern bool sendEnvironments; +extern bool sendMinimalEnvironment; +extern bool dumpVoxelsOnMove; +extern EnvironmentData environmentData[3]; +extern int receivedPacketCount; +extern JurisdictionMap* jurisdiction; +extern JurisdictionSender* jurisdictionSender; +extern VoxelServerPacketProcessor* voxelServerPacketProcessor; +extern pthread_mutex_t treeLock; + + + +#endif // __voxel_server__VoxelServer__ diff --git a/voxel-server/src/VoxelServerPacketProcessor.cpp b/voxel-server/src/VoxelServerPacketProcessor.cpp new file mode 100644 index 0000000000..de2848a7ac --- /dev/null +++ b/voxel-server/src/VoxelServerPacketProcessor.cpp @@ -0,0 +1,136 @@ +// +// VoxelServerPacketProcessor.cpp +// voxel-server +// +// Created by Brad Hefta-Gaub on 8/12/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// +// Threaded or non-threaded network packet processor for the voxel-server +// + +#include +#include + +#include "VoxelServer.h" +#include "VoxelServerPacketProcessor.h" + + +void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { + + int numBytesPacketHeader = numBytesForPacketHeader(packetData); + + if (packetData[0] == PACKET_TYPE_SET_VOXEL || packetData[0] == PACKET_TYPE_SET_VOXEL_DESTRUCTIVE) { + bool destructive = (packetData[0] == PACKET_TYPE_SET_VOXEL_DESTRUCTIVE); + PerformanceWarning warn(::shouldShowAnimationDebug, + destructive ? "PACKET_TYPE_SET_VOXEL_DESTRUCTIVE" : "PACKET_TYPE_SET_VOXEL", + ::shouldShowAnimationDebug); + + ::receivedPacketCount++; + + unsigned short int itemNumber = (*((unsigned short int*)(packetData + numBytesPacketHeader))); + if (::shouldShowAnimationDebug) { + printf("got %s - command from client receivedBytes=%ld itemNumber=%d\n", + destructive ? "PACKET_TYPE_SET_VOXEL_DESTRUCTIVE" : "PACKET_TYPE_SET_VOXEL", + packetLength, itemNumber); + } + + if (::debugVoxelReceiving) { + printf("got %s - %d command from client receivedBytes=%ld itemNumber=%d\n", + destructive ? "PACKET_TYPE_SET_VOXEL_DESTRUCTIVE" : "PACKET_TYPE_SET_VOXEL", + ::receivedPacketCount, packetLength, itemNumber); + } + int atByte = numBytesPacketHeader + sizeof(itemNumber); + unsigned char* voxelData = (unsigned char*)&packetData[atByte]; + while (atByte < packetLength) { + unsigned char octets = (unsigned char)*voxelData; + const int COLOR_SIZE_IN_BYTES = 3; + int voxelDataSize = bytesRequiredForCodeLength(octets) + COLOR_SIZE_IN_BYTES; + int voxelCodeSize = bytesRequiredForCodeLength(octets); + + // color randomization on insert + int colorRandomizer = ::wantColorRandomizer ? randIntInRange (-50, 50) : 0; + int red = voxelData[voxelCodeSize + 0]; + int green = voxelData[voxelCodeSize + 1]; + int blue = voxelData[voxelCodeSize + 2]; + + if (::shouldShowAnimationDebug) { + printf("insert voxels - wantColorRandomizer=%s old r=%d,g=%d,b=%d \n", + (::wantColorRandomizer?"yes":"no"),red,green,blue); + } + + red = std::max(0, std::min(255, red + colorRandomizer)); + green = std::max(0, std::min(255, green + colorRandomizer)); + blue = std::max(0, std::min(255, blue + colorRandomizer)); + + if (::shouldShowAnimationDebug) { + printf("insert voxels - wantColorRandomizer=%s NEW r=%d,g=%d,b=%d \n", + (::wantColorRandomizer?"yes":"no"),red,green,blue); + } + voxelData[voxelCodeSize + 0] = red; + voxelData[voxelCodeSize + 1] = green; + voxelData[voxelCodeSize + 2] = blue; + + if (::shouldShowAnimationDebug) { + float* vertices = firstVertexForCode(voxelData); + printf("inserting voxel at: %f,%f,%f\n", vertices[0], vertices[1], vertices[2]); + delete []vertices; + } + + serverTree.readCodeColorBufferToTree(voxelData, destructive); + // skip to next + voxelData += voxelDataSize; + atByte += voxelDataSize; + } + + // Make sure our Node and NodeList knows we've heard from this node. + Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress); + if (node) { + node->setLastHeardMicrostamp(usecTimestampNow()); + } + + } else if (packetData[0] == PACKET_TYPE_ERASE_VOXEL) { + + // Send these bits off to the VoxelTree class to process them + pthread_mutex_lock(&::treeLock); + ::serverTree.processRemoveVoxelBitstream((unsigned char*)packetData, packetLength); + pthread_mutex_unlock(&::treeLock); + + // Make sure our Node and NodeList knows we've heard from this node. + Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress); + if (node) { + node->setLastHeardMicrostamp(usecTimestampNow()); + } + } else if (packetData[0] == PACKET_TYPE_Z_COMMAND) { + + // the Z command is a special command that allows the sender to send the voxel server high level semantic + // requests, like erase all, or add sphere scene + + char* command = (char*) &packetData[numBytesPacketHeader]; // start of the command + int commandLength = strlen(command); // commands are null terminated strings + int totalLength = numBytesPacketHeader + commandLength + 1; // 1 for null termination + printf("got Z message len(%ld)= %s\n", packetLength, command); + bool rebroadcast = true; // by default rebroadcast + + while (totalLength <= packetLength) { + if (strcmp(command, TEST_COMMAND) == 0) { + printf("got Z message == a message, nothing to do, just report\n"); + } + totalLength += commandLength + 1; // 1 for null termination + } + + if (rebroadcast) { + // Now send this to the connected nodes so they can also process these messages + printf("rebroadcasting Z message to connected nodes... nodeList.broadcastToNodes()\n"); + NodeList::getInstance()->broadcastToNodes(packetData, packetLength, &NODE_TYPE_AGENT, 1); + } + + // Make sure our Node and NodeList knows we've heard from this node. + Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress); + if (node) { + node->setLastHeardMicrostamp(usecTimestampNow()); + } + } else { + printf("unknown packet ignored... packetData[0]=%c\n", packetData[0]); + } +} + diff --git a/voxel-server/src/VoxelServerPacketProcessor.h b/voxel-server/src/VoxelServerPacketProcessor.h new file mode 100644 index 0000000000..b2b44666e0 --- /dev/null +++ b/voxel-server/src/VoxelServerPacketProcessor.h @@ -0,0 +1,22 @@ +// +// VoxelServerPacketProcessor.h +// voxel-server +// +// Created by Brad Hefta-Gaub on 8/12/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// +// Threaded or non-threaded network packet processor for the voxel-server +// + +#ifndef __voxel_server__VoxelServerPacketProcessor__ +#define __voxel_server__VoxelServerPacketProcessor__ + +#include + +/// Handles processing of incoming network packets for the voxel-server. As with other ReceivedPacketProcessor classes +/// the user is responsible for reading inbound packets and adding them to the processing queue by calling queueReceivedPacket() +class VoxelServerPacketProcessor : public ReceivedPacketProcessor { +protected: + virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength); +}; +#endif // __voxel_server__VoxelServerPacketProcessor__ diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 3446ebe9c1..fc87f5973b 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -23,6 +23,9 @@ #include +#include "VoxelPersistThread.h" +#include "VoxelServerPacketProcessor.h" + #ifdef _WIN32 #include "Syssocket.h" #include "Systime.h" @@ -32,36 +35,15 @@ #include #endif +#include "VoxelServer.h" + const char* LOCAL_VOXELS_PERSIST_FILE = "resources/voxels.svo"; const char* VOXELS_PERSIST_FILE = "/etc/highfidelity/voxel-server/resources/voxels.svo"; -const int MAX_FILENAME_LENGTH = 1024; char voxelPersistFilename[MAX_FILENAME_LENGTH]; -const int VOXEL_PERSIST_INTERVAL = 1000 * 30; // every 30 seconds - -const int VOXEL_LISTEN_PORT = 40106; - - -const int VOXEL_SIZE_BYTES = 3 + (3 * sizeof(float)); -const int VOXELS_PER_PACKET = (MAX_PACKET_SIZE - 1) / VOXEL_SIZE_BYTES; - -const int MIN_BRIGHTNESS = 64; -const float DEATH_STAR_RADIUS = 4.0; -const float MAX_CUBE = 0.05f; - -const int VOXEL_SEND_INTERVAL_USECS = 17 * 1000; // approximately 60fps int PACKETS_PER_CLIENT_PER_INTERVAL = 10; -const int SENDING_TIME_TO_SPARE = 5 * 1000; // usec of sending interval to spare for calculating voxels -const int INTERVALS_PER_SECOND = 1000 * 1000 / VOXEL_SEND_INTERVAL_USECS; - -const int MAX_VOXEL_TREE_DEPTH_LEVELS = 4; - -const int ENVIRONMENT_SEND_INTERVAL_USECS = 1000000; - VoxelTree serverTree(true); // this IS a reaveraging tree bool wantVoxelPersist = true; bool wantLocalDomain = false; - - bool wantColorRandomizer = false; bool debugVoxelSending = false; bool shouldShowAnimationDebug = false; @@ -70,43 +52,14 @@ bool debugVoxelReceiving = false; bool sendEnvironments = true; bool sendMinimalEnvironment = false; bool dumpVoxelsOnMove = false; - EnvironmentData environmentData[3]; - int receivedPacketCount = 0; JurisdictionMap* jurisdiction = NULL; JurisdictionSender* jurisdictionSender = NULL; +VoxelServerPacketProcessor* voxelServerPacketProcessor = NULL; +VoxelPersistThread* voxelPersistThread = NULL; +pthread_mutex_t treeLock; -void randomlyFillVoxelTree(int levelsToGo, VoxelNode *currentRootNode) { - // randomly generate children for this node - // the first level of the tree (where levelsToGo = MAX_VOXEL_TREE_DEPTH_LEVELS) has all 8 - if (levelsToGo > 0) { - - bool createdChildren = false; - createdChildren = false; - - for (int i = 0; i < 8; i++) { - if (true) { - // create a new VoxelNode to put here - currentRootNode->addChildAtIndex(i); - randomlyFillVoxelTree(levelsToGo - 1, currentRootNode->getChildAtIndex(i)); - createdChildren = true; - } - } - - if (!createdChildren) { - // we didn't create any children for this node, making it a leaf - // give it a random color - currentRootNode->setRandomColor(MIN_BRIGHTNESS); - } else { - // set the color value for this node - currentRootNode->setColorFromAverageOfChildren(); - } - } else { - // this is a leaf node, just give it a color - currentRootNode->setRandomColor(MIN_BRIGHTNESS); - } -} void eraseVoxelTreeAndCleanupNodeVisitData() { @@ -122,8 +75,6 @@ void eraseVoxelTreeAndCleanupNodeVisitData() { } } -pthread_mutex_t treeLock; - void handlePacketSend(NodeList* nodeList, NodeList::iterator& node, VoxelNodeData* nodeData, @@ -380,29 +331,6 @@ void deepestLevelVoxelDistributor(NodeList* nodeList, pthread_mutex_unlock(&::treeLock); } -uint64_t lastPersistVoxels = 0; -void persistVoxelsWhenDirty() { - uint64_t now = usecTimestampNow(); - if (::lastPersistVoxels == 0) { - ::lastPersistVoxels = now; - } - int sinceLastTime = (now - ::lastPersistVoxels) / 1000; - - // check the dirty bit and persist here... - if (::wantVoxelPersist && ::serverTree.isDirty() && sinceLastTime > VOXEL_PERSIST_INTERVAL) { - { - PerformanceWarning warn(::shouldShowAnimationDebug, - "persistVoxelsWhenDirty() - writeToSVOFile()", ::shouldShowAnimationDebug); - - printf("saving voxels to file...\n"); - serverTree.writeToSVOFile(::voxelPersistFilename); - serverTree.clearDirtyBit(); // tree is clean after saving - printf("DONE saving voxels to file...\n"); - } - ::lastPersistVoxels = usecTimestampNow(); - } -} - void* distributeVoxelsToListeners(void* args) { NodeList* nodeList = NodeList::getInstance(); @@ -589,6 +517,12 @@ int main(int argc, const char * argv[]) { unsigned long internalNodeCount = ::serverTree.rootNode->getSubTreeInternalNodeCount(); unsigned long leafNodeCount = ::serverTree.rootNode->getSubTreeLeafNodeCount(); printf("Nodes after loading scene %lu nodes %lu internal %lu leaves\n", nodeCount, internalNodeCount, leafNodeCount); + + // now set up VoxelPersistThread + ::voxelPersistThread = new VoxelPersistThread(&::serverTree, ::voxelPersistFilename); + if (::voxelPersistThread) { + ::voxelPersistThread->initialize(true); + } } // Check to see if the user passed in a command line option for loading an old style local @@ -610,32 +544,6 @@ int main(int argc, const char * argv[]) { printf("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d\n", packetsPerSecond, PACKETS_PER_CLIENT_PER_INTERVAL); } - const char* ADD_RANDOM_VOXELS = "--AddRandomVoxels"; - if (cmdOptionExists(argc, argv, ADD_RANDOM_VOXELS)) { - // create an octal code buffer and load it with 0 so that the recursive tree fill can give - // octal codes to the tree nodes that it is creating - randomlyFillVoxelTree(MAX_VOXEL_TREE_DEPTH_LEVELS, serverTree.rootNode); - } - - const char* ADD_SCENE = "--AddScene"; - bool addScene = cmdOptionExists(argc, argv, ADD_SCENE); - const char* NO_ADD_SCENE = "--NoAddScene"; - bool noAddScene = cmdOptionExists(argc, argv, NO_ADD_SCENE); - if (addScene && noAddScene) { - printf("WARNING! --AddScene and --NoAddScene are mutually exclusive. We will honor --NoAddScene\n"); - } - - // We will add a scene if... - // 1) we attempted to load a persistant file and it wasn't there - // 2) you asked us to add a scene - // HOWEVER -- we will NEVER add a scene if you explicitly tell us not to! - // - // TEMPORARILY DISABLED!!! - bool actuallyAddScene = false; // !noAddScene && (addScene || (::wantVoxelPersist && !persistantFileRead)); - if (actuallyAddScene) { - addSphereScene(&serverTree); - } - // for now, initialize the environments with fixed values environmentData[1].setID(1); environmentData[1].setGravity(1.0f); @@ -652,10 +560,10 @@ int main(int argc, const char * argv[]) { pthread_t sendVoxelThread; pthread_create(&sendVoxelThread, NULL, distributeVoxelsToListeners, NULL); - sockaddr nodePublicAddress; + sockaddr senderAddress; unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE]; - ssize_t receivedBytes; + ssize_t packetLength; timeval lastDomainServerCheckIn = {}; @@ -664,6 +572,12 @@ int main(int argc, const char * argv[]) { if (::jurisdictionSender) { ::jurisdictionSender->initialize(true); } + + // set up our VoxelServerPacketProcessor + ::voxelServerPacketProcessor = new VoxelServerPacketProcessor(); + if (::voxelServerPacketProcessor) { + ::voxelServerPacketProcessor->initialize(true); + } // loop to send to nodes requesting data while (true) { @@ -674,155 +588,34 @@ int main(int argc, const char * argv[]) { NodeList::getInstance()->sendDomainServerCheckIn(); } - // check to see if we need to persist our voxel state - persistVoxelsWhenDirty(); - - if (nodeList->getNodeSocket()->receive(&nodePublicAddress, packetData, &receivedBytes) && + if (nodeList->getNodeSocket()->receive(&senderAddress, packetData, &packetLength) && packetVersionMatch(packetData)) { - + int numBytesPacketHeader = numBytesForPacketHeader(packetData); - - if (packetData[0] == PACKET_TYPE_SET_VOXEL || packetData[0] == PACKET_TYPE_SET_VOXEL_DESTRUCTIVE) { - bool destructive = (packetData[0] == PACKET_TYPE_SET_VOXEL_DESTRUCTIVE); - PerformanceWarning warn(::shouldShowAnimationDebug, - destructive ? "PACKET_TYPE_SET_VOXEL_DESTRUCTIVE" : "PACKET_TYPE_SET_VOXEL", - ::shouldShowAnimationDebug); - - ::receivedPacketCount++; - - unsigned short int itemNumber = (*((unsigned short int*)(packetData + numBytesPacketHeader))); - if (::shouldShowAnimationDebug) { - printf("got %s - command from client receivedBytes=%ld itemNumber=%d\n", - destructive ? "PACKET_TYPE_SET_VOXEL_DESTRUCTIVE" : "PACKET_TYPE_SET_VOXEL", - receivedBytes,itemNumber); - } - - if (::debugVoxelReceiving) { - printf("got %s - %d command from client receivedBytes=%ld itemNumber=%d\n", - destructive ? "PACKET_TYPE_SET_VOXEL_DESTRUCTIVE" : "PACKET_TYPE_SET_VOXEL", - ::receivedPacketCount, receivedBytes,itemNumber); - } - int atByte = numBytesPacketHeader + sizeof(itemNumber); - unsigned char* voxelData = (unsigned char*)&packetData[atByte]; - while (atByte < receivedBytes) { - unsigned char octets = (unsigned char)*voxelData; - const int COLOR_SIZE_IN_BYTES = 3; - int voxelDataSize = bytesRequiredForCodeLength(octets) + COLOR_SIZE_IN_BYTES; - int voxelCodeSize = bytesRequiredForCodeLength(octets); - // color randomization on insert - int colorRandomizer = ::wantColorRandomizer ? randIntInRange (-50, 50) : 0; - int red = voxelData[voxelCodeSize + 0]; - int green = voxelData[voxelCodeSize + 1]; - int blue = voxelData[voxelCodeSize + 2]; - - if (::shouldShowAnimationDebug) { - printf("insert voxels - wantColorRandomizer=%s old r=%d,g=%d,b=%d \n", - (::wantColorRandomizer?"yes":"no"),red,green,blue); - } - - red = std::max(0, std::min(255, red + colorRandomizer)); - green = std::max(0, std::min(255, green + colorRandomizer)); - blue = std::max(0, std::min(255, blue + colorRandomizer)); - - if (::shouldShowAnimationDebug) { - printf("insert voxels - wantColorRandomizer=%s NEW r=%d,g=%d,b=%d \n", - (::wantColorRandomizer?"yes":"no"),red,green,blue); - } - voxelData[voxelCodeSize + 0] = red; - voxelData[voxelCodeSize + 1] = green; - voxelData[voxelCodeSize + 2] = blue; - - if (::shouldShowAnimationDebug) { - float* vertices = firstVertexForCode(voxelData); - printf("inserting voxel at: %f,%f,%f\n", vertices[0], vertices[1], vertices[2]); - delete []vertices; - } - - serverTree.readCodeColorBufferToTree(voxelData, destructive); - // skip to next - voxelData += voxelDataSize; - atByte += voxelDataSize; - } - - // Make sure our Node and NodeList knows we've heard from this node. - Node* node = NodeList::getInstance()->nodeWithAddress(&nodePublicAddress); - if (node) { - node->setLastHeardMicrostamp(usecTimestampNow()); - } - - } else if (packetData[0] == PACKET_TYPE_ERASE_VOXEL) { - - // Send these bits off to the VoxelTree class to process them - pthread_mutex_lock(&::treeLock); - serverTree.processRemoveVoxelBitstream((unsigned char*)packetData, receivedBytes); - pthread_mutex_unlock(&::treeLock); - - // Make sure our Node and NodeList knows we've heard from this node. - Node* node = NodeList::getInstance()->nodeWithAddress(&nodePublicAddress); - if (node) { - node->setLastHeardMicrostamp(usecTimestampNow()); - } - } else if (packetData[0] == PACKET_TYPE_Z_COMMAND) { - - // the Z command is a special command that allows the sender to send the voxel server high level semantic - // requests, like erase all, or add sphere scene - - char* command = (char*) &packetData[numBytesPacketHeader]; // start of the command - int commandLength = strlen(command); // commands are null terminated strings - int totalLength = numBytesPacketHeader + commandLength + 1; // 1 for null termination - printf("got Z message len(%ld)= %s\n", receivedBytes, command); - bool rebroadcast = true; // by default rebroadcast - - while (totalLength <= receivedBytes) { - if (strcmp(command, ERASE_ALL_COMMAND) == 0) { - printf("got Z message == erase all\n"); - eraseVoxelTreeAndCleanupNodeVisitData(); - rebroadcast = false; - } - if (strcmp(command, ADD_SCENE_COMMAND) == 0) { - printf("got Z message == add scene\n"); - addSphereScene(&serverTree); - rebroadcast = false; - } - if (strcmp(command, TEST_COMMAND) == 0) { - printf("got Z message == a message, nothing to do, just report\n"); - } - totalLength += commandLength + 1; // 1 for null termination - } - - if (rebroadcast) { - // Now send this to the connected nodes so they can also process these messages - printf("rebroadcasting Z message to connected nodes... nodeList.broadcastToNodes()\n"); - nodeList->broadcastToNodes(packetData, receivedBytes, &NODE_TYPE_AGENT, 1); - } - - // Make sure our Node and NodeList knows we've heard from this node. - Node* node = NodeList::getInstance()->nodeWithAddress(&nodePublicAddress); - if (node) { - node->setLastHeardMicrostamp(usecTimestampNow()); - } - } else if (packetData[0] == PACKET_TYPE_HEAD_DATA) { + if (packetData[0] == PACKET_TYPE_HEAD_DATA) { // If we got a PACKET_TYPE_HEAD_DATA, then we're talking to an NODE_TYPE_AVATAR, and we // need to make sure we have it in our nodeList. - + uint16_t nodeID = 0; unpackNodeId(packetData + numBytesPacketHeader, &nodeID); - Node* node = nodeList->addOrUpdateNode(&nodePublicAddress, - &nodePublicAddress, + Node* node = NodeList::getInstance()->addOrUpdateNode(&senderAddress, + &senderAddress, NODE_TYPE_AGENT, nodeID); - - nodeList->updateNodeWithData(node, packetData, receivedBytes); + + NodeList::getInstance()->updateNodeWithData(node, packetData, packetLength); } else if (packetData[0] == PACKET_TYPE_PING) { // If the packet is a ping, let processNodeData handle it. - nodeList->processNodeData(&nodePublicAddress, packetData, receivedBytes); + NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength); } else if (packetData[0] == PACKET_TYPE_DOMAIN) { - nodeList->processNodeData(&nodePublicAddress, packetData, receivedBytes); + NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength); } else if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) { if (::jurisdictionSender) { - jurisdictionSender->queueReceivedPacket(nodePublicAddress, packetData, receivedBytes); + ::jurisdictionSender->queueReceivedPacket(senderAddress, packetData, packetLength); } + } else if (::voxelServerPacketProcessor) { + ::voxelServerPacketProcessor->queueReceivedPacket(senderAddress, packetData, packetLength); } else { printf("unknown packet ignored... packetData[0]=%c\n", packetData[0]); } @@ -837,10 +630,20 @@ int main(int argc, const char * argv[]) { } if (::jurisdictionSender) { - jurisdictionSender->terminate(); + ::jurisdictionSender->terminate(); delete ::jurisdictionSender; } + if (::voxelServerPacketProcessor) { + ::voxelServerPacketProcessor->terminate(); + delete ::voxelServerPacketProcessor; + } + + if (::voxelPersistThread) { + ::voxelPersistThread->terminate(); + delete ::voxelPersistThread; + } + return 0; } From bb5a432c7451f6df85004475a88d297659790636 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 21 Aug 2013 15:21:58 -0700 Subject: [PATCH 3/9] removed old dead code --- voxel-server/src/VoxelServer.h | 1 - .../src/VoxelServerPacketProcessor.cpp | 23 ++++--------------- voxel-server/src/main.cpp | 5 ---- 3 files changed, 4 insertions(+), 25 deletions(-) diff --git a/voxel-server/src/VoxelServer.h b/voxel-server/src/VoxelServer.h index b258ee9406..326a926dbe 100644 --- a/voxel-server/src/VoxelServer.h +++ b/voxel-server/src/VoxelServer.h @@ -38,7 +38,6 @@ extern int PACKETS_PER_CLIENT_PER_INTERVAL; extern VoxelTree serverTree; // this IS a reaveraging tree extern bool wantVoxelPersist; extern bool wantLocalDomain; -extern bool wantColorRandomizer; extern bool debugVoxelSending; extern bool shouldShowAnimationDebug; extern bool displayVoxelStats; diff --git a/voxel-server/src/VoxelServerPacketProcessor.cpp b/voxel-server/src/VoxelServerPacketProcessor.cpp index de2848a7ac..4de08cadb5 100644 --- a/voxel-server/src/VoxelServerPacketProcessor.cpp +++ b/voxel-server/src/VoxelServerPacketProcessor.cpp @@ -47,28 +47,13 @@ void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned int voxelDataSize = bytesRequiredForCodeLength(octets) + COLOR_SIZE_IN_BYTES; int voxelCodeSize = bytesRequiredForCodeLength(octets); - // color randomization on insert - int colorRandomizer = ::wantColorRandomizer ? randIntInRange (-50, 50) : 0; - int red = voxelData[voxelCodeSize + 0]; - int green = voxelData[voxelCodeSize + 1]; - int blue = voxelData[voxelCodeSize + 2]; - if (::shouldShowAnimationDebug) { - printf("insert voxels - wantColorRandomizer=%s old r=%d,g=%d,b=%d \n", - (::wantColorRandomizer?"yes":"no"),red,green,blue); - } - - red = std::max(0, std::min(255, red + colorRandomizer)); - green = std::max(0, std::min(255, green + colorRandomizer)); - blue = std::max(0, std::min(255, blue + colorRandomizer)); + int red = voxelData[voxelCodeSize + 0]; + int green = voxelData[voxelCodeSize + 1]; + int blue = voxelData[voxelCodeSize + 2]; - if (::shouldShowAnimationDebug) { - printf("insert voxels - wantColorRandomizer=%s NEW r=%d,g=%d,b=%d \n", - (::wantColorRandomizer?"yes":"no"),red,green,blue); + printf("insert voxels - r=%d,g=%d,b=%d \n", red, green, blue); } - voxelData[voxelCodeSize + 0] = red; - voxelData[voxelCodeSize + 1] = green; - voxelData[voxelCodeSize + 2] = blue; if (::shouldShowAnimationDebug) { float* vertices = firstVertexForCode(voxelData); diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index fc87f5973b..299a148f09 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -44,7 +44,6 @@ int PACKETS_PER_CLIENT_PER_INTERVAL = 10; VoxelTree serverTree(true); // this IS a reaveraging tree bool wantVoxelPersist = true; bool wantLocalDomain = false; -bool wantColorRandomizer = false; bool debugVoxelSending = false; bool shouldShowAnimationDebug = false; bool displayVoxelStats = false; @@ -475,10 +474,6 @@ int main(int argc, const char * argv[]) { ::shouldShowAnimationDebug = cmdOptionExists(argc, argv, WANT_ANIMATION_DEBUG); printf("shouldShowAnimationDebug=%s\n", debug::valueOf(::shouldShowAnimationDebug)); - const char* WANT_COLOR_RANDOMIZER = "--wantColorRandomizer"; - ::wantColorRandomizer = cmdOptionExists(argc, argv, WANT_COLOR_RANDOMIZER); - printf("wantColorRandomizer=%s\n", debug::valueOf(::wantColorRandomizer)); - // By default we will voxel persist, if you want to disable this, then pass in this parameter const char* NO_VOXEL_PERSIST = "--NoVoxelPersist"; if (cmdOptionExists(argc, argv, NO_VOXEL_PERSIST)) { From f19477dd636c744907f12836aac780a0188cbb87 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 21 Aug 2013 15:57:25 -0700 Subject: [PATCH 4/9] dead code cleanup --- voxel-server/src/VoxelServerPacketProcessor.cpp | 8 ++------ voxel-server/src/main.cpp | 16 ---------------- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/voxel-server/src/VoxelServerPacketProcessor.cpp b/voxel-server/src/VoxelServerPacketProcessor.cpp index 4de08cadb5..0717e39ad8 100644 --- a/voxel-server/src/VoxelServerPacketProcessor.cpp +++ b/voxel-server/src/VoxelServerPacketProcessor.cpp @@ -52,13 +52,9 @@ void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned int green = voxelData[voxelCodeSize + 1]; int blue = voxelData[voxelCodeSize + 2]; - printf("insert voxels - r=%d,g=%d,b=%d \n", red, green, blue); - } - - if (::shouldShowAnimationDebug) { float* vertices = firstVertexForCode(voxelData); - printf("inserting voxel at: %f,%f,%f\n", vertices[0], vertices[1], vertices[2]); - delete []vertices; + printf("inserting voxel: %f,%f,%f r=%d,g=%d,b=%d\n", vertices[0], vertices[1], vertices[2], red, green, blue); + delete[] vertices; } serverTree.readCodeColorBufferToTree(voxelData, destructive); diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 299a148f09..1a22ccf1ee 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -60,20 +60,6 @@ VoxelPersistThread* voxelPersistThread = NULL; pthread_mutex_t treeLock; -void eraseVoxelTreeAndCleanupNodeVisitData() { - - // As our tree to erase all it's voxels - ::serverTree.eraseAllVoxels(); - // enumerate the nodes clean up their marker nodes - for (NodeList::iterator node = NodeList::getInstance()->begin(); node != NodeList::getInstance()->end(); node++) { - VoxelNodeData* nodeData = (VoxelNodeData*) node->getLinkedData(); - if (nodeData) { - // clean up the node visit data - nodeData->nodeBag.deleteAll(); - } - } -} - void handlePacketSend(NodeList* nodeList, NodeList::iterator& node, VoxelNodeData* nodeData, @@ -111,14 +97,12 @@ void handlePacketSend(NodeList* nodeList, nodeData->resetVoxelPacket(); } - // Version of voxel distributor that sends the deepest LOD level at once void deepestLevelVoxelDistributor(NodeList* nodeList, NodeList::iterator& node, VoxelNodeData* nodeData, bool viewFrustumChanged) { - pthread_mutex_lock(&::treeLock); int truePacketsSent = 0; From 25e21f862c6fe3b32fd1f4b60917bf2d7d32e57a Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 21 Aug 2013 16:23:55 -0700 Subject: [PATCH 5/9] flush delete queue after encode is complete --- libraries/voxels/src/VoxelTree.cpp | 13 +++++++++++++ libraries/voxels/src/VoxelTree.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 3e04686843..bd22446c17 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1832,6 +1832,9 @@ void VoxelTree::doneEncoding(VoxelNode* node) { pthread_mutex_lock(&_encodeSetLock); _codesBeingEncoded.erase(node->getOctalCode()); pthread_mutex_unlock(&_encodeSetLock); + + // if we have any pending delete codes, then delete them now. + emptyDeleteQueue(); } void VoxelTree::startDeleting(unsigned char* code) { @@ -1859,6 +1862,16 @@ void VoxelTree::queueForLaterDelete(unsigned char* codeBuffer) { pthread_mutex_unlock(&_deletePendingSetLock); } +void VoxelTree::emptyDeleteQueue() { + pthread_mutex_lock(&_deletePendingSetLock); + for (std::set::iterator i = _codesPendingDelete.begin(); i != _codesPendingDelete.end(); ++i) { + unsigned char* codeToDelete = *i; + _codesBeingDeleted.erase(codeToDelete); + deleteVoxelCodeFromTree(codeToDelete, COLLAPSE_EMPTY_TREE); + } + pthread_mutex_unlock(&_deletePendingSetLock); +} + void VoxelTree::cancelImport() { _stopImport = true; } diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 5c6add5230..4128ba6cbd 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -252,6 +252,8 @@ private: /// Adds an Octal Code to the set of codes that needs to be deleted void queueForLaterDelete(unsigned char* codeBuffer); + /// flushes out any Octal Codes that had to be queued + void emptyDeleteQueue(); }; float boundaryDistanceForRenderLevel(unsigned int renderLevel); From 213f04f55ee773db98c35be85f02f97d5525ceb8 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 21 Aug 2013 16:37:58 -0700 Subject: [PATCH 6/9] fix comment --- voxel-server/src/VoxelServer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/voxel-server/src/VoxelServer.h b/voxel-server/src/VoxelServer.h index 326a926dbe..df45b747b0 100644 --- a/voxel-server/src/VoxelServer.h +++ b/voxel-server/src/VoxelServer.h @@ -1,7 +1,7 @@ // VoxelServer.h // voxel-server // -// Created by Stephen Birarda on 3/13/13. +// Created by Brad Hefta-Gaub on 8/21/13 // // From aa5aa1fb49c2921eaeefef27cb594e87bd05ea89 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 21 Aug 2013 16:41:10 -0700 Subject: [PATCH 7/9] fix comment --- voxel-server/src/VoxelPersistThread.cpp | 2 +- voxel-server/src/VoxelPersistThread.h | 4 ++-- voxel-server/src/VoxelServer.h | 1 + voxel-server/src/VoxelServerPacketProcessor.cpp | 2 +- voxel-server/src/VoxelServerPacketProcessor.h | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/voxel-server/src/VoxelPersistThread.cpp b/voxel-server/src/VoxelPersistThread.cpp index 00272b57a4..19c69bdc4b 100644 --- a/voxel-server/src/VoxelPersistThread.cpp +++ b/voxel-server/src/VoxelPersistThread.cpp @@ -2,7 +2,7 @@ // VoxelPersistThread.cpp // voxel-server // -// Created by Brad Hefta-Gaub on 8/12/13. +// Created by Brad Hefta-Gaub on 8/21/13 // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // // Threaded or non-threaded voxel persistance diff --git a/voxel-server/src/VoxelPersistThread.h b/voxel-server/src/VoxelPersistThread.h index 0b5bd2dc16..bdd60619b3 100644 --- a/voxel-server/src/VoxelPersistThread.h +++ b/voxel-server/src/VoxelPersistThread.h @@ -1,8 +1,8 @@ // // VoxelPersistThread.h -// shared +// voxel-server // -// Created by Brad Hefta-Gaub on 8/12/13. +// Created by Brad Hefta-Gaub on 8/21/13 // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // // Threaded or non-threaded received packet processor. diff --git a/voxel-server/src/VoxelServer.h b/voxel-server/src/VoxelServer.h index df45b747b0..0f4c8577db 100644 --- a/voxel-server/src/VoxelServer.h +++ b/voxel-server/src/VoxelServer.h @@ -2,6 +2,7 @@ // voxel-server // // Created by Brad Hefta-Gaub on 8/21/13 +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // // diff --git a/voxel-server/src/VoxelServerPacketProcessor.cpp b/voxel-server/src/VoxelServerPacketProcessor.cpp index 0717e39ad8..aaa347ee86 100644 --- a/voxel-server/src/VoxelServerPacketProcessor.cpp +++ b/voxel-server/src/VoxelServerPacketProcessor.cpp @@ -2,7 +2,7 @@ // VoxelServerPacketProcessor.cpp // voxel-server // -// Created by Brad Hefta-Gaub on 8/12/13. +// Created by Brad Hefta-Gaub on 8/21/13 // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // // Threaded or non-threaded network packet processor for the voxel-server diff --git a/voxel-server/src/VoxelServerPacketProcessor.h b/voxel-server/src/VoxelServerPacketProcessor.h index b2b44666e0..caad7bf240 100644 --- a/voxel-server/src/VoxelServerPacketProcessor.h +++ b/voxel-server/src/VoxelServerPacketProcessor.h @@ -2,7 +2,7 @@ // VoxelServerPacketProcessor.h // voxel-server // -// Created by Brad Hefta-Gaub on 8/12/13. +// Created by Brad Hefta-Gaub on 8/21/13 // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // // Threaded or non-threaded network packet processor for the voxel-server From 535a9faef314a81993a4d37dd4103216ea09c790 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 21 Aug 2013 16:42:35 -0700 Subject: [PATCH 8/9] fix comment --- voxel-server/src/VoxelPersistThread.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/voxel-server/src/VoxelPersistThread.h b/voxel-server/src/VoxelPersistThread.h index bdd60619b3..bdf8bbd73c 100644 --- a/voxel-server/src/VoxelPersistThread.h +++ b/voxel-server/src/VoxelPersistThread.h @@ -5,11 +5,11 @@ // Created by Brad Hefta-Gaub on 8/21/13 // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // -// Threaded or non-threaded received packet processor. +// Threaded or non-threaded voxel persistance // -#ifndef __shared__VoxelPersistThread__ -#define __shared__VoxelPersistThread__ +#ifndef __voxel_server__VoxelPersistThread__ +#define __voxel_server__VoxelPersistThread__ #include #include @@ -30,4 +30,4 @@ private: int _persistInterval; }; -#endif // __shared__PacketReceiver__ +#endif // __voxel_server__VoxelPersistThread__ From 6206d9e8db427ff8f7f825f812b52f8d10bba423 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 21 Aug 2013 17:41:26 -0700 Subject: [PATCH 9/9] fix for collisions when wearing Oculus --- interface/src/avatar/MyAvatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 4ab5caf882..00898da333 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -172,7 +172,7 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter, float gyroCam if (_isCollisionsOn) { Camera* myCamera = Application::getInstance()->getCamera(); - if (myCamera->getMode() == CAMERA_MODE_FIRST_PERSON) { + if (myCamera->getMode() == CAMERA_MODE_FIRST_PERSON && !OculusManager::isConnected()) { _collisionRadius = myCamera->getAspectRatio() * (myCamera->getNearClip() / cos(myCamera->getFieldOfView() / 2.f)); _collisionRadius *= COLLISION_RADIUS_SCALAR; } else {