From d99af64410f6fac8fa05f516fd061373ee74f3a5 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 29 Apr 2019 11:07:36 -0700 Subject: [PATCH 1/4] fix wearables not disappearing with avatar --- .../src/avatars-renderer/Avatar.cpp | 19 ++++++++++++++++++- .../src/avatars-renderer/Avatar.h | 2 +- libraries/render/src/render/Item.cpp | 6 +++++- libraries/render/src/render/Item.h | 6 ++++++ 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 204ed79660..0f11b13101 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -2111,6 +2111,7 @@ void Avatar::updateAttachmentRenderIDs() { void Avatar::updateDescendantRenderIDs() { _subItemLock.withWriteLock([&] { + auto oldDescendantRenderIDs = _descendantRenderIDs; _descendantRenderIDs.clear(); auto entityTreeRenderer = DependencyManager::get(); EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr; @@ -2125,13 +2126,29 @@ void Avatar::updateDescendantRenderIDs() { render::ItemIDs renderableSubItems; uint32_t numRenderableSubItems = renderer->metaFetchMetaSubItems(renderableSubItems); if (numRenderableSubItems > 0) { - _descendantRenderIDs.insert(_descendantRenderIDs.end(), renderableSubItems.begin(), renderableSubItems.end()); + for (auto& renderID : renderableSubItems) { + _descendantRenderIDs.insert(renderID); + oldDescendantRenderIDs.erase(renderID); + } } } } } }); }); + + render::Transaction transaction; + for (auto& oldDescendantRenderID : oldDescendantRenderIDs) { + transaction.updateItem(oldDescendantRenderID, [](render::PayloadProxyInterface& self) { + self.setOverrideSubMetaCulled(false); + }); + } + for (auto& descendantRenderIDs : _descendantRenderIDs) { + transaction.updateItem(descendantRenderIDs, [](render::PayloadProxyInterface& self) { + self.setOverrideSubMetaCulled(true); + }); + } + AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); } }); } diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index a196c018d2..3820309f17 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -776,7 +776,7 @@ protected: void updateAttachmentRenderIDs(); render::ItemIDs _attachmentRenderIDs; void updateDescendantRenderIDs(); - render::ItemIDs _descendantRenderIDs; + render::ItemIDSet _descendantRenderIDs; uint32_t _lastAncestorChainRenderableVersion { 0 }; }; diff --git a/libraries/render/src/render/Item.cpp b/libraries/render/src/render/Item.cpp index 532964777f..d5dde7f86b 100644 --- a/libraries/render/src/render/Item.cpp +++ b/libraries/render/src/render/Item.cpp @@ -123,7 +123,11 @@ namespace render { if (!payload) { return ItemKey::Builder::opaqueShape().withTypeMeta(); } - return payload->getKey(); + if (payload->overrideSubMetaCulled()) { + return ItemKey::Builder(payload->getKey()).withSubMetaCulled(); + } else { + return payload->getKey(); + } } template <> const ShapeKey shapeGetShapeKey(const PayloadProxyInterface::Pointer& payload) { diff --git a/libraries/render/src/render/Item.h b/libraries/render/src/render/Item.h index 79557e3e44..e3f10365db 100644 --- a/libraries/render/src/render/Item.h +++ b/libraries/render/src/render/Item.h @@ -599,6 +599,12 @@ public: virtual Item::Bound getBound() = 0; virtual void render(RenderArgs* args) = 0; virtual uint32_t metaFetchMetaSubItems(ItemIDs& subItems) = 0; + + bool overrideSubMetaCulled() const { return _overrideSubMetaCulled; } + void setOverrideSubMetaCulled(bool overrideSubMetaCulled) { _overrideSubMetaCulled = overrideSubMetaCulled; } + +protected: + bool _overrideSubMetaCulled { false }; }; template <> const ItemKey payloadGetKey(const PayloadProxyInterface::Pointer& payload); From 0bcd8b81e138e6f47e0f0a7690bc9c5c94e006cf Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 30 Apr 2019 10:31:09 -0700 Subject: [PATCH 2/4] trying and failing to fix models --- .../src/avatars-renderer/Avatar.cpp | 35 +++++++++---------- .../src/avatars-renderer/Avatar.h | 3 +- .../src/RenderableEntityItem.cpp | 15 +++++--- .../src/RenderableEntityItem.h | 4 ++- .../src/RenderableMaterialEntityItem.cpp | 3 +- .../src/RenderableModelEntityItem.cpp | 12 ++++++- .../src/RenderableModelEntityItem.h | 1 + .../RenderableParticleEffectEntityItem.cpp | 14 +++++--- .../src/RenderablePolyLineEntityItem.cpp | 9 ++++- .../src/RenderablePolyVoxEntityItem.cpp | 10 ++++++ .../src/RenderablePolyVoxEntityItem.h | 2 +- libraries/entities/src/EntityItem.cpp | 11 ++++++ libraries/entities/src/EntityItem.h | 5 +++ .../render-utils/src/MeshPartPayload.cpp | 8 +++++ libraries/render-utils/src/MeshPartPayload.h | 7 ++-- libraries/render-utils/src/Model.cpp | 16 ++++++++- libraries/render-utils/src/Model.h | 3 ++ libraries/render/src/render/Item.cpp | 6 +--- libraries/render/src/render/Item.h | 8 +---- 19 files changed, 122 insertions(+), 50 deletions(-) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 0f11b13101..c44b88cbf6 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -2111,7 +2111,8 @@ void Avatar::updateAttachmentRenderIDs() { void Avatar::updateDescendantRenderIDs() { _subItemLock.withWriteLock([&] { - auto oldDescendantRenderIDs = _descendantRenderIDs; + auto oldRenderingDescendantEntityIDs = _renderingDescendantEntityIDs; + _renderingDescendantEntityIDs.clear(); _descendantRenderIDs.clear(); auto entityTreeRenderer = DependencyManager::get(); EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr; @@ -2121,34 +2122,30 @@ void Avatar::updateDescendantRenderIDs() { if (object && object->getNestableType() == NestableType::Entity) { EntityItemPointer entity = std::static_pointer_cast(object); if (entity->isVisible()) { - auto renderer = entityTreeRenderer->renderableForEntityId(object->getID()); + auto id = object->getID(); + _renderingDescendantEntityIDs.insert(id); + oldRenderingDescendantEntityIDs.erase(id); + entity->setCullWithParent(true); + + auto renderer = entityTreeRenderer->renderableForEntityId(id); if (renderer) { render::ItemIDs renderableSubItems; uint32_t numRenderableSubItems = renderer->metaFetchMetaSubItems(renderableSubItems); if (numRenderableSubItems > 0) { - for (auto& renderID : renderableSubItems) { - _descendantRenderIDs.insert(renderID); - oldDescendantRenderIDs.erase(renderID); - } + _descendantRenderIDs.insert(_descendantRenderIDs.end(), renderableSubItems.begin(), renderableSubItems.end()); } } } } }); - }); - render::Transaction transaction; - for (auto& oldDescendantRenderID : oldDescendantRenderIDs) { - transaction.updateItem(oldDescendantRenderID, [](render::PayloadProxyInterface& self) { - self.setOverrideSubMetaCulled(false); - }); - } - for (auto& descendantRenderIDs : _descendantRenderIDs) { - transaction.updateItem(descendantRenderIDs, [](render::PayloadProxyInterface& self) { - self.setOverrideSubMetaCulled(true); - }); - } - AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); + for (auto& oldRenderingDescendantEntityID : oldRenderingDescendantEntityIDs) { + auto entity = entityTree->findEntityByEntityItemID(oldRenderingDescendantEntityID); + if (entity) { + entity->setCullWithParent(false); + } + } + }); } }); } diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index 3820309f17..890cd78bb8 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -776,7 +776,8 @@ protected: void updateAttachmentRenderIDs(); render::ItemIDs _attachmentRenderIDs; void updateDescendantRenderIDs(); - render::ItemIDSet _descendantRenderIDs; + render::ItemIDs _descendantRenderIDs; + std::unordered_set _renderingDescendantEntityIDs; uint32_t _lastAncestorChainRenderableVersion { 0 }; }; diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index fb6fbad2ac..184ac60524 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -186,16 +186,20 @@ render::hifi::Layer EntityRenderer::getHifiRenderLayer() const { } ItemKey EntityRenderer::getKey() { + auto builder = ItemKey::Builder().withTypeShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); if (isTransparent()) { - return ItemKey::Builder::transparentShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); + builder.withTransparent(); } - // This allows shapes to cast shadows if (_canCastShadow) { - return ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(getTagMask()).withShadowCaster().withLayer(getHifiRenderLayer()); - } else { - return ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); + builder.withShadowCaster(); } + + if (_cullWithParent) { + builder.withSubMetaCulled(); + } + + return builder.build(); } uint32_t EntityRenderer::metaFetchMetaSubItems(ItemIDs& subItems) { @@ -430,6 +434,7 @@ void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transa setRenderLayer(entity->getRenderLayer()); setPrimitiveMode(entity->getPrimitiveMode()); _canCastShadow = entity->getCanCastShadow(); + setCullWithParent(entity->getCullWithParent()); _cauterized = entity->getCauterized(); _needsRenderUpdate = false; }); diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index 39f9ad091e..0d4ea93fd9 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -107,7 +107,8 @@ protected: virtual void setIsVisibleInSecondaryCamera(bool value) { _isVisibleInSecondaryCamera = value; } virtual void setRenderLayer(RenderLayer value) { _renderLayer = value; } virtual void setPrimitiveMode(PrimitiveMode value) { _primitiveMode = value; } - + virtual void setCullWithParent(bool value) { _cullWithParent = value; } + template T withReadLockResult(const std::function& f) { T result; @@ -139,6 +140,7 @@ protected: bool _visible { false }; bool _isVisibleInSecondaryCamera { false }; bool _canCastShadow { false }; + bool _cullWithParent { false }; RenderLayer _renderLayer { RenderLayer::WORLD }; PrimitiveMode _primitiveMode { PrimitiveMode::SOLID }; bool _cauterized { false }; diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index 9a634a85ad..60b823937f 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -230,8 +230,7 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo } ItemKey MaterialEntityRenderer::getKey() { - ItemKey::Builder builder; - builder.withTypeShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); + auto builder = ItemKey::Builder().withTypeShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); if (!_visible) { builder.withInvisible(); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index bfbbe12ea6..abe72a44e0 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1051,8 +1051,10 @@ ModelEntityRenderer::ModelEntityRenderer(const EntityItemPointer& entity) : Pare void ModelEntityRenderer::setKey(bool didVisualGeometryRequestSucceed) { auto builder = ItemKey::Builder().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); - if (_model && _model->isGroupCulled()) { + if (!_cullWithParent && _model && _model->isGroupCulled()) { builder.withMetaCullGroup(); + } else if (_cullWithParent) { + builder.withoutSubMetaCulled(); } if (didVisualGeometryRequestSucceed) { @@ -1503,6 +1505,14 @@ void ModelEntityRenderer::setPrimitiveMode(PrimitiveMode value) { } } +void ModelEntityRenderer::setCullWithParent(bool value) { + Parent::setCullWithParent(value); + setKey(_didLastVisualGeometryRequestSucceed); + if (_model) { + _model->setCullWithParent(_cullWithParent); + } +} + // NOTE: this only renders the "meta" portion of the Model, namely it renders debugging items void ModelEntityRenderer::doRender(RenderArgs* args) { DETAILED_PROFILE_RANGE(render_detail, "MetaModelRender"); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index ee6e7d0b04..7782ffa367 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -164,6 +164,7 @@ protected: void setIsVisibleInSecondaryCamera(bool value) override; void setRenderLayer(RenderLayer value) override; void setPrimitiveMode(PrimitiveMode value) override; + void setCullWithParent(bool value) override; private: void animate(const TypedEntityPointer& entity); diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index d517ecd026..0b46e593ae 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -177,11 +177,17 @@ void ParticleEffectEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEn ItemKey ParticleEffectEntityRenderer::getKey() { // FIXME: implement isTransparent() for particles and an opaque pipeline - if (_visible) { - return ItemKey::Builder::transparentShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); - } else { - return ItemKey::Builder().withInvisible().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()).build(); + auto builder = ItemKey::Builder::transparentShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); + + if (!_visible) { + builder.withInvisible(); } + + if (_cullWithParent) { + builder.withSubMetaCulled(); + } + + return builder.build(); } ShapeKey ParticleEffectEntityRenderer::getShapeKey() { diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index 2430643ce2..b32a478e99 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -71,7 +71,14 @@ void PolyLineEntityRenderer::buildPipeline() { } ItemKey PolyLineEntityRenderer::getKey() { - return ItemKey::Builder::transparentShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); + // FIXME: implement isTransparent() for polylines and an opaque pipeline + auto builder = ItemKey::Builder::transparentShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); + + if (_cullWithParent) { + builder.withSubMetaCulled(); + } + + return builder.build(); } ShapeKey PolyLineEntityRenderer::getShapeKey() { diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 183d2881f3..d432ab814e 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -1612,6 +1612,16 @@ PolyVoxEntityRenderer::PolyVoxEntityRenderer(const EntityItemPointer& entity) : _params = std::make_shared(sizeof(glm::vec4), nullptr); } +ItemKey PolyVoxEntityRenderer::getKey() { + auto builder = ItemKey::Builder::opaqueShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); + + if (_cullWithParent) { + builder.withSubMetaCulled(); + } + + return builder.build(); +} + ShapeKey PolyVoxEntityRenderer::getShapeKey() { auto builder = ShapeKey::Builder().withCustom(CUSTOM_PIPELINE_NUMBER); if (_primitiveMode == PrimitiveMode::LINES) { diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index 7aea87535e..47a0df380d 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -173,7 +173,7 @@ public: } protected: - virtual ItemKey getKey() override { return ItemKey::Builder::opaqueShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); } + virtual ItemKey getKey() override; virtual ShapeKey getShapeKey() override; virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index e1ede9192a..f556a747e9 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -3061,6 +3061,17 @@ void EntityItem::setCanCastShadow(bool value) { } } +bool EntityItem::getCullWithParent() const { + return _cullWithParent; +} + +void EntityItem::setCullWithParent(bool value) { + if (_cullWithParent != value) { + _cullWithParent = value; + emit requestRenderUpdate(); + } +} + bool EntityItem::isChildOfMyAvatar() const { QUuid ancestorID = findAncestorOfType(NestableType::Avatar); return !ancestorID.isNull() && (ancestorID == Physics::getSessionUUID() || ancestorID == AVATAR_SELF_ID); diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 29a1a8d73c..73eb863e56 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -303,6 +303,9 @@ public: bool getCanCastShadow() const; void setCanCastShadow(bool value); + bool getCullWithParent() const; + void setCullWithParent(bool value); + void setCauterized(bool value); bool getCauterized() const; @@ -752,6 +755,8 @@ protected: QHash _grabActions; + bool _cullWithParent { false }; + private: static std::function _getBillboardRotationOperator; static std::function _getPrimaryViewFrustumPositionOperator; diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 7be5f93a95..a9c0ab3140 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -92,6 +92,10 @@ void MeshPartPayload::updateKey(const render::ItemKey& key) { builder.withTransparent(); } + if (_cullWithParent) { + builder.withSubMetaCulled(); + } + _itemKey = builder.build(); } @@ -337,6 +341,10 @@ void ModelMeshPartPayload::updateKey(const render::ItemKey& key) { builder.withTransparent(); } + if (_cullWithParent) { + builder.withSubMetaCulled(); + } + _itemKey = builder.build(); } diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h index 641fc81487..fc9e0ab97e 100644 --- a/libraries/render-utils/src/MeshPartPayload.h +++ b/libraries/render-utils/src/MeshPartPayload.h @@ -43,7 +43,7 @@ public: // Render Item interface virtual render::ItemKey getKey() const; virtual render::Item::Bound getBound() const; - virtual render::ShapeKey getShapeKey() const; // shape interface + virtual render::ShapeKey getShapeKey() const; virtual void render(RenderArgs* args); // ModelMeshPartPayload functions to perform render @@ -73,8 +73,11 @@ public: void addMaterial(graphics::MaterialLayer material); void removeMaterial(graphics::MaterialPointer material); + void setCullWithParent(bool value) { _cullWithParent = value; } + protected: render::ItemKey _itemKey{ render::ItemKey::Builder::opaqueShape().build() }; + bool _cullWithParent { false }; }; namespace render { @@ -103,7 +106,7 @@ public: void updateTransformForSkinnedMesh(const Transform& renderTransform, const Transform& boundTransform); // Render Item interface - render::ShapeKey getShapeKey() const override; // shape interface + render::ShapeKey getShapeKey() const override; void render(RenderArgs* args) override; void setShapeKey(bool invalidateShapeKey, PrimitiveMode primitiveMode, bool useDualQuaternionSkinning); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index e2d78a8d94..1f0f78911a 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -151,7 +151,7 @@ void Model::setOffset(const glm::vec3& offset) { } void Model::calculateTextureInfo() { - if (!_hasCalculatedTextureInfo && isLoaded() && getGeometry()->areTexturesLoaded() && !_modelMeshRenderItemsMap.isEmpty()) { + if (!_hasCalculatedTextureInfo && isLoaded() && getGeometry()->areTexturesLoaded() && !_modelMeshRenderItems.isEmpty()) { size_t textureSize = 0; int textureCount = 0; bool allTexturesLoaded = true; @@ -954,6 +954,20 @@ void Model::setCauterized(bool cauterized, const render::ScenePointer& scene) { } } +void Model::setCullWithParent(bool cullWithParent) { + if (_cullWithParent != cullWithParent) { + _cullWithParent = cullWithParent; + + render::Transaction transaction; + foreach(auto item, _modelMeshRenderItemsMap.keys()) { + transaction.updateItem(item, [cullWithParent](ModelMeshPartPayload& data) { + data.setCullWithParent(cullWithParent); + }); + } + AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); + } +} + const render::ItemKey Model::getRenderItemKeyGlobalFlags() const { return _renderItemKeyGlobalFlags; } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 1431b5e3f9..31838697ad 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -129,6 +129,8 @@ public: bool isCauterized() const { return _cauterized; } void setCauterized(bool value, const render::ScenePointer& scene); + void setCullWithParent(bool value); + // Access the current RenderItemKey Global Flags used by the model and applied to the render items representing the parts of the model. const render::ItemKey getRenderItemKeyGlobalFlags() const; @@ -506,6 +508,7 @@ protected: // render::ItemKey _renderItemKeyGlobalFlags; bool _cauterized { false }; + bool _cullWithParent { false }; bool shouldInvalidatePayloadShapeKey(int meshIndex); diff --git a/libraries/render/src/render/Item.cpp b/libraries/render/src/render/Item.cpp index d5dde7f86b..532964777f 100644 --- a/libraries/render/src/render/Item.cpp +++ b/libraries/render/src/render/Item.cpp @@ -123,11 +123,7 @@ namespace render { if (!payload) { return ItemKey::Builder::opaqueShape().withTypeMeta(); } - if (payload->overrideSubMetaCulled()) { - return ItemKey::Builder(payload->getKey()).withSubMetaCulled(); - } else { - return payload->getKey(); - } + return payload->getKey(); } template <> const ShapeKey shapeGetShapeKey(const PayloadProxyInterface::Pointer& payload) { diff --git a/libraries/render/src/render/Item.h b/libraries/render/src/render/Item.h index e3f10365db..7265c12957 100644 --- a/libraries/render/src/render/Item.h +++ b/libraries/render/src/render/Item.h @@ -599,12 +599,6 @@ public: virtual Item::Bound getBound() = 0; virtual void render(RenderArgs* args) = 0; virtual uint32_t metaFetchMetaSubItems(ItemIDs& subItems) = 0; - - bool overrideSubMetaCulled() const { return _overrideSubMetaCulled; } - void setOverrideSubMetaCulled(bool overrideSubMetaCulled) { _overrideSubMetaCulled = overrideSubMetaCulled; } - -protected: - bool _overrideSubMetaCulled { false }; }; template <> const ItemKey payloadGetKey(const PayloadProxyInterface::Pointer& payload); @@ -615,7 +609,7 @@ template <> const ShapeKey shapeGetShapeKey(const PayloadProxyInterface::Pointer typedef Item::PayloadPointer PayloadPointer; -typedef std::vector< PayloadPointer > Payloads; +typedef std::vector Payloads; // A map of items by ShapeKey to optimize rendering pipeline assignments using ShapeBounds = std::unordered_map; From 413bf10f791ba6f8c64ed5c156ead99729e12bba Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Tue, 26 Nov 2019 22:28:06 -0800 Subject: [PATCH 3/4] stupid, shadows still broken --- .../entities-renderer/src/RenderableModelEntityItem.cpp | 2 +- libraries/render-utils/src/Model.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index f568f27b77..ad2737143c 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1000,7 +1000,7 @@ void ModelEntityRenderer::setKey(bool didVisualGeometryRequestSucceed) { if (!_cullWithParent && _model && _model->isGroupCulled()) { builder.withMetaCullGroup(); } else if (_cullWithParent) { - builder.withoutSubMetaCulled(); + builder.withSubMetaCulled(); } if (didVisualGeometryRequestSucceed) { diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index ac4381330d..d9d6cb8da3 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -978,9 +978,11 @@ void Model::setCullWithParent(bool cullWithParent) { _cullWithParent = cullWithParent; render::Transaction transaction; - foreach(auto item, _modelMeshRenderItemsMap.keys()) { - transaction.updateItem(item, [cullWithParent](ModelMeshPartPayload& data) { + auto renderItemsKey = _renderItemKeyGlobalFlags; + for(auto item : _modelMeshRenderItemIDs) { + transaction.updateItem(item, [cullWithParent, renderItemsKey](ModelMeshPartPayload& data) { data.setCullWithParent(cullWithParent); + data.updateKey(renderItemsKey); }); } AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); From 400b771a1a56cc185e76b7b75eeb8aec5afea0f2 Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Thu, 5 Dec 2019 01:29:11 -0800 Subject: [PATCH 4/4] fix shadows!! --- .../src/RenderablePolyLineEntityItem.cpp | 8 ++- .../render-utils/src/RenderShadowTask.cpp | 6 +- libraries/render/src/render/CullTask.cpp | 70 +------------------ libraries/render/src/render/CullTask.h | 28 +++----- .../src/render/RenderFetchCullSortTask.cpp | 2 +- 5 files changed, 20 insertions(+), 94 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index 74ee926df2..e75f8593d6 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -97,9 +97,11 @@ void PolyLineEntityRenderer::buildPipelines() { } ItemKey PolyLineEntityRenderer::getKey() { - auto builder = isTransparent() ? - ItemKey::Builder::transparentShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()) : - ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); + auto builder = ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); + + if (isTransparent()) { + builder.withTransparent(); + } if (_cullWithParent) { builder.withSubMetaCulled(); diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index 22decb47a7..dbfa23a143 100755 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -61,12 +61,12 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende const auto currentKeyLight = setupOutput.getN(4); // Fetch and cull the items from the scene - static const auto shadowCasterReceiverFilter = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(tagBits, tagMask); + static const auto shadowCasterReceiverFilter = ItemFilter::Builder::visibleWorldItems().withOpaque().withoutLayered().withTagBits(tagBits, tagMask); const auto fetchInput = FetchSpatialTree::Inputs(shadowCasterReceiverFilter, queryResolution).asVarying(); const auto shadowSelection = task.addJob("FetchShadowTree", fetchInput); - const auto selectionInputs = FilterSpatialSelection::Inputs(shadowSelection, shadowCasterReceiverFilter).asVarying(); - const auto shadowItems = task.addJob("FilterShadowSelection", selectionInputs); + const auto selectionInputs = CullSpatialSelection::Inputs(shadowSelection, shadowCasterReceiverFilter).asVarying(); + const auto shadowItems = task.addJob("FilterShadowSelection", selectionInputs, nullptr, true, RenderDetails::SHADOW); // Cull objects that are not visible in camera view. Hopefully the cull functor only performs LOD culling, not // frustum culling or this will make shadow casters out of the camera frustum disappear. diff --git a/libraries/render/src/render/CullTask.cpp b/libraries/render/src/render/CullTask.cpp index 5e5c6b4c6e..068d6f9851 100644 --- a/libraries/render/src/render/CullTask.cpp +++ b/libraries/render/src/render/CullTask.cpp @@ -172,7 +172,7 @@ void FetchSpatialTree::run(const RenderContextPointer& renderContext, const Inpu void CullSpatialSelection::configure(const Config& config) { _justFrozeFrustum = _justFrozeFrustum || (config.freezeFrustum && !_freezeFrustum); _freezeFrustum = config.freezeFrustum; - _skipCulling = config.skipCulling; + _overrideSkipCulling = config.skipCulling; } void CullSpatialSelection::run(const RenderContextPointer& renderContext, @@ -209,7 +209,7 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext, // 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) { + if (_skipCulling || _overrideSkipCulling) { // inside & fit items: filter only, culling is disabled { PerformanceTimer perfTimer("insideFitItems"); @@ -444,69 +444,3 @@ void ApplyCullFunctorOnItemBounds::run(const RenderContextPointer& renderContext args->popViewFrustum(); } } - -void FilterSpatialSelection::run(const RenderContextPointer& renderContext, - const Inputs& inputs, ItemBounds& outItems) { - assert(renderContext->args); - auto& scene = renderContext->_scene; - auto& inSelection = inputs.get0(); - - // Now we have a selection of items to render - outItems.clear(); - outItems.reserve(inSelection.numItems()); - - const auto filter = inputs.get1(); - if (!filter.selectsNothing()) { - // Now get the bound, and - // filter individually against the _filter - - // inside & fit items: filter only - { - PerformanceTimer perfTimer("insideFitItems"); - for (auto id : inSelection.insideItems) { - auto& item = scene->getItem(id); - if (filter.test(item.getKey())) { - ItemBound itemBound(id, item.getBound()); - outItems.emplace_back(itemBound); - } - } - } - - // inside & subcell items: filter only - { - PerformanceTimer perfTimer("insideSmallItems"); - for (auto id : inSelection.insideSubcellItems) { - auto& item = scene->getItem(id); - if (filter.test(item.getKey())) { - ItemBound itemBound(id, item.getBound()); - outItems.emplace_back(itemBound); - - } - } - } - - // partial & fit items: filter only - { - PerformanceTimer perfTimer("partialFitItems"); - for (auto id : inSelection.partialItems) { - auto& item = scene->getItem(id); - if (filter.test(item.getKey())) { - ItemBound itemBound(id, item.getBound()); - outItems.emplace_back(itemBound); - } - } - } - - // partial & subcell items: filter only - { - PerformanceTimer perfTimer("partialSmallItems"); - for (auto id : inSelection.partialSubcellItems) { - auto& item = scene->getItem(id); - if (filter.test(item.getKey())) { - ItemBound itemBound(id, item.getBound()); - outItems.emplace_back(itemBound); - } - } - } - } -} diff --git a/libraries/render/src/render/CullTask.h b/libraries/render/src/render/CullTask.h index 99ca7abe6c..e67edd6666 100644 --- a/libraries/render/src/render/CullTask.h +++ b/libraries/render/src/render/CullTask.h @@ -100,26 +100,25 @@ namespace render { }; class CullSpatialSelection { - bool _freezeFrustum{ false }; // initialized by Config - bool _justFrozeFrustum{ false }; - bool _skipCulling{ false }; - ViewFrustum _frozenFrustum; public: using Config = CullSpatialSelectionConfig; using Inputs = render::VaryingSet2; using JobModel = Job::ModelIO; - CullSpatialSelection(CullFunctor cullFunctor, RenderDetails::Type type) : - _cullFunctor{ cullFunctor }, + CullSpatialSelection(CullFunctor cullFunctor, bool skipCulling, RenderDetails::Type type) : + _cullFunctor(cullFunctor), + _skipCulling(skipCulling), _detailType(type) {} - CullSpatialSelection(CullFunctor cullFunctor) : - _cullFunctor{ cullFunctor } { - } - CullFunctor _cullFunctor; + bool _skipCulling { false }; RenderDetails::Type _detailType{ RenderDetails::OTHER }; + bool _freezeFrustum { false }; // initialized by Config + bool _justFrozeFrustum { false }; + bool _overrideSkipCulling { false }; + ViewFrustum _frozenFrustum; + void configure(const Config& config); void run(const RenderContextPointer& renderContext, const Inputs& inputs, ItemBounds& outItems); }; @@ -147,15 +146,6 @@ namespace render { }; - class FilterSpatialSelection { - public: - using Inputs = render::VaryingSet2; - using JobModel = Job::ModelIO; - - FilterSpatialSelection() {} - void run(const RenderContextPointer& renderContext, const Inputs& inputs, ItemBounds& outItems); - }; - class ApplyCullFunctorOnItemBounds { public: using Inputs = render::VaryingSet2; diff --git a/libraries/render/src/render/RenderFetchCullSortTask.cpp b/libraries/render/src/render/RenderFetchCullSortTask.cpp index 6b1a57ed88..ebcf5a432b 100644 --- a/libraries/render/src/render/RenderFetchCullSortTask.cpp +++ b/libraries/render/src/render/RenderFetchCullSortTask.cpp @@ -27,7 +27,7 @@ void RenderFetchCullSortTask::build(JobModel& task, const Varying& input, Varyin const auto fetchInput = FetchSpatialTree::Inputs(filter, glm::ivec2(0,0)).asVarying(); const auto spatialSelection = task.addJob("FetchSceneSelection", fetchInput); const auto cullInputs = CullSpatialSelection::Inputs(spatialSelection, spatialFilter).asVarying(); - const auto culledSpatialSelection = task.addJob("CullSceneSelection", cullInputs, cullFunctor, RenderDetails::ITEM); + const auto culledSpatialSelection = task.addJob("CullSceneSelection", cullInputs, cullFunctor, false, RenderDetails::ITEM); // Layered objects are not culled const ItemFilter layeredFilter = ItemFilter::Builder::visibleWorldItems().withTagBits(tagBits, tagMask);