diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 7d130125b3..61aa3b5d2d 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -220,6 +220,7 @@ void EntityTreeRenderer::stopDomainAndNonOwnedEntities() { void EntityTreeRenderer::clearDomainAndNonOwnedEntities() { stopDomainAndNonOwnedEntities(); + auto sessionUUID = getTree()->getMyAvatarSessionUUID(); std::unordered_map savedEntities; // remove all entities from the scene auto scene = _viewState->getMain3DScene(); @@ -227,7 +228,7 @@ void EntityTreeRenderer::clearDomainAndNonOwnedEntities() { for (const auto& entry : _entitiesInScene) { const auto& renderer = entry.second; const EntityItemPointer& entityItem = renderer->getEntity(); - if (!(entityItem->isLocalEntity() || (entityItem->isAvatarEntity() && entityItem->getOwningAvatarID() == getTree()->getMyAvatarSessionUUID()))) { + if (!(entityItem->isLocalEntity() || (entityItem->isAvatarEntity() && entityItem->getOwningAvatarID() == sessionUUID))) { fadeOutRenderable(renderer); } else { savedEntities[entry.first] = entry.second; @@ -238,7 +239,9 @@ void EntityTreeRenderer::clearDomainAndNonOwnedEntities() { _renderablesToUpdate = savedEntities; _entitiesInScene = savedEntities; - _layeredZones.clearNonLocalLayeredZones(); + if (_layeredZones.clearDomainAndNonOwnedZones(sessionUUID)) { + applyLayeredZones(); + } OctreeProcessor::clearDomainAndNonOwnedEntities(); } @@ -271,6 +274,9 @@ void EntityTreeRenderer::clear() { // reset the zone to the default (while we load the next scene) _layeredZones.clear(); + if (!_shuttingDown) { + applyLayeredZones(); + } OctreeProcessor::clear(); } @@ -363,6 +369,7 @@ void EntityTreeRenderer::addPendingEntities(const render::ScenePointer& scene, r for (const auto& processedId : processedIds) { _entitiesToAdd.erase(processedId); } + forceRecheckEntities(); } } } @@ -537,8 +544,7 @@ void EntityTreeRenderer::handleSpaceUpdate(std::pair proxyUp _spaceUpdates.emplace_back(proxyUpdate.first, proxyUpdate.second); } -bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QSet& entitiesContainingAvatar) { - bool didUpdate = false; +void EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QSet& entitiesContainingAvatar) { float radius = 0.01f; // for now, assume 0.01 meter radius, because we actually check the point inside later QVector entityIDs; @@ -550,7 +556,7 @@ bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QSetevalEntitiesInSphere(_avatarPosition, radius, PickFilter(), entityIDs); - LayeredZones oldLayeredZones(std::move(_layeredZones)); + LayeredZones oldLayeredZones(_layeredZones); _layeredZones.clear(); // create a list of entities that actually contain the avatar's position @@ -578,8 +584,8 @@ bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QSetgetVisible() && renderableForEntity(entity)) { - _layeredZones.insert(std::dynamic_pointer_cast(entity)); + if (isZone && entity->getVisible() && renderableIdForEntity(entity) != render::Item::INVALID_ITEM_ID) { + _layeredZones.emplace(std::dynamic_pointer_cast(entity)); } if ((!hasScript && isZone) || scriptHasLoaded) { @@ -588,24 +594,16 @@ bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QSetgetAvatarPosition(); @@ -623,7 +621,7 @@ bool EntityTreeRenderer::checkEnterLeaveEntities() { _forceRecheckEntities = false; QSet entitiesContainingAvatar; - didUpdate = findBestZoneAndMaybeContainingEntities(entitiesContainingAvatar); + findBestZoneAndMaybeContainingEntities(entitiesContainingAvatar); // Note: at this point we don't need to worry about the tree being locked, because we only deal with // EntityItemIDs from here. The callEntityScriptMethod() method is robust against attempting to call scripts @@ -649,7 +647,6 @@ bool EntityTreeRenderer::checkEnterLeaveEntities() { } } } - return didUpdate; } void EntityTreeRenderer::leaveDomainAndNonOwnedEntities() { @@ -696,18 +693,12 @@ bool EntityTreeRenderer::applyLayeredZones() { // in the expected layered order and update the scene with it auto scene = _viewState->getMain3DScene(); if (scene) { - render::Transaction transaction; render::ItemIDs list; - for (auto& zone : _layeredZones) { - auto id = renderableIdForEntity(zone.zone); - // The zone may not have been rendered yet. - if (id != render::Item::INVALID_ITEM_ID) { - list.push_back(id); - } - } - render::Selection selection("RankedZones", list); - transaction.resetSelection(selection); + _layeredZones.appendRenderIDs(list, this); + render::Selection selection("RankedZones", list); + render::Transaction transaction; + transaction.resetSelection(selection); scene->enqueueTransaction(transaction); } else { qCWarning(entitiesrenderer) << "EntityTreeRenderer::applyLayeredZones(), Unexpected null scene, possibly during application shutdown"; @@ -1018,7 +1009,6 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) { } void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) { - forceRecheckEntities(); // reset our state to force checking our inside/outsideness of entities checkAndCallPreload(entityID); auto entity = std::static_pointer_cast(_tree)->findEntityByID(entityID); if (entity) { @@ -1190,107 +1180,96 @@ void EntityTreeRenderer::updateEntityRenderStatus(bool shouldRenderEntities) { } void EntityTreeRenderer::updateZone(const EntityItemID& id) { - // Get in the zone! - auto zone = std::dynamic_pointer_cast(getTree()->findEntityByEntityItemID(id)); - if (zone && zone->contains(_avatarPosition)) { - _layeredZones.update(zone); + if (auto zone = std::dynamic_pointer_cast(getTree()->findEntityByEntityItemID(id))) { + _layeredZones.update(zone, _avatarPosition, this); + applyLayeredZones(); } } -EntityTreeRenderer::LayeredZones::LayeredZones(LayeredZones&& other) { - // In a swap: - // > All iterators and references remain valid. The past-the-end iterator is invalidated. - bool isSkyboxLayerValid = (other._skyboxLayer != other.end()); +bool EntityTreeRenderer::LayeredZones::clearDomainAndNonOwnedZones(const QUuid& sessionUUID) { + bool zonesChanged = false; - swap(other); - _map.swap(other._map); - _skyboxLayer = other._skyboxLayer; + auto it = c.begin(); + while (it != c.end()) { + if (!(it->zone->isLocalEntity() || (it->zone->isAvatarEntity() && it->zone->getOwningAvatarID() == sessionUUID))) { + zonesChanged = true; + it = c.erase(it); + } else { + it++; + } + } - if (!isSkyboxLayerValid) { - _skyboxLayer = end(); + if (zonesChanged) { + std::make_heap(c.begin(), c.end(), comp); + } + return zonesChanged; +} + +std::pair EntityTreeRenderer::LayeredZones::getZoneInteractionProperties() const { + auto it = c.cbegin(); + while (it != c.cend()) { + if (it->zone && it->zone->isDomainEntity()) { + return { it->zone->getFlyingAllowed(), it->zone->getGhostingAllowed() }; + } + it++; + } + return { true, true }; +} + +void EntityTreeRenderer::LayeredZones::remove(const std::shared_ptr& zone) { + auto it = c.begin(); + while (it != c.end()) { + if (it->zone == zone) { + break; + } + it++; + } + if (it != c.end()) { + c.erase(it); + std::make_heap(c.begin(), c.end(), comp); } } -void EntityTreeRenderer::LayeredZones::clearNonLocalLayeredZones() { - std::set localLayeredZones; - std::map newMap; +void EntityTreeRenderer::LayeredZones::update(std::shared_ptr zone, const glm::vec3& position, EntityTreeRenderer* entityTreeRenderer) { + // When a zone's position or visibility changes, we call this method + // In order to resort our zones, we first remove the changed zone, and then re-insert it if necessary + remove(zone); - for (auto iter = begin(); iter != end(); iter++) { - LayeredZone layeredZone = *iter; + // Only call contains if the zone is rendering + if (zone->isVisible() && entityTreeRenderer->renderableIdForEntity(zone) != render::Item::INVALID_ITEM_ID && zone->contains(position)) { + emplace(zone); + } +} - if (layeredZone.zone->isLocalEntity()) { - bool success; - iterator it; - std::tie(it, success) = localLayeredZones.insert(layeredZone); +bool EntityTreeRenderer::LayeredZones::equals(const LayeredZones& other) const { + if (size() != other.size()) { + return false; + } - if (success) { - newMap.emplace(layeredZone.id, it); + auto it = c.cbegin(); + auto otherIt = other.c.cbegin(); + while (it != c.cend()) { + if (*it != *otherIt) { + return false; + } + it++; + otherIt++; + } + + return true; +} + +void EntityTreeRenderer::LayeredZones::appendRenderIDs(render::ItemIDs& list, EntityTreeRenderer* entityTreeRenderer) const { + auto it = c.cbegin(); + while (it != c.cend()) { + if (it->zone) { + auto id = entityTreeRenderer->renderableIdForEntityId(it->id); + if (id != render::Item::INVALID_ITEM_ID) { + list.push_back(id); } } + it++; } - - std::set::operator=(localLayeredZones); - _map = newMap; - _skyboxLayer = empty() ? end() : begin(); -} - -void EntityTreeRenderer::LayeredZones::clear() { - std::set::clear(); - _map.clear(); - _skyboxLayer = end(); -} - -std::pair EntityTreeRenderer::LayeredZones::insert(const LayeredZone& layer) { - iterator it; - bool success; - std::tie(it, success) = std::set::insert(layer); - - if (success) { - _map.emplace(it->id, it); - } - - return { it, success }; -} - -void EntityTreeRenderer::LayeredZones::update(std::shared_ptr zone) { - bool isVisible = zone->isVisible(); - - if (empty() && isVisible) { - // there are no zones: set this one - insert(zone); - return; - } else { - LayeredZone zoneLayer(zone); - - // find this zone's layer, if it exists - iterator layer = end(); - auto it = _map.find(zoneLayer.id); - if (it != _map.end()) { - layer = it->second; - // if the volume changed, we need to resort the layer (reinsertion) - // if the visibility changed, we need to erase the layer - if (zoneLayer.volume != layer->volume || !isVisible) { - erase(layer); - _map.erase(it); - layer = end(); - } - } - - // (re)insert this zone's layer if necessary - if (layer == end() && isVisible) { - std::tie(layer, std::ignore) = insert(zoneLayer); - _map.emplace(layer->id, layer); - } - } -} - -bool EntityTreeRenderer::LayeredZones::contains(const LayeredZones& other) { - bool result = std::equal(other.begin(), other._skyboxLayer, begin()); - if (result) { - // if valid, set the _skyboxLayer from the other LayeredZones - _skyboxLayer = std::next(begin(), std::distance(other.begin(), other._skyboxLayer)); - } - return result; } CalculateEntityLoadingPriority EntityTreeRenderer::_calculateEntityLoadingPriorityFunc = [](const EntityItem& item) -> float { @@ -1298,14 +1277,7 @@ CalculateEntityLoadingPriority EntityTreeRenderer::_calculateEntityLoadingPriori }; std::pair EntityTreeRenderer::getZoneInteractionProperties() { - for (auto& zone : _layeredZones) { - // Only domain entities control flying allowed and ghosting allowed - if (zone.zone && zone.zone->isDomainEntity()) { - return { zone.zone->getFlyingAllowed(), zone.zone->getGhostingAllowed() }; - } - } - - return { true, true }; + return _layeredZones.getZoneInteractionProperties(); } bool EntityTreeRenderer::wantsKeyboardFocus(const EntityItemID& id) const { diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 05105a2c7f..f7f5ae9f22 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -169,7 +169,7 @@ private: void resetEntitiesScriptEngine(); - bool findBestZoneAndMaybeContainingEntities(QSet& entitiesContainingAvatar); + void findBestZoneAndMaybeContainingEntities(QSet& entitiesContainingAvatar); bool applyLayeredZones(); void stopDomainAndNonOwnedEntities(); @@ -180,7 +180,7 @@ private: EntityItemID _currentClickingOnEntityID; QScriptValueList createEntityArgs(const EntityItemID& entityID); - bool checkEnterLeaveEntities(); + void checkEnterLeaveEntities(); void leaveDomainAndNonOwnedEntities(); void leaveAllEntities(); void forceRecheckEntities(); @@ -210,48 +210,38 @@ private: class LayeredZone { public: - LayeredZone(std::shared_ptr zone, QUuid id, float volume) : zone(zone), id(id), volume(volume) {} - LayeredZone(std::shared_ptr zone) : LayeredZone(zone, zone->getID(), zone->getVolumeEstimate()) {} + LayeredZone(std::shared_ptr zone) : zone(zone), id(zone->getID()), volume(zone->getVolumeEstimate()) {} - bool operator<(const LayeredZone& r) const { return std::tie(volume, id) < std::tie(r.volume, r.id); } - bool operator==(const LayeredZone& r) const { return id == r.id; } - bool operator<=(const LayeredZone& r) const { return (*this < r) || (*this == r); } + bool operator>(const LayeredZone& r) const { return volume > r.volume; } + bool operator==(const LayeredZone& r) const { return zone.get() == r.zone.get(); } + bool operator!=(const LayeredZone& r) const { return !(*this == r); } + bool operator>=(const LayeredZone& r) const { return (*this > r) || (*this == r); } std::shared_ptr zone; QUuid id; float volume; }; - class LayeredZones : public std::set { + class LayeredZones : public std::priority_queue, std::greater> { public: - LayeredZones() {}; - LayeredZones(LayeredZones&& other); + void clear() { *this = LayeredZones(); } + bool clearDomainAndNonOwnedZones(const QUuid& sessionUUID); - // avoid accidental misconstruction - LayeredZones(const LayeredZones&) = delete; - LayeredZones& operator=(const LayeredZones&) = delete; - LayeredZones& operator=(LayeredZones&&) = delete; + bool equals(const LayeredZones& other) const; + void remove(const std::shared_ptr& zone); + void update(std::shared_ptr zone, const glm::vec3& position, EntityTreeRenderer* entityTreeRenderer); - void clear(); - void clearNonLocalLayeredZones(); - std::pair insert(const LayeredZone& layer); - void update(std::shared_ptr zone); - bool contains(const LayeredZones& other); - - std::shared_ptr getZone() { return empty() ? nullptr : begin()->zone; } - - private: - std::map _map; - iterator _skyboxLayer { end() }; + void appendRenderIDs(render::ItemIDs& list, EntityTreeRenderer* entityTreeRenderer) const; + std::pair getZoneInteractionProperties() const; }; LayeredZones _layeredZones; - float _avgRenderableUpdateCost { 0.0f }; - uint64_t _lastZoneCheck { 0 }; const uint64_t ZONE_CHECK_INTERVAL = USECS_PER_MSEC * 100; // ~10hz const float ZONE_CHECK_DISTANCE = 0.001f; + float _avgRenderableUpdateCost { 0.0f }; + ReadWriteLockable _changedEntitiesGuard; std::unordered_set _changedEntities; diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 64cca404cb..e4300cca76 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -92,9 +92,7 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) { } { // Sun - // Need an update ? if (_needSunUpdate) { - // Do we need to allocate the light in the stage ? if (LightStage::isIndexInvalid(_sunIndex)) { _sunIndex = _stage->addLight(_sunLight); } else { @@ -107,9 +105,7 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) { { // Ambient updateAmbientMap(); - // Need an update ? if (_needAmbientUpdate) { - // Do we need to allocate the light in the stage ? if (LightStage::isIndexInvalid(_ambientIndex)) { _ambientIndex = _stage->addLight(_ambientLight); } else { @@ -123,7 +119,7 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) { updateSkyboxMap(); if (_needBackgroundUpdate) { - if (_skyboxMode == COMPONENT_MODE_ENABLED && BackgroundStage::isIndexInvalid(_backgroundIndex)) { + if (BackgroundStage::isIndexInvalid(_backgroundIndex)) { _backgroundIndex = _backgroundStage->addBackground(_background); } _needBackgroundUpdate = false; @@ -186,24 +182,19 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) { } } -void ZoneEntityRenderer::removeFromScene(const ScenePointer& scene, Transaction& transaction) { -#if 0 - if (_model) { - _model->removeFromScene(scene, transaction); - } -#endif - Parent::removeFromScene(scene, transaction); -} - void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { - DependencyManager::get()->updateZone(entity->getID()); - auto position = entity->getWorldPosition(); auto rotation = entity->getWorldOrientation(); auto dimensions = entity->getScaledDimensions(); bool rotationChanged = rotation != _lastRotation; bool transformChanged = rotationChanged || position != _lastPosition || dimensions != _lastDimensions; + auto visible = entity->getVisible(); + if (transformChanged || visible != _lastVisible) { + _lastVisible = visible; + DependencyManager::get()->updateZone(entity->getID()); + } + auto proceduralUserData = entity->getUserData(); bool proceduralUserDataChanged = _proceduralUserData != proceduralUserData; @@ -226,25 +217,6 @@ void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen _proceduralUserData = entity->getUserData(); } -#if 0 - if (_lastShapeURL != _typedEntity->getCompoundShapeURL()) { - _lastShapeURL = _typedEntity->getCompoundShapeURL(); - _model.reset(); - _model = std::make_shared(); - _model->setIsWireframe(true); - _model->init(); - _model->setURL(_lastShapeURL); - } - - if (_model && _model->isActive()) { - _model->setScaleToFit(true, _lastDimensions); - _model->setSnapModelToRegistrationPoint(true, _entity->getRegistrationPoint()); - _model->setRotation(_lastRotation); - _model->setTranslation(_lastPosition); - _model->simulate(0.0f); - } -#endif - updateKeyZoneItemFromEntity(entity); if (keyLightChanged) { @@ -296,6 +268,10 @@ ItemKey ZoneEntityRenderer::getKey() { } bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { + if (entity->getVisible() != _lastVisible) { + return true; + } + if (entity->keyLightPropertiesChanged() || entity->ambientLightPropertiesChanged() || entity->hazePropertiesChanged() || @@ -323,25 +299,7 @@ bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoint return true; } -#if 0 - if (_typedEntity->getCompoundShapeURL() != _lastShapeURL) { - return true; - } - - if (_model) { - if (!_model->needsFixupInScene() && (!ZoneEntityItem::getDrawZoneBoundaries() || _entity->getShapeType() != SHAPE_TYPE_COMPOUND)) { - return true; - } - - if (_model->needsFixupInScene() && (ZoneEntityItem::getDrawZoneBoundaries() || _entity->getShapeType() == SHAPE_TYPE_COMPOUND)) { - return true; - } - - if (_lastModelActive != _model->isActive()) { - return true; - } - } -#endif + // FIXME: do we need to trigger an update when shapeType changes? see doRenderUpdateAsynchronousTyped return false; } @@ -450,7 +408,6 @@ void ZoneEntityRenderer::updateKeyZoneItemFromEntity(const TypedEntityPointer& e } void ZoneEntityRenderer::setAmbientURL(const QString& ambientUrl) { - // nothing change if nothing change if (_ambientTextureURL == ambientUrl) { return; } @@ -466,8 +423,6 @@ void ZoneEntityRenderer::setAmbientURL(const QString& ambientUrl) { _pendingAmbientTexture = true; auto textureCache = DependencyManager::get(); _ambientTexture = textureCache->getTexture(_ambientTextureURL, image::TextureUsage::AMBIENT_TEXTURE); - - // keep whatever is assigned on the ambient map/sphere until texture is loaded } } @@ -492,7 +447,6 @@ void ZoneEntityRenderer::updateAmbientMap() { } void ZoneEntityRenderer::setSkyboxURL(const QString& skyboxUrl) { - // nothing change if nothing change if (_skyboxTextureURL == skyboxUrl) { return; } diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h index 2fa55f1540..5fd9b87408 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h @@ -24,9 +24,6 @@ #include "RenderableEntityItem.h" #include -#if 0 -#include -#endif namespace render { namespace entities { class ZoneEntityRenderer : public TypedEntityRenderer { @@ -40,7 +37,6 @@ protected: virtual void onRemoveFromSceneTyped(const TypedEntityPointer& entity) override; virtual ItemKey getKey() override; virtual void doRender(RenderArgs* args) override; - virtual void removeFromScene(const ScenePointer& scene, Transaction& transaction) override; virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; @@ -76,14 +72,7 @@ private: glm::vec3 _lastPosition; glm::vec3 _lastDimensions; glm::quat _lastRotation; - - // FIXME compount shapes are currently broken - // FIXME draw zone boundaries are currently broken (also broken in master) -#if 0 - ModelPointer _model; - bool _lastModelActive { false }; - QString _lastShapeURL; -#endif + bool _lastVisible; LightStagePointer _stage; const graphics::LightPointer _sunLight { std::make_shared() }; @@ -137,25 +126,4 @@ private: } } // namespace -#if 0 - -class NetworkGeometry; -class KeyLightPayload; - -class RenderableZoneEntityItemMeta; - -class RenderableZoneEntityItem : public ZoneEntityItem, public RenderableEntityInterface { -public: - virtual bool contains(const glm::vec3& point) const override; - virtual bool addToScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override; - virtual void removeFromScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override; -private: - virtual void locationChanged(bool tellPhysics = true, bool tellChildren = true) override { EntityItem::locationChanged(tellPhysics, tellChildren); notifyBoundChanged(); } - virtual void dimensionsChanged() override { EntityItem::dimensionsChanged(); notifyBoundChanged(); } - void notifyBoundChanged(); - void notifyChangedRenderItem(); - void sceneUpdateRenderItemFromEntity(render::Transaction& transaction); -}; -#endif - #endif // hifi_RenderableZoneEntityItem_h diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index 0e9672a7f2..8403d87868 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -43,7 +43,7 @@ const Selection::Name ZoneRendererTask::ZONES_SELECTION { "RankedZones" }; void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& output) { // Filter out the sorted list of zones - const auto zoneItems = task.addJob("FilterZones", input, ZONES_SELECTION.c_str()); + const auto zoneItems = task.addJob("FilterZones", input, ZONES_SELECTION); // just setup the current zone env task.addJob("SetupZones", zoneItems); diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index 4f6fe3e36a..ff848aa464 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -277,6 +277,9 @@ void Scene::processTransactionFrame(const Transaction& transaction) { // removes removeItems(transaction._removedItems); + // handle selections + resetSelections(transaction._resetSelections); + // add transitions transitionItems(transaction._addedTransitions); reApplyTransitions(transaction._reAppliedTransitions); @@ -287,13 +290,6 @@ void Scene::processTransactionFrame(const Transaction& transaction) { _numAllocatedItems.exchange(maxID); } - if (transaction.touchTransactions()) { - std::unique_lock lock(_selectionsMutex); - - // resets and potential NEW items - resetSelections(transaction._resetSelections); - } - resetHighlights(transaction._highlightResets); removeHighlights(transaction._highlightRemoves); queryHighlights(transaction._highlightQueries); @@ -581,35 +577,34 @@ void Scene::resetItemTransition(ItemID itemId) { } } -// This function is thread safe Selection Scene::getSelection(const Selection::Name& name) const { std::unique_lock lock(_selectionsMutex); auto found = _selections.find(name); if (found == _selections.end()) { return Selection(); } else { - return (*found).second; + return found->second; } } -// This function is thread safe bool Scene::isSelectionEmpty(const Selection::Name& name) const { std::unique_lock lock(_selectionsMutex); auto found = _selections.find(name); if (found == _selections.end()) { return true; } else { - return (*found).second.isEmpty(); + return found->second.isEmpty(); } } void Scene::resetSelections(const Transaction::SelectionResets& transactions) { + std::unique_lock lock(_selectionsMutex); for (auto selection : transactions) { auto found = _selections.find(selection.getName()); if (found == _selections.end()) { - _selections.insert(SelectionMap::value_type(selection.getName(), selection)); + _selections[selection.getName()] = selection; } else { - (*found).second = selection; + found->second = selection; } } } diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index 08fbf33bcd..5f4a209b66 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -78,9 +78,6 @@ public: void merge(Transaction&& transaction); void clear(); - // Checkers if there is work to do when processing the transaction - bool touchTransactions() const { return !_resetSelections.empty(); } - protected: using Reset = std::tuple; diff --git a/libraries/render/src/render/Selection.h b/libraries/render/src/render/Selection.h index 2c7ce710cd..05b2395b42 100644 --- a/libraries/render/src/render/Selection.h +++ b/libraries/render/src/render/Selection.h @@ -45,9 +45,8 @@ namespace render { Name _name; ItemIDs _items; }; - using Selections = std::vector; - using SelectionMap = std::map; + using SelectionMap = std::unordered_map; }