From ecb6309932af5e747c58dbbe0cbe839da7091a10 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 8 Jul 2015 15:02:54 -0700 Subject: [PATCH] fix HEADER_LENGTH in Octree --- libraries/octree/src/Octree.cpp | 168 ++++++++++++++++---------------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index 6a884ec062..836c9649c1 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -190,13 +190,13 @@ bool Octree::recurseElementWithOperator(OctreeElement* element, RecurseOctreeOpe if (operatorObject->preRecursion(element)) { for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { OctreeElement* child = element->getChildAtIndex(i); - + // If there is no child at that location, the Operator may want to create a child at that location. // So give the operator a chance to do so.... if (!child) { child = operatorObject->possiblyCreateChildAt(element, i); } - + if (child) { if (!recurseElementWithOperator(child, operatorObject, recursionCount + 1)) { break; // stop recursing if operator returns false... @@ -204,7 +204,7 @@ bool Octree::recurseElementWithOperator(OctreeElement* element, RecurseOctreeOpe } } } - + return operatorObject->postRecursion(element); } @@ -282,20 +282,20 @@ int Octree::readElementData(OctreeElement* destinationElement, const unsigned ch // give this destination element the child mask from the packet const unsigned char ALL_CHILDREN_ASSUMED_TO_EXIST = 0xFF; - + if ((size_t)bytesLeftToRead < sizeof(unsigned char)) { qCDebug(octree) << "UNEXPECTED: readElementData() only had " << bytesLeftToRead << " bytes. " "Not enough for meaningful data."; return bytesAvailable; // assume we read the entire buffer... } - + if (destinationElement->getScale() < SCALE_AT_DANGEROUSLY_DEEP_RECURSION) { - qCDebug(octree) << "UNEXPECTED: readElementData() destination element is unreasonably small [" + qCDebug(octree) << "UNEXPECTED: readElementData() destination element is unreasonably small [" << destinationElement->getScale() << " meters] " << " Discarding " << bytesAvailable << " remaining bytes."; return bytesAvailable; // assume we read the entire buffer... } - + unsigned char colorInPacketMask = *nodeData; bytesRead += sizeof(colorInPacketMask); bytesLeftToRead -= sizeof(colorInPacketMask); @@ -303,13 +303,13 @@ int Octree::readElementData(OctreeElement* destinationElement, const unsigned ch for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { // check the colors mask to see if we have a child to color in if (oneAtBit(colorInPacketMask, i)) { - // addChildAtIndex() should actually be called getOrAddChildAtIndex(). + // addChildAtIndex() should actually be called getOrAddChildAtIndex(). // When it adds the child it automatically sets the detinationElement dirty. OctreeElement* childElementAt = destinationElement->addChildAtIndex(i); int childElementDataRead = childElementAt->readElementDataFromBuffer(nodeData + bytesRead, bytesLeftToRead, args); childElementAt->setSourceUUID(args.sourceUUID); - + bytesRead += childElementDataRead; bytesLeftToRead -= childElementDataRead; @@ -327,7 +327,7 @@ int Octree::readElementData(OctreeElement* destinationElement, const unsigned ch unsigned char childrenInTreeMask = ALL_CHILDREN_ASSUMED_TO_EXIST; unsigned char childInBufferMask = 0; - int bytesForMasks = args.includeExistsBits ? sizeof(childrenInTreeMask) + sizeof(childInBufferMask) + int bytesForMasks = args.includeExistsBits ? sizeof(childrenInTreeMask) + sizeof(childInBufferMask) : sizeof(childInBufferMask); if (bytesLeftToRead < bytesForMasks) { @@ -337,7 +337,7 @@ int Octree::readElementData(OctreeElement* destinationElement, const unsigned ch } return bytesAvailable; // assume we read the entire buffer... } - + childrenInTreeMask = args.includeExistsBits ? *(nodeData + bytesRead) : ALL_CHILDREN_ASSUMED_TO_EXIST; childInBufferMask = *(nodeData + bytesRead + (args.includeExistsBits ? sizeof(childrenInTreeMask) : 0)); @@ -378,7 +378,7 @@ int Octree::readElementData(OctreeElement* destinationElement, const unsigned ch } } } - + // if this is the root, and there is more data to read, allow it to read it's element data... if (destinationElement == _rootElement && rootElementHasData() && bytesLeftToRead > 0) { // tell the element to read the subsequent data @@ -420,13 +420,13 @@ void Octree::readBitstreamToTree(const unsigned char * bitstream, unsigned long "This buffer is corrupt. Returning."; return; } - + if (numberOfThreeBitSectionsInStream == OVERFLOWED_OCTCODE_BUFFER) { qCDebug(octree) << "UNEXPECTED: parsing of the octal code would overflow the buffer. " "This buffer is corrupt. Returning."; return; } - + int numberOfThreeBitSectionsFromNode = numberOfThreeBitSectionsInCode(bitstreamRootElement->getOctalCode()); // if the octal code returned is not on the same level as the code being searched for, we have OctreeElements to create @@ -583,11 +583,11 @@ void Octree::deleteOctalCodeFromTreeRecursion(OctreeElement* element, void* extr void Octree::eraseAllOctreeElements(bool createNewRoot) { delete _rootElement; // this will recurse and delete all children _rootElement = NULL; - + if (createNewRoot) { _rootElement = createNewElement(); } - + _isDirty = true; } @@ -678,7 +678,7 @@ OctreeElement* Octree::getOctreeElementAt(float x, float y, float z, float s) co OctreeElement* Octree::getOctreeEnclosingElementAt(float x, float y, float z, float s) const { unsigned char* octalCode = pointToOctalCode(x,y,z,s); OctreeElement* element = nodeForOctalCode(_rootElement, octalCode, NULL); - + delete[] octalCode; // cleanup memory #ifdef HAS_AUDIT_CHILDREN if (element) { @@ -713,7 +713,7 @@ public: bool findRayIntersectionOp(OctreeElement* element, void* extraData) { RayArgs* args = static_cast(extraData); bool keepSearching = true; - if (element->findRayIntersection(args->origin, args->direction, keepSearching, + if (element->findRayIntersection(args->origin, args->direction, keepSearching, args->element, args->distance, args->face, args->intersectedObject, args->precisionPicking)) { args->found = true; } @@ -723,7 +723,7 @@ bool findRayIntersectionOp(OctreeElement* element, void* extraData) { bool Octree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, OctreeElement*& element, float& distance, BoxFace& face, void** intersectedObject, Octree::lockType lockType, bool* accurateResult, bool precisionPicking) { - RayArgs args = { origin, direction, element, distance, face, + RayArgs args = { origin, direction, element, distance, face, intersectedObject, false, precisionPicking}; distance = FLT_MAX; @@ -742,7 +742,7 @@ bool Octree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direc } recurseTreeWithOperation(findRayIntersectionOp, &args); - + if (gotLock) { unlock(); } @@ -772,7 +772,7 @@ bool findSpherePenetrationOp(OctreeElement* element, void* extraData) { if (element->hasContent()) { glm::vec3 elementPenetration; if (element->findSpherePenetration(args->center, args->radius, elementPenetration, &args->penetratedObject)) { - // NOTE: it is possible for this penetration accumulation algorithm to produce a + // NOTE: it is possible for this penetration accumulation algorithm to produce a // final penetration vector with zero length. args->penetration = addPenetrations(args->penetration, elementPenetration); args->found = true; @@ -817,7 +817,7 @@ bool Octree::findSpherePenetration(const glm::vec3& center, float radius, glm::v if (gotLock) { unlock(); } - + if (accurateResult) { *accurateResult = true; // if user asked to accuracy or result, let them know this is accurate } @@ -867,14 +867,14 @@ bool findCapsulePenetrationOp(OctreeElement* element, void* extraData) { } uint qHash(const glm::vec3& point) { - // NOTE: TREE_SCALE = 16384 (15 bits) and multiplier is 1024 (11 bits), + // NOTE: TREE_SCALE = 16384 (15 bits) and multiplier is 1024 (11 bits), // so each component (26 bits) uses more than its alloted 21 bits. // however we don't expect to span huge cubes so it is ok if we wrap // (every 2^21 / 2^10 = 2048 meters). const uint BITS_PER_COMPONENT = 21; const quint64 MAX_SCALED_COMPONENT = 2097152; // 2^21 const float RESOLUTION_PER_METER = 1024.0f; // 2^10 - return qHash((quint64)(point.x * RESOLUTION_PER_METER) % MAX_SCALED_COMPONENT + + return qHash((quint64)(point.x * RESOLUTION_PER_METER) % MAX_SCALED_COMPONENT + (((quint64)(point.y * RESOLUTION_PER_METER)) % MAX_SCALED_COMPONENT << BITS_PER_COMPONENT) + (((quint64)(point.z * RESOLUTION_PER_METER)) % MAX_SCALED_COMPONENT << 2 * BITS_PER_COMPONENT)); } @@ -899,9 +899,9 @@ bool findContentInCubeOp(OctreeElement* element, void* extraData) { return false; } -bool Octree::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, +bool Octree::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration, Octree::lockType lockType, bool* accurateResult) { - + CapsuleArgs args = { start, end, radius, penetration, false }; penetration = glm::vec3(0.0f, 0.0f, 0.0f); @@ -920,7 +920,7 @@ bool Octree::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end } recurseTreeWithOperation(findCapsulePenetrationOp, &args); - + if (gotLock) { unlock(); } @@ -967,7 +967,7 @@ OctreeElement* Octree::getElementEnclosingPoint(const glm::vec3& point, Octree:: GetElementEnclosingArgs args; args.point = point; args.element = NULL; - + bool gotLock = false; if (lockType == Octree::Lock) { lockForRead(); @@ -983,7 +983,7 @@ OctreeElement* Octree::getElementEnclosingPoint(const glm::vec3& point, Octree:: } recurseTreeWithOperation(getElementEnclosingOperation, (void*)&args); - + if (gotLock) { unlock(); } @@ -1040,7 +1040,7 @@ int Octree::encodeTreeBitstream(OctreeElement* element, params.stopReason = EncodeBitstreamParams::DIDNT_FIT; return bytesWritten; } - + bytesWritten += codeLength; // keep track of byte count int currentEncodeLevel = 0; @@ -1126,7 +1126,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element, return bytesAtThisLevel; } } - + ViewFrustum::location nodeLocationThisView = ViewFrustum::INSIDE; // assume we're inside // caller can pass NULL as viewFrustum if they want everything @@ -1216,7 +1216,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element, // If the user also asked for occlusion culling, check if this element is occluded, but only if it's not a leaf. // leaf occlusion is handled down below when we check child nodes if (params.wantOcclusionCulling && !element->isLeaf()) { - OctreeProjectedPolygon* voxelPolygon = + OctreeProjectedPolygon* voxelPolygon = new OctreeProjectedPolygon(params.viewFrustum->getProjectedPolygon(element->getAACube())); // In order to check occlusion culling, the shadow has to be "all in view" otherwise, we will ignore occlusion @@ -1256,13 +1256,13 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element, if (params.includeExistsBits) { requiredBytes += sizeof(childrenExistInTreeBits); } - + // If this datatype allows root elements to include data, and this is the root, then ask the tree for the // minimum bytes needed for root data and reserve those also if (element == _rootElement && rootElementHasData()) { requiredBytes += minimumRequiredRootDataBytes(); } - + bool continueThisLevel = packetData->reserveBytes(requiredBytes); // If we can't reserve our minimum bytes then we can discard this level and return as if none of this level fits @@ -1327,10 +1327,10 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element, OctreeElement* childElement = sortedChildren[i]; int originalIndex = indexOfChildren[i]; - bool childIsInView = (childElement && + bool childIsInView = (childElement && ( !params.viewFrustum || // no view frustum was given, everything is assumed in view (nodeLocationThisView == ViewFrustum::INSIDE) || // parent was fully in view, we can assume ALL children are - (nodeLocationThisView == ViewFrustum::INTERSECT && + (nodeLocationThisView == ViewFrustum::INTERSECT && childElement->isInView(*params.viewFrustum)) // the parent intersects and the child is in view )); @@ -1450,7 +1450,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element, } } - // NOTE: the childrenDataBits indicates that there is an array of child element data included in this packet. + // NOTE: the childrenDataBits indicates that there is an array of child element data included in this packet. // We wil write this bit mask but we may come back later and update the bits that are actually included packetData->releaseReservedBytes(sizeof(childrenDataBits)); continueThisLevel = packetData->appendBitMask(childrenDataBits); @@ -1463,10 +1463,10 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element, if (params.stats) { params.stats->colorBitsWritten(); // really data bits not just color bits } - + // NOW might be a good time to give our tree subclass and this element a chance to set up and check any extra encode data element->initializeExtraEncodeData(params); - + // write the child element data... NOTE: includeColor means include element data // NOTE: the format of the bitstream is generally this: // [octalcode] @@ -1486,31 +1486,31 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element, // processed and sent the data bits for. Let our tree subclass determine if it really wants to send the // data for this child at this point if (childElement && element->shouldIncludeChildData(i, params)) { - + int bytesBeforeChild = packetData->getUncompressedSize(); - + // a childElement may "partially" write it's data. for example, the model server where the entire // contents of the element may be larger than can fit in a single MTU/packetData. In this case, // we want to allow the appendElementData() to respond that it produced partial data, which should be // written, but that the childElement needs to be reprocessed in an additional pass or passes // to be completed. LevelDetails childDataLevelKey = packetData->startLevel(); - + OctreeElement::AppendState childAppendState = childElement->appendElementData(packetData, params); - + // allow our tree subclass to do any additional bookkeeping it needs to do with encoded data state element->updateEncodedData(i, childAppendState, params); // Continue this level so long as some part of this child element was appended. bool childFit = (childAppendState != OctreeElement::NONE); - + // some datatypes (like Voxels) assume that all child data will fit, if it doesn't fit // the data type wants to bail on this element level completely if (!childFit && mustIncludeAllChildData()) { continueThisLevel = false; - break; + break; } - + // If the child was partially or fully appended, then mark the actualChildrenDataBits as including // this child data if (childFit) { @@ -1527,9 +1527,9 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element, elementAppendState = OctreeElement::PARTIAL; params.stopReason = EncodeBitstreamParams::DIDNT_FIT; } - + int bytesAfterChild = packetData->getUncompressedSize(); - + bytesAtThisLevel += (bytesAfterChild - bytesBeforeChild); // keep track of byte count for this child // don't need to check childElement here, because we can't get here with no childElement @@ -1540,7 +1540,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element, } } } - + if (!mustIncludeAllChildData() && !continueThisLevel) { qCDebug(octree) << "WARNING UNEXPECTED CASE: reached end of child element data loop with continueThisLevel=FALSE"; qCDebug(octree) << "This is not expected!!!! -- continueThisLevel=FALSE...."; @@ -1753,7 +1753,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element, // If we made it this far, then we've written all of our child data... if this element is the root // element, then we also allow the root element to write out it's data... if (continueThisLevel && element == _rootElement && rootElementHasData()) { - + int bytesBeforeChild = packetData->getUncompressedSize(); // release the bytes we reserved... @@ -1772,7 +1772,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element, } else { packetData->discardLevel(rootDataLevelKey); } - + if (!allOfRootFit) { elementAppendState = OctreeElement::PARTIAL; params.stopReason = EncodeBitstreamParams::DIDNT_FIT; @@ -1804,7 +1804,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element, continueThisLevel = packetData->endLevel(thisLevelKey); } else { packetData->discardLevel(thisLevelKey); - + if (!mustIncludeAllChildData()) { qCDebug(octree) << "WARNING UNEXPECTED CASE: Something failed in attempting to pack this element"; qCDebug(octree) << "This is not expected!!!! -- continueThisLevel=FALSE...."; @@ -1831,7 +1831,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element, params.stopReason = EncodeBitstreamParams::DIDNT_FIT; bytesAtThisLevel = 0; // didn't fit } else { - + // assuming we made it here with continueThisLevel == true, we STILL might want // to add our element back to the bag for additional encoding, specifically if // the appendState is PARTIAL, in this case, we re-add our element to the bag @@ -1841,7 +1841,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element, bag.insert(element); } } - + // If our element is completed let the element know so it can do any cleanup it of extra wants if (elementAppendState == OctreeElement::COMPLETED) { element->elementEncodeComplete(params, &bag); @@ -1866,13 +1866,13 @@ bool Octree::readFromFile(const char* fileName) { emit importProgress(0); qCDebug(octree) << "Loading file" << qFileName << "..."; - + fileOk = readFromStream(fileLength, fileInputStream); emit importProgress(100); file.close(); } - + return fileOk; } @@ -1881,19 +1881,19 @@ bool Octree::readFromURL(const QString& urlString) { // determine if this is a local file or a network resource QUrl url(urlString); - + if (url.isLocalFile()) { readOk = readFromFile(qPrintable(url.toLocalFile())); } else { QNetworkRequest request; request.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT); request.setUrl(url); - + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkReply* reply = networkAccessManager.get(request); qCDebug(octree) << "Downloading svo at" << qPrintable(urlString); - + QEventLoop loop; QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec(); @@ -1933,7 +1933,7 @@ bool Octree::readSVOFromStream(unsigned long streamLength, QDataStream& inputStr PacketVersion gotVersion = 0; unsigned long headerLength = 0; // bytes in the header - + bool wantImportProgress = true; PacketType::Value expectedType = expectedDataPacketType(); @@ -1944,10 +1944,10 @@ bool Octree::readSVOFromStream(unsigned long streamLength, QDataStream& inputStr if (getWantSVOfileVersions()) { // read just enough of the file to parse the header... - const unsigned long HEADER_LENGTH = sizeof(PacketType) + sizeof(PacketVersion); + const unsigned long HEADER_LENGTH = sizeof(PacketType::Value) + sizeof(PacketVersion); unsigned char fileHeader[HEADER_LENGTH]; inputStream.readRawData((char*)&fileHeader, HEADER_LENGTH); - + headerLength = HEADER_LENGTH; // we need this later to skip to the data unsigned char* dataAt = (unsigned char*)&fileHeader; @@ -1960,22 +1960,22 @@ bool Octree::readSVOFromStream(unsigned long streamLength, QDataStream& inputStr dataAt += sizeof(expectedType); dataLength -= sizeof(expectedType); gotVersion = *dataAt; - + if (gotType == expectedType) { if (canProcessVersion(gotVersion)) { dataAt += sizeof(gotVersion); dataLength -= sizeof(gotVersion); fileOk = true; - qCDebug(octree, "SVO file version match. Expected: %d Got: %d", + qCDebug(octree, "SVO file version match. Expected: %d Got: %d", versionForPacketType(expectedDataPacketType()), gotVersion); hasBufferBreaks = versionHasSVOfileBreaks(gotVersion); } else { - qCDebug(octree, "SVO file version mismatch. Expected: %d Got: %d", + qCDebug(octree, "SVO file version mismatch. Expected: %d Got: %d", versionForPacketType(expectedDataPacketType()), gotVersion); } } else { - qCDebug(octree) << "SVO file type mismatch. Expected: " << nameForPacketType(expectedType) + qCDebug(octree) << "SVO file type mismatch. Expected: " << nameForPacketType(expectedType) << " Got: " << nameForPacketType(gotType); } @@ -1983,7 +1983,7 @@ bool Octree::readSVOFromStream(unsigned long streamLength, QDataStream& inputStr qCDebug(octree) << " NOTE: this file type does not include type and version information."; fileOk = true; // assume the file is ok } - + if (hasBufferBreaks) { qCDebug(octree) << " this version includes buffer breaks"; } else { @@ -1991,18 +1991,18 @@ bool Octree::readSVOFromStream(unsigned long streamLength, QDataStream& inputStr } if (fileOk) { - + // if this version of the file does not include buffer breaks, then we need to load the entire file at once if (!hasBufferBreaks) { - + // read the entire file into a buffer, WHAT!? Why not. unsigned long dataLength = streamLength - headerLength; unsigned char* entireFileDataSection = new unsigned char[dataLength]; inputStream.readRawData((char*)entireFileDataSection, dataLength); unsigned char* dataAt = entireFileDataSection; - - ReadBitstreamToTreeParams args(WANT_COLOR, NO_EXISTS_BITS, NULL, 0, + + ReadBitstreamToTreeParams args(WANT_COLOR, NO_EXISTS_BITS, NULL, 0, SharedNodePointer(), wantImportProgress, gotVersion); readBitstreamToTree(dataAt, dataLength, args); @@ -2010,38 +2010,38 @@ bool Octree::readSVOFromStream(unsigned long streamLength, QDataStream& inputStr } else { - + unsigned long dataLength = streamLength - headerLength; unsigned long remainingLength = dataLength; const unsigned long MAX_CHUNK_LENGTH = MAX_OCTREE_PACKET_SIZE * 2; unsigned char* fileChunk = new unsigned char[MAX_CHUNK_LENGTH]; - + while (remainingLength > 0) { quint16 chunkLength = 0; inputStream.readRawData((char*)&chunkLength, sizeof(chunkLength)); remainingLength -= sizeof(chunkLength); - + if (chunkLength > remainingLength) { - qCDebug(octree) << "UNEXPECTED chunk size of:" << chunkLength + qCDebug(octree) << "UNEXPECTED chunk size of:" << chunkLength << "greater than remaining length:" << remainingLength; break; } if (chunkLength > MAX_CHUNK_LENGTH) { - qCDebug(octree) << "UNEXPECTED chunk size of:" << chunkLength + qCDebug(octree) << "UNEXPECTED chunk size of:" << chunkLength << "greater than MAX_CHUNK_LENGTH:" << MAX_CHUNK_LENGTH; break; } - + inputStream.readRawData((char*)fileChunk, chunkLength); remainingLength -= chunkLength; - + unsigned char* dataAt = fileChunk; unsigned long dataLength = chunkLength; - - ReadBitstreamToTreeParams args(WANT_COLOR, NO_EXISTS_BITS, NULL, 0, + + ReadBitstreamToTreeParams args(WANT_COLOR, NO_EXISTS_BITS, NULL, 0, SharedNodePointer(), wantImportProgress, gotVersion); readBitstreamToTree(dataAt, dataLength, args); @@ -2051,7 +2051,7 @@ bool Octree::readSVOFromStream(unsigned long streamLength, QDataStream& inputStr } } - + return fileOk; } @@ -2136,7 +2136,7 @@ void Octree::writeToSVOFile(const char* fileName, OctreeElement* element) { } else { qCDebug(octree) << " this version does not include buffer breaks"; } - + OctreeElementBag elementBag; OctreeElementExtraEncodeData extraEncodeData; @@ -2153,7 +2153,7 @@ void Octree::writeToSVOFile(const char* fileName, OctreeElement* element) { while (!elementBag.isEmpty()) { OctreeElement* subTree = elementBag.extract(); - + lockForRead(); // do tree locking down here so that we have shorter slices and less thread contention EncodeBitstreamParams params(INT_MAX, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS); params.extraEncodeData = &extraEncodeData; @@ -2188,7 +2188,7 @@ void Octree::writeToSVOFile(const char* fileName, OctreeElement* element) { } file.write((const char*)packetData.getFinalizedData(), packetData.getFinalizedSize()); } - + releaseSceneEncodeData(&extraEncodeData); } file.close();