diff --git a/libraries/models/src/ModelItem.cpp b/libraries/models/src/ModelItem.cpp index de49bf1712..ca93803899 100644 --- a/libraries/models/src/ModelItem.cpp +++ b/libraries/models/src/ModelItem.cpp @@ -132,7 +132,7 @@ void ModelItem::init(glm::vec3 position, float radius, rgbColor color, uint32_t _lastAnimated = now; } -bool ModelItem::appendModelData(OctreePacketData* packetData) const { +OctreeElement::AppendState ModelItem::appendModelData(OctreePacketData* packetData, EncodeBitstreamParams& params) const { bool success = packetData->appendValue(getID()); @@ -193,12 +193,10 @@ bool ModelItem::appendModelData(OctreePacketData* packetData) const { success = packetData->appendValue(getAnimationFPS()); } - return success; + return success ? OctreeElement::COMPLETED : OctreeElement::NONE; } -bool ModelItem::new___appendModelData(OctreePacketData* packetData, EncodeBitstreamParams& params) const { - - // bool headerFits = ... +OctreeElement::AppendState ModelItem::new___appendModelData(OctreePacketData* packetData, EncodeBitstreamParams& params) const { // ALL this fits... // object ID [16 bytes] @@ -208,7 +206,7 @@ bool ModelItem::new___appendModelData(OctreePacketData* packetData, EncodeBitstr // PropertyFlags<>( everything ) [1-2 bytes] // ~27-35 bytes... - bool success = false; + OctreeElement::AppendState appendState = OctreeElement::COMPLETED; // assume the best quint64 updateDelta = getLastUpdated() <= getLastEdited() ? 0 : getLastUpdated() - getLastEdited(); ByteCountCoded updateDeltaCoder = updateDelta; @@ -252,6 +250,7 @@ bool ModelItem::new___appendModelData(OctreePacketData* packetData, EncodeBitstr packetData->endLevel(propertyLevel); } else { packetData->discardLevel(propertyLevel); + appendState = OctreeElement::PARTIAL; } // PROP_RADIUS @@ -263,6 +262,7 @@ bool ModelItem::new___appendModelData(OctreePacketData* packetData, EncodeBitstr packetData->endLevel(propertyLevel); } else { packetData->discardLevel(propertyLevel); + appendState = OctreeElement::PARTIAL; } // PROP_MODEL_URL @@ -274,6 +274,7 @@ bool ModelItem::new___appendModelData(OctreePacketData* packetData, EncodeBitstr packetData->endLevel(propertyLevel); } else { packetData->discardLevel(propertyLevel); + appendState = OctreeElement::PARTIAL; } // PROP_ROTATION @@ -285,6 +286,7 @@ bool ModelItem::new___appendModelData(OctreePacketData* packetData, EncodeBitstr packetData->endLevel(propertyLevel); } else { packetData->discardLevel(propertyLevel); + appendState = OctreeElement::PARTIAL; } // PROP_COLOR @@ -296,6 +298,7 @@ bool ModelItem::new___appendModelData(OctreePacketData* packetData, EncodeBitstr packetData->endLevel(propertyLevel); } else { packetData->discardLevel(propertyLevel); + appendState = OctreeElement::PARTIAL; } // PROP_SCRIPT @@ -310,6 +313,7 @@ bool ModelItem::new___appendModelData(OctreePacketData* packetData, EncodeBitstr packetData->endLevel(propertyLevel); } else { packetData->discardLevel(propertyLevel); + appendState = OctreeElement::PARTIAL; } // PROP_ANIMATION_FPS @@ -321,6 +325,7 @@ bool ModelItem::new___appendModelData(OctreePacketData* packetData, EncodeBitstr packetData->endLevel(propertyLevel); } else { packetData->discardLevel(propertyLevel); + appendState = OctreeElement::PARTIAL; } // PROP_ANIMATION_FRAME_INDEX @@ -332,6 +337,7 @@ bool ModelItem::new___appendModelData(OctreePacketData* packetData, EncodeBitstr packetData->endLevel(propertyLevel); } else { packetData->discardLevel(propertyLevel); + appendState = OctreeElement::PARTIAL; } // PROP_ANIMATION_PLAYING @@ -343,6 +349,7 @@ bool ModelItem::new___appendModelData(OctreePacketData* packetData, EncodeBitstr packetData->endLevel(propertyLevel); } else { packetData->discardLevel(propertyLevel); + appendState = OctreeElement::PARTIAL; } // PROP_SHOULD_BE_DELETED @@ -354,6 +361,7 @@ bool ModelItem::new___appendModelData(OctreePacketData* packetData, EncodeBitstr packetData->endLevel(propertyLevel); } else { packetData->discardLevel(propertyLevel); + appendState = OctreeElement::PARTIAL; } } if (propertyCount > 0) { @@ -381,12 +389,12 @@ bool ModelItem::new___appendModelData(OctreePacketData* packetData, EncodeBitstr } packetData->endLevel(modelLevel); - success = true; } else { packetData->discardLevel(modelLevel); + appendState = OctreeElement::NONE; // if we got here, then we didn't include the item } - return success; + return appendState; } int ModelItem::expectedBytes() { diff --git a/libraries/models/src/ModelItem.h b/libraries/models/src/ModelItem.h index a9d5c70475..662c89c558 100644 --- a/libraries/models/src/ModelItem.h +++ b/libraries/models/src/ModelItem.h @@ -282,10 +282,10 @@ public: void setProperties(const ModelItemProperties& properties); - bool new___appendModelData(OctreePacketData* packetData, EncodeBitstreamParams& params) const; + OctreeElement::AppendState new___appendModelData(OctreePacketData* packetData, EncodeBitstreamParams& params) const; int new___readModelDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args); - bool appendModelData(OctreePacketData* packetData) const; + OctreeElement::AppendState appendModelData(OctreePacketData* packetData, EncodeBitstreamParams& params) const; int readModelDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args); static int expectedBytes(); diff --git a/libraries/models/src/ModelTreeElement.cpp b/libraries/models/src/ModelTreeElement.cpp index a7cfce59e5..a5c1c373ab 100644 --- a/libraries/models/src/ModelTreeElement.cpp +++ b/libraries/models/src/ModelTreeElement.cpp @@ -56,7 +56,10 @@ ModelTreeElement* ModelTreeElement::addChildAtIndex(int index) { // contents across multiple packets. OctreeElement::AppendState ModelTreeElement::appendElementData(OctreePacketData* packetData, EncodeBitstreamParams& params) const { - bool success = true; // assume the best... + + OctreeElement::AppendState appendElementState = OctreeElement::COMPLETED; // assume the best... + + LevelDetails elementLevel = packetData->startLevel(); // write our models out... first determine which of the models are in view based on our params uint16_t numberOfModels = 0; @@ -79,33 +82,49 @@ OctreeElement::AppendState ModelTreeElement::appendElementData(OctreePacketData* } int numberOfModelsOffset = packetData->getUncompressedByteOffset(); - success = packetData->appendValue(numberOfModels); + bool successAppendModelCount = packetData->appendValue(numberOfModels); - if (success) { + if (successAppendModelCount) { foreach (uint16_t i, indexesOfModelsToInclude) { const ModelItem& model = (*_modelItems)[i]; LevelDetails modelLevel = packetData->startLevel(); - success = model.appendModelData(packetData); + OctreeElement::AppendState appendModelState = model.appendModelData(packetData, params); - if (success) { + // If none of this model data was able to be appended, then discard it + // and don't include it in our model count + if (appendModelState == OctreeElement::NONE) { + packetData->discardLevel(modelLevel); + } else { + // If either ALL or some of it got appended, then end the level (commit it) + // and include the model in our final count of models packetData->endLevel(modelLevel); actualNumberOfModels++; } - if (!success) { - packetData->discardLevel(modelLevel); - break; + + // If any part of the model items didn't fit, then the element is considered partial + if (appendModelState != OctreeElement::COMPLETED) { + appendElementState = OctreeElement::PARTIAL; } } } - if (!success) { - success = packetData->updatePriorBytes(numberOfModelsOffset, + // If we wrote fewer models than we expected, update the number of models in our packet + bool successUpdateModelCount = true; + if (numberOfModels != actualNumberOfModels) { + successUpdateModelCount = packetData->updatePriorBytes(numberOfModelsOffset, (const unsigned char*)&actualNumberOfModels, sizeof(actualNumberOfModels)); } + + if (!successUpdateModelCount) { + packetData->discardLevel(elementLevel); + appendElementState = OctreeElement::NONE; + } else { + packetData->endLevel(elementLevel); + } - return success ? OctreeElement::COMPLETED : OctreeElement::NONE; + return appendElementState; } bool ModelTreeElement::containsModelBounds(const ModelItem& model) const {