diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 15ae1584f6..c25aaeeecd 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1111,7 +1111,7 @@ void MyAvatar::setEnableDebugDrawIKChains(bool isEnabled) { } void MyAvatar::setEnableMeshVisible(bool isEnabled) { - _skeletonModel->setVisibleInScene(isEnabled, qApp->getMain3DScene(), render::ItemKey::TAG_BITS_NONE); + _skeletonModel->setVisibleInScene(isEnabled, qApp->getMain3DScene(), render::ItemKey::TAG_BITS_NONE, true); } void MyAvatar::setEnableInverseKinematics(bool isEnabled) { @@ -1463,7 +1463,7 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { _skeletonModelChangeCount++; int skeletonModelChangeCount = _skeletonModelChangeCount; Avatar::setSkeletonModelURL(skeletonModelURL); - _skeletonModel->setVisibleInScene(true, qApp->getMain3DScene(), render::ItemKey::TAG_BITS_NONE); + _skeletonModel->setVisibleInScene(true, qApp->getMain3DScene(), render::ItemKey::TAG_BITS_NONE, true); _headBoneSet.clear(); _cauterizationNeedsUpdate = true; @@ -1821,7 +1821,7 @@ void MyAvatar::attach(const QString& modelURL, const QString& jointName, void MyAvatar::setVisibleInSceneIfReady(Model* model, const render::ScenePointer& scene, bool visible) { if (model->isActive() && model->isRenderable()) { - model->setVisibleInScene(visible, scene, render::ItemKey::TAG_BITS_NONE); + model->setVisibleInScene(visible, scene, render::ItemKey::TAG_BITS_NONE, true); } } @@ -2015,7 +2015,7 @@ void MyAvatar::preDisplaySide(RenderArgs* renderArgs) { _attachmentData[i].jointName.compare("HeadTop_End", Qt::CaseInsensitive) == 0 || _attachmentData[i].jointName.compare("Face", Qt::CaseInsensitive) == 0) { _attachmentModels[i]->setVisibleInScene(shouldDrawHead, qApp->getMain3DScene(), - render::ItemKey::TAG_BITS_NONE); + render::ItemKey::TAG_BITS_NONE, true); } } } diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 4847650163..2b2c1403ff 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -87,7 +87,7 @@ void ModelOverlay::update(float deltatime) { if (_visibleDirty) { _visibleDirty = false; // don't show overlays in mirrors - _model->setVisibleInScene(getVisible(), scene, render::ItemKey::TAG_BITS_0); + _model->setVisibleInScene(getVisible(), scene, render::ItemKey::TAG_BITS_0, false); } if (_drawInFrontDirty) { _drawInFrontDirty = false; diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 86635cd3bf..a2a23f2508 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -50,7 +50,7 @@ const glm::vec3 HAND_TO_PALM_OFFSET(0.0f, 0.12f, 0.08f); namespace render { template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar) { - return ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(ItemKey::TAG_BITS_0 | ItemKey::TAG_BITS_1); + return ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(ItemKey::TAG_BITS_0 | ItemKey::TAG_BITS_1).withMetaCullGroup(); } template <> const Item::Bound payloadGetBound(const AvatarSharedPointer& avatar) { return static_pointer_cast(avatar)->getBounds(); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index ca15382c71..56e3f96014 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1352,7 +1352,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce // FIXME: this seems like it could be optimized if we tracked our last known visible state in // the renderable item. As it stands now the model checks it's visible/invisible state // so most of the time we don't do anything in this function. - model->setVisibleInScene(_visible, scene, viewTaskBits); + model->setVisibleInScene(_visible, scene, viewTaskBits, false); } // TODO? early exit here when not visible? diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 9655b60a78..da11535396 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -71,7 +71,7 @@ void MeshPartPayload::updateMaterial(graphics::MaterialPointer drawMaterial) { _drawMaterial = drawMaterial; } -void MeshPartPayload::updateKey(bool isVisible, bool isLayered, uint8_t tagBits) { +void MeshPartPayload::updateKey(bool isVisible, bool isLayered, uint8_t tagBits, bool isGroupCulled) { ItemKey::Builder builder; builder.withTypeShape(); @@ -85,6 +85,10 @@ void MeshPartPayload::updateKey(bool isVisible, bool isLayered, uint8_t tagBits) builder.withLayered(); } + if (isGroupCulled) { + builder.withSubMetaCulled(); + } + if (_drawMaterial) { auto matKey = _drawMaterial->getKey(); if (matKey.isTranslucent()) { @@ -403,7 +407,7 @@ void ModelMeshPartPayload::updateTransformForSkinnedMesh(const Transform& render _worldBound.transform(boundTransform); } -void ModelMeshPartPayload::updateKey(bool isVisible, bool isLayered, uint8_t tagBits) { +void ModelMeshPartPayload::updateKey(bool isVisible, bool isLayered, uint8_t tagBits, bool isGroupCulled) { ItemKey::Builder builder; builder.withTypeShape(); @@ -417,6 +421,10 @@ void ModelMeshPartPayload::updateKey(bool isVisible, bool isLayered, uint8_t tag builder.withLayered(); } + if (isGroupCulled) { + builder.withSubMetaCulled(); + } + if (_isBlendShaped || _isSkinned) { builder.withDeformed(); } diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h index 21f9dc2e68..40efc67572 100644 --- a/libraries/render-utils/src/MeshPartPayload.h +++ b/libraries/render-utils/src/MeshPartPayload.h @@ -33,7 +33,7 @@ public: typedef render::Payload Payload; typedef Payload::DataPointer Pointer; - virtual void updateKey(bool isVisible, bool isLayered, uint8_t tagBits); + virtual void updateKey(bool isVisible, bool isLayered, uint8_t tagBits, bool isGroupCulled = false); virtual void updateMeshPart(const std::shared_ptr& drawMesh, int partIndex); @@ -99,7 +99,7 @@ public: using TransformType = glm::mat4; #endif - void updateKey(bool isVisible, bool isLayered, uint8_t tagBits) override; + void updateKey(bool isVisible, bool isLayered, uint8_t tagBits, bool isGroupCulled = false) override; void updateClusterBuffer(const std::vector& clusterTransforms); void updateTransformForSkinnedMesh(const Transform& renderTransform, const Transform& boundTransform); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index b9ccc28c01..bb8353c746 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -271,6 +271,7 @@ void Model::updateRenderItems() { uint8_t viewTagBits = self->getViewTagBits(); bool isLayeredInFront = self->isLayeredInFront(); bool isLayeredInHUD = self->isLayeredInHUD(); + bool isGroupCulled = self->isGroupCulled(); render::Transaction transaction; for (int i = 0; i < (int) self->_modelMeshRenderItemIDs.size(); i++) { @@ -284,7 +285,7 @@ void Model::updateRenderItems() { transaction.updateItem(itemID, [modelTransform, clusterTransforms, invalidatePayloadShapeKey, isWireframe, isVisible, viewTagBits, isLayeredInFront, - isLayeredInHUD](ModelMeshPartPayload& data) { + isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) { data.updateClusterBuffer(clusterTransforms); Transform renderTransform = modelTransform; @@ -300,7 +301,7 @@ void Model::updateRenderItems() { } data.updateTransformForSkinnedMesh(renderTransform, modelTransform); - data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits); + data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits, isGroupCulled); data.setLayer(isLayeredInFront, isLayeredInHUD); data.setShapeKey(invalidatePayloadShapeKey, isWireframe); }); @@ -684,10 +685,11 @@ void Model::calculateTriangleSets() { } } -void Model::setVisibleInScene(bool isVisible, const render::ScenePointer& scene, uint8_t viewTagBits) { - if (_isVisible != isVisible || _viewTagBits != viewTagBits) { +void Model::setVisibleInScene(bool isVisible, const render::ScenePointer& scene, uint8_t viewTagBits, bool isGroupCulled) { + if (_isVisible != isVisible || _viewTagBits != viewTagBits || _isGroupCulled != isGroupCulled) { _isVisible = isVisible; _viewTagBits = viewTagBits; + _isGroupCulled = isGroupCulled; bool isLayeredInFront = _isLayeredInFront; bool isLayeredInHUD = _isLayeredInHUD; @@ -695,14 +697,14 @@ void Model::setVisibleInScene(bool isVisible, const render::ScenePointer& scene, render::Transaction transaction; foreach (auto item, _modelMeshRenderItemsMap.keys()) { transaction.updateItem(item, [isVisible, viewTagBits, isLayeredInFront, - isLayeredInHUD](ModelMeshPartPayload& data) { - data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits); + isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) { + data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits, isGroupCulled); }); } foreach(auto item, _collisionRenderItemsMap.keys()) { transaction.updateItem(item, [isVisible, viewTagBits, isLayeredInFront, - isLayeredInHUD](ModelMeshPartPayload& data) { - data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits); + isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) { + data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits, isGroupCulled); }); } scene->enqueueTransaction(transaction); @@ -717,19 +719,20 @@ void Model::setLayeredInFront(bool isLayeredInFront, const render::ScenePointer& bool isVisible = _isVisible; uint8_t viewTagBits = _viewTagBits; bool isLayeredInHUD = _isLayeredInHUD; + bool isGroupCulled = _isGroupCulled; render::Transaction transaction; foreach(auto item, _modelMeshRenderItemsMap.keys()) { transaction.updateItem(item, [isVisible, viewTagBits, isLayeredInFront, - isLayeredInHUD](ModelMeshPartPayload& data) { - data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits); + isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) { + data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits, isGroupCulled); data.setLayer(isLayeredInFront, isLayeredInHUD); }); } foreach(auto item, _collisionRenderItemsMap.keys()) { transaction.updateItem(item, [isVisible, viewTagBits, isLayeredInFront, - isLayeredInHUD](ModelMeshPartPayload& data) { - data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits); + isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) { + data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits, isGroupCulled); data.setLayer(isLayeredInFront, isLayeredInHUD); }); } @@ -744,19 +747,20 @@ void Model::setLayeredInHUD(bool isLayeredInHUD, const render::ScenePointer& sce bool isVisible = _isVisible; uint8_t viewTagBits = _viewTagBits; bool isLayeredInFront = _isLayeredInFront; + bool isGroupCulled = _isGroupCulled; render::Transaction transaction; foreach(auto item, _modelMeshRenderItemsMap.keys()) { transaction.updateItem(item, [isVisible, viewTagBits, isLayeredInFront, - isLayeredInHUD](ModelMeshPartPayload& data) { - data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits); + isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) { + data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits, isGroupCulled); data.setLayer(isLayeredInFront, isLayeredInHUD); }); } foreach(auto item, _collisionRenderItemsMap.keys()) { transaction.updateItem(item, [isVisible, viewTagBits, isLayeredInFront, - isLayeredInHUD](ModelMeshPartPayload& data) { - data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits); + isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) { + data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits, isGroupCulled); data.setLayer(isLayeredInFront, isLayeredInHUD); }); } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index ca0904f334..57d2798a66 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -86,7 +86,7 @@ public: const QUrl& getURL() const { return _url; } // new Scene/Engine rendering support - void setVisibleInScene(bool isVisible, const render::ScenePointer& scene, uint8_t viewTagBits); + void setVisibleInScene(bool isVisible, const render::ScenePointer& scene, uint8_t viewTagBits, bool isGroupCulled); void setLayeredInFront(bool isLayeredInFront, const render::ScenePointer& scene); void setLayeredInHUD(bool isLayeredInHUD, const render::ScenePointer& scene); bool needsFixupInScene() const; @@ -109,6 +109,8 @@ public: bool isLayeredInFront() const { return _isLayeredInFront; } bool isLayeredInHUD() const { return _isLayeredInHUD; } + bool isGroupCulled() const { return _isGroupCulled; } + virtual void updateRenderItems(); void setRenderItemsNeedUpdate(); bool getRenderItemsNeedUpdate() { return _renderItemsNeedUpdate; } @@ -462,6 +464,8 @@ protected: bool _isLayeredInFront { false }; bool _isLayeredInHUD { false }; + bool _isGroupCulled{ false }; + bool shouldInvalidatePayloadShapeKey(int meshIndex); private: diff --git a/libraries/render/src/render/CullTask.cpp b/libraries/render/src/render/CullTask.cpp index 4dec3030ef..f04427540a 100644 --- a/libraries/render/src/render/CullTask.cpp +++ b/libraries/render/src/render/CullTask.cpp @@ -211,13 +211,14 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext, outItems.clear(); outItems.reserve(inSelection.numItems()); - const auto filter = inputs.get1(); - if (!filter.selectsNothing()) { - // Now get the bound, and + const auto srcFilter = inputs.get1(); + if (!srcFilter.selectsNothing()) { + auto filter = render::ItemFilter::Builder(srcFilter).withoutSubMetaCulled().build(); + + // Now get the bound, and // filter individually against the _filter // visibility cull if partially selected ( octree cell contianing it was partial) // distance cull if was a subcell item ( octree cell is way bigger than the item bound itself, so now need to test per item) - if (_skipCulling) { // inside & fit items: filter only, culling is disabled { @@ -227,6 +228,9 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext, if (filter.test(item.getKey())) { ItemBound itemBound(id, item.getBound()); outItems.emplace_back(itemBound); + if (item.getKey().isMetaCullGroup()) { + item.fetchMetaSubItemBounds(outItems, (*scene)); + } } } } @@ -239,6 +243,9 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext, if (filter.test(item.getKey())) { ItemBound itemBound(id, item.getBound()); outItems.emplace_back(itemBound); + if (item.getKey().isMetaCullGroup()) { + item.fetchMetaSubItemBounds(outItems, (*scene)); + } } } } @@ -251,6 +258,9 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext, if (filter.test(item.getKey())) { ItemBound itemBound(id, item.getBound()); outItems.emplace_back(itemBound); + if (item.getKey().isMetaCullGroup()) { + item.fetchMetaSubItemBounds(outItems, (*scene)); + } } } } @@ -263,6 +273,9 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext, if (filter.test(item.getKey())) { ItemBound itemBound(id, item.getBound()); outItems.emplace_back(itemBound); + if (item.getKey().isMetaCullGroup()) { + item.fetchMetaSubItemBounds(outItems, (*scene)); + } } } } @@ -277,6 +290,9 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext, if (filter.test(item.getKey())) { ItemBound itemBound(id, item.getBound()); outItems.emplace_back(itemBound); + if (item.getKey().isMetaCullGroup()) { + item.fetchMetaSubItemBounds(outItems, (*scene)); + } } } } @@ -290,6 +306,9 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext, ItemBound itemBound(id, item.getBound()); if (test.solidAngleTest(itemBound.bound)) { outItems.emplace_back(itemBound); + if (item.getKey().isMetaCullGroup()) { + item.fetchMetaSubItemBounds(outItems, (*scene)); + } } } } @@ -304,6 +323,9 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext, ItemBound itemBound(id, item.getBound()); if (test.frustumTest(itemBound.bound)) { outItems.emplace_back(itemBound); + if (item.getKey().isMetaCullGroup()) { + item.fetchMetaSubItemBounds(outItems, (*scene)); + } } } } @@ -319,6 +341,9 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext, if (test.frustumTest(itemBound.bound)) { if (test.solidAngleTest(itemBound.bound)) { outItems.emplace_back(itemBound); + if (item.getKey().isMetaCullGroup()) { + item.fetchMetaSubItemBounds(outItems, (*scene)); + } } } } diff --git a/libraries/render/src/render/Item.cpp b/libraries/render/src/render/Item.cpp index 612dba076b..ed052adf6e 100644 --- a/libraries/render/src/render/Item.cpp +++ b/libraries/render/src/render/Item.cpp @@ -113,6 +113,21 @@ const ShapeKey Item::getShapeKey() const { return shapeKey; } +uint32_t Item::fetchMetaSubItemBounds(ItemBounds& subItemBounds, Scene& scene) const { + ItemIDs subItems; + auto numSubs = fetchMetaSubItems(subItems); + + for (auto id : subItems) { + auto& item = scene.getItem(id); + if (item.exist()) { + subItemBounds.emplace_back(id, item.getBound()); + } else { + numSubs--; + } + } + return numSubs; +} + namespace render { template <> const ItemKey payloadGetKey(const PayloadProxyInterface::Pointer& payload) { if (!payload) { diff --git a/libraries/render/src/render/Item.h b/libraries/render/src/render/Item.h index ff4b3a0458..e4dcc7ee03 100644 --- a/libraries/render/src/render/Item.h +++ b/libraries/render/src/render/Item.h @@ -78,6 +78,8 @@ public: INVISIBLE, // Visible or not in the scene? SHADOW_CASTER, // Item cast shadows LAYERED, // Item belongs to one of the layers different from the default layer + META_CULL_GROUP, // As a meta item, the culling of my sub items is based solely on my bounding box and my visibility in the view + SUB_META_CULLED, // As a sub item of a meta render item set as cull group, need to be set to my culling to the meta render it FIRST_TAG_BIT, // 8 Tags available to organize the items and filter them against LAST_TAG_BIT = FIRST_TAG_BIT + NUM_TAGS, @@ -122,6 +124,8 @@ public: Builder& withInvisible() { _flags.set(INVISIBLE); return (*this); } Builder& withShadowCaster() { _flags.set(SHADOW_CASTER); return (*this); } Builder& withLayered() { _flags.set(LAYERED); return (*this); } + Builder& withMetaCullGroup() { _flags.set(META_CULL_GROUP); return (*this); } + Builder& withSubMetaCulled() { _flags.set(SUB_META_CULLED); return (*this); } Builder& withTag(Tag tag) { _flags.set(FIRST_TAG_BIT + tag); return (*this); } // Set ALL the tags in one call using the Tag bits @@ -159,6 +163,12 @@ public: bool isLayered() const { return _flags[LAYERED]; } bool isSpatial() const { return !isLayered(); } + bool isMetaCullGroup() const { return _flags[META_CULL_GROUP]; } + void setMetaCullGroup(bool cullGroup) { (cullGroup ? _flags.set(META_CULL_GROUP) : _flags.reset(META_CULL_GROUP)); } + + bool isSubMetaCulled() const { return _flags[SUB_META_CULLED]; } + void setSubMetaCulled(bool metaCulled) { (metaCulled ? _flags.set(SUB_META_CULLED) : _flags.reset(SUB_META_CULLED)); } + bool isTag(Tag tag) const { return _flags[FIRST_TAG_BIT + tag]; } uint8_t getTagBits() const { return ((_flags.to_ulong() & KEY_TAG_BITS_MASK) >> FIRST_TAG_BIT); } @@ -193,6 +203,7 @@ public: ItemKey::Flags _mask{ 0 }; public: Builder() {} + Builder(const ItemFilter& srcFilter) : _value(srcFilter._value), _mask(srcFilter._mask) {} ItemFilter build() const { return ItemFilter(_value, _mask); } @@ -221,6 +232,12 @@ public: Builder& withoutLayered() { _value.reset(ItemKey::LAYERED); _mask.set(ItemKey::LAYERED); return (*this); } Builder& withLayered() { _value.set(ItemKey::LAYERED); _mask.set(ItemKey::LAYERED); return (*this); } + Builder& withoutMetaCullGroup() { _value.reset(ItemKey::META_CULL_GROUP); _mask.set(ItemKey::META_CULL_GROUP); return (*this); } + Builder& withMetaCullGroup() { _value.set(ItemKey::META_CULL_GROUP); _mask.set(ItemKey::META_CULL_GROUP); return (*this); } + + Builder& withoutSubMetaCulled() { _value.reset(ItemKey::SUB_META_CULLED); _mask.set(ItemKey::SUB_META_CULLED); return (*this); } + Builder& withSubMetaCulled() { _value.set(ItemKey::SUB_META_CULLED); _mask.set(ItemKey::SUB_META_CULLED); return (*this); } + Builder& withoutTag(ItemKey::Tag tagIndex) { _value.reset(ItemKey::FIRST_TAG_BIT + tagIndex); _mask.set(ItemKey::FIRST_TAG_BIT + tagIndex); return (*this); } Builder& withTag(ItemKey::Tag tagIndex) { _value.set(ItemKey::FIRST_TAG_BIT + tagIndex); _mask.set(ItemKey::FIRST_TAG_BIT + tagIndex); return (*this); } // Set ALL the tags in one call using the Tag bits and the Tag bits touched @@ -420,6 +437,7 @@ public: // Meta Type Interface uint32_t fetchMetaSubItems(ItemIDs& subItems) const { return _payload->fetchMetaSubItems(subItems); } + uint32_t fetchMetaSubItemBounds(ItemBounds& subItemBounds, Scene& scene) const; // Access the status const StatusPointer& getStatus() const { return _payload->getStatus(); } diff --git a/libraries/render/src/render/RenderFetchCullSortTask.cpp b/libraries/render/src/render/RenderFetchCullSortTask.cpp index 6fb9ba88aa..7b9765dca1 100644 --- a/libraries/render/src/render/RenderFetchCullSortTask.cpp +++ b/libraries/render/src/render/RenderFetchCullSortTask.cpp @@ -30,7 +30,7 @@ void RenderFetchCullSortTask::build(JobModel& task, const Varying& input, Varyin const auto culledSpatialSelection = task.addJob("CullSceneSelection", cullInputs, cullFunctor, RenderDetails::ITEM); // Overlays are not culled - const ItemFilter overlayfilter = ItemFilter::Builder().withVisible().withTagBits(tagBits, tagMask); + const ItemFilter overlayfilter = ItemFilter::Builder().withVisible().withoutSubMetaCulled().withTagBits(tagBits, tagMask); const auto nonspatialFilter = render::Varying(overlayfilter); const auto nonspatialSelection = task.addJob("FetchOverlaySelection", nonspatialFilter);