gltf importer accept local files and binary read fix

This commit is contained in:
luiscuenca 2018-07-16 10:19:38 -07:00
parent b6d6239bb5
commit c574305ddc
2 changed files with 95 additions and 128 deletions

View file

@ -21,14 +21,17 @@
#include <QtCore/qpair.h> #include <QtCore/qpair.h>
#include <QtCore/qlist.h> #include <QtCore/qlist.h>
#include <QtNetwork/QNetworkAccessManager> #include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest> #include <QtNetwork/QNetworkRequest>
#include <qfile.h> #include <qfile.h>
#include <qfileinfo.h>
#include <shared/NsightHelpers.h> #include <shared/NsightHelpers.h>
#include <NetworkAccessManager.h> #include <NetworkAccessManager.h>
#include <ResourceManager.h> #include <ResourceManager.h>
#include <PathUtils.h>
#include "FBXReader.h" #include "FBXReader.h"
@ -786,13 +789,18 @@ bool GLTFReader::buildGeometry(FBXGeometry& geometry, const QUrl& url) {
QVector<glm::vec3> raw_vertices; QVector<glm::vec3> raw_vertices;
QVector<glm::vec3> raw_normals; QVector<glm::vec3> raw_normals;
addArrayOfType(indicesBuffer.blob, bool success = addArrayOfType(indicesBuffer.blob,
indicesBufferview.byteOffset + indicesAccBoffset, indicesBufferview.byteOffset + indicesAccBoffset,
indicesBufferview.byteLength, indicesAccessor.count,
part.triangleIndices, part.triangleIndices,
indicesAccessor.type, indicesAccessor.type,
indicesAccessor.componentType); indicesAccessor.componentType);
if (!success) {
qWarning(modelformat) << "There was a problem reading glTF INDICES data for model " << _url;
continue;
}
QList<QString> keys = primitive.attributes.values.keys(); QList<QString> keys = primitive.attributes.values.keys();
foreach(auto &key, keys) { foreach(auto &key, keys) {
@ -805,44 +813,60 @@ bool GLTFReader::buildGeometry(FBXGeometry& geometry, const QUrl& url) {
int accBoffset = accessor.defined["byteOffset"] ? accessor.byteOffset : 0; int accBoffset = accessor.defined["byteOffset"] ? accessor.byteOffset : 0;
if (key == "POSITION") { if (key == "POSITION") {
QVector<float> vertices; QVector<float> vertices;
addArrayOfType(buffer.blob, success = addArrayOfType(buffer.blob,
bufferview.byteOffset + accBoffset, bufferview.byteOffset + accBoffset,
bufferview.byteLength, vertices, accessor.count, vertices,
accessor.type, accessor.type,
accessor.componentType); accessor.componentType);
if (!success) {
qWarning(modelformat) << "There was a problem reading glTF POSITION data for model " << _url;
continue;
}
for (int n = 0; n < vertices.size(); n = n + 3) { for (int n = 0; n < vertices.size(); n = n + 3) {
mesh.vertices.push_back(glm::vec3(vertices[n], vertices[n + 1], vertices[n + 2])); mesh.vertices.push_back(glm::vec3(vertices[n], vertices[n + 1], vertices[n + 2]));
} }
} else if (key == "NORMAL") { } else if (key == "NORMAL") {
QVector<float> normals; QVector<float> normals;
addArrayOfType(buffer.blob, success = addArrayOfType(buffer.blob,
bufferview.byteOffset + accBoffset, bufferview.byteOffset + accBoffset,
bufferview.byteLength, accessor.count,
normals, normals,
accessor.type, accessor.type,
accessor.componentType); accessor.componentType);
if (!success) {
qWarning(modelformat) << "There was a problem reading glTF NORMAL data for model " << _url;
continue;
}
for (int n = 0; n < normals.size(); n = n + 3) { for (int n = 0; n < normals.size(); n = n + 3) {
mesh.normals.push_back(glm::vec3(normals[n], normals[n + 1], normals[n + 2])); mesh.normals.push_back(glm::vec3(normals[n], normals[n + 1], normals[n + 2]));
} }
} else if (key == "TEXCOORD_0") { } else if (key == "TEXCOORD_0") {
QVector<float> texcoords; QVector<float> texcoords;
addArrayOfType(buffer.blob, success = addArrayOfType(buffer.blob,
bufferview.byteOffset + accBoffset, bufferview.byteOffset + accBoffset,
bufferview.byteLength, accessor.count,
texcoords, texcoords,
accessor.type, accessor.type,
accessor.componentType); accessor.componentType);
if (!success) {
qWarning(modelformat) << "There was a problem reading glTF TEXCOORD_0 data for model " << _url;
continue;
}
for (int n = 0; n < texcoords.size(); n = n + 2) { for (int n = 0; n < texcoords.size(); n = n + 2) {
mesh.texCoords.push_back(glm::vec2(texcoords[n], texcoords[n + 1])); mesh.texCoords.push_back(glm::vec2(texcoords[n], texcoords[n + 1]));
} }
} else if (key == "TEXCOORD_1") { } else if (key == "TEXCOORD_1") {
QVector<float> texcoords; QVector<float> texcoords;
addArrayOfType(buffer.blob, success = addArrayOfType(buffer.blob,
bufferview.byteOffset + accBoffset, bufferview.byteOffset + accBoffset,
bufferview.byteLength, accessor.count,
texcoords, texcoords,
accessor.type, accessor.type,
accessor.componentType); accessor.componentType);
if (!success) {
qWarning(modelformat) << "There was a problem reading glTF TEXCOORD_1 data for model " << _url;
continue;
}
for (int n = 0; n < texcoords.size(); n = n + 2) { for (int n = 0; n < texcoords.size(); n = n + 2) {
mesh.texCoords1.push_back(glm::vec2(texcoords[n], texcoords[n + 1])); mesh.texCoords1.push_back(glm::vec2(texcoords[n], texcoords[n + 1]));
} }
@ -888,8 +912,16 @@ bool GLTFReader::buildGeometry(FBXGeometry& geometry, const QUrl& url) {
FBXGeometry* GLTFReader::readGLTF(QByteArray& model, const QVariantHash& mapping, FBXGeometry* GLTFReader::readGLTF(QByteArray& model, const QVariantHash& mapping,
const QUrl& url, bool loadLightmaps, float lightmapLevel) { const QUrl& url, bool loadLightmaps, float lightmapLevel) {
_url = url; _url = url;
// Normalize url for local files
QUrl normalizeUrl = DependencyManager::get<ResourceManager>()->normalizeURL(url);
if (normalizeUrl.scheme().isEmpty() || (normalizeUrl.scheme() == "file")) {
QString localFileName = PathUtils::expandToLocalDataAbsolutePath(normalizeUrl).toLocalFile();
_url = QUrl(QFileInfo(localFileName).absoluteFilePath());
}
parseGLTF(model); parseGLTF(model);
//_file.dump(); //_file.dump();
FBXGeometry* geometryPtr = new FBXGeometry(); FBXGeometry* geometryPtr = new FBXGeometry();
@ -904,6 +936,7 @@ FBXGeometry* GLTFReader::readGLTF(QByteArray& model, const QVariantHash& mapping
bool GLTFReader::readBinary(const QString& url, QByteArray& outdata) { bool GLTFReader::readBinary(const QString& url, QByteArray& outdata) {
QUrl binaryUrl = _url.resolved(QUrl(url).fileName()); QUrl binaryUrl = _url.resolved(QUrl(url).fileName());
qCDebug(modelformat) << "binaryUrl: " << binaryUrl << " OriginalUrl: " << _url; qCDebug(modelformat) << "binaryUrl: " << binaryUrl << " OriginalUrl: " << _url;
bool success; bool success;
std::tie<bool, QByteArray>(success, outdata) = requestData(binaryUrl); std::tie<bool, QByteArray>(success, outdata) = requestData(binaryUrl);
@ -1018,13 +1051,12 @@ void GLTFReader::setFBXMaterial(FBXMaterial& fbxmat, const GLTFMaterial& materia
fbxmat.opacityTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]); fbxmat.opacityTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]);
fbxmat.albedoTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]); fbxmat.albedoTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]);
fbxmat.useAlbedoMap = true; fbxmat.useAlbedoMap = true;
fbxmat.metallicTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]);
fbxmat.useMetallicMap = true;
} }
if (material.pbrMetallicRoughness.defined["metallicRoughnessTexture"]) { if (material.pbrMetallicRoughness.defined["metallicRoughnessTexture"]) {
fbxmat.roughnessTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]); fbxmat.roughnessTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]);
fbxmat.useRoughnessMap = true; fbxmat.useRoughnessMap = true;
fbxmat.metallicTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]);
fbxmat.useMetallicMap = true;
} }
if (material.pbrMetallicRoughness.defined["roughnessFactor"]) { if (material.pbrMetallicRoughness.defined["roughnessFactor"]) {
fbxmat._material->setRoughness(material.pbrMetallicRoughness.roughnessFactor); fbxmat._material->setRoughness(material.pbrMetallicRoughness.roughnessFactor);
@ -1043,7 +1075,7 @@ void GLTFReader::setFBXMaterial(FBXMaterial& fbxmat, const GLTFMaterial& materia
} }
template<typename T, typename L> template<typename T, typename L>
bool GLTFReader::readArray(const QByteArray& bin, int byteOffset, int byteLength, bool GLTFReader::readArray(const QByteArray& bin, int byteOffset, int count,
QVector<L>& outarray, int accessorType) { QVector<L>& outarray, int accessorType) {
QDataStream blobstream(bin); QDataStream blobstream(bin);
@ -1051,142 +1083,77 @@ bool GLTFReader::readArray(const QByteArray& bin, int byteOffset, int byteLength
blobstream.setVersion(QDataStream::Qt_5_9); blobstream.setVersion(QDataStream::Qt_5_9);
blobstream.setFloatingPointPrecision(QDataStream::FloatingPointPrecision::SinglePrecision); blobstream.setFloatingPointPrecision(QDataStream::FloatingPointPrecision::SinglePrecision);
int vsize = byteLength / sizeof(T); qCDebug(modelformat) << "size1: " << count;
qCDebug(modelformat) << "size1: " << vsize;
int dataskipped = blobstream.skipRawData(byteOffset); int dataskipped = blobstream.skipRawData(byteOffset);
qCDebug(modelformat) << "dataskipped: " << dataskipped; qCDebug(modelformat) << "dataskipped: " << dataskipped;
int bufferCount = 0;
while (outarray.size() < vsize) { switch (accessorType) {
case GLTFAccessorType::SCALAR:
T value1, value2, value3, value4, bufferCount = 1;
value5, value6, value7, value8, break;
value9, value10, value11, value12, case GLTFAccessorType::VEC2:
value13, value14, value15, value16; bufferCount = 2;
break;
if (accessorType == GLTFAccessorType::SCALAR) { case GLTFAccessorType::VEC3:
bufferCount = 3;
blobstream >> value1; break;
case GLTFAccessorType::VEC4:
outarray.push_back(value1); bufferCount = 4;
} else if (accessorType == GLTFAccessorType::VEC2) { break;
case GLTFAccessorType::MAT2:
blobstream >> value1; bufferCount = 4;
blobstream >> value2; break;
case GLTFAccessorType::MAT3:
outarray.push_back(value1); bufferCount = 9;
outarray.push_back(value2); break;
} else if (accessorType == GLTFAccessorType::VEC3) { case GLTFAccessorType::MAT4:
bufferCount = 16;
blobstream >> value1; break;
blobstream >> value2; default:
blobstream >> value3; qWarning(modelformat) << "Unknown accessorType: " << accessorType;
blobstream.unsetDevice();
outarray.push_back(value1); return false;
outarray.push_back(value2); }
outarray.push_back(value3); for (int i = 0; i < count; i++) {
} else if (accessorType == GLTFAccessorType::VEC4 || accessorType == GLTFAccessorType::MAT2) { for (int j = 0; j < bufferCount; j++) {
if (!blobstream.atEnd()) {
blobstream >> value1; T value;
blobstream >> value2; blobstream >> value;
blobstream >> value3; outarray.push_back(value);
blobstream >> value4; } else {
blobstream.unsetDevice();
outarray.push_back(value1); return false;
outarray.push_back(value2);
outarray.push_back(value3);
outarray.push_back(value4);
} else if (accessorType == GLTFAccessorType::MAT3) {
blobstream >> value1;
blobstream >> value2;
blobstream >> value3;
blobstream >> value4;
blobstream >> value5;
blobstream >> value6;
blobstream >> value7;
blobstream >> value8;
blobstream >> value9;
outarray.push_back(value1);
outarray.push_back(value2);
outarray.push_back(value3);
outarray.push_back(value4);
outarray.push_back(value5);
outarray.push_back(value6);
outarray.push_back(value7);
outarray.push_back(value8);
outarray.push_back(value9);
} else if (accessorType == GLTFAccessorType::MAT4) {
blobstream >> value1;
blobstream >> value2;
blobstream >> value3;
blobstream >> value4;
blobstream >> value5;
blobstream >> value6;
blobstream >> value7;
blobstream >> value8;
blobstream >> value9;
blobstream >> value10;
blobstream >> value11;
blobstream >> value12;
blobstream >> value13;
blobstream >> value14;
blobstream >> value15;
blobstream >> value16;
outarray.push_back(value1);
outarray.push_back(value2);
outarray.push_back(value3);
outarray.push_back(value4);
outarray.push_back(value5);
outarray.push_back(value6);
outarray.push_back(value7);
outarray.push_back(value8);
outarray.push_back(value9);
outarray.push_back(value10);
outarray.push_back(value11);
outarray.push_back(value12);
outarray.push_back(value13);
outarray.push_back(value14);
outarray.push_back(value15);
outarray.push_back(value16);
} }
} }
}
blobstream.unsetDevice(); blobstream.unsetDevice();
return true; return true;
} }
template<typename T> template<typename T>
bool GLTFReader::addArrayOfType(const QByteArray& bin, int byteOffset, int byteLength, bool GLTFReader::addArrayOfType(const QByteArray& bin, int byteOffset, int count,
QVector<T>& outarray, int accessorType, int componentType) { QVector<T>& outarray, int accessorType, int componentType) {
switch (componentType) { switch (componentType) {
case GLTFAccessorComponentType::BYTE: {} case GLTFAccessorComponentType::BYTE: {}
case GLTFAccessorComponentType::UNSIGNED_BYTE: { case GLTFAccessorComponentType::UNSIGNED_BYTE: {
readArray<uchar>(bin, byteOffset, byteLength, outarray, accessorType); return readArray<uchar>(bin, byteOffset, count, outarray, accessorType);
break;
} }
case GLTFAccessorComponentType::SHORT: { case GLTFAccessorComponentType::SHORT: {
readArray<short>(bin, byteOffset, byteLength, outarray, accessorType); return readArray<short>(bin, byteOffset, count, outarray, accessorType);
break;
} }
case GLTFAccessorComponentType::UNSIGNED_INT: { case GLTFAccessorComponentType::UNSIGNED_INT: {
readArray<quint32>(bin, byteOffset, byteLength, outarray, accessorType); return readArray<uint>(bin, byteOffset, count, outarray, accessorType);
break;
} }
case GLTFAccessorComponentType::UNSIGNED_SHORT: { case GLTFAccessorComponentType::UNSIGNED_SHORT: {
readArray<ushort>(bin, byteOffset, byteLength, outarray, accessorType); return readArray<ushort>(bin, byteOffset, count, outarray, accessorType);
break;
} }
case GLTFAccessorComponentType::FLOAT: { case GLTFAccessorComponentType::FLOAT: {
readArray<float>(bin, byteOffset, byteLength, outarray, accessorType); return readArray<float>(bin, byteOffset, count, outarray, accessorType);
break;
} }
} }
return true; return false;
} }
void GLTFReader::retriangulate(const QVector<int>& inIndices, const QVector<glm::vec3>& in_vertices, void GLTFReader::retriangulate(const QVector<int>& inIndices, const QVector<glm::vec3>& in_vertices,

View file

@ -762,11 +762,11 @@ private:
bool readBinary(const QString& url, QByteArray& outdata); bool readBinary(const QString& url, QByteArray& outdata);
template<typename T, typename L> template<typename T, typename L>
bool readArray(const QByteArray& bin, int byteOffset, int byteLength, bool readArray(const QByteArray& bin, int byteOffset, int count,
QVector<L>& outarray, int accessorType); QVector<L>& outarray, int accessorType);
template<typename T> template<typename T>
bool addArrayOfType(const QByteArray& bin, int byteOffset, int byteLength, bool addArrayOfType(const QByteArray& bin, int byteOffset, int count,
QVector<T>& outarray, int accessorType, int componentType); QVector<T>& outarray, int accessorType, int componentType);
void retriangulate(const QVector<int>& in_indices, const QVector<glm::vec3>& in_vertices, void retriangulate(const QVector<int>& in_indices, const QVector<glm::vec3>& in_vertices,