From 76d2e9bc78080a7f23ffec833d6d6a3ea0c857a0 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 20 Feb 2018 17:37:07 -0800 Subject: [PATCH 1/4] fix comment --- libraries/entities/src/DeleteEntityOperator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities/src/DeleteEntityOperator.cpp b/libraries/entities/src/DeleteEntityOperator.cpp index 347d40ea49..8e6e545401 100644 --- a/libraries/entities/src/DeleteEntityOperator.cpp +++ b/libraries/entities/src/DeleteEntityOperator.cpp @@ -95,7 +95,7 @@ bool DeleteEntityOperator::preRecursion(const OctreeElementPointer& element) { EntityItemPointer theEntity = details.entity; bool entityDeleted = entityTreeElement->removeEntityItem(theEntity, true); // remove it from the element assert(entityDeleted); - (void)entityDeleted; // quite warning + (void)entityDeleted; // quiet warning about unused variable _tree->clearEntityMapEntry(details.entity->getEntityItemID()); _foundCount++; } From e7495d830b2f18dc5ce57298f4cc91e5fbd0bd1f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 20 Feb 2018 17:37:36 -0800 Subject: [PATCH 2/4] maintain Space proxies for entities --- .../src/entities/EntityTreeHeadlessViewer.cpp | 4 +++ interface/src/Application.cpp | 18 +++------- interface/src/Application.h | 3 -- libraries/avatars-renderer/CMakeLists.txt | 1 + libraries/entities-renderer/CMakeLists.txt | 1 + .../src/EntityTreeRenderer.cpp | 35 +++++++++++++++++-- .../src/EntityTreeRenderer.h | 9 +++++ libraries/entities/src/EntityItem.cpp | 6 +++- libraries/entities/src/EntityItem.h | 4 +++ libraries/entities/src/EntityTree.cpp | 10 ++++-- libraries/entities/src/EntityTree.h | 4 ++- libraries/workload/src/workload/Space.cpp | 2 +- libraries/workload/src/workload/Space.h | 3 +- 13 files changed, 75 insertions(+), 25 deletions(-) diff --git a/assignment-client/src/entities/EntityTreeHeadlessViewer.cpp b/assignment-client/src/entities/EntityTreeHeadlessViewer.cpp index 81c42cda1e..d22055b349 100644 --- a/assignment-client/src/entities/EntityTreeHeadlessViewer.cpp +++ b/assignment-client/src/entities/EntityTreeHeadlessViewer.cpp @@ -35,6 +35,10 @@ void EntityTreeHeadlessViewer::update() { EntityTreePointer tree = std::static_pointer_cast(_tree); tree->withTryWriteLock([&] { tree->update(); + + // flush final EntityTree references to deleted entities + std::vector deletedEntities; + tree->swapRemovedEntities(deletedEntities); }); } } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 85fa533b9c..7080602a22 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4544,8 +4544,6 @@ void Application::init() { _physicsEngine->init(); EntityTreePointer tree = getEntities()->getTree(); - connect(tree.get(), &EntityTree::deletingEntity, this, &Application::deletingEntity, Qt::QueuedConnection); - connect(tree.get(), &EntityTree::addingEntity, this, &Application::addingEntity, Qt::QueuedConnection); _entitySimulation->init(tree, _physicsEngine, &_entityEditSender); tree->setSimulation(_entitySimulation); @@ -4879,14 +4877,16 @@ void Application::setKeyboardFocusEntity(const EntityItemID& entityItemID) { auto entityId = _keyboardFocusedEntity.get(); if (entities->wantsKeyboardFocus(entityId)) { entities->setProxyWindow(entityId, _window->windowHandle()); - auto entity = getEntities()->getEntity(entityId); if (_keyboardMouseDevice->isActive()) { _keyboardMouseDevice->pluginFocusOutEvent(); } _lastAcceptedKeyPress = usecTimestampNow(); - setKeyboardFocusHighlight(entity->getWorldPosition(), entity->getWorldOrientation(), - entity->getScaledDimensions() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR); + auto entity = getEntities()->getEntity(entityId); + if (entity) { + setKeyboardFocusHighlight(entity->getWorldPosition(), entity->getWorldOrientation(), + entity->getScaledDimensions() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR); + } } } } @@ -7675,12 +7675,4 @@ void Application::saveNextPhysicsStats(QString filename) { _physicsEngine->saveNextPhysicsStats(filename); } -void Application::addingEntity(const EntityItemID& entityID) { - // TODO: Andrew to implement this -} - -void Application::deletingEntity(const EntityItemID& entityID) { - // TODO: Andrew to implement this -} - #include "Application.moc" diff --git a/interface/src/Application.h b/interface/src/Application.h index 3c2dee03e7..0435425d5f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -391,9 +391,6 @@ public slots: const QString getPreferredCursor() const { return _preferredCursor.get(); } void setPreferredCursor(const QString& cursor); - void addingEntity(const EntityItemID& entityID); - void deletingEntity(const EntityItemID& entityID); - private slots: void onDesktopRootItemCreated(QQuickItem* qmlContext); void onDesktopRootContextCreated(QQmlContext* qmlContext); diff --git a/libraries/avatars-renderer/CMakeLists.txt b/libraries/avatars-renderer/CMakeLists.txt index 40e1607b2a..d3d61ea3fa 100644 --- a/libraries/avatars-renderer/CMakeLists.txt +++ b/libraries/avatars-renderer/CMakeLists.txt @@ -14,5 +14,6 @@ include_hifi_library_headers(audio) include_hifi_library_headers(entities) include_hifi_library_headers(octree) include_hifi_library_headers(task) +include_hifi_library_headers(workload) target_bullet() diff --git a/libraries/entities-renderer/CMakeLists.txt b/libraries/entities-renderer/CMakeLists.txt index 0f33a73e40..92f78e357e 100644 --- a/libraries/entities-renderer/CMakeLists.txt +++ b/libraries/entities-renderer/CMakeLists.txt @@ -14,6 +14,7 @@ include_hifi_library_headers(entities) include_hifi_library_headers(avatars) include_hifi_library_headers(controllers) include_hifi_library_headers(task) +include_hifi_library_headers(workload) target_bullet() target_polyvox() diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index ba81922979..879dd709e8 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -278,6 +278,13 @@ void EntityTreeRenderer::addPendingEntities(const render::ScenePointer& scene, r if (!entity->isParentPathComplete()) { continue; } + if (entity->getSpaceIndex() == -1) { + std::unique_lock lock(_spaceLock); + workload::Space::Sphere sphere(entity->getWorldPosition(), entity->getBoundingRadius()); + int32_t spaceIndex = _space.createProxy(sphere); + entity->setSpaceIndex(spaceIndex); + connect(entity.get(), &EntityItem::spaceUpdate, this, &EntityTreeRenderer::handleSpaceUpdate, Qt::QueuedConnection); + } auto entityID = entity->getEntityItemID(); processedIds.insert(entityID); @@ -287,7 +294,6 @@ void EntityTreeRenderer::addPendingEntities(const render::ScenePointer& scene, r } } - if (!processedIds.empty()) { for (const auto& processedId : processedIds) { _entitiesToAdd.erase(processedId); @@ -407,8 +413,7 @@ void EntityTreeRenderer::update(bool simulate) { // here we update _currentFrame and _lastAnimated and sync with the server properties. tree->update(simulate); - // Update the rendereable entities as needed - { + { // Update the rendereable entities as needed PROFILE_RANGE(simulation_physics, "Scene"); PerformanceTimer sceneTimer("scene"); auto scene = _viewState->getMain3DScene(); @@ -421,6 +426,25 @@ void EntityTreeRenderer::update(bool simulate) { scene->enqueueTransaction(transaction); } } + { // update proxies in the workload::Space + std::unique_lock lock(_spaceLock); + _space.updateProxies(_spaceUpdates); + _spaceUpdates.clear(); + } + { // flush final EntityTree references to removed entities + std::vector deletedEntities; + tree->swapRemovedEntities(deletedEntities); + { // delete proxies from workload::Space + std::vector deadProxies; + std::unique_lock lock(_spaceLock); + for (auto entity : deletedEntities) { + int32_t spaceIndex = entity->getSpaceIndex(); + disconnect(entity.get(), &EntityItem::spaceUpdate, this, &EntityTreeRenderer::handleSpaceUpdate); + deadProxies.push_back(spaceIndex); + } + _space.deleteProxies(deadProxies); + } + } if (simulate) { // Handle enter/leave entity logic @@ -437,6 +461,11 @@ void EntityTreeRenderer::update(bool simulate) { } } +void EntityTreeRenderer::handleSpaceUpdate(std::pair proxyUpdate) { + std::unique_lock lock(_spaceLock); + _spaceUpdates.push_back(proxyUpdate); +} + bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QVector* entitiesContainingAvatar) { bool didUpdate = false; float radius = 0.01f; // for now, assume 0.01 meter radius, because we actually check the point inside later diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index f5cedfdd01..9602588dc4 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -24,6 +24,7 @@ #include #include #include +#include class AbstractScriptingServicesInterface; class AbstractViewStateInterface; @@ -139,6 +140,10 @@ public slots: EntityRendererPointer renderableForEntityId(const EntityItemID& id) const; render::ItemID renderableIdForEntityId(const EntityItemID& id) const; + //void handleSpaceUpdate(workload::Space::ProxyUpdate proxyUpdate); + void handleSpaceUpdate(std::pair proxyUpdate); + void testSlot(); + protected: virtual OctreePointer createTree() override { EntityTreePointer newTree = EntityTreePointer(new EntityTree(true)); @@ -261,6 +266,10 @@ private: static std::function _entitiesShouldFadeFunction; static std::function _renderDebugHullsOperator; + + mutable std::mutex _spaceLock; + workload::Space _space; + std::vector _spaceUpdates; }; diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index ed902c9f05..b25ec2c10e 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -2364,14 +2364,18 @@ void EntityItem::locationChanged(bool tellPhysics) { tree->entityChanged(getThisPointer()); } } - // TODO: Andrew to connect this to the Space instance in Application SpatiallyNestable::locationChanged(tellPhysics); // tell all the children, also + std::pair data(_spaceIndex, glm::vec4(getWorldPosition(), _boundingRadius)); + emit spaceUpdate(data); somethingChangedNotification(); } void EntityItem::dimensionsChanged() { requiresRecalcBoxes(); SpatiallyNestable::dimensionsChanged(); // Do what you have to do + _boundingRadius = 0.5f * glm::length(getScaledDimensions()); + std::pair data(_spaceIndex, glm::vec4(getWorldPosition(), _boundingRadius)); + emit spaceUpdate(data); somethingChangedNotification(); } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index dbdb762c16..497e1b7836 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -464,6 +464,7 @@ public: virtual bool getMeshes(MeshProxyList& result) { return true; } virtual void locationChanged(bool tellPhysics = true) override; + //void wtf(int32_t i) override; virtual bool getScalesWithParent() const override; @@ -478,6 +479,7 @@ public: void setCauterized(bool value) { _cauterized = value; } bool getCauterized() const { return _cauterized; } + float getBoundingRadius() const { return _boundingRadius; } void setSpaceIndex(int32_t index) { assert(_spaceIndex == -1); _spaceIndex = index; } int32_t getSpaceIndex() const { return _spaceIndex; } @@ -490,6 +492,7 @@ public: signals: void requestRenderUpdate(); + void spaceUpdate(std::pair data); protected: QHash _changeHandlers; @@ -641,6 +644,7 @@ protected: quint64 _lastUpdatedAccelerationTimestamp { 0 }; quint64 _lastUpdatedQueryAACubeTimestamp { 0 }; + float _boundingRadius { 0.0f }; int32_t _spaceIndex { -1 }; // index to proxy in workload::Space bool _cauterized { false }; // if true, don't draw because it would obscure 1st-person camera diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index ad0066af4a..6afe7cc574 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -260,7 +260,7 @@ void EntityTree::postAddEntity(EntityItemPointer entity) { return; } } - + // check to see if we need to simulate this entity.. if (_simulation) { _simulation->addEntity(entity); @@ -271,10 +271,11 @@ void EntityTree::postAddEntity(EntityItemPointer entity) { } _isDirty = true; - emit addingEntity(entity->getEntityItemID()); // find and hook up any entities with this entity as a (previously) missing parent fixupNeedsParentFixups(); + + emit addingEntity(entity->getEntityItemID()); } bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties, const SharedNodePointer& senderNode) { @@ -695,6 +696,11 @@ void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator) if (_simulation) { _simulation->prepareEntityForDelete(theEntity); } + + // We save a pointer to theEntity for external contexts that need it + // but this means: external contexts that remove entities from the tree + // must occasionally swapRemovedEntities() to flush these references. + _removedEntities.push_back(theEntity); } } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 4eb0e15a94..f6130430a2 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -280,7 +280,7 @@ public: void setMyAvatar(std::shared_ptr myAvatar) { _myAvatar = myAvatar; } - void queueUpdateSpaceProxy(int32_t index, const glm::vec4& sphere); + void swapRemovedEntities(std::vector& entities) { entities.swap(_removedEntities); } static void setAddMaterialToEntityOperator(std::function addMaterialToEntityOperator) { _addMaterialToEntityOperator = addMaterialToEntityOperator; } static void setRemoveMaterialFromEntityOperator(std::function removeMaterialFromEntityOperator) { _removeMaterialFromEntityOperator = removeMaterialFromEntityOperator; } @@ -411,6 +411,8 @@ private: static std::function _removeMaterialFromAvatarOperator; static std::function _addMaterialToOverlayOperator; static std::function _removeMaterialFromOverlayOperator; + + std::vector _removedEntities; }; #endif // hifi_EntityTree_h diff --git a/libraries/workload/src/workload/Space.cpp b/libraries/workload/src/workload/Space.cpp index 2c38ec9f8b..3e8b61992e 100644 --- a/libraries/workload/src/workload/Space.cpp +++ b/libraries/workload/src/workload/Space.cpp @@ -40,7 +40,7 @@ void Space::deleteProxies(const std::vector& deadIndices) { } } -void Space::updateProxies(const std::vector >& changedProxies) { +void Space::updateProxies(const std::vector& changedProxies) { for (uint32_t i = 0; i < changedProxies.size(); ++i) { int32_t proxyId = changedProxies[i].first; if (proxyId > -1 && proxyId < (int32_t)_proxies.size()) { diff --git a/libraries/workload/src/workload/Space.h b/libraries/workload/src/workload/Space.h index 3a8dd3c488..3706d45434 100644 --- a/libraries/workload/src/workload/Space.h +++ b/libraries/workload/src/workload/Space.h @@ -29,6 +29,7 @@ public: static const uint8_t REGION_INVALID = 4; using Sphere = glm::vec4; // = center, w = radius + using ProxyUpdate = std::pair; class Proxy { public: @@ -61,7 +62,7 @@ public: int32_t createProxy(const Sphere& sphere); void deleteProxies(const std::vector& deadIndices); - void updateProxies(const std::vector >& changedProxies); + void updateProxies(const std::vector& changedProxies); void setViews(const std::vector& views); uint32_t getNumObjects() const { return (uint32_t)(_proxies.size() - _freeIndices.size()); } From c3d08d06ff3681208c5e9c784a542446dd2127eb Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 20 Feb 2018 17:50:12 -0800 Subject: [PATCH 3/4] remove cruft --- libraries/entities-renderer/src/EntityTreeRenderer.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 9602588dc4..f034353347 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -140,9 +140,7 @@ public slots: EntityRendererPointer renderableForEntityId(const EntityItemID& id) const; render::ItemID renderableIdForEntityId(const EntityItemID& id) const; - //void handleSpaceUpdate(workload::Space::ProxyUpdate proxyUpdate); void handleSpaceUpdate(std::pair proxyUpdate); - void testSlot(); protected: virtual OctreePointer createTree() override { From 9246f6c24a3f279f7bf4399075eb3964788d57af Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 20 Feb 2018 19:15:54 -0800 Subject: [PATCH 4/4] render-perf depdends on workload library --- libraries/entities-renderer/CMakeLists.txt | 3 +-- tests/render-perf/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/libraries/entities-renderer/CMakeLists.txt b/libraries/entities-renderer/CMakeLists.txt index 92f78e357e..083a1716ce 100644 --- a/libraries/entities-renderer/CMakeLists.txt +++ b/libraries/entities-renderer/CMakeLists.txt @@ -1,7 +1,7 @@ set(TARGET_NAME entities-renderer) AUTOSCRIBE_SHADER_LIB(gpu graphics procedural render render-utils) setup_hifi_library(Network Script) -link_hifi_libraries(shared gpu procedural graphics model-networking script-engine render render-utils image qml ui pointers) +link_hifi_libraries(shared workload gpu procedural graphics model-networking script-engine render render-utils image qml ui pointers) include_hifi_library_headers(networking) include_hifi_library_headers(gl) include_hifi_library_headers(ktx) @@ -14,7 +14,6 @@ include_hifi_library_headers(entities) include_hifi_library_headers(avatars) include_hifi_library_headers(controllers) include_hifi_library_headers(task) -include_hifi_library_headers(workload) target_bullet() target_polyvox() diff --git a/tests/render-perf/CMakeLists.txt b/tests/render-perf/CMakeLists.txt index 7e61d9550c..80b9b0eb85 100644 --- a/tests/render-perf/CMakeLists.txt +++ b/tests/render-perf/CMakeLists.txt @@ -13,7 +13,7 @@ set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") # link in the shared libraries link_hifi_libraries( - shared task networking animation + shared task workload networking animation ktx image octree gl gpu gpu-gl render render-utils graphics fbx model-networking