فهرست منبع

Merge branch 'master' into fix-gcc4.9-compilation

Kim Kulling 4 سال پیش
والد
کامیت
70cc1630fa

+ 5 - 2
code/AssetLib/Assxml/AssxmlFileWriter.cpp

@@ -598,8 +598,11 @@ static void WriteDump(const char *pFile, const char *cmd, const aiScene *scene,
                 if (!mesh->mTextureCoords[a])
                     break;
 
-                ioprintf(io, "\t\t<TextureCoords num=\"%u\" set=\"%u\" num_components=\"%u\"> \n", mesh->mNumVertices,
-                        a, mesh->mNumUVComponents[a]);
+                ioprintf(io, "\t\t<TextureCoords num=\"%u\" set=\"%u\" name=\"%s\" num_components=\"%u\"> \n",
+                         mesh->mNumVertices,
+                         a,
+                         mesh->mTextureCoordsNames[a].C_Str(),
+                         mesh->mNumUVComponents[a]);
 
                 if (!shortened) {
                     if (mesh->mNumUVComponents[a] == 3) {

+ 5 - 5
code/AssetLib/DXF/DXFLoader.cpp

@@ -63,11 +63,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 using namespace Assimp;
 
 // AutoCAD Binary DXF<CR><LF><SUB><NULL>
-const std::string AI_DXF_BINARY_IDENT = std::string("AutoCAD Binary DXF\r\n\x1a\0");
-const size_t AI_DXF_BINARY_IDENT_LEN = 24u;
+static constexpr char AI_DXF_BINARY_IDENT[] = "AutoCAD Binary DXF\r\n\x1a";
+static constexpr size_t AI_DXF_BINARY_IDENT_LEN = sizeof AI_DXF_BINARY_IDENT;
 
 // default vertex color that all uncolored vertices will receive
-const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f));
+static const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f));
 
 // color indices for DXF - 16 are supported, the table is
 // taken directly from the DXF spec.
@@ -156,10 +156,10 @@ void DXFImporter::InternReadFile( const std::string& filename, aiScene* pScene,
     }
 
     // Check whether this is a binary DXF file - we can't read binary DXF files :-(
-    char buff[AI_DXF_BINARY_IDENT_LEN+1] = {0};
+    char buff[AI_DXF_BINARY_IDENT_LEN] = {0};
     file->Read(buff,AI_DXF_BINARY_IDENT_LEN,1);
 
-    if (0 == strncmp(AI_DXF_BINARY_IDENT.c_str(),buff,AI_DXF_BINARY_IDENT_LEN)) {
+    if (0 == memcmp(AI_DXF_BINARY_IDENT,buff,AI_DXF_BINARY_IDENT_LEN)) {
         throw DeadlyImportError("DXF: Binary files are not supported at the moment");
     }
 

+ 2 - 0
code/AssetLib/FBX/FBXConverter.cpp

@@ -1126,6 +1126,8 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
             *out_uv++ = aiVector3D(v.x, v.y, 0.0f);
         }
 
+        out_mesh->mTextureCoordsNames[i] = mesh.GetTextureCoordChannelName(i);
+
         out_mesh->mNumUVComponents[i] = 2;
     }
 

+ 3 - 3
code/AssetLib/FBX/FBXMeshGeometry.cpp

@@ -604,15 +604,15 @@ void MeshGeometry::ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out,
 }
 
 // ------------------------------------------------------------------------------------------------
-static const std::string BinormalIndexToken = "BinormalIndex";
-static const std::string BinormalsIndexToken = "BinormalsIndex";
+static const char * BinormalIndexToken = "BinormalIndex";
+static const char * BinormalsIndexToken = "BinormalsIndex";
 
 void MeshGeometry::ReadVertexDataBinormals(std::vector<aiVector3D>& binormals_out, const Scope& source,
     const std::string& MappingInformationType,
     const std::string& ReferenceInformationType)
 {
     const char * str = source.Elements().count( "Binormals" ) > 0 ? "Binormals" : "Binormal";
-    const char * strIdx = source.Elements().count( "Binormals" ) > 0 ? BinormalsIndexToken.c_str() : BinormalIndexToken.c_str();
+    const char * strIdx = source.Elements().count( "Binormals" ) > 0 ? BinormalsIndexToken : BinormalIndexToken;
     ResolveVertexDataArray(binormals_out,source,MappingInformationType,ReferenceInformationType,
         str,
         strIdx,

+ 3 - 3
code/AssetLib/Ogre/OgreBinarySerializer.cpp

@@ -55,9 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 namespace Assimp {
 namespace Ogre {
 
-const std::string MESH_VERSION_1_8 = "[MeshSerializer_v1.8]";
-const std::string SKELETON_VERSION_1_8 = "[Serializer_v1.80]";
-const std::string SKELETON_VERSION_1_1 = "[Serializer_v1.10]";
+static constexpr auto MESH_VERSION_1_8 = "[MeshSerializer_v1.8]";
+static constexpr auto SKELETON_VERSION_1_8 = "[Serializer_v1.80]";
+static constexpr auto SKELETON_VERSION_1_1 = "[Serializer_v1.10]";
 
 const unsigned short HEADER_CHUNK_ID = 0x1000;
 

+ 8 - 8
code/AssetLib/OpenGEX/OpenGEXImporter.cpp

@@ -749,22 +749,22 @@ enum MeshAttribute {
     TexCoord
 };
 
-static const std::string PosToken = "position";
-static const std::string ColToken = "color";
-static const std::string NormalToken = "normal";
-static const std::string TexCoordToken = "texcoord";
+constexpr auto PosToken = "position";
+constexpr auto ColToken = "color";
+constexpr auto NormalToken = "normal";
+constexpr auto TexCoordToken = "texcoord";
 
 //------------------------------------------------------------------------------------------------
 static MeshAttribute getAttributeByName(const char *attribName) {
     ai_assert(nullptr != attribName);
 
-    if (0 == strncmp(PosToken.c_str(), attribName, PosToken.size())) {
+    if (0 == strcmp(PosToken, attribName)) {
         return Position;
-    } else if (0 == strncmp(ColToken.c_str(), attribName, ColToken.size())) {
+    } else if (0 == strcmp(ColToken, attribName)) {
         return Color;
-    } else if (0 == strncmp(NormalToken.c_str(), attribName, NormalToken.size())) {
+    } else if (0 == strcmp(NormalToken, attribName)) {
         return Normal;
-    } else if (0 == strncmp(TexCoordToken.c_str(), attribName, TexCoordToken.size())) {
+    } else if (0 == strcmp(TexCoordToken, attribName)) {
         return TexCoord;
     }
 

+ 2 - 0
code/AssetLib/glTF2/glTF2Asset.h

@@ -1118,11 +1118,13 @@ public:
         bool KHR_materials_transmission;
         bool KHR_draco_mesh_compression;
         bool FB_ngon_encoding;
+        bool KHR_texture_basisu;
     } extensionsUsed;
 
     //! Keeps info about the required extensions
     struct RequiredExtensions {
         bool KHR_draco_mesh_compression;
+        bool KHR_texture_basisu;
     } extensionsRequired;
 
     AssetMetadata asset;

+ 2 - 0
code/AssetLib/glTF2/glTF2Asset.inl

@@ -1146,6 +1146,7 @@ inline Image::Image() :
 }
 
 inline void Image::Read(Value &obj, Asset &r) {
+    //basisu: no need to handle .ktx2, .basis, load as is
     if (!mDataLength) {
         Value *curUri = FindString(obj, "uri");
         if (nullptr != curUri) {
@@ -2126,6 +2127,7 @@ inline void Asset::ReadExtensionsUsed(Document &doc) {
     CHECK_EXT(KHR_materials_clearcoat);
     CHECK_EXT(KHR_materials_transmission);
     CHECK_EXT(KHR_draco_mesh_compression);
+    CHECK_EXT(KHR_texture_basisu);
 
 #undef CHECK_EXT
 }

+ 13 - 0
code/AssetLib/glTF2/glTF2AssetWriter.inl

@@ -250,6 +250,7 @@ namespace glTF2 {
 
     inline void Write(Value& obj, Image& img, AssetWriter& w)
     {
+        //basisu: no need to handle .ktx2, .basis, write as is
         if (img.bufferView) {
             obj.AddMember("bufferView", img.bufferView->index, w.mAl);
             obj.AddMember("mimeType", Value(img.mimeType, w.mAl).Move(), w.mAl);
@@ -892,10 +893,22 @@ namespace glTF2 {
             if (this->mAsset.extensionsUsed.FB_ngon_encoding) {
                 exts.PushBack(StringRef("FB_ngon_encoding"), mAl);
             }
+            
+            if (this->mAsset.extensionsUsed.KHR_texture_basisu) {
+                exts.PushBack(StringRef("KHR_texture_basisu"), mAl);
+            }
         }
 
         if (!exts.Empty())
             mDoc.AddMember("extensionsUsed", exts, mAl);
+            
+        //basisu extensionRequired
+        Value extsReq;
+        extsReq.SetArray();
+        if (this->mAsset.extensionsUsed.KHR_texture_basisu) {
+            extsReq.PushBack(StringRef("KHR_texture_basisu"), mAl);
+            mDoc.AddMember("extensionsRequired", extsReq, mAl);
+        }
     }
 
     template<class T>

+ 34 - 6
code/AssetLib/glTF2/glTF2Exporter.cpp

@@ -494,7 +494,6 @@ void glTF2Exporter::GetMatTexProp(const aiMaterial* mat, float& prop, const char
 
 void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref<Texture>& texture, aiTextureType tt, unsigned int slot = 0)
 {
-
     if (mat->GetTextureCount(tt) > 0) {
         aiString tex;
 
@@ -507,6 +506,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref<Texture>& texture, aiTe
                     texture = mAsset->textures.Get(it->second);
                 }
 
+                bool useBasisUniversal = false;
                 if (!texture) {
                     std::string texId = mAsset->FindUniqueID("", "texture");
                     texture = mAsset->textures.Create(texId);
@@ -519,18 +519,46 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref<Texture>& texture, aiTe
                         aiTexture* curTex = mScene->mTextures[atoi(&path[1])];
 
                         texture->source->name = curTex->mFilename.C_Str();
-
-                        // The asset has its own buffer, see Image::SetData
-                        texture->source->SetData(reinterpret_cast<uint8_t *>(curTex->pcData), curTex->mWidth, *mAsset);
-
+                        
+                        //basisu: embedded ktx2, bu
                         if (curTex->achFormatHint[0]) {
                             std::string mimeType = "image/";
-                            mimeType += (memcmp(curTex->achFormatHint, "jpg", 3) == 0) ? "jpeg" : curTex->achFormatHint;
+                            if(memcmp(curTex->achFormatHint, "jpg", 3) == 0)
+                                mimeType += "jpeg";
+                            else if(memcmp(curTex->achFormatHint, "ktx", 3) == 0) {
+                                useBasisUniversal = true;
+                                mimeType += "ktx";
+                            }
+                            else if(memcmp(curTex->achFormatHint, "kx2", 3) == 0) {
+                                useBasisUniversal = true;
+                                mimeType += "ktx2";
+                            }
+                            else if(memcmp(curTex->achFormatHint, "bu", 2) == 0) {
+                                useBasisUniversal = true;
+                                mimeType += "basis";
+                            }
+                            else
+                                mimeType += curTex->achFormatHint;
                             texture->source->mimeType = mimeType;
                         }
+                        
+                        // The asset has its own buffer, see Image::SetData
+                        //basisu: "image/ktx2", "image/basis" as is
+                        texture->source->SetData(reinterpret_cast<uint8_t *>(curTex->pcData), curTex->mWidth, *mAsset);
                     }
                     else {
                         texture->source->uri = path;
+                        if(texture->source->uri.find(".ktx")!=std::string::npos ||
+                           texture->source->uri.find(".basis")!=std::string::npos)
+                        {
+                            useBasisUniversal = true;
+                        }
+                    }
+                    
+                    //basisu
+                    if(useBasisUniversal) {
+                        mAsset->extensionsUsed.KHR_texture_basisu = true;
+                        mAsset->extensionsRequired.KHR_texture_basisu = true;
                     }
 
                     GetTexSampler(mat, texture, tt, slot);

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

@@ -1263,7 +1263,7 @@ aiMeshMorphAnim *CreateMeshMorphAnim(glTF2::Asset&, Node &node, AnimationSampler
 
         static const float kMillisecondsFromSeconds = 1000.f;
 
-        if (nullptr != samplers.weight) {
+        if (samplers.weight && samplers.weight->input && samplers.weight->output) {
             float *times = nullptr;
             samplers.weight->input->ExtractData(times);
             float *values = nullptr;
@@ -1476,6 +1476,12 @@ void glTF2Importer::ImportEmbeddedTextures(glTF2::Asset &r) {
                 if (strcmp(ext, "jpeg") == 0) {
                     ext = "jpg";
                 }
+                else if(strcmp(ext, "ktx2") == 0) { //basisu: ktx remains
+                    ext = "kx2";
+                }
+                else if(strcmp(ext, "basis") == 0) { //basisu
+                    ext = "bu";
+                }
 
                 size_t len = strlen(ext);
                 if (len <= 3) {

+ 5 - 5
code/Common/DefaultLogger.cpp

@@ -169,7 +169,7 @@ void Logger::debug(const char *message) {
     // sometimes importers will include data from the input file
     // (i.e. node names) in their messages.
     if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) {
-        return;
+        return OnDebug("<fixme: long message discarded>");
     }
     return OnDebug(message);
 }
@@ -179,7 +179,7 @@ void Logger::verboseDebug(const char *message) {
 
     // SECURITY FIX: see above
     if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) {
-        return;
+        return OnVerboseDebug("<fixme: long message discarded>");
     }
     return OnVerboseDebug(message);
 }
@@ -189,7 +189,7 @@ void Logger::info(const char *message) {
 
     // SECURITY FIX: see above
     if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) {
-        return;
+        return OnInfo("<fixme: long message discarded>");
     }
     return OnInfo(message);
 }
@@ -199,7 +199,7 @@ void Logger::warn(const char *message) {
 
     // SECURITY FIX: see above
     if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) {
-        return;
+        return OnWarn("<fixme: long message discarded>");
     }
     return OnWarn(message);
 }
@@ -208,7 +208,7 @@ void Logger::warn(const char *message) {
 void Logger::error(const char *message) {
     // SECURITY FIX: see above
     if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) {
-        return;
+        return OnError("<fixme: long message discarded>");
     }
     return OnError(message);
 }

+ 3 - 1
code/Common/Exporter.cpp

@@ -343,9 +343,11 @@ const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const cha
         delete pimpl->blob;
         pimpl->blob = nullptr;
     }
+    
+    auto baseName = pProperties ? pProperties->GetPropertyString(AI_CONFIG_EXPORT_BLOB_NAME, AI_BLOBIO_MAGIC) : AI_BLOBIO_MAGIC;
 
     std::shared_ptr<IOSystem> old = pimpl->mIOSystem;
-    BlobIOSystem* blobio = new BlobIOSystem();
+    BlobIOSystem *blobio = new BlobIOSystem(baseName);
     pimpl->mIOSystem = std::shared_ptr<IOSystem>( blobio );
 
     if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName(), pPreprocessing, pProperties)) {

+ 24 - 8
include/assimp/BlobIOSystem.h

@@ -194,8 +194,14 @@ class BlobIOSystem : public IOSystem {
     friend class BlobIOStream;
     typedef std::pair<std::string, aiExportDataBlob *> BlobEntry;
 
+
 public:
-    BlobIOSystem() {
+    BlobIOSystem() :
+            baseName{AI_BLOBIO_MAGIC} {
+    }
+
+    BlobIOSystem(const std::string &baseName) :
+            baseName(baseName) {
     }
 
     virtual ~BlobIOSystem() {
@@ -207,27 +213,32 @@ public:
 public:
     // -------------------------------------------------------------------
     const char *GetMagicFileName() const {
-        return AI_BLOBIO_MAGIC;
+        return baseName.c_str();
     }
 
     // -------------------------------------------------------------------
     aiExportDataBlob *GetBlobChain() {
+        const auto magicName = std::string(this->GetMagicFileName());
+        const bool hasBaseName = baseName != AI_BLOBIO_MAGIC;
+
         // one must be the master
         aiExportDataBlob *master = nullptr, *cur;
+
         for (const BlobEntry &blobby : blobs) {
-            if (blobby.first == AI_BLOBIO_MAGIC) {
+            if (blobby.first == magicName) {
                 master = blobby.second;
+                master->name.Set(hasBaseName ? blobby.first : "");
                 break;
             }
         }
+
         if (!master) {
             ASSIMP_LOG_ERROR("BlobIOSystem: no data written or master file was not closed properly.");
             return nullptr;
         }
 
-        master->name.Set("");
-
         cur = master;
+
         for (const BlobEntry &blobby : blobs) {
             if (blobby.second == master) {
                 continue;
@@ -236,9 +247,13 @@ public:
             cur->next = blobby.second;
             cur = cur->next;
 
-            // extract the file extension from the file written
-            const std::string::size_type s = blobby.first.find_first_of('.');
-            cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s + 1));
+            if (hasBaseName) {
+                cur->name.Set(blobby.first);
+            } else {
+                // extract the file extension from the file written
+                const std::string::size_type s = blobby.first.find_first_of('.');
+                cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s + 1));
+            }
         }
 
         // give up blob ownership
@@ -283,6 +298,7 @@ private:
     }
 
 private:
+    std::string baseName;
     std::set<std::string> created;
     std::vector<BlobEntry> blobs;
 };

+ 1 - 1
include/assimp/camera.h

@@ -137,7 +137,7 @@ struct aiCamera
      */
     C_STRUCT aiVector3D mLookAt;
 
-    /** Half horizontal field of view angle, in radians.
+    /** Horizontal field of view angle, in radians.
      *
      *  The field of view angle is the angle between the center
      *  line of the screen and the left or right border.

+ 16 - 10
include/assimp/cexport.h

@@ -205,16 +205,22 @@ struct aiExportDataBlob {
     void *data;
 
     /** Name of the blob. An empty string always
-        indicates the first (and primary) blob,
-        which contains the actual file data.
-        Any other blobs are auxiliary files produced
-        by exporters (i.e. material files). Existence
-        of such files depends on the file format. Most
-        formats don't split assets across multiple files.
-
-        If used, blob names usually contain the file
-        extension that should be used when writing
-        the data to disc.
+      * indicates the first (and primary) blob,
+      * which contains the actual file data.
+      * Any other blobs are auxiliary files produced
+      * by exporters (i.e. material files). Existence
+      * of such files depends on the file format. Most
+      * formats don't split assets across multiple files.
+      *
+      * If used, blob names usually contain the file
+      * extension that should be used when writing
+      * the data to disc.
+      *
+      * The blob names generated can be influenced by
+      * setting the #AI_CONFIG_EXPORT_BLOB_NAME export
+      * property to the name that is used for the master
+      * blob. All other names are typically derived from
+      * the base name, by the file format exporter.
      */
     C_STRUCT aiString name;
 

+ 17 - 0
include/assimp/config.h.in

@@ -1075,6 +1075,23 @@ enum aiComponent
  */
 #define AI_CONFIG_EXPORT_POINT_CLOUDS "EXPORT_POINT_CLOUDS"
 
+/**
+ * @brief Specifies the blob name, assimp uses for exporting.
+ * 
+ * Some formats require auxiliary files to be written, that need to be linked back into 
+ * the original file. For example, OBJ files export materials to a separate MTL file and
+ * use the `mtllib` keyword to reference this file.
+ * 
+ * When exporting blobs using #ExportToBlob, assimp does not know the name of the blob
+ * file and thus outputs `mtllib $blobfile.mtl`, which might not be desired, since the 
+ * MTL file might be called differently. 
+ * 
+ * This property can be used to give the exporter a hint on how to use the magic 
+ * `$blobfile` keyword. If the exporter detects the keyword and is provided with a name
+ * for the blob, it instead uses this name.
+ */
+#define AI_CONFIG_EXPORT_BLOB_NAME "EXPORT_BLOB_NAME"
+
 /**
  *  @brief  Specifies a gobal key factor for scale, float value
  */

+ 4 - 0
include/assimp/mesh.h

@@ -674,6 +674,10 @@ struct aiMesh {
     */
     C_STRUCT aiVector3D *mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
 
+    /** Vertex stream names.
+     */
+    C_STRUCT aiString mTextureCoordsNames[AI_MAX_NUMBER_OF_TEXTURECOORDS];
+
     /** Specifies the number of components for a given UV channel.
     * Up to three channels are supported (UVW, for accessing volume
     * or cube maps). If the value is 2 for a given channel n, the