mirror of
https://github.com/lubosz/overte.git
synced 2025-08-17 05:42:08 +02:00
Merge pull request #16548 from HifiExperiments/visible
Case 17368: Fix wearables not disappearing with avatar
This commit is contained in:
commit
fb70569fc2
22 changed files with 137 additions and 107 deletions
|
@ -2125,6 +2125,8 @@ void Avatar::updateAttachmentRenderIDs() {
|
||||||
|
|
||||||
void Avatar::updateDescendantRenderIDs() {
|
void Avatar::updateDescendantRenderIDs() {
|
||||||
_subItemLock.withWriteLock([&] {
|
_subItemLock.withWriteLock([&] {
|
||||||
|
auto oldRenderingDescendantEntityIDs = _renderingDescendantEntityIDs;
|
||||||
|
_renderingDescendantEntityIDs.clear();
|
||||||
_descendantRenderIDs.clear();
|
_descendantRenderIDs.clear();
|
||||||
auto entityTreeRenderer = DependencyManager::get<EntityTreeRenderer>();
|
auto entityTreeRenderer = DependencyManager::get<EntityTreeRenderer>();
|
||||||
EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr;
|
EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr;
|
||||||
|
@ -2134,7 +2136,12 @@ void Avatar::updateDescendantRenderIDs() {
|
||||||
if (object && object->getNestableType() == NestableType::Entity) {
|
if (object && object->getNestableType() == NestableType::Entity) {
|
||||||
EntityItemPointer entity = std::static_pointer_cast<EntityItem>(object);
|
EntityItemPointer entity = std::static_pointer_cast<EntityItem>(object);
|
||||||
if (entity->isVisible()) {
|
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) {
|
if (renderer) {
|
||||||
render::ItemIDs renderableSubItems;
|
render::ItemIDs renderableSubItems;
|
||||||
uint32_t numRenderableSubItems = renderer->metaFetchMetaSubItems(renderableSubItems);
|
uint32_t numRenderableSubItems = renderer->metaFetchMetaSubItems(renderableSubItems);
|
||||||
|
@ -2145,6 +2152,13 @@ void Avatar::updateDescendantRenderIDs() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (auto& oldRenderingDescendantEntityID : oldRenderingDescendantEntityIDs) {
|
||||||
|
auto entity = entityTree->findEntityByEntityItemID(oldRenderingDescendantEntityID);
|
||||||
|
if (entity) {
|
||||||
|
entity->setCullWithParent(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -783,6 +783,7 @@ protected:
|
||||||
render::ItemIDs _attachmentRenderIDs;
|
render::ItemIDs _attachmentRenderIDs;
|
||||||
void updateDescendantRenderIDs();
|
void updateDescendantRenderIDs();
|
||||||
render::ItemIDs _descendantRenderIDs;
|
render::ItemIDs _descendantRenderIDs;
|
||||||
|
std::unordered_set<EntityItemID> _renderingDescendantEntityIDs;
|
||||||
uint32_t _lastAncestorChainRenderableVersion { 0 };
|
uint32_t _lastAncestorChainRenderableVersion { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -177,6 +177,10 @@ ItemKey EntityRenderer::getKey() {
|
||||||
builder.withShadowCaster();
|
builder.withShadowCaster();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_cullWithParent) {
|
||||||
|
builder.withSubMetaCulled();
|
||||||
|
}
|
||||||
|
|
||||||
if (!_visible) {
|
if (!_visible) {
|
||||||
builder.withInvisible();
|
builder.withInvisible();
|
||||||
}
|
}
|
||||||
|
@ -420,6 +424,7 @@ void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transa
|
||||||
setRenderLayer(entity->getRenderLayer());
|
setRenderLayer(entity->getRenderLayer());
|
||||||
setPrimitiveMode(entity->getPrimitiveMode());
|
setPrimitiveMode(entity->getPrimitiveMode());
|
||||||
_canCastShadow = entity->getCanCastShadow();
|
_canCastShadow = entity->getCanCastShadow();
|
||||||
|
setCullWithParent(entity->getCullWithParent());
|
||||||
_cauterized = entity->getCauterized();
|
_cauterized = entity->getCauterized();
|
||||||
entity->setNeedsRenderUpdate(false);
|
entity->setNeedsRenderUpdate(false);
|
||||||
});
|
});
|
||||||
|
|
|
@ -108,6 +108,7 @@ protected:
|
||||||
virtual void setIsVisibleInSecondaryCamera(bool value) { _isVisibleInSecondaryCamera = value; }
|
virtual void setIsVisibleInSecondaryCamera(bool value) { _isVisibleInSecondaryCamera = value; }
|
||||||
virtual void setRenderLayer(RenderLayer value) { _renderLayer = value; }
|
virtual void setRenderLayer(RenderLayer value) { _renderLayer = value; }
|
||||||
virtual void setPrimitiveMode(PrimitiveMode value) { _primitiveMode = value; }
|
virtual void setPrimitiveMode(PrimitiveMode value) { _primitiveMode = value; }
|
||||||
|
virtual void setCullWithParent(bool value) { _cullWithParent = value; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void requestRenderUpdate();
|
void requestRenderUpdate();
|
||||||
|
@ -130,6 +131,7 @@ protected:
|
||||||
bool _visible { false };
|
bool _visible { false };
|
||||||
bool _isVisibleInSecondaryCamera { false };
|
bool _isVisibleInSecondaryCamera { false };
|
||||||
bool _canCastShadow { false };
|
bool _canCastShadow { false };
|
||||||
|
bool _cullWithParent { false };
|
||||||
RenderLayer _renderLayer { RenderLayer::WORLD };
|
RenderLayer _renderLayer { RenderLayer::WORLD };
|
||||||
PrimitiveMode _primitiveMode { PrimitiveMode::SOLID };
|
PrimitiveMode _primitiveMode { PrimitiveMode::SOLID };
|
||||||
bool _cauterized { false };
|
bool _cauterized { false };
|
||||||
|
|
|
@ -210,8 +210,7 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemKey MaterialEntityRenderer::getKey() {
|
ItemKey MaterialEntityRenderer::getKey() {
|
||||||
ItemKey::Builder builder;
|
auto builder = ItemKey::Builder().withTypeShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
|
||||||
builder.withTypeShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
|
|
||||||
|
|
||||||
if (!_visible) {
|
if (!_visible) {
|
||||||
builder.withInvisible();
|
builder.withInvisible();
|
||||||
|
|
|
@ -997,8 +997,10 @@ ModelEntityRenderer::ModelEntityRenderer(const EntityItemPointer& entity) : Pare
|
||||||
void ModelEntityRenderer::setKey(bool didVisualGeometryRequestSucceed) {
|
void ModelEntityRenderer::setKey(bool didVisualGeometryRequestSucceed) {
|
||||||
auto builder = ItemKey::Builder().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
|
auto builder = ItemKey::Builder().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
|
||||||
|
|
||||||
if (_model && _model->isGroupCulled()) {
|
if (!_cullWithParent && _model && _model->isGroupCulled()) {
|
||||||
builder.withMetaCullGroup();
|
builder.withMetaCullGroup();
|
||||||
|
} else if (_cullWithParent) {
|
||||||
|
builder.withSubMetaCulled();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (didVisualGeometryRequestSucceed) {
|
if (didVisualGeometryRequestSucceed) {
|
||||||
|
@ -1437,6 +1439,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
|
// NOTE: this only renders the "meta" portion of the Model, namely it renders debugging items
|
||||||
void ModelEntityRenderer::doRender(RenderArgs* args) {
|
void ModelEntityRenderer::doRender(RenderArgs* args) {
|
||||||
DETAILED_PROFILE_RANGE(render_detail, "MetaModelRender");
|
DETAILED_PROFILE_RANGE(render_detail, "MetaModelRender");
|
||||||
|
|
|
@ -164,6 +164,7 @@ protected:
|
||||||
void setIsVisibleInSecondaryCamera(bool value) override;
|
void setIsVisibleInSecondaryCamera(bool value) override;
|
||||||
void setRenderLayer(RenderLayer value) override;
|
void setRenderLayer(RenderLayer value) override;
|
||||||
void setPrimitiveMode(PrimitiveMode value) override;
|
void setPrimitiveMode(PrimitiveMode value) override;
|
||||||
|
void setCullWithParent(bool value) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void animate(const TypedEntityPointer& entity);
|
void animate(const TypedEntityPointer& entity);
|
||||||
|
|
|
@ -151,11 +151,17 @@ void ParticleEffectEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEn
|
||||||
|
|
||||||
ItemKey ParticleEffectEntityRenderer::getKey() {
|
ItemKey ParticleEffectEntityRenderer::getKey() {
|
||||||
// FIXME: implement isTransparent() for particles and an opaque pipeline
|
// FIXME: implement isTransparent() for particles and an opaque pipeline
|
||||||
if (_visible) {
|
auto builder = ItemKey::Builder::transparentShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
|
||||||
return ItemKey::Builder::transparentShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
|
|
||||||
} else {
|
if (!_visible) {
|
||||||
return ItemKey::Builder().withInvisible().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()).build();
|
builder.withInvisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_cullWithParent) {
|
||||||
|
builder.withSubMetaCulled();
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeKey ParticleEffectEntityRenderer::getShapeKey() {
|
ShapeKey ParticleEffectEntityRenderer::getShapeKey() {
|
||||||
|
|
|
@ -97,9 +97,17 @@ void PolyLineEntityRenderer::buildPipelines() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemKey PolyLineEntityRenderer::getKey() {
|
ItemKey PolyLineEntityRenderer::getKey() {
|
||||||
return isTransparent() ?
|
auto builder = ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
|
||||||
ItemKey::Builder::transparentShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()) :
|
|
||||||
ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
|
if (isTransparent()) {
|
||||||
|
builder.withTransparent();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_cullWithParent) {
|
||||||
|
builder.withSubMetaCulled();
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeKey PolyLineEntityRenderer::getShapeKey() {
|
ShapeKey PolyLineEntityRenderer::getShapeKey() {
|
||||||
|
|
|
@ -1776,6 +1776,16 @@ PolyVoxEntityRenderer::PolyVoxEntityRenderer(const EntityItemPointer& entity) :
|
||||||
_params = std::make_shared<gpu::Buffer>(sizeof(glm::vec4), nullptr);
|
_params = std::make_shared<gpu::Buffer>(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() {
|
ShapeKey PolyVoxEntityRenderer::getShapeKey() {
|
||||||
auto builder = ShapeKey::Builder().withCustom(CUSTOM_PIPELINE_NUMBER);
|
auto builder = ShapeKey::Builder().withCustom(CUSTOM_PIPELINE_NUMBER);
|
||||||
if (_primitiveMode == PrimitiveMode::LINES) {
|
if (_primitiveMode == PrimitiveMode::LINES) {
|
||||||
|
|
|
@ -209,7 +209,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ItemKey getKey() override { return ItemKey::Builder::opaqueShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); }
|
virtual ItemKey getKey() override;
|
||||||
virtual ShapeKey getShapeKey() override;
|
virtual ShapeKey getShapeKey() override;
|
||||||
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
|
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
|
||||||
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
|
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
|
||||||
|
|
|
@ -3027,6 +3027,21 @@ void EntityItem::setCanCastShadow(bool value) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EntityItem::getCullWithParent() const {
|
||||||
|
bool result;
|
||||||
|
withReadLock([&] {
|
||||||
|
result = _cullWithParent;
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityItem::setCullWithParent(bool value) {
|
||||||
|
withWriteLock([&] {
|
||||||
|
_needsRenderUpdate |= _cullWithParent != value;
|
||||||
|
_cullWithParent = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
bool EntityItem::isChildOfMyAvatar() const {
|
bool EntityItem::isChildOfMyAvatar() const {
|
||||||
QUuid ancestorID = findAncestorOfType(NestableType::Avatar);
|
QUuid ancestorID = findAncestorOfType(NestableType::Avatar);
|
||||||
return !ancestorID.isNull() && (ancestorID == Physics::getSessionUUID() || ancestorID == AVATAR_SELF_ID);
|
return !ancestorID.isNull() && (ancestorID == Physics::getSessionUUID() || ancestorID == AVATAR_SELF_ID);
|
||||||
|
|
|
@ -307,6 +307,9 @@ public:
|
||||||
bool getCanCastShadow() const;
|
bool getCanCastShadow() const;
|
||||||
void setCanCastShadow(bool value);
|
void setCanCastShadow(bool value);
|
||||||
|
|
||||||
|
bool getCullWithParent() const;
|
||||||
|
void setCullWithParent(bool value);
|
||||||
|
|
||||||
void setCauterized(bool value);
|
void setCauterized(bool value);
|
||||||
bool getCauterized() const;
|
bool getCauterized() const;
|
||||||
|
|
||||||
|
@ -767,6 +770,8 @@ protected:
|
||||||
|
|
||||||
QHash<QUuid, EntityDynamicPointer> _grabActions;
|
QHash<QUuid, EntityDynamicPointer> _grabActions;
|
||||||
|
|
||||||
|
bool _cullWithParent { false };
|
||||||
|
|
||||||
mutable bool _needsRenderUpdate { false };
|
mutable bool _needsRenderUpdate { false };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -106,6 +106,10 @@ void MeshPartPayload::updateKey(const render::ItemKey& key) {
|
||||||
builder.withTransparent();
|
builder.withTransparent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_cullWithParent) {
|
||||||
|
builder.withSubMetaCulled();
|
||||||
|
}
|
||||||
|
|
||||||
_itemKey = builder.build();
|
_itemKey = builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,6 +372,10 @@ void ModelMeshPartPayload::updateKey(const render::ItemKey& key) {
|
||||||
builder.withTransparent();
|
builder.withTransparent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_cullWithParent) {
|
||||||
|
builder.withSubMetaCulled();
|
||||||
|
}
|
||||||
|
|
||||||
_itemKey = builder.build();
|
_itemKey = builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
// Render Item interface
|
// Render Item interface
|
||||||
virtual render::ItemKey getKey() const;
|
virtual render::ItemKey getKey() const;
|
||||||
virtual render::Item::Bound getBound() const;
|
virtual render::Item::Bound getBound() const;
|
||||||
virtual render::ShapeKey getShapeKey() const; // shape interface
|
virtual render::ShapeKey getShapeKey() const;
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args);
|
||||||
|
|
||||||
// ModelMeshPartPayload functions to perform render
|
// ModelMeshPartPayload functions to perform render
|
||||||
|
@ -72,10 +72,13 @@ public:
|
||||||
void addMaterial(graphics::MaterialLayer material);
|
void addMaterial(graphics::MaterialLayer material);
|
||||||
void removeMaterial(graphics::MaterialPointer material);
|
void removeMaterial(graphics::MaterialPointer material);
|
||||||
|
|
||||||
|
void setCullWithParent(bool value) { _cullWithParent = value; }
|
||||||
|
|
||||||
static bool enableMaterialProceduralShaders;
|
static bool enableMaterialProceduralShaders;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
render::ItemKey _itemKey{ render::ItemKey::Builder::opaqueShape().build() };
|
render::ItemKey _itemKey{ render::ItemKey::Builder::opaqueShape().build() };
|
||||||
|
bool _cullWithParent { false };
|
||||||
uint64_t _created;
|
uint64_t _created;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -104,7 +107,7 @@ public:
|
||||||
void updateClusterBuffer(const std::vector<Model::TransformDualQuaternion>& clusterDualQuaternions);
|
void updateClusterBuffer(const std::vector<Model::TransformDualQuaternion>& clusterDualQuaternions);
|
||||||
|
|
||||||
// Render Item interface
|
// Render Item interface
|
||||||
render::ShapeKey getShapeKey() const override; // shape interface
|
render::ShapeKey getShapeKey() const override;
|
||||||
void render(RenderArgs* args) override;
|
void render(RenderArgs* args) override;
|
||||||
|
|
||||||
void setShapeKey(bool invalidateShapeKey, PrimitiveMode primitiveMode, bool useDualQuaternionSkinning);
|
void setShapeKey(bool invalidateShapeKey, PrimitiveMode primitiveMode, bool useDualQuaternionSkinning);
|
||||||
|
|
|
@ -154,7 +154,7 @@ void Model::setOffset(const glm::vec3& offset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::calculateTextureInfo() {
|
void Model::calculateTextureInfo() {
|
||||||
if (!_hasCalculatedTextureInfo && isLoaded() && getNetworkModel()->areTexturesLoaded() && !_modelMeshRenderItemIDs.empty()) {
|
if (!_hasCalculatedTextureInfo && isLoaded() && getNetworkModel()->areTexturesLoaded() && !_modelMeshRenderItems.isEmpty()) {
|
||||||
size_t textureSize = 0;
|
size_t textureSize = 0;
|
||||||
int textureCount = 0;
|
int textureCount = 0;
|
||||||
bool allTexturesLoaded = true;
|
bool allTexturesLoaded = true;
|
||||||
|
@ -973,6 +973,22 @@ void Model::setCauterized(bool cauterized, const render::ScenePointer& scene) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Model::setCullWithParent(bool cullWithParent) {
|
||||||
|
if (_cullWithParent != cullWithParent) {
|
||||||
|
_cullWithParent = cullWithParent;
|
||||||
|
|
||||||
|
render::Transaction transaction;
|
||||||
|
auto renderItemsKey = _renderItemKeyGlobalFlags;
|
||||||
|
for(auto item : _modelMeshRenderItemIDs) {
|
||||||
|
transaction.updateItem<ModelMeshPartPayload>(item, [cullWithParent, renderItemsKey](ModelMeshPartPayload& data) {
|
||||||
|
data.setCullWithParent(cullWithParent);
|
||||||
|
data.updateKey(renderItemsKey);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const render::ItemKey Model::getRenderItemKeyGlobalFlags() const {
|
const render::ItemKey Model::getRenderItemKeyGlobalFlags() const {
|
||||||
return _renderItemKeyGlobalFlags;
|
return _renderItemKeyGlobalFlags;
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,6 +129,8 @@ public:
|
||||||
bool isCauterized() const { return _cauterized; }
|
bool isCauterized() const { return _cauterized; }
|
||||||
void setCauterized(bool value, const render::ScenePointer& scene);
|
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.
|
// 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;
|
const render::ItemKey getRenderItemKeyGlobalFlags() const;
|
||||||
|
|
||||||
|
@ -515,6 +517,7 @@ protected:
|
||||||
//
|
//
|
||||||
render::ItemKey _renderItemKeyGlobalFlags;
|
render::ItemKey _renderItemKeyGlobalFlags;
|
||||||
bool _cauterized { false };
|
bool _cauterized { false };
|
||||||
|
bool _cullWithParent { false };
|
||||||
|
|
||||||
bool shouldInvalidatePayloadShapeKey(int meshIndex);
|
bool shouldInvalidatePayloadShapeKey(int meshIndex);
|
||||||
|
|
||||||
|
|
|
@ -61,12 +61,12 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
|
||||||
const auto currentKeyLight = setupOutput.getN<RenderShadowSetup::Output>(4);
|
const auto currentKeyLight = setupOutput.getN<RenderShadowSetup::Output>(4);
|
||||||
// Fetch and cull the items from the scene
|
// 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 fetchInput = FetchSpatialTree::Inputs(shadowCasterReceiverFilter, queryResolution).asVarying();
|
||||||
const auto shadowSelection = task.addJob<FetchSpatialTree>("FetchShadowTree", fetchInput);
|
const auto shadowSelection = task.addJob<FetchSpatialTree>("FetchShadowTree", fetchInput);
|
||||||
const auto selectionInputs = FilterSpatialSelection::Inputs(shadowSelection, shadowCasterReceiverFilter).asVarying();
|
const auto selectionInputs = CullSpatialSelection::Inputs(shadowSelection, shadowCasterReceiverFilter).asVarying();
|
||||||
const auto shadowItems = task.addJob<FilterSpatialSelection>("FilterShadowSelection", selectionInputs);
|
const auto shadowItems = task.addJob<CullSpatialSelection>("FilterShadowSelection", selectionInputs, nullptr, true, RenderDetails::SHADOW);
|
||||||
|
|
||||||
// Cull objects that are not visible in camera view. Hopefully the cull functor only performs LOD culling, not
|
// 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.
|
// frustum culling or this will make shadow casters out of the camera frustum disappear.
|
||||||
|
|
|
@ -172,7 +172,7 @@ void FetchSpatialTree::run(const RenderContextPointer& renderContext, const Inpu
|
||||||
void CullSpatialSelection::configure(const Config& config) {
|
void CullSpatialSelection::configure(const Config& config) {
|
||||||
_justFrozeFrustum = _justFrozeFrustum || (config.freezeFrustum && !_freezeFrustum);
|
_justFrozeFrustum = _justFrozeFrustum || (config.freezeFrustum && !_freezeFrustum);
|
||||||
_freezeFrustum = config.freezeFrustum;
|
_freezeFrustum = config.freezeFrustum;
|
||||||
_skipCulling = config.skipCulling;
|
_overrideSkipCulling = config.skipCulling;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
||||||
|
@ -209,7 +209,7 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
||||||
// filter individually against the _filter
|
// filter individually against the _filter
|
||||||
// visibility cull if partially selected ( octree cell contianing it was partial)
|
// 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)
|
// 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
|
// inside & fit items: filter only, culling is disabled
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("insideFitItems");
|
PerformanceTimer perfTimer("insideFitItems");
|
||||||
|
@ -444,69 +444,3 @@ void ApplyCullFunctorOnItemBounds::run(const RenderContextPointer& renderContext
|
||||||
args->popViewFrustum();
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -100,26 +100,25 @@ namespace render {
|
||||||
};
|
};
|
||||||
|
|
||||||
class CullSpatialSelection {
|
class CullSpatialSelection {
|
||||||
bool _freezeFrustum{ false }; // initialized by Config
|
|
||||||
bool _justFrozeFrustum{ false };
|
|
||||||
bool _skipCulling{ false };
|
|
||||||
ViewFrustum _frozenFrustum;
|
|
||||||
public:
|
public:
|
||||||
using Config = CullSpatialSelectionConfig;
|
using Config = CullSpatialSelectionConfig;
|
||||||
using Inputs = render::VaryingSet2<ItemSpatialTree::ItemSelection, ItemFilter>;
|
using Inputs = render::VaryingSet2<ItemSpatialTree::ItemSelection, ItemFilter>;
|
||||||
using JobModel = Job::ModelIO<CullSpatialSelection, Inputs, ItemBounds, Config>;
|
using JobModel = Job::ModelIO<CullSpatialSelection, Inputs, ItemBounds, Config>;
|
||||||
|
|
||||||
CullSpatialSelection(CullFunctor cullFunctor, RenderDetails::Type type) :
|
CullSpatialSelection(CullFunctor cullFunctor, bool skipCulling, RenderDetails::Type type) :
|
||||||
_cullFunctor{ cullFunctor },
|
_cullFunctor(cullFunctor),
|
||||||
|
_skipCulling(skipCulling),
|
||||||
_detailType(type) {}
|
_detailType(type) {}
|
||||||
|
|
||||||
CullSpatialSelection(CullFunctor cullFunctor) :
|
|
||||||
_cullFunctor{ cullFunctor } {
|
|
||||||
}
|
|
||||||
|
|
||||||
CullFunctor _cullFunctor;
|
CullFunctor _cullFunctor;
|
||||||
|
bool _skipCulling { false };
|
||||||
RenderDetails::Type _detailType{ RenderDetails::OTHER };
|
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 configure(const Config& config);
|
||||||
void run(const RenderContextPointer& renderContext, const Inputs& inputs, ItemBounds& outItems);
|
void run(const RenderContextPointer& renderContext, const Inputs& inputs, ItemBounds& outItems);
|
||||||
};
|
};
|
||||||
|
@ -147,15 +146,6 @@ namespace render {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FilterSpatialSelection {
|
|
||||||
public:
|
|
||||||
using Inputs = render::VaryingSet2<ItemSpatialTree::ItemSelection, ItemFilter>;
|
|
||||||
using JobModel = Job::ModelIO<FilterSpatialSelection, Inputs, ItemBounds>;
|
|
||||||
|
|
||||||
FilterSpatialSelection() {}
|
|
||||||
void run(const RenderContextPointer& renderContext, const Inputs& inputs, ItemBounds& outItems);
|
|
||||||
};
|
|
||||||
|
|
||||||
class ApplyCullFunctorOnItemBounds {
|
class ApplyCullFunctorOnItemBounds {
|
||||||
public:
|
public:
|
||||||
using Inputs = render::VaryingSet2<ItemBounds, ViewFrustumPointer>;
|
using Inputs = render::VaryingSet2<ItemBounds, ViewFrustumPointer>;
|
||||||
|
|
|
@ -625,7 +625,7 @@ template <> const ShapeKey shapeGetShapeKey(const PayloadProxyInterface::Pointer
|
||||||
|
|
||||||
|
|
||||||
typedef Item::PayloadPointer PayloadPointer;
|
typedef Item::PayloadPointer PayloadPointer;
|
||||||
typedef std::vector< PayloadPointer > Payloads;
|
typedef std::vector<PayloadPointer> Payloads;
|
||||||
|
|
||||||
// A map of items by ShapeKey to optimize rendering pipeline assignments
|
// A map of items by ShapeKey to optimize rendering pipeline assignments
|
||||||
using ShapeBounds = std::unordered_map<ShapeKey, ItemBounds, ShapeKey::Hash, ShapeKey::KeyEqual>;
|
using ShapeBounds = std::unordered_map<ShapeKey, ItemBounds, ShapeKey::Hash, ShapeKey::KeyEqual>;
|
||||||
|
|
|
@ -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 fetchInput = FetchSpatialTree::Inputs(filter, glm::ivec2(0,0)).asVarying();
|
||||||
const auto spatialSelection = task.addJob<FetchSpatialTree>("FetchSceneSelection", fetchInput);
|
const auto spatialSelection = task.addJob<FetchSpatialTree>("FetchSceneSelection", fetchInput);
|
||||||
const auto cullInputs = CullSpatialSelection::Inputs(spatialSelection, spatialFilter).asVarying();
|
const auto cullInputs = CullSpatialSelection::Inputs(spatialSelection, spatialFilter).asVarying();
|
||||||
const auto culledSpatialSelection = task.addJob<CullSpatialSelection>("CullSceneSelection", cullInputs, cullFunctor, RenderDetails::ITEM);
|
const auto culledSpatialSelection = task.addJob<CullSpatialSelection>("CullSceneSelection", cullInputs, cullFunctor, false, RenderDetails::ITEM);
|
||||||
|
|
||||||
// Layered objects are not culled
|
// Layered objects are not culled
|
||||||
const ItemFilter layeredFilter = ItemFilter::Builder::visibleWorldItems().withTagBits(tagBits, tagMask);
|
const ItemFilter layeredFilter = ItemFilter::Builder::visibleWorldItems().withTagBits(tagBits, tagMask);
|
||||||
|
|
Loading…
Reference in a new issue