diff --git a/code/AssetLib/3DS/3DSLoader.cpp b/code/AssetLib/3DS/3DSLoader.cpp index aa29956df..fc8758c2b 100644 --- a/code/AssetLib/3DS/3DSLoader.cpp +++ b/code/AssetLib/3DS/3DSLoader.cpp @@ -103,10 +103,6 @@ Discreet3DSImporter::Discreet3DSImporter() : // empty } -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -Discreet3DSImporter::~Discreet3DSImporter() = default; - // ------------------------------------------------------------------------------------------------ // Returns whether the class can handle the format of the given file. bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { diff --git a/code/AssetLib/3DS/3DSLoader.h b/code/AssetLib/3DS/3DSLoader.h index 6bd73f412..c579507e0 100644 --- a/code/AssetLib/3DS/3DSLoader.h +++ b/code/AssetLib/3DS/3DSLoader.h @@ -59,7 +59,6 @@ struct aiNode; namespace Assimp { - using namespace D3DS; // --------------------------------------------------------------------------------- @@ -68,7 +67,7 @@ using namespace D3DS; class Discreet3DSImporter : public BaseImporter { public: Discreet3DSImporter(); - ~Discreet3DSImporter() override; + ~Discreet3DSImporter() override = default; // ------------------------------------------------------------------- /** Returns whether the class can handle the format of the given file. diff --git a/code/AssetLib/FBX/FBXImporter.cpp b/code/AssetLib/FBX/FBXImporter.cpp index 56e0f38e9..32631996e 100644 --- a/code/AssetLib/FBX/FBXImporter.cpp +++ b/code/AssetLib/FBX/FBXImporter.cpp @@ -95,7 +95,7 @@ FBXImporter::FBXImporter() = default; // Returns whether the class can handle the format of the given file. bool FBXImporter::CanRead(const std::string & pFile, IOSystem * pIOHandler, bool /*checkSig*/) const { // at least ASCII-FBX files usually have a 'FBX' somewhere in their head - static const char *tokens[] = { "fbx" }; + static const char *tokens[] = { " \n\r\n " }; return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens)); } diff --git a/code/AssetLib/IQM/IQMImporter.cpp b/code/AssetLib/IQM/IQMImporter.cpp index 139b490d8..392ed1193 100644 --- a/code/AssetLib/IQM/IQMImporter.cpp +++ b/code/AssetLib/IQM/IQMImporter.cpp @@ -100,13 +100,6 @@ bool IQMImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c if (!pIOHandler) { return true; } - /* - * don't use CheckMagicToken because that checks with swapped bytes too, leading to false - * positives. This magic is not uint32_t, but char[4], so memcmp is the best way - - const char* tokens[] = {"3DMO", "3dmo"}; - return CheckMagicToken(pIOHandler,pFile,tokens,2,0,4); - */ std::unique_ptr pStream(pIOHandler->Open(pFile, "rb")); unsigned char data[15]; if (!pStream || 15 != pStream->Read(data, 1, 15)) { diff --git a/code/AssetLib/Obj/ObjFileImporter.cpp b/code/AssetLib/Obj/ObjFileImporter.cpp index 173ef2074..73924f86a 100644 --- a/code/AssetLib/Obj/ObjFileImporter.cpp +++ b/code/AssetLib/Obj/ObjFileImporter.cpp @@ -78,7 +78,9 @@ using namespace std; ObjFileImporter::ObjFileImporter() : m_Buffer(), m_pRootObject(nullptr), - m_strAbsPath(std::string(1, DefaultIOSystem().getOsSeparator())) {} + m_strAbsPath(std::string(1, DefaultIOSystem().getOsSeparator())) { + // empty +} // ------------------------------------------------------------------------------------------------ // Destructor. @@ -102,7 +104,7 @@ const aiImporterDesc *ObjFileImporter::GetInfo() const { // Obj-file import implementation void ObjFileImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSystem *pIOHandler) { // Read file into memory - static const std::string mode = "rb"; + static constexpr char mode[] = "rb"; auto streamCloser = [&](IOStream *pStream) { pIOHandler->Close(pStream); }; diff --git a/code/AssetLib/XGL/XGLLoader.cpp b/code/AssetLib/XGL/XGLLoader.cpp index 04e303370..1d3cf9eb4 100644 --- a/code/AssetLib/XGL/XGLLoader.cpp +++ b/code/AssetLib/XGL/XGLLoader.cpp @@ -3,7 +3,7 @@ Open Asset Import Library (assimp) --------------------------------------------------------------------------- -Copyright (c) 2006-2022, assimp team +Copyright (c) 2006-2023, assimp team All rights reserved. @@ -56,62 +56,43 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -//#include -//#include -using namespace Assimp; +namespace Assimp { -namespace Assimp { // this has to be in here because LogFunctions is in ::Assimp +static constexpr uint32_t ErrorId = ~0u; template <> const char *LogFunctions::Prefix() { return "XGL: "; } -} // namespace Assimp - -static const aiImporterDesc desc = { - "XGL Importer", - "", - "", - "", - aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportCompressedFlavour, - 0, - 0, - 0, - 0, - "xgl zgl" -}; +static constexpr aiImporterDesc desc = { + "XGL Importer", "", "", "", + aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportCompressedFlavour, + 0, 0, 0, 0, "xgl zgl"}; // ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -XGLImporter::XGLImporter() : - mXmlParser(nullptr), - m_scene(nullptr) { +XGLImporter::XGLImporter() : mXmlParser(nullptr), m_scene(nullptr) { // empty } // ------------------------------------------------------------------------------------------------ -// Destructor, private as well XGLImporter::~XGLImporter() { delete mXmlParser; } // ------------------------------------------------------------------------------------------------ -// Returns whether the class can handle the format of the given file. bool XGLImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { static const char *tokens[] = { "", "", "" }; return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens)); } // ------------------------------------------------------------------------------------------------ -// Get a list of all file extensions which are handled by this class const aiImporterDesc *XGLImporter::GetInfo() const { return &desc; } // ------------------------------------------------------------------------------------------------ -// Imports the given file into the given scene structure. void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { #ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL std::vector uncompressed; @@ -159,7 +140,7 @@ void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy std::vector &meshes = scope.meshes_linear; std::vector &materials = scope.materials_linear; - if (!meshes.size() || !materials.size()) { + if (meshes.empty() || materials.empty()) { ThrowException("failed to extract data from XGL file, no meshes loaded"); } @@ -199,9 +180,10 @@ void XGLImporter::ReadWorld(XmlNode &node, TempScope &scope) { } aiNode *const nd = ReadObject(node, scope); - if (!nd) { + if (nd == nullptr) { ThrowException("failure reading "); } + if (nd->mName.length == 0) { nd->mName.Set("WORLD"); } @@ -254,15 +236,19 @@ aiNode *XGLImporter::ReadObject(XmlNode &node, TempScope &scope) { const std::string &s = ai_stdStrToLower(child.name()); if (s == "mesh") { const size_t prev = scope.meshes_linear.size(); - bool empty; - if (ReadMesh(child, scope, empty)) { + if (ReadMesh(child, scope)) { const size_t newc = scope.meshes_linear.size(); for (size_t i = 0; i < newc - prev; ++i) { meshes.push_back(static_cast(i + prev)); } + } else { + printf("skipping empty mesh\n"); } } else if (s == "mat") { - ReadMaterial(child, scope); + const uint32_t matId = ReadMaterial(child, scope); + if (matId == ErrorId) { + ThrowException("Invalid material id detected."); + } } else if (s == "object") { children.push_back(ReadObject(child, scope)); } else if (s == "objectref") { @@ -438,18 +424,25 @@ aiMesh *XGLImporter::ToOutputMesh(const TempMaterialMesh &m) { return mesh.release(); } -// ------------------------------------------------------------------------------------------------ -bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope, bool &empty) { - TempMesh t; +// ------------------------------------------------------------------------------------------------ +inline static unsigned int generateMeshId(unsigned int meshId, bool nor, bool uv) { + unsigned int currentMeshId = meshId | ((nor ? 1 : 0) << 31) | ((uv ? 1 : 0) << 30); + return currentMeshId; +} + +// ------------------------------------------------------------------------------------------------ +bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope) { + TempMesh t; + uint32_t matId = 99999; + bool mesh_created = false; std::map bymat; const unsigned int mesh_id = ReadIDAttr(node); - bool empty_mesh = true; for (XmlNode &child : node.children()) { const std::string &s = ai_stdStrToLower(child.name()); if (s == "mat") { - ReadMaterial(child, scope); + matId = ReadMaterial(child, scope); } else if (s == "p") { pugi::xml_attribute attr = child.attribute("ID"); if (attr.empty()) { @@ -477,66 +470,41 @@ bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope, bool &empty) { } else if (s == "f" || s == "l" || s == "p") { const unsigned int vcount = s == "f" ? 3 : (s == "l" ? 2 : 1); - unsigned int mid = ~0u; - TempFace tf[3]; + unsigned int meshId = ErrorId; + TempFace tempFace[3] = {}; bool has[3] = { false }; - for (XmlNode &sub_child : child.children()) { - const std::string &scn = ai_stdStrToLower(sub_child.name()); - if (scn == "fv1" || scn == "lv1" || scn == "pv1") { - ReadFaceVertex(sub_child, t, tf[0]); - has[0] = true; - } else if (scn == "fv2" || scn == "lv2") { - ReadFaceVertex(sub_child, t, tf[1]); - has[1] = true; - } else if (scn == "fv3") { - ReadFaceVertex(sub_child, t, tf[2]); - has[2] = true; - } else if (scn == "mat") { - if (mid != ~0u) { - LogWarn("only one material tag allowed per "); - } - mid = ResolveMaterialRef(sub_child, scope); - } else if (scn == "matref") { - if (mid != ~0u) { - LogWarn("only one material tag allowed per "); - } - mid = ResolveMaterialRef(sub_child, scope); - } - } - if (has[0] || has[1] || has[2]) { - empty_mesh = false; - } - - if (mid == ~0u) { + meshId = ReadVertices(child, t, tempFace, has, meshId, scope); + if (meshId == ErrorId) { ThrowException("missing material index"); } - bool nor = false; - bool uv = false; + bool nor = false, uv = false; for (unsigned int i = 0; i < vcount; ++i) { if (!has[i]) { ThrowException("missing face vertex data"); } - nor = nor || tf[i].has_normal; - uv = uv || tf[i].has_uv; + nor = nor || tempFace[i].has_normal; + uv = uv || tempFace[i].has_uv; } - if (mid >= (1 << 30)) { + if (meshId >= (1 << 30)) { LogWarn("material indices exhausted, this may cause errors in the output"); } - unsigned int meshId = mid | ((nor ? 1 : 0) << 31) | ((uv ? 1 : 0) << 30); + const unsigned int currentMeshId = generateMeshId(meshId, nor, uv); - TempMaterialMesh &mesh = bymat[meshId]; - mesh.matid = mid; + // Generate the temp mesh + TempMaterialMesh &mesh = bymat[currentMeshId]; + mesh.matid = meshId; + mesh_created = true; for (unsigned int i = 0; i < vcount; ++i) { - mesh.positions.push_back(tf[i].pos); + mesh.positions.push_back(tempFace[i].pos); if (nor) { - mesh.normals.push_back(tf[i].normal); + mesh.normals.push_back(tempFace[i].normal); } if (uv) { - mesh.uvs.push_back(tf[i].uv); + mesh.uvs.push_back(tempFace[i].uv); } mesh.pflags |= 1 << (vcount - 1); @@ -546,25 +514,59 @@ bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope, bool &empty) { } } - // finally extract output meshes and add them to the scope - using pairt = std::pair; - for (const pairt &p : bymat) { - aiMesh *const m = ToOutputMesh(p.second); - scope.meshes_linear.push_back(m); - - // if this is a definition, keep it on the stack - if (mesh_id != ~0u) { - scope.meshes.insert(std::pair(mesh_id, m)); - } - } - if (empty_mesh) { - LogWarn("Mesh is empty, skipping."); - empty = empty_mesh; - return false; + if (!mesh_created) { + TempMaterialMesh &mesh = bymat[mesh_id]; + mesh.matid = matId; } + // finally extract output meshes and add them to the scope + AppendOutputMeshes(bymat, scope, mesh_id); + // no id == not a reference, insert this mesh right *here* - return mesh_id == ~0u; + return mesh_id == ErrorId; +} + +// ---------------------------------------------------------------------------------------------- +void XGLImporter::AppendOutputMeshes(std::map bymat, TempScope &scope, + const unsigned int mesh_id) { + using pairt = std::pair; + for (const pairt &p : bymat) { + aiMesh *const m = ToOutputMesh(p.second); + scope.meshes_linear.push_back(m); + + // if this is a definition, keep it on the stack + if (mesh_id != ErrorId) { + scope.meshes.insert(std::pair(mesh_id, m)); + } + } +} + +// ---------------------------------------------------------------------------------------------- +unsigned int XGLImporter::ReadVertices(XmlNode &child, TempMesh t, TempFace *tf, bool *has, unsigned int mid, TempScope &scope) { + for (XmlNode &sub_child : child.children()) { + const std::string &scn = ai_stdStrToLower(sub_child.name()); + if (scn == "fv1" || scn == "lv1" || scn == "pv1") { + ReadFaceVertex(sub_child, t, tf[0]); + has[0] = true; + } else if (scn == "fv2" || scn == "lv2") { + ReadFaceVertex(sub_child, t, tf[1]); + has[1] = true; + } else if (scn == "fv3") { + ReadFaceVertex(sub_child, t, tf[2]); + has[2] = true; + } else if (scn == "mat") { + if (mid != ErrorId) { + LogWarn("only one material tag allowed per "); + } + mid = ResolveMaterialRef(sub_child, scope); + } else if (scn == "matref") { + if (mid != ErrorId) { + LogWarn("only one material tag allowed per "); + } + mid = ResolveMaterialRef(sub_child, scope); + } + } + return mid; } // ---------------------------------------------------------------------------------------------- @@ -598,10 +600,10 @@ unsigned int XGLImporter::ResolveMaterialRef(XmlNode &node, TempScope &scope) { } // ------------------------------------------------------------------------------------------------ -void XGLImporter::ReadMaterial(XmlNode &node, TempScope &scope) { +unsigned int XGLImporter::ReadMaterial(XmlNode &node, TempScope &scope) { const unsigned int mat_id = ReadIDAttr(node); - auto *mat(new aiMaterial); + auto *mat = new aiMaterial; for (XmlNode &child : node.children()) { const std::string &s = ai_stdStrToLower(child.name()); if (s == "amb") { @@ -627,6 +629,8 @@ void XGLImporter::ReadMaterial(XmlNode &node, TempScope &scope) { scope.materials[mat_id] = mat; scope.materials_linear.push_back(mat); + + return mat_id; } // ---------------------------------------------------------------------------------------------- @@ -683,7 +687,7 @@ unsigned int XGLImporter::ReadIDAttr(XmlNode &node) { } } - return ~0u; + return ErrorId; } // ------------------------------------------------------------------------------------------------ @@ -712,14 +716,14 @@ unsigned int XGLImporter::ReadIndexFromText(XmlNode &node) { const char *s = v.c_str(); if (!SkipSpaces(&s)) { LogError("unexpected EOL, failed to parse index element"); - return ~0u; + return ErrorId; } - const char *se; + const char *se = nullptr; const unsigned int t = strtoul10(s, &se); if (se == s) { LogError("failed to read index"); - return ~0u; + return ErrorId; } return t; @@ -786,4 +790,6 @@ aiColor3D XGLImporter::ReadCol3(XmlNode &node) { return aiColor3D(v.x, v.y, v.z); } +} // namespace Assimp + #endif // ASSIMP_BUILD_NO_XGL_IMPORTER diff --git a/code/AssetLib/XGL/XGLLoader.h b/code/AssetLib/XGL/XGLLoader.h index ae7ccddc2..2f0f14200 100644 --- a/code/AssetLib/XGL/XGLLoader.h +++ b/code/AssetLib/XGL/XGLLoader.h @@ -69,12 +69,14 @@ namespace Assimp { */ class XGLImporter : public BaseImporter, public LogFunctions { public: + /// @brief The class constructor. XGLImporter(); + + /// @brief The class destructor. ~XGLImporter() override; - // ------------------------------------------------------------------- - /** Returns whether the class can handle the format of the given file. - * See BaseImporter::CanRead() for details. */ + /// @brief Returns whether the class can handle the format of the given file. + /// @see BaseImporter::CanRead() for details. */ bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override; @@ -92,10 +94,7 @@ protected: private: struct TempScope { - TempScope() : - light() { - // empty - } + TempScope() : light() {} ~TempScope() { for (aiMesh *m : meshes_linear) { @@ -145,9 +144,7 @@ private: }; struct TempMaterialMesh { - TempMaterialMesh() : - pflags(), - matid() { + TempMaterialMesh() : pflags(), matid() { // empty } @@ -160,9 +157,7 @@ private: }; struct TempFace { - TempFace() : - has_uv(), - has_normal() { + TempFace() : has_uv(), has_normal() { // empty } @@ -175,26 +170,25 @@ private: private: void Cleanup(); - std::string GetElementName(); bool ReadElement(); bool ReadElementUpToClosing(const char *closetag); bool SkipToText(); unsigned int ReadIDAttr(XmlNode &node); - void ReadWorld(XmlNode &node, TempScope &scope); void ReadLighting(XmlNode &node, TempScope &scope); aiLight *ReadDirectionalLight(XmlNode &node); aiNode *ReadObject(XmlNode &node, TempScope &scope); - bool ReadMesh(XmlNode &node, TempScope &scope, bool &empty); - void ReadMaterial(XmlNode &node, TempScope &scope); + bool ReadMesh(XmlNode &node, TempScope &scope); + void AppendOutputMeshes(std::map bymat, TempScope &scope, const unsigned int mesh_id); + unsigned int ReadVertices(XmlNode &child, TempMesh t, TempFace *tf, bool *has, unsigned int mid, TempScope &scope); + unsigned int ReadMaterial(XmlNode &node, TempScope &scope); aiVector2D ReadVec2(XmlNode &node); aiVector3D ReadVec3(XmlNode &node); aiColor3D ReadCol3(XmlNode &node); aiMatrix4x4 ReadTrafo(XmlNode &node); unsigned int ReadIndexFromText(XmlNode &node); float ReadFloat(XmlNode &node); - aiMesh *ToOutputMesh(const TempMaterialMesh &m); void ReadFaceVertex(XmlNode &node, const TempMesh &t, TempFace &out); unsigned int ResolveMaterialRef(XmlNode &node, TempScope &scope); diff --git a/code/Common/Compression.cpp b/code/Common/Compression.cpp index 3bf306dee..a6a7be7e4 100644 --- a/code/Common/Compression.cpp +++ b/code/Common/Compression.cpp @@ -66,6 +66,10 @@ Compression::Compression() : Compression::~Compression() { ai_assert(mImpl != nullptr); + if (mImpl->mOpen) { + close(); + } + delete mImpl; } @@ -124,7 +128,7 @@ static int getFlushMode(Compression::FlushMode flush) { return z_flush; } -constexpr size_t MYBLOCK = 32786; +static constexpr size_t MYBLOCK = 32786; size_t Compression::decompress(const void *data, size_t in, std::vector &uncompressed) { ai_assert(mImpl != nullptr); diff --git a/contrib/zlib/zconf.h.included b/contrib/zlib/zconf.h.included index 352f552b8..2271dc5f5 100644 --- a/contrib/zlib/zconf.h.included +++ b/contrib/zlib/zconf.h.included @@ -40,6 +40,9 @@ # define crc32 z_crc32 # define crc32_combine z_crc32_combine # define crc32_combine64 z_crc32_combine64 +# define crc32_combine_gen z_crc32_combine_gen +# define crc32_combine_gen64 z_crc32_combine_gen64 +# define crc32_combine_op z_crc32_combine_op # define crc32_z z_crc32_z # define deflate z_deflate # define deflateBound z_deflateBound @@ -351,6 +354,9 @@ # ifdef FAR # undef FAR # endif +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif # include /* No need for _export, use ZLIB.DEF instead. */ /* For complete Windows compatibility, use WINAPI, not __stdcall. */ @@ -469,11 +475,18 @@ typedef uLong FAR uLongf; # undef _LARGEFILE64_SOURCE #endif -#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) -# define Z_HAVE_UNISTD_H +#ifndef Z_HAVE_UNISTD_H +# ifdef __WATCOMC__ +# define Z_HAVE_UNISTD_H +# endif +#endif +#ifndef Z_HAVE_UNISTD_H +# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32) +# define Z_HAVE_UNISTD_H +# endif #endif #ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# if defined(Z_HAVE_UNISTD_H) # include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ # ifdef VMS # include /* for off_t */