mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 17:14:59 +02:00
Simplify ModelLoader to utilize new model format registry
This commit is contained in:
parent
243a1d6598
commit
39d1a2be6f
2 changed files with 6 additions and 123 deletions
|
@ -11,64 +11,14 @@
|
|||
|
||||
#include "ModelLoader.h"
|
||||
|
||||
#include "FBXSerializer.h"
|
||||
#include "OBJSerializer.h"
|
||||
#include "GLTFSerializer.h"
|
||||
#include <DependencyManager.h>
|
||||
#include "ModelFormatRegistry.h"
|
||||
|
||||
ModelLoader::ModelLoader() {
|
||||
// Add supported model formats
|
||||
|
||||
MIMEType fbxMIMEType("fbx");
|
||||
fbxMIMEType.extensions.push_back("fbx");
|
||||
fbxMIMEType.fileSignatures.emplace_back("Kaydara FBX Binary \x00", 0);
|
||||
addSupportedFormat<FBXSerializer>(fbxMIMEType);
|
||||
|
||||
MIMEType objMIMEType("obj");
|
||||
objMIMEType.extensions.push_back("obj");
|
||||
addSupportedFormat<OBJSerializer>(objMIMEType);
|
||||
|
||||
MIMEType gltfMIMEType("gltf");
|
||||
gltfMIMEType.extensions.push_back("gltf");
|
||||
gltfMIMEType.webMediaTypes.push_back("model/gltf+json");
|
||||
addSupportedFormat<GLTFSerializer>(gltfMIMEType);
|
||||
}
|
||||
|
||||
hfm::Model::Pointer ModelLoader::load(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const {
|
||||
// Check file contents
|
||||
for (auto& supportedFormat : supportedFormats) {
|
||||
for (auto& fileSignature : supportedFormat.mimeType.fileSignatures) {
|
||||
auto testBytes = data.mid(fileSignature.byteOffset, (int)fileSignature.bytes.size()).toStdString();
|
||||
if (testBytes == fileSignature.bytes) {
|
||||
return supportedFormat.loader(data, mapping, url);
|
||||
}
|
||||
}
|
||||
auto factory = DependencyManager::get<ModelFormatRegistry>()->getFactoryForMIMEType(data, mapping, url, webMediaType);
|
||||
if (!factory) {
|
||||
return hfm::Model::Pointer();
|
||||
}
|
||||
|
||||
// Check file extension
|
||||
std::string urlString = url.path().toStdString();
|
||||
std::size_t extensionSeparator = urlString.rfind('.');
|
||||
if (extensionSeparator != std::string::npos) {
|
||||
std::string detectedExtension = urlString.substr(extensionSeparator + 1);
|
||||
for (auto& supportedFormat : supportedFormats) {
|
||||
for (auto& extension : supportedFormat.mimeType.extensions) {
|
||||
if (extension == detectedExtension) {
|
||||
return supportedFormat.loader(data, mapping, url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check web media type
|
||||
if (webMediaType != "") {
|
||||
for (auto& supportedFormat : supportedFormats) {
|
||||
for (auto& candidateWebMediaType : supportedFormat.mimeType.webMediaTypes) {
|
||||
if (candidateWebMediaType == webMediaType) {
|
||||
return supportedFormat.loader(data, mapping, url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Supported file type not found. Abort loading.
|
||||
return hfm::Model::Pointer();
|
||||
return factory->get()->read(data, mapping, url);
|
||||
}
|
||||
|
|
|
@ -12,82 +12,15 @@
|
|||
#ifndef hifi_ModelLoader_h
|
||||
#define hifi_ModelLoader_h
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
#include <shared/HifiTypes.h>
|
||||
#include <hfm/HFM.h>
|
||||
#include <hfm/HFMSerializer.h>
|
||||
|
||||
class ModelLoader {
|
||||
public:
|
||||
|
||||
// A short sequence of bytes, typically at the beginning of the file, which identifies the file format
|
||||
class FileSignature {
|
||||
public:
|
||||
FileSignature(const std::string& bytes, int byteOffset) :
|
||||
bytes(bytes),
|
||||
byteOffset(byteOffset) {
|
||||
}
|
||||
|
||||
std::string bytes;
|
||||
int byteOffset;
|
||||
};
|
||||
|
||||
// A named file extension with a list of known ways to positively identify the file type
|
||||
class MIMEType {
|
||||
public:
|
||||
MIMEType(const std::string& name) :
|
||||
name(name) {
|
||||
}
|
||||
|
||||
std::string name;
|
||||
std::vector<std::string> extensions;
|
||||
std::vector<std::string> webMediaTypes;
|
||||
std::vector<FileSignature> fileSignatures;
|
||||
};
|
||||
|
||||
ModelLoader();
|
||||
|
||||
// T is a subclass of hfm::Serializer
|
||||
template <typename T>
|
||||
void addSupportedFormat(const MIMEType& mimeType) {
|
||||
supportedFormats.push_back(SupportedFormat(mimeType, SupportedFormat::getLoader<T>()));
|
||||
}
|
||||
|
||||
// Given the currently stored list of supported file formats, determine how to load a model from the given parameters.
|
||||
// If successful, return an owned reference to the newly loaded model.
|
||||
// If failed, return an empty reference.
|
||||
hfm::Model::Pointer load(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const;
|
||||
|
||||
protected:
|
||||
using Loader = std::function<hfm::Model::Pointer(const hifi::ByteArray&, const hifi::VariantHash&, const hifi::URL&)>;
|
||||
|
||||
class SupportedFormat {
|
||||
public:
|
||||
SupportedFormat(const MIMEType& mimeType, const Loader& loader) :
|
||||
mimeType(mimeType),
|
||||
loader(loader) {
|
||||
}
|
||||
|
||||
MIMEType mimeType;
|
||||
Loader loader;
|
||||
|
||||
template <typename T>
|
||||
static Loader getLoader() {
|
||||
assert([](){
|
||||
T t;
|
||||
return dynamic_cast<hfm::Serializer*>(&t) != nullptr;
|
||||
}());
|
||||
|
||||
return [](const hifi::ByteArray& bytes, const hifi::VariantHash& mapping, const hifi::URL& url) -> hfm::Model::Pointer {
|
||||
return T().read(bytes, mapping, url);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<SupportedFormat> supportedFormats;
|
||||
};
|
||||
|
||||
#endif // hifi_ModelLoader_h
|
||||
|
|
Loading…
Reference in a new issue