From c6347eb92a5950f4b8663993ef69cd92b62d4e91 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Mon, 28 Mar 2016 13:39:43 -0700 Subject: [PATCH] checkpoint for debugging/comparing edit.js --- .../src/entities/AssignmentParentFinder.cpp | 8 ++- .../src/entities/AssignmentParentFinder.h | 2 +- interface/src/Application.cpp | 62 +++++++++++++++---- interface/src/InterfaceParentFinder.cpp | 12 ++-- interface/src/InterfaceParentFinder.h | 2 +- libraries/entities/src/EntityTree.cpp | 11 +++- libraries/entities/src/EntityTree.h | 4 +- libraries/shared/src/SpatialParentFinder.h | 6 +- libraries/shared/src/SpatiallyNestable.cpp | 4 +- libraries/shared/src/SpatiallyNestable.h | 4 +- 10 files changed, 86 insertions(+), 29 deletions(-) diff --git a/assignment-client/src/entities/AssignmentParentFinder.cpp b/assignment-client/src/entities/AssignmentParentFinder.cpp index 294556383e..a0232daff4 100644 --- a/assignment-client/src/entities/AssignmentParentFinder.cpp +++ b/assignment-client/src/entities/AssignmentParentFinder.cpp @@ -11,7 +11,7 @@ #include "AssignmentParentFinder.h" -SpatiallyNestableWeakPointer AssignmentParentFinder::find(QUuid parentID, bool& success) const { +SpatiallyNestableWeakPointer AssignmentParentFinder::find(QUuid parentID, bool& success, SpatialParentTree* entityTree) const { SpatiallyNestableWeakPointer parent; if (parentID.isNull()) { @@ -20,7 +20,11 @@ SpatiallyNestableWeakPointer AssignmentParentFinder::find(QUuid parentID, bool& } // search entities - parent = _tree->findEntityByEntityItemID(parentID); + if (entityTree) { + parent = entityTree->findByID(parentID); + } else { + parent = _tree->findEntityByEntityItemID(parentID); + } if (parent.expired()) { success = false; } else { diff --git a/assignment-client/src/entities/AssignmentParentFinder.h b/assignment-client/src/entities/AssignmentParentFinder.h index 9a776bc7dd..0c16143143 100644 --- a/assignment-client/src/entities/AssignmentParentFinder.h +++ b/assignment-client/src/entities/AssignmentParentFinder.h @@ -25,7 +25,7 @@ class AssignmentParentFinder : public SpatialParentFinder { public: AssignmentParentFinder(EntityTreePointer tree) : _tree(tree) { } virtual ~AssignmentParentFinder() { } - virtual SpatiallyNestableWeakPointer find(QUuid parentID, bool& success) const; + virtual SpatiallyNestableWeakPointer find(QUuid parentID, bool& success, SpatialParentTree* entityTree = nullptr) const; protected: EntityTreePointer _tree; diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9bef698167..df08afcf64 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -270,7 +270,7 @@ public: void run() override { while (!_quit) { QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS); - +/* fixme uint64_t lastHeartbeat = _heartbeat; // sample atomic _heartbeat, because we could context switch away and have it updated on us uint64_t now = usecTimestampNow(); auto lastHeartbeatAge = (now > lastHeartbeat) ? now - lastHeartbeat : 0; @@ -319,6 +319,7 @@ public: deadlockDetectionCrash(); } #endif + */ } } @@ -2790,43 +2791,78 @@ void Application::calibrateEyeTracker5Points() { } #endif +class EntityDatum { // For parent-first sorting and mapping. +public: + EntityItemPointer item; + EntityItemProperties properties; + EntityItemID originalParentID; + EntityItemID mappedID; + EntityDatum() {}; + EntityDatum(EntityItemPointer itemArg, EntityItemProperties propertiesArg, EntityItemID parentID) : + item(itemArg), properties(propertiesArg), originalParentID(parentID) { + }; +}; bool Application::exportEntities(const QString& filename, const QVector& entityIDs) { - QVector entities; + QHash entities; auto entityTree = getEntities()->getTree(); auto exportTree = std::make_shared(); exportTree->createRootElement(); glm::vec3 root(TREE_SCALE, TREE_SCALE, TREE_SCALE); - for (auto entityID : entityIDs) { + for (auto entityID : entityIDs) { // Gather entities and properties. auto entityItem = entityTree->findEntityByEntityItemID(entityID); if (!entityItem) { + qCDebug(interfaceapp) << "Skipping export of" << entityID << "that is not in scene."; continue; } auto properties = entityItem->getProperties(); - auto position = properties.getPosition(); - + auto position = properties.getPosition(); // see setPosition, below. root.x = glm::min(root.x, position.x); root.y = glm::min(root.y, position.y); root.z = glm::min(root.z, position.z); - entities << entityItem; + qCDebug(interfaceapp) << "Exporting" << entityItem->getEntityItemID() << entityItem->getName(); + entities[entityID] = EntityDatum(entityItem, properties, properties.getParentID()); } if (entities.size() == 0) { return false; } - for (auto entityItem : entities) { - auto properties = entityItem->getProperties(); + for (EntityDatum& entityDatum : entities) { + // Recursively add the parents of entities to the exportTree, mapping their new identifiers as we go. + std::function getMapped = [&](EntityDatum& datum) { + auto originalID = datum.item->getEntityItemID(); + if (!datum.mappedID.isInvalidID()) { + qCDebug(interfaceapp) << "already mapped" << datum.properties.getName() << originalID << "=>" << datum.mappedID; + return datum.mappedID; // We are a parent that has already been added/mapped. + } + auto properties = datum.properties; + auto parentID = datum.originalParentID; + if (!datum.originalParentID.isInvalidID()) { // Recurse over ancestors, updating properties. + qCDebug(interfaceapp) << "FIXME recursing" << datum.originalParentID << "parent of" << datum.item->getEntityItemID(); + // Warning: this is not a tail-call, so exporting a REALLY deep parent hierarchy will blow the call stack. + parentID = getMapped(entities[parentID]); + properties.setParentID(parentID); + } + // The so-called root offset (which isn't) is confusing and not what content developers want. And why would queryAACube not then be offset? + // But leaving it in for bug-compatibility right now. -HRS + properties.setPosition(properties.getPosition() - root); + datum.mappedID = originalID; //EntityItemID(QUuid::createUuid()); + auto newEntity = exportTree->addEntity(datum.mappedID, properties); + qCDebug(interfaceapp) << "mapped" << properties.getName(); + qCDebug(interfaceapp) << " " << originalID << "p:" << datum.originalParentID; + qCDebug(interfaceapp) << " =>" << datum.mappedID << "p:" << parentID; - properties.setPosition(properties.getPosition() - root); - exportTree->addEntity(entityItem->getEntityItemID(), properties); + return datum.mappedID; + }; + + getMapped(entityDatum); } - // remap IDs on export so that we aren't publishing the IDs of entities in our domain - exportTree->remapIDs(); + //exportTree->remapIDs(); exportTree->writeToJSONFile(filename.toLocal8Bit().constData()); @@ -2902,7 +2938,7 @@ bool Application::importEntities(const QString& urlOrFilename) { bool success = _entityClipboard->readFromURL(url.toString()); if (success) { - _entityClipboard->remapIDs(); + // FIXME _entityClipboard->remapIDs(); _entityClipboard->reaverageOctreeElements(); } return success; diff --git a/interface/src/InterfaceParentFinder.cpp b/interface/src/InterfaceParentFinder.cpp index de4b0ce38c..b1db63debd 100644 --- a/interface/src/InterfaceParentFinder.cpp +++ b/interface/src/InterfaceParentFinder.cpp @@ -16,7 +16,7 @@ #include "InterfaceParentFinder.h" -SpatiallyNestableWeakPointer InterfaceParentFinder::find(QUuid parentID, bool& success) const { +SpatiallyNestableWeakPointer InterfaceParentFinder::find(QUuid parentID, bool& success, SpatialParentTree* entityTree) const { SpatiallyNestableWeakPointer parent; if (parentID.isNull()) { @@ -25,9 +25,13 @@ SpatiallyNestableWeakPointer InterfaceParentFinder::find(QUuid parentID, bool& s } // search entities - EntityTreeRenderer* treeRenderer = qApp->getEntities(); - EntityTreePointer tree = treeRenderer ? treeRenderer->getTree() : nullptr; - parent = tree ? tree->findEntityByEntityItemID(parentID) : nullptr; + if (entityTree) { + parent = entityTree->findByID(parentID); + } else { + EntityTreeRenderer* treeRenderer = qApp->getEntities(); + EntityTreePointer tree = treeRenderer ? treeRenderer->getTree() : nullptr; + parent = tree ? tree->findEntityByEntityItemID(parentID) : nullptr; + } if (!parent.expired()) { success = true; return parent; diff --git a/interface/src/InterfaceParentFinder.h b/interface/src/InterfaceParentFinder.h index db579c2144..a2e9fb50e4 100644 --- a/interface/src/InterfaceParentFinder.h +++ b/interface/src/InterfaceParentFinder.h @@ -21,7 +21,7 @@ class InterfaceParentFinder : public SpatialParentFinder { public: InterfaceParentFinder() { } virtual ~InterfaceParentFinder() { } - virtual SpatiallyNestableWeakPointer find(QUuid parentID, bool& success) const; + virtual SpatiallyNestableWeakPointer find(QUuid parentID, bool& success, SpatialParentTree* entityTree = nullptr) const; }; #endif // hifi_InterfaceParentFinder_h diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index af1c2e71aa..ef7af3da86 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1009,6 +1009,7 @@ void EntityTree::entityChanged(EntityItemPointer entity) { void EntityTree::fixupMissingParents() { MovingEntitiesOperator moveOperator(getThisPointer()); + if (!_missingParent.empty()) qCDebug(entities) << "HRS fixme fixupMissingParents" << _missingParent.count() << "entities"; QMutableVectorIterator iter(_missingParent); while (iter.hasNext()) { EntityItemWeakPointer entityWP = iter.next(); @@ -1027,6 +1028,7 @@ void EntityTree::fixupMissingParents() { bool doMove = false; if (entity->isParentIDValid()) { + qCDebug(entities) << "HRS fixme valid parent" << entity->getEntityItemID() << queryAACubeSuccess; // this entity's parent was previously not known, and now is. Update its location in the EntityTree... doMove = true; } else if (getIsServer() && _avatarIDs.contains(entity->getParentID())) { @@ -1038,6 +1040,7 @@ void EntityTree::fixupMissingParents() { _childrenOfAvatars[entity->getParentID()] += entity->getEntityItemID(); doMove = true; } + else qCDebug(entities) << "HRS fixme failed parent" << entity->getEntityItemID() << queryAACubeSuccess; if (queryAACubeSuccess && doMove) { moveOperator.addEntityToMoveList(entity, newCube); @@ -1328,19 +1331,22 @@ QVector EntityTree::sendEntities(EntityEditPacketSender* packetSen } bool EntityTree::sendEntitiesOperation(OctreeElementPointer element, void* extraData) { + qCDebug(entities) << "sendEntitiesOperation"; SendEntitiesOperationArgs* args = static_cast(extraData); EntityTreeElementPointer entityTreeElement = std::static_pointer_cast(element); entityTreeElement->forEachEntity([&](EntityItemPointer entityItem) { - EntityItemID newID(QUuid::createUuid()); + EntityItemID newID = entityItem->getEntityItemID(); // FIXME (QUuid::createUuid()); args->newEntityIDs->append(newID); EntityItemProperties properties = entityItem->getProperties(); properties.setPosition(properties.getPosition() + args->root); properties.markAllChanged(); // so the entire property set is considered new, since we're making a new entity + qCDebug(entities) << "sending" << newID << properties.getName() << "parent:" << properties.getParentID(); // queue the packet to send to the server args->packetSender->queueEditEntityMessage(PacketType::EntityAdd, newID, properties); // also update the local tree instantly (note: this is not our tree, but an alternate tree) + // [Sure looks like the global application's tree to me. See callers. -HRS] if (args->localTree) { args->localTree->withWriteLock([&] { args->localTree->addEntity(newID, properties); @@ -1389,11 +1395,12 @@ bool EntityTree::readFromMap(QVariantMap& map) { } EntityItemPointer entity = addEntity(entityItemID, properties); + qCDebug(entities) << "HRS FIXME added" << entityItemID << properties.getName(); if (!entity) { qCDebug(entities) << "adding Entity failed:" << entityItemID << properties.getType(); } } - + qCDebug(entities) << "HRS FIXME end of readFromMap"; return true; } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 0b85c5f32f..8cf6a7e45b 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -16,6 +16,7 @@ #include #include +#include class EntityTree; typedef std::shared_ptr EntityTreePointer; @@ -52,7 +53,7 @@ public: }; -class EntityTree : public Octree { +class EntityTree : public Octree, public SpatialParentTree { Q_OBJECT public: EntityTree(bool shouldReaverage = false); @@ -125,6 +126,7 @@ public: EntityItemPointer findClosestEntity(glm::vec3 position, float targetRadius); EntityItemPointer findEntityByID(const QUuid& id); EntityItemPointer findEntityByEntityItemID(const EntityItemID& entityID); + SpatiallyNestablePointer EntityTree::findByID(const QUuid& id) { return findEntityByID(id); } EntityItemID assignEntityID(const EntityItemID& entityItemID); /// Assigns a known ID for a creator token ID diff --git a/libraries/shared/src/SpatialParentFinder.h b/libraries/shared/src/SpatialParentFinder.h index 9b49490fa5..ff2593c621 100644 --- a/libraries/shared/src/SpatialParentFinder.h +++ b/libraries/shared/src/SpatialParentFinder.h @@ -19,6 +19,10 @@ class SpatiallyNestable; using SpatiallyNestableWeakPointer = std::weak_ptr; using SpatiallyNestablePointer = std::shared_ptr; +class SpatialParentTree { +public: + SpatiallyNestablePointer findByID(const QUuid& id) { return nullptr; } +}; class SpatialParentFinder : public Dependency { @@ -31,7 +35,7 @@ public: SpatialParentFinder() { } virtual ~SpatialParentFinder() { } - virtual SpatiallyNestableWeakPointer find(QUuid parentID, bool& success) const = 0; + virtual SpatiallyNestableWeakPointer find(QUuid parentID, bool& success, SpatialParentTree* entityTree = nullptr) const = 0; }; #endif // hifi_SpatialParentFinder_h diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 55da4822ef..4e091694de 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -70,7 +70,7 @@ Transform SpatiallyNestable::getParentTransform(bool& success, int depth) const return result; } -SpatiallyNestablePointer SpatiallyNestable::getParentPointer(bool& success) const { +SpatiallyNestablePointer SpatiallyNestable::getParentPointer(bool& success, SpatialParentTree* entityTree) const { SpatiallyNestablePointer parent = _parent.lock(); QUuid parentID = getParentID(); // used for its locking @@ -105,7 +105,7 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer(bool& success) cons success = false; return nullptr; } - _parent = parentFinder->find(parentID, success); + _parent = parentFinder->find(parentID, success, entityTree); if (!success) { return nullptr; } diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index a65c7c7f2c..8800fc5ed7 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -139,14 +139,14 @@ public: void die() { _isDead = true; } bool isDead() const { return _isDead; } - bool isParentIDValid() const { bool success = false; getParentPointer(success); return success; } + bool isParentIDValid(SpatialParentTree* entityTree = nullptr) const { bool success = false; getParentPointer(success, entityTree); return success; } protected: const NestableType _nestableType; // EntityItem or an AvatarData QUuid _id; QUuid _parentID; // what is this thing's transform relative to? quint16 _parentJointIndex { 0 }; // which joint of the parent is this relative to? - SpatiallyNestablePointer getParentPointer(bool& success) const; + SpatiallyNestablePointer getParentPointer(bool& success, SpatialParentTree* entityTree = nullptr) const; mutable SpatiallyNestableWeakPointer _parent;