From 0bcd8b81e138e6f47e0f0a7690bc9c5c94e006cf 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 | 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;