Showing the changes to interface/src/Application.cpp (1 of 10 files). Show all
Unified · Split
| @@ -270,7 +270,7 @@ public: · 269 unmodified lines | |||
| 270 | void run() override { | 270 | void run() override { |
| 271 | while (!_quit) { | 271 | while (!_quit) { |
| 272 | QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS); | 272 | QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS); |
| 273 | 273 | /* fixme | |
| 274 | uint64_t lastHeartbeat = _heartbeat; // sample atomic _heartbeat, because we could context switch away and have it updated on us | 274 | uint64_t lastHeartbeat = _heartbeat; // sample atomic _heartbeat, because we could context switch away and have it updated on us |
| 275 | uint64_t now = usecTimestampNow(); | 275 | uint64_t now = usecTimestampNow(); |
| 276 | auto lastHeartbeatAge = (now > lastHeartbeat) ? now - lastHeartbeat : 0; | 276 | auto lastHeartbeatAge = (now > lastHeartbeat) ? now - lastHeartbeat : 0; |
| @@ -319,6 +319,7 @@ public: · 42 unmodified lines | |||
| 319 | deadlockDetectionCrash(); | 319 | deadlockDetectionCrash(); |
| 320 | } | 320 | } |
| 321 | #endif | 321 | #endif |
| 322 | */ | ||
| 322 | } | 323 | } |
| 323 | } | 324 | } |
| 324 | 325 | ||
| @@ -2790,43 +2791,78 @@ void Application::calibrateEyeTracker5Points() { · 2465 unmodified lines | |||
| 2790 | } | 2791 | } |
| 2791 | #endif | 2792 | #endif |
| 2792 | 2793 | ||
| 2794 | class EntityDatum { // For parent-first sorting and mapping. | ||
| 2795 | public: | ||
| 2796 | EntityItemPointer item; | ||
| 2797 | EntityItemProperties properties; | ||
| 2798 | EntityItemID originalParentID; | ||
| 2799 | EntityItemID mappedID; | ||
| 2800 | EntityDatum() {}; | ||
| 2801 | EntityDatum(EntityItemPointer itemArg, EntityItemProperties propertiesArg, EntityItemID parentID) : | ||
| 2802 | item(itemArg), properties(propertiesArg), originalParentID(parentID) { | ||
| 2803 | }; | ||
| 2804 | }; | ||
| 2793 | bool Application::exportEntities(const QString& filename, const QVector<EntityItemID>& entityIDs) { | 2805 | bool Application::exportEntities(const QString& filename, const QVector<EntityItemID>& entityIDs) { |
| 2794 | QVector<EntityItemPointer> entities; | 2806 | QHash<EntityItemID, EntityDatum> entities; |
| 2795 | 2807 | ||
| 2796 | auto entityTree = getEntities()->getTree(); | 2808 | auto entityTree = getEntities()->getTree(); |
| 2797 | auto exportTree = std::make_shared<EntityTree>(); | 2809 | auto exportTree = std::make_shared<EntityTree>(); |
| 2798 | exportTree->createRootElement(); | 2810 | exportTree->createRootElement(); |
| 2799 | 2811 | ||
| 2800 | glm::vec3 root(TREE_SCALE, TREE_SCALE, TREE_SCALE); | 2812 | glm::vec3 root(TREE_SCALE, TREE_SCALE, TREE_SCALE); |
| 2801 | for (auto entityID : entityIDs) { | 2813 | for (auto entityID : entityIDs) { // Gather entities and properties. |
| 2802 | auto entityItem = entityTree->findEntityByEntityItemID(entityID); | 2814 | auto entityItem = entityTree->findEntityByEntityItemID(entityID); |
| 2803 | if (!entityItem) { | 2815 | if (!entityItem) { |
| 2816 | qCDebug(interfaceapp) << "Skipping export of" << entityID << "that is not in scene."; | ||
| 2804 | continue; | 2817 | continue; |
| 2805 | } | 2818 | } |
| 2806 | 2819 | ||
| 2807 | auto properties = entityItem->getProperties(); | 2820 | auto properties = entityItem->getProperties(); |
| 2808 | auto position = properties.getPosition(); | 2821 | auto position = properties.getPosition(); // see setPosition, below. |
| 2809 | |||
| 2810 | root.x = glm::min(root.x, position.x); | 2822 | root.x = glm::min(root.x, position.x); |
| 2811 | root.y = glm::min(root.y, position.y); | 2823 | root.y = glm::min(root.y, position.y); |
| 2812 | root.z = glm::min(root.z, position.z); | 2824 | root.z = glm::min(root.z, position.z); |
| 2813 | 2825 | ||
| 2814 | entities << entityItem; | 2826 | qCDebug(interfaceapp) << "Exporting" << entityItem->getEntityItemID() << entityItem->getName(); |
| 2827 | entities[entityID] = EntityDatum(entityItem, properties, properties.getParentID()); | ||
| 2815 | } | 2828 | } |
| 2816 | 2829 | ||
| 2817 | if (entities.size() == 0) { | 2830 | if (entities.size() == 0) { |
| 2818 | return false; | 2831 | return false; |
| 2819 | } | 2832 | } |
| 2820 | 2833 | ||
| 2821 | for (auto entityItem : entities) { | 2834 | for (EntityDatum& entityDatum : entities) { |
| 2822 | auto properties = entityItem->getProperties(); | 2835 | // Recursively add the parents of entities to the exportTree, mapping their new identifiers as we go. |
| 2836 | std::function<EntityItemID(EntityDatum&)> getMapped = [&](EntityDatum& datum) { | ||
| 2837 | auto originalID = datum.item->getEntityItemID(); | ||
| 2838 | if (!datum.mappedID.isInvalidID()) { | ||
| 2839 | qCDebug(interfaceapp) << "already mapped" << datum.properties.getName() << originalID << "=>" << datum.mappedID; | ||
| 2840 | return datum.mappedID; // We are a parent that has already been added/mapped. | ||
| 2841 | } | ||
| 2842 | auto properties = datum.properties; | ||
| 2843 | auto parentID = datum.originalParentID; | ||
| 2844 | if (!datum.originalParentID.isInvalidID()) { // Recurse over ancestors, updating properties. | ||
| 2845 | qCDebug(interfaceapp) << "FIXME recursing" << datum.originalParentID << "parent of" << datum.item->getEntityItemID(); | ||
| 2846 | // Warning: this is not a tail-call, so exporting a REALLY deep parent hierarchy will blow the call stack. | ||
| 2847 | parentID = getMapped(entities[parentID]); | ||
| 2848 | properties.setParentID(parentID); | ||
| 2849 | } | ||
| 2850 | // The so-called root offset (which isn't) is confusing and not what content developers want. And why would queryAACube not then be offset? | ||
| 2851 | // But leaving it in for bug-compatibility right now. -HRS | ||
| 2852 | properties.setPosition(properties.getPosition() - root); | ||
| 2853 | datum.mappedID = originalID; //EntityItemID(QUuid::createUuid()); | ||
| 2854 | auto newEntity = exportTree->addEntity(datum.mappedID, properties); | ||
| 2855 | qCDebug(interfaceapp) << "mapped" << properties.getName(); | ||
| 2856 | qCDebug(interfaceapp) << " " << originalID << "p:" << datum.originalParentID; | ||
| 2857 | qCDebug(interfaceapp) << " =>" << datum.mappedID << "p:" << parentID; | ||
| 2823 | 2858 | ||
| 2824 | properties.setPosition(properties.getPosition() - root); | 2859 | return datum.mappedID; |
| 2825 | exportTree->addEntity(entityItem->getEntityItemID(), properties); | 2860 | }; |
| 2826 | } | ||
| 2827 | 2861 | ||
| 2862 | getMapped(entityDatum); | ||
| 2863 | } | ||
| 2828 | // remap IDs on export so that we aren't publishing the IDs of entities in our domain | 2864 | // remap IDs on export so that we aren't publishing the IDs of entities in our domain |
| 2829 | exportTree->remapIDs(); | 2865 | //exportTree->remapIDs(); |
| 2830 | 2866 | ||
| 2831 | exportTree->writeToJSONFile(filename.toLocal8Bit().constData()); | 2867 | exportTree->writeToJSONFile(filename.toLocal8Bit().constData()); |
| 2832 | 2868 | ||
| @@ -2902,7 +2938,7 @@ bool Application::importEntities(const QString& urlOrFilename) { · 69 unmodified lines | |||
| 2902 | 2938 | ||
| 2903 | bool success = _entityClipboard->readFromURL(url.toString()); | 2939 | bool success = _entityClipboard->readFromURL(url.toString()); |
| 2904 | if (success) { | 2940 | if (success) { |
| 2905 | _entityClipboard->remapIDs(); | 2941 | // FIXME _entityClipboard->remapIDs(); |
| 2906 | _entityClipboard->reaverageOctreeElements(); | 2942 | _entityClipboard->reaverageOctreeElements(); |
| 2907 | } | 2943 | } |
| 2908 | return success; | 2944 | return success; |