From b0a0293e6e0a19b0efa911c96a23ea9065f20208 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 28 Jul 2016 07:31:32 -0700 Subject: [PATCH] move compoundResource out of Model class --- .../src/EntityTreeRenderer.cpp | 18 -------- .../src/EntityTreeRenderer.h | 1 - .../src/RenderableModelEntityItem.cpp | 46 +++++++++++++------ .../src/RenderableModelEntityItem.h | 2 + libraries/entities/src/EntityTree.h | 1 - libraries/render-utils/src/Model.cpp | 43 ++++------------- libraries/render-utils/src/Model.h | 9 ---- 7 files changed, 42 insertions(+), 78 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 39031acaa1..209a27739b 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -499,22 +499,6 @@ ModelPointer EntityTreeRenderer::getModelForEntityItem(EntityItemPointer entityI return result; } -const FBXGeometry* EntityTreeRenderer::getCollisionGeometryForEntity(EntityItemPointer entityItem) { - const FBXGeometry* result = NULL; - - if (entityItem->getType() == EntityTypes::Model) { - std::shared_ptr modelEntityItem = - std::dynamic_pointer_cast(entityItem); - if (modelEntityItem->hasCompoundShapeURL()) { - ModelPointer model = modelEntityItem->getModel(this); - if (model && model->isCollisionLoaded()) { - result = &model->getCollisionFBXGeometry(); - } - } - } - return result; -} - void EntityTreeRenderer::processEraseMessage(ReceivedMessage& message, const SharedNodePointer& sourceNode) { std::static_pointer_cast(_tree)->processEraseMessage(message, sourceNode); } @@ -536,7 +520,6 @@ ModelPointer EntityTreeRenderer::allocateModel(const QString& url, const QString model->setLoadingPriority(loadingPriority); model->init(); model->setURL(QUrl(url)); - model->setCollisionModelURL(QUrl(collisionUrl)); return model; } @@ -553,7 +536,6 @@ ModelPointer EntityTreeRenderer::updateModel(ModelPointer model, const QString& } model->setURL(QUrl(newUrl)); - model->setCollisionModelURL(QUrl(collisionUrl)); return model; } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 5d634fa6ca..5664f33041 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -65,7 +65,6 @@ public: virtual const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem) override; virtual ModelPointer getModelForEntityItem(EntityItemPointer entityItem) override; - virtual const FBXGeometry* getCollisionGeometryForEntity(EntityItemPointer entityItem) override; /// clears the tree virtual void clear() override; diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index b80a003e8e..84646d7607 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -494,7 +494,7 @@ ModelPointer RenderableModelEntityItem::getModel(EntityTreeRenderer* renderer) { _model = _myRenderer->allocateModel(getModelURL(), getCompoundShapeURL(), renderer->getEntityLoadingPriority(*this)); _needsInitialSimulation = true; // If we need to change URLs, update it *after rendering* (to avoid access violations) - } else if ((QUrl(getModelURL()) != _model->getURL() || QUrl(getCompoundShapeURL()) != _model->getCollisionURL())) { + } else if (QUrl(getModelURL()) != _model->getURL()) { QMetaObject::invokeMethod(_myRenderer, "updateModel", Qt::QueuedConnection, Q_ARG(ModelPointer, _model), Q_ARG(const QString&, getModelURL()), @@ -566,6 +566,18 @@ bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& ori face, surfaceNormal, extraInfo, precisionPicking); } +void RenderableModelEntityItem::setShapeType(ShapeType type) { + ModelEntityItem::setShapeType(type); + if (_shapeType == SHAPE_TYPE_COMPOUND) { + if (!_compoundShapeResource && !_compoundShapeURL.isEmpty()) { + _compoundShapeResource = DependencyManager::get()->getGeometryResource(getCompoundShapeURL()); + } + } else if (_compoundShapeResource && !_compoundShapeURL.isEmpty()) { + // the compoundURL has been set but the shapeType does not agree + _compoundShapeResource.reset(); + } +} + void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) { auto currentCompoundShapeURL = getCompoundShapeURL(); ModelEntityItem::setCompoundShapeURL(url); @@ -575,6 +587,9 @@ void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) { if (tree) { QMetaObject::invokeMethod(tree.get(), "callLoader", Qt::QueuedConnection, Q_ARG(EntityItemID, getID())); } + if (_shapeType == SHAPE_TYPE_COMPOUND) { + _compoundShapeResource = DependencyManager::get()->getGeometryResource(url); + } } } @@ -582,7 +597,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() { ShapeType type = getShapeType(); if (type == SHAPE_TYPE_COMPOUND) { - if (!_model || _model->getCollisionURL().isEmpty()) { + if (!_model || _compoundShapeURL.isEmpty()) { EntityTreePointer tree = getTree(); if (tree) { QMetaObject::invokeMethod(tree.get(), "callLoader", Qt::QueuedConnection, Q_ARG(EntityItemID, getID())); @@ -595,15 +610,18 @@ bool RenderableModelEntityItem::isReadyToComputeShape() { return false; } - if (_model->isLoaded() && _model->isCollisionLoaded()) { - // 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 - PerformanceTimer perfTimer("_model->simulate"); - doInitialModelSimulation(); + if (_model->isLoaded()) { + if (_compoundShapeResource && _compoundShapeResource->isLoaded()) { + // 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 + PerformanceTimer perfTimer("_model->simulate"); + doInitialModelSimulation(); + } + return true; + } else if (!_compoundShapeURL.isEmpty()) { + _compoundShapeResource = DependencyManager::get()->getGeometryResource(_compoundShapeURL); } - - return true; } // the model is still being downloaded. @@ -625,8 +643,8 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { // should never fall in here when collision model not fully loaded // hence we assert that all geometries exist and are loaded - assert(_model && _model->isLoaded() && _model->isCollisionLoaded()); - const FBXGeometry& collisionGeometry = _model->getCollisionFBXGeometry(); + assert(_model && _model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded()); + const FBXGeometry& collisionGeometry = _compoundShapeResource->getFBXGeometry(); ShapeInfo::PointCollection& pointCollection = info.getPointCollection(); pointCollection.clear(); @@ -956,8 +974,8 @@ void RenderableModelEntityItem::setCollisionShape(const btCollisionShape* shape) } bool RenderableModelEntityItem::contains(const glm::vec3& point) const { - if (EntityItem::contains(point) && _model && _model->isCollisionLoaded()) { - return _model->getCollisionFBXGeometry().convexHullContains(worldToEntity(point)); + if (EntityItem::contains(point) && _model && _compoundShapeResource && _compoundShapeResource->isLoaded()) { + return _compoundShapeResource->getFBXGeometry().convexHullContains(worldToEntity(point)); } return false; diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 16cd9c8bc5..09468dfae0 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -56,6 +56,7 @@ public: virtual bool needsToCallUpdate() const override; virtual void update(const quint64& now) override; + virtual void setShapeType(ShapeType type) override; virtual void setCompoundShapeURL(const QString& url) override; virtual bool isReadyToComputeShape() override; @@ -100,6 +101,7 @@ private: QVariantMap parseTexturesToMap(QString textures); void remapTextures(); + GeometryResource::Pointer _compoundShapeResource; ModelPointer _model = nullptr; bool _needsInitialSimulation = true; bool _needsModelReload = true; diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 15daf3bf3c..7dc999aac2 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -40,7 +40,6 @@ class EntityItemFBXService { public: virtual const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem) = 0; virtual ModelPointer getModelForEntityItem(EntityItemPointer entityItem) = 0; - virtual const FBXGeometry* getCollisionGeometryForEntity(EntityItemPointer entityItem) = 0; }; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index ce8ebfb00a..d1269f769a 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -82,7 +82,6 @@ Model::Model(RigPointer rig, QObject* parent) : _renderGeometry(), _collisionGeometry(), _renderWatcher(_renderGeometry), - _collisionWatcher(_collisionGeometry), _translation(0.0f), _rotation(), _scale(1.0f, 1.0f, 1.0f), @@ -111,7 +110,6 @@ Model::Model(RigPointer rig, QObject* parent) : setSnapModelToRegistrationPoint(true, glm::vec3(0.5f)); connect(&_renderWatcher, &GeometryResourceWatcher::finished, this, &Model::loadURLFinished); - connect(&_collisionWatcher, &GeometryResourceWatcher::finished, this, &Model::loadCollisionModelURLFinished); } Model::~Model() { @@ -121,17 +119,15 @@ Model::~Model() { AbstractViewStateInterface* Model::_viewState = NULL; void Model::setShowCollisionMesh(bool value) { - if (_readyToShowCollisionGeometry) { - if (_showCollisionGeometry != value) { - _showCollisionGeometry = value; - _needsFixupInScene = true; - } + if (_showCollisionGeometry != value) { + _showCollisionGeometry = value; + _needsFixupInScene = true; } } bool Model::needsFixupInScene() const { if ((_needsFixupInScene || !_addedToScene) && !_needsReload && isLoaded()) { - if (_showCollisionGeometry && _readyToShowCollisionGeometry && _collisionGeometry) { + if (_showCollisionGeometry && _collisionGeometry) { return true; } if (!_meshStates.isEmpty() || (_renderGeometry && _renderGeometry->getMeshes().empty())) { @@ -614,13 +610,13 @@ void Model::setVisibleInScene(bool newValue, std::shared_ptr scen bool Model::addToScene(std::shared_ptr scene, render::PendingChanges& pendingChanges, render::Item::Status::Getters& statusGetters) { - bool readyToRender = (_showCollisionGeometry && _readyToShowCollisionGeometry && _collisionGeometry) || isLoaded(); + bool readyToRender = (_showCollisionGeometry && _collisionGeometry) || isLoaded(); if (!_addedToScene && readyToRender) { createRenderItemSet(); } bool somethingAdded = false; - if (_showCollisionGeometry && _readyToShowCollisionGeometry && _collisionGeometry) { + if (_showCollisionGeometry && _collisionGeometry) { if (_collisionRenderItems.empty()) { foreach (auto renderItem, _collisionRenderItemsSet) { auto item = scene->allocateID(); @@ -864,23 +860,6 @@ void Model::loadURLFinished(bool success) { emit setURLFinished(success); } -void Model::setCollisionModelURL(const QUrl& url) { - if (_collisionUrl == url && _collisionWatcher.getURL() == url) { - return; - } - _collisionUrl = url; - _collisionGeometryRequestFailed = false; - _collisionWatcher.setResource(DependencyManager::get()->getGeometryResource(url)); -} - -void Model::loadCollisionModelURLFinished(bool success) { - if (!success) { - _collisionGeometryRequestFailed = true; - } - - emit setCollisionModelURLFinished(success); -} - bool Model::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position) const { return _rig->getJointPositionInWorldFrame(jointIndex, position, _translation, _rotation); } @@ -1258,7 +1237,7 @@ AABox Model::getRenderableMeshBound() const { } void Model::createRenderItemSet() { - if (_showCollisionGeometry && _readyToShowCollisionGeometry && _collisionGeometry) { + if (_showCollisionGeometry && _collisionGeometry) { if (_collisionRenderItemsSet.empty()) { createCollisionRenderItemSet(); } @@ -1353,7 +1332,7 @@ bool Model::initWhenReady(render::ScenePointer scene) { render::PendingChanges pendingChanges; bool addedPendingChanges = false; - if (_showCollisionGeometry && _readyToShowCollisionGeometry && _collisionGeometry) { + if (_showCollisionGeometry && _collisionGeometry) { foreach (auto renderItem, _collisionRenderItemsSet) { auto item = scene->allocateID(); auto renderPayload = std::make_shared(renderItem); @@ -1395,14 +1374,8 @@ public: }; void Model::setCollisionMesh(model::MeshPointer mesh) { - _collisionWatcher.stopWatching(); _collisionGeometry = std::make_shared(mesh); - // HACK: we don't want to show the _collisionGeometry until we're ready (e.g. it has been created) - // hence we track whether it has been created using _readyToShowCollisionGeoemtry, because there - // is an ambiguous case where _collisionGeometry is valid (from CompoundURL) but has not yet been - // properly computed (zeroed offset transform) using the CollisionRenderMeshCache. - // // TODO: At the moment we create the collision mesh for every model that has a collision shape // as soon as we know the shape, but we SHOULD only ever create the render mesh when we need it. if (_showCollisionGeometry) { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 3fc681261a..edb8f0b6ae 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -115,7 +115,6 @@ public: const QVector& vertices, const QVector& normals); bool isLoaded() const { return (bool)_renderGeometry; } - bool isCollisionLoaded() const { return (bool)_collisionGeometry; } void setIsWireframe(bool isWireframe) { _isWireframe = isWireframe; } bool isWireframe() const { return _isWireframe; } @@ -142,13 +141,9 @@ public: /// Provided as a convenience, will crash if !isLoaded() // And so that getGeometry() isn't chained everywhere const FBXGeometry& getFBXGeometry() const { assert(isLoaded()); return _renderGeometry->getFBXGeometry(); } - /// Provided as a convenience, will crash if !isCollisionLoaded() - const FBXGeometry& getCollisionFBXGeometry() const { assert(isCollisionLoaded()); return _collisionGeometry->getFBXGeometry(); } // Set the model to use for collisions. // Should only be called from the model's rendering thread to avoid access violations of changed geometry. - Q_INVOKABLE void setCollisionModelURL(const QUrl& url); - const QUrl& getCollisionURL() const { return _collisionUrl; } bool isActive() const { return isLoaded(); } @@ -246,7 +241,6 @@ public: public slots: void loadURLFinished(bool success); - void loadCollisionModelURLFinished(bool success); signals: void setURLFinished(bool success); @@ -288,7 +282,6 @@ protected: Geometry::Pointer _collisionGeometry; GeometryResourceWatcher _renderWatcher; - GeometryResourceWatcher _collisionWatcher; glm::vec3 _translation; glm::quat _rotation; @@ -356,7 +349,6 @@ protected: QVector _blendshapeCoefficients; QUrl _url; - QUrl _collisionUrl; bool _isVisible; gpu::Buffers _blendedVertexBuffers; @@ -404,7 +396,6 @@ protected: bool _needsReload { true }; bool _needsUpdateClusterMatrices { true }; bool _showCollisionGeometry { false }; - bool _readyToShowCollisionGeometry { false }; mutable bool _needsUpdateTextures { true }; friend class ModelMeshPartPayload;