From a0c29202befa73137f6b74f3b60860bb9171ac15 Mon Sep 17 00:00:00 2001 From: Jackie9527 <80555200+Jackie9527@users.noreply.github.com> Date: Thu, 2 Mar 2023 21:12:35 +0800 Subject: [PATCH 01/21] Add build options to fix issues with clang 15. Signed-off-by: Jackie9527 <80555200+Jackie9527@users.noreply.github.com> --- code/CMakeLists.txt | 66 ++++++++++++++++++++++++++++++++++++- contrib/zlib/CMakeLists.txt | 10 +++++- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index a098f3e85..d8e03bca4 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -1188,7 +1188,71 @@ TARGET_USE_COMMON_OUTPUT_DIRECTORY(assimp) IF (ASSIMP_WARNINGS_AS_ERRORS) MESSAGE(STATUS "Treating all warnings as errors (for assimp library only)") IF (MSVC) - TARGET_COMPILE_OPTIONS(assimp PRIVATE /W4 /WX) + + IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl + TARGET_COMPILE_OPTIONS(assimp PRIVATE -Wall -Werror + -Wno-unused-function + -Wno-microsoft-enum-value + -Wno-switch-enum + -Wno-covered-switch-default + -Wno-reserved-identifier + -Wno-c++98-compat-pedantic + -Wno-c++98-compat + -Wno-documentation + -Wno-documentation-unknown-command + -Wno-deprecated-dynamic-exception-spec + -Wno-undef + -Wno-suggest-destructor-override + -Wno-suggest-override + -Wno-inconsistent-missing-destructor-override + -Wno-zero-as-null-pointer-constant + -Wno-global-constructors + -Wno-exit-time-destructors + -Wno-extra-semi-stmt + -Wno-missing-prototypes + -Wno-old-style-cast + -Wno-cast-align + -Wno-cast-qual + -Wno-float-equal + -Wno-implicit-int-float-conversion + -Wno-sign-conversion + -Wno-implicit-float-conversion + -Wno-implicit-int-conversion + -Wno-float-conversion + -Wno-double-promotion + -Wno-unused-macros + -Wno-disabled-macro-expansion + -Wno-shadow-field-in-constructor + -Wno-shadow-field + -Wno-shadow + -Wno-language-extension-token + -Wno-header-hygiene + -Wno-tautological-value-range-compare + -Wno-tautological-type-limit-compare + -Wno-missing-noreturn + -Wno-missing-variable-declarations + -Wno-extra-semi + -Wno-nonportable-system-include-path + -Wno-undefined-reinterpret-cast + -Wno-shift-sign-overflow + -Wno-deprecated-copy-with-user-provided-dtor + -Wno-deprecated-copy-with-dtor + -Wno-deprecated + -Wno-format-nonliteral + -Wno-format-non-iso + -Wno-comma + -Wno-unreachable-code-break + -Wno-unreachable-code-return + -Wno-unreachable-code + -Wno-implicit-fallthrough + -Wno-unused-template + -Wno-undefined-func-template + -Wno-nested-anon-types + -Wno-declaration-after-statement + ) + ELSE() + TARGET_COMPILE_OPTIONS(assimp PRIVATE /W4 /WX) + ENDIF() ELSE() TARGET_COMPILE_OPTIONS(assimp PRIVATE -Wall -Werror) ENDIF() diff --git a/contrib/zlib/CMakeLists.txt b/contrib/zlib/CMakeLists.txt index 469151ff6..5bc2d6065 100644 --- a/contrib/zlib/CMakeLists.txt +++ b/contrib/zlib/CMakeLists.txt @@ -76,7 +76,15 @@ if(MSVC) set(CMAKE_DEBUG_POSTFIX "d") add_definitions(-D_CRT_SECURE_NO_DEPRECATE) add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-non-prototype") + endif() + include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +else() + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-non-prototype") + endif() endif() if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) @@ -88,7 +96,7 @@ if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) message(STATUS "to 'zconf.h.included' because this file is included with zlib") message(STATUS "but CMake generates it automatically in the build directory.") file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included) - endif() + endif() endif() set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc) From dfd70b5c10cd45ef9d80c96ee08fe4e7393520a9 Mon Sep 17 00:00:00 2001 From: Florian Born Date: Thu, 9 Mar 2023 19:06:58 +0100 Subject: [PATCH 02/21] GLTF Importer: Build a list of the actual vertices so it works well with shared attribute lists --- code/AssetLib/glTF2/glTF2Asset.h | 2 +- code/AssetLib/glTF2/glTF2Asset.inl | 19 ++--- code/AssetLib/glTF2/glTF2Importer.cpp | 100 +++++++++++++++++--------- 3 files changed, 78 insertions(+), 43 deletions(-) diff --git a/code/AssetLib/glTF2/glTF2Asset.h b/code/AssetLib/glTF2/glTF2Asset.h index 1d7cff325..cf9c8f11c 100644 --- a/code/AssetLib/glTF2/glTF2Asset.h +++ b/code/AssetLib/glTF2/glTF2Asset.h @@ -565,7 +565,7 @@ struct Accessor : public Object { inline size_t GetMaxByteSize(); template - void ExtractData(T *&outData); + size_t ExtractData(T *&outData, const std::vector *remappingIndices = nullptr); void WriteData(size_t count, const void *src_buffer, size_t src_stride); void WriteSparseValues(size_t count, const void *src_data, size_t src_dataStride); diff --git a/code/AssetLib/glTF2/glTF2Asset.inl b/code/AssetLib/glTF2/glTF2Asset.inl index 0e2998357..4e4497e1f 100644 --- a/code/AssetLib/glTF2/glTF2Asset.inl +++ b/code/AssetLib/glTF2/glTF2Asset.inl @@ -962,14 +962,15 @@ inline size_t Accessor::GetMaxByteSize() { } template -void Accessor::ExtractData(T *&outData) { +size_t Accessor::ExtractData(T *&outData, const std::vector *remappingIndices) { uint8_t *data = GetPointer(); if (!data) { throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name)); } + const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count; const size_t elemSize = GetElementSize(); - const size_t totalSize = elemSize * count; + const size_t totalSize = elemSize * usedCount; const size_t stride = GetStride(); @@ -980,18 +981,20 @@ void Accessor::ExtractData(T *&outData) { } const size_t maxSize = GetMaxByteSize(); - if (count * stride > maxSize) { - throw DeadlyImportError("GLTF: count*stride ", (count * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name)); + if (usedCount * stride > maxSize) { + throw DeadlyImportError("GLTF: count*stride ", (usedCount * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name)); } - outData = new T[count]; - if (stride == elemSize && targetElemSize == elemSize) { + outData = new T[usedCount]; + if (remappingIndices == nullptr && stride == elemSize && targetElemSize == elemSize) { memcpy(outData, data, totalSize); } else { - for (size_t i = 0; i < count; ++i) { - memcpy(outData + i, data + i * stride, elemSize); + for (size_t i = 0; i < usedCount; ++i) { + size_t srcIdx = remappingIndices != nullptr ? static_cast((*remappingIndices)[i]) : i; + memcpy(outData + i, data + srcIdx * stride, elemSize); } } + return usedCount; } inline void Accessor::WriteData(size_t _count, const void *src_buffer, size_t src_stride) { diff --git a/code/AssetLib/glTF2/glTF2Importer.cpp b/code/AssetLib/glTF2/glTF2Importer.cpp index d30556806..f0dc284c3 100644 --- a/code/AssetLib/glTF2/glTF2Importer.cpp +++ b/code/AssetLib/glTF2/glTF2Importer.cpp @@ -453,6 +453,12 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { unsigned int k = 0; meshOffsets.clear(); + + const unsigned int unusedIndex = ~0; + std::vector usedVertexIndices; + std::vector reverseMappingIndices; + std::vector indexBuffer; + for (unsigned int m = 0; m < r.meshes.Size(); ++m) { Mesh &mesh = r.meshes[m]; @@ -462,6 +468,36 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { for (unsigned int p = 0; p < mesh.primitives.size(); ++p) { Mesh::Primitive &prim = mesh.primitives[p]; + // extract used vertices: + bool useIndexBuffer = prim.indices; + std::vector* usedVertexIndicesPtr = nullptr; + if (useIndexBuffer) { + size_t count = prim.indices->count; + indexBuffer.resize(count); + usedVertexIndices.clear(); + reverseMappingIndices.clear(); + usedVertexIndices.reserve(count / 3); // this is a very rough heuristic to reduce re-allocations + usedVertexIndicesPtr = &usedVertexIndices; + Accessor::Indexer data = prim.indices->GetIndexer(); + if (!data.IsValid()) { + throw DeadlyImportError("GLTF: Invalid accessor without data in mesh ", getContextForErrorMessages(mesh.id, mesh.name)); + } + + // Build the vertex remapping table and the modified index buffer (used later instead of the original one) + // In case no index buffer is used, the original vertex arrays are being used so no remapping is required in the first place. + for (unsigned int i = 0; i < count; ++i) { + unsigned int index = data.GetUInt(i); + if (index >= reverseMappingIndices.size()) { + reverseMappingIndices.resize(index + 1, unusedIndex); + } + if (reverseMappingIndices[index] == unusedIndex) { + reverseMappingIndices[index] = static_cast(usedVertexIndices.size()); + usedVertexIndices.push_back(index); + } + indexBuffer[i] = reverseMappingIndices[index]; + } + } + aiMesh *aim = new aiMesh(); meshes.push_back(std::unique_ptr(aim)); @@ -493,26 +529,27 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { Mesh::Primitive::Attributes &attr = prim.attributes; + size_t numAllVertices = 0; if (!attr.position.empty() && attr.position[0]) { - aim->mNumVertices = static_cast(attr.position[0]->count); - attr.position[0]->ExtractData(aim->mVertices); + numAllVertices = attr.position[0]->count; + aim->mNumVertices = static_cast(attr.position[0]->ExtractData(aim->mVertices, usedVertexIndicesPtr)); } if (!attr.normal.empty() && attr.normal[0]) { - if (attr.normal[0]->count != aim->mNumVertices) { + if (attr.normal[0]->count != numAllVertices) { DefaultLogger::get()->warn("Normal count in mesh \"", mesh.name, "\" does not match the vertex count, normals ignored."); } else { - attr.normal[0]->ExtractData(aim->mNormals); + attr.normal[0]->ExtractData(aim->mNormals, usedVertexIndicesPtr); // only extract tangents if normals are present if (!attr.tangent.empty() && attr.tangent[0]) { - if (attr.tangent[0]->count != aim->mNumVertices) { + if (attr.tangent[0]->count != numAllVertices) { DefaultLogger::get()->warn("Tangent count in mesh \"", mesh.name, "\" does not match the vertex count, tangents ignored."); } else { // generate bitangents from normals and tangents according to spec Tangent *tangents = nullptr; - attr.tangent[0]->ExtractData(tangents); + attr.tangent[0]->ExtractData(tangents, usedVertexIndicesPtr); aim->mTangents = new aiVector3D[aim->mNumVertices]; aim->mBitangents = new aiVector3D[aim->mNumVertices]; @@ -529,7 +566,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { } for (size_t c = 0; c < attr.color.size() && c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c) { - if (attr.color[c]->count != aim->mNumVertices) { + if (attr.color[c]->count != numAllVertices) { DefaultLogger::get()->warn("Color stream size in mesh \"", mesh.name, "\" does not match the vertex count"); continue; @@ -537,7 +574,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { auto componentType = attr.color[c]->componentType; if (componentType == glTF2::ComponentType_FLOAT) { - attr.color[c]->ExtractData(aim->mColors[c]); + attr.color[c]->ExtractData(aim->mColors[c], usedVertexIndicesPtr); } else { if (componentType == glTF2::ComponentType_UNSIGNED_BYTE) { aim->mColors[c] = GetVertexColorsForType(attr.color[c]); @@ -552,13 +589,13 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { continue; } - if (attr.texcoord[tc]->count != aim->mNumVertices) { + if (attr.texcoord[tc]->count != numAllVertices) { DefaultLogger::get()->warn("Texcoord stream size in mesh \"", mesh.name, "\" does not match the vertex count"); continue; } - attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]); + attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc], usedVertexIndicesPtr); aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents(); aiVector3D *values = aim->mTextureCoords[tc]; @@ -583,11 +620,11 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { Mesh::Primitive::Target &target = targets[i]; if (needPositions) { - if (target.position[0]->count != aim->mNumVertices) { + if (target.position[0]->count != numAllVertices) { ASSIMP_LOG_WARN("Positions of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count"); } else { aiVector3D *positionDiff = nullptr; - target.position[0]->ExtractData(positionDiff); + target.position[0]->ExtractData(positionDiff, usedVertexIndicesPtr); for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) { aiAnimMesh.mVertices[vertexId] += positionDiff[vertexId]; } @@ -595,11 +632,11 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { } } if (needNormals) { - if (target.normal[0]->count != aim->mNumVertices) { + if (target.normal[0]->count != numAllVertices) { ASSIMP_LOG_WARN("Normals of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count"); } else { aiVector3D *normalDiff = nullptr; - target.normal[0]->ExtractData(normalDiff); + target.normal[0]->ExtractData(normalDiff, usedVertexIndicesPtr); for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) { aiAnimMesh.mNormals[vertexId] += normalDiff[vertexId]; } @@ -610,14 +647,14 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { if (!aiAnimMesh.HasNormals()) { // prevent nullptr access to aiAnimMesh.mNormals below when no normals are available ASSIMP_LOG_WARN("Bitangents of target ", i, " in mesh \"", mesh.name, "\" can't be computed, because mesh has no normals."); - } else if (target.tangent[0]->count != aim->mNumVertices) { + } else if (target.tangent[0]->count != numAllVertices) { ASSIMP_LOG_WARN("Tangents of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count"); } else { Tangent *tangent = nullptr; - attr.tangent[0]->ExtractData(tangent); + attr.tangent[0]->ExtractData(tangent, usedVertexIndicesPtr); aiVector3D *tangentDiff = nullptr; - target.tangent[0]->ExtractData(tangentDiff); + target.tangent[0]->ExtractData(tangentDiff, usedVertexIndicesPtr); for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; ++vertexId) { tangent[vertexId].xyz += tangentDiff[vertexId]; @@ -641,20 +678,15 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { aiFace *facePtr = nullptr; size_t nFaces = 0; - if (prim.indices) { - size_t count = prim.indices->count; - - Accessor::Indexer data = prim.indices->GetIndexer(); - if (!data.IsValid()) { - throw DeadlyImportError("GLTF: Invalid accessor without data in mesh ", getContextForErrorMessages(mesh.id, mesh.name)); - } + if (useIndexBuffer) { + size_t count = indexBuffer.size(); switch (prim.mode) { case PrimitiveMode_POINTS: { nFaces = count; facePtr = faces = new aiFace[nFaces]; for (unsigned int i = 0; i < count; ++i) { - SetFaceAndAdvance1(facePtr, aim->mNumVertices, data.GetUInt(i)); + SetFaceAndAdvance1(facePtr, aim->mNumVertices, indexBuffer[i]); } break; } @@ -667,7 +699,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { } facePtr = faces = new aiFace[nFaces]; for (unsigned int i = 0; i < count; i += 2) { - SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1)); + SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[i], indexBuffer[i + 1]); } break; } @@ -676,12 +708,12 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { case PrimitiveMode_LINE_STRIP: { nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0); facePtr = faces = new aiFace[nFaces]; - SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(1)); + SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[0], indexBuffer[1]); for (unsigned int i = 2; i < count; ++i) { - SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(i - 1), data.GetUInt(i)); + SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[i - 1], indexBuffer[i]); } if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop - SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(static_cast(count) - 1), faces[0].mIndices[0]); + SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[static_cast(count) - 1], faces[0].mIndices[0]); } break; } @@ -694,7 +726,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { } facePtr = faces = new aiFace[nFaces]; for (unsigned int i = 0; i < count; i += 3) { - SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2)); + SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[i], indexBuffer[i + 1], indexBuffer[i + 2]); } break; } @@ -705,10 +737,10 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { // The ordering is to ensure that the triangles are all drawn with the same orientation if ((i + 1) % 2 == 0) { // For even n, vertices n + 1, n, and n + 2 define triangle n - SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i + 1), data.GetUInt(i), data.GetUInt(i + 2)); + SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[i + 1], indexBuffer[i], indexBuffer[i + 2]); } else { // For odd n, vertices n, n+1, and n+2 define triangle n - SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2)); + SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[i], indexBuffer[i + 1], indexBuffer[i + 2]); } } break; @@ -716,9 +748,9 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { case PrimitiveMode_TRIANGLE_FAN: nFaces = count - 2; facePtr = faces = new aiFace[nFaces]; - SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(1), data.GetUInt(2)); + SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[0], indexBuffer[1], indexBuffer[2]); for (unsigned int i = 1; i < nFaces; ++i) { - SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(i + 1), data.GetUInt(i + 2)); + SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[0], indexBuffer[i + 1], indexBuffer[i + 2]); } break; } From 60cefdd54927e79515563907887a1d9813d0b9b3 Mon Sep 17 00:00:00 2001 From: Florian Born Date: Fri, 10 Mar 2023 12:10:38 +0100 Subject: [PATCH 03/21] Jan's fedback --- code/AssetLib/glTF2/glTF2Asset.inl | 25 ++++++++++++++++++------- code/AssetLib/glTF2/glTF2Importer.cpp | 24 ++++++++++++------------ 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/code/AssetLib/glTF2/glTF2Asset.inl b/code/AssetLib/glTF2/glTF2Asset.inl index 4e4497e1f..b4ea77c79 100644 --- a/code/AssetLib/glTF2/glTF2Asset.inl +++ b/code/AssetLib/glTF2/glTF2Asset.inl @@ -981,18 +981,29 @@ size_t Accessor::ExtractData(T *&outData, const std::vector *remap } const size_t maxSize = GetMaxByteSize(); - if (usedCount * stride > maxSize) { - throw DeadlyImportError("GLTF: count*stride ", (usedCount * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name)); - } outData = new T[usedCount]; - if (remappingIndices == nullptr && stride == elemSize && targetElemSize == elemSize) { - memcpy(outData, data, totalSize); - } else { + + if (remappingIndices != nullptr) { + const unsigned int maxIndex = static_cast(maxSize / stride - 1); for (size_t i = 0; i < usedCount; ++i) { - size_t srcIdx = remappingIndices != nullptr ? static_cast((*remappingIndices)[i]) : i; + size_t srcIdx = (*remappingIndices)[i]; + if (srcIdx > maxIndex) { + throw DeadlyImportError("GLTF: index*stride ", (srcIdx * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name)); + } memcpy(outData + i, data + srcIdx * stride, elemSize); } + } else { // non-indexed cases + if (usedCount * stride > maxSize) { + throw DeadlyImportError("GLTF: count*stride ", (usedCount * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name)); + } + if (stride == elemSize && targetElemSize == elemSize) { + memcpy(outData, data, totalSize); + } else { + for (size_t i = 0; i < usedCount; ++i) { + memcpy(outData + i, data + i * stride, elemSize); + } + } } return usedCount; } diff --git a/code/AssetLib/glTF2/glTF2Importer.cpp b/code/AssetLib/glTF2/glTF2Importer.cpp index f0dc284c3..ed9b1ca85 100644 --- a/code/AssetLib/glTF2/glTF2Importer.cpp +++ b/code/AssetLib/glTF2/glTF2Importer.cpp @@ -454,7 +454,6 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { meshOffsets.clear(); - const unsigned int unusedIndex = ~0; std::vector usedVertexIndices; std::vector reverseMappingIndices; std::vector indexBuffer; @@ -470,14 +469,14 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { // extract used vertices: bool useIndexBuffer = prim.indices; - std::vector* usedVertexIndicesPtr = nullptr; + std::vector* vertexRemappingTable = nullptr; if (useIndexBuffer) { size_t count = prim.indices->count; indexBuffer.resize(count); usedVertexIndices.clear(); reverseMappingIndices.clear(); usedVertexIndices.reserve(count / 3); // this is a very rough heuristic to reduce re-allocations - usedVertexIndicesPtr = &usedVertexIndices; + vertexRemappingTable = &usedVertexIndices; Accessor::Indexer data = prim.indices->GetIndexer(); if (!data.IsValid()) { throw DeadlyImportError("GLTF: Invalid accessor without data in mesh ", getContextForErrorMessages(mesh.id, mesh.name)); @@ -485,6 +484,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { // Build the vertex remapping table and the modified index buffer (used later instead of the original one) // In case no index buffer is used, the original vertex arrays are being used so no remapping is required in the first place. + const unsigned int unusedIndex = ~0u; for (unsigned int i = 0; i < count; ++i) { unsigned int index = data.GetUInt(i); if (index >= reverseMappingIndices.size()) { @@ -532,14 +532,14 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { size_t numAllVertices = 0; if (!attr.position.empty() && attr.position[0]) { numAllVertices = attr.position[0]->count; - aim->mNumVertices = static_cast(attr.position[0]->ExtractData(aim->mVertices, usedVertexIndicesPtr)); + aim->mNumVertices = static_cast(attr.position[0]->ExtractData(aim->mVertices, vertexRemappingTable)); } if (!attr.normal.empty() && attr.normal[0]) { if (attr.normal[0]->count != numAllVertices) { DefaultLogger::get()->warn("Normal count in mesh \"", mesh.name, "\" does not match the vertex count, normals ignored."); } else { - attr.normal[0]->ExtractData(aim->mNormals, usedVertexIndicesPtr); + attr.normal[0]->ExtractData(aim->mNormals, vertexRemappingTable); // only extract tangents if normals are present if (!attr.tangent.empty() && attr.tangent[0]) { @@ -549,7 +549,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { // generate bitangents from normals and tangents according to spec Tangent *tangents = nullptr; - attr.tangent[0]->ExtractData(tangents, usedVertexIndicesPtr); + attr.tangent[0]->ExtractData(tangents, vertexRemappingTable); aim->mTangents = new aiVector3D[aim->mNumVertices]; aim->mBitangents = new aiVector3D[aim->mNumVertices]; @@ -574,7 +574,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { auto componentType = attr.color[c]->componentType; if (componentType == glTF2::ComponentType_FLOAT) { - attr.color[c]->ExtractData(aim->mColors[c], usedVertexIndicesPtr); + attr.color[c]->ExtractData(aim->mColors[c], vertexRemappingTable); } else { if (componentType == glTF2::ComponentType_UNSIGNED_BYTE) { aim->mColors[c] = GetVertexColorsForType(attr.color[c]); @@ -595,7 +595,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { continue; } - attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc], usedVertexIndicesPtr); + attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc], vertexRemappingTable); aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents(); aiVector3D *values = aim->mTextureCoords[tc]; @@ -624,7 +624,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { ASSIMP_LOG_WARN("Positions of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count"); } else { aiVector3D *positionDiff = nullptr; - target.position[0]->ExtractData(positionDiff, usedVertexIndicesPtr); + target.position[0]->ExtractData(positionDiff, vertexRemappingTable); for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) { aiAnimMesh.mVertices[vertexId] += positionDiff[vertexId]; } @@ -636,7 +636,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { ASSIMP_LOG_WARN("Normals of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count"); } else { aiVector3D *normalDiff = nullptr; - target.normal[0]->ExtractData(normalDiff, usedVertexIndicesPtr); + target.normal[0]->ExtractData(normalDiff, vertexRemappingTable); for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) { aiAnimMesh.mNormals[vertexId] += normalDiff[vertexId]; } @@ -651,10 +651,10 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { ASSIMP_LOG_WARN("Tangents of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count"); } else { Tangent *tangent = nullptr; - attr.tangent[0]->ExtractData(tangent, usedVertexIndicesPtr); + attr.tangent[0]->ExtractData(tangent, vertexRemappingTable); aiVector3D *tangentDiff = nullptr; - target.tangent[0]->ExtractData(tangentDiff, usedVertexIndicesPtr); + target.tangent[0]->ExtractData(tangentDiff, vertexRemappingTable); for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; ++vertexId) { tangent[vertexId].xyz += tangentDiff[vertexId]; From 8176c6a0e47c18317267b00e579cb0217fb2ccc3 Mon Sep 17 00:00:00 2001 From: Florian Born Date: Fri, 10 Mar 2023 18:36:43 +0100 Subject: [PATCH 04/21] Adjusting the unit tests to pass new gltf --- code/AssetLib/glTF2/glTF2Importer.cpp | 21 +++++++++++++++------ test/unit/utglTF2ImportExport.cpp | 14 +++++++------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/code/AssetLib/glTF2/glTF2Importer.cpp b/code/AssetLib/glTF2/glTF2Importer.cpp index ed9b1ca85..428763798 100644 --- a/code/AssetLib/glTF2/glTF2Importer.cpp +++ b/code/AssetLib/glTF2/glTF2Importer.cpp @@ -467,7 +467,15 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { for (unsigned int p = 0; p < mesh.primitives.size(); ++p) { Mesh::Primitive &prim = mesh.primitives[p]; - // extract used vertices: + Mesh::Primitive::Attributes &attr = prim.attributes; + + // Find out the maximum number of vertices: + size_t numAllVertices = 0; + if (!attr.position.empty() && attr.position[0]) { + numAllVertices = attr.position[0]->count; + } + + // Extract used vertices: bool useIndexBuffer = prim.indices; std::vector* vertexRemappingTable = nullptr; if (useIndexBuffer) { @@ -487,6 +495,11 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { const unsigned int unusedIndex = ~0u; for (unsigned int i = 0; i < count; ++i) { unsigned int index = data.GetUInt(i); + if (index >= numAllVertices) { + // Out-of-range indices will be filtered out when adding the faces and then lead to a warning. At this stage, we just keep them. + indexBuffer[i] = index; + continue; + } if (index >= reverseMappingIndices.size()) { reverseMappingIndices.resize(index + 1, unusedIndex); } @@ -527,12 +540,8 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { break; } - Mesh::Primitive::Attributes &attr = prim.attributes; - - size_t numAllVertices = 0; if (!attr.position.empty() && attr.position[0]) { - numAllVertices = attr.position[0]->count; - aim->mNumVertices = static_cast(attr.position[0]->ExtractData(aim->mVertices, vertexRemappingTable)); + aim->mNumVertices = static_cast(attr.position[0]->ExtractData(aim->mVertices, vertexRemappingTable)); } if (!attr.normal.empty() && attr.normal[0]) { diff --git a/test/unit/utglTF2ImportExport.cpp b/test/unit/utglTF2ImportExport.cpp index ef3fc4137..957a94b15 100644 --- a/test/unit/utglTF2ImportExport.cpp +++ b/test/unit/utglTF2ImportExport.cpp @@ -380,7 +380,7 @@ TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeLines) { const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_08.gltf", aiProcess_ValidateDataStructure); EXPECT_NE(nullptr, scene); EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4u); - std::array l1 = { { 0u, 3u, 2u, 1u, 0u } }; + std::array l1 = { { 0u, 1u, 2u, 3u, 0u } }; EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 2u); for (unsigned int i = 0; i < scene->mMeshes[0]->mNumFaces; ++i) { EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[0], l1[i]); @@ -394,7 +394,7 @@ TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeLineLoop) { const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_09.gltf", aiProcess_ValidateDataStructure); EXPECT_NE(nullptr, scene); EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4u); - std::array l1 = { { 0, 3u, 2u, 1u, 0u } }; + std::array l1 = { { 0, 1u, 2u, 3u, 0u } }; EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 2u); for (unsigned int i = 0; i < scene->mMeshes[0]->mNumFaces; ++i) { EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[0], l1[i]); @@ -408,7 +408,7 @@ TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeLineStrip) { const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_10.gltf", aiProcess_ValidateDataStructure); EXPECT_NE(nullptr, scene); EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4u); - std::array l1 = { { 0u, 3u, 2u, 1u, 0u } }; + std::array l1 = { { 0u, 1u, 2u, 3u, 0u } }; EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 2u); for (unsigned int i = 0; i < scene->mMeshes[0]->mNumFaces; ++i) { EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[0], l1[i]); @@ -423,13 +423,13 @@ TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeTrianglesStrip) { EXPECT_NE(nullptr, scene); EXPECT_EQ(scene->mMeshes[0]->mNumFaces, 2u); EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4u); - std::array f1 = { { 0u, 3u, 1u } }; + std::array f1 = { { 0u, 1u, 2u } }; EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 3u); for (size_t i = 0; i < 3; ++i) { EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mIndices[i], f1[i]); } - std::array f2 = { { 1u, 3u, 2u } }; + std::array f2 = { { 2u, 1u, 3u } }; EXPECT_EQ(scene->mMeshes[0]->mFaces[1].mNumIndices, 3u); for (size_t i = 0; i < 3; ++i) { EXPECT_EQ(scene->mMeshes[0]->mFaces[1].mIndices[i], f2[i]); @@ -443,13 +443,13 @@ TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeTrianglesFan) { EXPECT_NE(nullptr, scene); EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4u); EXPECT_EQ(scene->mMeshes[0]->mNumFaces, 2u); - std::array f1 = { { 0u, 3u, 2u } }; + std::array f1 = { { 0u, 1u, 2u } }; EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 3u); for (size_t i = 0; i < 3; ++i) { EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mIndices[i], f1[i]); } - std::array f2 = { { 0u, 2u, 1u } }; + std::array f2 = { { 0u, 2u, 3u } }; EXPECT_EQ(scene->mMeshes[0]->mFaces[1].mNumIndices, 3u); for (size_t i = 0; i < 3; ++i) { EXPECT_EQ(scene->mMeshes[0]->mFaces[1].mIndices[i], f2[i]); From cdfdd75a66e2323bd834f923798d3043ad3deaf8 Mon Sep 17 00:00:00 2001 From: Inho Lee Date: Tue, 21 Mar 2023 10:35:24 +0100 Subject: [PATCH 05/21] FBXConverter : import FbxCamera correctly FbxCamera's default value is correct but its transformed values are described in each NodeProperties. --- code/AssetLib/FBX/FBXConverter.cpp | 30 +++++++++++++++++++++--------- code/AssetLib/FBX/FBXConverter.h | 9 ++++++--- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp index 37654746e..416a73d9b 100644 --- a/code/AssetLib/FBX/FBXConverter.cpp +++ b/code/AssetLib/FBX/FBXConverter.cpp @@ -152,7 +152,7 @@ void FBXConverter::ConvertRootNode() { mSceneOut->mRootNode->mName.Set(unique_name); // root has ID 0 - ConvertNodes(0L, mSceneOut->mRootNode, mSceneOut->mRootNode); + ConvertNodes(0L, mSceneOut->mRootNode, mSceneOut->mRootNode, aiMatrix4x4()); } static std::string getAncestorBaseName(const aiNode *node) { @@ -196,7 +196,7 @@ struct FBXConverter::PotentialNode { /// todo: get bone from stack /// todo: make map of aiBone* to aiNode* /// then update convert clusters to the new format -void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node) { +void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node, const aiMatrix4x4 &globalTransform) { const std::vector &conns = doc.GetConnectionsByDestinationSequenced(id, "Model"); std::vector nodes; @@ -290,14 +290,15 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node) } // recursion call - child nodes - ConvertNodes(model->ID(), last_parent, root_node); + aiMatrix4x4 newGlobalMatrix = globalTransform * nodes_chain.front().mNode->mTransformation; + ConvertNodes(model->ID(), last_parent, root_node, newGlobalMatrix); if (doc.Settings().readLights) { ConvertLights(*model, node_name); } if (doc.Settings().readCameras) { - ConvertCameras(*model, node_name); + ConvertCameras(*model, node_name, newGlobalMatrix); } nodes.push_back(std::move(nodes_chain.front())); @@ -327,12 +328,14 @@ void FBXConverter::ConvertLights(const Model &model, const std::string &orig_nam } } -void FBXConverter::ConvertCameras(const Model &model, const std::string &orig_name) { +void FBXConverter::ConvertCameras(const Model &model, + const std::string &orig_name, + const aiMatrix4x4 &transform) { const std::vector &node_attrs = model.GetAttributes(); for (const NodeAttribute *attr : node_attrs) { const Camera *const cam = dynamic_cast(attr); if (cam) { - ConvertCamera(*cam, orig_name); + ConvertCamera(*cam, orig_name, transform); } } } @@ -413,7 +416,9 @@ void FBXConverter::ConvertLight(const Light &light, const std::string &orig_name } } -void FBXConverter::ConvertCamera(const Camera &cam, const std::string &orig_name) { +void FBXConverter::ConvertCamera(const Camera &cam, + const std::string &orig_name, + aiMatrix4x4 transform) { cameras.push_back(new aiCamera()); aiCamera *const out_camera = cameras.back(); @@ -421,9 +426,16 @@ void FBXConverter::ConvertCamera(const Camera &cam, const std::string &orig_name out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight(); + aiVector3D pos = cam.Position(); + out_camera->mLookAt = cam.InterestPosition(); + out_camera->mUp = pos + cam.UpVector(); + transform.Inverse(); + pos *= transform; + out_camera->mLookAt *= transform; + out_camera->mUp *= transform; + out_camera->mLookAt -= pos; + out_camera->mUp -= pos; out_camera->mPosition = aiVector3D(0.0f); - out_camera->mLookAt = aiVector3D(1.0f, 0.0f, 0.0f); - out_camera->mUp = aiVector3D(0.0f, 1.0f, 0.0f); out_camera->mHorizontalFOV = AI_DEG_TO_RAD(cam.FieldOfView()); diff --git a/code/AssetLib/FBX/FBXConverter.h b/code/AssetLib/FBX/FBXConverter.h index 41acb6ffe..b9b6c46b0 100644 --- a/code/AssetLib/FBX/FBXConverter.h +++ b/code/AssetLib/FBX/FBXConverter.h @@ -134,19 +134,22 @@ private: // ------------------------------------------------------------------------------------------------ // collect and assign child nodes - void ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node); + void ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node, + const aiMatrix4x4 &globalTransform); // ------------------------------------------------------------------------------------------------ void ConvertLights(const Model& model, const std::string &orig_name ); // ------------------------------------------------------------------------------------------------ - void ConvertCameras(const Model& model, const std::string &orig_name ); + void ConvertCameras(const Model& model, const std::string &orig_name, + const aiMatrix4x4 &transform); // ------------------------------------------------------------------------------------------------ void ConvertLight( const Light& light, const std::string &orig_name ); // ------------------------------------------------------------------------------------------------ - void ConvertCamera( const Camera& cam, const std::string &orig_name ); + void ConvertCamera(const Camera& cam, const std::string &orig_name, + aiMatrix4x4 transform); // ------------------------------------------------------------------------------------------------ void GetUniqueName( const std::string &name, std::string& uniqueName ); From d8201bdb6f43ca396b5cdcacfbda67870397554b Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 25 Mar 2023 16:00:29 +0100 Subject: [PATCH 06/21] Update Readme.md --- Readme.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Readme.md b/Readme.md index 1af71fad8..c8fe3f43f 100644 --- a/Readme.md +++ b/Readme.md @@ -22,6 +22,9 @@ Additionally, assimp features various __mesh post processing tools__: normals an ### Latest Doc's ### Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/). +### Prebuild binaries ### +Please check our [Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib) + ### Get involved ### This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases).
From f4e9930e509ca92718cb65f980d38cefdd0a8065 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 28 Mar 2023 13:45:09 +0200 Subject: [PATCH 07/21] Update Readme.md --- Readme.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Readme.md b/Readme.md index 1af71fad8..5cfcbee8c 100644 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,8 @@ Open Asset Import Library (assimp) ================================== -A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data. + +Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export. + ### Current project status ### [![Financial Contributors on Open Collective](https://opencollective.com/assimp/all/badge.svg?label=financial+contributors)](https://opencollective.com/assimp) ![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg) @@ -65,26 +67,27 @@ Open Asset Import Library is implemented in C++. The directory structure looks l /port Ports to other languages and scripts to maintain those. /test Unit- and regression tests, test suite of models /tools Tools (old assimp viewer, command line `assimp`) - /samples A small number of samples to illustrate possible - use cases for Assimp + /samples A small number of samples to illustrate possible use-cases for Assimp The source code is organized in the following way: code/Common The base implementation for importers and the infrastructure + code/CApi Special implementations which are only used for the C-API + code/Geometry A collection of geometry tools + code/Material The material system + code/PBR An exporter for physical based models code/PostProcessing The post-processing steps code/AssetLib/ Implementation for import and export for the format ### Where to get help ### To find our documentation, visit [our website](https://assimp.org/) or check out [Wiki](https://github.com/assimp/assimp/wiki) -If the docs don't solve your problem, you can: -- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest). -- Ask on [Assimp-Community on Reddit](https://www.reddit.com/r/Assimp/) +### Communities ### - Ask a question at [The Assimp-Discussion Board](https://github.com/assimp/assimp/discussions) +- Ask on [Assimp-Community on Reddit](https://www.reddit.com/r/Assimp/) +- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest). - Nothing has worked? File a question or an issue-report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues) -Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export. - And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
### Contributing ### From 55fa3d4251438806d11865d84b06ec638f42fc27 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 28 Mar 2023 15:19:33 +0200 Subject: [PATCH 08/21] Update Readme.md --- Readme.md | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/Readme.md b/Readme.md index 5cfcbee8c..c680cd834 100644 --- a/Readme.md +++ b/Readme.md @@ -24,15 +24,16 @@ Additionally, assimp features various __mesh post processing tools__: normals an ### Latest Doc's ### Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/). -### Get involved ### -This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases). -
-You find a bug in the docs? Use [Doc-Repo](https://github.com/assimp/assimp-docs). -
-Please check our Wiki as well: https://github.com/assimp/assimp/wiki - If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb +### Communities ### +- Ask a question at [The Assimp-Discussion Board](https://github.com/assimp/assimp/discussions) +- Ask on [Assimp-Community on Reddit](https://www.reddit.com/r/Assimp/) +- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest). +- Nothing has worked? File a question or an issue-report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues) + +And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+ #### Supported file formats #### You can find the complete list of supported file-formats [here](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md) @@ -79,17 +80,6 @@ The source code is organized in the following way: code/PostProcessing The post-processing steps code/AssetLib/ Implementation for import and export for the format -### Where to get help ### -To find our documentation, visit [our website](https://assimp.org/) or check out [Wiki](https://github.com/assimp/assimp/wiki) - -### Communities ### -- Ask a question at [The Assimp-Discussion Board](https://github.com/assimp/assimp/discussions) -- Ask on [Assimp-Community on Reddit](https://www.reddit.com/r/Assimp/) -- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest). -- Nothing has worked? File a question or an issue-report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues) - -And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
- ### Contributing ### Contributions to assimp are highly appreciated. The easiest way to get involved is to submit a pull request with your changes against the main repository's `master` branch. From 4438b3ecc9aae5156f888ecd5a9604d8e1ce638e Mon Sep 17 00:00:00 2001 From: aniongithub Date: Wed, 29 Mar 2023 18:36:18 +0000 Subject: [PATCH 09/21] Fix Issue #4486 using the fix described by @jianliang79 --- code/AssetLib/FBX/FBXConverter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp index f1f57c10b..257845384 100644 --- a/code/AssetLib/FBX/FBXConverter.cpp +++ b/code/AssetLib/FBX/FBXConverter.cpp @@ -640,7 +640,7 @@ void FBXConverter::GetRotationMatrix(Model::RotOrder mode, const aiVector3D &rot bool FBXConverter::NeedsComplexTransformationChain(const Model &model) { const PropertyTable &props = model.Props(); - const auto zero_epsilon = ai_epsilon; + const auto zero_epsilon = Math::getEpsilon(); const aiVector3D all_ones(1.0f, 1.0f, 1.0f); for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) { const TransformationComp comp = static_cast(i); From 6d65e9c393e99cc703dc61f6b2d75e5f359d9910 Mon Sep 17 00:00:00 2001 From: Sven Liedtke Date: Thu, 30 Mar 2023 09:21:30 +0200 Subject: [PATCH 10/21] Fix link issue in UWP builds without functional replacement --- contrib/unzip/crypt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/unzip/crypt.c b/contrib/unzip/crypt.c index 4cc731b3e..cc6650630 100644 --- a/contrib/unzip/crypt.c +++ b/contrib/unzip/crypt.c @@ -103,7 +103,7 @@ int cryptrand(unsigned char *buf, unsigned int len) unsigned __int64 pentium_tsc[1]; int result = 0; - + #if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { result = CryptGenRandom(provider, len, buf); @@ -111,6 +111,7 @@ int cryptrand(unsigned char *buf, unsigned int len) if (result) return len; } + #endif for (rlen = 0; rlen < (int)len; ++rlen) { From 5cf9d3abf7d7f6debbab1e491313249b805bd2f3 Mon Sep 17 00:00:00 2001 From: Sven Liedtke Date: Sat, 1 Apr 2023 01:02:21 +0200 Subject: [PATCH 11/21] std::getenv is not supported using uwp --- code/Common/ImporterRegistry.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/code/Common/ImporterRegistry.cpp b/code/Common/ImporterRegistry.cpp index 78c02d96d..ac4f5e544 100644 --- a/code/Common/ImporterRegistry.cpp +++ b/code/Common/ImporterRegistry.cpp @@ -214,7 +214,12 @@ void GetImporterInstanceList(std::vector &out) { // Some importers may be unimplemented or otherwise unsuitable for general use // in their current state. Devs can set ASSIMP_ENABLE_DEV_IMPORTERS in their // local environment to enable them, otherwise they're left out of the registry. +#if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP + // not supported under uwp const char *envStr = std::getenv("ASSIMP_ENABLE_DEV_IMPORTERS"); +#else + const char *envStr = { "0" }; +#endif bool devImportersEnabled = envStr && strcmp(envStr, "0"); // Ensure no unused var warnings if all uses are #ifndef'd away below: @@ -378,7 +383,7 @@ void GetImporterInstanceList(std::vector &out) { out.push_back(new IQMImporter()); #endif //#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER - // out.push_back(new StepFile::StepFileImporter()); + // out.push_back(new StepFile::StepFileImporter()); //#endif } From 6b547613106cce7513806426c05a75f7bba92cfc Mon Sep 17 00:00:00 2001 From: Jackie9527 <80555200+Jackie9527@users.noreply.github.com> Date: Sat, 1 Apr 2023 10:30:10 +0800 Subject: [PATCH 12/21] Fix warning related to nested-anon-types. Signed-off-by: Jackie9527 <80555200+Jackie9527@users.noreply.github.com> --- code/AssetLib/glTF/glTFAsset.h | 27 ++++++++++++++------------- code/CMakeLists.txt | 1 - 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/code/AssetLib/glTF/glTFAsset.h b/code/AssetLib/glTF/glTFAsset.h index d2ae84b49..b5e6375ad 100644 --- a/code/AssetLib/glTF/glTFAsset.h +++ b/code/AssetLib/glTF/glTFAsset.h @@ -513,21 +513,22 @@ struct Camera : public Object { }; Type type; + struct Perspective { + float aspectRatio; //! Date: Sat, 1 Apr 2023 12:19:20 +0800 Subject: [PATCH 13/21] Fix warning related to format-non-iso. Signed-off-by: Jackie9527 <80555200+Jackie9527@users.noreply.github.com> --- code/CMakeLists.txt | 1 - include/assimp/StringUtils.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index fd3b1cb88..3f5b8e936 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -1246,7 +1246,6 @@ IF (ASSIMP_WARNINGS_AS_ERRORS) -Wno-deprecated-copy-with-dtor -Wno-deprecated -Wno-format-nonliteral - -Wno-format-non-iso -Wno-comma -Wno-unreachable-code-break -Wno-unreachable-code-return diff --git a/include/assimp/StringUtils.h b/include/assimp/StringUtils.h index 59c6e9ead..cd8726785 100644 --- a/include/assimp/StringUtils.h +++ b/include/assimp/StringUtils.h @@ -56,7 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(__clang__) #define AI_SIZEFMT "%Iu" #else #define AI_SIZEFMT "%zu" From 1dcb5da1cd0e40e65bdeabb118d9a9fec3aa9e8a Mon Sep 17 00:00:00 2001 From: Jackie9527 <80555200+Jackie9527@users.noreply.github.com> Date: Sat, 1 Apr 2023 13:01:22 +0800 Subject: [PATCH 14/21] Fix warning related to unreachable-code. Signed-off-by: Jackie9527 <80555200+Jackie9527@users.noreply.github.com> --- code/AssetLib/B3D/B3DImporter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/code/AssetLib/B3D/B3DImporter.cpp b/code/AssetLib/B3D/B3DImporter.cpp index e87744603..bf8145798 100644 --- a/code/AssetLib/B3D/B3DImporter.cpp +++ b/code/AssetLib/B3D/B3DImporter.cpp @@ -418,7 +418,6 @@ void B3DImporter::ReadTRIS(int v0) { ASSIMP_LOG_ERROR("Bad triangle index: i0=", i0, ", i1=", i1, ", i2=", i2); #endif Fail("Bad triangle index"); - continue; } face->mNumIndices = 3; face->mIndices = new unsigned[3]; From 04066ece8e5c1f1f5fed6167ab0e1fd9564f333e Mon Sep 17 00:00:00 2001 From: Jackie9527 <80555200+Jackie9527@users.noreply.github.com> Date: Sat, 1 Apr 2023 13:02:04 +0800 Subject: [PATCH 15/21] Fix warning related to unreachable-code. Signed-off-by: Jackie9527 <80555200+Jackie9527@users.noreply.github.com> --- code/AssetLib/LWO/LWOMaterial.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/LWO/LWOMaterial.cpp b/code/AssetLib/LWO/LWOMaterial.cpp index 50bac884b..8d83dfb67 100644 --- a/code/AssetLib/LWO/LWOMaterial.cpp +++ b/code/AssetLib/LWO/LWOMaterial.cpp @@ -345,7 +345,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface &surf, aiMaterial *pcMat) { // (the diffuse value is just a scaling factor) // If a diffuse texture is set, we set this value to 1.0 - clr = (b && false ? aiColor3D(1.0, 1.0, 1.0) : surf.mColor); + clr = (b ? aiColor3D(1.0, 1.0, 1.0) : surf.mColor); clr.r *= surf.mDiffuseValue; clr.g *= surf.mDiffuseValue; clr.b *= surf.mDiffuseValue; From 4d2512dcae8b181a8f61e2d068f3f331ea0e935a Mon Sep 17 00:00:00 2001 From: Jackie9527 <80555200+Jackie9527@users.noreply.github.com> Date: Sat, 1 Apr 2023 13:03:02 +0800 Subject: [PATCH 16/21] Fix warning related to unreachable-code. Signed-off-by: Jackie9527 <80555200+Jackie9527@users.noreply.github.com> --- contrib/poly2tri/poly2tri/sweep/sweep.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/poly2tri/poly2tri/sweep/sweep.cc b/contrib/poly2tri/poly2tri/sweep/sweep.cc index 8e3d794c0..565a198d8 100644 --- a/contrib/poly2tri/poly2tri/sweep/sweep.cc +++ b/contrib/poly2tri/poly2tri/sweep/sweep.cc @@ -118,8 +118,8 @@ void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangl Point* p1 = triangle->PointCCW(point); Orientation o1 = Orient2d(eq, *p1, ep); if (o1 == COLLINEAR) { - // ASSIMP_CHANGE (aramis_acg) - throw std::runtime_error("EdgeEvent - collinear points not supported"); + + if( triangle->Contains(&eq, p1)) { triangle->MarkConstrainedEdge(&eq, p1 ); // We are modifying the constraint maybe it would be better to @@ -137,8 +137,8 @@ void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangl Point* p2 = triangle->PointCW(point); Orientation o2 = Orient2d(eq, *p2, ep); if (o2 == COLLINEAR) { - // ASSIMP_CHANGE (aramis_acg) - throw std::runtime_error("EdgeEvent - collinear points not supported"); + + if( triangle->Contains(&eq, p2)) { triangle->MarkConstrainedEdge(&eq, p2 ); From 20b2f857c592ea5594a9c53b45a75333e8ae49ca Mon Sep 17 00:00:00 2001 From: Jackie9527 <80555200+Jackie9527@users.noreply.github.com> Date: Sat, 1 Apr 2023 13:04:13 +0800 Subject: [PATCH 17/21] Remove -Wno-unreachable-code Signed-off-by: Jackie9527 <80555200+Jackie9527@users.noreply.github.com> --- code/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index fd3b1cb88..aead2d1a0 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -1250,7 +1250,6 @@ IF (ASSIMP_WARNINGS_AS_ERRORS) -Wno-comma -Wno-unreachable-code-break -Wno-unreachable-code-return - -Wno-unreachable-code -Wno-implicit-fallthrough -Wno-unused-template -Wno-undefined-func-template From dacaebc0788848157ad6c54e1f10aa0e117fcefb Mon Sep 17 00:00:00 2001 From: Jackie9527 <80555200+Jackie9527@users.noreply.github.com> Date: Sat, 1 Apr 2023 23:49:22 +0800 Subject: [PATCH 18/21] Remove unused -Wno-shadow-field-in-constructor. Signed-off-by: Jackie9527 <80555200+Jackie9527@users.noreply.github.com> --- code/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index fd3b1cb88..e05b4dd7b 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -1229,7 +1229,6 @@ IF (ASSIMP_WARNINGS_AS_ERRORS) -Wno-double-promotion -Wno-unused-macros -Wno-disabled-macro-expansion - -Wno-shadow-field-in-constructor -Wno-shadow-field -Wno-shadow -Wno-language-extension-token From 9915e875bf259f354d40bd97d0c4d0100e679477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Suhajda=20Tam=C3=A1s?= Date: Mon, 3 Apr 2023 23:35:04 +0200 Subject: [PATCH 19/21] glTF2: Fix incorrect camera position --- code/AssetLib/glTF2/glTF2Importer.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/code/AssetLib/glTF2/glTF2Importer.cpp b/code/AssetLib/glTF2/glTF2Importer.cpp index d30556806..fda89c2a7 100644 --- a/code/AssetLib/glTF2/glTF2Importer.cpp +++ b/code/AssetLib/glTF2/glTF2Importer.cpp @@ -1172,11 +1172,6 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector & if (node.camera) { pScene->mCameras[node.camera.GetIndex()]->mName = ainode->mName; - if (node.translation.isPresent) { - aiVector3D trans; - CopyValue(node.translation.value, trans); - pScene->mCameras[node.camera.GetIndex()]->mPosition = trans; - } } if (node.light) { From 9d76493ad846256ac3d6126c109380e332eb0066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Suhajda=20Tam=C3=A1s?= Date: Tue, 4 Apr 2023 00:06:09 +0200 Subject: [PATCH 20/21] Fix mLookAt with pretransformed vertices mLookAt is a position vector inside the nodes reference frame, not a direction vector, so translation should be applied to it. --- code/PostProcessing/PretransformVertices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/PostProcessing/PretransformVertices.cpp b/code/PostProcessing/PretransformVertices.cpp index b6bb6155e..16548f09c 100644 --- a/code/PostProcessing/PretransformVertices.cpp +++ b/code/PostProcessing/PretransformVertices.cpp @@ -577,7 +577,7 @@ void PretransformVertices::Execute(aiScene *pScene) { // multiply all properties of the camera with the absolute // transformation of the corresponding node cam->mPosition = nd->mTransformation * cam->mPosition; - cam->mLookAt = aiMatrix3x3(nd->mTransformation) * cam->mLookAt; + cam->mLookAt = nd->mTransformation * cam->mLookAt; cam->mUp = aiMatrix3x3(nd->mTransformation) * cam->mUp; } From e6f26fc52e93979a999ebf3b1ed083cc9006e294 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 4 Apr 2023 12:54:26 +0200 Subject: [PATCH 21/21] Remove dead code. --- code/Common/ImporterRegistry.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/Common/ImporterRegistry.cpp b/code/Common/ImporterRegistry.cpp index ac4f5e544..c67fee936 100644 --- a/code/Common/ImporterRegistry.cpp +++ b/code/Common/ImporterRegistry.cpp @@ -382,9 +382,6 @@ void GetImporterInstanceList(std::vector &out) { #ifndef ASSIMP_BUILD_NO_IQM_IMPORTER out.push_back(new IQMImporter()); #endif - //#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER - // out.push_back(new StepFile::StepFileImporter()); - //#endif } /** will delete all registered importers. */