Browse Source

ObjImporter: reorder texture coordinate handling to be before normals.

To have it consistent, as it was a mess right now. OBJ indices are
position/texcoord/normal, so this should match that order.
master
Vladimír Vondruš 4 years ago
parent
commit
9b8c655c13
  1. 54
      src/MagnumPlugins/ObjImporter/ObjImporter.cpp

54
src/MagnumPlugins/ObjImporter/ObjImporter.cpp

@ -284,8 +284,8 @@ Containers::Optional<MeshData> ObjImporter::doMesh(const UnsignedInt id, Unsigne
Containers::Optional<MeshPrimitive> primitive; Containers::Optional<MeshPrimitive> primitive;
Containers::Array<Vector3> positions; Containers::Array<Vector3> positions;
Containers::Array<Vector3> normals;
Containers::Array<Vector2> textureCoordinates; Containers::Array<Vector2> textureCoordinates;
Containers::Array<Vector3> normals;
/* Taking a shortcut as there's fortunately nothing else than just 3 types /* Taking a shortcut as there's fortunately nothing else than just 3 types
of data. First positions, then normals, then texture coordinates. */ of data. First positions, then normals, then texture coordinates. */
Containers::Array<Vector3ui> indices; Containers::Array<Vector3ui> indices;
@ -409,18 +409,18 @@ Containers::Optional<MeshData> ObjImporter::doMesh(const UnsignedInt id, Unsigne
indexTuple = indexTuple.suffix(foundSlash1.end()); indexTuple = indexTuple.suffix(foundSlash1.end());
const Containers::StringView foundSlash2 = indexTuple.findOr('/', indexTuple.end()); const Containers::StringView foundSlash2 = indexTuple.findOr('/', indexTuple.end());
if(!foundSlash2 || foundSlash2.begin() != indexTuple.begin()) { if(!foundSlash2 || foundSlash2.begin() != indexTuple.begin()) {
if(!parseUnsignedInt("Trade::ObjImporter::mesh():", indexTuple.prefix(foundSlash2.begin()), data[i][2])) if(!parseUnsignedInt("Trade::ObjImporter::mesh():", indexTuple.prefix(foundSlash2.begin()), data[i][1]))
return {}; return {};
data[i][2] -= mesh.textureCoordinateIndexOffset; data[i][1] -= mesh.textureCoordinateIndexOffset;
++textureCoordinateIndexCount; ++textureCoordinateIndexCount;
} }
/* If there was a second slash, last is a normal */ /* If there was a second slash, last is a normal */
if(foundSlash2) { if(foundSlash2) {
indexTuple = indexTuple.suffix(foundSlash2.end()); indexTuple = indexTuple.suffix(foundSlash2.end());
if(!parseUnsignedInt("Trade::ObjImporter::mesh():", indexTuple, data[i][1])) if(!parseUnsignedInt("Trade::ObjImporter::mesh():", indexTuple, data[i][2]))
return {}; return {};
data[i][1] -= mesh.normalIndexOffset; data[i][2] -= mesh.normalIndexOffset;
++normalIndexCount; ++normalIndexCount;
} }
} }
@ -486,26 +486,26 @@ Containers::Optional<MeshData> ObjImporter::doMesh(const UnsignedInt id, Unsigne
} }
/* If there are index data, there should be also vertex data (and also the other way) */ /* If there are index data, there should be also vertex data (and also the other way) */
if(normals.isEmpty() != (normalIndexCount == 0)) {
Error() << "Trade::ObjImporter::mesh(): incomplete normal data";
return Containers::NullOpt;
}
if(textureCoordinates.isEmpty() != (textureCoordinateIndexCount == 0)) { if(textureCoordinates.isEmpty() != (textureCoordinateIndexCount == 0)) {
Error() << "Trade::ObjImporter::mesh(): incomplete texture coordinate data"; Error() << "Trade::ObjImporter::mesh(): incomplete texture coordinate data";
return Containers::NullOpt; return Containers::NullOpt;
} }
if(normals.isEmpty() != (normalIndexCount == 0)) {
/* All index arrays should have the same length */ Error() << "Trade::ObjImporter::mesh(): incomplete normal data";
if(normalIndexCount && normalIndexCount != indices.size()) {
CORRADE_INTERNAL_ASSERT(normalIndexCount < indices.size());
Error() << "Trade::ObjImporter::mesh(): some normal indices are missing";
return Containers::NullOpt; return Containers::NullOpt;
} }
/* All index arrays should have the same length */
if(textureCoordinateIndexCount && textureCoordinateIndexCount != indices.size()) { if(textureCoordinateIndexCount && textureCoordinateIndexCount != indices.size()) {
CORRADE_INTERNAL_ASSERT(textureCoordinateIndexCount < indices.size()); CORRADE_INTERNAL_ASSERT(textureCoordinateIndexCount < indices.size());
Error() << "Trade::ObjImporter::mesh(): some texture coordinate indices are missing"; Error() << "Trade::ObjImporter::mesh(): some texture coordinate indices are missing";
return Containers::NullOpt; return Containers::NullOpt;
} }
if(normalIndexCount && normalIndexCount != indices.size()) {
CORRADE_INTERNAL_ASSERT(normalIndexCount < indices.size());
Error() << "Trade::ObjImporter::mesh(): some normal indices are missing";
return Containers::NullOpt;
}
/* Merge index arrays. If any of the attributes was not there, the whole /* Merge index arrays. If any of the attributes was not there, the whole
index array has zeros, not affecting the uniqueness in any way. */ index array has zeros, not affecting the uniqueness in any way. */
@ -517,14 +517,14 @@ Containers::Optional<MeshData> ObjImporter::doMesh(const UnsignedInt id, Unsigne
/* Allocate attribute and vertex data */ /* Allocate attribute and vertex data */
std::size_t attributeCount = 1; std::size_t attributeCount = 1;
UnsignedInt stride = sizeof(Vector3); UnsignedInt stride = sizeof(Vector3);
if(normalIndexCount) {
++attributeCount;
stride += sizeof(Vector3);
}
if(textureCoordinateIndexCount) { if(textureCoordinateIndexCount) {
++attributeCount; ++attributeCount;
stride += sizeof(Vector2); stride += sizeof(Vector2);
} }
if(normalIndexCount) {
++attributeCount;
stride += sizeof(Vector3);
}
Containers::Array<MeshAttributeData> attributeData{attributeCount}; Containers::Array<MeshAttributeData> attributeData{attributeCount};
Containers::Array<char> vertexData{NoInit, vertexCount*stride}; Containers::Array<char> vertexData{NoInit, vertexCount*stride};
@ -540,22 +540,22 @@ Containers::Optional<MeshData> ObjImporter::doMesh(const UnsignedInt id, Unsigne
attributeData[attributeIndex++] = MeshAttributeData{MeshAttribute::Position, view}; attributeData[attributeIndex++] = MeshAttributeData{MeshAttribute::Position, view};
offset += sizeof(Vector3); offset += sizeof(Vector3);
} }
if(normalIndexCount) {
Containers::StridedArrayView1D<Vector3> view{vertexData,
reinterpret_cast<Vector3*>(vertexData.data() + offset), vertexCount, stride};
if(!checkAndDuplicateInto(indicesPerAttribute[1].prefix(vertexCount), normals, view, mesh.normalIndexOffset))
return Containers::NullOpt;
attributeData[attributeIndex++] = MeshAttributeData{MeshAttribute::Normal, view};
offset += sizeof(Vector3);
}
if(textureCoordinateIndexCount) { if(textureCoordinateIndexCount) {
Containers::StridedArrayView1D<Vector2> view{vertexData, Containers::StridedArrayView1D<Vector2> view{vertexData,
reinterpret_cast<Vector2*>(vertexData.data() + offset), vertexCount, stride}; reinterpret_cast<Vector2*>(vertexData.data() + offset), vertexCount, stride};
if(!checkAndDuplicateInto(indicesPerAttribute[2].prefix(vertexCount), textureCoordinates, view, mesh.textureCoordinateIndexOffset)) if(!checkAndDuplicateInto(indicesPerAttribute[1].prefix(vertexCount), textureCoordinates, view, mesh.textureCoordinateIndexOffset))
return Containers::NullOpt; return Containers::NullOpt;
attributeData[attributeIndex++] = MeshAttributeData{MeshAttribute::TextureCoordinates, view}; attributeData[attributeIndex++] = MeshAttributeData{MeshAttribute::TextureCoordinates, view};
offset += sizeof(Vector2); offset += sizeof(Vector2);
} }
if(normalIndexCount) {
Containers::StridedArrayView1D<Vector3> view{vertexData,
reinterpret_cast<Vector3*>(vertexData.data() + offset), vertexCount, stride};
if(!checkAndDuplicateInto(indicesPerAttribute[2].prefix(vertexCount), normals, view, mesh.normalIndexOffset))
return Containers::NullOpt;
attributeData[attributeIndex++] = MeshAttributeData{MeshAttribute::Normal, view};
offset += sizeof(Vector3);
}
CORRADE_INTERNAL_ASSERT(offset == stride && attributeIndex == attributeCount); CORRADE_INTERNAL_ASSERT(offset == stride && attributeIndex == attributeCount);
return MeshData{*primitive, return MeshData{*primitive,

Loading…
Cancel
Save