From 0bb3752121966fe40b455aa6b20421e986ce7e87 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 28 Feb 2014 14:29:18 -0800 Subject: [PATCH] Fixed seg fault, don't attempt to transfer joints between different models (as opposed to different LODs). --- interface/src/renderer/Model.cpp | 108 +++++++++++++++++-------------- interface/src/renderer/Model.h | 3 + 2 files changed, 62 insertions(+), 49 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index d87879ac27..acb7b50ec9 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -102,43 +102,7 @@ void Model::reset() { void Model::simulate(float deltaTime, bool delayLoad) { // update our LOD - QVector newJointStates; - if (_geometry) { - QSharedPointer geometry = _geometry; - if (_nextGeometry) { - if (!delayLoad) { - _nextGeometry->setLoadPriority(this, -_lodDistance); - _nextGeometry->ensureLoading(); - } - if (_nextGeometry->isLoaded()) { - geometry = _nextGeometry; - _nextGeometry.clear(); - } - } - geometry = geometry->getLODOrFallback(_lodDistance, _lodHysteresis, delayLoad); - if (_geometry != geometry) { - if (!_jointStates.isEmpty()) { - // copy the existing joint states - const FBXGeometry& oldGeometry = _geometry->getFBXGeometry(); - const FBXGeometry& newGeometry = geometry->getFBXGeometry(); - newJointStates = createJointStates(newGeometry); - for (QHash::const_iterator it = oldGeometry.jointIndices.constBegin(); - it != oldGeometry.jointIndices.constEnd(); it++) { - int newIndex = newGeometry.jointIndices.value(it.key()); - if (newIndex != 0) { - newJointStates[newIndex - 1] = _jointStates.at(it.value() - 1); - } - } - } - deleteGeometry(); - _dilatedTextures.clear(); - _geometry = geometry; - } - if (!delayLoad) { - _geometry->setLoadPriority(this, -_lodDistance); - _geometry->ensureLoading(); - } - } + QVector newJointStates = updateGeometry(delayLoad); if (!isActive()) { return; } @@ -451,19 +415,10 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo _url = url; // if so instructed, keep the current geometry until the new one is loaded - _nextGeometry = Application::getInstance()->getGeometryCache()->getGeometry(url, fallback, delayLoad); - if (retainCurrent && isActive() && !_nextGeometry->isLoaded()) { - return; + _nextBaseGeometry = _nextGeometry = Application::getInstance()->getGeometryCache()->getGeometry(url, fallback, delayLoad); + if (!retainCurrent || !isActive() || _nextGeometry->isLoaded()) { + applyNextGeometry(); } - - // delete our local geometry and custom textures - deleteGeometry(); - _dilatedTextures.clear(); - _lodHysteresis = NetworkGeometry::NO_HYSTERESIS; - - // we retain a reference to the base geometry so that its reference count doesn't fall to zero - _baseGeometry = _geometry = _nextGeometry; - _nextGeometry.reset(); } glm::vec4 Model::computeAverageColor() const { @@ -826,6 +781,61 @@ void Model::applyCollision(CollisionInfo& collision) { } } +QVector Model::updateGeometry(bool delayLoad) { + QVector newJointStates; + if (_nextGeometry) { + _nextGeometry = _nextGeometry->getLODOrFallback(_lodDistance, _lodHysteresis, delayLoad); + if (!delayLoad) { + _nextGeometry->setLoadPriority(this, -_lodDistance); + _nextGeometry->ensureLoading(); + } + if (_nextGeometry->isLoaded()) { + applyNextGeometry(); + return newJointStates; + } + } + if (!_geometry) { + return newJointStates; + } + QSharedPointer geometry = _geometry->getLODOrFallback(_lodDistance, _lodHysteresis, delayLoad); + if (_geometry != geometry) { + if (!_jointStates.isEmpty()) { + // copy the existing joint states + const FBXGeometry& oldGeometry = _geometry->getFBXGeometry(); + const FBXGeometry& newGeometry = geometry->getFBXGeometry(); + newJointStates = createJointStates(newGeometry); + for (QHash::const_iterator it = oldGeometry.jointIndices.constBegin(); + it != oldGeometry.jointIndices.constEnd(); it++) { + int newIndex = newGeometry.jointIndices.value(it.key()); + if (newIndex != 0) { + newJointStates[newIndex - 1] = _jointStates.at(it.value() - 1); + } + } + } + deleteGeometry(); + _dilatedTextures.clear(); + _geometry = geometry; + } + if (!delayLoad) { + _geometry->setLoadPriority(this, -_lodDistance); + _geometry->ensureLoading(); + } + return newJointStates; +} + +void Model::applyNextGeometry() { + // delete our local geometry and custom textures + deleteGeometry(); + _dilatedTextures.clear(); + _lodHysteresis = NetworkGeometry::NO_HYSTERESIS; + + // we retain a reference to the base geometry so that its reference count doesn't fall to zero + _baseGeometry = _nextBaseGeometry; + _geometry = _nextGeometry; + _nextBaseGeometry.reset(); + _nextGeometry.reset(); +} + void Model::deleteGeometry() { foreach (Model* attachment, _attachments) { delete attachment; diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 25bd1f08f5..524bd9dc79 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -237,10 +237,13 @@ protected: private: + QVector updateGeometry(bool delayLoad); + void applyNextGeometry(); void deleteGeometry(); void renderMeshes(float alpha, bool translucent); QSharedPointer _baseGeometry; ///< reference required to prevent collection of base + QSharedPointer _nextBaseGeometry; QSharedPointer _nextGeometry; float _lodDistance; float _lodHysteresis;