mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 09:09:56 +02:00
Add MIME type-based Serializer selection
This commit is contained in:
parent
2387641cbb
commit
b3d5f2fa65
1 changed files with 55 additions and 60 deletions
|
@ -144,9 +144,9 @@ void GeometryMappingResource::onGeometryMappingLoaded(bool success) {
|
||||||
|
|
||||||
class GeometryReader : public QRunnable {
|
class GeometryReader : public QRunnable {
|
||||||
public:
|
public:
|
||||||
GeometryReader(QWeakPointer<Resource>& resource, const QUrl& url, const QVariantHash& mapping,
|
GeometryReader(const ModelLoader& modelLoader, QWeakPointer<Resource>& resource, const QUrl& url, const QVariantHash& mapping,
|
||||||
const QByteArray& data, bool combineParts) :
|
const QByteArray& data, bool combineParts, const QString& webMediaType) :
|
||||||
_resource(resource), _url(url), _mapping(mapping), _data(data), _combineParts(combineParts) {
|
_modelLoader(modelLoader), _resource(resource), _url(url), _mapping(mapping), _data(data), _combineParts(combineParts), _webMediaType(webMediaType) {
|
||||||
|
|
||||||
DependencyManager::get<StatTracker>()->incrementStat("PendingProcessing");
|
DependencyManager::get<StatTracker>()->incrementStat("PendingProcessing");
|
||||||
}
|
}
|
||||||
|
@ -154,11 +154,13 @@ public:
|
||||||
virtual void run() override;
|
virtual void run() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ModelLoader _modelLoader;
|
||||||
QWeakPointer<Resource> _resource;
|
QWeakPointer<Resource> _resource;
|
||||||
QUrl _url;
|
QUrl _url;
|
||||||
QVariantHash _mapping;
|
QVariantHash _mapping;
|
||||||
QByteArray _data;
|
QByteArray _data;
|
||||||
bool _combineParts;
|
bool _combineParts;
|
||||||
|
QString _webMediaType;
|
||||||
};
|
};
|
||||||
|
|
||||||
void GeometryReader::run() {
|
void GeometryReader::run() {
|
||||||
|
@ -183,62 +185,54 @@ void GeometryReader::run() {
|
||||||
throw QString("reply is NULL");
|
throw QString("reply is NULL");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure the resource has not been deleted
|
||||||
|
auto resource = _resource.toStrongRef();
|
||||||
|
if (!resource) {
|
||||||
|
qCWarning(modelnetworking) << "Abandoning load of" << _url << "; could not get strong ref";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QString urlname = _url.path().toLower();
|
QString urlname = _url.path().toLower();
|
||||||
if (!urlname.isEmpty() && !_url.path().isEmpty() &&
|
if (urlname.isEmpty() || _url.path().isEmpty()) {
|
||||||
|
|
||||||
(_url.path().toLower().endsWith(".fbx") ||
|
|
||||||
_url.path().toLower().endsWith(".obj") ||
|
|
||||||
_url.path().toLower().endsWith(".obj.gz") ||
|
|
||||||
_url.path().toLower().endsWith(".gltf"))) {
|
|
||||||
|
|
||||||
HFMModel::Pointer hfmModel;
|
|
||||||
|
|
||||||
QVariantHash serializerMapping = _mapping;
|
|
||||||
serializerMapping["combineParts"] = _combineParts;
|
|
||||||
|
|
||||||
if (_url.path().toLower().endsWith(".fbx")) {
|
|
||||||
hfmModel = FBXSerializer().read(_data, serializerMapping, _url);
|
|
||||||
if (hfmModel->meshes.size() == 0 && hfmModel->joints.size() == 0) {
|
|
||||||
throw QString("empty geometry, possibly due to an unsupported FBX version");
|
|
||||||
}
|
|
||||||
} else if (_url.path().toLower().endsWith(".obj")) {
|
|
||||||
hfmModel = OBJSerializer().read(_data, serializerMapping, _url);
|
|
||||||
} else if (_url.path().toLower().endsWith(".obj.gz")) {
|
|
||||||
QByteArray uncompressedData;
|
|
||||||
if (gunzip(_data, uncompressedData)){
|
|
||||||
hfmModel = OBJSerializer().read(uncompressedData, serializerMapping, _url);
|
|
||||||
} else {
|
|
||||||
throw QString("failed to decompress .obj.gz");
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (_url.path().toLower().endsWith(".gltf")) {
|
|
||||||
hfmModel = GLTFSerializer().read(_data, serializerMapping, _url);
|
|
||||||
if (hfmModel->meshes.size() == 0 && hfmModel->joints.size() == 0) {
|
|
||||||
throw QString("empty geometry, possibly due to an unsupported GLTF version");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw QString("unsupported format");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add scripts to hfmModel
|
|
||||||
if (!_mapping.value(SCRIPT_FIELD).isNull()) {
|
|
||||||
QVariantList scripts = _mapping.values(SCRIPT_FIELD);
|
|
||||||
for (auto &script : scripts) {
|
|
||||||
hfmModel->scripts.push_back(script.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure the resource has not been deleted
|
|
||||||
auto resource = _resource.toStrongRef();
|
|
||||||
if (!resource) {
|
|
||||||
qCWarning(modelnetworking) << "Abandoning load of" << _url << "; could not get strong ref";
|
|
||||||
} else {
|
|
||||||
QMetaObject::invokeMethod(resource.data(), "setGeometryDefinition",
|
|
||||||
Q_ARG(HFMModel::Pointer, hfmModel));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw QString("url is invalid");
|
throw QString("url is invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HFMModel::Pointer hfmModel;
|
||||||
|
QVariantHash serializerMapping = _mapping;
|
||||||
|
serializerMapping["combineParts"] = _combineParts;
|
||||||
|
|
||||||
|
if (_url.path().toLower().endsWith(".gz")) {
|
||||||
|
QByteArray uncompressedData;
|
||||||
|
if (!gunzip(_data, uncompressedData)) {
|
||||||
|
throw QString("failed to decompress .gz model");
|
||||||
|
}
|
||||||
|
// Strip the compression extension from the path, so the loader can infer the file type from what remains.
|
||||||
|
// This is okay because we don't expect the serializer to be able to read the contents of a compressed model file.
|
||||||
|
auto strippedUrl = _url;
|
||||||
|
strippedUrl.setPath(_url.path().left(_url.path().size() - 3));
|
||||||
|
hfmModel = _modelLoader.load(uncompressedData, serializerMapping, strippedUrl, "");
|
||||||
|
} else {
|
||||||
|
hfmModel = _modelLoader.load(_data, serializerMapping, _url, _webMediaType.toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hfmModel) {
|
||||||
|
throw QString("unsupported format");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hfmModel->meshes.size() == 0 && hfmModel->joints.size() == 0) {
|
||||||
|
throw QString("empty geometry, possibly due to an unsupported model version");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add scripts to hfmModel
|
||||||
|
if (!_mapping.value(SCRIPT_FIELD).isNull()) {
|
||||||
|
QVariantList scripts = _mapping.values(SCRIPT_FIELD);
|
||||||
|
for (auto &script : scripts) {
|
||||||
|
hfmModel->scripts.push_back(script.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod(resource.data(), "setGeometryDefinition",
|
||||||
|
Q_ARG(HFMModel::Pointer, hfmModel));
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
auto resource = _resource.toStrongRef();
|
auto resource = _resource.toStrongRef();
|
||||||
if (resource) {
|
if (resource) {
|
||||||
|
@ -258,8 +252,8 @@ void GeometryReader::run() {
|
||||||
class GeometryDefinitionResource : public GeometryResource {
|
class GeometryDefinitionResource : public GeometryResource {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
GeometryDefinitionResource(const QUrl& url, const QVariantHash& mapping, const QUrl& textureBaseUrl, bool combineParts) :
|
GeometryDefinitionResource(const ModelLoader& modelLoader, const QUrl& url, const QVariantHash& mapping, const QUrl& textureBaseUrl, bool combineParts) :
|
||||||
GeometryResource(url, resolveTextureBaseUrl(url, textureBaseUrl)), _mapping(mapping), _combineParts(combineParts) {}
|
GeometryResource(url, resolveTextureBaseUrl(url, textureBaseUrl)), _modelLoader(modelLoader), _mapping(mapping), _combineParts(combineParts) {}
|
||||||
|
|
||||||
QString getType() const override { return "GeometryDefinition"; }
|
QString getType() const override { return "GeometryDefinition"; }
|
||||||
|
|
||||||
|
@ -269,6 +263,7 @@ protected:
|
||||||
Q_INVOKABLE void setGeometryDefinition(HFMModel::Pointer hfmModel);
|
Q_INVOKABLE void setGeometryDefinition(HFMModel::Pointer hfmModel);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ModelLoader _modelLoader;
|
||||||
QVariantHash _mapping;
|
QVariantHash _mapping;
|
||||||
bool _combineParts;
|
bool _combineParts;
|
||||||
};
|
};
|
||||||
|
@ -278,7 +273,7 @@ void GeometryDefinitionResource::downloadFinished(const QByteArray& data) {
|
||||||
_url = _effectiveBaseURL;
|
_url = _effectiveBaseURL;
|
||||||
_textureBaseUrl = _effectiveBaseURL;
|
_textureBaseUrl = _effectiveBaseURL;
|
||||||
}
|
}
|
||||||
QThreadPool::globalInstance()->start(new GeometryReader(_self, _effectiveBaseURL, _mapping, data, _combineParts));
|
QThreadPool::globalInstance()->start(new GeometryReader(_modelLoader, _self, _effectiveBaseURL, _mapping, data, _combineParts, _request->getWebMediaType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryDefinitionResource::setGeometryDefinition(HFMModel::Pointer hfmModel) {
|
void GeometryDefinitionResource::setGeometryDefinition(HFMModel::Pointer hfmModel) {
|
||||||
|
@ -344,7 +339,7 @@ QSharedPointer<Resource> ModelCache::createResource(const QUrl& url, const QShar
|
||||||
auto mapping = geometryExtra ? geometryExtra->mapping : QVariantHash();
|
auto mapping = geometryExtra ? geometryExtra->mapping : QVariantHash();
|
||||||
auto textureBaseUrl = geometryExtra ? geometryExtra->textureBaseUrl : QUrl();
|
auto textureBaseUrl = geometryExtra ? geometryExtra->textureBaseUrl : QUrl();
|
||||||
bool combineParts = geometryExtra ? geometryExtra->combineParts : true;
|
bool combineParts = geometryExtra ? geometryExtra->combineParts : true;
|
||||||
resource = new GeometryDefinitionResource(url, mapping, textureBaseUrl, combineParts);
|
resource = new GeometryDefinitionResource(_modelLoader, url, mapping, textureBaseUrl, combineParts);
|
||||||
}
|
}
|
||||||
|
|
||||||
return QSharedPointer<Resource>(resource, &Resource::deleter);
|
return QSharedPointer<Resource>(resource, &Resource::deleter);
|
||||||
|
|
Loading…
Reference in a new issue