trying and failing to fix models

This commit is contained in:
SamGondelman 2019-04-30 10:31:09 -07:00
parent d99af64410
commit 0bcd8b81e1
19 changed files with 122 additions and 50 deletions

View file

@ -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<EntityTreeRenderer>();
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<EntityItem>(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<render::PayloadProxyInterface>(oldDescendantRenderID, [](render::PayloadProxyInterface& self) {
self.setOverrideSubMetaCulled(false);
});
}
for (auto& descendantRenderIDs : _descendantRenderIDs) {
transaction.updateItem<render::PayloadProxyInterface>(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);
}
}
});
}
});
}

View file

@ -776,7 +776,8 @@ protected:
void updateAttachmentRenderIDs();
render::ItemIDs _attachmentRenderIDs;
void updateDescendantRenderIDs();
render::ItemIDSet _descendantRenderIDs;
render::ItemIDs _descendantRenderIDs;
std::unordered_set<EntityItemID> _renderingDescendantEntityIDs;
uint32_t _lastAncestorChainRenderableVersion { 0 };
};

View file

@ -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;
});

View file

@ -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 <typename F, typename T>
T withReadLockResult(const std::function<T()>& 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 };

View file

@ -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();

View file

@ -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");

View file

@ -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);

View file

@ -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() {

View file

@ -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() {

View file

@ -1612,6 +1612,16 @@ PolyVoxEntityRenderer::PolyVoxEntityRenderer(const EntityItemPointer& entity) :
_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() {
auto builder = ShapeKey::Builder().withCustom(CUSTOM_PIPELINE_NUMBER);
if (_primitiveMode == PrimitiveMode::LINES) {

View file

@ -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;

View file

@ -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);

View file

@ -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<QUuid, EntityDynamicPointer> _grabActions;
bool _cullWithParent { false };
private:
static std::function<glm::quat(const glm::vec3&, const glm::quat&, BillboardMode, const glm::vec3&)> _getBillboardRotationOperator;
static std::function<glm::vec3()> _getPrimaryViewFrustumPositionOperator;

View file

@ -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();
}

View file

@ -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);

View file

@ -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<ModelMeshPartPayload>(item, [cullWithParent](ModelMeshPartPayload& data) {
data.setCullWithParent(cullWithParent);
});
}
AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction);
}
}
const render::ItemKey Model::getRenderItemKeyGlobalFlags() const {
return _renderItemKeyGlobalFlags;
}

View file

@ -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);

View file

@ -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) {

View file

@ -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<PayloadPointer> Payloads;
// A map of items by ShapeKey to optimize rendering pipeline assignments
using ShapeBounds = std::unordered_map<ShapeKey, ItemBounds, ShapeKey::Hash, ShapeKey::KeyEqual>;