diff --git a/interface/src/ModelPackager.cpp b/interface/src/ModelPackager.cpp index a7fc0b9e20..5d7d4b1396 100644 --- a/interface/src/ModelPackager.cpp +++ b/interface/src/ModelPackager.cpp @@ -109,7 +109,7 @@ bool ModelPackager::loadModel() { qCDebug(interfaceapp) << "Reading FBX file : " << _fbxInfo.filePath(); QByteArray fbxContents = fbx.readAll(); - _hfmModel.reset(readFBX(fbxContents, QVariantHash(), _fbxInfo.filePath())); + _hfmModel.reset(FBXSerializer().read(fbxContents, QVariantHash(), _fbxInfo.filePath())); // make sure we have some basic mappings populateBasicMapping(_mapping, _fbxInfo.filePath(), *_hfmModel); diff --git a/libraries/animation/src/AnimationCache.cpp b/libraries/animation/src/AnimationCache.cpp index 06dfc0262a..5c9f083a3b 100644 --- a/libraries/animation/src/AnimationCache.cpp +++ b/libraries/animation/src/AnimationCache.cpp @@ -71,7 +71,7 @@ void AnimationReader::run() { // Parse the FBX directly from the QNetworkReply HFMModel::Pointer hfmModel; if (_url.path().toLower().endsWith(".fbx")) { - hfmModel.reset(readFBX(_data, QVariantHash(), _url.path())); + hfmModel.reset(FBXSerializer().read(_data, QVariantHash(), _url.path())); } else { QString errorStr("usupported format"); emit onError(299, errorStr); diff --git a/libraries/baking/src/FBXBaker.cpp b/libraries/baking/src/FBXBaker.cpp index 6349b06c49..afaca1dd62 100644 --- a/libraries/baking/src/FBXBaker.cpp +++ b/libraries/baking/src/FBXBaker.cpp @@ -187,10 +187,10 @@ void FBXBaker::importScene() { return; } - FBXSerializer serializer; + FBXSerializer fbxSerializer; qCDebug(model_baking) << "Parsing" << _modelURL; - _rootNode = serializer._rootNode = serializer.parseFBX(&fbxFile); + _rootNode = fbxSerializer._rootNode = fbxSerializer.parseFBX(&fbxFile); #ifdef HIFI_DUMP_FBX { @@ -206,8 +206,8 @@ void FBXBaker::importScene() { } #endif - _hfmModel = serializer.extractHFMModel({}, _modelURL.toString()); - _textureContentMap = serializer._textureContent; + _hfmModel = fbxSerializer.extractHFMModel({}, _modelURL.toString()); + _textureContentMap = fbxSerializer._textureContent; } void FBXBaker::rewriteAndBakeSceneModels() { diff --git a/libraries/baking/src/OBJBaker.cpp b/libraries/baking/src/OBJBaker.cpp index 389e708c12..83079bc052 100644 --- a/libraries/baking/src/OBJBaker.cpp +++ b/libraries/baking/src/OBJBaker.cpp @@ -145,7 +145,7 @@ void OBJBaker::bakeOBJ() { bool combineParts = true; // set true so that OBJSerializer reads material info from material library OBJSerializer serializer; - auto geometry = serializer.readOBJ(objData, QVariantHash(), combineParts, _modelURL); + auto geometry = serializer.read(objData, QVariantHash(), _modelURL, combineParts); // Write OBJ Data as FBX tree nodes createFBXNodeTree(_rootNode, *geometry); diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index fb7d95cf37..1cbb0ce386 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -1796,19 +1796,20 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr return hfmModelPtr; } -HFMModel* readFBX(const QByteArray& data, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) { +HFMModel* FBXSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url, bool combineParts) { QBuffer buffer(const_cast(&data)); buffer.open(QIODevice::ReadOnly); - return readFBX(&buffer, mapping, url, loadLightmaps, lightmapLevel); + return read(&buffer, mapping, url, combineParts); } -HFMModel* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) { - FBXSerializer serializer; - serializer._rootNode = FBXSerializer::parseFBX(device); - serializer._loadLightmaps = loadLightmaps; - serializer._lightmapLevel = lightmapLevel; +HFMModel* FBXSerializer::read(QIODevice* device, const QVariantHash& mapping, const QUrl& url, bool combineParts) { + _rootNode = parseFBX(device); qCDebug(modelformat) << "Reading FBX: " << url; - return serializer.extractHFMModel(mapping, url); + return extractHFMModel(mapping, url.toString()); +} + +HFMModel* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) { + return FBXSerializer().extractHFMModel(mapping, url); } diff --git a/libraries/fbx/src/FBXSerializer.h b/libraries/fbx/src/FBXSerializer.h index 9809b257e8..1173af2693 100644 --- a/libraries/fbx/src/FBXSerializer.h +++ b/libraries/fbx/src/FBXSerializer.h @@ -27,7 +27,7 @@ #include #include "FBX.h" -#include +#include #include #include @@ -35,10 +35,6 @@ class QIODevice; class FBXNode; -/// Reads HFMModel from the supplied model and mapping data. -/// \exception QString if an error occurs in parsing -HFMModel* readFBX(const QByteArray& data, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f); - /// Reads HFMModel from the supplied model and mapping data. /// \exception QString if an error occurs in parsing HFMModel* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f); @@ -102,9 +98,13 @@ public: class ExtractedMesh; -class FBXSerializer { +class FBXSerializer : public HFMSerializer { public: HFMModel* _hfmModel; + /// Reads HFMModel from the supplied model and mapping data. + /// \exception QString if an error occurs in parsing + HFMModel* read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl(), bool combineParts = false) override; + HFMModel* read(QIODevice* device, const QVariantHash& mapping, const QUrl& url = QUrl(), bool combineParts = false); FBXNode _rootNode; static FBXNode parseFBX(QIODevice* device); @@ -147,9 +147,9 @@ public: void consolidateHFMMaterials(const QVariantHash& mapping); - bool _loadLightmaps = true; - float _lightmapOffset = 0.0f; - float _lightmapLevel; + bool _loadLightmaps { true }; + float _lightmapOffset { 0.0f }; + float _lightmapLevel { 1.0f }; QMultiMap _connectionParentMap; QMultiMap _connectionChildMap; diff --git a/libraries/fbx/src/GLTFSerializer.cpp b/libraries/fbx/src/GLTFSerializer.cpp index 5e60cfffe7..8f529868db 100644 --- a/libraries/fbx/src/GLTFSerializer.cpp +++ b/libraries/fbx/src/GLTFSerializer.cpp @@ -910,8 +910,8 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const QUrl& url) { return true; } -HFMModel* GLTFSerializer::readGLTF(QByteArray& data, const QVariantHash& mapping, - const QUrl& url, bool loadLightmaps, float lightmapLevel) { +HFMModel* GLTFSerializer::read(const QByteArray& data, const QVariantHash& mapping, + const QUrl& url, bool combineParts) { _url = url; diff --git a/libraries/fbx/src/GLTFSerializer.h b/libraries/fbx/src/GLTFSerializer.h index 8ce64a83f2..754d097614 100644 --- a/libraries/fbx/src/GLTFSerializer.h +++ b/libraries/fbx/src/GLTFSerializer.h @@ -15,6 +15,7 @@ #include #include #include +#include #include "FBXSerializer.h" @@ -702,12 +703,12 @@ struct GLTFFile { } }; -class GLTFSerializer : public QObject { +class GLTFSerializer : public QObject, public HFMSerializer { Q_OBJECT public: GLTFSerializer(); - HFMModel* readGLTF(QByteArray& data, const QVariantHash& mapping, - const QUrl& url, bool loadLightmaps = true, float lightmapLevel = 1.0f); + HFMModel* read(const QByteArray& data, const QVariantHash& mapping, + const QUrl& url = QUrl(), bool combineParts = false) override; private: GLTFFile _file; QUrl _url; diff --git a/libraries/fbx/src/OBJSerializer.cpp b/libraries/fbx/src/OBJSerializer.cpp index a1a6893280..1684b2812c 100644 --- a/libraries/fbx/src/OBJSerializer.cpp +++ b/libraries/fbx/src/OBJSerializer.cpp @@ -652,12 +652,12 @@ done: } -HFMModel::Pointer OBJSerializer::readOBJ(QByteArray& data, const QVariantHash& mapping, bool combineParts, const QUrl& url) { +HFMModel* OBJSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url, bool combineParts) { PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xffff0000, nullptr); - QBuffer buffer { &data }; + QBuffer buffer { const_cast(&data) }; buffer.open(QIODevice::ReadOnly); - auto hfmModelPtr { std::make_shared() }; + auto hfmModelPtr = new HFMModel(); HFMModel& hfmModel { *hfmModelPtr }; OBJTokenizer tokenizer { &buffer }; float scaleGuess = 1.0f; diff --git a/libraries/fbx/src/OBJSerializer.h b/libraries/fbx/src/OBJSerializer.h index d33d2edf07..ccb97c02ff 100644 --- a/libraries/fbx/src/OBJSerializer.h +++ b/libraries/fbx/src/OBJSerializer.h @@ -1,5 +1,6 @@ #include +#include #include "FBXSerializer.h" class OBJTokenizer { @@ -75,7 +76,7 @@ public: OBJMaterial() : shininess(0.0f), opacity(1.0f), diffuseColor(0.9f), specularColor(0.9f), emissiveColor(0.0f), illuminationModel(-1) {} }; -class OBJSerializer: public QObject { // QObject so we can make network requests. +class OBJSerializer: public QObject, public HFMSerializer { // QObject so we can make network requests. Q_OBJECT public: typedef QVector FaceGroup; @@ -86,8 +87,8 @@ public: QVector faceGroups; QString currentMaterialName; QHash materials; - - HFMModel::Pointer readOBJ(QByteArray& data, const QVariantHash& mapping, bool combineParts, const QUrl& url = QUrl()); + + HFMModel* read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl(), bool combineParts = false) override; private: QUrl _url; diff --git a/libraries/hfm/src/hfm/HFMSerializer.h b/libraries/hfm/src/hfm/HFMSerializer.h index bd63d8bf82..3cd48b76b2 100644 --- a/libraries/hfm/src/hfm/HFMSerializer.h +++ b/libraries/hfm/src/hfm/HFMSerializer.h @@ -26,4 +26,6 @@ class Serializer { }; +using HFMSerializer = hfm::Serializer; + #endif // hifi_HFMSerializer_h diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 5a7e383630..507ee23f7c 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -196,23 +196,22 @@ void GeometryReader::run() { HFMModel::Pointer hfmModel; if (_url.path().toLower().endsWith(".fbx")) { - hfmModel.reset(readFBX(_data, _mapping, _url.path())); + hfmModel.reset(FBXSerializer().read(_data, _mapping, _url.path())); 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().readOBJ(_data, _mapping, _combineParts, _url); + hfmModel.reset(OBJSerializer().read(_data, _mapping, _url, _combineParts)); } else if (_url.path().toLower().endsWith(".obj.gz")) { QByteArray uncompressedData; if (gunzip(_data, uncompressedData)){ - hfmModel = OBJSerializer().readOBJ(uncompressedData, _mapping, _combineParts, _url); + hfmModel.reset(OBJSerializer().read(uncompressedData, _mapping, _url, _combineParts)); } else { throw QString("failed to decompress .obj.gz"); } } else if (_url.path().toLower().endsWith(".gltf")) { - std::shared_ptr glreader = std::make_shared(); - hfmModel.reset(glreader->readGLTF(_data, _mapping, _url)); + hfmModel.reset(GLTFSerializer().read(_data, _mapping, _url)); if (hfmModel->meshes.size() == 0 && hfmModel->joints.size() == 0) { throw QString("empty geometry, possibly due to an unsupported GLTF version"); } diff --git a/tests-manual/gpu/src/TestFbx.cpp b/tests-manual/gpu/src/TestFbx.cpp index 290913e406..379481baa8 100644 --- a/tests-manual/gpu/src/TestFbx.cpp +++ b/tests-manual/gpu/src/TestFbx.cpp @@ -100,7 +100,7 @@ bool TestFbx::isReady() const { void TestFbx::parseFbx(const QByteArray& fbxData) { QVariantHash mapping; - HFMModel* hfmModel = readFBX(fbxData, mapping); + HFMModel* hfmModel = FBXSerializer().read(fbxData, mapping); size_t totalVertexCount = 0; size_t totalIndexCount = 0; size_t totalPartCount = 0; diff --git a/tools/skeleton-dump/src/SkeletonDumpApp.cpp b/tools/skeleton-dump/src/SkeletonDumpApp.cpp index bad38f24ba..cbee73528f 100644 --- a/tools/skeleton-dump/src/SkeletonDumpApp.cpp +++ b/tools/skeleton-dump/src/SkeletonDumpApp.cpp @@ -54,7 +54,7 @@ SkeletonDumpApp::SkeletonDumpApp(int argc, char* argv[]) : QCoreApplication(argc return; } QByteArray blob = file.readAll(); - std::unique_ptr geometry(readFBX(blob, QVariantHash())); + std::unique_ptr geometry(FBXSerializer().read(blob, QVariantHash())); std::unique_ptr skeleton(new AnimSkeleton(*geometry)); skeleton->dump(verbose); } diff --git a/tools/vhacd-util/src/VHACDUtil.cpp b/tools/vhacd-util/src/VHACDUtil.cpp index b1dcdebe60..4036dbefa7 100644 --- a/tools/vhacd-util/src/VHACDUtil.cpp +++ b/tools/vhacd-util/src/VHACDUtil.cpp @@ -44,9 +44,9 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, HFMModel& result) { HFMModel::Pointer hfmModel; if (filename.toLower().endsWith(".obj")) { bool combineParts = false; - hfmModel = OBJSerializer().readOBJ(fbxContents, QVariantHash(), combineParts); + hfmModel.reset(OBJSerializer().read(fbxContents, QVariantHash(), filename, combineParts)); } else if (filename.toLower().endsWith(".fbx")) { - hfmModel.reset(readFBX(fbxContents, QVariantHash(), filename)); + hfmModel.reset(FBXSerializer().read(fbxContents, QVariantHash(), filename)); } else { qWarning() << "file has unknown extension" << filename; return false;