mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 17:03:58 +02:00
fixing models not rendering sometimes
This commit is contained in:
parent
f6c1d3e635
commit
ca2d2c751c
9 changed files with 47 additions and 15 deletions
|
@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ void ParticleTreeRenderer::renderElement(OctreeElement* element, RenderArgs* arg
|
|||
|
||||
bool drawAsModel = particle.hasModel();
|
||||
|
||||
args->_renderedItems++;
|
||||
args->_itemsRendered++;
|
||||
|
||||
if (drawAsModel) {
|
||||
glPushMatrix();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<ModelItem>::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();
|
||||
|
|
|
@ -23,7 +23,16 @@ class ModelTreeElement;
|
|||
|
||||
class ModelTreeUpdateArgs {
|
||||
public:
|
||||
ModelTreeUpdateArgs() :
|
||||
_totalElements(0),
|
||||
_totalItems(0),
|
||||
_movingItems(0)
|
||||
{ }
|
||||
|
||||
QList<ModelItem> _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<ModelItem>& getModels() const { return *_modelItems; }
|
||||
QList<ModelItem>& 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; }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue