From 985f3ee6650983582b8612217f236f8c46a274e3 Mon Sep 17 00:00:00 2001 From: RichardTea <31507749+RichardTea@users.noreply.github.com> Date: Fri, 11 Jun 2021 15:17:25 +0100 Subject: [PATCH] Fix glTFv2 texcoord/uv mapping Use the standard property to indicate the UV map index --- code/AssetLib/glTF2/glTF2Exporter.cpp | 21 ++++++----- code/AssetLib/glTF2/glTF2Exporter.h | 2 +- code/AssetLib/glTF2/glTF2Importer.cpp | 3 +- include/assimp/material.h | 4 +-- include/assimp/pbrmaterial.h | 4 +-- test/unit/utglTF2ImportExport.cpp | 50 ++++++++++++++++++++------- 6 files changed, 56 insertions(+), 28 deletions(-) diff --git a/code/AssetLib/glTF2/glTF2Exporter.cpp b/code/AssetLib/glTF2/glTF2Exporter.cpp index 3cb3891b0..7e0966aff 100644 --- a/code/AssetLib/glTF2/glTF2Exporter.cpp +++ b/code/AssetLib/glTF2/glTF2Exporter.cpp @@ -492,11 +492,14 @@ void glTF2Exporter::GetMatTexProp(const aiMaterial& mat, float& prop, const char mat.Get(textureKey.c_str(), tt, slot, prop); } -void glTF2Exporter::GetMatTex(const aiMaterial& mat, Ref& texture, aiTextureType tt, unsigned int slot = 0) +void glTF2Exporter::GetMatTex(const aiMaterial& mat, Ref& texture, unsigned int &texCoord, aiTextureType tt, unsigned int slot = 0) { if (mat.GetTextureCount(tt) > 0) { aiString tex; + // Read texcoord (UV map index) + mat.Get(AI_MATKEY_UVWSRC(tt, slot), texCoord); + if (mat.Get(AI_MATKEY_TEXTURE(tt, slot), tex) == AI_SUCCESS) { std::string path = tex.C_Str(); @@ -572,21 +575,21 @@ void glTF2Exporter::GetMatTex(const aiMaterial& mat, TextureInfo& prop, aiTextur { Ref& texture = prop.texture; - GetMatTex(mat, texture, tt, slot); + GetMatTex(mat, texture, prop.texCoord, tt, slot); - if (texture) { - GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot); - } + //if (texture) { + // GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot); + //} } void glTF2Exporter::GetMatTex(const aiMaterial& mat, NormalTextureInfo& prop, aiTextureType tt, unsigned int slot = 0) { Ref& texture = prop.texture; - GetMatTex(mat, texture, tt, slot); + GetMatTex(mat, texture, prop.texCoord, tt, slot); if (texture) { - GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot); + //GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot); GetMatTexProp(mat, prop.scale, "scale", tt, slot); } } @@ -595,10 +598,10 @@ void glTF2Exporter::GetMatTex(const aiMaterial& mat, OcclusionTextureInfo& prop, { Ref& texture = prop.texture; - GetMatTex(mat, texture, tt, slot); + GetMatTex(mat, texture, prop.texCoord, tt, slot); if (texture) { - GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot); + //GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot); GetMatTexProp(mat, prop.strength, "strength", tt, slot); } } diff --git a/code/AssetLib/glTF2/glTF2Exporter.h b/code/AssetLib/glTF2/glTF2Exporter.h index edc85d998..f5238297f 100644 --- a/code/AssetLib/glTF2/glTF2Exporter.h +++ b/code/AssetLib/glTF2/glTF2Exporter.h @@ -104,7 +104,7 @@ namespace Assimp void GetTexSampler(const aiMaterial& mat, glTF2::Ref texture, aiTextureType tt, unsigned int slot); void GetMatTexProp(const aiMaterial& mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int idx); void GetMatTexProp(const aiMaterial& mat, float& prop, const char* propName, aiTextureType tt, unsigned int idx); - void GetMatTex(const aiMaterial& mat, glTF2::Ref& texture, aiTextureType tt, unsigned int slot); + void GetMatTex(const aiMaterial& mat, glTF2::Ref& texture, unsigned int &texCoord, aiTextureType tt, unsigned int slot); void GetMatTex(const aiMaterial& mat, glTF2::TextureInfo& prop, aiTextureType tt, unsigned int slot); void GetMatTex(const aiMaterial& mat, glTF2::NormalTextureInfo& prop, aiTextureType tt, unsigned int slot); void GetMatTex(const aiMaterial& mat, glTF2::OcclusionTextureInfo& prop, aiTextureType tt, unsigned int slot); diff --git a/code/AssetLib/glTF2/glTF2Importer.cpp b/code/AssetLib/glTF2/glTF2Importer.cpp index b435f111d..aadc9fb16 100644 --- a/code/AssetLib/glTF2/glTF2Importer.cpp +++ b/code/AssetLib/glTF2/glTF2Importer.cpp @@ -165,7 +165,8 @@ inline void SetMaterialTextureProperty(std::vector &embeddedTexIdxs, Asset } mat->AddProperty(&uri, AI_MATKEY_TEXTURE(texType, texSlot)); - mat->AddProperty(&prop.texCoord, 1, AI_MATKEY_GLTF_TEXTURE_TEXCOORD(texType, texSlot)); + const int uvIndex = static_cast(prop.texCoord); + mat->AddProperty(&uvIndex, 1, AI_MATKEY_UVWSRC(texType, texSlot)); if (prop.textureTransformSupported) { aiUVTransform transform; diff --git a/include/assimp/material.h b/include/assimp/material.h index f348da369..2024be07f 100644 --- a/include/assimp/material.h +++ b/include/assimp/material.h @@ -144,9 +144,7 @@ enum aiTextureMapMode { enum aiTextureMapping { /** The mapping coordinates are taken from an UV channel. * - * #AI_MATKEY_UVWSRC property - * - * Specifies from which UV channel + * #AI_MATKEY_UVWSRC property specifies from which UV channel * the texture coordinates are to be taken from (remember, * meshes can have more than one UV channel). */ diff --git a/include/assimp/pbrmaterial.h b/include/assimp/pbrmaterial.h index c67bcc3b8..93e7e3095 100644 --- a/include/assimp/pbrmaterial.h +++ b/include/assimp/pbrmaterial.h @@ -75,7 +75,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_FACTOR "$mat.gltf.materialTransmission.transmissionFactor", 0, 0 //#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_TEXTURE aiTextureType_UNKNOWN, 5 -#define _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE "$tex.file.texCoord" +//#define _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE "$tex.file.texCoord" #define _AI_MATKEY_GLTF_MAPPINGNAME_BASE "$tex.mappingname" #define _AI_MATKEY_GLTF_MAPPINGID_BASE "$tex.mappingid" #define _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE "$tex.mappingfiltermag" @@ -83,7 +83,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define _AI_MATKEY_GLTF_SCALE_BASE "$tex.scale" #define _AI_MATKEY_GLTF_STRENGTH_BASE "$tex.strength" -#define AI_MATKEY_GLTF_TEXTURE_TEXCOORD(type, N) _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE, type, N +//#define AI_MATKEY_GLTF_TEXTURE_TEXCOORD(type, N) _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE, type, N #define AI_MATKEY_GLTF_MAPPINGNAME(type, N) _AI_MATKEY_GLTF_MAPPINGNAME_BASE, type, N #define AI_MATKEY_GLTF_MAPPINGID(type, N) _AI_MATKEY_GLTF_MAPPINGID_BASE, type, N #define AI_MATKEY_GLTF_MAPPINGFILTER_MAG(type, N) _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE, type, N diff --git a/test/unit/utglTF2ImportExport.cpp b/test/unit/utglTF2ImportExport.cpp index ee8b1a742..2c000bb37 100644 --- a/test/unit/utglTF2ImportExport.cpp +++ b/test/unit/utglTF2ImportExport.cpp @@ -603,32 +603,58 @@ TEST_F(utglTF2ImportExport, sceneMetadata) { } TEST_F(utglTF2ImportExport, texcoords) { + Assimp::Importer importer; - const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTexcoords-glTF/boxTexcoords.gltf", - aiProcess_ValidateDataStructure); + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTexcoords-glTF/boxTexcoords.gltf", aiProcess_ValidateDataStructure); + ASSERT_NE(scene, nullptr); + ASSERT_TRUE(scene->HasMaterials()); + const aiMaterial *material = scene->mMaterials[0]; + + aiString path; + unsigned int uvIndex = 255; + aiTextureMapMode modes[2]; + EXPECT_EQ(aiReturn_SUCCESS, material->GetTexture(AI_MATKEY_BASE_COLOR_TEXTURE, &path, nullptr, &uvIndex, nullptr, nullptr, modes)); + EXPECT_STREQ(path.C_Str(), "texture.png"); + EXPECT_EQ(uvIndex, 0); + + uvIndex = 255; + EXPECT_EQ(aiReturn_SUCCESS, material->GetTexture(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE, &path, nullptr, &uvIndex, nullptr, nullptr, modes)); + EXPECT_STREQ(path.C_Str(), "texture.png"); + EXPECT_EQ(uvIndex, 1); +} + +#ifndef ASSIMP_BUILD_NO_EXPORT + +TEST_F(utglTF2ImportExport, texcoords_export) { + { + Assimp::Importer importer; + Assimp::Exporter exporter; + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTexcoords-glTF/boxTexcoords.gltf", aiProcess_ValidateDataStructure); + ASSERT_NE(scene, nullptr); + ASSERT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "glb2", ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTexcoords-glTF/boxTexcoords.gltf_out.glb")); + } + + Assimp::Importer importer; + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTexcoords-glTF/boxTexcoords.gltf", aiProcess_ValidateDataStructure); ASSERT_NE(scene, nullptr); ASSERT_TRUE(scene->HasMaterials()); const aiMaterial *material = scene->mMaterials[0]; aiString path; + unsigned int uvIndex = 255; aiTextureMapMode modes[2]; - EXPECT_EQ(aiReturn_SUCCESS, material->GetTexture(aiTextureType_DIFFUSE, 0, &path, nullptr, nullptr, - nullptr, nullptr, modes)); + EXPECT_EQ(aiReturn_SUCCESS, material->GetTexture(AI_MATKEY_BASE_COLOR_TEXTURE, &path, nullptr, &uvIndex, nullptr, nullptr, modes)); EXPECT_STREQ(path.C_Str(), "texture.png"); - - int uvIndex = -1; - EXPECT_EQ(aiGetMaterialInteger(material, AI_MATKEY_GLTF_TEXTURE_TEXCOORD(aiTextureType_DIFFUSE, 0), &uvIndex), aiReturn_SUCCESS); EXPECT_EQ(uvIndex, 0); - // Using manual macro expansion of AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE here. - // The following works with some but not all compilers: - // #define APPLY(X, Y) X(Y) - // ..., APPLY(AI_MATKEY_GLTF_TEXTURE_TEXCOORD, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE), ... - EXPECT_EQ(aiGetMaterialInteger(material, AI_MATKEY_GLTF_TEXTURE_TEXCOORD(aiTextureType_UNKNOWN, 0), &uvIndex), aiReturn_SUCCESS); + uvIndex = 255; + EXPECT_EQ(aiReturn_SUCCESS, material->GetTexture(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE, &path, nullptr, &uvIndex, nullptr, nullptr, modes)); + EXPECT_STREQ(path.C_Str(), "texture.png"); EXPECT_EQ(uvIndex, 1); } +#endif // ASSIMP_BUILD_NO_EXPORT TEST_F(utglTF2ImportExport, recursive_nodes) { Assimp::Importer importer; const aiScene* scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/RecursiveNodes/RecursiveNodes.gltf", aiProcess_ValidateDataStructure);