From 5b13b97f27ef6362b0d63a16c536fb26b224efef Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Tue, 19 Oct 2021 14:22:28 +0100 Subject: [PATCH 01/25] Ensure the usage pattern of SpatialSort. --- code/Common/SpatialSort.cpp | 15 ++++++++++++--- include/assimp/SpatialSort.h | 3 +++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/code/Common/SpatialSort.cpp b/code/Common/SpatialSort.cpp index 2bd848164..3ef9f055b 100644 --- a/code/Common/SpatialSort.cpp +++ b/code/Common/SpatialSort.cpp @@ -58,14 +58,16 @@ const aiVector3D PlaneInit(0.8523f, 0.34321f, 0.5736f); // define the reference plane. We choose some arbitrary vector away from all basic axes // in the hope that no model spreads all its vertices along this plane. SpatialSort::SpatialSort(const aiVector3D *pPositions, unsigned int pNumPositions, unsigned int pElementOffset) : - mPlaneNormal(PlaneInit) { + mPlaneNormal(PlaneInit), + mFinalized(false) { mPlaneNormal.Normalize(); Fill(pPositions, pNumPositions, pElementOffset); } // ------------------------------------------------------------------------------------------------ SpatialSort::SpatialSort() : - mPlaneNormal(PlaneInit) { + mPlaneNormal(PlaneInit), + mFinalized(false) { mPlaneNormal.Normalize(); } @@ -80,21 +82,25 @@ void SpatialSort::Fill(const aiVector3D *pPositions, unsigned int pNumPositions, unsigned int pElementOffset, bool pFinalize /*= true */) { mPositions.clear(); + mFinalized = false; Append(pPositions, pNumPositions, pElementOffset, pFinalize); + mFinalized = pFinalize; } // ------------------------------------------------------------------------------------------------ void SpatialSort::Finalize() { std::sort(mPositions.begin(), mPositions.end()); + mFinalized = true; } // ------------------------------------------------------------------------------------------------ void SpatialSort::Append(const aiVector3D *pPositions, unsigned int pNumPositions, unsigned int pElementOffset, bool pFinalize /*= true */) { + ai_assert(!mFinalized && "You cannot add positions to the SpatialSort object after it has been finalized."); // store references to all given positions along with their distance to the reference plane const size_t initial = mPositions.size(); - mPositions.reserve(initial + (pFinalize ? pNumPositions : pNumPositions * 2)); + mPositions.reserve(initial + pNumPositions); for (unsigned int a = 0; a < pNumPositions; a++) { const char *tempPointer = reinterpret_cast(pPositions); const aiVector3D *vec = reinterpret_cast(tempPointer + a * pElementOffset); @@ -114,6 +120,7 @@ void SpatialSort::Append(const aiVector3D *pPositions, unsigned int pNumPosition // Returns an iterator for all positions close to the given position. void SpatialSort::FindPositions(const aiVector3D &pPosition, ai_real pRadius, std::vector &poResults) const { + ai_assert(mFinalized && "The SpatialSort object must be finalized before FindPositions can be called."); const ai_real dist = pPosition * mPlaneNormal; const ai_real minDist = dist - pRadius, maxDist = dist + pRadius; @@ -229,6 +236,7 @@ BinFloat ToBinary(const ai_real &pValue) { // Fills an array with indices of all positions identical to the given position. In opposite to // FindPositions(), not an epsilon is used but a (very low) tolerance of four floating-point units. void SpatialSort::FindIdenticalPositions(const aiVector3D &pPosition, std::vector &poResults) const { + ai_assert(mFinalized && "The SpatialSort object must be finalized before FindIdenticalPositions can be called."); // Epsilons have a huge disadvantage: they are of constant precision, while floating-point // values are of log2 precision. If you apply e=0.01 to 100, the epsilon is rather small, but // if you apply it to 0.001, it is enormous. @@ -297,6 +305,7 @@ void SpatialSort::FindIdenticalPositions(const aiVector3D &pPosition, std::vecto // ------------------------------------------------------------------------------------------------ unsigned int SpatialSort::GenerateMappingTable(std::vector &fill, ai_real pRadius) const { + ai_assert(mFinalized && "The SpatialSort object must be finalized before GenerateMappingTable can be called."); fill.resize(mPositions.size(), UINT_MAX); ai_real dist, maxDist; diff --git a/include/assimp/SpatialSort.h b/include/assimp/SpatialSort.h index 39ebae77b..5db23c86b 100644 --- a/include/assimp/SpatialSort.h +++ b/include/assimp/SpatialSort.h @@ -168,6 +168,9 @@ protected: // all positions, sorted by distance to the sorting plane std::vector mPositions; + + // False until the Finalize method is called. + bool mFinalized; }; } // end of namespace Assimp From 4d10f5d133af0c88aa3557e049709e3fa44f53b6 Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Wed, 20 Oct 2021 12:47:44 +0100 Subject: [PATCH 02/25] Move distance initialization to Finalize. --- code/Common/SpatialSort.cpp | 8 ++++---- include/assimp/SpatialSort.h | 12 +++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/code/Common/SpatialSort.cpp b/code/Common/SpatialSort.cpp index 3ef9f055b..a8afbfaf6 100644 --- a/code/Common/SpatialSort.cpp +++ b/code/Common/SpatialSort.cpp @@ -89,6 +89,9 @@ void SpatialSort::Fill(const aiVector3D *pPositions, unsigned int pNumPositions, // ------------------------------------------------------------------------------------------------ void SpatialSort::Finalize() { + for (unsigned int i = 0; i < mPositions.size(); i++) { + mPositions[i].mDistance = mPositions[i].mPosition * mPlaneNormal; + } std::sort(mPositions.begin(), mPositions.end()); mFinalized = true; } @@ -104,10 +107,7 @@ void SpatialSort::Append(const aiVector3D *pPositions, unsigned int pNumPosition for (unsigned int a = 0; a < pNumPositions; a++) { const char *tempPointer = reinterpret_cast(pPositions); const aiVector3D *vec = reinterpret_cast(tempPointer + a * pElementOffset); - - // store position by index and distance - ai_real distance = *vec * mPlaneNormal; - mPositions.push_back(Entry(static_cast(a + initial), *vec, distance)); + mPositions.push_back(Entry(static_cast(a + initial), *vec)); } if (pFinalize) { diff --git a/include/assimp/SpatialSort.h b/include/assimp/SpatialSort.h index 5db23c86b..475a11d7c 100644 --- a/include/assimp/SpatialSort.h +++ b/include/assimp/SpatialSort.h @@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include namespace Assimp { @@ -150,16 +151,17 @@ protected: struct Entry { unsigned int mIndex; ///< The vertex referred by this entry aiVector3D mPosition; ///< Position - ai_real mDistance; ///< Distance of this vertex to the sorting plane + /// Distance of this vertex to the sorting plane. This is set by Finalize. + ai_real mDistance; Entry() AI_NO_EXCEPT - : mIndex(999999999), + : mIndex(std::numeric_limits::max()), mPosition(), - mDistance(99999.) { + mDistance(std::numeric_limits::max()) { // empty } - Entry(unsigned int pIndex, const aiVector3D &pPosition, ai_real pDistance) : - mIndex(pIndex), mPosition(pPosition), mDistance(pDistance) { + Entry(unsigned int pIndex, const aiVector3D &pPosition) : + mIndex(pIndex), mPosition(pPosition) { // empty } From c644f9d71979143674686d88534bf738fd27bfd6 Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Wed, 20 Oct 2021 15:08:08 +0100 Subject: [PATCH 03/25] Subtract the centroid --- code/Common/SpatialSort.cpp | 12 +++++++---- include/assimp/SpatialSort.h | 7 ++++-- test/unit/Common/utSpatialSort.cpp | 34 ++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/code/Common/SpatialSort.cpp b/code/Common/SpatialSort.cpp index a8afbfaf6..08a7c55df 100644 --- a/code/Common/SpatialSort.cpp +++ b/code/Common/SpatialSort.cpp @@ -89,8 +89,12 @@ void SpatialSort::Fill(const aiVector3D *pPositions, unsigned int pNumPositions, // ------------------------------------------------------------------------------------------------ void SpatialSort::Finalize() { + const ai_real scale = 1.0f / mPositions.size(); for (unsigned int i = 0; i < mPositions.size(); i++) { - mPositions[i].mDistance = mPositions[i].mPosition * mPlaneNormal; + mCentroid += scale * mPositions[i].mPosition; + } + for (unsigned int i = 0; i < mPositions.size(); i++) { + mPositions[i].mDistance = (mPositions[i].mPosition - mCentroid) * mPlaneNormal; } std::sort(mPositions.begin(), mPositions.end()); mFinalized = true; @@ -121,7 +125,7 @@ void SpatialSort::Append(const aiVector3D *pPositions, unsigned int pNumPosition void SpatialSort::FindPositions(const aiVector3D &pPosition, ai_real pRadius, std::vector &poResults) const { ai_assert(mFinalized && "The SpatialSort object must be finalized before FindPositions can be called."); - const ai_real dist = pPosition * mPlaneNormal; + const ai_real dist = (pPosition - mCentroid) * mPlaneNormal; const ai_real minDist = dist - pRadius, maxDist = dist + pRadius; // clear the array @@ -262,7 +266,7 @@ void SpatialSort::FindIdenticalPositions(const aiVector3D &pPosition, std::vecto // Convert the plane distance to its signed integer representation so the ULPs tolerance can be // applied. For some reason, VC won't optimize two calls of the bit pattern conversion. - const BinFloat minDistBinary = ToBinary(pPosition * mPlaneNormal) - distanceToleranceInULPs; + const BinFloat minDistBinary = ToBinary((pPosition - mCentroid) * mPlaneNormal) - distanceToleranceInULPs; const BinFloat maxDistBinary = minDistBinary + 2 * distanceToleranceInULPs; // clear the array in this strange fashion because a simple clear() would also deallocate @@ -312,7 +316,7 @@ unsigned int SpatialSort::GenerateMappingTable(std::vector &fill, unsigned int t = 0; const ai_real pSquared = pRadius * pRadius; for (size_t i = 0; i < mPositions.size();) { - dist = mPositions[i].mPosition * mPlaneNormal; + dist = (mPositions[i].mPosition - mCentroid) * mPlaneNormal; maxDist = dist + pRadius; fill[mPositions[i].mIndex] = t; diff --git a/include/assimp/SpatialSort.h b/include/assimp/SpatialSort.h index 475a11d7c..39f863b15 100644 --- a/include/assimp/SpatialSort.h +++ b/include/assimp/SpatialSort.h @@ -143,7 +143,7 @@ public: ai_real pRadius) const; protected: - /** Normal of the sorting plane, normalized. The center is always at (0, 0, 0) */ + /** Normal of the sorting plane, normalized. */ aiVector3D mPlaneNormal; /** An entry in a spatially sorted position array. Consists of a vertex index, @@ -171,8 +171,11 @@ protected: // all positions, sorted by distance to the sorting plane std::vector mPositions; - // False until the Finalize method is called. + /// false until the Finalize method is called. bool mFinalized; + + /// The centroid of the positions. Calculated in Finalize. + aiVector3D mCentroid; }; } // end of namespace Assimp diff --git a/test/unit/Common/utSpatialSort.cpp b/test/unit/Common/utSpatialSort.cpp index 94dfd2dc4..ba411d99f 100644 --- a/test/unit/Common/utSpatialSort.cpp +++ b/test/unit/Common/utSpatialSort.cpp @@ -82,3 +82,37 @@ TEST_F(utSpatialSort, findPositionsTest) { sSort.FindPositions(vecs[0], 0.01f, indices); EXPECT_EQ(1u, indices.size()); } + +TEST_F(utSpatialSort, highlyDisplacedPositionsTest) { + constexpr unsigned int verticesPerAxis = 10; + constexpr ai_real step = 0.001f; + constexpr ai_real offset = 5000.0f - (0.5f * verticesPerAxis * step); + constexpr unsigned int totalNumPositions = verticesPerAxis * verticesPerAxis * verticesPerAxis; + aiVector3D* positions = new aiVector3D[totalNumPositions]; + for (unsigned int x = 0; x < verticesPerAxis; ++x) { + for (unsigned int y = 0; y < verticesPerAxis; ++y) { + for (unsigned int z = 0; z < verticesPerAxis; ++z) { + const unsigned int index = (x * verticesPerAxis * verticesPerAxis) + (y * verticesPerAxis) + z; + positions[index] = aiVector3D(offset + (x * step), offset + (y * step), offset + (z * step)); + } + } + } + + SpatialSort sSort; + sSort.Fill(positions, totalNumPositions, sizeof(aiVector3D)); + + // Enough to pick up the neighboring vertices, but not the neighbors' neighbors. + const ai_real epsilon = 1.1f * step; + std::vector indices; + // Iterate through the interior points of the cube. + for (unsigned int x = 1; x < verticesPerAxis - 1; ++x) { + for (unsigned int y = 1; y < verticesPerAxis - 1; ++y) { + for (unsigned int z = 1; z < verticesPerAxis - 1; ++z) { + const unsigned int index = (x * verticesPerAxis * verticesPerAxis) + (y * verticesPerAxis) + z; + sSort.FindPositions(positions[index], epsilon, indices); + ASSERT_EQ(7u, indices.size()); + } + } + } + delete[] positions; +} From 4ba99c1bb08709fc7e0106d626af0f9e3c95fee9 Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Wed, 20 Oct 2021 16:15:00 +0100 Subject: [PATCH 04/25] Comments --- test/unit/Common/utSpatialSort.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/unit/Common/utSpatialSort.cpp b/test/unit/Common/utSpatialSort.cpp index ba411d99f..8ebae76e8 100644 --- a/test/unit/Common/utSpatialSort.cpp +++ b/test/unit/Common/utSpatialSort.cpp @@ -84,8 +84,10 @@ TEST_F(utSpatialSort, findPositionsTest) { } TEST_F(utSpatialSort, highlyDisplacedPositionsTest) { + // Make a cube of positions, and then query it using the SpatialSort object. constexpr unsigned int verticesPerAxis = 10; constexpr ai_real step = 0.001f; + // Note the large constant offset here. constexpr ai_real offset = 5000.0f - (0.5f * verticesPerAxis * step); constexpr unsigned int totalNumPositions = verticesPerAxis * verticesPerAxis * verticesPerAxis; aiVector3D* positions = new aiVector3D[totalNumPositions]; @@ -101,10 +103,10 @@ TEST_F(utSpatialSort, highlyDisplacedPositionsTest) { SpatialSort sSort; sSort.Fill(positions, totalNumPositions, sizeof(aiVector3D)); - // Enough to pick up the neighboring vertices, but not the neighbors' neighbors. + // Enough to pick up a point and its 6 immediate neighbors, but not any other point. const ai_real epsilon = 1.1f * step; std::vector indices; - // Iterate through the interior points of the cube. + // Iterate through the _interior_ points of the cube. for (unsigned int x = 1; x < verticesPerAxis - 1; ++x) { for (unsigned int y = 1; y < verticesPerAxis - 1; ++y) { for (unsigned int z = 1; z < verticesPerAxis - 1; ++z) { From db0127859aeb27add83afc9440f41e1a0a8db6db Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Thu, 21 Oct 2021 08:39:44 +0100 Subject: [PATCH 05/25] CalculateDistance method --- code/Common/SpatialSort.cpp | 11 ++++++++--- include/assimp/SpatialSort.h | 17 ++++++++++++----- test/unit/Common/utSpatialSort.cpp | 2 +- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/code/Common/SpatialSort.cpp b/code/Common/SpatialSort.cpp index 08a7c55df..9b96887ac 100644 --- a/code/Common/SpatialSort.cpp +++ b/code/Common/SpatialSort.cpp @@ -87,6 +87,11 @@ void SpatialSort::Fill(const aiVector3D *pPositions, unsigned int pNumPositions, mFinalized = pFinalize; } +// ------------------------------------------------------------------------------------------------ +ai_real SpatialSort::CalculateDistance(const aiVector3D &pPosition) const { + return (pPosition - mCentroid) * mPlaneNormal; +} + // ------------------------------------------------------------------------------------------------ void SpatialSort::Finalize() { const ai_real scale = 1.0f / mPositions.size(); @@ -94,7 +99,7 @@ void SpatialSort::Finalize() { mCentroid += scale * mPositions[i].mPosition; } for (unsigned int i = 0; i < mPositions.size(); i++) { - mPositions[i].mDistance = (mPositions[i].mPosition - mCentroid) * mPlaneNormal; + mPositions[i].mDistance = CalculateDistance(mPositions[i].mPosition); } std::sort(mPositions.begin(), mPositions.end()); mFinalized = true; @@ -125,7 +130,7 @@ void SpatialSort::Append(const aiVector3D *pPositions, unsigned int pNumPosition void SpatialSort::FindPositions(const aiVector3D &pPosition, ai_real pRadius, std::vector &poResults) const { ai_assert(mFinalized && "The SpatialSort object must be finalized before FindPositions can be called."); - const ai_real dist = (pPosition - mCentroid) * mPlaneNormal; + const ai_real dist = CalculateDistance(pPosition); const ai_real minDist = dist - pRadius, maxDist = dist + pRadius; // clear the array @@ -266,7 +271,7 @@ void SpatialSort::FindIdenticalPositions(const aiVector3D &pPosition, std::vecto // Convert the plane distance to its signed integer representation so the ULPs tolerance can be // applied. For some reason, VC won't optimize two calls of the bit pattern conversion. - const BinFloat minDistBinary = ToBinary((pPosition - mCentroid) * mPlaneNormal) - distanceToleranceInULPs; + const BinFloat minDistBinary = ToBinary(CalculateDistance(pPosition)) - distanceToleranceInULPs; const BinFloat maxDistBinary = minDistBinary + 2 * distanceToleranceInULPs; // clear the array in this strange fashion because a simple clear() would also deallocate diff --git a/include/assimp/SpatialSort.h b/include/assimp/SpatialSort.h index 39f863b15..c0c4a0292 100644 --- a/include/assimp/SpatialSort.h +++ b/include/assimp/SpatialSort.h @@ -143,9 +143,19 @@ public: ai_real pRadius) const; protected: - /** Normal of the sorting plane, normalized. */ + /** Return the distance to the sorting plane. */ + ai_real CalculateDistance(const aiVector3D &pPosition) const; + +protected: + /** Normal of the sorting plane, normalized. + */ aiVector3D mPlaneNormal; + /** The centroid of the positions, which is used as a point on the sorting plane + * when calculating distance. This value is calculated in Finalize. + */ + aiVector3D mCentroid; + /** An entry in a spatially sorted position array. Consists of a vertex index, * its position and its pre-calculated distance from the reference plane */ struct Entry { @@ -161,7 +171,7 @@ protected: // empty } Entry(unsigned int pIndex, const aiVector3D &pPosition) : - mIndex(pIndex), mPosition(pPosition) { + mIndex(pIndex), mPosition(pPosition), mDistance(std::numeric_limits::max()) { // empty } @@ -173,9 +183,6 @@ protected: /// false until the Finalize method is called. bool mFinalized; - - /// The centroid of the positions. Calculated in Finalize. - aiVector3D mCentroid; }; } // end of namespace Assimp diff --git a/test/unit/Common/utSpatialSort.cpp b/test/unit/Common/utSpatialSort.cpp index 8ebae76e8..f0b694c7d 100644 --- a/test/unit/Common/utSpatialSort.cpp +++ b/test/unit/Common/utSpatialSort.cpp @@ -103,7 +103,7 @@ TEST_F(utSpatialSort, highlyDisplacedPositionsTest) { SpatialSort sSort; sSort.Fill(positions, totalNumPositions, sizeof(aiVector3D)); - // Enough to pick up a point and its 6 immediate neighbors, but not any other point. + // Enough to find a point and its 6 immediate neighbors, but not any other point. const ai_real epsilon = 1.1f * step; std::vector indices; // Iterate through the _interior_ points of the cube. From e01b488075209cc76af56620539d345c6e0395e6 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 26 Oct 2021 22:06:10 +0200 Subject: [PATCH 06/25] Remove dead code. --- code/AssetLib/3MF/XmlSerializer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/code/AssetLib/3MF/XmlSerializer.cpp b/code/AssetLib/3MF/XmlSerializer.cpp index 7a33d08ed..985286fa7 100644 --- a/code/AssetLib/3MF/XmlSerializer.cpp +++ b/code/AssetLib/3MF/XmlSerializer.cpp @@ -159,7 +159,6 @@ bool parseColor(const char *color, aiColor4D &diffuse) { return false; } - //const char *buf(color); if ('#' != color[0]) { return false; } From 6e5600a9a5bd2fa2aafa577fd0b113d99ba5b2b4 Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Thu, 28 Oct 2021 10:26:14 -0400 Subject: [PATCH 07/25] Added another constructor to avoid requiring a full ANativeActivity --- include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h | 2 ++ port/AndroidJNI/AndroidJNIIOSystem.cpp | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h b/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h index 01505d571..370327542 100644 --- a/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h +++ b/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h @@ -65,6 +65,8 @@ public: /** Constructor. */ AndroidJNIIOSystem(ANativeActivity* activity); + AndroidJNIIOSystem(const char *internalPath, AAssetManager assetManager); + /** Destructor. */ ~AndroidJNIIOSystem(); diff --git a/port/AndroidJNI/AndroidJNIIOSystem.cpp b/port/AndroidJNI/AndroidJNIIOSystem.cpp index db499a20b..bed40ce51 100644 --- a/port/AndroidJNI/AndroidJNIIOSystem.cpp +++ b/port/AndroidJNI/AndroidJNIIOSystem.cpp @@ -67,6 +67,12 @@ AndroidJNIIOSystem::AndroidJNIIOSystem(ANativeActivity* activity) AndroidActivityInit(activity); } +AndroidJNIIOSystem::AndroidJNIIOSystem(const char *internalPath, AAssetManager assetManager) +{ + mApkWorkspacePath = internalDataPath; + mApkAssetManager = assetManager; +} + // ------------------------------------------------------------------------------------------------ // Destructor. AndroidJNIIOSystem::~AndroidJNIIOSystem() From e5cd5733e1c2e5aae93382dae0b2524657a96c7a Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 28 Oct 2021 17:50:25 +0200 Subject: [PATCH 08/25] Update AndroidJNIIOSystem.cpp --- port/AndroidJNI/AndroidJNIIOSystem.cpp | 169 ++++++++++++------------- 1 file changed, 83 insertions(+), 86 deletions(-) diff --git a/port/AndroidJNI/AndroidJNIIOSystem.cpp b/port/AndroidJNI/AndroidJNIIOSystem.cpp index bed40ce51..00cf3af9c 100644 --- a/port/AndroidJNI/AndroidJNIIOSystem.cpp +++ b/port/AndroidJNI/AndroidJNIIOSystem.cpp @@ -3,7 +3,7 @@ Open Asset Import Library (assimp) --------------------------------------------------------------------------- -Copyright (c) 2006-2020, assimp team +Copyright (c) 2006-2021, assimp team All rights reserved. @@ -67,51 +67,50 @@ AndroidJNIIOSystem::AndroidJNIIOSystem(ANativeActivity* activity) AndroidActivityInit(activity); } -AndroidJNIIOSystem::AndroidJNIIOSystem(const char *internalPath, AAssetManager assetManager) -{ - mApkWorkspacePath = internalDataPath; - mApkAssetManager = assetManager; +AndroidJNIIOSystem::AndroidJNIIOSystem(const char *internalPath, AAssetManager assetManager) : + mApkWorkspacePath(internalDataPath), + mApkAssetManager(assetManager) { + // empty } // ------------------------------------------------------------------------------------------------ // Destructor. -AndroidJNIIOSystem::~AndroidJNIIOSystem() -{ - // nothing to do here +AndroidJNIIOSystem::~AndroidJNIIOSystem() { + // nothing to do here } // ------------------------------------------------------------------------------------------------ // Tests for the existence of a file at the given path. -bool AndroidJNIIOSystem::Exists( const char* pFile) const -{ - AAsset* asset = AAssetManager_open(mApkAssetManager, pFile, - AASSET_MODE_UNKNOWN); - FILE* file = ::fopen( (mApkWorkspacePath + getOsSeparator() + std::string(pFile)).c_str(), "rb"); +bool AndroidJNIIOSystem::Exists( const char* pFile) const { + AAsset* asset = AAssetManager_open(mApkAssetManager, pFile, AASSET_MODE_UNKNOWN); + FILE* file = ::fopen( (mApkWorkspacePath + getOsSeparator() + std::string(pFile)).c_str(), "rb"); + + if (!asset && !file) { + __android_log_print(ANDROID_LOG_ERROR, "Assimp", "Asset manager can not find: %s", pFile); + return false; + } - if (!asset && !file) - { - __android_log_print(ANDROID_LOG_ERROR, "Assimp", "Asset manager can not find: %s", pFile); - return false; - } - - __android_log_print(ANDROID_LOG_ERROR, "Assimp", "Asset exists"); - if (file) - ::fclose( file); - return true; + __android_log_print(ANDROID_LOG_ERROR, "Assimp", "Asset exists"); + if (file) { + ::fclose( file); + } + + return true; } // ------------------------------------------------------------------------------------------------ // Inits Android extractor -void AndroidJNIIOSystem::AndroidActivityInit(ANativeActivity* activity) -{ - mApkWorkspacePath = activity->internalDataPath; - mApkAssetManager = activity->assetManager; +void AndroidJNIIOSystem::AndroidActivityInit(ANativeActivity* activity) { + if (activity == nullptr) { + return; + } + mApkWorkspacePath = activity->internalDataPath; + mApkAssetManager = activity->assetManager; } // ------------------------------------------------------------------------------------------------ // Create the directory for the extracted resource -static int mkpath(std::string path, mode_t mode) -{ +static int mkpath(std::string path, mode_t mode) { if (mkdir(path.c_str(), mode) == -1) { switch(errno) { case ENOENT: @@ -131,82 +130,80 @@ static int mkpath(std::string path, mode_t mode) // ------------------------------------------------------------------------------------------------ // Extracts android asset -bool AndroidJNIIOSystem::AndroidExtractAsset(std::string name) -{ - std::string newPath = mApkWorkspacePath + getOsSeparator() + name; +bool AndroidJNIIOSystem::AndroidExtractAsset(std::string name) { + std::string newPath = mApkWorkspacePath + getOsSeparator() + name; - DefaultIOSystem io; + DefaultIOSystem io; - // Do not extract if extracted already - if ( io.Exists(newPath.c_str()) ) { - __android_log_print(ANDROID_LOG_DEFAULT, "Assimp", "Asset already extracted"); - return true; - } - // Open file - AAsset* asset = AAssetManager_open(mApkAssetManager, name.c_str(), + // Do not extract if extracted already + if ( io.Exists(newPath.c_str()) ) { + __android_log_print(ANDROID_LOG_DEFAULT, "Assimp", "Asset already extracted"); + return true; + } + + // Open file + AAsset* asset = AAssetManager_open(mApkAssetManager, name.c_str(), AASSET_MODE_UNKNOWN); - std::vector assetContent; + std::vector assetContent; - if (asset != NULL) { - // Find size - off_t assetSize = AAsset_getLength(asset); + if (asset != NULL) { + // Find size + off_t assetSize = AAsset_getLength(asset); - // Prepare input buffer - assetContent.resize(assetSize); + // Prepare input buffer + assetContent.resize(assetSize); - // Store input buffer - AAsset_read(asset, &assetContent[0], assetSize); + // Store input buffer + AAsset_read(asset, &assetContent[0], assetSize); - // Close - AAsset_close(asset); + // Close + AAsset_close(asset); - // Prepare directory for output buffer - std::string directoryNewPath = newPath; - directoryNewPath = dirname(&directoryNewPath[0]); + // Prepare directory for output buffer + std::string directoryNewPath = newPath; + directoryNewPath = dirname(&directoryNewPath[0]); - if (mkpath(directoryNewPath, S_IRUSR | S_IWUSR | S_IXUSR) == -1) { - __android_log_print(ANDROID_LOG_ERROR, "assimp", - "Can not create the directory for the output file"); - } + if (mkpath(directoryNewPath, S_IRUSR | S_IWUSR | S_IXUSR) == -1) { + __android_log_print(ANDROID_LOG_ERROR, "assimp", "Can not create the directory for the output file"); + } - // Prepare output buffer - std::ofstream assetExtracted(newPath.c_str(), - std::ios::out | std::ios::binary); - if (!assetExtracted) { - __android_log_print(ANDROID_LOG_ERROR, "assimp", - "Can not open output file"); - } + // Prepare output buffer + std::ofstream assetExtracted(newPath.c_str(), std::ios::out | std::ios::binary); + if (!assetExtracted) { + __android_log_print(ANDROID_LOG_ERROR, "assimp", "Can not open output file"); + } - // Write output buffer into a file - assetExtracted.write(&assetContent[0], assetContent.size()); - assetExtracted.close(); + // Write output buffer into a file + assetExtracted.write(&assetContent[0], assetContent.size()); + assetExtracted.close(); - __android_log_print(ANDROID_LOG_DEFAULT, "Assimp", "Asset extracted"); - } else { - __android_log_print(ANDROID_LOG_ERROR, "assimp", "Asset not found: %s", name.c_str()); - return false; - } - return true; + __android_log_print(ANDROID_LOG_DEFAULT, "Assimp", "Asset extracted"); + } else { + __android_log_print(ANDROID_LOG_ERROR, "assimp", "Asset not found: %s", name.c_str()); + return false; + } + + return true; } // ------------------------------------------------------------------------------------------------ // Open a new file with a given path. -IOStream* AndroidJNIIOSystem::Open( const char* strFile, const char* strMode) -{ - ai_assert(NULL != strFile); - ai_assert(NULL != strMode); +IOStream* AndroidJNIIOSystem::Open( const char* strFile, const char* strMode) { + ai_assert(nullptr != strFile); + ai_assert(nullptr != strMode); - std::string fullPath(mApkWorkspacePath + getOsSeparator() + std::string(strFile)); - if (Exists(strFile)) - AndroidExtractAsset(std::string(strFile)); + std::string fullPath(mApkWorkspacePath + getOsSeparator() + std::string(strFile)); + if (Exists(strFile)) { + AndroidExtractAsset(std::string(strFile)); + } - FILE* file = ::fopen( fullPath.c_str(), strMode); + FILE* file = ::fopen( fullPath.c_str(), strMode); + if (nullptr == file) { + return nullptr; + } - if( NULL == file) - return NULL; - - __android_log_print(ANDROID_LOG_ERROR, "assimp", "AndroidIOSystem: file %s opened", fullPath.c_str()); - return new DefaultIOStream(file, fullPath); + __android_log_print(ANDROID_LOG_ERROR, "assimp", "AndroidIOSystem: file %s opened", fullPath.c_str()); + return new DefaultIOStream(file, fullPath); } #undef PATHLIMIT From 5333e41607f07046c3a15c55bc74e1eecfad0ab7 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 28 Oct 2021 17:52:01 +0200 Subject: [PATCH 09/25] Update AndroidJNIIOSystem.h --- .../port/AndroidJNI/AndroidJNIIOSystem.h | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h b/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h index 370327542..bb52d3065 100644 --- a/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h +++ b/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h @@ -2,7 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2020, assimp team +Copyright (c) 2006-2021, assimp team All rights reserved. Redistribution and use of this software in source and binary forms, @@ -54,38 +54,32 @@ namespace Assimp { // --------------------------------------------------------------------------- /** Android extension to DefaultIOSystem using the standard C file functions */ -class ASSIMP_API AndroidJNIIOSystem : public DefaultIOSystem -{ +class ASSIMP_API AndroidJNIIOSystem : public DefaultIOSystem { public: - /** Initialize android activity data */ std::string mApkWorkspacePath; AAssetManager* mApkAssetManager; - /** Constructor. */ + /// Constructor. AndroidJNIIOSystem(ANativeActivity* activity); + /// Class constructor with past and asset manager. AndroidJNIIOSystem(const char *internalPath, AAssetManager assetManager); - /** Destructor. */ + /// Destructor. ~AndroidJNIIOSystem(); - // ------------------------------------------------------------------- - /** Tests for the existence of a file at the given path. */ + /// Tests for the existence of a file at the given path. bool Exists( const char* pFile) const; - // ------------------------------------------------------------------- - /** Opens a file at the given path, with given mode */ + /// Opens a file at the given path, with given mode IOStream* Open( const char* strFile, const char* strMode); - // ------------------------------------------------------------------------------------------------ - // Inits Android extractor + /// Inits Android extractor void AndroidActivityInit(ANativeActivity* activity); - // ------------------------------------------------------------------------------------------------ - // Extracts android asset + /// Extracts android asset bool AndroidExtractAsset(std::string name); - }; } //!ns Assimp From 30f17aa2064b86c0096f0ec701b9e8ea9312fef2 Mon Sep 17 00:00:00 2001 From: Alex Rebert Date: Thu, 28 Oct 2021 21:32:38 -0400 Subject: [PATCH 10/25] Fix heap out-of-bounds write in _m3d_safestr While there is a 256 character limit when computing the length of the newly allocated strength, that limit was missing when copying the string. This commit adds a new length check in the copy loop, preventing it from writhing out of bounds. Fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=34416 --- code/AssetLib/M3D/m3d.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/M3D/m3d.h b/code/AssetLib/M3D/m3d.h index b148c11d7..875007eab 100644 --- a/code/AssetLib/M3D/m3d.h +++ b/code/AssetLib/M3D/m3d.h @@ -896,7 +896,7 @@ char *_m3d_safestr(char *in, int morelines) { if (!out) return NULL; while (*i == ' ' || *i == '\t' || *i == '\r' || (morelines && *i == '\n')) i++; - for (; *i && (morelines || (*i != '\r' && *i != '\n')); i++) { + for (; *i && (morelines || (*i != '\r' && *i != '\n')) && o - out < l; i++) { if (*i == '\r') continue; if (*i == '\n') { if (morelines >= 3 && o > out && *(o - 1) == '\n') break; From 932dfe05627c139013b9ea5d5e0e0e296b467e7e Mon Sep 17 00:00:00 2001 From: Alex Rebert Date: Thu, 28 Oct 2021 22:27:19 -0400 Subject: [PATCH 11/25] Fix overflowing allocations in MDLMaterialLoader Some allocations might underallocate due to integer overflows. This commit ensures that we are throwing an exception if the allocation size does not fit in an unsigned int. Fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=25341 --- code/AssetLib/MDL/MDLMaterialLoader.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/AssetLib/MDL/MDLMaterialLoader.cpp b/code/AssetLib/MDL/MDLMaterialLoader.cpp index f44896819..62320814a 100644 --- a/code/AssetLib/MDL/MDLMaterialLoader.cpp +++ b/code/AssetLib/MDL/MDLMaterialLoader.cpp @@ -132,6 +132,9 @@ void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char *szData) { pcNew->mWidth = pcHeader->skinwidth; pcNew->mHeight = pcHeader->skinheight; + if(pcNew->mWidth != 0 && pcNew->mHeight > UINT_MAX/pcNew->mWidth) { + throw DeadlyImportError("Invalid MDL file. A texture is too big."); + } pcNew->pcData = new aiTexel[pcNew->mWidth * pcNew->mHeight]; const unsigned char *szColorMap; @@ -217,6 +220,9 @@ void MDLImporter::ParseTextureColorData(const unsigned char *szData, // allocate storage for the texture image if (do_read) { + if(pcNew->mWidth != 0 && pcNew->mHeight > UINT_MAX/pcNew->mWidth) { + throw DeadlyImportError("Invalid MDL file. A texture is too big."); + } pcNew->pcData = new aiTexel[pcNew->mWidth * pcNew->mHeight]; } From 1fe9d405f5c4811eb6073cf5fc6622842192e06b Mon Sep 17 00:00:00 2001 From: Alex Rebert Date: Thu, 28 Oct 2021 22:36:11 -0400 Subject: [PATCH 12/25] Fix out-of-bounds read in MDLImporter Fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=24502 --- code/AssetLib/MDL/MDLLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/MDL/MDLLoader.cpp b/code/AssetLib/MDL/MDLLoader.cpp index 40475021b..c59375da0 100644 --- a/code/AssetLib/MDL/MDLLoader.cpp +++ b/code/AssetLib/MDL/MDLLoader.cpp @@ -600,7 +600,7 @@ void MDLImporter::InternReadFile_3DGS_MDL345() { // need to read all textures for (unsigned int i = 0; i < (unsigned int)pcHeader->num_skins; ++i) { - if (szCurrent >= szEnd) { + if (szCurrent + sizeof(uint32_t) > szEnd) { throw DeadlyImportError("Texture data past end of file."); } BE_NCONST MDL::Skin *pcSkin; From 107371657b39c8cd4bcc8d8865d9071ff17049d2 Mon Sep 17 00:00:00 2001 From: Alex Rebert Date: Thu, 28 Oct 2021 23:12:54 -0400 Subject: [PATCH 13/25] Fix out-of-bounds read in ReadFirstSkin Fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=25401 --- code/AssetLib/HMP/HMPLoader.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/AssetLib/HMP/HMPLoader.cpp b/code/AssetLib/HMP/HMPLoader.cpp index 97c1858fb..661e4d1b2 100644 --- a/code/AssetLib/HMP/HMPLoader.cpp +++ b/code/AssetLib/HMP/HMPLoader.cpp @@ -451,6 +451,7 @@ void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char *szC // now we need to skip any other skins ... for (unsigned int i = 1; i < iNumSkins; ++i) { + SizeCheck(szCursor + 3 * sizeof(uint32_t)); iType = *((uint32_t *)szCursor); szCursor += sizeof(uint32_t); iWidth = *((uint32_t *)szCursor); From 6a3ac623b960905b3450b78e7614453dae0540ed Mon Sep 17 00:00:00 2001 From: Alex Rebert Date: Thu, 28 Oct 2021 23:13:29 -0400 Subject: [PATCH 14/25] Fix out-of-bounds reads in OpenDDLParser Fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=31795 Fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=24463 Fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=36594 --- contrib/openddlparser/code/OpenDDLParser.cpp | 20 +++++++++++-------- .../openddlparser/OpenDDLParserUtils.h | 3 ++- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/contrib/openddlparser/code/OpenDDLParser.cpp b/contrib/openddlparser/code/OpenDDLParser.cpp index 0c9e0bd98..e2bef97a7 100644 --- a/contrib/openddlparser/code/OpenDDLParser.cpp +++ b/contrib/openddlparser/code/OpenDDLParser.cpp @@ -292,12 +292,15 @@ char *OpenDDLParser::parseHeader(char *in, char *end) { Property *first(nullptr); in = lookForNextToken(in, end); - if (*in == Grammar::OpenPropertyToken[0]) { + if (in != end && *in == Grammar::OpenPropertyToken[0]) { in++; Property *prop(nullptr), *prev(nullptr); - while (*in != Grammar::ClosePropertyToken[0] && in != end) { + while (in != end && *in != Grammar::ClosePropertyToken[0]) { in = OpenDDLParser::parseProperty(in, end, &prop); in = lookForNextToken(in, end); + if(in == end) { + break; + } if (*in != Grammar::CommaSeparator[0] && *in != Grammar::ClosePropertyToken[0]) { logInvalidTokenError(in, Grammar::ClosePropertyToken, m_logCallback); @@ -314,7 +317,9 @@ char *OpenDDLParser::parseHeader(char *in, char *end) { prev = prop; } } - ++in; + if(in != end) { + ++in; + } } // set the properties @@ -479,7 +484,7 @@ void OpenDDLParser::normalizeBuffer(std::vector &buffer) { // check for a comment if (isCommentOpenTag(c, end)) { ++readIdx; - while (!isCommentCloseTag(&buffer[readIdx], end)) { + while (readIdx < len && !isCommentCloseTag(&buffer[readIdx], end)) { ++readIdx; } ++readIdx; @@ -489,7 +494,7 @@ void OpenDDLParser::normalizeBuffer(std::vector &buffer) { if (isComment(c, end)) { ++readIdx; // skip the comment and the rest of the line - while (!isEndofLine(buffer[readIdx])) { + while (readIdx < len && !isEndofLine(buffer[readIdx])) { ++readIdx; } } @@ -548,8 +553,7 @@ char *OpenDDLParser::parseIdentifier(char *in, char *end, Text **id) { // get size of id size_t idLen(0); char *start(in); - while (!isSeparator(*in) && - !isNewLine(*in) && (in != end) && + while ((in != end) && !isSeparator(*in) && !isNewLine(*in) && *in != Grammar::OpenPropertyToken[0] && *in != Grammar::ClosePropertyToken[0] && *in != '$') { @@ -861,7 +865,7 @@ char *OpenDDLParser::parseProperty(char *in, char *end, Property **prop) { in = parseIdentifier(in, end, &id); if (nullptr != id) { in = lookForNextToken(in, end); - if (*in == '=') { + if (in != end && *in == '=') { ++in; in = getNextToken(in, end); Value *primData(nullptr); diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h b/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h index 5f177f252..42ad675f8 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h @@ -318,7 +318,8 @@ static const unsigned char chartype_table[256] = { template inline bool isNumeric(const T in) { - return (chartype_table[static_cast(in)] == 1); + size_t idx = static_cast(in); + return idx < sizeof(chartype_table) && (chartype_table[idx] == 1); } template From 1909b3e8d27deed5acc93e7f9a0bf48b397e1788 Mon Sep 17 00:00:00 2001 From: Alex Rebert Date: Thu, 28 Oct 2021 23:33:07 -0400 Subject: [PATCH 15/25] Fix overflow in IOStreamBuffer `getNextLine` & `getNextDataLine` now double the buffer size each time it is needed to avoid writing out of bounds. Fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=24465 --- include/assimp/IOStreamBuffer.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/assimp/IOStreamBuffer.h b/include/assimp/IOStreamBuffer.h index d54774759..bbb5ef256 100644 --- a/include/assimp/IOStreamBuffer.h +++ b/include/assimp/IOStreamBuffer.h @@ -261,6 +261,11 @@ AI_FORCE_INLINE bool IOStreamBuffer::getNextDataLine(std::vector &buffer, buffer[i] = m_cache[m_cachePos]; ++m_cachePos; ++i; + + if(i == buffer.size()) { + buffer.resize(buffer.size() * 2); + } + if (m_cachePos >= size()) { break; } @@ -308,6 +313,11 @@ AI_FORCE_INLINE bool IOStreamBuffer::getNextLine(std::vector &buffer) { buffer[i] = m_cache[m_cachePos]; ++m_cachePos; ++i; + + if(i == buffer.size()) { + buffer.resize(buffer.size() * 2); + } + if (m_cachePos >= m_cacheSize) { if (!readNextBlock()) { return false; From 6f07e89fdfb0ef3ca554ceac576aceb4420aa1c3 Mon Sep 17 00:00:00 2001 From: Alex Rebert Date: Thu, 28 Oct 2021 23:50:16 -0400 Subject: [PATCH 16/25] Fix out-of-bounds read in RemoveLineComments Fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=24553 --- code/Common/RemoveComments.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/code/Common/RemoveComments.cpp b/code/Common/RemoveComments.cpp index e1ba99761..9974e985a 100644 --- a/code/Common/RemoveComments.cpp +++ b/code/Common/RemoveComments.cpp @@ -64,20 +64,28 @@ void CommentRemover::RemoveLineComments(const char* szComment, if (len > lenBuffer) { len = lenBuffer; } - while (*szBuffer) { + + char *szCurrent = szBuffer; + while (*szCurrent) { // skip over quotes - if (*szBuffer == '\"' || *szBuffer == '\'') - while (*szBuffer++ && *szBuffer != '\"' && *szBuffer != '\''); - if (!strncmp(szBuffer,szComment,len)) { - while (!IsLineEnd(*szBuffer)) - *szBuffer++ = chReplacement; + if (*szCurrent == '\"' || *szCurrent == '\'') + while (*szCurrent++ && *szCurrent != '\"' && *szCurrent != '\''); - if (!*szBuffer) { + size_t lenRemaining = lenBuffer - (szCurrent - szBuffer); + if(lenRemaining < len) { + break; + } + + if (!strncmp(szCurrent,szComment,len)) { + while (!IsLineEnd(*szCurrent)) + *szCurrent++ = chReplacement; + + if (!*szCurrent) { break; } } - ++szBuffer; + ++szCurrent; } } From f28500dd0f69bda6402c3b6f92d25334c4415127 Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Fri, 29 Oct 2021 09:03:55 -0400 Subject: [PATCH 17/25] Fixed building of Android port --- include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h | 2 +- port/AndroidJNI/AndroidJNIIOSystem.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h b/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h index bb52d3065..29ad8e079 100644 --- a/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h +++ b/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h @@ -64,7 +64,7 @@ public: AndroidJNIIOSystem(ANativeActivity* activity); /// Class constructor with past and asset manager. - AndroidJNIIOSystem(const char *internalPath, AAssetManager assetManager); + AndroidJNIIOSystem(const char *internalPath, AAssetManager* assetManager); /// Destructor. ~AndroidJNIIOSystem(); diff --git a/port/AndroidJNI/AndroidJNIIOSystem.cpp b/port/AndroidJNI/AndroidJNIIOSystem.cpp index 00cf3af9c..e0f812362 100644 --- a/port/AndroidJNI/AndroidJNIIOSystem.cpp +++ b/port/AndroidJNI/AndroidJNIIOSystem.cpp @@ -67,8 +67,8 @@ AndroidJNIIOSystem::AndroidJNIIOSystem(ANativeActivity* activity) AndroidActivityInit(activity); } -AndroidJNIIOSystem::AndroidJNIIOSystem(const char *internalPath, AAssetManager assetManager) : - mApkWorkspacePath(internalDataPath), +AndroidJNIIOSystem::AndroidJNIIOSystem(const char *internalPath, AAssetManager* assetManager) : + mApkWorkspacePath(internalPath), mApkAssetManager(assetManager) { // empty } From e90061779637e4fe46798f2318fe26746d8dac78 Mon Sep 17 00:00:00 2001 From: Alex Rebert Date: Fri, 29 Oct 2021 09:17:40 -0400 Subject: [PATCH 18/25] Fix out-of-bounds read in FileSystemFilter::Cleanup Fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=33238 --- code/Common/FileSystemFilter.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/Common/FileSystemFilter.h b/code/Common/FileSystemFilter.h index 6782dd9e5..81576aa6c 100644 --- a/code/Common/FileSystemFilter.h +++ b/code/Common/FileSystemFilter.h @@ -300,13 +300,14 @@ private: const char separator = getOsSeparator(); for (it = in.begin(); it != in.end(); ++it) { + int remaining = std::distance(in.end(), it); // Exclude :// and \\, which remain untouched. // https://sourceforge.net/tracker/?func=detail&aid=3031725&group_id=226462&atid=1067632 - if ( !strncmp(&*it, "://", 3 )) { + if (remaining >= 3 && !strncmp(&*it, "://", 3 )) { it += 3; continue; } - if (it == in.begin() && !strncmp(&*it, "\\\\", 2)) { + if (it == in.begin() && remaining >= 2 && !strncmp(&*it, "\\\\", 2)) { it += 2; continue; } From 5a3401b69f0c3e7ba27aa96481e32b2618b7827e Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 2 Nov 2021 10:38:38 +0100 Subject: [PATCH 19/25] Update D3MFOpcPackage.cpp - Log an error in case of a nullptr-exception in reading out the 3MF-Archive - closes https://github.com/assimp/assimp/issues/4153 --- code/AssetLib/3MF/D3MFOpcPackage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/3MF/D3MFOpcPackage.cpp b/code/AssetLib/3MF/D3MFOpcPackage.cpp index ac5b91e67..8d51a7417 100644 --- a/code/AssetLib/3MF/D3MFOpcPackage.cpp +++ b/code/AssetLib/3MF/D3MFOpcPackage.cpp @@ -149,7 +149,7 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) : IOStream *fileStream = mZipArchive->Open(file.c_str()); if (nullptr == fileStream) { - ai_assert(fileStream != nullptr); + ASSIMP_LOG_ERROR("Filestream is nullptr."); continue; } From b8a10e62f9ba1d69b52a23e9a95e5fb2baed5e0d Mon Sep 17 00:00:00 2001 From: Aaron Gokaslan Date: Tue, 9 Nov 2021 13:08:13 -0500 Subject: [PATCH 20/25] Remove optimization fence --- code/AssetLib/STEPParser/STEPFileReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/STEPParser/STEPFileReader.cpp b/code/AssetLib/STEPParser/STEPFileReader.cpp index 360277912..09a596aa4 100644 --- a/code/AssetLib/STEPParser/STEPFileReader.cpp +++ b/code/AssetLib/STEPParser/STEPFileReader.cpp @@ -325,7 +325,7 @@ std::shared_ptr EXPRESS::DataType::Parse(const char*& i std::transform(s.begin(),s.end(),s.begin(),&ai_tolower ); if (schema->IsKnownToken(s)) { for(cur = t+1;*cur++ != '(';); - const std::shared_ptr dt = Parse(cur); + std::shared_ptr dt = Parse(cur); inout = *cur ? cur+1 : cur; return dt; } From 7ddd9b2484b863b78602d98b68586243a68fd02e Mon Sep 17 00:00:00 2001 From: iraj mohtasham <36444724+irajsb@users.noreply.github.com> Date: Wed, 10 Nov 2021 00:04:12 +0330 Subject: [PATCH 21/25] Added UE4 plugin --- Readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Readme.md b/Readme.md index 949d60966..4196bba76 100644 --- a/Readme.md +++ b/Readme.md @@ -43,6 +43,7 @@ Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file. * [Pascal](port/AssimpPascal/Readme.md) * [Javascript (Alpha)](https://github.com/makc/assimp2json) * [Unity 3d Plugin](https://ricardoreis.net/trilib-2/) +* [Unreal Engine Plugin](https://github.com/irajsb/UE4_Assimp/) * [JVM](https://github.com/kotlin-graphics/assimp) Full jvm port (current [status](https://github.com/kotlin-graphics/assimp/wiki/Status)) * [HAXE-Port](https://github.com/longde123/assimp-haxe) The Assimp-HAXE-port. * [Rust](https://github.com/jkvargas/russimp) From e206d699da026aa88dbeb43730c0818f428a03f7 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 9 Nov 2021 23:26:20 +0100 Subject: [PATCH 22/25] Change version to 5.1.0 - Change version for Version 5.1.0-RC1 to 5.1.0 - closes https://github.com/assimp/assimp/issues/4161 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f893646a..4e47b5732 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,7 +53,7 @@ IF(ASSIMP_HUNTER_ENABLED) add_definitions(-DASSIMP_USE_HUNTER) ENDIF() -PROJECT( Assimp VERSION 5.0.1 ) +PROJECT(Assimp VERSION 5.1.0) # All supported options ############################################### From 8a613a86555008a8310a3d0a62e51e2335cf721e Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 9 Nov 2021 23:27:58 +0100 Subject: [PATCH 23/25] Fix unittest --- test/unit/utVersion.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/unit/utVersion.cpp b/test/unit/utVersion.cpp index 0de6ef39c..6577c7758 100644 --- a/test/unit/utVersion.cpp +++ b/test/unit/utVersion.cpp @@ -44,16 +44,16 @@ class utVersion : public ::testing::Test { }; TEST_F( utVersion, aiGetLegalStringTest ) { - const char *lv( aiGetLegalString() ); + const char *lv = aiGetLegalString(); EXPECT_NE( lv, nullptr ); std::string text( lv ); - size_t pos( text.find( std::string( "2021" ) ) ); + size_t pos = text.find(std::string("2021")); EXPECT_NE( pos, std::string::npos ); } TEST_F( utVersion, aiGetVersionMinorTest ) { - EXPECT_EQ( aiGetVersionMinor(), 0U ); + EXPECT_EQ( aiGetVersionMinor(), 1U ); } TEST_F( utVersion, aiGetVersionMajorTest ) { From c01d33a77a388be98ab4316979949d0294c8a619 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 10 Nov 2021 09:12:35 +0100 Subject: [PATCH 24/25] Update anim.h - Add missing whitespaces --- include/assimp/anim.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/assimp/anim.h b/include/assimp/anim.h index dcd054d1e..8a73297a5 100644 --- a/include/assimp/anim.h +++ b/include/assimp/anim.h @@ -98,6 +98,7 @@ struct aiVectorKey { bool operator<(const aiVectorKey &rhs) const { return mTime < rhs.mTime; } + bool operator>(const aiVectorKey &rhs) const { return mTime > rhs.mTime; } @@ -131,6 +132,7 @@ struct aiQuatKey { bool operator==(const aiQuatKey &rhs) const { return rhs.mValue == this->mValue; } + bool operator!=(const aiQuatKey &rhs) const { return rhs.mValue != this->mValue; } @@ -139,6 +141,7 @@ struct aiQuatKey { bool operator<(const aiQuatKey &rhs) const { return mTime < rhs.mTime; } + bool operator>(const aiQuatKey &rhs) const { return mTime > rhs.mTime; } From 5fd2a5559cda5b8d821e25d0bfeb68aba83a3007 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 10 Nov 2021 09:19:29 +0100 Subject: [PATCH 25/25] Update mesh.h - Add initialization for armature attributes. - closes https://github.com/assimp/assimp/issues/4158 --- include/assimp/mesh.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/assimp/mesh.h b/include/assimp/mesh.h index 8223b3443..225f8556a 100644 --- a/include/assimp/mesh.h +++ b/include/assimp/mesh.h @@ -300,6 +300,10 @@ struct aiBone { aiBone() AI_NO_EXCEPT : mName(), mNumWeights(0), +#ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS + mArmature(nullptr), + mNode(nullptr), +#endif mWeights(nullptr), mOffsetMatrix() { // empty @@ -309,6 +313,10 @@ struct aiBone { aiBone(const aiBone &other) : mName(other.mName), mNumWeights(other.mNumWeights), +#ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS + mArmature(nullptr), + mNode(nullptr), +#endif mWeights(nullptr), mOffsetMatrix(other.mOffsetMatrix) { if (other.mWeights && other.mNumWeights) {