mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +02:00
don't keep empty mesh-parts. take units hint from a common first-line comment, if it's there.
This commit is contained in:
parent
95cc8672c0
commit
48144a46b1
1 changed files with 39 additions and 16 deletions
|
@ -27,7 +27,8 @@ public:
|
|||
enum SpecialToken {
|
||||
NO_TOKEN = -1,
|
||||
NO_PUSHBACKED_TOKEN = -1,
|
||||
DATUM_TOKEN = 0x100
|
||||
DATUM_TOKEN = 0x100,
|
||||
COMMENT_TOKEN = 0x101
|
||||
};
|
||||
int nextToken();
|
||||
const QByteArray& getDatum() const { return _datum; }
|
||||
|
@ -35,11 +36,13 @@ public:
|
|||
void skipLine() { _device->readLine(); }
|
||||
void pushBackToken(int token) { _pushedBackToken = token; }
|
||||
void ungetChar(char ch) { _device->ungetChar(ch); }
|
||||
const QString getComment() const { return _comment; }
|
||||
|
||||
private:
|
||||
QIODevice* _device;
|
||||
QByteArray _datum;
|
||||
int _pushedBackToken;
|
||||
QString _comment;
|
||||
};
|
||||
|
||||
|
||||
|
@ -56,9 +59,11 @@ int OBJTokenizer::nextToken() {
|
|||
continue; // skip whitespace
|
||||
}
|
||||
switch (ch) {
|
||||
case '#':
|
||||
_device->readLine(); // skip the comment
|
||||
break;
|
||||
case '#': {
|
||||
_comment = _device->readLine(); // skip the comment
|
||||
qDebug() << "COMMENT:" << _comment;
|
||||
return COMMENT_TOKEN;
|
||||
}
|
||||
|
||||
case '\"':
|
||||
_datum = "";
|
||||
|
@ -104,7 +109,8 @@ bool OBJTokenizer::isNextTokenFloat() {
|
|||
}
|
||||
|
||||
bool parseOBJGroup(OBJTokenizer &tokenizer, const QVariantHash& mapping,
|
||||
FBXGeometry &geometry, QVector<glm::vec3>& faceNormals, QVector<int>& faceNormalIndexes) {
|
||||
FBXGeometry &geometry, QVector<glm::vec3>& faceNormals, QVector<int>& faceNormalIndexes,
|
||||
float& scaleGuess) {
|
||||
FBXMesh &mesh = geometry.meshes[0];
|
||||
mesh.parts.append(FBXMeshPart());
|
||||
FBXMeshPart &meshPart = mesh.parts.last();
|
||||
|
@ -128,7 +134,17 @@ bool parseOBJGroup(OBJTokenizer &tokenizer, const QVariantHash& mapping,
|
|||
meshPart._material->setEmissive(glm::vec3(0.0, 0.0, 0.0));
|
||||
|
||||
while (true) {
|
||||
if (tokenizer.nextToken() != OBJTokenizer::DATUM_TOKEN) {
|
||||
int tokenType = tokenizer.nextToken();
|
||||
if (tokenType == OBJTokenizer::COMMENT_TOKEN) {
|
||||
if (tokenizer.getComment().contains("This file uses centimeters as units")) {
|
||||
scaleGuess = 1.0f / 100.0f;
|
||||
}
|
||||
if (tokenizer.getComment().contains("This file uses millimeters as units")) {
|
||||
scaleGuess = 1.0f / 1000.0f;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (tokenType != OBJTokenizer::DATUM_TOKEN) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
@ -192,6 +208,7 @@ bool parseOBJGroup(OBJTokenizer &tokenizer, const QVariantHash& mapping,
|
|||
while (true) {
|
||||
if (tokenizer.nextToken() != OBJTokenizer::DATUM_TOKEN) {
|
||||
if (indices.count() == 0) {
|
||||
// nonsense, bail out.
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
|
@ -266,22 +283,22 @@ bool parseOBJGroup(OBJTokenizer &tokenizer, const QVariantHash& mapping,
|
|||
}
|
||||
} else {
|
||||
// something we don't (yet) care about
|
||||
qDebug() << "OBJ parser is skipping a line with" << token;
|
||||
// qDebug() << "OBJ parser is skipping a line with" << token;
|
||||
tokenizer.skipLine();
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
if (meshPart.triangleIndices.size() == 0 && meshPart.quadIndices.size() == 0) {
|
||||
// empty mesh?
|
||||
mesh.parts.pop_back();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FBXGeometry extractOBJGeometry(const FBXNode& node, const QVariantHash& mapping) {
|
||||
FBXGeometry geometry;
|
||||
return geometry;
|
||||
}
|
||||
|
||||
|
||||
FBXGeometry readOBJ(const QByteArray& model, const QVariantHash& mapping) {
|
||||
QBuffer buffer(const_cast<QByteArray*>(&model));
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
|
@ -294,24 +311,30 @@ FBXGeometry readOBJ(QIODevice* device, const QVariantHash& mapping) {
|
|||
OBJTokenizer tokenizer(device);
|
||||
QVector<int> faceNormalIndexes;
|
||||
QVector<glm::vec3> faceNormals;
|
||||
float scaleGuess = 1.0f;
|
||||
|
||||
faceNormalIndexes.clear();
|
||||
|
||||
geometry.meshExtents.reset();
|
||||
geometry.meshes.append(FBXMesh());
|
||||
|
||||
|
||||
|
||||
try {
|
||||
// call parseOBJGroup as long as it's returning true. Each successful call will
|
||||
// add a new meshPart to the geometry's single mesh.
|
||||
bool success = true;
|
||||
while (success) {
|
||||
success = parseOBJGroup(tokenizer, mapping, geometry, faceNormals, faceNormalIndexes);
|
||||
success = parseOBJGroup(tokenizer, mapping, geometry, faceNormals, faceNormalIndexes, scaleGuess);
|
||||
}
|
||||
|
||||
FBXMesh &mesh = geometry.meshes[0];
|
||||
|
||||
// if we got a hint about units, scale all the points
|
||||
if (scaleGuess != 1.0f) {
|
||||
for (int i = 0; i < mesh.vertices.size(); i++) {
|
||||
mesh.vertices[i] *= scaleGuess;
|
||||
}
|
||||
}
|
||||
|
||||
mesh.meshExtents.reset();
|
||||
foreach (const glm::vec3& vertex, mesh.vertices) {
|
||||
mesh.meshExtents.addPoint(vertex);
|
||||
|
|
Loading…
Reference in a new issue