diff --git a/interface/src/entities/EntityTreeRenderer.cpp b/interface/src/entities/EntityTreeRenderer.cpp index 4ad24196ae..18b4c55272 100644 --- a/interface/src/entities/EntityTreeRenderer.cpp +++ b/interface/src/entities/EntityTreeRenderer.cpp @@ -177,8 +177,6 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args) //qDebug() << "EntityTreeRenderer::renderElement() element=" << element << "numberOfEntities=" << numberOfEntities; bool isShadowMode = args->_renderMode == OctreeRenderer::SHADOW_RENDER_MODE; - - bool displayModelBounds = Menu::getInstance()->isOptionChecked(MenuOption::DisplayModelBounds); bool displayElementProxy = Menu::getInstance()->isOptionChecked(MenuOption::DisplayModelElementProxy); bool displayElementChildProxies = Menu::getInstance()->isOptionChecked(MenuOption::DisplayModelElementChildProxies); diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 8b75806f6a..91b8ebb353 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -961,7 +961,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int memcpy(&lastEdited, dataAt, sizeof(lastEdited)); dataAt += sizeof(lastEdited); processedBytes += sizeof(lastEdited); -qDebug() << "EntityItemProperties::decodeEntityEditPacket() ... lastEdited=" << lastEdited; + //qDebug() << "EntityItemProperties::decodeEntityEditPacket() ... lastEdited=" << lastEdited; properties.setLastEdited(lastEdited); // encoded id @@ -976,7 +976,7 @@ qDebug() << "EntityItemProperties::decodeEntityEditPacket() ... lastEdited=" << bool isNewEntityItem = (editID == NEW_ENTITY); - qDebug() << "EntityItemProperties::decodeEntityEditPacket() isNewEntityItem=" << isNewEntityItem; + //qDebug() << "EntityItemProperties::decodeEntityEditPacket() isNewEntityItem=" << isNewEntityItem; if (isNewEntityItem) { // If this is a NEW_ENTITY, then we assume that there's an additional uint32_t creatorToken, that @@ -1025,10 +1025,12 @@ qDebug() << "EntityItemProperties::decodeEntityEditPacket() ... lastEdited=" << QByteArray encodedUpdateDelta((const char*)dataAt, (bytesToRead - processedBytes)); ByteCountCoded updateDeltaCoder = encodedUpdateDelta; quint64 updateDelta = updateDeltaCoder; - quint64 lastUpdated = lastEdited + updateDelta; // don't adjust for clock skew since we already did that for lastEdited encodedUpdateDelta = updateDeltaCoder; // determine true bytesToRead dataAt += encodedUpdateDelta.size(); processedBytes += encodedUpdateDelta.size(); + + // TODO: Do we need this lastUpdated?? We don't seem to use it. + //quint64 lastUpdated = lastEdited + updateDelta; // don't adjust for clock skew since we already did that for lastEdited // Property Flags... QByteArray encodedPropertyFlags((const char*)dataAt, (bytesToRead - processedBytes)); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 31d8f6696e..66662eb13f 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -349,6 +349,13 @@ bool UpdateEntityOperator::PostRecursion(OctreeElement* element) { (_foundNew && subTreeContainsNewEntity(element))) { element->markWithChangedTime(); } + + EntityTreeElement* entityTreeElement = static_cast(element); + bool somethingPruned = entityTreeElement->pruneChildren(); // take this opportunity to prune any empty leaves + if (somethingPruned) { + qDebug() << "UpdateEntityOperator::PostRecursion() something pruned!!!"; + } + return keepSearching; // if we haven't yet found it, keep looking } @@ -573,6 +580,13 @@ bool DeleteEntityOperator::PostRecursion(OctreeElement* element) { if ((subTreeContainsSomeEntitiesToDelete(element))) { element->markWithChangedTime(); } + + EntityTreeElement* entityTreeElement = static_cast(element); + bool somethingPruned = entityTreeElement->pruneChildren(); // take this opportunity to prune any empty leaves + if (somethingPruned) { + qDebug() << "DeleteEntityOperator::PostRecursion() something pruned!!!"; + } + return keepSearching; // if we haven't yet found it, keep looking } diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index ad42ac9315..e1709c95b7 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -709,6 +709,21 @@ bool EntityTreeElement::collapseChildren() { return false; } +bool EntityTreeElement::pruneChildren() { + bool somethingPruned = false; + for (int childIndex = 0; childIndex < NUMBER_OF_CHILDREN; childIndex++) { + EntityTreeElement* child = getChildAtIndex(childIndex); + + // if my child is a leaf, but has no entities, then it's safe to delete my child + if (child && child->isLeaf() && !child->hasEntities()) { + qDebug() << "EntityTreeElement::pruneChildren()... WANT TO PRUNE!!!! childIndex=" << childIndex; + deleteChildAtIndex(childIndex); + somethingPruned = true; + } + } + return somethingPruned; +} + void EntityTreeElement::debugDump() { qDebug() << "EntityTreeElement..."; diff --git a/libraries/entities/src/EntityTreeElement.h b/libraries/entities/src/EntityTreeElement.h index e02f7f1583..3125a968a4 100644 --- a/libraries/entities/src/EntityTreeElement.h +++ b/libraries/entities/src/EntityTreeElement.h @@ -163,6 +163,8 @@ public: void debugDump(); + bool pruneChildren(); + protected: virtual void init(unsigned char * octalCode); EntityTree* _myTree; diff --git a/libraries/entities/src/MovingEntitiesOperator.cpp b/libraries/entities/src/MovingEntitiesOperator.cpp index 32c055891e..171774a178 100644 --- a/libraries/entities/src/MovingEntitiesOperator.cpp +++ b/libraries/entities/src/MovingEntitiesOperator.cpp @@ -80,11 +80,8 @@ bool MovingEntitiesOperator::PreRecursion(OctreeElement* element) { if (!details.oldFound && entityTreeElement == details.oldContainingElement) { EntityItemID entityItemID = details.entity->getEntityItemID(); entityTreeElement->removeEntityWithEntityItemID(entityItemID); -qDebug() << "removing entityItem from element... entityItemID=" << entityItemID << "entityTreeElement=" << entityTreeElement; - // if we haven't yet found the entity's new location clear our containing element - //if (!details.newFound) { - // _tree->setContainingElement(entityItemID, NULL); - //} + + //qDebug() << "removing entityItem from element... entityItemID=" << entityItemID << "entityTreeElement=" << entityTreeElement; _foundOldCount++; //details.oldFound = true; // TODO: would be nice to add this optimization } @@ -94,7 +91,7 @@ qDebug() << "removing entityItem from element... entityItemID=" << entityItemID EntityItemID entityItemID = details.entity->getEntityItemID(); entityTreeElement->addEntityItem(details.entity); _tree->setContainingElement(entityItemID, entityTreeElement); -qDebug() << "adding entityItem to element... entityItemID=" << entityItemID << "entityTreeElement=" << entityTreeElement; + //qDebug() << "adding entityItem to element... entityItemID=" << entityItemID << "entityTreeElement=" << entityTreeElement; _foundNewCount++; //details.newFound = true; // TODO: would be nice to add this optimization } @@ -118,6 +115,13 @@ bool MovingEntitiesOperator::PostRecursion(OctreeElement* element) { if ((shouldRecurseSubTree(element))) { element->markWithChangedTime(); } + + EntityTreeElement* entityTreeElement = static_cast(element); + bool somethingPruned = entityTreeElement->pruneChildren(); // take this opportunity to prune any empty leaves + if (somethingPruned) { + qDebug() << "MovingEntitiesOperator::PostRecursion() something pruned!!!"; + } + return keepSearching; // if we haven't yet found it, keep looking } diff --git a/libraries/entities/src/todo.txt b/libraries/entities/src/todo.txt index deb5f36b60..77aaca4fff 100644 --- a/libraries/entities/src/todo.txt +++ b/libraries/entities/src/todo.txt @@ -39,8 +39,10 @@ Model properties: // // REQUIRED TO DO: + 12) clean up delete behavior... + 12a) make sure server is deleting items?? + 12b) Use the delete message instead of shouldDelete property - D) update and verify all particle examples to use new entity features E) memory leaks??? 22) Import/Export Models - verify it works. /copy/paste?? 22a) void ModelItemProperties::copyFromNewModelItem(const ModelItem& modelItem); // XXX ??? Do we need this???? @@ -67,16 +69,40 @@ Model properties: O) Test models -> attachments logic - 12) clean up delete behavior... - 12a) make sure server is deleting items?? - 12b) Use the delete message instead of shouldDelete property S) What happens if the edit properties don't fit in a single message MTU??? + T) animations not always working????? + U) ---- WHAT'S THIS ------- + UNEXPECTED -- OctreeElement::getMyChildContaining() cubeScale=[0.000012] > ourScale=[0.000004] + + V) crash/assert when you move an entity out of domain bounds??? + + [DEBUG] [2014-08-11 15:44:46 -0700] [50756:65082] [entity-server] EntityItemProperties::decodeEntityEditPacket() PROP_VELOCITY value= {type='glm::vec3', x=0, y=-0.00194919, z=0} + [DEBUG] [2014-08-11 15:44:46 -0700] [50756:65082] [entity-server] ******************************* EntityItemProperties::decodeEntityEditPacket() PROP_DAMPING value= 0.99 + [DEBUG] [2014-08-11 15:44:46 -0700] [50756:65082] [entity-server] EntityItem EntityItem::decodeEntityEditPacket() model URL= "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/pug.fbx" + [DEBUG] [2014-08-11 15:44:46 -0700] [50756:65082] [entity-server] getAACubeTreeUnits() + [DEBUG] [2014-08-11 15:44:46 -0700] [50756:65082] [entity-server] corner in meters= 33.735 , -0.189079 , 13.3167 + [DEBUG] [2014-08-11 15:44:46 -0700] [50756:65082] [entity-server] dimension in meters= 0.2 + [DEBUG] [2014-08-11 15:44:46 -0700] [50756:65082] [entity-server] corner in tree units= 0.00205902 , -1.15405e-05 , 0.000812788 + [DEBUG] [2014-08-11 15:44:46 -0700] [50756:65082] [entity-server] dimension in tree units= 1.2207e-05 + [DEBUG] [2014-08-11 15:44:46 -0700] [50756:65082] [entity-server] EntityTree::changeEntityState().... + [DEBUG] [2014-08-11 15:44:46 -0700] [50756:65082] [entity-server] oldState: 2 + [DEBUG] [2014-08-11 15:44:46 -0700] [50756:65082] [entity-server] newState: 2 + [DEBUG] [2014-08-11 15:44:46 -0700] [50756:65082] [entity-server] EntityTree::changeEntityState() BEFORE.... + [DEBUG] [2014-08-11 15:44:46 -0700] [50756:65082] [entity-server] _changingEntities: () + [DEBUG] [2014-08-11 15:44:46 -0700] [50756:65082] [entity-server] _movingEntities: (0x7ff58b4964e0) + [DEBUG] [2014-08-11 15:44:46 -0700] [50756:65082] [entity-server] EntityTree::changeEntityState() AFTER.... + [DEBUG] [2014-08-11 15:44:46 -0700] [50756:65082] [entity-server] _changingEntities: () + [DEBUG] [2014-08-11 15:44:46 -0700] [50756:65082] [entity-server] _movingEntities: (0x7ff58b4964e0) + [DEBUG] [2014-08-11 15:44:46 -0700] [50756:65082] [entity-server] after updateEntity() we no longer have a containing element??? + Assertion failed: (containingElement), function updateEntity, file /Users/zappoman/Development/HiFi/hifi/libraries/entities/src/EntityTree.cpp, line 404. // NICE TO DO: + D) update and verify all particle examples to use new entity features + Ac) implement support for requestedProperties in appendEntityData() that only include CHANGED properties for the viewer... Az) visible???