diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index ab057f9d12..b6def4d35d 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -331,7 +331,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() const { const_cast<RenderableModelEntityItem*>(this)->fetchCollisionGeometryResource(); } - if (_collisionGeometryResource && _collisionGeometryResource->isLoaded()) { + if (_collisionGeometryResource && _collisionGeometryResource->isLoaded() && _collisionGeometryResource->isHFMModelLoaded()) { // we have both URLs AND both geometries AND they are both fully loaded. if (_needsInitialSimulation) { // the _model's offset will be wrong until _needsInitialSimulation is false @@ -362,7 +362,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { } if (type == SHAPE_TYPE_COMPOUND) { - if (!_collisionGeometryResource || !_collisionGeometryResource->isLoaded()) { + if (!_collisionGeometryResource || !_collisionGeometryResource->isLoaded() || !_collisionGeometryResource->isHFMModelLoaded()) { return; } @@ -493,6 +493,9 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { std::vector<std::shared_ptr<const graphics::Mesh>> meshes; if (type == SHAPE_TYPE_SIMPLE_COMPOUND) { + if (!_collisionGeometryResource || !_collisionGeometryResource->isLoaded() || !_collisionGeometryResource->isHFMModelLoaded()) { + return; + } auto& hfmMeshes = _collisionGeometryResource->getHFMModel().meshes; meshes.reserve(hfmMeshes.size()); for (auto& hfmMesh : hfmMeshes) { @@ -721,7 +724,7 @@ int RenderableModelEntityItem::avatarJointIndex(int modelJointIndex) { bool RenderableModelEntityItem::contains(const glm::vec3& point) const { auto model = getModel(); - if (EntityItem::contains(point) && model && _collisionGeometryResource && _collisionGeometryResource->isLoaded()) { + if (model && _collisionGeometryResource && _collisionGeometryResource->isLoaded() && _collisionGeometryResource->isHFMModelLoaded() && EntityItem::contains(point)) { glm::mat4 worldToHFMMatrix = model->getWorldToHFMMatrix(); glm::vec3 hfmPoint = worldToHFMMatrix * glm::vec4(point, 1.0f); return _collisionGeometryResource->getHFMModel().convexHullContains(hfmPoint); @@ -738,6 +741,9 @@ bool RenderableModelEntityItem::shouldBePhysical() const { // If we have a model, make sure it hasn't failed to download. // If it has, we'll report back that we shouldn't be physical so that physics aren't held waiting for us to be ready. physicalModelLoaded = model && !model->didVisualGeometryRequestFail(); + if (shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { + physicalModelLoaded &= _collisionGeometryResource && !_collisionGeometryResource->isFailed(); + } } else if (shapeType == SHAPE_TYPE_COMPOUND) { physicalModelLoaded = _collisionGeometryResource && !_collisionGeometryResource->isFailed(); } else if (shapeType != SHAPE_TYPE_NONE) { @@ -1054,6 +1060,10 @@ ModelEntityRenderer::ModelEntityRenderer(const EntityItemPointer& entity) : Pare void ModelEntityRenderer::setKey(bool didVisualGeometryRequestSucceed, const ModelPointer& model) { auto builder = ItemKey::Builder().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); + if (!_visible) { + builder.withInvisible(); + } + if (!_cullWithParent && model && model->isGroupCulled()) { builder.withMetaCullGroup(); } else if (_cullWithParent) { diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index e46bdc03b3..86d6f9ed86 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -961,7 +961,29 @@ void Model::setCauterized(bool cauterized, const render::ScenePointer& scene) { void Model::setPrimitiveMode(PrimitiveMode primitiveMode, const render::ScenePointer& scene) { if (_primitiveMode != primitiveMode) { _primitiveMode = primitiveMode; - updateRenderItemsKey(scene); + if (!scene) { + _needsFixupInScene = true; + return; + } + + bool useDualQuaternionSkinning = _useDualQuaternionSkinning; + std::unordered_map<int, bool> shouldInvalidatePayloadShapeKeyMap; + + for (auto& shape : _modelMeshRenderItemShapes) { + shouldInvalidatePayloadShapeKeyMap[shape.meshIndex] = shouldInvalidatePayloadShapeKey(shape.meshIndex); + } + + render::Transaction transaction; + + for (int i = 0; i < (int) _modelMeshRenderItemIDs.size(); i++) { + auto itemID = _modelMeshRenderItemIDs[i]; + auto meshIndex = _modelMeshRenderItemShapes[i].meshIndex; + bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex); + transaction.updateItem<ModelMeshPartPayload>(itemID, [invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning] (ModelMeshPartPayload& data) { + data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning); + }); + } + scene->enqueueTransaction(transaction); } }