Browse Source

Allow empty slots in mTextureCoords (#5636)

* Allow empty slots in aiMesh::mTextureCoords.
1.Explicitly say in documentation that empty slots are allowed (it was unclear).
2.Change GetNumUVChannels() implementation to allow empty slots.
3.Revert fraction of 2da2835b29355a0b8f077fee466aba7a4148c1e1 where empty slots are detected and error logged.

* Fix #5632 by reverting fraction of d6aacefa1ef1219b85028b4038ef7e861c2e9462 where Collada texcoords are renumbered to avoid empty slots.

---------

Co-authored-by: Kim Kulling <[email protected]>
Stepan Hrbek 1 year ago
parent
commit
206839d4f2

+ 4 - 6
code/AssetLib/Collada/ColladaLoader.cpp

@@ -625,16 +625,14 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
     }
 
     // same for texture coords, as many as we have
-    // empty slots are not allowed, need to pack and adjust UV indexes accordingly
-    for (size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
+    for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
         if (pSrcMesh->mTexCoords[a].size() >= pStartVertex + numVertices) {
-            dstMesh->mTextureCoords[real] = new aiVector3D[numVertices];
+            dstMesh->mTextureCoords[a] = new aiVector3D[numVertices];
             for (size_t b = 0; b < numVertices; ++b) {
-                dstMesh->mTextureCoords[real][b] = pSrcMesh->mTexCoords[a][pStartVertex + b];
+                dstMesh->mTextureCoords[a][b] = pSrcMesh->mTexCoords[a][pStartVertex + b];
             }
 
-            dstMesh->mNumUVComponents[real] = pSrcMesh->mNumUVComponents[a];
-            ++real;
+            dstMesh->mNumUVComponents[a] = pSrcMesh->mNumUVComponents[a];
         }
     }
 

+ 1 - 14
code/PostProcessing/ValidateDataStructure.cpp

@@ -371,20 +371,7 @@ void ValidateDSProcess::Validate(const aiMesh *pMesh) {
         ReportWarning("There are unreferenced vertices");
     }
 
-    // texture channel 2 may not be set if channel 1 is zero ...
-    {
-        unsigned int i = 0;
-        for (; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
-            if (!pMesh->HasTextureCoords(i)) break;
-        }
-        for (; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i)
-            if (pMesh->HasTextureCoords(i)) {
-                ReportError("Texture coordinate channel %i exists "
-                            "although the previous channel was nullptr.",
-                        i);
-            }
-    }
-    // the same for the vertex colors
+    // vertex color channel 2 may not be set if channel 1 is zero ...
     {
         unsigned int i = 0;
         for (; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {

+ 7 - 4
include/assimp/mesh.h

@@ -729,8 +729,9 @@ struct aiMesh {
     /**
      * @brief Vertex texture coordinates, also known as UV channels.
      * 
-     * A mesh may contain 0 to AI_MAX_NUMBER_OF_TEXTURECOORDS per
-     * vertex. nullptr if not present. The array is mNumVertices in size.
+     * A mesh may contain 0 to AI_MAX_NUMBER_OF_TEXTURECOORDS channels per
+     * vertex. Used and unused (nullptr) channels may go in any order.
+     * The array is mNumVertices in size.
      */
     C_STRUCT aiVector3D *mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
 
@@ -950,8 +951,10 @@ struct aiMesh {
     //! @return the number of stored uv-channels.
     unsigned int GetNumUVChannels() const {
         unsigned int n(0);
-        while (n < AI_MAX_NUMBER_OF_TEXTURECOORDS && mTextureCoords[n]) {
-            ++n;
+        for (unsigned i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; i++) {
+            if (mTextureCoords[i]) {
+                ++n;
+            }
         }
 
         return n;