diff --git a/doc/changelog-plugins.dox b/doc/changelog-plugins.dox index 7bb87e325..ad7cb1036 100644 --- a/doc/changelog-plugins.dox +++ b/doc/changelog-plugins.dox @@ -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", diff --git a/src/MagnumPlugins/TinyGltfImporter/Test/TinyGltfImporterTest.cpp b/src/MagnumPlugins/TinyGltfImporter/Test/TinyGltfImporterTest.cpp index 9faf8a4a0..670381495 100644 --- a/src/MagnumPlugins/TinyGltfImporter/Test/TinyGltfImporterTest.cpp +++ b/src/MagnumPlugins/TinyGltfImporter/Test/TinyGltfImporterTest.cpp @@ -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} }; @@ -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"}, @@ -1625,7 +1627,7 @@ void TinyGltfImporterTest::meshIndexed() { Containers::arrayView({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(MeshAttribute::Position), @@ -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(MeshAttribute::Tangent), + Containers::arrayView({ + {-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() { @@ -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({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)); diff --git a/src/MagnumPlugins/TinyGltfImporter/Test/mesh-embedded.glb b/src/MagnumPlugins/TinyGltfImporter/Test/mesh-embedded.glb index fc663034d..947ad8afd 100644 Binary files a/src/MagnumPlugins/TinyGltfImporter/Test/mesh-embedded.glb and b/src/MagnumPlugins/TinyGltfImporter/Test/mesh-embedded.glb differ diff --git a/src/MagnumPlugins/TinyGltfImporter/Test/mesh-embedded.gltf b/src/MagnumPlugins/TinyGltfImporter/Test/mesh-embedded.gltf index a23cc6fbd..0a5fb8800 100644 --- a/src/MagnumPlugins/TinyGltfImporter/Test/mesh-embedded.gltf +++ b/src/MagnumPlugins/TinyGltfImporter/Test/mesh-embedded.gltf @@ -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=="}]} \ No newline at end of file +{"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=="}]} \ No newline at end of file diff --git a/src/MagnumPlugins/TinyGltfImporter/Test/mesh-invalid.gltf b/src/MagnumPlugins/TinyGltfImporter/Test/mesh-invalid.gltf index d73f2e84d..048519e9b 100644 --- a/src/MagnumPlugins/TinyGltfImporter/Test/mesh-invalid.gltf +++ b/src/MagnumPlugins/TinyGltfImporter/Test/mesh-invalid.gltf @@ -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": [ diff --git a/src/MagnumPlugins/TinyGltfImporter/Test/mesh-primitives-types.bin b/src/MagnumPlugins/TinyGltfImporter/Test/mesh-primitives-types.bin index 58d13e661..c738070e7 100644 Binary files a/src/MagnumPlugins/TinyGltfImporter/Test/mesh-primitives-types.bin and b/src/MagnumPlugins/TinyGltfImporter/Test/mesh-primitives-types.bin differ diff --git a/src/MagnumPlugins/TinyGltfImporter/Test/mesh-primitives-types.bin.in b/src/MagnumPlugins/TinyGltfImporter/Test/mesh-primitives-types.bin.in index b8fff7f71..c73ed240d 100644 --- a/src/MagnumPlugins/TinyGltfImporter/Test/mesh-primitives-types.bin.in +++ b/src/MagnumPlugins/TinyGltfImporter/Test/mesh-primitives-types.bin.in @@ -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 diff --git a/src/MagnumPlugins/TinyGltfImporter/Test/mesh-primitives-types.gltf b/src/MagnumPlugins/TinyGltfImporter/Test/mesh-primitives-types.gltf index a68a2f670..333ba1d22 100644 --- a/src/MagnumPlugins/TinyGltfImporter/Test/mesh-primitives-types.gltf +++ b/src/MagnumPlugins/TinyGltfImporter/Test/mesh-primitives-types.gltf @@ -58,26 +58,28 @@ ] }, { - "name": "positions normalized unsigned byte, texcoords normalized short; indices unsigned short; line strip", + "name": "positions normalized unsigned byte, tangents short, texcoords normalized short; indices unsigned short; line strip", "primitives": [ { "mode": 3, "attributes": { "TEXCOORD_0": 14, - "POSITION": 15 + "TANGENT": 15, + "POSITION": 16 }, - "indices": 16 + "indices": 17 } ] }, { - "name": "positions normalized short, texcoords unsigned byte; triangles", + "name": "positions normalized short, texcoords unsigned byte, tangents byte; triangles", "primitives": [ { "mode": 4, "attributes": { - "TEXCOORD_0": 17, - "POSITION": 18 + "TEXCOORD_0": 18, + "POSITION": 19, + "TANGENT": 20 } } ] @@ -87,8 +89,8 @@ "primitives": [ { "attributes": { - "POSITION": 19, - "TEXCOORD_0": 20 + "POSITION": 21, + "TEXCOORD_0": 22 } } ] @@ -98,8 +100,8 @@ "primitives": [ { "attributes": { - "POSITION": 21, - "TEXCOORD_0": 22 + "POSITION": 23, + "TEXCOORD_0": 24 } } ] @@ -236,13 +238,22 @@ "name": "15", "bufferView": 6, "byteOffset": 4, + "componentType": 5122, + "normalized": true, + "count": 5, + "type": "VEC4" + }, + { + "name": "16", + "bufferView": 6, + "byteOffset": 12, "componentType": 5121, "normalized": true, "count": 5, "type": "VEC3" }, { - "name": "16", + "name": "17", "bufferView": 7, "byteOffset": 0, "componentType": 5123, @@ -250,7 +261,7 @@ "type": "SCALAR" }, { - "name": "17", + "name": "18", "bufferView": 8, "byteOffset": 0, "componentType": 5121, @@ -258,7 +269,7 @@ "type": "VEC2" }, { - "name": "18", + "name": "19", "bufferView": 8, "byteOffset": 2, "componentType": 5122, @@ -267,7 +278,16 @@ "type": "VEC3" }, { - "name": "19", + "name": "20", + "bufferView": 8, + "byteOffset": 8, + "componentType": 5120, + "normalized": true, + "count": 5, + "type": "VEC4" + }, + { + "name": "21", "bufferView": 9, "byteOffset": 0, "componentType": 5123, @@ -276,7 +296,7 @@ "type": "VEC3" }, { - "name": "20", + "name": "22", "bufferView": 9, "byteOffset": 6, "componentType": 5120, @@ -285,7 +305,7 @@ "type": "VEC2" }, { - "name": "21", + "name": "23", "bufferView": 10, "byteOffset": 0, "componentType": 5120, @@ -294,7 +314,7 @@ "type": "VEC3" }, { - "name": "22", + "name": "24", "bufferView": 10, "byteOffset": 4, "componentType": 5123, @@ -347,40 +367,40 @@ "name": "6", "buffer": 0, "byteOffset": 332, - "byteLength": 40, - "byteStride": 8 + "byteLength": 80, + "byteStride": 16 }, { "name": "7", "buffer": 0, - "byteOffset": 372, + "byteOffset": 412, "byteLength": 12 }, { "name": "8", "buffer": 0, - "byteOffset": 384, - "byteLength": 40, - "byteStride": 8 + "byteOffset": 424, + "byteLength": 60, + "byteStride": 12 }, { "name": "9", "buffer": 0, - "byteOffset": 424, + "byteOffset": 484, "byteLength": 40, "byteStride": 8 }, { "name": "10", "buffer": 0, - "byteOffset": 464, + "byteOffset": 524, "byteLength": 40, "byteStride": 8 } ], "buffers": [ { - "byteLength": 504, + "byteLength": 564, "uri": "mesh-primitives-types.bin" } ] diff --git a/src/MagnumPlugins/TinyGltfImporter/Test/mesh.bin b/src/MagnumPlugins/TinyGltfImporter/Test/mesh.bin index 7d3e73465..7adeacfa1 100644 Binary files a/src/MagnumPlugins/TinyGltfImporter/Test/mesh.bin and b/src/MagnumPlugins/TinyGltfImporter/Test/mesh.bin differ diff --git a/src/MagnumPlugins/TinyGltfImporter/Test/mesh.bin.in b/src/MagnumPlugins/TinyGltfImporter/Test/mesh.bin.in index 8465afee1..713645867 100644 --- a/src/MagnumPlugins/TinyGltfImporter/Test/mesh.bin.in +++ b/src/MagnumPlugins/TinyGltfImporter/Test/mesh.bin.in @@ -1,12 +1,12 @@ -type = '<3Bx18f6f' +type = '<3Bx 3f3f4f 3f3f4f 3f3f4f 2f2f2f' input = [ # indices 0, 1, 2, - # interleaved positions & normals - 1.5, -1.0, -0.5, 0.1, 0.2, 0.3, - -0.5, 2.5, 0.75, 0.4, 0.5, 0.6, - -2.0, 1.0, 0.3, 0.7, 0.8, 0.9, + # interleaved positions, normals & tangents + 1.5, -1.0, -0.5, 0.1, 0.2, 0.3, -0.1, -0.2, -0.3, 1.0, + -0.5, 2.5, 0.75, 0.4, 0.5, 0.6, -0.4, -0.5, -0.6, -1.0, + -2.0, 1.0, 0.3, 0.7, 0.8, 0.9, -0.7, -0.8, -0.9, 1.0, # non-interleaved texture coordinates 0.3, 0.0, diff --git a/src/MagnumPlugins/TinyGltfImporter/Test/mesh.glb b/src/MagnumPlugins/TinyGltfImporter/Test/mesh.glb index fc663034d..947ad8afd 100644 Binary files a/src/MagnumPlugins/TinyGltfImporter/Test/mesh.glb and b/src/MagnumPlugins/TinyGltfImporter/Test/mesh.glb differ diff --git a/src/MagnumPlugins/TinyGltfImporter/Test/mesh.gltf b/src/MagnumPlugins/TinyGltfImporter/Test/mesh.gltf index f0686df98..e928e71dd 100644 --- a/src/MagnumPlugins/TinyGltfImporter/Test/mesh.gltf +++ b/src/MagnumPlugins/TinyGltfImporter/Test/mesh.gltf @@ -20,7 +20,8 @@ { "attributes": { "NORMAL": 2, - "POSITION": 1 + "POSITION": 1, + "TANGENT": 4 }, "indices": 0 } @@ -69,32 +70,39 @@ "componentType": 5126, "count": 3, "type": "VEC2" + }, + { + "bufferView": 1, + "byteOffset": 24, + "componentType": 5126, + "count": 3, + "type": "VEC4" } ], "bufferViews": [ { "buffer": 0, - "byteLength": 3, "byteOffset": 0, + "byteLength": 3, "target": 34963 }, { "buffer": 0, - "byteLength": 72, "byteOffset": 4, - "byteStride": 24, + "byteLength": 120, + "byteStride": 40, "target": 34962 }, { "buffer": 0, + "byteOffset": 124, "byteLength": 24, - "byteOffset": 76, "target": 34962 } ], "buffers": [ { - "byteLength": 100, + "byteLength": 148, "uri": "mesh.bin" } ] diff --git a/src/MagnumPlugins/TinyGltfImporter/TinyGltfImporter.cpp b/src/MagnumPlugins/TinyGltfImporter/TinyGltfImporter.cpp index 76a39a9fc..92da682c6 100644 --- a/src/MagnumPlugins/TinyGltfImporter/TinyGltfImporter.cpp +++ b/src/MagnumPlugins/TinyGltfImporter/TinyGltfImporter.cpp @@ -1080,6 +1080,23 @@ Containers::Optional TinyGltfImporter::doMesh(const UnsignedInt id, Un return Containers::NullOpt; } + } else if(attribute.first == "TANGENT") { + name = MeshAttribute::Tangent; + + if(accessor.type != TINYGLTF_TYPE_VEC4) { + Error{} << "Trade::TinyGltfImporter::mesh(): unexpected TANGENT type" << accessor.type; + return Containers::NullOpt; + } + + if(!(accessor.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT && !accessor.normalized) && + !(accessor.componentType == TINYGLTF_COMPONENT_TYPE_BYTE && accessor.normalized) && + !(accessor.componentType == TINYGLTF_COMPONENT_TYPE_SHORT && accessor.normalized)) { + Error{} << "Trade::TinyGltfImporter::mesh(): unsupported TANGENT component type" + << (accessor.normalized ? "normalized" : "unnormalized") + << accessor.componentType; + return Containers::NullOpt; + } + /* Texture coordinate attribute ends with _0, _1 ... */ } else if(Utility::String::beginsWith(attribute.first, "TEXCOORD")) { name = MeshAttribute::TextureCoordinates;