mirror of
https://github.com/lubosz/overte.git
synced 2025-04-19 16:44:04 +02:00
move compoundResource out of Model class
This commit is contained in:
parent
ef597265d7
commit
b0a0293e6e
7 changed files with 42 additions and 78 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue