From 3593afea3b3df07700803d4b2c67cf9e5f9d7cd2 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 4 Jun 2015 11:37:02 -0700 Subject: [PATCH 1/4] optimize part offset calculation --- libraries/render-utils/src/Model.cpp | 29 ++++++++++++++-------------- libraries/render-utils/src/Model.h | 3 +++ 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index ab597051cc..cb8217d465 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -680,6 +680,7 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) { _calculatedMeshTriangles.clear(); _calculatedMeshTriangles.resize(numberOfMeshes); _calculatedMeshPartBoxes.clear(); + _calculatedMeshPartOffet.clear(); for (int i = 0; i < numberOfMeshes; i++) { const FBXMesh& mesh = geometry.meshes.at(i); Extents scaledMeshExtents = calculateScaledOffsetExtents(mesh.meshExtents); @@ -688,9 +689,10 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) { if (pickAgainstTriangles) { QVector thisMeshTriangles; + qint64 partOffset = 0; for (int j = 0; j < mesh.parts.size(); j++) { const FBXMeshPart& part = mesh.parts.at(j); - + bool atLeastOnePointInBounds = false; AABox thisPartBounds; @@ -773,6 +775,11 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) { } } _calculatedMeshPartBoxes[QPair(i, j)] = thisPartBounds; + _calculatedMeshPartOffet[QPair(i, j)] = partOffset; + + partOffset += part.quadIndices.size() * sizeof(int); + partOffset += part.triangleIndices.size() * sizeof(int); + } _calculatedMeshTriangles[i] = thisMeshTriangles; _calculatedMeshPartBoxesValid = true; @@ -2026,6 +2033,12 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran if (!_readyWhenAdded) { return; // bail asap } + + // we always need these properly calculated before we can render, this will likely already have been done + // since the engine will call our getPartBounds() before rendering us. + if (!_calculatedMeshPartBoxesValid) { + recalculateMeshBoxes(true); + } auto textureCache = DependencyManager::get(); gpu::Batch& batch = *(args->_batch); @@ -2211,19 +2224,7 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran meshPartsRendered++; - // FIX ME This is very unefficient - qint64 offset = 0; - for (int j = 0; j < partIndex; j++) { - const NetworkMeshPart& networkPart = networkMesh.parts.at(j); - const FBXMeshPart& part = mesh.parts.at(j); - if ((networkPart.isTranslucent() || part.opacity != 1.0f) != translucent) { - offset += (part.quadIndices.size() + part.triangleIndices.size()) * sizeof(int); - continue; - } - - offset += part.quadIndices.size() * sizeof(int); - offset += part.triangleIndices.size() * sizeof(int); - } + qint64 offset = _calculatedMeshPartOffet[QPair(meshIndex, partIndex)]; if (part.quadIndices.size() > 0) { batch.drawIndexed(gpu::QUADS, part.quadIndices.size(), offset); diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 3795dc8731..85d0022cbc 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -367,6 +367,9 @@ private: }; QHash, AABox> _calculatedMeshPartBoxes; // world coordinate AABoxes for all sub mesh part boxes + QHash, qint64> _calculatedMeshPartOffet; + + bool _calculatedMeshPartBoxesValid; QVector _calculatedMeshBoxes; // world coordinate AABoxes for all sub mesh boxes bool _calculatedMeshBoxesValid; From a62b55fcb238e920886fb9801361778a7b75f762 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 4 Jun 2015 13:25:40 -0700 Subject: [PATCH 2/4] Update entity payload items to correctly hide when not visible --- .../src/RenderableEntityItem.cpp | 2 +- .../src/RenderableModelEntityItem.cpp | 2 ++ libraries/render-utils/src/Model.cpp | 25 ++++++++++++++++--- libraries/render-utils/src/Model.h | 6 ++++- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index e5e0f2ff85..56e385e689 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -31,7 +31,7 @@ namespace render { template <> void payloadRender(const RenderableEntityItemProxy::Pointer& payload, RenderArgs* args) { if (args) { args->_elementsTouched++; - if (payload && payload->entity) { + if (payload && payload->entity && payload->entity->getVisible()) { payload->entity->render(args); } } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 29da23702c..81ddb912cc 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -221,6 +221,8 @@ void RenderableModelEntityItem::render(RenderArgs* args) { _model->addToScene(scene, pendingChanges); } scene->enqueuePendingChanges(pendingChanges); + + _model->setVisibleInScene(getVisible(), scene); } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index ab597051cc..8f724d9ad5 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -78,6 +78,7 @@ Model::Model(QObject* parent) : _showTrueJointTransforms(true), _lodDistance(0.0f), _pupilDilation(0.0f), + _isVisible(true), _url("http://invalid.com"), _blendNumber(0), _appliedBlendNumber(0), @@ -823,6 +824,9 @@ public: namespace render { template <> const ItemKey payloadGetKey(const TransparentMeshPart::Pointer& payload) { + if (!payload->model->isVisible()) { + return ItemKey::Builder().withInvisible().build(); + } return ItemKey::Builder::transparentShape(); } @@ -853,6 +857,9 @@ public: namespace render { template <> const ItemKey payloadGetKey(const OpaqueMeshPart::Pointer& payload) { + if (!payload->model->isVisible()) { + return ItemKey::Builder().withInvisible().build(); + } return ItemKey::Builder::opaqueShape(); } @@ -872,6 +879,18 @@ namespace render { } } +void Model::setVisibleInScene(bool newValue, std::shared_ptr scene) { + if (_isVisible != newValue) { + _isVisible = newValue; + + render::PendingChanges pendingChanges; + foreach (auto item, _renderItems.keys()) { + pendingChanges.resetItem(item, _renderItems[item]); + } + scene->enqueuePendingChanges(pendingChanges); + } +} + bool Model::addToScene(std::shared_ptr scene, render::PendingChanges& pendingChanges) { if (!_meshGroupsKnown && isLoadedWithTextures()) { @@ -893,7 +912,7 @@ bool Model::addToScene(std::shared_ptr scene, render::PendingChan auto renderData = TransparentMeshPart::Pointer(renderItem); auto renderPayload = render::PayloadPointer(new TransparentMeshPart::Payload(renderData)); pendingChanges.resetItem(item, renderPayload); - _renderItems << item; + _renderItems.insert(item, renderPayload); somethingAdded = true; } foreach (auto renderItem, _opaqueRenderItems) { @@ -901,7 +920,7 @@ bool Model::addToScene(std::shared_ptr scene, render::PendingChan auto renderData = OpaqueMeshPart::Pointer(renderItem); auto renderPayload = render::PayloadPointer(new OpaqueMeshPart::Payload(renderData)); pendingChanges.resetItem(item, renderPayload); - _renderItems << item; + _renderItems.insert(item, renderPayload); somethingAdded = true; } @@ -916,7 +935,7 @@ void Model::removeFromScene(std::shared_ptr scene, render::Pendin attachment->removeFromScene(scene, pendingChanges); } - foreach (auto item, _renderItems) { + foreach (auto item, _renderItems.keys()) { pendingChanges.removeItem(item); } _renderItems.clear(); diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 3795dc8731..57c20469ca 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -107,6 +107,9 @@ public: bool isActive() const { return _geometry && _geometry->isLoaded(); } bool isRenderable() const { return !_meshStates.isEmpty() || (isActive() && _geometry->getMeshes().isEmpty()); } + + void setVisibleInScene(bool newValue, std::shared_ptr scene); + bool isVisible() const { return _isVisible; } bool isLoadedWithTextures() const { return _geometry && _geometry->isLoadedWithTextures(); } @@ -334,6 +337,7 @@ private: QUrl _url; QUrl _collisionUrl; + bool _isVisible; gpu::Buffers _blendedVertexBuffers; std::vector _transforms; @@ -528,7 +532,7 @@ private: QSet> _transparentRenderItems; QSet> _opaqueRenderItems; - QSet _renderItems; + QMap _renderItems; bool _readyWhenAdded = false; From 56ac987c9b2ef489aa3bea110e37abe5c7419112 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 4 Jun 2015 13:40:43 -0700 Subject: [PATCH 3/4] handle url reloading at the model level, this addresses avatars changing their models --- libraries/render-utils/src/Model.cpp | 21 +++++++++------------ libraries/render-utils/src/Model.h | 3 ++- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index cb8217d465..6bb5d298f1 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -407,6 +407,7 @@ void Model::reset() { _meshGroupsKnown = false; _readyWhenAdded = false; // in case any of our users are using scenes + _needsReload = true; } bool Model::updateGeometry() { @@ -458,6 +459,7 @@ bool Model::updateGeometry() { _geometry = geometry; _meshGroupsKnown = false; _readyWhenAdded = false; // in case any of our users are using scenes + _needsReload = true; initJointStates(newJointStates); needToRebuild = true; } else if (_jointStates.isEmpty()) { @@ -1319,6 +1321,10 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo if (_url == url && _geometry && _geometry->getURL() == url) { return; } + + _readyWhenAdded = false; // reset out render items. + _needsReload = true; + _url = url; // if so instructed, keep the current geometry until the new one is loaded @@ -1971,6 +1977,7 @@ void Model::applyNextGeometry() { _geometry = _nextGeometry; _meshGroupsKnown = false; _readyWhenAdded = false; // in case any of our users are using scenes + _needsReload = false; // we are loaded now! _nextBaseGeometry.reset(); _nextGeometry.reset(); } @@ -2049,18 +2056,6 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran _transforms.push_back(Transform()); } - // _transforms[0] = _viewState->getViewTransform(); - // args->_viewFrustum->evalViewTransform(_transforms[0]); - - // apply entity translation offset to the viewTransform in one go (it's a preTranslate because viewTransform goes from world to eye space) - // _transforms[0].setTranslation(_translation); - - // batch.setViewTransform(_transforms[0]); - - - // const float OPAQUE_ALPHA_THRESHOLD = 0.5f; - // const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f; - // auto alphaThreshold = translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME auto alphaThreshold = args->_alphaThreshold; //translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME const FBXGeometry& geometry = _geometry->getFBXGeometry(); const QVector& networkMeshes = _geometry->getMeshes(); @@ -2099,6 +2094,7 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran if (meshIndex < 0 || meshIndex >= networkMeshes.size() || meshIndex > geometry.meshes.size()) { _meshGroupsKnown = false; // regenerate these lists next time around. _readyWhenAdded = false; // in case any of our users are using scenes + _needsReload = true; return; // FIXME! } @@ -2414,6 +2410,7 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod if (i < 0 || i >= networkMeshes.size() || i > geometry.meshes.size()) { _meshGroupsKnown = false; // regenerate these lists next time around. _readyWhenAdded = false; // in case any of our users are using scenes + _needsReload = true; continue; } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 85d0022cbc..ad2d725027 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -118,7 +118,7 @@ public: // new Scene/Engine rendering support bool needsFixupInScene() { return !_readyWhenAdded && readyToAddToScene(); } - bool readyToAddToScene(RenderArgs* renderArgs = nullptr) { return isRenderable() && isActive() && isLoadedWithTextures(); } + bool readyToAddToScene(RenderArgs* renderArgs = nullptr) { return !_needsReload && isRenderable() && isActive() && isLoadedWithTextures(); } bool addToScene(std::shared_ptr scene, render::PendingChanges& pendingChanges); void removeFromScene(std::shared_ptr scene, render::PendingChanges& pendingChanges); @@ -533,6 +533,7 @@ private: QSet> _opaqueRenderItems; QSet _renderItems; bool _readyWhenAdded = false; + bool _needsReload = true; private: From 5af52048ec0e744c07bb9b6b327082e37a729ee0 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 4 Jun 2015 13:45:10 -0700 Subject: [PATCH 4/4] Add render/Scene.h include to Model.h --- libraries/render-utils/src/Model.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 57c20469ca..d49f51fa1b 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -30,6 +30,7 @@ #include #include #include "PhysicsEntity.h" +#include #include #include "AnimationHandle.h"