mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-10 22:38:34 +02:00
gltf importer accept local files and binary read fix
This commit is contained in:
parent
b6d6239bb5
commit
c574305ddc
2 changed files with 95 additions and 128 deletions
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue