mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-19 07:59:01 +02:00
Add ModelLoader
This commit is contained in:
parent
be511378cd
commit
f900a81e7a
2 changed files with 139 additions and 0 deletions
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// ModelLoader.cpp
|
||||
// libraries/model-networking/src/model-networking
|
||||
//
|
||||
// Created by Sabrina Shanman on 2018/11/14.
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "ModelLoader.h"
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
//
|
||||
// ModelLoader.h
|
||||
// libraries/model-networking/src/model-networking
|
||||
//
|
||||
// Created by Sabrina Shanman on 2018/11/13.
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_ModelLoader_h
|
||||
#define hifi_ModelLoader_h
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
#include <shared/Hifitypes.h>
|
||||
#include <hfm/HFM.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;
|
||||
};
|
||||
|
||||
// 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(dynamic_cast<hfm::Serializer*>(&T()));
|
||||
|
||||
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