Made geometry refresh safe

This commit is contained in:
Atlante45 2015-07-10 15:20:19 -07:00
parent 5cfa1605df
commit 49993695a5
4 changed files with 49 additions and 14 deletions

View file

@ -544,7 +544,7 @@ const FBXGeometry* EntityTreeRenderer::getCollisionGeometryForEntity(EntityItemP
Model* model = modelEntityItem->getModel(this);
if (model) {
const QSharedPointer<NetworkGeometry> collisionNetworkGeometry = model->getCollisionGeometry();
if (!collisionNetworkGeometry.isNull()) {
if (!collisionNetworkGeometry || !collisionNetworkGeometry->isLoaded()) {
result = &collisionNetworkGeometry->getFBXGeometry();
}
}

View file

@ -397,8 +397,8 @@ bool RenderableModelEntityItem::isReadyToComputeShape() {
const QSharedPointer<NetworkGeometry> collisionNetworkGeometry = _model->getCollisionGeometry();
const QSharedPointer<NetworkGeometry> renderNetworkGeometry = _model->getGeometry();
if ((! collisionNetworkGeometry.isNull() && collisionNetworkGeometry->isLoadedWithTextures()) &&
(! renderNetworkGeometry.isNull() && renderNetworkGeometry->isLoadedWithTextures())) {
if ((!collisionNetworkGeometry && collisionNetworkGeometry->isLoadedWithTextures()) &&
(!renderNetworkGeometry && renderNetworkGeometry->isLoadedWithTextures())) {
// we have both URLs AND both geometries AND they are both fully loaded.
return true;
}
@ -419,7 +419,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
// should never fall in here when collision model not fully loaded
// hence we assert collisionNetworkGeometry is not NULL
assert(!collisionNetworkGeometry.isNull());
assert(!collisionNetworkGeometry);
const FBXGeometry& collisionGeometry = collisionNetworkGeometry->getFBXGeometry();
const QSharedPointer<NetworkGeometry> renderNetworkGeometry = _model->getGeometry();

View file

@ -457,7 +457,8 @@ bool Model::updateGeometry() {
}
deleteGeometry();
_dilatedTextures.clear();
_geometry = geometry;
setGeometry(geometry);
_meshGroupsKnown = false;
_readyWhenAdded = false; // in case any of our users are using scenes
invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid
@ -1142,13 +1143,32 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo
onInvalidate();
// if so instructed, keep the current geometry until the new one is loaded
_nextBaseGeometry = _nextGeometry = DependencyManager::get<GeometryCache>()->getGeometry(url, fallback, delayLoad);
_nextGeometry = DependencyManager::get<GeometryCache>()->getGeometry(url, fallback, delayLoad);
_nextLODHysteresis = NetworkGeometry::NO_HYSTERESIS;
if (!retainCurrent || !isActive() || (_nextGeometry && _nextGeometry->isLoaded())) {
applyNextGeometry();
}
}
void Model::geometryRefreshed() {
QObject* sender = QObject::sender();
if (sender == _geometry) {
_readyWhenAdded = false; // reset out render items.
_needsReload = true;
invalidCalculatedMeshBoxes();
onInvalidate();
// if so instructed, keep the current geometry until the new one is loaded
_nextGeometry = DependencyManager::get<GeometryCache>()->getGeometry(_url);
_nextLODHysteresis = NetworkGeometry::NO_HYSTERESIS;
applyNextGeometry();
} else {
sender->disconnect(this, SLOT(geometryRefreshed()));
}
}
const QSharedPointer<NetworkGeometry> Model::getCollisionGeometry(bool delayLoad)
{
@ -1156,7 +1176,11 @@ const QSharedPointer<NetworkGeometry> Model::getCollisionGeometry(bool delayLoad
_collisionGeometry = DependencyManager::get<GeometryCache>()->getGeometry(_collisionUrl, QUrl(), delayLoad);
}
return _collisionGeometry;
if (_collisionGeometry && _collisionGeometry->isLoaded()) {
return _collisionGeometry;
}
return QSharedPointer<NetworkGeometry>();
}
void Model::setCollisionModelURL(const QUrl& url) {
@ -1776,6 +1800,18 @@ void Model::setBlendedVertices(int blendNumber, const QWeakPointer<NetworkGeomet
}
}
void Model::setGeometry(const QSharedPointer<NetworkGeometry>& newGeometry) {
if (_geometry == newGeometry) {
return;
}
if (_geometry) {
_geometry->disconnect(_geometry.data(), &Resource::onRefresh, this, &Model::geometryRefreshed);
}
_geometry = newGeometry;
QObject::connect(_geometry.data(), &Resource::onRefresh, this, &Model::geometryRefreshed);
}
void Model::applyNextGeometry() {
// delete our local geometry and custom textures
deleteGeometry();
@ -1783,13 +1819,12 @@ void Model::applyNextGeometry() {
_lodHysteresis = _nextLODHysteresis;
// we retain a reference to the base geometry so that its reference count doesn't fall to zero
_baseGeometry = _nextBaseGeometry;
_geometry = _nextGeometry;
setGeometry(_nextGeometry);
_meshGroupsKnown = false;
_readyWhenAdded = false; // in case any of our users are using scenes
_needsReload = false; // we are loaded now!
invalidCalculatedMeshBoxes();
_nextBaseGeometry.reset();
_nextGeometry.reset();
}

View file

@ -245,6 +245,7 @@ public:
protected:
QSharedPointer<NetworkGeometry> _geometry;
void setGeometry(const QSharedPointer<NetworkGeometry>& newGeometry);
glm::vec3 _scale;
glm::vec3 _offset;
@ -321,6 +322,9 @@ protected:
// hook for derived classes to be notified when setUrl invalidates the current model.
virtual void onInvalidate() {};
protected slots:
void geometryRefreshed();
private:
friend class AnimationHandle;
@ -330,15 +334,12 @@ private:
QVector<JointState> createJointStates(const FBXGeometry& geometry);
void initJointTransforms();
QSharedPointer<NetworkGeometry> _baseGeometry; ///< reference required to prevent collection of base
QSharedPointer<NetworkGeometry> _nextBaseGeometry;
QSharedPointer<NetworkGeometry> _nextGeometry;
float _lodDistance;
float _lodHysteresis;
float _nextLODHysteresis;
QSharedPointer<NetworkGeometry> _collisionGeometry;
QSharedPointer<NetworkGeometry> _saveNonCollisionGeometry;
float _pupilDilation;
QVector<float> _blendshapeCoefficients;
@ -524,7 +525,6 @@ private:
QMap<render::ItemID, render::PayloadPointer> _renderItems;
bool _readyWhenAdded = false;
bool _needsReload = true;
};
Q_DECLARE_METATYPE(QPointer<Model>)