allow obj reader to either combine meshes or keep parts separate

This commit is contained in:
Seth Alves 2017-04-07 15:59:01 -07:00
parent b9c7d6351f
commit 8d00f0ab8f
4 changed files with 21 additions and 10 deletions

View file

@ -302,7 +302,8 @@ QNetworkReply* OBJReader::request(QUrl& url, bool isTest) {
} }
bool OBJReader::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, FBXGeometry& geometry, float& scaleGuess) { bool OBJReader::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, FBXGeometry& geometry,
float& scaleGuess, bool combineParts) {
FaceGroup faces; FaceGroup faces;
FBXMesh& mesh = geometry.meshes[0]; FBXMesh& mesh = geometry.meshes[0];
mesh.parts.append(FBXMeshPart()); mesh.parts.append(FBXMeshPart());
@ -348,6 +349,9 @@ bool OBJReader::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mappi
} }
QByteArray groupName = tokenizer.getDatum(); QByteArray groupName = tokenizer.getDatum();
currentGroup = groupName; currentGroup = groupName;
if (!combineParts) {
currentMaterialName = QString("part-") + QString::number(_partCounter++);
}
} else if (token == "mtllib" && !_url.isEmpty()) { } else if (token == "mtllib" && !_url.isEmpty()) {
if (tokenizer.nextToken() != OBJTokenizer::DATUM_TOKEN) { if (tokenizer.nextToken() != OBJTokenizer::DATUM_TOKEN) {
break; break;
@ -361,7 +365,9 @@ bool OBJReader::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mappi
} }
QString nextName = tokenizer.getDatum(); QString nextName = tokenizer.getDatum();
if (nextName != currentMaterialName) { if (nextName != currentMaterialName) {
currentMaterialName = nextName; if (combineParts) {
currentMaterialName = nextName;
}
#ifdef WANT_DEBUG #ifdef WANT_DEBUG
qCDebug(modelformat) << "OBJ Reader new current material:" << currentMaterialName; qCDebug(modelformat) << "OBJ Reader new current material:" << currentMaterialName;
#endif #endif
@ -419,7 +425,7 @@ done:
} }
FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, const QUrl& url) { FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, bool combineParts, const QUrl& url) {
PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xffff0000, nullptr); PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xffff0000, nullptr);
QBuffer buffer { &model }; QBuffer buffer { &model };
buffer.open(QIODevice::ReadOnly); buffer.open(QIODevice::ReadOnly);
@ -438,7 +444,7 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping,
try { try {
// call parseOBJGroup as long as it's returning true. Each successful call will // call parseOBJGroup as long as it's returning true. Each successful call will
// add a new meshPart to the geometry's single mesh. // add a new meshPart to the geometry's single mesh.
while (parseOBJGroup(tokenizer, mapping, geometry, scaleGuess)) {} while (parseOBJGroup(tokenizer, mapping, geometry, scaleGuess, combineParts)) {}
FBXMesh& mesh = geometry.meshes[0]; FBXMesh& mesh = geometry.meshes[0];
mesh.meshIndex = 0; mesh.meshIndex = 0;

View file

@ -22,7 +22,7 @@ public:
glm::vec3 getVec3(); glm::vec3 getVec3();
glm::vec2 getVec2(); glm::vec2 getVec2();
float getFloat() { return std::stof((nextToken() != OBJTokenizer::DATUM_TOKEN) ? nullptr : getDatum().data()); } float getFloat() { return std::stof((nextToken() != OBJTokenizer::DATUM_TOKEN) ? nullptr : getDatum().data()); }
private: private:
QIODevice* _device; QIODevice* _device;
QByteArray _datum; QByteArray _datum;
@ -73,15 +73,18 @@ public:
QHash<QString, OBJMaterial> materials; QHash<QString, OBJMaterial> materials;
QNetworkReply* request(QUrl& url, bool isTest); QNetworkReply* request(QUrl& url, bool isTest);
FBXGeometry* readOBJ(QByteArray& model, const QVariantHash& mapping, const QUrl& url = QUrl()); FBXGeometry* readOBJ(QByteArray& model, const QVariantHash& mapping, bool combineParts, const QUrl& url = QUrl());
private: private:
QUrl _url; QUrl _url;
QHash<QByteArray, bool> librariesSeen; QHash<QByteArray, bool> librariesSeen;
bool parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, FBXGeometry& geometry, float& scaleGuess); bool parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, FBXGeometry& geometry,
float& scaleGuess, bool combineParts);
void parseMaterialLibrary(QIODevice* device); void parseMaterialLibrary(QIODevice* device);
bool isValidTexture(const QByteArray &filename); // true if the file exists. TODO?: check content-type header and that it is a supported format. bool isValidTexture(const QByteArray &filename); // true if the file exists. TODO?: check content-type header and that it is a supported format.
int _partCounter { 0 };
}; };
// What are these utilities doing here? One is used by fbx loading code in VHACD Utils, and the other a general debugging utility. // What are these utilities doing here? One is used by fbx loading code in VHACD Utils, and the other a general debugging utility.

View file

@ -178,7 +178,8 @@ void GeometryReader::run() {
throw QString("empty geometry, possibly due to an unsupported FBX version"); throw QString("empty geometry, possibly due to an unsupported FBX version");
} }
} else if (_url.path().toLower().endsWith(".obj")) { } else if (_url.path().toLower().endsWith(".obj")) {
fbxGeometry.reset(OBJReader().readOBJ(_data, _mapping, _url)); bool combineParts = false;
fbxGeometry.reset(OBJReader().readOBJ(_data, _mapping, combineParts, _url));
} else { } else {
throw QString("unsupported format"); throw QString("unsupported format");
} }

View file

@ -43,7 +43,8 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, FBXGeometry& result) {
QByteArray fbxContents = fbx.readAll(); QByteArray fbxContents = fbx.readAll();
FBXGeometry* geom; FBXGeometry* geom;
if (filename.toLower().endsWith(".obj")) { if (filename.toLower().endsWith(".obj")) {
geom = OBJReader().readOBJ(fbxContents, QVariantHash()); bool combineParts = false;
geom = OBJReader().readOBJ(fbxContents, QVariantHash(), combineParts);
} else if (filename.toLower().endsWith(".fbx")) { } else if (filename.toLower().endsWith(".fbx")) {
geom = readFBX(fbxContents, QVariantHash(), filename); geom = readFBX(fbxContents, QVariantHash(), filename);
} else { } else {