mirror of
https://github.com/lubosz/overte.git
synced 2025-08-04 20:30:26 +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 "ModelLoader.h"
|
||||||
|
|
||||||
#include "FBXSerializer.h"
|
#include <DependencyManager.h>
|
||||||
#include "OBJSerializer.h"
|
#include "ModelFormatRegistry.h"
|
||||||
#include "GLTFSerializer.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 {
|
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
|
auto factory = DependencyManager::get<ModelFormatRegistry>()->getFactoryForMIMEType(data, mapping, url, webMediaType);
|
||||||
for (auto& supportedFormat : supportedFormats) {
|
if (!factory) {
|
||||||
for (auto& fileSignature : supportedFormat.mimeType.fileSignatures) {
|
return hfm::Model::Pointer();
|
||||||
auto testBytes = data.mid(fileSignature.byteOffset, (int)fileSignature.bytes.size()).toStdString();
|
|
||||||
if (testBytes == fileSignature.bytes) {
|
|
||||||
return supportedFormat.loader(data, mapping, url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return factory->get()->read(data, mapping, url);
|
||||||
// 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();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,82 +12,15 @@
|
||||||
#ifndef hifi_ModelLoader_h
|
#ifndef hifi_ModelLoader_h
|
||||||
#define hifi_ModelLoader_h
|
#define hifi_ModelLoader_h
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#include <shared/HifiTypes.h>
|
#include <shared/HifiTypes.h>
|
||||||
#include <hfm/HFM.h>
|
#include <hfm/HFM.h>
|
||||||
#include <hfm/HFMSerializer.h>
|
|
||||||
|
|
||||||
class ModelLoader {
|
class ModelLoader {
|
||||||
public:
|
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.
|
// 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 successful, return an owned reference to the newly loaded model.
|
||||||
// If failed, return an empty reference.
|
// 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;
|
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
|
#endif // hifi_ModelLoader_h
|
||||||
|
|
Loading…
Reference in a new issue