get model props spanning multiple packets

This commit is contained in:
ZappoMan 2014-06-12 13:03:37 -07:00
parent 1cb5521f01
commit 2e5e6e3f61
6 changed files with 268 additions and 121 deletions

View file

@ -132,7 +132,7 @@ void ModelItem::init(glm::vec3 position, float radius, rgbColor color, uint32_t
_lastAnimated = now; _lastAnimated = now;
} }
OctreeElement::AppendState ModelItem::appendModelData(OctreePacketData* packetData, EncodeBitstreamParams& params) const { OctreeElement::AppendState ModelItem::oldVersionAppendModelData(OctreePacketData* packetData, EncodeBitstreamParams& params) const {
bool success = packetData->appendValue(getID()); bool success = packetData->appendValue(getID());
@ -196,7 +196,8 @@ OctreeElement::AppendState ModelItem::appendModelData(OctreePacketData* packetDa
return success ? OctreeElement::COMPLETED : OctreeElement::NONE; return success ? OctreeElement::COMPLETED : OctreeElement::NONE;
} }
OctreeElement::AppendState ModelItem::new___appendModelData(OctreePacketData* packetData, EncodeBitstreamParams& params) const { OctreeElement::AppendState ModelItem::appendModelData(OctreePacketData* packetData, EncodeBitstreamParams& params,
ModelTreeElementExtraEncodeData* modelTreeElementExtraEncodeData) const {
// ALL this fits... // ALL this fits...
// object ID [16 bytes] // object ID [16 bytes]
@ -212,6 +213,29 @@ OctreeElement::AppendState ModelItem::new___appendModelData(OctreePacketData* pa
ByteCountCoded<quint64> updateDeltaCoder = updateDelta; ByteCountCoded<quint64> updateDeltaCoder = updateDelta;
QByteArray encodedUpdateDelta = updateDeltaCoder; QByteArray encodedUpdateDelta = updateDeltaCoder;
ModelPropertyFlags propertyFlags(PROP_LAST_ITEM); ModelPropertyFlags propertyFlags(PROP_LAST_ITEM);
ModelPropertyFlags requestedProperties;
requestedProperties += PROP_POSITION;
requestedProperties += PROP_RADIUS;
requestedProperties += PROP_MODEL_URL;
requestedProperties += PROP_ROTATION;
requestedProperties += PROP_COLOR;
requestedProperties += PROP_ANIMATION_URL;
requestedProperties += PROP_ANIMATION_FPS;
requestedProperties += PROP_ANIMATION_FRAME_INDEX;
requestedProperties += PROP_ANIMATION_PLAYING;
requestedProperties += PROP_SHOULD_BE_DELETED;
ModelPropertyFlags propertiesDidntFit = requestedProperties;
// If we are being called for a subsequent pass at appendModelData() that failed to completely encode this item,
// then our modelTreeElementExtraEncodeData should include data about which properties we need to append.
if (modelTreeElementExtraEncodeData && modelTreeElementExtraEncodeData->includedItems.contains(getModelItemID())) {
requestedProperties = modelTreeElementExtraEncodeData->includedItems.value(getModelItemID());
}
//qDebug() << "requestedProperties=";
//requestedProperties.debugDumpBits();
LevelDetails modelLevel = packetData->startLevel(); LevelDetails modelLevel = packetData->startLevel();
@ -242,126 +266,206 @@ OctreeElement::AppendState ModelItem::new___appendModelData(OctreePacketData* pa
// PROP_VISIBLE, // PROP_VISIBLE,
// PROP_POSITION // PROP_POSITION
LevelDetails propertyLevel = packetData->startLevel(); if (requestedProperties.getHasProperty(PROP_POSITION)) {
successPropertyFits = packetData->appendPosition(getPosition()); //qDebug() << "PROP_POSITION requested...";
if (successPropertyFits) { LevelDetails propertyLevel = packetData->startLevel();
propertyFlags |= PROP_POSITION; successPropertyFits = packetData->appendPosition(getPosition());
propertyCount++; if (successPropertyFits) {
packetData->endLevel(propertyLevel); propertyFlags |= PROP_POSITION;
propertiesDidntFit -= PROP_POSITION;
propertyCount++;
packetData->endLevel(propertyLevel);
} else {
//qDebug() << "PROP_POSITION didn't fit...";
packetData->discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else { } else {
packetData->discardLevel(propertyLevel); //qDebug() << "PROP_POSITION NOT requested...";
appendState = OctreeElement::PARTIAL; propertiesDidntFit -= PROP_POSITION;
} }
// PROP_RADIUS // PROP_RADIUS
propertyLevel = packetData->startLevel(); if (requestedProperties.getHasProperty(PROP_RADIUS)) {
successPropertyFits = packetData->appendValue(getRadius()); //qDebug() << "PROP_RADIUS requested...";
if (successPropertyFits) { LevelDetails propertyLevel = packetData->startLevel();
propertyFlags |= PROP_RADIUS; successPropertyFits = packetData->appendValue(getRadius());
propertyCount++; if (successPropertyFits) {
packetData->endLevel(propertyLevel); propertyFlags |= PROP_RADIUS;
propertiesDidntFit -= PROP_RADIUS;
propertyCount++;
packetData->endLevel(propertyLevel);
} else {
//qDebug() << "PROP_RADIUS didn't fit...";
packetData->discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else { } else {
packetData->discardLevel(propertyLevel); //qDebug() << "PROP_RADIUS NOT requested...";
appendState = OctreeElement::PARTIAL; propertiesDidntFit -= PROP_RADIUS;
} }
// PROP_MODEL_URL // PROP_MODEL_URL
propertyLevel = packetData->startLevel(); if (requestedProperties.getHasProperty(PROP_MODEL_URL)) {
successPropertyFits = packetData->appendValue(getModelURL()); //qDebug() << "PROP_MODEL_URL requested...";
if (successPropertyFits) { LevelDetails propertyLevel = packetData->startLevel();
propertyFlags |= PROP_MODEL_URL; successPropertyFits = packetData->appendValue(getModelURL());
propertyCount++; if (successPropertyFits) {
packetData->endLevel(propertyLevel); propertyFlags |= PROP_MODEL_URL;
propertiesDidntFit -= PROP_MODEL_URL;
propertyCount++;
packetData->endLevel(propertyLevel);
} else {
//qDebug() << "PROP_MODEL_URL didn't fit...";
packetData->discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else { } else {
packetData->discardLevel(propertyLevel); //qDebug() << "PROP_MODEL_URL NOT requested...";
appendState = OctreeElement::PARTIAL; propertiesDidntFit -= PROP_MODEL_URL;
} }
// PROP_ROTATION // PROP_ROTATION
propertyLevel = packetData->startLevel(); if (requestedProperties.getHasProperty(PROP_ROTATION)) {
successPropertyFits = packetData->appendValue(getModelRotation()); //qDebug() << "PROP_ROTATION requested...";
if (successPropertyFits) { LevelDetails propertyLevel = packetData->startLevel();
propertyFlags |= PROP_ROTATION; successPropertyFits = packetData->appendValue(getModelRotation());
propertyCount++; if (successPropertyFits) {
packetData->endLevel(propertyLevel); propertyFlags |= PROP_ROTATION;
propertiesDidntFit -= PROP_ROTATION;
propertyCount++;
packetData->endLevel(propertyLevel);
} else {
//qDebug() << "PROP_ROTATION didn't fit...";
packetData->discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else { } else {
packetData->discardLevel(propertyLevel); //qDebug() << "PROP_ROTATION NOT requested...";
appendState = OctreeElement::PARTIAL; propertiesDidntFit -= PROP_ROTATION;
} }
// PROP_COLOR // PROP_COLOR
propertyLevel = packetData->startLevel(); if (requestedProperties.getHasProperty(PROP_COLOR)) {
successPropertyFits = packetData->appendColor(getColor()); //qDebug() << "PROP_COLOR requested...";
if (successPropertyFits) { LevelDetails propertyLevel = packetData->startLevel();
propertyFlags |= PROP_COLOR; successPropertyFits = packetData->appendColor(getColor());
propertyCount++; if (successPropertyFits) {
packetData->endLevel(propertyLevel); propertyFlags |= PROP_COLOR;
propertiesDidntFit -= PROP_COLOR;
propertyCount++;
packetData->endLevel(propertyLevel);
} else {
//qDebug() << "PROP_COLOR didn't fit...";
packetData->discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else { } else {
packetData->discardLevel(propertyLevel); //qDebug() << "PROP_COLOR NOT requested...";
appendState = OctreeElement::PARTIAL; propertiesDidntFit -= PROP_COLOR;
} }
// PROP_SCRIPT // PROP_SCRIPT
// script would go here... // script would go here...
// PROP_ANIMATION_URL // PROP_ANIMATION_URL
propertyLevel = packetData->startLevel(); if (requestedProperties.getHasProperty(PROP_ANIMATION_URL)) {
successPropertyFits = packetData->appendValue(getAnimationURL()); //qDebug() << "PROP_ANIMATION_URL requested...";
if (successPropertyFits) { LevelDetails propertyLevel = packetData->startLevel();
propertyFlags |= PROP_ANIMATION_URL; successPropertyFits = packetData->appendValue(getAnimationURL());
propertyCount++; if (successPropertyFits) {
packetData->endLevel(propertyLevel); propertyFlags |= PROP_ANIMATION_URL;
propertiesDidntFit -= PROP_ANIMATION_URL;
propertyCount++;
packetData->endLevel(propertyLevel);
} else {
//qDebug() << "PROP_ANIMATION_URL didn't fit...";
packetData->discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else { } else {
packetData->discardLevel(propertyLevel); //qDebug() << "PROP_ANIMATION_URL NOT requested...";
appendState = OctreeElement::PARTIAL; propertiesDidntFit -= PROP_ANIMATION_URL;
} }
// PROP_ANIMATION_FPS // PROP_ANIMATION_FPS
propertyLevel = packetData->startLevel(); if (requestedProperties.getHasProperty(PROP_ANIMATION_FPS)) {
successPropertyFits = packetData->appendValue(getAnimationFPS()); //qDebug() << "PROP_ANIMATION_FPS requested...";
if (successPropertyFits) { LevelDetails propertyLevel = packetData->startLevel();
propertyFlags |= PROP_ANIMATION_FPS; successPropertyFits = packetData->appendValue(getAnimationFPS());
propertyCount++; if (successPropertyFits) {
packetData->endLevel(propertyLevel); propertyFlags |= PROP_ANIMATION_FPS;
propertiesDidntFit -= PROP_ANIMATION_FPS;
propertyCount++;
packetData->endLevel(propertyLevel);
} else {
//qDebug() << "PROP_ANIMATION_FPS didn't fit...";
packetData->discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else { } else {
packetData->discardLevel(propertyLevel); //qDebug() << "PROP_ANIMATION_FPS NOT requested...";
appendState = OctreeElement::PARTIAL; propertiesDidntFit -= PROP_ANIMATION_FPS;
} }
// PROP_ANIMATION_FRAME_INDEX // PROP_ANIMATION_FRAME_INDEX
propertyLevel = packetData->startLevel(); if (requestedProperties.getHasProperty(PROP_ANIMATION_FRAME_INDEX)) {
successPropertyFits = packetData->appendValue(getAnimationFrameIndex()); //qDebug() << "PROP_ANIMATION_FRAME_INDEX requested...";
if (successPropertyFits) { LevelDetails propertyLevel = packetData->startLevel();
propertyFlags |= PROP_ANIMATION_FRAME_INDEX; successPropertyFits = packetData->appendValue(getAnimationFrameIndex());
propertyCount++; if (successPropertyFits) {
packetData->endLevel(propertyLevel); propertyFlags |= PROP_ANIMATION_FRAME_INDEX;
propertiesDidntFit -= PROP_ANIMATION_FRAME_INDEX;
propertyCount++;
packetData->endLevel(propertyLevel);
} else {
//qDebug() << "PROP_ANIMATION_FRAME_INDEX didn't fit...";
packetData->discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else { } else {
packetData->discardLevel(propertyLevel); //qDebug() << "PROP_ANIMATION_FRAME_INDEX NOT requested...";
appendState = OctreeElement::PARTIAL; propertiesDidntFit -= PROP_ANIMATION_FRAME_INDEX;
} }
// PROP_ANIMATION_PLAYING // PROP_ANIMATION_PLAYING
propertyLevel = packetData->startLevel(); if (requestedProperties.getHasProperty(PROP_ANIMATION_PLAYING)) {
successPropertyFits = packetData->appendValue(getAnimationIsPlaying()); //qDebug() << "PROP_ANIMATION_PLAYING requested...";
if (successPropertyFits) { LevelDetails propertyLevel = packetData->startLevel();
propertyFlags |= PROP_ANIMATION_PLAYING; successPropertyFits = packetData->appendValue(getAnimationIsPlaying());
propertyCount++; if (successPropertyFits) {
packetData->endLevel(propertyLevel); propertyFlags |= PROP_ANIMATION_PLAYING;
propertiesDidntFit -= PROP_ANIMATION_PLAYING;
propertyCount++;
packetData->endLevel(propertyLevel);
} else {
//qDebug() << "PROP_ANIMATION_PLAYING didn't fit...";
packetData->discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else { } else {
packetData->discardLevel(propertyLevel); //qDebug() << "PROP_ANIMATION_PLAYING NOT requested...";
appendState = OctreeElement::PARTIAL; propertiesDidntFit -= PROP_ANIMATION_PLAYING;
} }
// PROP_SHOULD_BE_DELETED // PROP_SHOULD_BE_DELETED
propertyLevel = packetData->startLevel(); if (requestedProperties.getHasProperty(PROP_SHOULD_BE_DELETED)) {
successPropertyFits = packetData->appendValue(getShouldDie()); //qDebug() << "PROP_SHOULD_BE_DELETED requested...";
if (successPropertyFits) { LevelDetails propertyLevel = packetData->startLevel();
propertyFlags |= PROP_SHOULD_BE_DELETED; successPropertyFits = packetData->appendValue(getShouldDie());
propertyCount++; if (successPropertyFits) {
packetData->endLevel(propertyLevel); propertyFlags |= PROP_SHOULD_BE_DELETED;
propertiesDidntFit -= PROP_SHOULD_BE_DELETED;
propertyCount++;
packetData->endLevel(propertyLevel);
} else {
//qDebug() << "PROP_SHOULD_BE_DELETED didn't fit...";
packetData->discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else { } else {
packetData->discardLevel(propertyLevel); //qDebug() << "PROP_SHOULD_BE_DELETED NOT requested...";
appendState = OctreeElement::PARTIAL; propertiesDidntFit -= PROP_SHOULD_BE_DELETED;
} }
} }
if (propertyCount > 0) { if (propertyCount > 0) {
@ -393,6 +497,18 @@ OctreeElement::AppendState ModelItem::new___appendModelData(OctreePacketData* pa
packetData->discardLevel(modelLevel); packetData->discardLevel(modelLevel);
appendState = OctreeElement::NONE; // if we got here, then we didn't include the item appendState = OctreeElement::NONE; // if we got here, then we didn't include the item
} }
//qDebug() << "propertyFlags=";
//propertyFlags.debugDumpBits();
//qDebug() << "propertiesDidntFit=";
//propertiesDidntFit.debugDumpBits();
// If any part of the model items didn't fit, then the element is considered partial
if (appendState != OctreeElement::COMPLETED) {
// add this item into our list for the next appendElementData() pass
modelTreeElementExtraEncodeData->includedItems.insert(getModelItemID(), propertiesDidntFit);
}
return appendState; return appendState;
} }
@ -409,7 +525,7 @@ int ModelItem::expectedBytes() {
return expectedBytes; return expectedBytes;
} }
int ModelItem::readModelDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args) { int ModelItem::oldVersionReadModelDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args) {
int bytesRead = 0; int bytesRead = 0;
if (bytesLeftToRead >= expectedBytes()) { if (bytesLeftToRead >= expectedBytes()) {
@ -499,7 +615,7 @@ int ModelItem::readModelDataFromBuffer(const unsigned char* data, int bytesLeftT
return bytesRead; return bytesRead;
} }
int ModelItem::new___readModelDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args) { int ModelItem::readModelDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args) {
// TODO: handle old format?? // TODO: handle old format??
//if (args.bitstreamVersion >= VERSION_MODELS_HAVE_ANIMATION) { //if (args.bitstreamVersion >= VERSION_MODELS_HAVE_ANIMATION) {

View file

@ -29,6 +29,7 @@ class ModelEditPacketSender;
class ModelItemProperties; class ModelItemProperties;
class ModelsScriptingInterface; class ModelsScriptingInterface;
class ModelTree; class ModelTree;
class ModelTreeElementExtraEncodeData;
class ScriptEngine; class ScriptEngine;
class VoxelEditPacketSender; class VoxelEditPacketSender;
class VoxelsScriptingInterface; class VoxelsScriptingInterface;
@ -286,11 +287,12 @@ public:
void setProperties(const ModelItemProperties& properties); void setProperties(const ModelItemProperties& properties);
OctreeElement::AppendState new___appendModelData(OctreePacketData* packetData, EncodeBitstreamParams& params) const; OctreeElement::AppendState appendModelData(OctreePacketData* packetData, EncodeBitstreamParams& params,
int new___readModelDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args); ModelTreeElementExtraEncodeData* modelTreeElementExtraEncodeData) const;
OctreeElement::AppendState appendModelData(OctreePacketData* packetData, EncodeBitstreamParams& params) const;
int readModelDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args); int readModelDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args);
OctreeElement::AppendState oldVersionAppendModelData(OctreePacketData* packetData, EncodeBitstreamParams& params) const;
int oldVersionReadModelDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args);
static int expectedBytes(); static int expectedBytes();
static bool encodeModelEditMessageDetails(PacketType command, ModelItemID id, const ModelItemProperties& details, static bool encodeModelEditMessageDetails(PacketType command, ModelItemID id, const ModelItemProperties& details,

View file

@ -74,7 +74,8 @@ public:
bool hasAnyDeletedModels() const { return _recentlyDeletedModelItemIDs.size() > 0; } bool hasAnyDeletedModels() const { return _recentlyDeletedModelItemIDs.size() > 0; }
bool hasModelsDeletedSince(quint64 sinceTime); bool hasModelsDeletedSince(quint64 sinceTime);
bool encodeModelsDeletedSince(OCTREE_PACKET_SEQUENCE sequenceNumber, quint64& sinceTime, unsigned char* packetData, size_t maxLength, size_t& outputLength); bool encodeModelsDeletedSince(OCTREE_PACKET_SEQUENCE sequenceNumber, quint64& sinceTime,
unsigned char* packetData, size_t maxLength, size_t& outputLength);
void forgetModelsDeletedBefore(quint64 sinceTime); void forgetModelsDeletedBefore(quint64 sinceTime);
void processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode); void processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode);

View file

@ -56,14 +56,19 @@ ModelTreeElement* ModelTreeElement::addChildAtIndex(int index) {
// contents across multiple packets. // contents across multiple packets.
OctreeElement::AppendState ModelTreeElement::appendElementData(OctreePacketData* packetData, OctreeElement::AppendState ModelTreeElement::appendElementData(OctreePacketData* packetData,
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 // first, check the params.extraEncodeData to see if there's any partial re-encode data for this element
OctreeElementExtraEncodeData* extraEncodeData = params.extraEncodeData; OctreeElementExtraEncodeData* extraEncodeData = params.extraEncodeData;
ModelTreeElementExtraEncodeData* elementExtraEncodeData = NULL; ModelTreeElementExtraEncodeData* modelTreeElementExtraEncodeData = NULL;
bool hadElementExtraData = false;
if (extraEncodeData && extraEncodeData->contains(this)) { if (extraEncodeData && extraEncodeData->contains(this)) {
elementExtraEncodeData = static_cast<ModelTreeElementExtraEncodeData*>(extraEncodeData->value(this)); modelTreeElementExtraEncodeData = static_cast<ModelTreeElementExtraEncodeData*>(extraEncodeData->value(this));
hadElementExtraData = true;
} else {
// if there wasn't one already, then create one
modelTreeElementExtraEncodeData = new ModelTreeElementExtraEncodeData();
} }
LevelDetails elementLevel = packetData->startLevel(); LevelDetails elementLevel = packetData->startLevel();
@ -77,11 +82,8 @@ OctreeElement::AppendState ModelTreeElement::appendElementData(OctreePacketData*
const ModelItem& model = (*_modelItems)[i]; const ModelItem& model = (*_modelItems)[i];
bool includeThisModel = true; bool includeThisModel = true;
if (elementExtraEncodeData) { if (hadElementExtraData) {
includeThisModel = elementExtraEncodeData->includedItems.contains(model.getModelItemID()); includeThisModel = modelTreeElementExtraEncodeData->includedItems.contains(model.getModelItemID());
if (includeThisModel) {
elementExtraEncodeData->includedItems.remove(model.getModelItemID()); // remove it
}
} }
if (includeThisModel && params.viewFrustum) { if (includeThisModel && params.viewFrustum) {
@ -107,7 +109,7 @@ OctreeElement::AppendState ModelTreeElement::appendElementData(OctreePacketData*
LevelDetails modelLevel = packetData->startLevel(); LevelDetails modelLevel = packetData->startLevel();
OctreeElement::AppendState appendModelState = model.appendModelData(packetData, params); OctreeElement::AppendState appendModelState = model.appendModelData(packetData, params, modelTreeElementExtraEncodeData);
// If none of this model data was able to be appended, then discard it // If none of this model data was able to be appended, then discard it
// and don't include it in our model count // and don't include it in our model count
@ -119,33 +121,33 @@ OctreeElement::AppendState ModelTreeElement::appendElementData(OctreePacketData*
packetData->endLevel(modelLevel); packetData->endLevel(modelLevel);
actualNumberOfModels++; actualNumberOfModels++;
} }
// If the model item got completely appended, then we can remove it from the extra encode data
if (appendModelState == OctreeElement::COMPLETED) {
modelTreeElementExtraEncodeData->includedItems.remove(model.getModelItemID());
}
// 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
// NOTE: if the model item didn't fit or only partially fit, then the model item should have
// added itself to the extra encode data.
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 // If we were provided with extraEncodeData, and we allocated and/or got modelTreeElementExtraEncodeData
// then we need to do some additional processing // then we need to do some additional processing, namely make sure our extraEncodeData is up to date for
if (extraEncodeData && elementExtraEncodeData) { // this octree element.
if (extraEncodeData && modelTreeElementExtraEncodeData) {
// If after processing we have some includedItems left in it, then make sure we re-add it back to our map // 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()) { if (modelTreeElementExtraEncodeData->includedItems.size()) {
extraEncodeData->insert(this, elementExtraEncodeData); extraEncodeData->insert(this, modelTreeElementExtraEncodeData);
} else { } else {
// otherwise, clean things up... // otherwise, clean things up...
extraEncodeData->remove(this); extraEncodeData->remove(this);
delete elementExtraEncodeData; delete modelTreeElementExtraEncodeData;
} }
} }
@ -343,16 +345,22 @@ bool ModelTreeElement::findSpherePenetration(const glm::vec3& center, float radi
} }
bool ModelTreeElement::updateModel(const ModelItem& model) { bool ModelTreeElement::updateModel(const ModelItem& model) {
const bool wantDebug = false;
if (wantDebug) {
ModelItemID modelItemID = model.getModelItemID();
qDebug() << "ModelTreeElement::updateModel(model) modelID.id="
<< modelItemID.id << "creatorTokenID=" << modelItemID.creatorTokenID;
}
// NOTE: this method must first lookup the model by ID, hence it is O(N) // NOTE: this method must first lookup the model by ID, hence it is O(N)
// and "model is not found" is worst-case (full N) but maybe we don't care? // and "model is not found" is worst-case (full N) but maybe we don't care?
// (guaranteed that num models per elemen is small?) // (guaranteed that num models per elemen is small?)
const bool wantDebug = false;
uint16_t numberOfModels = _modelItems->size(); uint16_t numberOfModels = _modelItems->size();
for (uint16_t i = 0; i < numberOfModels; i++) { for (uint16_t i = 0; i < numberOfModels; i++) {
ModelItem& thisModel = (*_modelItems)[i]; ModelItem& thisModel = (*_modelItems)[i];
if (thisModel.getID() == model.getID()) { if (thisModel.getID() == model.getID()) {
int difference = thisModel.getLastUpdated() - model.getLastUpdated(); int difference = thisModel.getLastUpdated() - model.getLastUpdated();
bool changedOnServer = thisModel.getLastEdited() < model.getLastEdited(); bool changedOnServer = thisModel.getLastEdited() <= model.getLastEdited();
bool localOlder = thisModel.getLastUpdated() < model.getLastUpdated(); bool localOlder = thisModel.getLastUpdated() < model.getLastUpdated();
if (changedOnServer || localOlder) { if (changedOnServer || localOlder) {
if (wantDebug) { if (wantDebug) {
@ -506,6 +514,8 @@ bool ModelTreeElement::removeModelWithID(uint32_t id) {
int ModelTreeElement::readElementDataFromBuffer(const unsigned char* data, int bytesLeftToRead, int ModelTreeElement::readElementDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
ReadBitstreamToTreeParams& args) { ReadBitstreamToTreeParams& args) {
const bool wantDebugging = false;
// If we're the root, but this bitstream doesn't support root elements with data, then // If we're the root, but this bitstream doesn't support root elements with data, then
// return without reading any bytes // return without reading any bytes
@ -532,6 +542,22 @@ int ModelTreeElement::readElementDataFromBuffer(const unsigned char* data, int b
for (uint16_t i = 0; i < numberOfModels; i++) { for (uint16_t i = 0; i < numberOfModels; i++) {
ModelItem tempModel; ModelItem tempModel;
int bytesForThisModel = tempModel.readModelDataFromBuffer(dataAt, bytesLeftToRead, args); int bytesForThisModel = tempModel.readModelDataFromBuffer(dataAt, bytesLeftToRead, args);
if (wantDebugging) {
ModelItemID modelItemID = tempModel.getModelItemID();
qDebug() << "ModelTreeElement::readElementDataFromBuffer()... tempModel.modelItemID.id="
<< modelItemID.id << "creatorTokenID=" << modelItemID.creatorTokenID;
}
const ModelItem* existingModelItem = _myTree->findModelByID(modelItemID.id, true);
if (existingModelItem) {
//qDebug() << "ModelTreeElement::readElementDataFromBuffer()... model item already exists...";
tempModel.copyChangedProperties(*existingModelItem); // copy original properties...
bytesForThisModel = tempModel.readModelDataFromBuffer(dataAt, bytesLeftToRead, args); // reread only the changed properties
}
//qDebug() << "ModelTreeElement::readElementDataFromBuffer()... _myTree->storeModel(tempModel)";
_myTree->storeModel(tempModel); _myTree->storeModel(tempModel);
dataAt += bytesForThisModel; dataAt += bytesForThisModel;
bytesLeftToRead -= bytesForThisModel; bytesLeftToRead -= bytesForThisModel;

View file

@ -47,7 +47,7 @@ public:
class ModelTreeElementExtraEncodeData { class ModelTreeElementExtraEncodeData {
public: public:
QMap<ModelItemID, bool> includedItems; // for now, bool, soon ModelPropertyFlags QMap<ModelItemID, ModelPropertyFlags> includedItems; // for now, bool, soon ModelPropertyFlags
}; };

View file

@ -16,6 +16,8 @@
#include <ByteCountCoding.h> #include <ByteCountCoding.h>
#include <ModelItem.h> #include <ModelItem.h>
#include <ModelTree.h>
#include <ModelTreeElement.h>
#include <Octree.h> #include <Octree.h>
#include <OctreeConstants.h> #include <OctreeConstants.h>
#include <PropertyFlags.h> #include <PropertyFlags.h>
@ -1270,7 +1272,7 @@ void OctreeTests::byteCountCodingTests(bool verbose) {
void OctreeTests::modelItemTests(bool verbose) { void OctreeTests::modelItemTests(bool verbose) {
//verbose = true; //verbose = true;
ModelTreeElementExtraEncodeData modelTreeElementExtraEncodeData;
int testsTaken = 0; int testsTaken = 0;
int testsPassed = 0; int testsPassed = 0;
int testsFailed = 0; int testsFailed = 0;
@ -1288,7 +1290,7 @@ void OctreeTests::modelItemTests(bool verbose) {
modelItem.setID(1042); modelItem.setID(1042);
modelItem.setModelURL("http://foo.com/foo.fbx"); modelItem.setModelURL("http://foo.com/foo.fbx");
bool appendResult = modelItem.new___appendModelData(&packetData, params); bool appendResult = modelItem.appendModelData(&packetData, params, &modelTreeElementExtraEncodeData);
int bytesWritten = packetData.getUncompressedSize(); int bytesWritten = packetData.getUncompressedSize();
if (verbose) { if (verbose) {
qDebug() << "Test 1: bytesRead == bytesWritten ..."; qDebug() << "Test 1: bytesRead == bytesWritten ...";
@ -1302,7 +1304,7 @@ void OctreeTests::modelItemTests(bool verbose) {
const unsigned char* data = packetData.getUncompressedData(); const unsigned char* data = packetData.getUncompressedData();
int bytesLeftToRead = packetData.getUncompressedSize(); int bytesLeftToRead = packetData.getUncompressedSize();
int bytesRead = modelItemFromBuffer.new___readModelDataFromBuffer(data, bytesLeftToRead, args); int bytesRead = modelItemFromBuffer.readModelDataFromBuffer(data, bytesLeftToRead, args);
if (verbose) { if (verbose) {
qDebug() << "bytesRead=" << bytesRead; qDebug() << "bytesRead=" << bytesRead;
qDebug() << "modelItemFromBuffer.getID()=" << modelItemFromBuffer.getID(); qDebug() << "modelItemFromBuffer.getID()=" << modelItemFromBuffer.getID();
@ -1343,7 +1345,7 @@ void OctreeTests::modelItemTests(bool verbose) {
QByteArray garbageData(almostFullOfData, 0); QByteArray garbageData(almostFullOfData, 0);
packetData.appendValue(garbageData); packetData.appendValue(garbageData);
appendResult = modelItem.new___appendModelData(&packetData, params); appendResult = modelItem.appendModelData(&packetData, params, &modelTreeElementExtraEncodeData);
bytesWritten = packetData.getUncompressedSize() - almostFullOfData; bytesWritten = packetData.getUncompressedSize() - almostFullOfData;
if (verbose) { if (verbose) {
qDebug() << "Test 3: attempt to appendModelData in nearly full packetData ..."; qDebug() << "Test 3: attempt to appendModelData in nearly full packetData ...";
@ -1370,7 +1372,7 @@ void OctreeTests::modelItemTests(bool verbose) {
QByteArray garbageData(almostFullOfData, 0); QByteArray garbageData(almostFullOfData, 0);
packetData.appendValue(garbageData); packetData.appendValue(garbageData);
appendResult = modelItem.new___appendModelData(&packetData, params); appendResult = modelItem.appendModelData(&packetData, params, &modelTreeElementExtraEncodeData);
bytesWritten = packetData.getUncompressedSize() - almostFullOfData; bytesWritten = packetData.getUncompressedSize() - almostFullOfData;
if (verbose) { if (verbose) {
qDebug() << "Test 4: attempt to appendModelData in nearly full packetData which some should fit ..."; qDebug() << "Test 4: attempt to appendModelData in nearly full packetData which some should fit ...";
@ -1392,7 +1394,7 @@ void OctreeTests::modelItemTests(bool verbose) {
const unsigned char* data = packetData.getUncompressedData() + almostFullOfData; const unsigned char* data = packetData.getUncompressedData() + almostFullOfData;
int bytesLeftToRead = packetData.getUncompressedSize() - almostFullOfData; int bytesLeftToRead = packetData.getUncompressedSize() - almostFullOfData;
int bytesRead = modelItemFromBuffer.new___readModelDataFromBuffer(data, bytesLeftToRead, args); int bytesRead = modelItemFromBuffer.readModelDataFromBuffer(data, bytesLeftToRead, args);
if (verbose) { if (verbose) {
qDebug() << "Test 5: partial ModelItem written ... bytesRead == bytesWritten..."; qDebug() << "Test 5: partial ModelItem written ... bytesRead == bytesWritten...";
qDebug() << "bytesRead=" << bytesRead; qDebug() << "bytesRead=" << bytesRead;