mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 20:32:21 +02:00
first cut at really using partial appendElementData to make models span packets. still needs work
This commit is contained in:
parent
66b0333dc9
commit
6389fea320
5 changed files with 88 additions and 10 deletions
|
@ -188,6 +188,10 @@ public:
|
||||||
bool isKnownID;
|
bool isKnownID;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool operator<(const ModelItemID& a, const ModelItemID& b) {
|
||||||
|
return (a.id == b.id) ? (a.creatorTokenID < b.creatorTokenID) : (a.id < b.id);
|
||||||
|
}
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(ModelItemID);
|
Q_DECLARE_METATYPE(ModelItemID);
|
||||||
Q_DECLARE_METATYPE(QVector<ModelItemID>);
|
Q_DECLARE_METATYPE(QVector<ModelItemID>);
|
||||||
QScriptValue ModelItemIDtoScriptValue(QScriptEngine* engine, const ModelItemID& properties);
|
QScriptValue ModelItemIDtoScriptValue(QScriptEngine* engine, const ModelItemID& properties);
|
||||||
|
|
|
@ -58,6 +58,13 @@ OctreeElement::AppendState ModelTreeElement::appendElementData(OctreePacketData*
|
||||||
EncodeBitstreamParams& params) const {
|
EncodeBitstreamParams& params) const {
|
||||||
|
|
||||||
OctreeElement::AppendState appendElementState = OctreeElement::COMPLETED; // assume the best...
|
OctreeElement::AppendState appendElementState = OctreeElement::COMPLETED; // assume the best...
|
||||||
|
|
||||||
|
// first, check the params.extraEncodeData to see if there's any partial re-encode data for this element
|
||||||
|
OctreeElementExtraEncodeData* extraEncodeData = params.extraEncodeData;
|
||||||
|
ModelTreeElementExtraEncodeData* elementExtraEncodeData = NULL;
|
||||||
|
if (extraEncodeData && extraEncodeData->contains(this)) {
|
||||||
|
elementExtraEncodeData = static_cast<ModelTreeElementExtraEncodeData*>(extraEncodeData->value(this));
|
||||||
|
}
|
||||||
|
|
||||||
LevelDetails elementLevel = packetData->startLevel();
|
LevelDetails elementLevel = packetData->startLevel();
|
||||||
|
|
||||||
|
@ -67,15 +74,25 @@ OctreeElement::AppendState ModelTreeElement::appendElementData(OctreePacketData*
|
||||||
QVector<uint16_t> indexesOfModelsToInclude;
|
QVector<uint16_t> indexesOfModelsToInclude;
|
||||||
|
|
||||||
for (uint16_t i = 0; i < _modelItems->size(); i++) {
|
for (uint16_t i = 0; i < _modelItems->size(); i++) {
|
||||||
if (params.viewFrustum) {
|
const ModelItem& model = (*_modelItems)[i];
|
||||||
const ModelItem& model = (*_modelItems)[i];
|
bool includeThisModel = true;
|
||||||
|
|
||||||
|
if (elementExtraEncodeData) {
|
||||||
|
includeThisModel = elementExtraEncodeData->includedItems.contains(model.getModelItemID());
|
||||||
|
if (includeThisModel) {
|
||||||
|
elementExtraEncodeData->includedItems.remove(model.getModelItemID()); // remove it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (includeThisModel && params.viewFrustum) {
|
||||||
AACube modelCube = model.getAACube();
|
AACube modelCube = model.getAACube();
|
||||||
modelCube.scale(TREE_SCALE);
|
modelCube.scale(TREE_SCALE);
|
||||||
if (params.viewFrustum->cubeInFrustum(modelCube) != ViewFrustum::OUTSIDE) {
|
if (params.viewFrustum->cubeInFrustum(modelCube) == ViewFrustum::OUTSIDE) {
|
||||||
indexesOfModelsToInclude << i;
|
includeThisModel = false; // out of view, don't include it
|
||||||
numberOfModels++;
|
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if (includeThisModel) {
|
||||||
indexesOfModelsToInclude << i;
|
indexesOfModelsToInclude << i;
|
||||||
numberOfModels++;
|
numberOfModels++;
|
||||||
}
|
}
|
||||||
|
@ -106,10 +123,32 @@ OctreeElement::AppendState ModelTreeElement::appendElementData(OctreePacketData*
|
||||||
// If any part of the model items didn't fit, then the element is considered partial
|
// If any part of the model items didn't fit, then the element is considered partial
|
||||||
if (appendModelState != OctreeElement::COMPLETED) {
|
if (appendModelState != OctreeElement::COMPLETED) {
|
||||||
appendElementState = OctreeElement::PARTIAL;
|
appendElementState = OctreeElement::PARTIAL;
|
||||||
|
|
||||||
|
// add this item into our list for the next appendElementData() pass
|
||||||
|
if (extraEncodeData) {
|
||||||
|
if (!elementExtraEncodeData) {
|
||||||
|
elementExtraEncodeData = new ModelTreeElementExtraEncodeData();
|
||||||
|
}
|
||||||
|
elementExtraEncodeData->includedItems.insert(model.getModelItemID(), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we were provided with extraEncodeData, and we allocated and/or got elementExtraEncodeData
|
||||||
|
// then we need to do some additional processing
|
||||||
|
if (extraEncodeData && elementExtraEncodeData) {
|
||||||
|
|
||||||
|
// If after processing we have some includedItems left in it, then make sure we re-add it back to our map
|
||||||
|
if (elementExtraEncodeData->includedItems.size()) {
|
||||||
|
extraEncodeData->insert(this, elementExtraEncodeData);
|
||||||
|
} else {
|
||||||
|
// otherwise, clean things up...
|
||||||
|
extraEncodeData->remove(this);
|
||||||
|
delete elementExtraEncodeData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If we wrote fewer models than we expected, update the number of models in our packet
|
// If we wrote fewer models than we expected, update the number of models in our packet
|
||||||
bool successUpdateModelCount = true;
|
bool successUpdateModelCount = true;
|
||||||
if (numberOfModels != actualNumberOfModels) {
|
if (numberOfModels != actualNumberOfModels) {
|
||||||
|
|
|
@ -45,6 +45,11 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ModelTreeElementExtraEncodeData {
|
||||||
|
public:
|
||||||
|
QMap<ModelItemID, bool> includedItems; // for now, bool, soon ModelPropertyFlags
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class ModelTreeElement : public OctreeElement {
|
class ModelTreeElement : public OctreeElement {
|
||||||
friend class ModelTree; // to allow createElement to new us...
|
friend class ModelTree; // to allow createElement to new us...
|
||||||
|
|
|
@ -988,6 +988,10 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element,
|
||||||
OctreePacketData* packetData, OctreeElementBag& bag,
|
OctreePacketData* packetData, OctreeElementBag& bag,
|
||||||
EncodeBitstreamParams& params, int& currentEncodeLevel,
|
EncodeBitstreamParams& params, int& currentEncodeLevel,
|
||||||
const ViewFrustum::location& parentLocationThisView) const {
|
const ViewFrustum::location& parentLocationThisView) const {
|
||||||
|
|
||||||
|
// The append state of this level/element.
|
||||||
|
OctreeElement::AppendState elementAppendState = OctreeElement::COMPLETED; // assume the best
|
||||||
|
|
||||||
// How many bytes have we written so far at this level;
|
// How many bytes have we written so far at this level;
|
||||||
int bytesAtThisLevel = 0;
|
int bytesAtThisLevel = 0;
|
||||||
|
|
||||||
|
@ -1350,8 +1354,23 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element,
|
||||||
// to allow the appendElementData() to respond that it produced partial data, which should be
|
// 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
|
// written, but that the childElement needs to be reprocessed in an additional pass or passes
|
||||||
// to be completed. In the case that an element was partially written, we need to
|
// to be completed. In the case that an element was partially written, we need to
|
||||||
OctreeElement::AppendState appendState = childElement->appendElementData(packetData, params);
|
|
||||||
continueThisLevel = (appendState == OctreeElement::COMPLETED);
|
|
||||||
|
OctreeElement::AppendState childAppendState = childElement->appendElementData(packetData, params);
|
||||||
|
|
||||||
|
// Continue this level so long as some part of this child element was appended.
|
||||||
|
// TODO: consider if we want to also keep going in the child append state was NONE... to do this
|
||||||
|
// we'd need to make sure the appendElementData didn't accidentally add bad partial data, we'd
|
||||||
|
// also want to remove the child exists bit flag from the packet. I tried this quickly with voxels
|
||||||
|
// and got some bad data including bad colors and some errors in recursing the tree, so clearly there's
|
||||||
|
// more to it than that. This current implementation is slightly less efficient, because it could
|
||||||
|
// be that one child element didn't fit but theoretically others could.
|
||||||
|
continueThisLevel = (childAppendState != OctreeElement::NONE);
|
||||||
|
|
||||||
|
// If this child was partially appended, then consider this element to be partially appended
|
||||||
|
if (childAppendState == OctreeElement::PARTIAL) {
|
||||||
|
elementAppendState = OctreeElement::PARTIAL;
|
||||||
|
}
|
||||||
|
|
||||||
int bytesAfterChild = packetData->getUncompressedSize();
|
int bytesAfterChild = packetData->getUncompressedSize();
|
||||||
|
|
||||||
|
@ -1362,7 +1381,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element,
|
||||||
bytesAtThisLevel += (bytesAfterChild - bytesBeforeChild); // keep track of byte count for this child
|
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
|
// don't need to check childElement here, because we can't get here with no childElement
|
||||||
if (params.stats) {
|
if (params.stats && (childAppendState != OctreeElement::NONE)) {
|
||||||
params.stats->colorSent(childElement);
|
params.stats->colorSent(childElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1571,6 +1590,17 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element,
|
||||||
|
|
||||||
params.stopReason = EncodeBitstreamParams::DIDNT_FIT;
|
params.stopReason = EncodeBitstreamParams::DIDNT_FIT;
|
||||||
bytesAtThisLevel = 0; // didn't 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
|
||||||
|
// and assume that the appendElementData() has stored any required state data
|
||||||
|
// in the params extraEncodeData
|
||||||
|
if (elementAppendState == OctreeElement::PARTIAL) {
|
||||||
|
qDebug() << "elementAppendState == OctreeElement::PARTIAL... bag.insert(element).....";
|
||||||
|
bag.insert(element);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytesAtThisLevel;
|
return bytesAtThisLevel;
|
||||||
|
|
|
@ -41,6 +41,6 @@ private:
|
||||||
bool _hooked;
|
bool _hooked;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef QMap<OctreeElement*,void*> OctreeElementExtraEncodeData;
|
typedef QMap<const OctreeElement*,void*> OctreeElementExtraEncodeData;
|
||||||
|
|
||||||
#endif // hifi_OctreeElementBag_h
|
#endif // hifi_OctreeElementBag_h
|
||||||
|
|
Loading…
Reference in a new issue