diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 935dd4e796..613bd5d543 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -371,109 +371,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) { _model->updateRenderItems(); } - if (hasModel()) { - // Prepare the current frame - { - if (!_model || _needsModelReload) { - // TODO: this getModel() appears to be about 3% of model render time. We should optimize - PerformanceTimer perfTimer("getModel"); - auto renderer = qSharedPointerCast(args->_renderer); - getModel(renderer); - - // Remap textures immediately after loading to avoid flicker - remapTextures(); - } - - if (_model) { - if (hasRenderAnimation()) { - if (!jointsMapped()) { - QStringList modelJointNames = _model->getJointNames(); - mapJoints(modelJointNames); - } - } - - _jointDataLock.withWriteLock([&] { - getAnimationFrame(); - - // relay any inbound joint changes from scripts/animation/network to the model/rig - for (int index = 0; index < _localJointRotations.size(); index++) { - if (_localJointRotationsDirty[index]) { - glm::quat rotation = _localJointRotations[index]; - _model->setJointRotation(index, true, rotation, 1.0f); - _localJointRotationsDirty[index] = false; - } - } - for (int index = 0; index < _localJointTranslations.size(); index++) { - if (_localJointTranslationsDirty[index]) { - glm::vec3 translation = _localJointTranslations[index]; - _model->setJointTranslation(index, true, translation, 1.0f); - _localJointTranslationsDirty[index] = false; - } - } - }); - updateModelBounds(); - } - } - - // Enqueue updates for the next frame - if (_model) { - -#ifdef WANT_EXTRA_RENDER_DEBUGGING - // debugging... - gpu::Batch& batch = *args->_batch; - _model->renderDebugMeshBoxes(batch); -#endif - - render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); - - // FIXME: this seems like it could be optimized if we tracked our last known visible state in - // the renderable item. As it stands now the model checks it's visible/invisible state - // so most of the time we don't do anything in this function. - _model->setVisibleInScene(getVisible(), scene); - - // Remap textures for the next frame to avoid flicker - remapTextures(); - - // update whether the model should be showing collision mesh (this may flag for fixupInScene) - bool showingCollisionGeometry = (bool)(args->_debugFlags & (int)RenderArgs::RENDER_DEBUG_HULLS); - if (showingCollisionGeometry != _showCollisionGeometry) { - ShapeType type = getShapeType(); - _showCollisionGeometry = showingCollisionGeometry; - if (_showCollisionGeometry && type != SHAPE_TYPE_STATIC_MESH && type != SHAPE_TYPE_NONE) { - // NOTE: it is OK if _collisionMeshKey is nullptr - model::MeshPointer mesh = collisionMeshCache.getMesh(_collisionMeshKey); - // NOTE: the model will render the collisionGeometry if it has one - _model->setCollisionMesh(mesh); - } else { - // release mesh - if (_collisionMeshKey) { - collisionMeshCache.releaseMesh(_collisionMeshKey); - } - // clear model's collision geometry - model::MeshPointer mesh = nullptr; - _model->setCollisionMesh(mesh); - } - } - - if (_model->needsFixupInScene()) { - render::PendingChanges pendingChanges; - - _model->removeFromScene(scene, pendingChanges); - - render::Item::Status::Getters statusGetters; - makeEntityItemStatusGetters(getThisPointer(), statusGetters); - _model->addToScene(scene, pendingChanges, statusGetters); - - scene->enqueuePendingChanges(pendingChanges); - } - - auto& currentURL = getParsedModelURL(); - if (currentURL != _model->getURL()) { - // Defer setting the url to the render thread - getModel(_myRenderer); - } - } - } else { + if (!hasModel() || (_model && _model->didVisualGeometryRequestFail())) { static glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f); gpu::Batch& batch = *args->_batch; bool success; @@ -482,6 +380,109 @@ void RenderableModelEntityItem::render(RenderArgs* args) { batch.setModelTransform(shapeTransform); // we want to include the scale as well DependencyManager::get()->renderWireCubeInstance(batch, greenColor); } + return; + } + + // Prepare the current frame + { + if (!_model || _needsModelReload) { + // TODO: this getModel() appears to be about 3% of model render time. We should optimize + PerformanceTimer perfTimer("getModel"); + auto renderer = qSharedPointerCast(args->_renderer); + getModel(renderer); + + // Remap textures immediately after loading to avoid flicker + remapTextures(); + } + + if (_model) { + if (hasRenderAnimation()) { + if (!jointsMapped()) { + QStringList modelJointNames = _model->getJointNames(); + mapJoints(modelJointNames); + } + } + + _jointDataLock.withWriteLock([&] { + getAnimationFrame(); + + // relay any inbound joint changes from scripts/animation/network to the model/rig + for (int index = 0; index < _localJointRotations.size(); index++) { + if (_localJointRotationsDirty[index]) { + glm::quat rotation = _localJointRotations[index]; + _model->setJointRotation(index, true, rotation, 1.0f); + _localJointRotationsDirty[index] = false; + } + } + for (int index = 0; index < _localJointTranslations.size(); index++) { + if (_localJointTranslationsDirty[index]) { + glm::vec3 translation = _localJointTranslations[index]; + _model->setJointTranslation(index, true, translation, 1.0f); + _localJointTranslationsDirty[index] = false; + } + } + }); + updateModelBounds(); + } + } + + // Enqueue updates for the next frame + if (_model) { + +#ifdef WANT_EXTRA_RENDER_DEBUGGING + // debugging... + gpu::Batch& batch = *args->_batch; + _model->renderDebugMeshBoxes(batch); +#endif + + render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); + + // FIXME: this seems like it could be optimized if we tracked our last known visible state in + // the renderable item. As it stands now the model checks it's visible/invisible state + // so most of the time we don't do anything in this function. + _model->setVisibleInScene(getVisible(), scene); + + // Remap textures for the next frame to avoid flicker + remapTextures(); + + // update whether the model should be showing collision mesh (this may flag for fixupInScene) + bool showingCollisionGeometry = (bool)(args->_debugFlags & (int)RenderArgs::RENDER_DEBUG_HULLS); + if (showingCollisionGeometry != _showCollisionGeometry) { + ShapeType type = getShapeType(); + _showCollisionGeometry = showingCollisionGeometry; + if (_showCollisionGeometry && type != SHAPE_TYPE_STATIC_MESH && type != SHAPE_TYPE_NONE) { + // NOTE: it is OK if _collisionMeshKey is nullptr + model::MeshPointer mesh = collisionMeshCache.getMesh(_collisionMeshKey); + // NOTE: the model will render the collisionGeometry if it has one + _model->setCollisionMesh(mesh); + } else { + // release mesh + if (_collisionMeshKey) { + collisionMeshCache.releaseMesh(_collisionMeshKey); + } + // clear model's collision geometry + model::MeshPointer mesh = nullptr; + _model->setCollisionMesh(mesh); + } + } + + if (_model->needsFixupInScene()) { + render::PendingChanges pendingChanges; + + _model->removeFromScene(scene, pendingChanges); + + render::Item::Status::Getters statusGetters; + makeEntityItemStatusGetters(getThisPointer(), statusGetters); + _model->addToScene(scene, pendingChanges, statusGetters); + + scene->enqueuePendingChanges(pendingChanges); + } + + auto& currentURL = getParsedModelURL(); + if (currentURL != _model->getURL()) { + // Defer setting the url to the render thread + getModel(_myRenderer); + } } } @@ -587,6 +588,10 @@ EntityItemProperties RenderableModelEntityItem::getProperties(EntityPropertyFlag return properties; } +bool RenderableModelEntityItem::supportsDetailedRayIntersection() const { + return _model && _model->isLoaded(); +} + bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, void** intersectedObject, bool precisionPicking) const { diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index bac2118326..057ca36e13 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -46,7 +46,7 @@ public: void updateModelBounds(); virtual void render(RenderArgs* args) override; - virtual bool supportsDetailedRayIntersection() const override { return true; } + virtual bool supportsDetailedRayIntersection() const override; virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal,