浏览代码

Fix glTFv2 texcoord/uv mapping

Use the standard property to indicate the UV map index
RichardTea 4 年之前
父节点
当前提交
985f3ee665

+ 12 - 9
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>& texture, aiTextureType tt, unsigned int slot = 0)
+void glTF2Exporter::GetMatTex(const aiMaterial& mat, Ref<Texture>& 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>& 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>& 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>& 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);
     }
 }

+ 1 - 1
code/AssetLib/glTF2/glTF2Exporter.h

@@ -104,7 +104,7 @@ namespace Assimp
         void GetTexSampler(const aiMaterial& mat, glTF2::Ref<glTF2::Texture> 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<glTF2::Texture>& texture, aiTextureType tt, unsigned int slot);
+        void GetMatTex(const aiMaterial& mat, glTF2::Ref<glTF2::Texture>& 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);

+ 2 - 1
code/AssetLib/glTF2/glTF2Importer.cpp

@@ -165,7 +165,8 @@ inline void SetMaterialTextureProperty(std::vector<int> &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<int>(prop.texCoord);
+        mat->AddProperty(&uvIndex, 1, AI_MATKEY_UVWSRC(texType, texSlot));
 
         if (prop.textureTransformSupported) {
             aiUVTransform transform;

+ 1 - 3
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).
     */

+ 2 - 2
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

+ 38 - 12
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(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");
+    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"));
+    }
 
-    int uvIndex = -1;
-    EXPECT_EQ(aiGetMaterialInteger(material, AI_MATKEY_GLTF_TEXTURE_TEXCOORD(aiTextureType_DIFFUSE, 0), &uvIndex), aiReturn_SUCCESS);
+    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(AI_MATKEY_BASE_COLOR_TEXTURE, &path, nullptr, &uvIndex, nullptr, nullptr, modes));
+    EXPECT_STREQ(path.C_Str(), "texture.png");
     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);