From f6681d4b3dd39424fa1478a07795dd4d1ac5038f Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Thu, 7 Jul 2016 13:07:43 -0700 Subject: [PATCH 1/8] remove unused cruft --- libraries/render-utils/src/GeometryCache.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 1bfdc1798e..385f2c6fa4 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -402,8 +402,6 @@ private: QHash<Vec2FloatPairPair, GridBuffer> _gridBuffers; QHash<int, GridBuffer> _registeredGridBuffers; - QHash<QUrl, QWeakPointer<NetworkGeometry> > _networkGeometry; - gpu::ShaderPointer _simpleShader; gpu::ShaderPointer _unlitShader; static render::ShapePipelinePointer _simplePipeline; From 9f7d2cf2630832aa25f9af9a2e78539d9129c05f Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Thu, 7 Jul 2016 13:08:18 -0700 Subject: [PATCH 2/8] NetworkGeometry --> GeometryResourceWatcher Model class gets render and collision geometries with watchers also changed names for readability --- .../src/model-networking/ModelCache.cpp | 76 +++++++++------- .../src/model-networking/ModelCache.h | 87 +++++++++---------- .../render-utils/src/MeshPartPayload.cpp | 6 +- libraries/render-utils/src/Model.cpp | 77 ++++++++-------- libraries/render-utils/src/Model.h | 33 ++++--- 5 files changed, 144 insertions(+), 135 deletions(-) diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 40388e6123..afe86e0d1e 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -70,7 +70,7 @@ void GeometryMappingResource::downloadFinished(const QByteArray& data) { auto modelCache = DependencyManager::get<ModelCache>(); GeometryExtra extra{ mapping, _textureBaseUrl }; - // Get the raw GeometryResource, not the wrapped NetworkGeometry + // Get the raw GeometryResource _geometryResource = modelCache->getResource(url, QUrl(), &extra).staticCast<GeometryResource>(); // Avoid caching nested resources - their references will be held by the parent _geometryResource->_isCacheable = false; @@ -90,8 +90,8 @@ void GeometryMappingResource::downloadFinished(const QByteArray& data) { void GeometryMappingResource::onGeometryMappingLoaded(bool success) { if (success && _geometryResource) { - _geometry = _geometryResource->_geometry; - _shapes = _geometryResource->_shapes; + _fbxGeometry = _geometryResource->_fbxGeometry; + _meshParts = _geometryResource->_meshParts; _meshes = _geometryResource->_meshes; _materials = _geometryResource->_materials; @@ -200,31 +200,31 @@ void GeometryDefinitionResource::downloadFinished(const QByteArray& data) { void GeometryDefinitionResource::setGeometryDefinition(FBXGeometry::Pointer fbxGeometry) { // Assume ownership of the geometry pointer - _geometry = fbxGeometry; + _fbxGeometry = fbxGeometry; // Copy materials QHash<QString, size_t> materialIDAtlas; - for (const FBXMaterial& material : _geometry->materials) { + for (const FBXMaterial& material : _fbxGeometry->materials) { materialIDAtlas[material.materialID] = _materials.size(); _materials.push_back(std::make_shared<NetworkMaterial>(material, _textureBaseUrl)); } - std::shared_ptr<NetworkMeshes> meshes = std::make_shared<NetworkMeshes>(); - std::shared_ptr<NetworkShapes> shapes = std::make_shared<NetworkShapes>(); + std::shared_ptr<GeometryMeshes> meshes = std::make_shared<GeometryMeshes>(); + std::shared_ptr<GeometryMeshParts> shapes = std::make_shared<GeometryMeshParts>(); int meshID = 0; - for (const FBXMesh& mesh : _geometry->meshes) { + for (const FBXMesh& mesh : _fbxGeometry->meshes) { // Copy mesh pointers meshes->emplace_back(mesh._mesh); int partID = 0; for (const FBXMeshPart& part : mesh.parts) { // Construct local shapes - shapes->push_back(std::make_shared<NetworkShape>(meshID, partID, (int)materialIDAtlas[part.materialID])); + shapes->push_back(std::make_shared<MeshPart>(meshID, partID, (int)materialIDAtlas[part.materialID])); partID++; } meshID++; } _meshes = meshes; - _shapes = shapes; + _meshParts = shapes; finishedLoading(true); } @@ -250,17 +250,15 @@ QSharedPointer<Resource> ModelCache::createResource(const QUrl& url, const QShar return QSharedPointer<Resource>(resource, &Resource::deleter); } -std::shared_ptr<NetworkGeometry> ModelCache::getGeometry(const QUrl& url, const QVariantHash& mapping, const QUrl& textureBaseUrl) { +GeometryResource::Pointer ModelCache::fetchResource(const QUrl& url, const QVariantHash& mapping, const QUrl& textureBaseUrl) { GeometryExtra geometryExtra = { mapping, textureBaseUrl }; GeometryResource::Pointer resource = getResource(url, QUrl(), &geometryExtra).staticCast<GeometryResource>(); if (resource) { if (resource->isLoaded() && resource->shouldSetTextures()) { resource->setTextures(); } - return std::make_shared<NetworkGeometry>(resource); - } else { - return NetworkGeometry::Pointer(); } + return resource; } const QVariantMap Geometry::getTextures() const { @@ -278,9 +276,9 @@ const QVariantMap Geometry::getTextures() const { // FIXME: The materials should only be copied when modified, but the Model currently caches the original Geometry::Geometry(const Geometry& geometry) { - _geometry = geometry._geometry; + _fbxGeometry = geometry._fbxGeometry; _meshes = geometry._meshes; - _shapes = geometry._shapes; + _meshParts = geometry._meshParts; _materials.reserve(geometry._materials.size()); for (const auto& material : geometry._materials) { @@ -337,8 +335,8 @@ bool Geometry::areTexturesLoaded() const { } const std::shared_ptr<const NetworkMaterial> Geometry::getShapeMaterial(int shapeID) const { - if ((shapeID >= 0) && (shapeID < (int)_shapes->size())) { - int materialID = _shapes->at(shapeID)->materialID; + if ((shapeID >= 0) && (shapeID < (int)_meshParts->size())) { + int materialID = _meshParts->at(shapeID)->materialID; if ((materialID >= 0) && (materialID < (int)_materials.size())) { return _materials[materialID]; } @@ -352,7 +350,7 @@ void GeometryResource::deleter() { } void GeometryResource::setTextures() { - for (const FBXMaterial& material : _geometry->materials) { + for (const FBXMaterial& material : _fbxGeometry->materials) { _materials.push_back(std::make_shared<NetworkMaterial>(material, _textureBaseUrl)); } } @@ -361,26 +359,40 @@ void GeometryResource::resetTextures() { _materials.clear(); } -NetworkGeometry::NetworkGeometry(const GeometryResource::Pointer& networkGeometry) : _resource(networkGeometry) { - connect(_resource.data(), &Resource::finished, this, &NetworkGeometry::resourceFinished); - connect(_resource.data(), &Resource::onRefresh, this, &NetworkGeometry::resourceRefreshed); +void GeometryResourceWatcher::startWatching() { + connect(_resource.data(), &Resource::finished, this, &GeometryResourceWatcher::resourceFinished); + connect(_resource.data(), &Resource::onRefresh, this, &GeometryResourceWatcher::resourceRefreshed); if (_resource->isLoaded()) { resourceFinished(!_resource->getURL().isEmpty()); } } -void NetworkGeometry::resourceFinished(bool success) { - // FIXME: Model is not set up to handle a refresh - if (_instance) { - return; - } - if (success) { - _instance = std::make_shared<Geometry>(*_resource); - } - emit finished(success); +void GeometryResourceWatcher::stopWatching() { + disconnect(_resource.data(), &Resource::finished, this, &GeometryResourceWatcher::resourceFinished); + disconnect(_resource.data(), &Resource::onRefresh, this, &GeometryResourceWatcher::resourceRefreshed); } -void NetworkGeometry::resourceRefreshed() { +void GeometryResourceWatcher::setResource(GeometryResource::Pointer resource) { + if (_resource) { + stopWatching(); + } + _resource = resource; + if (_resource) { + if (_resource->isLoaded()) { + _geometryRef = std::make_shared<Geometry>(*_resource); + } else { + startWatching(); + } + } +} + +void GeometryResourceWatcher::resourceFinished(bool success) { + if (success) { + _geometryRef = std::make_shared<Geometry>(*_resource); + } +} + +void GeometryResourceWatcher::resourceRefreshed() { // FIXME: Model is not set up to handle a refresh // _instance.reset(); } diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index f15e1106e2..c450f96846 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -22,52 +22,30 @@ #include "TextureCache.h" // Alias instead of derive to avoid copying -using NetworkMesh = model::Mesh; class NetworkTexture; class NetworkMaterial; -class NetworkShape; -class NetworkGeometry; +class MeshPart; class GeometryMappingResource; -/// Stores cached model geometries. -class ModelCache : public ResourceCache, public Dependency { - Q_OBJECT - SINGLETON_DEPENDENCY - -public: - /// Loads a model geometry from the specified URL. - std::shared_ptr<NetworkGeometry> getGeometry(const QUrl& url, - const QVariantHash& mapping = QVariantHash(), const QUrl& textureBaseUrl = QUrl()); - -protected: - friend class GeometryMappingResource; - - virtual QSharedPointer<Resource> createResource(const QUrl& url, const QSharedPointer<Resource>& fallback, - const void* extra); - -private: - ModelCache(); - virtual ~ModelCache() = default; -}; - class Geometry { public: using Pointer = std::shared_ptr<Geometry>; + using WeakPointer = std::weak_ptr<Geometry>; Geometry() = default; Geometry(const Geometry& geometry); // Immutable over lifetime - using NetworkMeshes = std::vector<std::shared_ptr<const NetworkMesh>>; - using NetworkShapes = std::vector<std::shared_ptr<const NetworkShape>>; + using GeometryMeshes = std::vector<std::shared_ptr<const model::Mesh>>; + using GeometryMeshParts = std::vector<std::shared_ptr<const MeshPart>>; // Mutable, but must retain structure of vector using NetworkMaterials = std::vector<std::shared_ptr<NetworkMaterial>>; - const FBXGeometry& getGeometry() const { return *_geometry; } - const NetworkMeshes& getMeshes() const { return *_meshes; } + const FBXGeometry& getFBXGeometry() const { return *_fbxGeometry; } + const GeometryMeshes& getMeshes() const { return *_meshes; } const std::shared_ptr<const NetworkMaterial> getShapeMaterial(int shapeID) const; const QVariantMap getTextures() const; @@ -79,9 +57,9 @@ protected: friend class GeometryMappingResource; // Shared across all geometries, constant throughout lifetime - std::shared_ptr<const FBXGeometry> _geometry; - std::shared_ptr<const NetworkMeshes> _meshes; - std::shared_ptr<const NetworkShapes> _shapes; + std::shared_ptr<const FBXGeometry> _fbxGeometry; + std::shared_ptr<const GeometryMeshes> _meshes; + std::shared_ptr<const GeometryMeshParts> _meshParts; // Copied to each geometry, mutable throughout lifetime via setTextures NetworkMaterials _materials; @@ -108,7 +86,7 @@ protected: // Geometries may not hold onto textures while cached - that is for the texture cache // Instead, these methods clear and reset textures from the geometry when caching/loading - bool shouldSetTextures() const { return _geometry && _materials.empty(); } + bool shouldSetTextures() const { return _fbxGeometry && _materials.empty(); } void setTextures(); void resetTextures(); @@ -118,22 +96,21 @@ protected: bool _isCacheable { true }; }; -class NetworkGeometry : public QObject { +class GeometryResourceWatcher : public QObject { Q_OBJECT public: - using Pointer = std::shared_ptr<NetworkGeometry>; + using Pointer = std::shared_ptr<GeometryResourceWatcher>; - NetworkGeometry() = delete; - NetworkGeometry(const GeometryResource::Pointer& networkGeometry); + GeometryResourceWatcher() = delete; + GeometryResourceWatcher(Geometry::Pointer& geometryPtr) : _geometryRef(geometryPtr) {} - const QUrl& getURL() { return _resource->getURL(); } + void setResource(GeometryResource::Pointer resource); - /// Returns the geometry, if it is loaded (must be checked!) - const Geometry::Pointer& getGeometry() { return _instance; } + const QUrl& getURL() const { return _resource->getURL(); } -signals: - /// Emitted when the NetworkGeometry loads (or fails to) - void finished(bool success); +private: + void startWatching(); + void stopWatching(); private slots: void resourceFinished(bool success); @@ -141,7 +118,27 @@ private slots: private: GeometryResource::Pointer _resource; - Geometry::Pointer _instance { nullptr }; + Geometry::Pointer& _geometryRef; +}; + +/// Stores cached model geometries. +class ModelCache : public ResourceCache, public Dependency { + Q_OBJECT + SINGLETON_DEPENDENCY + +public: + GeometryResource::Pointer fetchResource(const QUrl& url, + const QVariantHash& mapping = QVariantHash(), const QUrl& textureBaseUrl = QUrl()); + +protected: + friend class GeometryMappingResource; + + virtual QSharedPointer<Resource> createResource(const QUrl& url, const QSharedPointer<Resource>& fallback, + const void* extra); + +private: + ModelCache(); + virtual ~ModelCache() = default; }; class NetworkMaterial : public model::Material { @@ -185,9 +182,9 @@ private: bool _isOriginal { true }; }; -class NetworkShape { +class MeshPart { public: - NetworkShape(int mesh, int part, int material) : meshID { mesh }, partID { part }, materialID { material } {} + MeshPart(int mesh, int part, int material) : meshID { mesh }, partID { part }, materialID { material } {} int meshID { -1 }; int partID { -1 }; int materialID { -1 }; diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 08c8dc23b4..4746b5a0c5 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -310,7 +310,7 @@ ModelMeshPartPayload::ModelMeshPartPayload(Model* model, int _meshIndex, int par _shapeID(shapeIndex) { assert(_model && _model->isLoaded()); - auto& modelMesh = _model->getGeometry()->getGeometry()->getMeshes().at(_meshIndex); + auto& modelMesh = _model->getGeometry()->getMeshes().at(_meshIndex); updateMeshPart(modelMesh, partIndex); updateTransform(transform, offsetTransform); @@ -331,7 +331,7 @@ void ModelMeshPartPayload::initCache() { _isBlendShaped = !mesh.blendshapes.isEmpty(); } - auto networkMaterial = _model->getGeometry()->getGeometry()->getShapeMaterial(_shapeID); + auto networkMaterial = _model->getGeometry()->getShapeMaterial(_shapeID); if (networkMaterial) { _drawMaterial = networkMaterial; }; @@ -384,7 +384,7 @@ ItemKey ModelMeshPartPayload::getKey() const { ShapeKey ModelMeshPartPayload::getShapeKey() const { assert(_model->isLoaded()); const FBXGeometry& geometry = _model->getFBXGeometry(); - const auto& networkMeshes = _model->getGeometry()->getGeometry()->getMeshes(); + const auto& networkMeshes = _model->getGeometry()->getMeshes(); // guard against partially loaded meshes if (_meshIndex >= (int)networkMeshes.size() || _meshIndex >= (int)geometry.meshes.size() || _meshIndex >= (int)_model->_meshStates.size()) { diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 43eced3107..ab9e0e7403 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -31,7 +31,7 @@ using namespace std; int nakedModelPointerTypeId = qRegisterMetaType<ModelPointer>(); -int weakNetworkGeometryPointerTypeId = qRegisterMetaType<std::weak_ptr<NetworkGeometry> >(); +int weakGeometryResourceBridgePointerTypeId = qRegisterMetaType<Geometry::WeakPointer >(); int vec3VectorTypeId = qRegisterMetaType<QVector<glm::vec3> >(); float Model::FAKE_DIMENSION_PLACEHOLDER = -1.0f; #define HTTP_INVALID_COM "http://invalid.com" @@ -79,6 +79,10 @@ void initCollisionHullMaterials() { Model::Model(RigPointer rig, QObject* parent) : QObject(parent), + _renderGeometry(), + _collisionGeometry(), + _renderWatcher(_renderGeometry), + _collisionWatcher(_collisionGeometry), _translation(0.0f), _rotation(), _scale(1.0f, 1.0f, 1.0f), @@ -98,7 +102,6 @@ Model::Model(RigPointer rig, QObject* parent) : _calculatedMeshTrianglesValid(false), _meshGroupsKnown(false), _isWireframe(false), - _renderCollisionHull(false), _rig(rig) { // we may have been created in the network thread, but we live in the main thread if (_viewState) { @@ -116,7 +119,7 @@ AbstractViewStateInterface* Model::_viewState = NULL; bool Model::needsFixupInScene() const { if (readyToAddToScene()) { - if (_needsUpdateTextures && _geometry->getGeometry()->areTexturesLoaded()) { + if (_needsUpdateTextures && _renderGeometry->areTexturesLoaded()) { _needsUpdateTextures = false; return true; } @@ -793,13 +796,13 @@ int Model::getLastFreeJointIndex(int jointIndex) const { void Model::setTextures(const QVariantMap& textures) { if (isLoaded()) { _needsUpdateTextures = true; - _geometry->getGeometry()->setTextures(textures); + _renderGeometry->setTextures(textures); } } void Model::setURL(const QUrl& url) { // don't recreate the geometry if it's the same URL - if (_url == url && _geometry && _geometry->getURL() == url) { + if (_url == url && _renderWatcher.getURL() == url) { return; } @@ -818,7 +821,7 @@ void Model::setURL(const QUrl& url) { invalidCalculatedMeshBoxes(); deleteGeometry(); - _geometry = DependencyManager::get<ModelCache>()->getGeometry(url); + _renderWatcher.setResource(DependencyManager::get<ModelCache>()->fetchResource(url)); onInvalidate(); } @@ -827,7 +830,7 @@ void Model::setCollisionModelURL(const QUrl& url) { return; } _collisionUrl = url; - _collisionGeometry = DependencyManager::get<ModelCache>()->getGeometry(url); + _collisionWatcher.setResource(DependencyManager::get<ModelCache>()->fetchResource(url)); } bool Model::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position) const { @@ -883,7 +886,7 @@ QStringList Model::getJointNames() const { class Blender : public QRunnable { public: - Blender(ModelPointer model, int blendNumber, const std::weak_ptr<NetworkGeometry>& geometry, + Blender(ModelPointer model, int blendNumber, const Geometry::WeakPointer& geometry, const QVector<FBXMesh>& meshes, const QVector<float>& blendshapeCoefficients); virtual void run(); @@ -892,12 +895,12 @@ private: ModelPointer _model; int _blendNumber; - std::weak_ptr<NetworkGeometry> _geometry; + Geometry::WeakPointer _geometry; QVector<FBXMesh> _meshes; QVector<float> _blendshapeCoefficients; }; -Blender::Blender(ModelPointer model, int blendNumber, const std::weak_ptr<NetworkGeometry>& geometry, +Blender::Blender(ModelPointer model, int blendNumber, const Geometry::WeakPointer& geometry, const QVector<FBXMesh>& meshes, const QVector<float>& blendshapeCoefficients) : _model(model), _blendNumber(blendNumber), @@ -940,7 +943,7 @@ void Blender::run() { // post the result to the geometry cache, which will dispatch to the model if still alive QMetaObject::invokeMethod(DependencyManager::get<ModelBlender>().data(), "setBlendedVertices", Q_ARG(ModelPointer, _model), Q_ARG(int, _blendNumber), - Q_ARG(const std::weak_ptr<NetworkGeometry>&, _geometry), Q_ARG(const QVector<glm::vec3>&, vertices), + Q_ARG(const Geometry::WeakPointer&, _geometry), Q_ARG(const QVector<glm::vec3>&, vertices), Q_ARG(const QVector<glm::vec3>&, normals)); } @@ -1151,7 +1154,7 @@ bool Model::maybeStartBlender() { if (isLoaded()) { const FBXGeometry& fbxGeometry = getFBXGeometry(); if (fbxGeometry.hasBlendedMeshes()) { - QThreadPool::globalInstance()->start(new Blender(getThisPointer(), ++_blendNumber, _geometry, + QThreadPool::globalInstance()->start(new Blender(getThisPointer(), ++_blendNumber, _renderGeometry, fbxGeometry.meshes, _blendshapeCoefficients)); return true; } @@ -1159,10 +1162,10 @@ bool Model::maybeStartBlender() { return false; } -void Model::setBlendedVertices(int blendNumber, const std::weak_ptr<NetworkGeometry>& geometry, +void Model::setBlendedVertices(int blendNumber, const Geometry::WeakPointer& geometry, const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& normals) { auto geometryRef = geometry.lock(); - if (!geometryRef || _geometry != geometryRef || _blendedVertexBuffers.empty() || blendNumber < _appliedBlendNumber) { + if (!geometryRef || _renderGeometry != geometryRef || _blendedVertexBuffers.empty() || blendNumber < _appliedBlendNumber) { return; } _appliedBlendNumber = blendNumber; @@ -1205,27 +1208,23 @@ AABox Model::getRenderableMeshBound() const { } void Model::segregateMeshGroups() { - NetworkGeometry::Pointer networkGeometry; + Geometry::Pointer geometry; bool showingCollisionHull = false; if (_showCollisionHull && _collisionGeometry) { if (isCollisionLoaded()) { - networkGeometry = _collisionGeometry; + geometry = _collisionGeometry; showingCollisionHull = true; } else { return; } } else { assert(isLoaded()); - networkGeometry = _geometry; + geometry = _renderGeometry; } - const FBXGeometry& geometry = networkGeometry->getGeometry()->getGeometry(); - const auto& networkMeshes = networkGeometry->getGeometry()->getMeshes(); + const auto& meshes = geometry->getMeshes(); // all of our mesh vectors must match in size - auto geoMeshesSize = geometry.meshes.size(); - if ((int)networkMeshes.size() != geoMeshesSize || - // geometry.meshes.size() != _meshStates.size()) { - geoMeshesSize > _meshStates.size()) { + if ((int)meshes.size() != _meshStates.size()) { qDebug() << "WARNING!!!! Mesh Sizes don't match! We will not segregate mesh groups yet."; return; } @@ -1249,23 +1248,25 @@ void Model::segregateMeshGroups() { // Run through all of the meshes, and place them into their segregated, but unsorted buckets int shapeID = 0; - for (int i = 0; i < (int)networkMeshes.size(); i++) { - const FBXMesh& mesh = geometry.meshes.at(i); - const auto& networkMesh = networkMeshes.at(i); + uint32_t numMeshes = (uint32_t)meshes.size(); + for (uint32_t i = 0; i < numMeshes; i++) { + const auto& mesh = meshes.at(i); + if (mesh) { - // Create the render payloads - int totalParts = mesh.parts.size(); - for (int partIndex = 0; partIndex < totalParts; partIndex++) { - if (showingCollisionHull) { - if (_collisionHullMaterials.empty()) { - initCollisionHullMaterials(); + // Create the render payloads + int numParts = (int)mesh->getNumParts(); + for (int partIndex = 0; partIndex < numParts; partIndex++) { + if (showingCollisionHull) { + if (_collisionHullMaterials.empty()) { + initCollisionHullMaterials(); + } + _collisionRenderItemsSet << std::make_shared<MeshPartPayload>(mesh, partIndex, _collisionHullMaterials[partIndex % NUM_COLLISION_HULL_COLORS], transform, offset); + } else { + _modelMeshRenderItemsSet << std::make_shared<ModelMeshPartPayload>(this, i, partIndex, shapeID, transform, offset); } - _collisionRenderItemsSet << std::make_shared<MeshPartPayload>(networkMesh, partIndex, _collisionHullMaterials[partIndex % NUM_COLLISION_HULL_COLORS], transform, offset); - } else { - _modelMeshRenderItemsSet << std::make_shared<ModelMeshPartPayload>(this, i, partIndex, shapeID, transform, offset); - } - shapeID++; + shapeID++; + } } } _meshGroupsKnown = true; @@ -1328,7 +1329,7 @@ void ModelBlender::noteRequiresBlend(ModelPointer model) { } void ModelBlender::setBlendedVertices(ModelPointer model, int blendNumber, - const std::weak_ptr<NetworkGeometry>& geometry, const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& normals) { + const Geometry::WeakPointer& geometry, const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& normals) { if (model) { model->setBlendedVertices(blendNumber, geometry, vertices, normals); } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 6a7c9ec560..aa0c49f720 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -97,7 +97,7 @@ public: bool showCollisionHull = false); void removeFromScene(std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges); void renderSetup(RenderArgs* args); - bool isRenderable() const { return !_meshStates.isEmpty() || (isActive() && getGeometry()->getGeometry()->getMeshes().empty()); } + bool isRenderable() const { return !_meshStates.isEmpty() || (isActive() && _renderGeometry->getMeshes().empty()); } bool isVisible() const { return _isVisible; } @@ -107,11 +107,11 @@ public: bool maybeStartBlender(); /// Sets blended vertices computed in a separate thread. - void setBlendedVertices(int blendNumber, const std::weak_ptr<NetworkGeometry>& geometry, + void setBlendedVertices(int blendNumber, const Geometry::WeakPointer& geometry, const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& normals); - bool isLoaded() const { return _geometry && _geometry->getGeometry(); } - bool isCollisionLoaded() const { return _collisionGeometry && _collisionGeometry->getGeometry(); } + bool isLoaded() const { return (bool)_renderGeometry; } + bool isCollisionLoaded() const { return (bool)_collisionGeometry; } void setIsWireframe(bool isWireframe) { _isWireframe = isWireframe; } bool isWireframe() const { return _isWireframe; } @@ -128,18 +128,18 @@ public: virtual void updateClusterMatrices(glm::vec3 modelPosition, glm::quat modelOrientation); /// Returns a reference to the shared geometry. - const NetworkGeometry::Pointer& getGeometry() const { return _geometry; } + const Geometry::Pointer& getGeometry() const { return _renderGeometry; } /// Returns a reference to the shared collision geometry. - const NetworkGeometry::Pointer& getCollisionGeometry() const { return _collisionGeometry; } + const Geometry::Pointer& getCollisionGeometry() const { return _collisionGeometry; } - const QVariantMap getTextures() const { assert(isLoaded()); return _geometry->getGeometry()->getTextures(); } + const QVariantMap getTextures() const { assert(isLoaded()); return _renderGeometry->getTextures(); } void setTextures(const QVariantMap& textures); /// Provided as a convenience, will crash if !isLoaded() // And so that getGeometry() isn't chained everywhere - const FBXGeometry& getFBXGeometry() const { assert(isLoaded()); return getGeometry()->getGeometry()->getGeometry(); } + const FBXGeometry& getFBXGeometry() const { assert(isLoaded()); return _renderGeometry->getFBXGeometry(); } /// Provided as a convenience, will crash if !isCollisionLoaded() - const FBXGeometry& getCollisionFBXGeometry() const { assert(isCollisionLoaded()); return getCollisionGeometry()->getGeometry()->getGeometry(); } + 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. @@ -263,7 +263,11 @@ protected: /// \return true if joint exists bool getJointPosition(int jointIndex, glm::vec3& position) const; - NetworkGeometry::Pointer _geometry; + Geometry::Pointer _renderGeometry; // only ever set by its watcher + Geometry::Pointer _collisionGeometry; // only ever set by its watcher + + GeometryResourceWatcher _renderWatcher; + GeometryResourceWatcher _collisionWatcher; glm::vec3 _translation; glm::quat _rotation; @@ -330,8 +334,6 @@ protected: void deleteGeometry(); void initJointTransforms(); - NetworkGeometry::Pointer _collisionGeometry; - float _pupilDilation; QVector<float> _blendshapeCoefficients; @@ -373,9 +375,6 @@ protected: static AbstractViewStateInterface* _viewState; - bool _renderCollisionHull; - - QSet<std::shared_ptr<MeshPartPayload>> _collisionRenderItemsSet; QMap<render::ItemID, render::PayloadPointer> _collisionRenderItems; @@ -395,7 +394,7 @@ protected: }; Q_DECLARE_METATYPE(ModelPointer) -Q_DECLARE_METATYPE(std::weak_ptr<NetworkGeometry>) +Q_DECLARE_METATYPE(Geometry::WeakPointer) /// Handle management of pending models that need blending class ModelBlender : public QObject, public Dependency { @@ -408,7 +407,7 @@ public: void noteRequiresBlend(ModelPointer model); public slots: - void setBlendedVertices(ModelPointer model, int blendNumber, const std::weak_ptr<NetworkGeometry>& geometry, + void setBlendedVertices(ModelPointer model, int blendNumber, const Geometry::WeakPointer& geometry, const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& normals); private: From 25fdea6bac0693d4e74a2e69dcc70d2f8542e418 Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Fri, 8 Jul 2016 23:02:05 -0700 Subject: [PATCH 3/8] fix for change of API after rebase --- .../src/RenderableModelEntityItem.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index d63361538a..bef790299c 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -709,9 +709,9 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { // compute meshPart local transforms QVector<glm::mat4> localTransforms; const FBXGeometry& fbxGeometry = _model->getFBXGeometry(); - int32_t numMeshes = (int32_t)fbxGeometry.meshes.size(); - int32_t totalNumVertices = 0; - for (int32_t i = 0; i < numMeshes; i++) { + int numFbxMeshes = fbxGeometry.meshes.size(); + int totalNumVertices = 0; + for (int i = 0; i < numFbxMeshes; i++) { const FBXMesh& mesh = fbxGeometry.meshes.at(i); if (mesh.clusters.size() > 0) { const FBXCluster& cluster = mesh.clusters.at(0); @@ -730,10 +730,8 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { return; } - auto& meshes = _model->getGeometry()->getGeometry()->getMeshes(); - - // the render geometry's mesh count should match that of the FBXGeometry - assert(numMeshes == (int32_t)(meshes.size())); + auto& meshes = _model->getGeometry()->getMeshes(); + int32_t numMeshes = (int32_t)(meshes.size()); ShapeInfo::PointCollection& pointCollection = info.getPointCollection(); pointCollection.clear(); From c50d41c532047a53445519c50efc996f4b8f9a80 Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Fri, 8 Jul 2016 23:08:49 -0700 Subject: [PATCH 4/8] finish name changes as per PR feedback --- .../src/model-networking/ModelCache.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index afe86e0d1e..442bf008e7 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -210,21 +210,21 @@ void GeometryDefinitionResource::setGeometryDefinition(FBXGeometry::Pointer fbxG } std::shared_ptr<GeometryMeshes> meshes = std::make_shared<GeometryMeshes>(); - std::shared_ptr<GeometryMeshParts> shapes = std::make_shared<GeometryMeshParts>(); + std::shared_ptr<GeometryMeshParts> parts = std::make_shared<GeometryMeshParts>(); int meshID = 0; for (const FBXMesh& mesh : _fbxGeometry->meshes) { // Copy mesh pointers meshes->emplace_back(mesh._mesh); int partID = 0; for (const FBXMeshPart& part : mesh.parts) { - // Construct local shapes - shapes->push_back(std::make_shared<MeshPart>(meshID, partID, (int)materialIDAtlas[part.materialID])); + // Construct local parts + parts->push_back(std::make_shared<MeshPart>(meshID, partID, (int)materialIDAtlas[part.materialID])); partID++; } meshID++; } _meshes = meshes; - _meshParts = shapes; + _meshParts = parts; finishedLoading(true); } @@ -334,9 +334,9 @@ bool Geometry::areTexturesLoaded() const { return true; } -const std::shared_ptr<const NetworkMaterial> Geometry::getShapeMaterial(int shapeID) const { - if ((shapeID >= 0) && (shapeID < (int)_meshParts->size())) { - int materialID = _meshParts->at(shapeID)->materialID; +const std::shared_ptr<const NetworkMaterial> Geometry::getShapeMaterial(int partID) const { + if ((partID >= 0) && (partID < (int)_meshParts->size())) { + int materialID = _meshParts->at(partID)->materialID; if ((materialID >= 0) && (materialID < (int)_materials.size())) { return _materials[materialID]; } From 4bebb682dc2a7db701c7b2fe6ff8d93688a5b39c Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Mon, 11 Jul 2016 08:45:57 -0700 Subject: [PATCH 5/8] namechange: fetchResource --> getGeometryResource --- .../model-networking/src/model-networking/ModelCache.cpp | 2 +- libraries/model-networking/src/model-networking/ModelCache.h | 2 +- libraries/render-utils/src/Model.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 442bf008e7..30794cf312 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -250,7 +250,7 @@ QSharedPointer<Resource> ModelCache::createResource(const QUrl& url, const QShar return QSharedPointer<Resource>(resource, &Resource::deleter); } -GeometryResource::Pointer ModelCache::fetchResource(const QUrl& url, const QVariantHash& mapping, const QUrl& textureBaseUrl) { +GeometryResource::Pointer ModelCache::getGeometryResource(const QUrl& url, const QVariantHash& mapping, const QUrl& textureBaseUrl) { GeometryExtra geometryExtra = { mapping, textureBaseUrl }; GeometryResource::Pointer resource = getResource(url, QUrl(), &geometryExtra).staticCast<GeometryResource>(); if (resource) { diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index c450f96846..93eab6aa24 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -127,7 +127,7 @@ class ModelCache : public ResourceCache, public Dependency { SINGLETON_DEPENDENCY public: - GeometryResource::Pointer fetchResource(const QUrl& url, + GeometryResource::Pointer getGeometryResource(const QUrl& url, const QVariantHash& mapping = QVariantHash(), const QUrl& textureBaseUrl = QUrl()); protected: diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index ab9e0e7403..485c578045 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -821,7 +821,7 @@ void Model::setURL(const QUrl& url) { invalidCalculatedMeshBoxes(); deleteGeometry(); - _renderWatcher.setResource(DependencyManager::get<ModelCache>()->fetchResource(url)); + _renderWatcher.setResource(DependencyManager::get<ModelCache>()->getGeometryResource(url)); onInvalidate(); } @@ -830,7 +830,7 @@ void Model::setCollisionModelURL(const QUrl& url) { return; } _collisionUrl = url; - _collisionWatcher.setResource(DependencyManager::get<ModelCache>()->fetchResource(url)); + _collisionWatcher.setResource(DependencyManager::get<ModelCache>()->getGeometryResource(url)); } bool Model::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position) const { From 3e4385913927e69b1a9068139a8822d12c6c5917 Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Mon, 11 Jul 2016 08:47:15 -0700 Subject: [PATCH 6/8] setCollisionModelURL() more symmetric with setURL() --- libraries/render-utils/src/Model.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 485c578045..e2363d0cca 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -826,7 +826,7 @@ void Model::setURL(const QUrl& url) { } void Model::setCollisionModelURL(const QUrl& url) { - if (_collisionUrl == url) { + if (_collisionUrl == url && _collisionWatcher.getURL() == url) { return; } _collisionUrl = url; From c106f4c3a01578f24831a8dbb2b07cf402ee212f Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Tue, 12 Jul 2016 10:15:28 -0700 Subject: [PATCH 7/8] fix crash for null pointer --- libraries/model-networking/src/model-networking/ModelCache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index 93eab6aa24..f513a21fbc 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -106,7 +106,7 @@ public: void setResource(GeometryResource::Pointer resource); - const QUrl& getURL() const { return _resource->getURL(); } + QUrl GeometryResourceWatcher::getURL() const { return (bool)_resource ? _resource->getURL() : QUrl(); } private: void startWatching(); From cba49be9eaa64b28a0af35df60114058dbad115b Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Tue, 12 Jul 2016 16:30:26 -0700 Subject: [PATCH 8/8] fix compile bug --- libraries/model-networking/src/model-networking/ModelCache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index f513a21fbc..aa3ea78db3 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -106,7 +106,7 @@ public: void setResource(GeometryResource::Pointer resource); - QUrl GeometryResourceWatcher::getURL() const { return (bool)_resource ? _resource->getURL() : QUrl(); } + QUrl getURL() const { return (bool)_resource ? _resource->getURL() : QUrl(); } private: void startWatching();