From e1845e2c3f78b39fd8852d6b659cccc735766ec7 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 31 Aug 2016 14:59:02 -0700 Subject: [PATCH] add support for renderInfo properties to model entities --- .../src/RenderableModelEntityItem.cpp | 9 ++++ .../entities/src/EntityItemProperties.cpp | 18 ++++++++ libraries/entities/src/EntityItemProperties.h | 19 +++++++++ libraries/model/src/model/TextureMap.h | 1 + .../render-utils/src/MeshPartPayload.cpp | 33 ++++++++++++++- libraries/render-utils/src/MeshPartPayload.h | 7 ++++ libraries/render-utils/src/Model.cpp | 42 ++++++++++++++++++- libraries/render-utils/src/Model.h | 13 ++++++ 8 files changed, 139 insertions(+), 3 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index fc3245f322..abc4e1c767 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -548,6 +548,15 @@ EntityItemProperties RenderableModelEntityItem::getProperties(EntityPropertyFlag if (_originalTexturesRead) { properties.setTextureNames(_originalTextures); } + + if (_model) { + properties.setRenderInfoVertexCount(_model->getRenderInfoVertexCount()); + properties.setRenderInfoTextureCount(_model->getRenderInfoTextureCount()); + properties.setRenderInfoTextureSize(_model->getRenderInfoTextureSize()); + properties.setRenderInfoDrawCalls(_model->getRenderInfoDrawCalls()); + properties.setRenderInfoHasTransparent(_model->getRenderInfoHasTransparent()); + } + return properties; } diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 06c91b4f32..0e40278824 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -580,6 +580,24 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLIENT_ONLY, clientOnly); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_OWNING_AVATAR_ID, owningAvatarID); + // Rendering info + if (!skipDefaults) { + QScriptValue renderInfo = engine->newObject(); + + // currently only supported by models + if (_type == EntityTypes::Model) { + renderInfo.setProperty("verticesCount", (int)getRenderInfoVertexCount()); // FIXME - theoretically the number of vertex could be > max int + renderInfo.setProperty("texturesSize", (int)getRenderInfoTextureSize()); // FIXME - theoretically the size of textures could be > max int + renderInfo.setProperty("hasTransparent", getRenderInfoHasTransparent()); + renderInfo.setProperty("drawCalls", getRenderInfoDrawCalls()); + } + + if (_type == EntityTypes::Model || _type == EntityTypes::PolyLine || _type == EntityTypes::ParticleEffect) { + renderInfo.setProperty("texturesCount", QScriptValue(_textureNames.count())); + } + COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(renderInfo, renderInfo); // Gettable but not settable + } + properties.setProperty("clientOnly", convertScriptValue(engine, getClientOnly())); properties.setProperty("owningAvatarID", convertScriptValue(engine, getOwningAvatarID())); diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 4591dabc51..473966dd60 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -285,6 +285,19 @@ public: void setJointRotationsDirty() { _jointRotationsSetChanged = true; _jointRotationsChanged = true; } void setJointTranslationsDirty() { _jointTranslationsSetChanged = true; _jointTranslationsChanged = true; } + // render info related items + size_t getRenderInfoVertexCount() const { return _renderInfoVertexCount; } + void setRenderInfoVertexCount(size_t value) { _renderInfoVertexCount = value; } + int getRenderInfoTextureCount() const { return _renderInfoTextureCount; } + void setRenderInfoTextureCount(int value) { _renderInfoTextureCount = value; } + size_t getRenderInfoTextureSize() const { return _renderInfoTextureSize; } + void setRenderInfoTextureSize(size_t value) { _renderInfoTextureSize = value; } + int getRenderInfoDrawCalls() const { return _renderInfoDrawCalls; } + void setRenderInfoDrawCalls(int value) { _renderInfoDrawCalls = value; } + bool getRenderInfoHasTransparent() const { return _renderInfoHasTransparent; } + void setRenderInfoHasTransparent(bool value) { _renderInfoHasTransparent = value; } + + protected: QString getCollisionMaskAsString() const; void setCollisionMaskFromString(const QString& maskString); @@ -308,6 +321,12 @@ private: glm::vec3 _naturalDimensions; glm::vec3 _naturalPosition; + size_t _renderInfoVertexCount { 0 }; + int _renderInfoTextureCount { 0 }; + size_t _renderInfoTextureSize { 0 }; + int _renderInfoDrawCalls { 0 }; + bool _renderInfoHasTransparent { false }; + EntityPropertyFlags _desiredProperties; // if set will narrow scopes of copy/to/from to just these properties }; diff --git a/libraries/model/src/model/TextureMap.h b/libraries/model/src/model/TextureMap.h index 795b685f27..ac35db2f03 100755 --- a/libraries/model/src/model/TextureMap.h +++ b/libraries/model/src/model/TextureMap.h @@ -59,6 +59,7 @@ public: TextureMap() {} void setTextureSource(gpu::TextureSourcePointer& textureSource); + gpu::TextureSourcePointer getTextureSource() const { return _textureSource; } bool isDefined() const; gpu::TextureView getTextureView() const; diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 42dd41c739..3e891bffe2 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -71,8 +71,37 @@ void MeshPartPayload::updateTransform(const Transform& transform, const Transfor void MeshPartPayload::updateMaterial(model::MaterialPointer drawMaterial) { _drawMaterial = drawMaterial; + calculateMaterialSize(); } +bool MeshPartPayload::calculateMaterialSize() { + bool allTextures = true; // assume we got this... + _materialTextureSize = 0; + auto textureMaps = _drawMaterial->getTextureMaps(); + for (auto const &textureMapItem : textureMaps) { + auto textureMap = textureMapItem.second; + if (textureMap) { + auto textureSoure = textureMap->getTextureSource(); + if (textureSoure) { + auto texture = textureSoure->getGPUTexture(); + if (texture) { + //auto storedSize = texture->getStoredSize(); + auto size = texture->getSize(); + _materialTextureSize += size; + } else { + allTextures = false; + } + } else { + allTextures = false; + } + } else { + allTextures = false; + } + } + return allTextures; +} + + ItemKey MeshPartPayload::getKey() const { ItemKey::Builder builder; builder.withTypeShape(); @@ -347,8 +376,8 @@ void ModelMeshPartPayload::initCache() { auto networkMaterial = _model->getGeometry()->getShapeMaterial(_shapeID); if (networkMaterial) { _drawMaterial = networkMaterial; - }; - + calculateMaterialSize(); + } } void ModelMeshPartPayload::notifyLocationChanged() { diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h index a934863846..f7ea77beba 100644 --- a/libraries/render-utils/src/MeshPartPayload.h +++ b/libraries/render-utils/src/MeshPartPayload.h @@ -64,6 +64,13 @@ public: mutable model::Box _worldBound; bool _hasColorAttrib = false; + + size_t getVerticesCount() const { return _drawMesh ? _drawMesh->getNumVertices() : 0; } + size_t getMaterialTextureSize() { return _materialTextureSize; } + bool calculateMaterialSize(); + +protected: + size_t _materialTextureSize { 0 }; }; namespace render { diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 3a7308c277..ebf5cb4327 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -161,6 +161,23 @@ void Model::setOffset(const glm::vec3& offset) { _snappedToRegistrationPoint = false; } +size_t Model::getRenderInfoTextureSize() { + if (!_hasCalculatedTextureSize && isLoaded() && getGeometry()->areTexturesLoaded()) { + size_t textureSize = 0; + bool allTexturesLoaded = true; + foreach(auto renderItem, _modelMeshRenderItemsSet) { + auto meshPart = renderItem.get(); + bool allTexturesForThisMesh = meshPart->calculateMaterialSize(); + allTexturesLoaded = allTexturesLoaded & allTexturesForThisMesh; + textureSize += meshPart->getMaterialTextureSize(); + } + _renderInfoTextureSize = textureSize; + _hasCalculatedTextureSize = allTexturesLoaded; // only do this once + } + return _renderInfoTextureSize; +} + + void Model::updateRenderItems() { if (!_addedToScene) { return; @@ -615,16 +632,26 @@ bool Model::addToScene(std::shared_ptr scene, } } else { if (_modelMeshRenderItems.empty()) { - foreach (auto renderItem, _modelMeshRenderItemsSet) { + + bool hasTransparent = false; + size_t verticesCount = 0; + foreach(auto renderItem, _modelMeshRenderItemsSet) { auto item = scene->allocateID(); auto renderPayload = std::make_shared(renderItem); if (statusGetters.size()) { renderPayload->addStatusGetters(statusGetters); } pendingChanges.resetItem(item, renderPayload); + + hasTransparent = hasTransparent || renderItem.get()->getShapeKey().isTranslucent(); + verticesCount += renderItem.get()->getVerticesCount(); _modelMeshRenderItems.insert(item, renderPayload); } somethingAdded = !_modelMeshRenderItems.empty(); + + _renderInfoVertexCount = verticesCount; + _renderInfoDrawCalls = _modelMeshRenderItems.count(); + _renderInfoHasTransparent = hasTransparent; } } @@ -650,6 +677,11 @@ void Model::removeFromScene(std::shared_ptr scene, render::Pendin _collisionRenderItems.clear(); _collisionRenderItemsSet.clear(); _addedToScene = false; + + _renderInfoVertexCount = 0; + _renderInfoDrawCalls = 0; + _renderInfoTextureSize = 0; + _renderInfoHasTransparent = false; } void Model::renderDebugMeshBoxes(gpu::Batch& batch) { @@ -1332,13 +1364,21 @@ bool Model::initWhenReady(render::ScenePointer scene) { } addedPendingChanges = !_collisionRenderItems.empty(); } else { + bool hasTransparent = false; + size_t verticesCount = 0; foreach (auto renderItem, _modelMeshRenderItemsSet) { auto item = scene->allocateID(); auto renderPayload = std::make_shared(renderItem); + + hasTransparent = hasTransparent || renderItem.get()->getShapeKey().isTranslucent(); + verticesCount += renderItem.get()->getVerticesCount(); _modelMeshRenderItems.insert(item, renderPayload); pendingChanges.resetItem(item, renderPayload); } addedPendingChanges = !_modelMeshRenderItems.empty(); + _renderInfoVertexCount = verticesCount; + _renderInfoDrawCalls = _modelMeshRenderItems.count(); + _renderInfoHasTransparent = hasTransparent; } _addedToScene = addedPendingChanges; if (addedPendingChanges) { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 7a193b1d47..1b16892296 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -232,6 +232,12 @@ public: void setLoadingPriority(float priority) { _loadingPriority = priority; } + size_t getRenderInfoVertexCount() const { return _renderInfoVertexCount; } + int getRenderInfoTextureCount() const { return _renderInfoTextureCount; } + size_t getRenderInfoTextureSize(); + int getRenderInfoDrawCalls() const { return _renderInfoDrawCalls; } + bool getRenderInfoHasTransparent() const { return _renderInfoHasTransparent; } + public slots: void loadURLFinished(bool success); @@ -400,6 +406,13 @@ protected: bool _renderItemsNeedUpdate { false }; + size_t _renderInfoVertexCount { 0 }; + int _renderInfoTextureCount { 0 }; + size_t _renderInfoTextureSize { 0 }; + bool _hasCalculatedTextureSize { false }; + int _renderInfoDrawCalls { 0 }; + int _renderInfoHasTransparent { false }; + private: float _loadingPriority { 0.0f };