Skip to content

Commit

Permalink
TinyGltfImporter: implement tangent support.
Browse files Browse the repository at this point in the history
  • Loading branch information
mosra committed Mar 28, 2020
1 parent ba6323c commit 1cc6b4e
Show file tree
Hide file tree
Showing 13 changed files with 191 additions and 69 deletions.
3 changes: 2 additions & 1 deletion doc/changelog-plugins.dox
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ namespace Magnum {
unuspported `KHR_lights_cmn` (see [mosra/magnum-plugins#77](https://github.com/mosra/magnum-plugins/pull/77))
- Support for the `KHR_texture_transform` and `KHR_mesh_quantization`
extensions in @ref Trade::TinyGltfImporter "TinyGltfImporter"
- Custom vertex attribute support in @ref Trade::TinyGltfImporter "TinyGltfImporter"
- Tangent and custom vertex attribute support in
@ref Trade::TinyGltfImporter "TinyGltfImporter"
- @ref Trade::DdsImporter "DdsImporter" and
@ref Trade::BasisImporter "BasisImporter", now support loading image mip
levels; @ref Trade::AssimpImporter "AssimpImporter",
Expand Down
68 changes: 56 additions & 12 deletions src/MagnumPlugins/TinyGltfImporter/Test/TinyGltfImporterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,56 +181,56 @@ constexpr struct {
MeshPrimitive primitive;
MeshIndexType indexType;
VertexFormat positionFormat;
VertexFormat normalFormat;
VertexFormat normalFormat, tangentFormat;
VertexFormat colorFormat;
VertexFormat textureCoordinateFormat;
} MeshPrimitivesTypesData[]{
{"positions byte, color4 unsigned short, texcoords normalized unsigned byte; triangle strip",
MeshPrimitive::TriangleStrip, MeshIndexType{},
VertexFormat::Vector3b,
VertexFormat{},
VertexFormat{}, VertexFormat{},
VertexFormat::Vector4usNormalized,
VertexFormat::Vector2ubNormalized},
{"positions short, colors unsigned byte, texcoords normalized unsigned short; lines",
MeshPrimitive::Lines, MeshIndexType{},
VertexFormat::Vector3s,
VertexFormat{},
VertexFormat{}, VertexFormat{},
VertexFormat::Vector3ubNormalized,
VertexFormat::Vector2usNormalized},
{"positions unsigned byte, normals byte, texcoords short; indices unsigned int; line loop",
MeshPrimitive::LineLoop, MeshIndexType::UnsignedInt,
VertexFormat::Vector3ub,
VertexFormat::Vector3bNormalized,
VertexFormat::Vector3bNormalized, VertexFormat{},
VertexFormat{},
VertexFormat::Vector2s},
{"positions unsigned short, normals short, texcoords byte; indices unsigned byte; triangle fan",
MeshPrimitive::TriangleFan, MeshIndexType::UnsignedByte,
VertexFormat::Vector3us,
VertexFormat::Vector3sNormalized,
VertexFormat::Vector3sNormalized, VertexFormat{},
VertexFormat{},
VertexFormat::Vector2b},
{"positions normalized unsigned byte, texcoords normalized short; indices unsigned short; line strip",
{"positions normalized unsigned byte, tangents short, texcoords normalized short; indices unsigned short; line strip",
MeshPrimitive::LineStrip, MeshIndexType::UnsignedShort,
VertexFormat::Vector3ubNormalized,
VertexFormat{},
VertexFormat{}, VertexFormat::Vector4sNormalized,
VertexFormat{},
VertexFormat::Vector2sNormalized},
{"positions normalized short, texcoords unsigned byte; triangles",
{"positions normalized short, texcoords unsigned byte, tangents byte; triangles",
MeshPrimitive::Triangles, MeshIndexType{},
VertexFormat::Vector3sNormalized,
VertexFormat{},
VertexFormat{}, VertexFormat::Vector4bNormalized,
VertexFormat{},
VertexFormat::Vector2ub},
{"positions normalized unsigned short, texcoords normalized byte",
MeshPrimitive::Triangles, MeshIndexType{},
VertexFormat::Vector3usNormalized,
VertexFormat{},
VertexFormat{}, VertexFormat{},
VertexFormat{},
VertexFormat::Vector2bNormalized},
{"positions normalized byte, texcoords unsigned short",
MeshPrimitive::Triangles, MeshIndexType{},
VertexFormat::Vector3bNormalized,
VertexFormat{},
VertexFormat{}, VertexFormat{},
VertexFormat{},
VertexFormat::Vector2us}
};
Expand All @@ -245,6 +245,8 @@ constexpr struct {
{"unsupported position component type", "unsupported POSITION component type unnormalized 5130"},
{"unexpected normal type", "unexpected NORMAL type 2"},
{"unsupported normal component type", "unsupported NORMAL component type unnormalized 5130"},
{"unexpected tangent type", "unexpected TANGENT type 3"},
{"unsupported tangent component type", "unsupported TANGENT component type unnormalized 5120"},
{"unexpected texcoord type", "unexpected TEXCOORD type 3"},
{"unsupported texcoord component type", "unsupported TEXCOORD component type normalized 5125"},
{"unexpected color type", "unexpected COLOR type 2"},
Expand Down Expand Up @@ -1625,7 +1627,7 @@ void TinyGltfImporterTest::meshIndexed() {
Containers::arrayView<UnsignedByte>({0, 1, 2}),
TestSuite::Compare::Container);

CORRADE_COMPARE(mesh->attributeCount(), 2);
CORRADE_COMPARE(mesh->attributeCount(), 3);
CORRADE_VERIFY(mesh->hasAttribute(MeshAttribute::Position));
CORRADE_COMPARE(mesh->attributeFormat(MeshAttribute::Position), VertexFormat::Vector3);
CORRADE_COMPARE_AS(mesh->attribute<Vector3>(MeshAttribute::Position),
Expand All @@ -1642,6 +1644,14 @@ void TinyGltfImporterTest::meshIndexed() {
{0.4f, 0.5f, 0.6f},
{0.7f, 0.8f, 0.9f}
}), TestSuite::Compare::Container);
CORRADE_VERIFY(mesh->hasAttribute(MeshAttribute::Tangent));
CORRADE_COMPARE(mesh->attributeFormat(MeshAttribute::Tangent), VertexFormat::Vector4);
CORRADE_COMPARE_AS(mesh->attribute<Vector4>(MeshAttribute::Tangent),
Containers::arrayView<Vector4>({
{-0.1f, -0.2f, -0.3f, 1.0f},
{-0.4f, -0.5f, -0.6f, -1.0f},
{-0.7f, -0.8f, -0.9f, 1.0f}
}), TestSuite::Compare::Container);
}

void TinyGltfImporterTest::meshIndexedAttributeless() {
Expand Down Expand Up @@ -2060,6 +2070,40 @@ void TinyGltfImporterTest::meshPrimitivesTypes() {
}
} else CORRADE_VERIFY(!mesh->hasAttribute(MeshAttribute::Normal));

/* Tangents */
if(data.tangentFormat != VertexFormat{}) {
CORRADE_VERIFY(mesh->hasAttribute(MeshAttribute::Tangent));
CORRADE_COMPARE(mesh->attributeFormat(MeshAttribute::Tangent), data.tangentFormat);

constexpr Vector3 expected[]{
{-0.933333f, -0.333333f, -0.6666667f},
{-1.0f, -0.0f, -0.133333f},
{-0.2f, -0.6f, -0.8f},
{-0.933333f, -0.4f, -0.733333f},
{-0.4f, -0.133333f, -0.733333f}
};

/* Because the signed packed formats are extremely imprecise, we
increase the fuzziness a bit */
auto tangents = mesh->tangentsAsArray();
const Float precision = Math::pow(10.0f, -1.5f*vertexFormatSize(vertexFormatComponentFormat(data.tangentFormat)));
CORRADE_COMPARE_AS(precision, 5.0e-2f, TestSuite::Compare::Less);
CORRADE_COMPARE_AS(precision, 1.0e-6f, TestSuite::Compare::GreaterOrEqual);
CORRADE_COMPARE(tangents.size(), Containers::arraySize(expected));
CORRADE_ITERATION("precision" << precision);
for(std::size_t i = 0; i != tangents.size(); ++i) {
CORRADE_ITERATION(i);
CORRADE_COMPARE_WITH(tangents[i], expected[i],
TestSuite::Compare::around(Vector3{precision}));
}

/* However the bitangents signs are just 1 or -1, so no need to take
extreme measures */
CORRADE_COMPARE_AS(mesh->bitangentSignsAsArray(),
Containers::arrayView<Float>({1.0f, -1.0f, 1.0f, -1.0f, 1.0f}),
TestSuite::Compare::Container);
} else CORRADE_VERIFY(!mesh->hasAttribute(MeshAttribute::Tangent));

/* Colors */
if(data.colorFormat == VertexFormat{}) {
CORRADE_VERIFY(!mesh->hasAttribute(MeshAttribute::Color));
Expand Down
Binary file modified src/MagnumPlugins/TinyGltfImporter/Test/mesh-embedded.glb
Binary file not shown.
2 changes: 1 addition & 1 deletion src/MagnumPlugins/TinyGltfImporter/Test/mesh-embedded.gltf
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"asset":{"version":"2.0"},"meshes":[{"name":"Non-indexed mesh","primitives":[{"attributes":{"POSITION":1,"TEXCOORD_0":3}}]},{"name":"Indexed mesh","primitives":[{"attributes":{"NORMAL":2,"POSITION":1},"indices":0}]},{"name":"Attribute-less mesh","primitives":[{"attributes":{}}]},{"name":"Attribute-less indexed mesh","primitives":[{"attributes":{},"indices":0}]}],"accessors":[{"bufferView":0,"componentType":5121,"count":3,"type":"SCALAR"},{"bufferView":1,"componentType":5126,"count":3,"type":"VEC3"},{"bufferView":1,"byteOffset":12,"componentType":5126,"count":3,"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":3,"type":"VEC2"}],"bufferViews":[{"buffer":0,"byteLength":3,"byteOffset":0,"target":34963},{"buffer":0,"byteLength":72,"byteOffset":4,"byteStride":24,"target":34962},{"buffer":0,"byteLength":24,"byteOffset":76,"target":34962}],"buffers":[{"byteLength":100,"uri":"data:application/octet-stream;base64,AAECAAAAwD8AAIC/AAAAv83MzD3NzEw+mpmZPgAAAL8AACBAAABAP83MzD4AAAA/mpkZPwAAAMAAAIA/mpmZPjMzMz/NzEw/ZmZmP5qZmT4AAAAAAAAAAAAAAD+amZk+mpmZPg=="}]}
{"asset":{"version":"2.0"},"meshes":[{"name":"Non-indexed mesh","primitives":[{"attributes":{"POSITION":1,"TEXCOORD_0":3}}]},{"name":"Indexed mesh","primitives":[{"attributes":{"NORMAL":2,"POSITION":1,"TANGENT":4},"indices":0}]},{"name":"Attribute-less mesh","primitives":[{"attributes":{}}]},{"name":"Attribute-less indexed mesh","primitives":[{"attributes":{},"indices":0}]}],"accessors":[{"bufferView":0,"componentType":5121,"count":3,"type":"SCALAR"},{"bufferView":1,"componentType":5126,"count":3,"type":"VEC3"},{"bufferView":1,"byteOffset":12,"componentType":5126,"count":3,"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":3,"type":"VEC2"},{"bufferView":1,"byteOffset":24,"componentType":5126,"count":3,"type":"VEC4"}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":3,"target":34963},{"buffer":0,"byteOffset":4,"byteLength":120,"byteStride":40,"target":34962},{"buffer":0,"byteOffset":124,"byteLength":24,"target":34962}],"buffers":[{"byteLength":148,"uri":"data:application/octet-stream;base64,AAECAAAAwD8AAIC/AAAAv83MzD3NzEw+mpmZPs3MzL3NzEy+mpmZvgAAgD8AAAC/AAAgQAAAQD/NzMw+AAAAP5qZGT/NzMy+AAAAv5qZGb8AAIC/AAAAwAAAgD+amZk+MzMzP83MTD9mZmY/MzMzv83MTL9mZma/AACAP5qZmT4AAAAAAAAAAAAAAD+amZk+mpmZPg=="}]}
20 changes: 20 additions & 0 deletions src/MagnumPlugins/TinyGltfImporter/Test/mesh-invalid.gltf
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,26 @@
}
]
},
{
"name": "unexpected tangent type",
"primitives": [
{
"attributes": {
"TANGENT": 0
}
}
]
},
{
"name": "unsupported tangent component type",
"primitives": [
{
"attributes": {
"TANGENT": 5
}
}
]
},
{
"name": "unexpected texcoord type",
"primitives": [
Expand Down
Binary file modified src/MagnumPlugins/TinyGltfImporter/Test/mesh-primitives-types.bin
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -131,66 +131,78 @@ input += [
0, 2, 1, 4, 3, 0
]

# 4. positions normalized unsigned byte, texcoords normalized short; indices unsigned short; line strip
type += '2h3Bx 2h3Bx 2h3Bx 2h3Bx 2h3Bx 6H' # stride = 8
# 4. texcoords normalized short, positions normalized unsigned byte, tangents short; indices unsigned short; line strip
type += '2h4h3Bx 2h4h3Bx 2h4h3Bx 2h4h3Bx 2h4h3Bx 6H' # stride = 16
input += [
S(-0.66666666666666667),
S(-0.93333333333333333),
b(0.8), b(0.4), b(0.2),
S(-0.93333333333333333), S(-0.33333333333333333),
S(-0.66666666666666667), S(1.0),
b(0.8), b(0.4), b(0.2),

S(-0.4),
S(-0.73333333333333333),
b(1.0),
b(0.33333333333333333),
b(0.66666666666666667),
S(-1.0), S(-0.0), S(-0.13333333333333333), S(-1.0),
b(1.0),
b(0.33333333333333333),
b(0.66666666666666667),

S(-0.8), S(-0.2),
b(0.73333333333333333),
b(0.86666666666666667),
b(0.0),
S(-0.2), S(-0.6), S(-0.8), S(1.0),
b(0.73333333333333333),
b(0.86666666666666667),
b(0.0),

S(-0.0),
S(-0.13333333333333333),
b(0.06666666666666667),
b(0.13333333333333333),
b(0.93333333333333333),
S(-0.93333333333333333), S(-0.4), S(-0.73333333333333333), S(-1.0),
b(0.06666666666666667),
b(0.13333333333333333),
b(0.93333333333333333),

S(-0.6),
S(-0.33333333333333333),
b(0.6),
b(0.26666666666666667),
b(0.46666666666666667),
S(-0.4), S(-0.13333333333333333), S(-0.73333333333333333), S(1.0),
b(0.6),
b(0.26666666666666667),
b(0.46666666666666667),

0, 2, 1, 4, 3, 0
]

# 5. positions normalized short, texcoords unsigned byte; triangles
type += '2B3h 2B3h 2B3h 2B3h 2B3h' # stride = 8
# 5. positions normalized short, texcoords unsigned byte, tangents byte; triangles
type += '2B3h4b 2B3h4b 2B3h4b 2B3h4b 2B3h4b' # stride = 12
input += [
75, 13,
S(-0.13333333333333333),
S(-0.33333333333333333),
S(-0.2),
B(-0.93333333333333333), B(-0.33333333333333333),
B(-0.66666666666666667), B(1.0),

98, 22,
S(-0.8),
S(-0.13333333333333333),
S(-0.4),
B(-1.0), B(-0.0), B(-0.13333333333333333), B(-1.0),

15, 125,
S(-1.0),
S(-0.93333333333333333),
S(-0.0),
B(-0.2), B(-0.6), B(-0.8), B(1.0),

12, 33,
S(-0.4),
S(-0.6),
S(-0.33333333333333333),
B(-0.93333333333333333), B(-0.4), B(-0.73333333333333333), B(-1.0),

24, 57,
S(-0.66666666666666667),
S(-0.73333333333333333),
S(-0.93333333333333333)
S(-0.93333333333333333),
B(-0.4), B(-0.13333333333333333), B(-0.73333333333333333), B(1.0)
]

# 6. positions normalized unsigned short, texcoords normalized byte
Expand Down
Loading

0 comments on commit 1cc6b4e

Please sign in to comment.