From 1736252f0de6ab85bb8f5f1df0bc6b0a9bc64416 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 30 Apr 2019 10:31:09 -0700 Subject: [PATCH] trying and failing to fix models --- .../src/avatars-renderer/Avatar.cpp | 35 +++++++++---------- .../src/avatars-renderer/Avatar.h | 3 +- .../src/RenderableEntityItem.cpp | 14 ++++---- .../src/RenderableEntityItem.h | 11 ++++++ .../src/RenderableMaterialEntityItem.cpp | 3 +- .../src/RenderableModelEntityItem.cpp | 12 ++++++- .../src/RenderableModelEntityItem.h | 1 + .../RenderableParticleEffectEntityItem.cpp | 14 +++++--- .../src/RenderablePolyLineEntityItem.cpp | 11 ++++-- .../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 | 8 ++--- 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, 126 insertions(+), 55 deletions(-) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index ce559a7729..868d49bb5c 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -2121,7 +2121,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; @@ -2131,34 +2132,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 235a04f109..6a740a793d 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -781,7 +781,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 fb3d2f1bf5..a1c5a5b432 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -168,19 +168,20 @@ render::hifi::Layer EntityRenderer::getHifiRenderLayer() const { } ItemKey EntityRenderer::getKey() { - ItemKey::Builder builder = ItemKey::Builder().withTypeShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); - + auto builder = ItemKey::Builder().withTypeShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); if (isTransparent()) { builder.withTransparent(); - } else if (_canCastShadow) { + } + + if (_canCastShadow) { builder.withShadowCaster(); } - if (!_visible) { - builder.withInvisible(); + if (_cullWithParent) { + builder.withSubMetaCulled(); } - return builder; + return builder.build(); } uint32_t EntityRenderer::metaFetchMetaSubItems(ItemIDs& subItems) const { @@ -419,6 +420,7 @@ void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transa setRenderLayer(entity->getRenderLayer()); setPrimitiveMode(entity->getPrimitiveMode()); _canCastShadow = entity->getCanCastShadow(); + setCullWithParent(entity->getCullWithParent()); _cauterized = entity->getCauterized(); entity->setNeedsRenderUpdate(false); }); diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index d11f6dd6f4..227eb6a018 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -108,6 +108,16 @@ 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; + withReadLock([&] { + result = f(); + }); + return result; + } signals: void requestRenderUpdate(); @@ -130,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 af121f2957..4c75a25962 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -210,8 +210,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 1f2be0c488..1ea0d9d4c7 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1057,8 +1057,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) { @@ -1497,6 +1499,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 c32dad901f..0119c7bc26 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 e3528e2291..f34eb85230 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -151,11 +151,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 9a762b3b3a..ae4654a21a 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -97,9 +97,14 @@ void PolyLineEntityRenderer::buildPipelines() { } ItemKey PolyLineEntityRenderer::getKey() { - return isTransparent() ? - ItemKey::Builder::transparentShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()) : - ItemKey::Builder::opaqueShape().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 853e36b45b..1555604604 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -1783,6 +1783,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 c322959f86..825b4429cd 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -209,7 +209,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 598ac17510..bbc9ff1991 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -3025,6 +3025,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 3274379ee9..16ce9985bf 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -305,6 +305,9 @@ public: bool getCanCastShadow() const; void setCanCastShadow(bool value); + bool getCullWithParent() const; + void setCullWithParent(bool value); + void setCauterized(bool value); bool getCauterized() const; @@ -762,7 +765,7 @@ protected: QHash _grabActions; - mutable bool _needsRenderUpdate { false }; + bool _cullWithParent { false }; private: static std::function _getBillboardRotationOperator; diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 947c53d546..d7983bbe50 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -102,6 +102,10 @@ void MeshPartPayload::updateKey(const render::ItemKey& key) { builder.withTransparent(); } + if (_cullWithParent) { + builder.withSubMetaCulled(); + } + _itemKey = builder.build(); } @@ -383,6 +387,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 4d9510e4a2..e7415c6b8d 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,11 +73,11 @@ public: void addMaterial(graphics::MaterialLayer material); void removeMaterial(graphics::MaterialPointer material); - static bool enableMaterialProceduralShaders; + void setCullWithParent(bool value) { _cullWithParent = value; } protected: render::ItemKey _itemKey{ render::ItemKey::Builder::opaqueShape().build() }; - uint64_t _created; + bool _cullWithParent { false }; }; namespace render { @@ -106,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 182bc535bf..32e44c5cbf 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -154,7 +154,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; @@ -960,6 +960,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 597fe552f7..b677861e9f 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; @@ -503,6 +505,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 e28a88f6dd..c94732eafe 100644 --- a/libraries/render/src/render/Item.h +++ b/libraries/render/src/render/Item.h @@ -615,12 +615,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); @@ -631,7 +625,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;