From ca2d2c751ce08618095c17842ffce156e311a712 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 15 May 2014 00:34:09 -0700 Subject: [PATCH] fixing models not rendering sometimes --- interface/src/models/ModelTreeRenderer.cpp | 5 ++++- .../src/particles/ParticleTreeRenderer.cpp | 2 +- libraries/models/src/ModelTree.cpp | 8 +++++--- libraries/models/src/ModelTreeElement.cpp | 17 ++++++++++++----- libraries/models/src/ModelTreeElement.h | 17 +++++++++++++++-- libraries/octree/src/OctreeElement.cpp | 2 +- libraries/octree/src/OctreeElement.h | 4 ++++ libraries/octree/src/OctreeRenderer.cpp | 2 +- libraries/octree/src/OctreeRenderer.h | 5 ++++- 9 files changed, 47 insertions(+), 15 deletions(-) diff --git a/interface/src/models/ModelTreeRenderer.cpp b/interface/src/models/ModelTreeRenderer.cpp index ae60683745..0f9da86887 100644 --- a/interface/src/models/ModelTreeRenderer.cpp +++ b/interface/src/models/ModelTreeRenderer.cpp @@ -74,6 +74,7 @@ Model* ModelTreeRenderer::getModel(const ModelItem& modelItem) { } void ModelTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args) { + args->_elementsTouched++; // actually render it here... // we need to iterate the actual modelItems of the element ModelTreeElement* modelTreeElement = (ModelTreeElement*)element; @@ -165,7 +166,7 @@ void ModelTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args) bool drawAsModel = modelItem.hasModel(); - args->_renderedItems++; + args->_itemsRendered++; if (drawAsModel) { glPushMatrix(); @@ -220,6 +221,8 @@ void ModelTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args) glutSolidSphere(radius, 15, 15); glPopMatrix(); } + } else { + args->_itemsOutOfView++; } } } diff --git a/interface/src/particles/ParticleTreeRenderer.cpp b/interface/src/particles/ParticleTreeRenderer.cpp index 2983093564..38ef9c8516 100644 --- a/interface/src/particles/ParticleTreeRenderer.cpp +++ b/interface/src/particles/ParticleTreeRenderer.cpp @@ -76,7 +76,7 @@ void ParticleTreeRenderer::renderElement(OctreeElement* element, RenderArgs* arg bool drawAsModel = particle.hasModel(); - args->_renderedItems++; + args->_itemsRendered++; if (drawAsModel) { glPushMatrix(); diff --git a/libraries/models/src/ModelTree.cpp b/libraries/models/src/ModelTree.cpp index 45694b081d..ee980b1185 100644 --- a/libraries/models/src/ModelTree.cpp +++ b/libraries/models/src/ModelTree.cpp @@ -491,11 +491,14 @@ void ModelTree::update() { lockForWrite(); _isDirty = true; - ModelTreeUpdateArgs args = { }; + ModelTreeUpdateArgs args; recurseTreeWithOperation(updateOperation, &args); // now add back any of the particles that moved elements.... int movingModels = args._movingModels.size(); + + qDebug() << "ModelTree::update()... movingModels=" << movingModels; + for (int i = 0; i < movingModels; i++) { bool shouldDie = args._movingModels[i].getShouldDie(); @@ -553,7 +556,7 @@ bool ModelTree::encodeModelsDeletedSince(quint64& sinceTime, unsigned char* outp memcpy(copyAt, &numberOfIds, sizeof(numberOfIds)); copyAt += sizeof(numberOfIds); outputLength += sizeof(numberOfIds); - + // we keep a multi map of model IDs to timestamps, we only want to include the model IDs that have been // deleted since we last sent to this node _recentlyDeletedModelsLock.lockForRead(); @@ -595,7 +598,6 @@ bool ModelTree::encodeModelsDeletedSince(quint64& sinceTime, unsigned char* outp // replace the correct count for ids included memcpy(numberOfIDsAt, &numberOfIds, sizeof(numberOfIds)); - return hasMoreToSend; } diff --git a/libraries/models/src/ModelTreeElement.cpp b/libraries/models/src/ModelTreeElement.cpp index c5dce04fe2..2f57818044 100644 --- a/libraries/models/src/ModelTreeElement.cpp +++ b/libraries/models/src/ModelTreeElement.cpp @@ -84,14 +84,17 @@ bool ModelTreeElement::appendElementData(OctreePacketData* packetData, EncodeBit } bool ModelTreeElement::containsModelBounds(const ModelItem& model) const { - return _box.contains(model.getMinimumPoint()) && _box.contains(model.getMaximumPoint()); + glm::vec3 clampedMin = glm::clamp(model.getMinimumPoint(), 0.0f, 1.0f); + glm::vec3 clampedMax = glm::clamp(model.getMaximumPoint(), 0.0f, 1.0f); + return _box.contains(clampedMin) && _box.contains(clampedMax); } bool ModelTreeElement::bestFitModelBounds(const ModelItem& model) const { - if (_box.contains(model.getMinimumPoint()) && _box.contains(model.getMaximumPoint())) { - int childForMinimumPoint = getMyChildContainingPoint(model.getMinimumPoint()); - int childForMaximumPoint = getMyChildContainingPoint(model.getMaximumPoint()); - + glm::vec3 clampedMin = glm::clamp(model.getMinimumPoint(), 0.0f, 1.0f); + glm::vec3 clampedMax = glm::clamp(model.getMaximumPoint(), 0.0f, 1.0f); + if (_box.contains(clampedMin) && _box.contains(clampedMax)) { + int childForMinimumPoint = getMyChildContainingPoint(clampedMin); + int childForMaximumPoint = getMyChildContainingPoint(clampedMax); // If I contain both the minimum and maximum point, but two different children of mine // contain those points, then I am the best fit for that model if (childForMinimumPoint != childForMaximumPoint) { @@ -102,10 +105,12 @@ bool ModelTreeElement::bestFitModelBounds(const ModelItem& model) const { } void ModelTreeElement::update(ModelTreeUpdateArgs& args) { + args._totalElements++; // update our contained models QList::iterator modelItr = _modelItems->begin(); while(modelItr != _modelItems->end()) { ModelItem& model = (*modelItr); + args._totalItems++; // TODO: this _lastChanged isn't actually changing because we're not marking this element as changed. // how do we want to handle this??? We really only want to consider an element changed when it is @@ -119,6 +124,8 @@ void ModelTreeElement::update(ModelTreeUpdateArgs& args) { // erase this model modelItr = _modelItems->erase(modelItr); + + args._movingItems++; // this element has changed so mark it... markWithChangedTime(); diff --git a/libraries/models/src/ModelTreeElement.h b/libraries/models/src/ModelTreeElement.h index ce9e2dec7e..83b745206f 100644 --- a/libraries/models/src/ModelTreeElement.h +++ b/libraries/models/src/ModelTreeElement.h @@ -23,7 +23,16 @@ class ModelTreeElement; class ModelTreeUpdateArgs { public: + ModelTreeUpdateArgs() : + _totalElements(0), + _totalItems(0), + _movingItems(0) + { } + QList _movingModels; + int _totalElements; + int _totalItems; + int _movingItems; }; class FindAndUpdateModelItemIDArgs { @@ -63,7 +72,11 @@ public: /// Should this element be considered to have content in it. This will be used in collision and ray casting methods. /// By default we assume that only leaves are actual content, but some octrees may have different semantics. - virtual bool hasContent() const { return isLeaf(); } + virtual bool hasContent() const { return hasModels(); } + + /// Should this element be considered to have detailed content in it. Specifically should it be rendered. + /// By default we assume that only leaves have detailed content, but some octrees may have different semantics. + virtual bool hasDetailedContent() const { return hasModels(); } /// Override this to break up large octree elements when an edit operation is performed on a smaller octree element. /// For example, if the octrees represent solid cubes and a delete of a smaller octree element is done then the @@ -92,7 +105,7 @@ public: const QList& getModels() const { return *_modelItems; } QList& getModels() { return *_modelItems; } - bool hasModels() const { return _modelItems->size() > 0; } + bool hasModels() const { return _modelItems ? _modelItems->size() > 0 : false; } void update(ModelTreeUpdateArgs& args); void setTree(ModelTree* tree) { _myTree = tree; } diff --git a/libraries/octree/src/OctreeElement.cpp b/libraries/octree/src/OctreeElement.cpp index edba26f2a7..0462a3b53d 100644 --- a/libraries/octree/src/OctreeElement.cpp +++ b/libraries/octree/src/OctreeElement.cpp @@ -1213,7 +1213,7 @@ bool OctreeElement::calculateShouldRender(const ViewFrustum* viewFrustum, float float furthestDistance = furthestDistanceToCamera(*viewFrustum); float childBoundary = boundaryDistanceForRenderLevel(getLevel() + 1 + boundaryLevelAdjust, voxelScaleSize); bool inChildBoundary = (furthestDistance <= childBoundary); - if (isLeaf() && inChildBoundary) { + if (hasDetailedContent() && inChildBoundary) { shouldRender = true; } else { float boundary = childBoundary * 2.0f; // the boundary is always twice the distance of the child boundary diff --git a/libraries/octree/src/OctreeElement.h b/libraries/octree/src/OctreeElement.h index 42c9abad46..2485e49797 100644 --- a/libraries/octree/src/OctreeElement.h +++ b/libraries/octree/src/OctreeElement.h @@ -71,6 +71,10 @@ public: /// Should this element be considered to have content in it. This will be used in collision and ray casting methods. /// By default we assume that only leaves are actual content, but some octrees may have different semantics. virtual bool hasContent() const { return isLeaf(); } + + /// Should this element be considered to have detailed content in it. Specifically should it be rendered. + /// By default we assume that only leaves have detailed content, but some octrees may have different semantics. + virtual bool hasDetailedContent() const { return isLeaf(); } /// Override this to break up large octree elements when an edit operation is performed on a smaller octree element. /// For example, if the octrees represent solid cubes and a delete of a smaller octree element is done then the diff --git a/libraries/octree/src/OctreeRenderer.cpp b/libraries/octree/src/OctreeRenderer.cpp index 1a85518181..e2aec8c890 100644 --- a/libraries/octree/src/OctreeRenderer.cpp +++ b/libraries/octree/src/OctreeRenderer.cpp @@ -156,7 +156,7 @@ bool OctreeRenderer::renderOperation(OctreeElement* element, void* extraData) { } void OctreeRenderer::render(RenderMode renderMode) { - RenderArgs args = { 0, this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode }; + RenderArgs args = { this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, 0, 0, 0 }; if (_tree) { _tree->lockForRead(); _tree->recurseTreeWithOperation(renderOperation, &args); diff --git a/libraries/octree/src/OctreeRenderer.h b/libraries/octree/src/OctreeRenderer.h index 73e26c97f6..18e68e26aa 100644 --- a/libraries/octree/src/OctreeRenderer.h +++ b/libraries/octree/src/OctreeRenderer.h @@ -71,12 +71,15 @@ protected: class RenderArgs { public: - int _renderedItems; OctreeRenderer* _renderer; ViewFrustum* _viewFrustum; float _sizeScale; int _boundaryLevelAdjust; OctreeRenderer::RenderMode _renderMode; + + int _elementsTouched; + int _itemsRendered; + int _itemsOutOfView; };