move compoundResource out of Model class

This commit is contained in:
Andrew Meadows 2016-07-28 07:31:32 -07:00
parent ef597265d7
commit b0a0293e6e
7 changed files with 42 additions and 78 deletions

View file

@ -499,22 +499,6 @@ ModelPointer EntityTreeRenderer::getModelForEntityItem(EntityItemPointer entityI
return result;
}
const FBXGeometry* EntityTreeRenderer::getCollisionGeometryForEntity(EntityItemPointer entityItem) {
const FBXGeometry* result = NULL;
if (entityItem->getType() == EntityTypes::Model) {
std::shared_ptr<RenderableModelEntityItem> modelEntityItem =
std::dynamic_pointer_cast<RenderableModelEntityItem>(entityItem);
if (modelEntityItem->hasCompoundShapeURL()) {
ModelPointer model = modelEntityItem->getModel(this);
if (model && model->isCollisionLoaded()) {
result = &model->getCollisionFBXGeometry();
}
}
}
return result;
}
void EntityTreeRenderer::processEraseMessage(ReceivedMessage& message, const SharedNodePointer& sourceNode) {
std::static_pointer_cast<EntityTree>(_tree)->processEraseMessage(message, sourceNode);
}
@ -536,7 +520,6 @@ ModelPointer EntityTreeRenderer::allocateModel(const QString& url, const QString
model->setLoadingPriority(loadingPriority);
model->init();
model->setURL(QUrl(url));
model->setCollisionModelURL(QUrl(collisionUrl));
return model;
}
@ -553,7 +536,6 @@ ModelPointer EntityTreeRenderer::updateModel(ModelPointer model, const QString&
}
model->setURL(QUrl(newUrl));
model->setCollisionModelURL(QUrl(collisionUrl));
return model;
}

View file

@ -65,7 +65,6 @@ public:
virtual const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem) override;
virtual ModelPointer getModelForEntityItem(EntityItemPointer entityItem) override;
virtual const FBXGeometry* getCollisionGeometryForEntity(EntityItemPointer entityItem) override;
/// clears the tree
virtual void clear() override;

View file

@ -494,7 +494,7 @@ ModelPointer RenderableModelEntityItem::getModel(EntityTreeRenderer* renderer) {
_model = _myRenderer->allocateModel(getModelURL(), getCompoundShapeURL(), renderer->getEntityLoadingPriority(*this));
_needsInitialSimulation = true;
// If we need to change URLs, update it *after rendering* (to avoid access violations)
} else if ((QUrl(getModelURL()) != _model->getURL() || QUrl(getCompoundShapeURL()) != _model->getCollisionURL())) {
} else if (QUrl(getModelURL()) != _model->getURL()) {
QMetaObject::invokeMethod(_myRenderer, "updateModel", Qt::QueuedConnection,
Q_ARG(ModelPointer, _model),
Q_ARG(const QString&, getModelURL()),
@ -566,6 +566,18 @@ bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& ori
face, surfaceNormal, extraInfo, precisionPicking);
}
void RenderableModelEntityItem::setShapeType(ShapeType type) {
ModelEntityItem::setShapeType(type);
if (_shapeType == SHAPE_TYPE_COMPOUND) {
if (!_compoundShapeResource && !_compoundShapeURL.isEmpty()) {
_compoundShapeResource = DependencyManager::get<ModelCache>()->getGeometryResource(getCompoundShapeURL());
}
} else if (_compoundShapeResource && !_compoundShapeURL.isEmpty()) {
// the compoundURL has been set but the shapeType does not agree
_compoundShapeResource.reset();
}
}
void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) {
auto currentCompoundShapeURL = getCompoundShapeURL();
ModelEntityItem::setCompoundShapeURL(url);
@ -575,6 +587,9 @@ void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) {
if (tree) {
QMetaObject::invokeMethod(tree.get(), "callLoader", Qt::QueuedConnection, Q_ARG(EntityItemID, getID()));
}
if (_shapeType == SHAPE_TYPE_COMPOUND) {
_compoundShapeResource = DependencyManager::get<ModelCache>()->getGeometryResource(url);
}
}
}
@ -582,7 +597,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() {
ShapeType type = getShapeType();
if (type == SHAPE_TYPE_COMPOUND) {
if (!_model || _model->getCollisionURL().isEmpty()) {
if (!_model || _compoundShapeURL.isEmpty()) {
EntityTreePointer tree = getTree();
if (tree) {
QMetaObject::invokeMethod(tree.get(), "callLoader", Qt::QueuedConnection, Q_ARG(EntityItemID, getID()));
@ -595,15 +610,18 @@ bool RenderableModelEntityItem::isReadyToComputeShape() {
return false;
}
if (_model->isLoaded() && _model->isCollisionLoaded()) {
// we have both URLs AND both geometries AND they are both fully loaded.
if (_needsInitialSimulation) {
// the _model's offset will be wrong until _needsInitialSimulation is false
PerformanceTimer perfTimer("_model->simulate");
doInitialModelSimulation();
if (_model->isLoaded()) {
if (_compoundShapeResource && _compoundShapeResource->isLoaded()) {
// we have both URLs AND both geometries AND they are both fully loaded.
if (_needsInitialSimulation) {
// the _model's offset will be wrong until _needsInitialSimulation is false
PerformanceTimer perfTimer("_model->simulate");
doInitialModelSimulation();
}
return true;
} else if (!_compoundShapeURL.isEmpty()) {
_compoundShapeResource = DependencyManager::get<ModelCache>()->getGeometryResource(_compoundShapeURL);
}
return true;
}
// the model is still being downloaded.
@ -625,8 +643,8 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
// should never fall in here when collision model not fully loaded
// hence we assert that all geometries exist and are loaded
assert(_model && _model->isLoaded() && _model->isCollisionLoaded());
const FBXGeometry& collisionGeometry = _model->getCollisionFBXGeometry();
assert(_model && _model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded());
const FBXGeometry& collisionGeometry = _compoundShapeResource->getFBXGeometry();
ShapeInfo::PointCollection& pointCollection = info.getPointCollection();
pointCollection.clear();
@ -956,8 +974,8 @@ void RenderableModelEntityItem::setCollisionShape(const btCollisionShape* shape)
}
bool RenderableModelEntityItem::contains(const glm::vec3& point) const {
if (EntityItem::contains(point) && _model && _model->isCollisionLoaded()) {
return _model->getCollisionFBXGeometry().convexHullContains(worldToEntity(point));
if (EntityItem::contains(point) && _model && _compoundShapeResource && _compoundShapeResource->isLoaded()) {
return _compoundShapeResource->getFBXGeometry().convexHullContains(worldToEntity(point));
}
return false;

View file

@ -56,6 +56,7 @@ public:
virtual bool needsToCallUpdate() const override;
virtual void update(const quint64& now) override;
virtual void setShapeType(ShapeType type) override;
virtual void setCompoundShapeURL(const QString& url) override;
virtual bool isReadyToComputeShape() override;
@ -100,6 +101,7 @@ private:
QVariantMap parseTexturesToMap(QString textures);
void remapTextures();
GeometryResource::Pointer _compoundShapeResource;
ModelPointer _model = nullptr;
bool _needsInitialSimulation = true;
bool _needsModelReload = true;

View file

@ -40,7 +40,6 @@ class EntityItemFBXService {
public:
virtual const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem) = 0;
virtual ModelPointer getModelForEntityItem(EntityItemPointer entityItem) = 0;
virtual const FBXGeometry* getCollisionGeometryForEntity(EntityItemPointer entityItem) = 0;
};

View file

@ -82,7 +82,6 @@ Model::Model(RigPointer rig, QObject* parent) :
_renderGeometry(),
_collisionGeometry(),
_renderWatcher(_renderGeometry),
_collisionWatcher(_collisionGeometry),
_translation(0.0f),
_rotation(),
_scale(1.0f, 1.0f, 1.0f),
@ -111,7 +110,6 @@ Model::Model(RigPointer rig, QObject* parent) :
setSnapModelToRegistrationPoint(true, glm::vec3(0.5f));
connect(&_renderWatcher, &GeometryResourceWatcher::finished, this, &Model::loadURLFinished);
connect(&_collisionWatcher, &GeometryResourceWatcher::finished, this, &Model::loadCollisionModelURLFinished);
}
Model::~Model() {
@ -121,17 +119,15 @@ Model::~Model() {
AbstractViewStateInterface* Model::_viewState = NULL;
void Model::setShowCollisionMesh(bool value) {
if (_readyToShowCollisionGeometry) {
if (_showCollisionGeometry != value) {
_showCollisionGeometry = value;
_needsFixupInScene = true;
}
if (_showCollisionGeometry != value) {
_showCollisionGeometry = value;
_needsFixupInScene = true;
}
}
bool Model::needsFixupInScene() const {
if ((_needsFixupInScene || !_addedToScene) && !_needsReload && isLoaded()) {
if (_showCollisionGeometry && _readyToShowCollisionGeometry && _collisionGeometry) {
if (_showCollisionGeometry && _collisionGeometry) {
return true;
}
if (!_meshStates.isEmpty() || (_renderGeometry && _renderGeometry->getMeshes().empty())) {
@ -614,13 +610,13 @@ void Model::setVisibleInScene(bool newValue, std::shared_ptr<render::Scene> scen
bool Model::addToScene(std::shared_ptr<render::Scene> scene,
render::PendingChanges& pendingChanges,
render::Item::Status::Getters& statusGetters) {
bool readyToRender = (_showCollisionGeometry && _readyToShowCollisionGeometry && _collisionGeometry) || isLoaded();
bool readyToRender = (_showCollisionGeometry && _collisionGeometry) || isLoaded();
if (!_addedToScene && readyToRender) {
createRenderItemSet();
}
bool somethingAdded = false;
if (_showCollisionGeometry && _readyToShowCollisionGeometry && _collisionGeometry) {
if (_showCollisionGeometry && _collisionGeometry) {
if (_collisionRenderItems.empty()) {
foreach (auto renderItem, _collisionRenderItemsSet) {
auto item = scene->allocateID();
@ -864,23 +860,6 @@ void Model::loadURLFinished(bool success) {
emit setURLFinished(success);
}
void Model::setCollisionModelURL(const QUrl& url) {
if (_collisionUrl == url && _collisionWatcher.getURL() == url) {
return;
}
_collisionUrl = url;
_collisionGeometryRequestFailed = false;
_collisionWatcher.setResource(DependencyManager::get<ModelCache>()->getGeometryResource(url));
}
void Model::loadCollisionModelURLFinished(bool success) {
if (!success) {
_collisionGeometryRequestFailed = true;
}
emit setCollisionModelURLFinished(success);
}
bool Model::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position) const {
return _rig->getJointPositionInWorldFrame(jointIndex, position, _translation, _rotation);
}
@ -1258,7 +1237,7 @@ AABox Model::getRenderableMeshBound() const {
}
void Model::createRenderItemSet() {
if (_showCollisionGeometry && _readyToShowCollisionGeometry && _collisionGeometry) {
if (_showCollisionGeometry && _collisionGeometry) {
if (_collisionRenderItemsSet.empty()) {
createCollisionRenderItemSet();
}
@ -1353,7 +1332,7 @@ bool Model::initWhenReady(render::ScenePointer scene) {
render::PendingChanges pendingChanges;
bool addedPendingChanges = false;
if (_showCollisionGeometry && _readyToShowCollisionGeometry && _collisionGeometry) {
if (_showCollisionGeometry && _collisionGeometry) {
foreach (auto renderItem, _collisionRenderItemsSet) {
auto item = scene->allocateID();
auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderItem);
@ -1395,14 +1374,8 @@ public:
};
void Model::setCollisionMesh(model::MeshPointer mesh) {
_collisionWatcher.stopWatching();
_collisionGeometry = std::make_shared<CollisionRenderGeometry>(mesh);
// HACK: we don't want to show the _collisionGeometry until we're ready (e.g. it has been created)
// hence we track whether it has been created using _readyToShowCollisionGeoemtry, because there
// is an ambiguous case where _collisionGeometry is valid (from CompoundURL) but has not yet been
// properly computed (zeroed offset transform) using the CollisionRenderMeshCache.
//
// TODO: At the moment we create the collision mesh for every model that has a collision shape
// as soon as we know the shape, but we SHOULD only ever create the render mesh when we need it.
if (_showCollisionGeometry) {

View file

@ -115,7 +115,6 @@ public:
const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& normals);
bool isLoaded() const { return (bool)_renderGeometry; }
bool isCollisionLoaded() const { return (bool)_collisionGeometry; }
void setIsWireframe(bool isWireframe) { _isWireframe = isWireframe; }
bool isWireframe() const { return _isWireframe; }
@ -142,13 +141,9 @@ public:
/// Provided as a convenience, will crash if !isLoaded()
// And so that getGeometry() isn't chained everywhere
const FBXGeometry& getFBXGeometry() const { assert(isLoaded()); return _renderGeometry->getFBXGeometry(); }
/// Provided as a convenience, will crash if !isCollisionLoaded()
const FBXGeometry& getCollisionFBXGeometry() const { assert(isCollisionLoaded()); return _collisionGeometry->getFBXGeometry(); }
// Set the model to use for collisions.
// Should only be called from the model's rendering thread to avoid access violations of changed geometry.
Q_INVOKABLE void setCollisionModelURL(const QUrl& url);
const QUrl& getCollisionURL() const { return _collisionUrl; }
bool isActive() const { return isLoaded(); }
@ -246,7 +241,6 @@ public:
public slots:
void loadURLFinished(bool success);
void loadCollisionModelURLFinished(bool success);
signals:
void setURLFinished(bool success);
@ -288,7 +282,6 @@ protected:
Geometry::Pointer _collisionGeometry;
GeometryResourceWatcher _renderWatcher;
GeometryResourceWatcher _collisionWatcher;
glm::vec3 _translation;
glm::quat _rotation;
@ -356,7 +349,6 @@ protected:
QVector<float> _blendshapeCoefficients;
QUrl _url;
QUrl _collisionUrl;
bool _isVisible;
gpu::Buffers _blendedVertexBuffers;
@ -404,7 +396,6 @@ protected:
bool _needsReload { true };
bool _needsUpdateClusterMatrices { true };
bool _showCollisionGeometry { false };
bool _readyToShowCollisionGeometry { false };
mutable bool _needsUpdateTextures { true };
friend class ModelMeshPartPayload;