mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-04-11 22:13:00 +02:00
Convert serializers and FBX.h to use HifiTypes.h
This commit is contained in:
parent
8ff212ac95
commit
2af17015d3
10 changed files with 177 additions and 179 deletions
|
@ -13,16 +13,17 @@
|
|||
#define hifi_FBX_h_
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QVarLengthArray>
|
||||
#include <QVariant>
|
||||
#include <QVector>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <shared/HifiTypes.h>
|
||||
|
||||
// See comment in FBXSerializer::parseFBX().
|
||||
static const int FBX_HEADER_BYTES_BEFORE_VERSION = 23;
|
||||
static const QByteArray FBX_BINARY_PROLOG("Kaydara FBX Binary ");
|
||||
static const QByteArray FBX_BINARY_PROLOG2("\0\x1a\0", 3);
|
||||
static const hifi::ByteArray FBX_BINARY_PROLOG("Kaydara FBX Binary ");
|
||||
static const hifi::ByteArray FBX_BINARY_PROLOG2("\0\x1a\0", 3);
|
||||
static const quint32 FBX_VERSION_2015 = 7400;
|
||||
static const quint32 FBX_VERSION_2016 = 7500;
|
||||
|
||||
|
@ -36,7 +37,7 @@ using FBXNodeList = QList<FBXNode>;
|
|||
/// A node within an FBX document.
|
||||
class FBXNode {
|
||||
public:
|
||||
QByteArray name;
|
||||
hifi::ByteArray name;
|
||||
QVariantList properties;
|
||||
FBXNodeList children;
|
||||
};
|
||||
|
|
|
@ -179,7 +179,7 @@ public:
|
|||
|
||||
void printNode(const FBXNode& node, int indentLevel) {
|
||||
int indentLength = 2;
|
||||
QByteArray spaces(indentLevel * indentLength, ' ');
|
||||
hifi::ByteArray spaces(indentLevel * indentLength, ' ');
|
||||
QDebug nodeDebug = qDebug(modelformat);
|
||||
|
||||
nodeDebug.nospace() << spaces.data() << node.name.data() << ": ";
|
||||
|
@ -309,7 +309,7 @@ public:
|
|||
};
|
||||
|
||||
bool checkMaterialsHaveTextures(const QHash<QString, HFMMaterial>& materials,
|
||||
const QHash<QString, QByteArray>& textureFilenames, const QMultiMap<QString, QString>& _connectionChildMap) {
|
||||
const QHash<QString, hifi::ByteArray>& textureFilenames, const QMultiMap<QString, QString>& _connectionChildMap) {
|
||||
foreach (const QString& materialID, materials.keys()) {
|
||||
foreach (const QString& childID, _connectionChildMap.values(materialID)) {
|
||||
if (textureFilenames.contains(childID)) {
|
||||
|
@ -376,7 +376,7 @@ HFMLight extractLight(const FBXNode& object) {
|
|||
return light;
|
||||
}
|
||||
|
||||
QByteArray fileOnUrl(const QByteArray& filepath, const QString& url) {
|
||||
hifi::ByteArray fileOnUrl(const hifi::ByteArray& filepath, const QString& url) {
|
||||
// in order to match the behaviour when loading models from remote URLs
|
||||
// we assume that all external textures are right beside the loaded model
|
||||
// ignoring any relative paths or absolute paths inside of models
|
||||
|
@ -384,7 +384,7 @@ QByteArray fileOnUrl(const QByteArray& filepath, const QString& url) {
|
|||
return filepath.mid(filepath.lastIndexOf('/') + 1);
|
||||
}
|
||||
|
||||
HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QString& url) {
|
||||
HFMModel* FBXSerializer::extractHFMModel(const hifi::VariantHash& mapping, const QString& url) {
|
||||
const FBXNode& node = _rootNode;
|
||||
QMap<QString, ExtractedMesh> meshes;
|
||||
QHash<QString, QString> modelIDsToNames;
|
||||
|
@ -407,11 +407,11 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
|
|||
|
||||
std::map<QString, HFMLight> lights;
|
||||
|
||||
QVariantHash blendshapeMappings = mapping.value("bs").toHash();
|
||||
hifi::VariantHash blendshapeMappings = mapping.value("bs").toHash();
|
||||
|
||||
QMultiHash<QByteArray, WeightedIndex> blendshapeIndices;
|
||||
QMultiHash<hifi::ByteArray, WeightedIndex> blendshapeIndices;
|
||||
for (int i = 0;; i++) {
|
||||
QByteArray blendshapeName = FACESHIFT_BLENDSHAPES[i];
|
||||
hifi::ByteArray blendshapeName = FACESHIFT_BLENDSHAPES[i];
|
||||
if (blendshapeName.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
|
@ -454,7 +454,7 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
|
|||
}
|
||||
} else if (subobject.name == "Properties70") {
|
||||
foreach (const FBXNode& subsubobject, subobject.children) {
|
||||
static const QVariant APPLICATION_NAME = QVariant(QByteArray("Original|ApplicationName"));
|
||||
static const QVariant APPLICATION_NAME = QVariant(hifi::ByteArray("Original|ApplicationName"));
|
||||
if (subsubobject.name == "P" && subsubobject.properties.size() >= 5 &&
|
||||
subsubobject.properties.at(0) == APPLICATION_NAME) {
|
||||
hfmModel.applicationName = subsubobject.properties.at(4).toString();
|
||||
|
@ -471,8 +471,8 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
|
|||
int index = 4;
|
||||
foreach (const FBXNode& subobject, object.children) {
|
||||
if (subobject.name == propertyName) {
|
||||
static const QVariant UNIT_SCALE_FACTOR = QByteArray("UnitScaleFactor");
|
||||
static const QVariant AMBIENT_COLOR = QByteArray("AmbientColor");
|
||||
static const QVariant UNIT_SCALE_FACTOR = hifi::ByteArray("UnitScaleFactor");
|
||||
static const QVariant AMBIENT_COLOR = hifi::ByteArray("AmbientColor");
|
||||
const auto& subpropName = subobject.properties.at(0);
|
||||
if (subpropName == UNIT_SCALE_FACTOR) {
|
||||
unitScaleFactor = subobject.properties.at(index).toFloat();
|
||||
|
@ -528,7 +528,7 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
|
|||
QVector<ExtractedBlendshape> blendshapes;
|
||||
foreach (const FBXNode& subobject, object.children) {
|
||||
bool properties = false;
|
||||
QByteArray propertyName;
|
||||
hifi::ByteArray propertyName;
|
||||
int index;
|
||||
if (subobject.name == "Properties60") {
|
||||
properties = true;
|
||||
|
@ -541,27 +541,27 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
|
|||
index = 4;
|
||||
}
|
||||
if (properties) {
|
||||
static const QVariant ROTATION_ORDER = QByteArray("RotationOrder");
|
||||
static const QVariant GEOMETRIC_TRANSLATION = QByteArray("GeometricTranslation");
|
||||
static const QVariant GEOMETRIC_ROTATION = QByteArray("GeometricRotation");
|
||||
static const QVariant GEOMETRIC_SCALING = QByteArray("GeometricScaling");
|
||||
static const QVariant LCL_TRANSLATION = QByteArray("Lcl Translation");
|
||||
static const QVariant LCL_ROTATION = QByteArray("Lcl Rotation");
|
||||
static const QVariant LCL_SCALING = QByteArray("Lcl Scaling");
|
||||
static const QVariant ROTATION_MAX = QByteArray("RotationMax");
|
||||
static const QVariant ROTATION_MAX_X = QByteArray("RotationMaxX");
|
||||
static const QVariant ROTATION_MAX_Y = QByteArray("RotationMaxY");
|
||||
static const QVariant ROTATION_MAX_Z = QByteArray("RotationMaxZ");
|
||||
static const QVariant ROTATION_MIN = QByteArray("RotationMin");
|
||||
static const QVariant ROTATION_MIN_X = QByteArray("RotationMinX");
|
||||
static const QVariant ROTATION_MIN_Y = QByteArray("RotationMinY");
|
||||
static const QVariant ROTATION_MIN_Z = QByteArray("RotationMinZ");
|
||||
static const QVariant ROTATION_OFFSET = QByteArray("RotationOffset");
|
||||
static const QVariant ROTATION_PIVOT = QByteArray("RotationPivot");
|
||||
static const QVariant SCALING_OFFSET = QByteArray("ScalingOffset");
|
||||
static const QVariant SCALING_PIVOT = QByteArray("ScalingPivot");
|
||||
static const QVariant PRE_ROTATION = QByteArray("PreRotation");
|
||||
static const QVariant POST_ROTATION = QByteArray("PostRotation");
|
||||
static const QVariant ROTATION_ORDER = hifi::ByteArray("RotationOrder");
|
||||
static const QVariant GEOMETRIC_TRANSLATION = hifi::ByteArray("GeometricTranslation");
|
||||
static const QVariant GEOMETRIC_ROTATION = hifi::ByteArray("GeometricRotation");
|
||||
static const QVariant GEOMETRIC_SCALING = hifi::ByteArray("GeometricScaling");
|
||||
static const QVariant LCL_TRANSLATION = hifi::ByteArray("Lcl Translation");
|
||||
static const QVariant LCL_ROTATION = hifi::ByteArray("Lcl Rotation");
|
||||
static const QVariant LCL_SCALING = hifi::ByteArray("Lcl Scaling");
|
||||
static const QVariant ROTATION_MAX = hifi::ByteArray("RotationMax");
|
||||
static const QVariant ROTATION_MAX_X = hifi::ByteArray("RotationMaxX");
|
||||
static const QVariant ROTATION_MAX_Y = hifi::ByteArray("RotationMaxY");
|
||||
static const QVariant ROTATION_MAX_Z = hifi::ByteArray("RotationMaxZ");
|
||||
static const QVariant ROTATION_MIN = hifi::ByteArray("RotationMin");
|
||||
static const QVariant ROTATION_MIN_X = hifi::ByteArray("RotationMinX");
|
||||
static const QVariant ROTATION_MIN_Y = hifi::ByteArray("RotationMinY");
|
||||
static const QVariant ROTATION_MIN_Z = hifi::ByteArray("RotationMinZ");
|
||||
static const QVariant ROTATION_OFFSET = hifi::ByteArray("RotationOffset");
|
||||
static const QVariant ROTATION_PIVOT = hifi::ByteArray("RotationPivot");
|
||||
static const QVariant SCALING_OFFSET = hifi::ByteArray("ScalingOffset");
|
||||
static const QVariant SCALING_PIVOT = hifi::ByteArray("ScalingPivot");
|
||||
static const QVariant PRE_ROTATION = hifi::ByteArray("PreRotation");
|
||||
static const QVariant POST_ROTATION = hifi::ByteArray("PostRotation");
|
||||
foreach(const FBXNode& property, subobject.children) {
|
||||
const auto& childProperty = property.properties.at(0);
|
||||
if (property.name == propertyName) {
|
||||
|
@ -701,8 +701,8 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
|
|||
const int MODEL_UV_SCALING_MIN_SIZE = 2;
|
||||
const int CROPPING_MIN_SIZE = 4;
|
||||
if (subobject.name == "RelativeFilename" && subobject.properties.length() >= RELATIVE_FILENAME_MIN_SIZE) {
|
||||
QByteArray filename = subobject.properties.at(0).toByteArray();
|
||||
QByteArray filepath = filename.replace('\\', '/');
|
||||
hifi::ByteArray filename = subobject.properties.at(0).toByteArray();
|
||||
hifi::ByteArray filepath = filename.replace('\\', '/');
|
||||
filename = fileOnUrl(filepath, url);
|
||||
_textureFilepaths.insert(getID(object.properties), filepath);
|
||||
_textureFilenames.insert(getID(object.properties), filename);
|
||||
|
@ -731,17 +731,17 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
|
|||
subobject.properties.at(2).value<int>(),
|
||||
subobject.properties.at(3).value<int>()));
|
||||
} else if (subobject.name == "Properties70") {
|
||||
QByteArray propertyName;
|
||||
hifi::ByteArray propertyName;
|
||||
int index;
|
||||
propertyName = "P";
|
||||
index = 4;
|
||||
foreach (const FBXNode& property, subobject.children) {
|
||||
static const QVariant UV_SET = QByteArray("UVSet");
|
||||
static const QVariant CURRENT_TEXTURE_BLEND_MODE = QByteArray("CurrentTextureBlendMode");
|
||||
static const QVariant USE_MATERIAL = QByteArray("UseMaterial");
|
||||
static const QVariant TRANSLATION = QByteArray("Translation");
|
||||
static const QVariant ROTATION = QByteArray("Rotation");
|
||||
static const QVariant SCALING = QByteArray("Scaling");
|
||||
static const QVariant UV_SET = hifi::ByteArray("UVSet");
|
||||
static const QVariant CURRENT_TEXTURE_BLEND_MODE = hifi::ByteArray("CurrentTextureBlendMode");
|
||||
static const QVariant USE_MATERIAL = hifi::ByteArray("UseMaterial");
|
||||
static const QVariant TRANSLATION = hifi::ByteArray("Translation");
|
||||
static const QVariant ROTATION = hifi::ByteArray("Rotation");
|
||||
static const QVariant SCALING = hifi::ByteArray("Scaling");
|
||||
if (property.name == propertyName) {
|
||||
QString v = property.properties.at(0).toString();
|
||||
if (property.properties.at(0) == UV_SET) {
|
||||
|
@ -795,8 +795,8 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
|
|||
_textureParams.insert(getID(object.properties), tex);
|
||||
}
|
||||
} else if (object.name == "Video") {
|
||||
QByteArray filepath;
|
||||
QByteArray content;
|
||||
hifi::ByteArray filepath;
|
||||
hifi::ByteArray content;
|
||||
foreach (const FBXNode& subobject, object.children) {
|
||||
if (subobject.name == "RelativeFilename") {
|
||||
filepath = subobject.properties.at(0).toByteArray();
|
||||
|
@ -816,7 +816,7 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
|
|||
foreach (const FBXNode& subobject, object.children) {
|
||||
bool properties = false;
|
||||
|
||||
QByteArray propertyName;
|
||||
hifi::ByteArray propertyName;
|
||||
int index;
|
||||
if (subobject.name == "Properties60") {
|
||||
properties = true;
|
||||
|
@ -833,31 +833,31 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
|
|||
|
||||
if (properties) {
|
||||
std::vector<std::string> unknowns;
|
||||
static const QVariant DIFFUSE_COLOR = QByteArray("DiffuseColor");
|
||||
static const QVariant DIFFUSE_FACTOR = QByteArray("DiffuseFactor");
|
||||
static const QVariant DIFFUSE = QByteArray("Diffuse");
|
||||
static const QVariant SPECULAR_COLOR = QByteArray("SpecularColor");
|
||||
static const QVariant SPECULAR_FACTOR = QByteArray("SpecularFactor");
|
||||
static const QVariant SPECULAR = QByteArray("Specular");
|
||||
static const QVariant EMISSIVE_COLOR = QByteArray("EmissiveColor");
|
||||
static const QVariant EMISSIVE_FACTOR = QByteArray("EmissiveFactor");
|
||||
static const QVariant EMISSIVE = QByteArray("Emissive");
|
||||
static const QVariant AMBIENT_FACTOR = QByteArray("AmbientFactor");
|
||||
static const QVariant SHININESS = QByteArray("Shininess");
|
||||
static const QVariant OPACITY = QByteArray("Opacity");
|
||||
static const QVariant MAYA_USE_NORMAL_MAP = QByteArray("Maya|use_normal_map");
|
||||
static const QVariant MAYA_BASE_COLOR = QByteArray("Maya|base_color");
|
||||
static const QVariant MAYA_USE_COLOR_MAP = QByteArray("Maya|use_color_map");
|
||||
static const QVariant MAYA_ROUGHNESS = QByteArray("Maya|roughness");
|
||||
static const QVariant MAYA_USE_ROUGHNESS_MAP = QByteArray("Maya|use_roughness_map");
|
||||
static const QVariant MAYA_METALLIC = QByteArray("Maya|metallic");
|
||||
static const QVariant MAYA_USE_METALLIC_MAP = QByteArray("Maya|use_metallic_map");
|
||||
static const QVariant MAYA_EMISSIVE = QByteArray("Maya|emissive");
|
||||
static const QVariant MAYA_EMISSIVE_INTENSITY = QByteArray("Maya|emissive_intensity");
|
||||
static const QVariant MAYA_USE_EMISSIVE_MAP = QByteArray("Maya|use_emissive_map");
|
||||
static const QVariant MAYA_USE_AO_MAP = QByteArray("Maya|use_ao_map");
|
||||
static const QVariant MAYA_UV_SCALE = QByteArray("Maya|uv_scale");
|
||||
static const QVariant MAYA_UV_OFFSET = QByteArray("Maya|uv_offset");
|
||||
static const QVariant DIFFUSE_COLOR = hifi::ByteArray("DiffuseColor");
|
||||
static const QVariant DIFFUSE_FACTOR = hifi::ByteArray("DiffuseFactor");
|
||||
static const QVariant DIFFUSE = hifi::ByteArray("Diffuse");
|
||||
static const QVariant SPECULAR_COLOR = hifi::ByteArray("SpecularColor");
|
||||
static const QVariant SPECULAR_FACTOR = hifi::ByteArray("SpecularFactor");
|
||||
static const QVariant SPECULAR = hifi::ByteArray("Specular");
|
||||
static const QVariant EMISSIVE_COLOR = hifi::ByteArray("EmissiveColor");
|
||||
static const QVariant EMISSIVE_FACTOR = hifi::ByteArray("EmissiveFactor");
|
||||
static const QVariant EMISSIVE = hifi::ByteArray("Emissive");
|
||||
static const QVariant AMBIENT_FACTOR = hifi::ByteArray("AmbientFactor");
|
||||
static const QVariant SHININESS = hifi::ByteArray("Shininess");
|
||||
static const QVariant OPACITY = hifi::ByteArray("Opacity");
|
||||
static const QVariant MAYA_USE_NORMAL_MAP = hifi::ByteArray("Maya|use_normal_map");
|
||||
static const QVariant MAYA_BASE_COLOR = hifi::ByteArray("Maya|base_color");
|
||||
static const QVariant MAYA_USE_COLOR_MAP = hifi::ByteArray("Maya|use_color_map");
|
||||
static const QVariant MAYA_ROUGHNESS = hifi::ByteArray("Maya|roughness");
|
||||
static const QVariant MAYA_USE_ROUGHNESS_MAP = hifi::ByteArray("Maya|use_roughness_map");
|
||||
static const QVariant MAYA_METALLIC = hifi::ByteArray("Maya|metallic");
|
||||
static const QVariant MAYA_USE_METALLIC_MAP = hifi::ByteArray("Maya|use_metallic_map");
|
||||
static const QVariant MAYA_EMISSIVE = hifi::ByteArray("Maya|emissive");
|
||||
static const QVariant MAYA_EMISSIVE_INTENSITY = hifi::ByteArray("Maya|emissive_intensity");
|
||||
static const QVariant MAYA_USE_EMISSIVE_MAP = hifi::ByteArray("Maya|use_emissive_map");
|
||||
static const QVariant MAYA_USE_AO_MAP = hifi::ByteArray("Maya|use_ao_map");
|
||||
static const QVariant MAYA_UV_SCALE = hifi::ByteArray("Maya|uv_scale");
|
||||
static const QVariant MAYA_UV_OFFSET = hifi::ByteArray("Maya|uv_offset");
|
||||
static const int MAYA_UV_OFFSET_PROPERTY_LENGTH = 6;
|
||||
static const int MAYA_UV_SCALE_PROPERTY_LENGTH = 6;
|
||||
|
||||
|
@ -1034,7 +1034,7 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
|
|||
clusters.insert(getID(object.properties), cluster);
|
||||
|
||||
} else if (object.properties.last() == "BlendShapeChannel") {
|
||||
QByteArray name = object.properties.at(1).toByteArray();
|
||||
hifi::ByteArray name = object.properties.at(1).toByteArray();
|
||||
|
||||
name = name.left(name.indexOf('\0'));
|
||||
if (!blendshapeIndices.contains(name)) {
|
||||
|
@ -1071,8 +1071,8 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
|
|||
#endif
|
||||
}
|
||||
} else if (child.name == "Connections") {
|
||||
static const QVariant OO = QByteArray("OO");
|
||||
static const QVariant OP = QByteArray("OP");
|
||||
static const QVariant OO = hifi::ByteArray("OO");
|
||||
static const QVariant OP = hifi::ByteArray("OP");
|
||||
foreach (const FBXNode& connection, child.children) {
|
||||
if (connection.name == "C" || connection.name == "Connect") {
|
||||
if (connection.properties.at(0) == OO) {
|
||||
|
@ -1091,7 +1091,7 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
|
|||
}
|
||||
} else if (connection.properties.at(0) == OP) {
|
||||
int counter = 0;
|
||||
QByteArray type = connection.properties.at(3).toByteArray().toLower();
|
||||
hifi::ByteArray type = connection.properties.at(3).toByteArray().toLower();
|
||||
if (type.contains("DiffuseFactor")) {
|
||||
diffuseFactorTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else if ((type.contains("diffuse") && !type.contains("tex_global_diffuse"))) {
|
||||
|
@ -1678,8 +1678,8 @@ std::unique_ptr<hfm::Serializer::Factory> FBXSerializer::getFactory() const {
|
|||
return std::make_unique<hfm::Serializer::SimpleFactory<FBXSerializer>>();
|
||||
}
|
||||
|
||||
HFMModel::Pointer FBXSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) {
|
||||
QBuffer buffer(const_cast<QByteArray*>(&data));
|
||||
HFMModel::Pointer FBXSerializer::read(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url) {
|
||||
QBuffer buffer(const_cast<hifi::ByteArray*>(&data));
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
|
||||
_rootNode = parseFBX(&buffer);
|
||||
|
|
|
@ -15,9 +15,6 @@
|
|||
#include <QtGlobal>
|
||||
#include <QMetaType>
|
||||
#include <QSet>
|
||||
#include <QUrl>
|
||||
#include <QVarLengthArray>
|
||||
#include <QVariant>
|
||||
#include <QVector>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
@ -25,6 +22,7 @@
|
|||
|
||||
#include <Extents.h>
|
||||
#include <Transform.h>
|
||||
#include <shared/HifiTypes.h>
|
||||
|
||||
#include "FBX.h"
|
||||
#include <hfm/HFMSerializer.h>
|
||||
|
@ -114,12 +112,12 @@ public:
|
|||
HFMModel* _hfmModel;
|
||||
/// Reads HFMModel from the supplied model and mapping data.
|
||||
/// \exception QString if an error occurs in parsing
|
||||
HFMModel::Pointer read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) override;
|
||||
HFMModel::Pointer read(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url = hifi::URL()) override;
|
||||
|
||||
FBXNode _rootNode;
|
||||
static FBXNode parseFBX(QIODevice* device);
|
||||
|
||||
HFMModel* extractHFMModel(const QVariantHash& mapping, const QString& url);
|
||||
HFMModel* extractHFMModel(const hifi::VariantHash& mapping, const QString& url);
|
||||
|
||||
static ExtractedMesh extractMesh(const FBXNode& object, unsigned int& meshIndex, bool deduplicate = true);
|
||||
QHash<QString, ExtractedMesh> meshes;
|
||||
|
@ -128,11 +126,11 @@ public:
|
|||
|
||||
QHash<QString, QString> _textureNames;
|
||||
// Hashes the original RelativeFilename of textures
|
||||
QHash<QString, QByteArray> _textureFilepaths;
|
||||
QHash<QString, hifi::ByteArray> _textureFilepaths;
|
||||
// Hashes the place to look for textures, in case they are not inlined
|
||||
QHash<QString, QByteArray> _textureFilenames;
|
||||
QHash<QString, hifi::ByteArray> _textureFilenames;
|
||||
// Hashes texture content by filepath, in case they are inlined
|
||||
QHash<QByteArray, QByteArray> _textureContent;
|
||||
QHash<hifi::ByteArray, hifi::ByteArray> _textureContent;
|
||||
QHash<QString, TextureParam> _textureParams;
|
||||
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <memory>
|
||||
|
||||
#include <QBuffer>
|
||||
#include <QDataStream>
|
||||
#include <QIODevice>
|
||||
#include <QStringList>
|
||||
#include <QTextStream>
|
||||
|
@ -29,7 +28,7 @@
|
|||
|
||||
HFMTexture FBXSerializer::getTexture(const QString& textureID, const QString& materialID) {
|
||||
HFMTexture texture;
|
||||
const QByteArray& filepath = _textureFilepaths.value(textureID);
|
||||
const hifi::ByteArray& filepath = _textureFilepaths.value(textureID);
|
||||
texture.content = _textureContent.value(filepath);
|
||||
|
||||
if (texture.content.isEmpty()) { // the content is not inlined
|
||||
|
|
|
@ -190,8 +190,8 @@ ExtractedMesh FBXSerializer::extractMesh(const FBXNode& object, unsigned int& me
|
|||
|
||||
bool isMaterialPerPolygon = false;
|
||||
|
||||
static const QVariant BY_VERTICE = QByteArray("ByVertice");
|
||||
static const QVariant INDEX_TO_DIRECT = QByteArray("IndexToDirect");
|
||||
static const QVariant BY_VERTICE = hifi::ByteArray("ByVertice");
|
||||
static const QVariant INDEX_TO_DIRECT = hifi::ByteArray("IndexToDirect");
|
||||
|
||||
bool isDracoMesh = false;
|
||||
|
||||
|
@ -321,7 +321,7 @@ ExtractedMesh FBXSerializer::extractMesh(const FBXNode& object, unsigned int& me
|
|||
}
|
||||
}
|
||||
} else if (child.name == "LayerElementMaterial") {
|
||||
static const QVariant BY_POLYGON = QByteArray("ByPolygon");
|
||||
static const QVariant BY_POLYGON = hifi::ByteArray("ByPolygon");
|
||||
foreach (const FBXNode& subdata, child.children) {
|
||||
if (subdata.name == "Materials") {
|
||||
materials = getIntVector(subdata);
|
||||
|
@ -348,7 +348,7 @@ ExtractedMesh FBXSerializer::extractMesh(const FBXNode& object, unsigned int& me
|
|||
// load the draco mesh from the FBX and create a draco::Mesh
|
||||
draco::Decoder decoder;
|
||||
draco::DecoderBuffer decodedBuffer;
|
||||
QByteArray dracoArray = child.properties.at(0).value<QByteArray>();
|
||||
hifi::ByteArray dracoArray = child.properties.at(0).value<hifi::ByteArray>();
|
||||
decodedBuffer.Init(dracoArray.data(), dracoArray.size());
|
||||
|
||||
std::unique_ptr<draco::Mesh> dracoMesh(new draco::Mesh());
|
||||
|
|
|
@ -48,10 +48,10 @@ QVariant readBinaryArray(QDataStream& in, int& position) {
|
|||
QVector<T> values;
|
||||
if ((int)QSysInfo::ByteOrder == (int)in.byteOrder()) {
|
||||
values.resize(arrayLength);
|
||||
QByteArray arrayData;
|
||||
hifi::ByteArray arrayData;
|
||||
if (encoding == FBX_PROPERTY_COMPRESSED_FLAG) {
|
||||
// preface encoded data with uncompressed length
|
||||
QByteArray compressed(sizeof(quint32) + compressedLength, 0);
|
||||
hifi::ByteArray compressed(sizeof(quint32) + compressedLength, 0);
|
||||
*((quint32*)compressed.data()) = qToBigEndian<quint32>(arrayLength * sizeof(T));
|
||||
in.readRawData(compressed.data() + sizeof(quint32), compressedLength);
|
||||
position += compressedLength;
|
||||
|
@ -73,11 +73,11 @@ QVariant readBinaryArray(QDataStream& in, int& position) {
|
|||
values.reserve(arrayLength);
|
||||
if (encoding == FBX_PROPERTY_COMPRESSED_FLAG) {
|
||||
// preface encoded data with uncompressed length
|
||||
QByteArray compressed(sizeof(quint32) + compressedLength, 0);
|
||||
hifi::ByteArray compressed(sizeof(quint32) + compressedLength, 0);
|
||||
*((quint32*)compressed.data()) = qToBigEndian<quint32>(arrayLength * sizeof(T));
|
||||
in.readRawData(compressed.data() + sizeof(quint32), compressedLength);
|
||||
position += compressedLength;
|
||||
QByteArray uncompressed = qUncompress(compressed);
|
||||
hifi::ByteArray uncompressed = qUncompress(compressed);
|
||||
if (uncompressed.isEmpty()) { // answers empty byte array if corrupt
|
||||
throw QString("corrupt fbx file");
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ public:
|
|||
};
|
||||
|
||||
int nextToken();
|
||||
const QByteArray& getDatum() const { return _datum; }
|
||||
const hifi::ByteArray& getDatum() const { return _datum; }
|
||||
|
||||
void pushBackToken(int token) { _pushedBackToken = token; }
|
||||
void ungetChar(char ch) { _device->ungetChar(ch); }
|
||||
|
@ -242,7 +242,7 @@ public:
|
|||
private:
|
||||
|
||||
QIODevice* _device;
|
||||
QByteArray _datum;
|
||||
hifi::ByteArray _datum;
|
||||
int _pushedBackToken;
|
||||
};
|
||||
|
||||
|
@ -325,7 +325,7 @@ FBXNode parseTextFBXNode(Tokenizer& tokenizer) {
|
|||
expectingDatum = true;
|
||||
|
||||
} else if (token == Tokenizer::DATUM_TOKEN && expectingDatum) {
|
||||
QByteArray datum = tokenizer.getDatum();
|
||||
hifi::ByteArray datum = tokenizer.getDatum();
|
||||
if ((token = tokenizer.nextToken()) == ':') {
|
||||
tokenizer.ungetChar(':');
|
||||
tokenizer.pushBackToken(Tokenizer::DATUM_TOKEN);
|
||||
|
|
|
@ -125,18 +125,18 @@ bool GLTFSerializer::getObjectArrayVal(const QJsonObject& object, const QString&
|
|||
return _defined;
|
||||
}
|
||||
|
||||
QByteArray GLTFSerializer::setGLBChunks(const QByteArray& data) {
|
||||
hifi::ByteArray GLTFSerializer::setGLBChunks(const hifi::ByteArray& data) {
|
||||
int byte = 4;
|
||||
int jsonStart = data.indexOf("JSON", Qt::CaseSensitive);
|
||||
int binStart = data.indexOf("BIN", Qt::CaseSensitive);
|
||||
int jsonLength, binLength;
|
||||
QByteArray jsonLengthChunk, binLengthChunk;
|
||||
hifi::ByteArray jsonLengthChunk, binLengthChunk;
|
||||
|
||||
jsonLengthChunk = data.mid(jsonStart - byte, byte);
|
||||
QDataStream tempJsonLen(jsonLengthChunk);
|
||||
tempJsonLen.setByteOrder(QDataStream::LittleEndian);
|
||||
tempJsonLen >> jsonLength;
|
||||
QByteArray jsonChunk = data.mid(jsonStart + byte, jsonLength);
|
||||
hifi::ByteArray jsonChunk = data.mid(jsonStart + byte, jsonLength);
|
||||
|
||||
if (binStart != -1) {
|
||||
binLengthChunk = data.mid(binStart - byte, byte);
|
||||
|
@ -567,10 +567,10 @@ bool GLTFSerializer::addTexture(const QJsonObject& object) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GLTFSerializer::parseGLTF(const QByteArray& data) {
|
||||
bool GLTFSerializer::parseGLTF(const hifi::ByteArray& data) {
|
||||
PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xffff0000, nullptr);
|
||||
|
||||
QByteArray jsonChunk = data;
|
||||
hifi::ByteArray jsonChunk = data;
|
||||
|
||||
if (_url.toString().endsWith("glb") && data.indexOf("glTF") == 0 && data.contains("JSON")) {
|
||||
jsonChunk = setGLBChunks(data);
|
||||
|
@ -734,7 +734,7 @@ glm::mat4 GLTFSerializer::getModelTransform(const GLTFNode& node) {
|
|||
return tmat;
|
||||
}
|
||||
|
||||
bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const QUrl& url) {
|
||||
bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::URL& url) {
|
||||
|
||||
//Build dependencies
|
||||
QVector<QVector<int>> nodeDependencies(_file.nodes.size());
|
||||
|
@ -993,15 +993,15 @@ std::unique_ptr<hfm::Serializer::Factory> GLTFSerializer::getFactory() const {
|
|||
return std::make_unique<hfm::Serializer::SimpleFactory<GLTFSerializer>>();
|
||||
}
|
||||
|
||||
HFMModel::Pointer GLTFSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) {
|
||||
HFMModel::Pointer GLTFSerializer::read(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url) {
|
||||
|
||||
_url = url;
|
||||
|
||||
// Normalize url for local files
|
||||
QUrl normalizeUrl = DependencyManager::get<ResourceManager>()->normalizeURL(_url);
|
||||
hifi::URL normalizeUrl = DependencyManager::get<ResourceManager>()->normalizeURL(_url);
|
||||
if (normalizeUrl.scheme().isEmpty() || (normalizeUrl.scheme() == "file")) {
|
||||
QString localFileName = PathUtils::expandToLocalDataAbsolutePath(normalizeUrl).toLocalFile();
|
||||
_url = QUrl(QFileInfo(localFileName).absoluteFilePath());
|
||||
_url = hifi::URL(QFileInfo(localFileName).absoluteFilePath());
|
||||
}
|
||||
|
||||
if (parseGLTF(data)) {
|
||||
|
@ -1019,15 +1019,15 @@ HFMModel::Pointer GLTFSerializer::read(const QByteArray& data, const QVariantHas
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool GLTFSerializer::readBinary(const QString& url, QByteArray& outdata) {
|
||||
bool GLTFSerializer::readBinary(const QString& url, hifi::ByteArray& outdata) {
|
||||
bool success;
|
||||
|
||||
if (url.contains("data:application/octet-stream;base64,")) {
|
||||
outdata = requestEmbeddedData(url);
|
||||
success = !outdata.isEmpty();
|
||||
} else {
|
||||
QUrl binaryUrl = _url.resolved(url);
|
||||
std::tie<bool, QByteArray>(success, outdata) = requestData(binaryUrl);
|
||||
hifi::URL binaryUrl = _url.resolved(url);
|
||||
std::tie<bool, hifi::ByteArray>(success, outdata) = requestData(binaryUrl);
|
||||
}
|
||||
|
||||
return success;
|
||||
|
@ -1037,16 +1037,16 @@ bool GLTFSerializer::doesResourceExist(const QString& url) {
|
|||
if (_url.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
QUrl candidateUrl = _url.resolved(url);
|
||||
hifi::URL candidateUrl = _url.resolved(url);
|
||||
return DependencyManager::get<ResourceManager>()->resourceExists(candidateUrl);
|
||||
}
|
||||
|
||||
std::tuple<bool, QByteArray> GLTFSerializer::requestData(QUrl& url) {
|
||||
std::tuple<bool, hifi::ByteArray> GLTFSerializer::requestData(hifi::URL& url) {
|
||||
auto request = DependencyManager::get<ResourceManager>()->createResourceRequest(
|
||||
nullptr, url, true, -1, "GLTFSerializer::requestData");
|
||||
|
||||
if (!request) {
|
||||
return std::make_tuple(false, QByteArray());
|
||||
return std::make_tuple(false, hifi::ByteArray());
|
||||
}
|
||||
|
||||
QEventLoop loop;
|
||||
|
@ -1057,17 +1057,17 @@ std::tuple<bool, QByteArray> GLTFSerializer::requestData(QUrl& url) {
|
|||
if (request->getResult() == ResourceRequest::Success) {
|
||||
return std::make_tuple(true, request->getData());
|
||||
} else {
|
||||
return std::make_tuple(false, QByteArray());
|
||||
return std::make_tuple(false, hifi::ByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray GLTFSerializer::requestEmbeddedData(const QString& url) {
|
||||
hifi::ByteArray GLTFSerializer::requestEmbeddedData(const QString& url) {
|
||||
QString binaryUrl = url.split(",")[1];
|
||||
return binaryUrl.isEmpty() ? QByteArray() : QByteArray::fromBase64(binaryUrl.toUtf8());
|
||||
return binaryUrl.isEmpty() ? hifi::ByteArray() : QByteArray::fromBase64(binaryUrl.toUtf8());
|
||||
}
|
||||
|
||||
|
||||
QNetworkReply* GLTFSerializer::request(QUrl& url, bool isTest) {
|
||||
QNetworkReply* GLTFSerializer::request(hifi::URL& url, bool isTest) {
|
||||
if (!qApp) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1098,8 +1098,8 @@ HFMTexture GLTFSerializer::getHFMTexture(const GLTFTexture& texture) {
|
|||
if (texture.defined["source"]) {
|
||||
QString url = _file.images[texture.source].uri;
|
||||
|
||||
QString fname = QUrl(url).fileName();
|
||||
QUrl textureUrl = _url.resolved(url);
|
||||
QString fname = hifi::URL(url).fileName();
|
||||
hifi::URL textureUrl = _url.resolved(url);
|
||||
qCDebug(modelformat) << "fname: " << fname;
|
||||
fbxtex.name = fname;
|
||||
fbxtex.filename = textureUrl.toEncoded();
|
||||
|
@ -1187,7 +1187,7 @@ void GLTFSerializer::setHFMMaterial(HFMMaterial& fbxmat, const GLTFMaterial& mat
|
|||
}
|
||||
|
||||
template<typename T, typename L>
|
||||
bool GLTFSerializer::readArray(const QByteArray& bin, int byteOffset, int count,
|
||||
bool GLTFSerializer::readArray(const hifi::ByteArray& bin, int byteOffset, int count,
|
||||
QVector<L>& outarray, int accessorType) {
|
||||
|
||||
QDataStream blobstream(bin);
|
||||
|
@ -1244,7 +1244,7 @@ bool GLTFSerializer::readArray(const QByteArray& bin, int byteOffset, int count,
|
|||
return true;
|
||||
}
|
||||
template<typename T>
|
||||
bool GLTFSerializer::addArrayOfType(const QByteArray& bin, int byteOffset, int count,
|
||||
bool GLTFSerializer::addArrayOfType(const hifi::ByteArray& bin, int byteOffset, int count,
|
||||
QVector<T>& outarray, int accessorType, int componentType) {
|
||||
|
||||
switch (componentType) {
|
||||
|
|
|
@ -214,7 +214,7 @@ struct GLTFBufferView {
|
|||
struct GLTFBuffer {
|
||||
int byteLength; //required
|
||||
QString uri;
|
||||
QByteArray blob;
|
||||
hifi::ByteArray blob;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["byteLength"]) {
|
||||
|
@ -705,16 +705,16 @@ public:
|
|||
MediaType getMediaType() const override;
|
||||
std::unique_ptr<hfm::Serializer::Factory> getFactory() const override;
|
||||
|
||||
HFMModel::Pointer read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) override;
|
||||
HFMModel::Pointer read(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url = hifi::URL()) override;
|
||||
private:
|
||||
GLTFFile _file;
|
||||
QUrl _url;
|
||||
QByteArray _glbBinary;
|
||||
hifi::URL _url;
|
||||
hifi::ByteArray _glbBinary;
|
||||
|
||||
glm::mat4 getModelTransform(const GLTFNode& node);
|
||||
|
||||
bool buildGeometry(HFMModel& hfmModel, const QUrl& url);
|
||||
bool parseGLTF(const QByteArray& data);
|
||||
bool buildGeometry(HFMModel& hfmModel, const hifi::URL& url);
|
||||
bool parseGLTF(const hifi::ByteArray& data);
|
||||
|
||||
bool getStringVal(const QJsonObject& object, const QString& fieldname,
|
||||
QString& value, QMap<QString, bool>& defined);
|
||||
|
@ -733,7 +733,7 @@ private:
|
|||
bool getObjectArrayVal(const QJsonObject& object, const QString& fieldname,
|
||||
QJsonArray& objects, QMap<QString, bool>& defined);
|
||||
|
||||
QByteArray setGLBChunks(const QByteArray& data);
|
||||
hifi::ByteArray setGLBChunks(const hifi::ByteArray& data);
|
||||
|
||||
int getMaterialAlphaMode(const QString& type);
|
||||
int getAccessorType(const QString& type);
|
||||
|
@ -760,24 +760,24 @@ private:
|
|||
bool addSkin(const QJsonObject& object);
|
||||
bool addTexture(const QJsonObject& object);
|
||||
|
||||
bool readBinary(const QString& url, QByteArray& outdata);
|
||||
bool readBinary(const QString& url, hifi::ByteArray& outdata);
|
||||
|
||||
template<typename T, typename L>
|
||||
bool readArray(const QByteArray& bin, int byteOffset, int count,
|
||||
bool readArray(const hifi::ByteArray& bin, int byteOffset, int count,
|
||||
QVector<L>& outarray, int accessorType);
|
||||
|
||||
template<typename T>
|
||||
bool addArrayOfType(const QByteArray& bin, int byteOffset, int count,
|
||||
bool addArrayOfType(const hifi::ByteArray& bin, int byteOffset, int count,
|
||||
QVector<T>& outarray, int accessorType, int componentType);
|
||||
|
||||
void retriangulate(const QVector<int>& in_indices, const QVector<glm::vec3>& in_vertices,
|
||||
const QVector<glm::vec3>& in_normals, QVector<int>& out_indices,
|
||||
QVector<glm::vec3>& out_vertices, QVector<glm::vec3>& out_normals);
|
||||
|
||||
std::tuple<bool, QByteArray> requestData(QUrl& url);
|
||||
QByteArray requestEmbeddedData(const QString& url);
|
||||
std::tuple<bool, hifi::ByteArray> requestData(hifi::URL& url);
|
||||
hifi::ByteArray requestEmbeddedData(const QString& url);
|
||||
|
||||
QNetworkReply* request(QUrl& url, bool isTest);
|
||||
QNetworkReply* request(hifi::URL& url, bool isTest);
|
||||
bool doesResourceExist(const QString& url);
|
||||
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ T& checked_at(QVector<T>& vector, int i) {
|
|||
OBJTokenizer::OBJTokenizer(QIODevice* device) : _device(device), _pushedBackToken(-1) {
|
||||
}
|
||||
|
||||
const QByteArray OBJTokenizer::getLineAsDatum() {
|
||||
const hifi::ByteArray OBJTokenizer::getLineAsDatum() {
|
||||
return _device->readLine().trimmed();
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,7 @@ bool OBJTokenizer::isNextTokenFloat() {
|
|||
if (nextToken() != OBJTokenizer::DATUM_TOKEN) {
|
||||
return false;
|
||||
}
|
||||
QByteArray token = getDatum();
|
||||
hifi::ByteArray token = getDatum();
|
||||
pushBackToken(OBJTokenizer::DATUM_TOKEN);
|
||||
bool ok;
|
||||
token.toFloat(&ok);
|
||||
|
@ -182,7 +182,7 @@ void setMeshPartDefaults(HFMMeshPart& meshPart, QString materialID) {
|
|||
// OBJFace
|
||||
// NOTE (trent, 7/20/17): The vertexColors vector being passed-in isn't necessary here, but I'm just
|
||||
// pairing it with the vertices vector for consistency.
|
||||
bool OBJFace::add(const QByteArray& vertexIndex, const QByteArray& textureIndex, const QByteArray& normalIndex, const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& vertexColors) {
|
||||
bool OBJFace::add(const hifi::ByteArray& vertexIndex, const hifi::ByteArray& textureIndex, const hifi::ByteArray& normalIndex, const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& vertexColors) {
|
||||
bool ok;
|
||||
int index = vertexIndex.toInt(&ok);
|
||||
if (!ok) {
|
||||
|
@ -238,11 +238,11 @@ void OBJFace::addFrom(const OBJFace* face, int index) { // add using data from f
|
|||
}
|
||||
}
|
||||
|
||||
bool OBJSerializer::isValidTexture(const QByteArray &filename) {
|
||||
bool OBJSerializer::isValidTexture(const hifi::ByteArray &filename) {
|
||||
if (_url.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
QUrl candidateUrl = _url.resolved(QUrl(filename));
|
||||
hifi::URL candidateUrl = _url.resolved(hifi::URL(filename));
|
||||
|
||||
return DependencyManager::get<ResourceManager>()->resourceExists(candidateUrl);
|
||||
}
|
||||
|
@ -278,7 +278,7 @@ void OBJSerializer::parseMaterialLibrary(QIODevice* device) {
|
|||
#endif
|
||||
return;
|
||||
}
|
||||
QByteArray token = tokenizer.getDatum();
|
||||
hifi::ByteArray token = tokenizer.getDatum();
|
||||
if (token == "newmtl") {
|
||||
if (tokenizer.nextToken() != OBJTokenizer::DATUM_TOKEN) {
|
||||
return;
|
||||
|
@ -328,8 +328,8 @@ void OBJSerializer::parseMaterialLibrary(QIODevice* device) {
|
|||
} else if (token == "Ks") {
|
||||
currentMaterial.specularColor = tokenizer.getVec3();
|
||||
} else if ((token == "map_Kd") || (token == "map_Ke") || (token == "map_Ks") || (token == "map_bump") || (token == "bump") || (token == "map_d")) {
|
||||
const QByteArray textureLine = tokenizer.getLineAsDatum();
|
||||
QByteArray filename;
|
||||
const hifi::ByteArray textureLine = tokenizer.getLineAsDatum();
|
||||
hifi::ByteArray filename;
|
||||
OBJMaterialTextureOptions textureOptions;
|
||||
parseTextureLine(textureLine, filename, textureOptions);
|
||||
if (filename.endsWith(".tga")) {
|
||||
|
@ -354,7 +354,7 @@ void OBJSerializer::parseMaterialLibrary(QIODevice* device) {
|
|||
}
|
||||
}
|
||||
|
||||
void OBJSerializer::parseTextureLine(const QByteArray& textureLine, QByteArray& filename, OBJMaterialTextureOptions& textureOptions) {
|
||||
void OBJSerializer::parseTextureLine(const hifi::ByteArray& textureLine, hifi::ByteArray& filename, OBJMaterialTextureOptions& textureOptions) {
|
||||
// Texture options reference http://paulbourke.net/dataformats/mtl/
|
||||
// and https://wikivisually.com/wiki/Material_Template_Library
|
||||
|
||||
|
@ -442,12 +442,12 @@ void OBJSerializer::parseTextureLine(const QByteArray& textureLine, QByteArray&
|
|||
}
|
||||
}
|
||||
|
||||
std::tuple<bool, QByteArray> requestData(QUrl& url) {
|
||||
std::tuple<bool, hifi::ByteArray> requestData(hifi::URL& url) {
|
||||
auto request = DependencyManager::get<ResourceManager>()->createResourceRequest(
|
||||
nullptr, url, true, -1, "(OBJSerializer) requestData");
|
||||
|
||||
if (!request) {
|
||||
return std::make_tuple(false, QByteArray());
|
||||
return std::make_tuple(false, hifi::ByteArray());
|
||||
}
|
||||
|
||||
QEventLoop loop;
|
||||
|
@ -458,12 +458,12 @@ std::tuple<bool, QByteArray> requestData(QUrl& url) {
|
|||
if (request->getResult() == ResourceRequest::Success) {
|
||||
return std::make_tuple(true, request->getData());
|
||||
} else {
|
||||
return std::make_tuple(false, QByteArray());
|
||||
return std::make_tuple(false, hifi::ByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QNetworkReply* request(QUrl& url, bool isTest) {
|
||||
QNetworkReply* request(hifi::URL& url, bool isTest) {
|
||||
if (!qApp) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -488,7 +488,7 @@ QNetworkReply* request(QUrl& url, bool isTest) {
|
|||
}
|
||||
|
||||
|
||||
bool OBJSerializer::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, HFMModel& hfmModel,
|
||||
bool OBJSerializer::parseOBJGroup(OBJTokenizer& tokenizer, const hifi::VariantHash& mapping, HFMModel& hfmModel,
|
||||
float& scaleGuess, bool combineParts) {
|
||||
FaceGroup faces;
|
||||
HFMMesh& mesh = hfmModel.meshes[0];
|
||||
|
@ -522,7 +522,7 @@ bool OBJSerializer::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& m
|
|||
result = false;
|
||||
break;
|
||||
}
|
||||
QByteArray token = tokenizer.getDatum();
|
||||
hifi::ByteArray token = tokenizer.getDatum();
|
||||
//qCDebug(modelformat) << token;
|
||||
// we don't support separate objects in the same file, so treat "o" the same as "g".
|
||||
if (token == "g" || token == "o") {
|
||||
|
@ -535,7 +535,7 @@ bool OBJSerializer::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& m
|
|||
if (tokenizer.nextToken() != OBJTokenizer::DATUM_TOKEN) {
|
||||
break;
|
||||
}
|
||||
QByteArray groupName = tokenizer.getDatum();
|
||||
hifi::ByteArray groupName = tokenizer.getDatum();
|
||||
currentGroup = groupName;
|
||||
if (!combineParts) {
|
||||
currentMaterialName = QString("part-") + QString::number(_partCounter++);
|
||||
|
@ -544,7 +544,7 @@ bool OBJSerializer::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& m
|
|||
if (tokenizer.nextToken(true) != OBJTokenizer::DATUM_TOKEN) {
|
||||
break;
|
||||
}
|
||||
QByteArray libraryName = tokenizer.getDatum();
|
||||
hifi::ByteArray libraryName = tokenizer.getDatum();
|
||||
librariesSeen[libraryName] = true;
|
||||
// We'll read it later only if we actually need it.
|
||||
} else if (token == "usemtl") {
|
||||
|
@ -598,14 +598,14 @@ bool OBJSerializer::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& m
|
|||
// vertex-index
|
||||
// vertex-index/texture-index
|
||||
// vertex-index/texture-index/surface-normal-index
|
||||
QByteArray token = tokenizer.getDatum();
|
||||
hifi::ByteArray token = tokenizer.getDatum();
|
||||
auto firstChar = token[0];
|
||||
// Tokenizer treats line endings as whitespace. Non-digit and non-negative sign indicates done;
|
||||
if (!isdigit(firstChar) && firstChar != '-') {
|
||||
tokenizer.pushBackToken(OBJTokenizer::DATUM_TOKEN);
|
||||
break;
|
||||
}
|
||||
QList<QByteArray> parts = token.split('/');
|
||||
QList<hifi::ByteArray> parts = token.split('/');
|
||||
assert(parts.count() >= 1);
|
||||
assert(parts.count() <= 3);
|
||||
// If indices are negative relative indices then adjust them to absolute indices based on current vector sizes
|
||||
|
@ -626,7 +626,7 @@ bool OBJSerializer::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& m
|
|||
}
|
||||
}
|
||||
}
|
||||
const QByteArray noData {};
|
||||
const hifi::ByteArray noData {};
|
||||
face.add(parts[0], (parts.count() > 1) ? parts[1] : noData, (parts.count() > 2) ? parts[2] : noData,
|
||||
vertices, vertexColors);
|
||||
face.groupName = currentGroup;
|
||||
|
@ -661,9 +661,9 @@ std::unique_ptr<hfm::Serializer::Factory> OBJSerializer::getFactory() const {
|
|||
return std::make_unique<hfm::Serializer::SimpleFactory<OBJSerializer>>();
|
||||
}
|
||||
|
||||
HFMModel::Pointer OBJSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) {
|
||||
HFMModel::Pointer OBJSerializer::read(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url) {
|
||||
PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xffff0000, nullptr);
|
||||
QBuffer buffer { const_cast<QByteArray*>(&data) };
|
||||
QBuffer buffer { const_cast<hifi::ByteArray*>(&data) };
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
|
||||
auto hfmModelPtr = std::make_shared<HFMModel>();
|
||||
|
@ -849,11 +849,11 @@ HFMModel::Pointer OBJSerializer::read(const QByteArray& data, const QVariantHash
|
|||
int extIndex = filename.lastIndexOf('.'); // by construction, this does not fail
|
||||
QString basename = filename.remove(extIndex + 1, sizeof("obj"));
|
||||
preDefinedMaterial.diffuseColor = glm::vec3(1.0f);
|
||||
QVector<QByteArray> extensions = { "jpg", "jpeg", "png", "tga" };
|
||||
QByteArray base = basename.toUtf8(), textName = "";
|
||||
QVector<hifi::ByteArray> extensions = { "jpg", "jpeg", "png", "tga" };
|
||||
hifi::ByteArray base = basename.toUtf8(), textName = "";
|
||||
qCDebug(modelformat) << "OBJSerializer looking for default texture";
|
||||
for (int i = 0; i < extensions.count(); i++) {
|
||||
QByteArray candidateString = base + extensions[i];
|
||||
hifi::ByteArray candidateString = base + extensions[i];
|
||||
if (isValidTexture(candidateString)) {
|
||||
textName = candidateString;
|
||||
break;
|
||||
|
@ -871,11 +871,11 @@ HFMModel::Pointer OBJSerializer::read(const QByteArray& data, const QVariantHash
|
|||
if (needsMaterialLibrary) {
|
||||
foreach (QString libraryName, librariesSeen.keys()) {
|
||||
// Throw away any path part of libraryName, and merge against original url.
|
||||
QUrl libraryUrl = _url.resolved(QUrl(libraryName).fileName());
|
||||
hifi::URL libraryUrl = _url.resolved(hifi::URL(libraryName).fileName());
|
||||
qCDebug(modelformat) << "OBJSerializer material library" << libraryName;
|
||||
bool success;
|
||||
QByteArray data;
|
||||
std::tie<bool, QByteArray>(success, data) = requestData(libraryUrl);
|
||||
hifi::ByteArray data;
|
||||
std::tie<bool, hifi::ByteArray>(success, data) = requestData(libraryUrl);
|
||||
if (success) {
|
||||
QBuffer buffer { &data };
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
|
|
|
@ -25,9 +25,9 @@ public:
|
|||
COMMENT_TOKEN = 0x101
|
||||
};
|
||||
int nextToken(bool allowSpaceChar = false);
|
||||
const QByteArray& getDatum() const { return _datum; }
|
||||
const hifi::ByteArray& getDatum() const { return _datum; }
|
||||
bool isNextTokenFloat();
|
||||
const QByteArray getLineAsDatum(); // some "filenames" have spaces in them
|
||||
const hifi::ByteArray getLineAsDatum(); // some "filenames" have spaces in them
|
||||
void skipLine() { _device->readLine(); }
|
||||
void pushBackToken(int token) { _pushedBackToken = token; }
|
||||
void ungetChar(char ch) { _device->ungetChar(ch); }
|
||||
|
@ -39,7 +39,7 @@ public:
|
|||
|
||||
private:
|
||||
QIODevice* _device;
|
||||
QByteArray _datum;
|
||||
hifi::ByteArray _datum;
|
||||
int _pushedBackToken;
|
||||
QString _comment;
|
||||
};
|
||||
|
@ -52,7 +52,7 @@ public:
|
|||
QString groupName; // We don't make use of hierarchical structure, but it can be preserved for debugging and future use.
|
||||
QString materialName;
|
||||
// Add one more set of vertex data. Answers true if successful
|
||||
bool add(const QByteArray& vertexIndex, const QByteArray& textureIndex, const QByteArray& normalIndex,
|
||||
bool add(const hifi::ByteArray& vertexIndex, const hifi::ByteArray& textureIndex, const hifi::ByteArray& normalIndex,
|
||||
const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& vertexColors);
|
||||
// Return a set of one or more OBJFaces from this one, in which each is just a triangle.
|
||||
// Even though HFMMeshPart can handle quads, it would be messy to try to keep track of mixed-size faces, so we treat everything as triangles.
|
||||
|
@ -75,11 +75,11 @@ public:
|
|||
glm::vec3 diffuseColor;
|
||||
glm::vec3 specularColor;
|
||||
glm::vec3 emissiveColor;
|
||||
QByteArray diffuseTextureFilename;
|
||||
QByteArray specularTextureFilename;
|
||||
QByteArray emissiveTextureFilename;
|
||||
QByteArray bumpTextureFilename;
|
||||
QByteArray opacityTextureFilename;
|
||||
hifi::ByteArray diffuseTextureFilename;
|
||||
hifi::ByteArray specularTextureFilename;
|
||||
hifi::ByteArray emissiveTextureFilename;
|
||||
hifi::ByteArray bumpTextureFilename;
|
||||
hifi::ByteArray opacityTextureFilename;
|
||||
|
||||
OBJMaterialTextureOptions bumpTextureOptions;
|
||||
int illuminationModel;
|
||||
|
@ -103,17 +103,17 @@ public:
|
|||
QString currentMaterialName;
|
||||
QHash<QString, OBJMaterial> materials;
|
||||
|
||||
HFMModel::Pointer read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) override;
|
||||
HFMModel::Pointer read(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url = hifi::URL()) override;
|
||||
|
||||
private:
|
||||
QUrl _url;
|
||||
hifi::URL _url;
|
||||
|
||||
QHash<QByteArray, bool> librariesSeen;
|
||||
bool parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, HFMModel& hfmModel,
|
||||
QHash<hifi::ByteArray, bool> librariesSeen;
|
||||
bool parseOBJGroup(OBJTokenizer& tokenizer, const hifi::VariantHash& mapping, HFMModel& hfmModel,
|
||||
float& scaleGuess, bool combineParts);
|
||||
void parseMaterialLibrary(QIODevice* device);
|
||||
void parseTextureLine(const QByteArray& textureLine, QByteArray& filename, OBJMaterialTextureOptions& textureOptions);
|
||||
bool isValidTexture(const QByteArray &filename); // true if the file exists. TODO?: check content-type header and that it is a supported format.
|
||||
void parseTextureLine(const hifi::ByteArray& textureLine, hifi::ByteArray& filename, OBJMaterialTextureOptions& textureOptions);
|
||||
bool isValidTexture(const hifi::ByteArray &filename); // true if the file exists. TODO?: check content-type header and that it is a supported format.
|
||||
|
||||
int _partCounter { 0 };
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue